Allow specifying environment variables.
Refactor the code a little to make this easier to munge around.
diff --git a/tools/run_tests/jobset.py b/tools/run_tests/jobset.py
index 8f16a4f..19ae52e 100755
--- a/tools/run_tests/jobset.py
+++ b/tools/run_tests/jobset.py
@@ -86,19 +86,49 @@
raise Exception('%s not found' % filename)
+class JobSpec(object):
+ """Specifies what to run for a job."""
+
+ def __init__(self, cmdline, shortname=None, environ={}, hash_targets=[]):
+ """
+ Arguments:
+ cmdline: a list of arguments to pass as the command line
+ environ: a dictionary of environment variables to set in the child process
+ hash_targets: which files to include in the hash representing the jobs version
+ (or empty, indicating the job should not be hashed)
+ """
+ self.cmdline = cmdline
+ self.environ = environ
+ self.shortname = cmdline[0] if shortname is None else shortname
+ self.hash_targets = hash_targets or []
+
+ def identity(self):
+ return '%r %r %r' % (self.cmdline, self.environ, self.hash_targets)
+
+ def __hash__(self):
+ return hash(self.identity())
+
+ def __cmp__(self, other):
+ return self.identity() == other.identity()
+
+
class Job(object):
"""Manages one job."""
- def __init__(self, cmdline, bin_hash, newline_on_success):
- self._cmdline = cmdline
+ def __init__(self, spec, bin_hash, newline_on_success):
+ self._spec = spec
self._bin_hash = bin_hash
self._tempfile = tempfile.TemporaryFile()
- self._process = subprocess.Popen(args=cmdline,
+ env = os.environ.copy()
+ for k, v in spec.environ.iteritems():
+ env[k] = v
+ self._process = subprocess.Popen(args=spec.cmdline,
stderr=subprocess.STDOUT,
- stdout=self._tempfile)
+ stdout=self._tempfile,
+ env=env)
self._state = _RUNNING
self._newline_on_success = newline_on_success
- message('START', ' '.join(self._cmdline))
+ message('START', spec.shortname)
def state(self, update_cache):
"""Poll current state of the job. Prints messages at completion."""
@@ -108,12 +138,13 @@
self._tempfile.seek(0)
stdout = self._tempfile.read()
message('FAILED', '%s [ret=%d]' % (
- ' '.join(self._cmdline), self._process.returncode), stdout)
+ self._spec.shortname, self._process.returncode), stdout)
else:
self._state = _SUCCESS
- message('PASSED', '%s' % ' '.join(self._cmdline),
+ message('PASSED', self._spec.shortname,
do_newline=self._newline_on_success)
- update_cache.finished(self._cmdline, self._bin_hash)
+ if self._bin_hash:
+ update_cache.finished(self._spec.identity(), self._bin_hash)
return self._state
def kill(self):
@@ -135,16 +166,26 @@
self._newline_on_success = newline_on_success
self._cache = cache
- def start(self, cmdline):
+ def start(self, spec):
"""Start a job. Return True on success, False on failure."""
while len(self._running) >= self._maxjobs:
if self.cancelled(): return False
self.reap()
if self.cancelled(): return False
- with open(which(cmdline[0])) as f:
- bin_hash = hashlib.sha1(f.read()).hexdigest()
- if self._cache.should_run(cmdline, bin_hash):
- self._running.add(Job(cmdline, bin_hash, self._newline_on_success))
+ if spec.hash_targets:
+ bin_hash = hashlib.sha1()
+ for fn in spec.hash_targets:
+ with open(which(fn)) as f:
+ bin_hash.update(f.read())
+ bin_hash = bin_hash.hexdigest()
+ should_run = self._cache.should_run(spec.identity(), bin_hash)
+ else:
+ bin_hash = None
+ should_run = True
+ if should_run:
+ self._running.add(Job(spec,
+ bin_hash,
+ self._newline_on_success))
return True
def reap(self):