mbligh | f4c3532 | 2006-03-13 01:01:10 +0000 | [diff] [blame] | 1 | from autotest_utils import * |
apw | 0865f48 | 2006-03-30 18:50:19 +0000 | [diff] [blame] | 2 | import os, sys, kernel, test, pickle, threading |
mbligh | f4c3532 | 2006-03-13 01:01:10 +0000 | [diff] [blame] | 3 | |
apw | 0865f48 | 2006-03-30 18:50:19 +0000 | [diff] [blame] | 4 | # Parallel run interface. |
| 5 | class AsyncRun(threading.Thread): |
| 6 | def __init__(self, cmd): |
| 7 | threading.Thread.__init__(self) |
| 8 | self.cmd = cmd |
| 9 | def run(self): |
| 10 | x = self.cmd.pop(0) |
| 11 | x(*self.cmd) |
| 12 | |
| 13 | # JOB: the actual job against which we do everything. |
mbligh | f4c3532 | 2006-03-13 01:01:10 +0000 | [diff] [blame] | 14 | class job: |
apw | ecf41b7 | 2006-03-31 14:00:55 +0000 | [diff] [blame] | 15 | def __init__(self, control, jobtag='default'): |
mbligh | f4c3532 | 2006-03-13 01:01:10 +0000 | [diff] [blame] | 16 | self.autodir = os.environ['AUTODIR'] |
mbligh | 8264186 | 2006-04-23 06:21:36 +0000 | [diff] [blame] | 17 | self.testdir = self.autodir + '/tests' |
mbligh | edf430c | 2006-04-23 06:52:09 +0000 | [diff] [blame^] | 18 | self.profdir = self.autodir + '/profilers' |
mbligh | f4c3532 | 2006-03-13 01:01:10 +0000 | [diff] [blame] | 19 | self.tmpdir = self.autodir + '/tmp' |
mbligh | a66742f | 2006-04-02 19:54:27 +0000 | [diff] [blame] | 20 | if os.path.exists(self.tmpdir): |
mbligh | a975fb6 | 2006-04-22 19:56:25 +0000 | [diff] [blame] | 21 | system('rm -rf ' + self.tmpdir) |
mbligh | a66742f | 2006-04-02 19:54:27 +0000 | [diff] [blame] | 22 | os.mkdir(self.tmpdir) |
mbligh | 24f7da0 | 2006-04-23 06:32:18 +0000 | [diff] [blame] | 23 | self.resultdir = self.autodir + '/results/' + jobtag |
mbligh | f4c3532 | 2006-03-13 01:01:10 +0000 | [diff] [blame] | 24 | if os.path.exists(self.resultdir): |
mbligh | a975fb6 | 2006-04-22 19:56:25 +0000 | [diff] [blame] | 25 | system('rm -rf ' + self.resultdir) |
mbligh | f4c3532 | 2006-03-13 01:01:10 +0000 | [diff] [blame] | 26 | os.mkdir(self.resultdir) |
| 27 | os.mkdir(self.resultdir + "/debug") |
| 28 | os.mkdir(self.resultdir + "/analysis") |
| 29 | |
apw | ecf41b7 | 2006-03-31 14:00:55 +0000 | [diff] [blame] | 30 | self.control = control |
mbligh | f4c3532 | 2006-03-13 01:01:10 +0000 | [diff] [blame] | 31 | self.jobtab = jobtag |
| 32 | |
| 33 | self.stdout = fd_stack(1, sys.stdout) |
| 34 | self.stderr = fd_stack(2, sys.stderr) |
| 35 | |
| 36 | def kernel(self, topdir, base_tree): |
| 37 | return kernel.kernel(self, topdir, base_tree) |
| 38 | |
apw | 5a78eef | 2006-04-03 14:16:59 +0000 | [diff] [blame] | 39 | def runtest(self, tag, testname, *test_args): |
mbligh | 8264186 | 2006-04-23 06:21:36 +0000 | [diff] [blame] | 40 | sys.path.insert(0, self.testdir + '/' + testname) |
apw | 5a78eef | 2006-04-03 14:16:59 +0000 | [diff] [blame] | 41 | exec "import %s" % testname |
| 42 | exec "mytest = %s.%s(self, testname + '.' + tag)" % (testname, testname) |
mbligh | 8264186 | 2006-04-23 06:21:36 +0000 | [diff] [blame] | 43 | mytest.bindir = self.testdir + '/' + testname |
| 44 | mytest.srcdir = mytest.bindir + '/' + testname |
| 45 | if os.path.exists(mytest.srcdir): |
| 46 | # Bad idea, as it'll always rebuild, but will do for now |
| 47 | system('rm -rf ' + mytest.srcdir) |
| 48 | mytest.tmpdir = self.tmpdir + '/' + testname |
| 49 | os.mkdir(mytest.tmpdir) |
mbligh | f4c3532 | 2006-03-13 01:01:10 +0000 | [diff] [blame] | 50 | mytest.run(testname, test_args) |
apw | 0865f48 | 2006-03-30 18:50:19 +0000 | [diff] [blame] | 51 | |
| 52 | def noop(self, text): |
| 53 | print "job: noop: " + text |
| 54 | |
| 55 | # Job control primatives. |
| 56 | def parallel(self, *l): |
| 57 | tasks = [] |
| 58 | for t in l: |
| 59 | task = AsyncRun(t) |
| 60 | tasks.append(task) |
| 61 | task.start() |
| 62 | for t in tasks: |
| 63 | t.join() |
| 64 | |
| 65 | # XXX: should have a better name. |
| 66 | def quit(self): |
| 67 | sys.exit(5) |
| 68 | |
| 69 | def complete(self, status): |
| 70 | # We are about to exit 'complete' so clean up the control file. |
| 71 | try: |
apw | ecf41b7 | 2006-03-31 14:00:55 +0000 | [diff] [blame] | 72 | os.unlink(self.control + '.state') |
apw | 0865f48 | 2006-03-30 18:50:19 +0000 | [diff] [blame] | 73 | except: |
| 74 | pass |
mbligh | a66742f | 2006-04-02 19:54:27 +0000 | [diff] [blame] | 75 | if os.path.exists(self.control): |
| 76 | os.rename(self.control, self.control + '.complete') |
apw | 1b02190 | 2006-04-03 17:02:56 +0000 | [diff] [blame] | 77 | sys.exit(status) |
apw | 0865f48 | 2006-03-30 18:50:19 +0000 | [diff] [blame] | 78 | |
| 79 | # STEPS: the stepping engine -- if the control file defines |
| 80 | # step_init we will be using this engine to drive multiple |
| 81 | # runs. |
| 82 | steps = [] |
| 83 | def next_step(self, step): |
| 84 | self.steps.append(step) |
apw | ecf41b7 | 2006-03-31 14:00:55 +0000 | [diff] [blame] | 85 | pickle.dump(self.steps, open(self.control + '.state', 'w')) |
apw | 0865f48 | 2006-03-30 18:50:19 +0000 | [diff] [blame] | 86 | |
| 87 | def step_engine(self, init): |
| 88 | # If there is a mid-job state file load that in and continue |
| 89 | # where it indicates. Otherwise start stepping at the passed |
| 90 | # entry. |
| 91 | try: |
apw | ecf41b7 | 2006-03-31 14:00:55 +0000 | [diff] [blame] | 92 | self.steps = pickle.load(open(self.control + '.state', |
| 93 | 'r')) |
apw | 0865f48 | 2006-03-30 18:50:19 +0000 | [diff] [blame] | 94 | except: |
| 95 | self.next_step(init) |
| 96 | |
| 97 | # Run the step list. |
| 98 | while len(self.steps) > 0: |
apw | fd922bb | 2006-04-04 07:47:00 +0000 | [diff] [blame] | 99 | step = self.steps.pop(0) |
apw | ecf41b7 | 2006-03-31 14:00:55 +0000 | [diff] [blame] | 100 | pickle.dump(self.steps, open(self.control + '.state', |
| 101 | 'w')) |
apw | 0865f48 | 2006-03-30 18:50:19 +0000 | [diff] [blame] | 102 | |
| 103 | cmd = step.pop(0) |
| 104 | cmd(*step) |
| 105 | |
| 106 | # all done, clean up and exit. |
| 107 | self.complete(0) |
| 108 | |