summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2001-07-29 12:26:00 (GMT)
committerSteven Knight <knight@baldmt.com>2001-07-29 12:26:00 (GMT)
commit6a38dd15e4d36404cd3121e97e8308c2841987ef (patch)
treef565cca8eae2e0065260831b7473d35ab1c1c4e4
parentd30b5d7c747a906752e5ab680743dade655e1537 (diff)
downloadSCons-6a38dd15e4d36404cd3121e97e8308c2841987ef.zip
SCons-6a38dd15e4d36404cd3121e97e8308c2841987ef.tar.gz
SCons-6a38dd15e4d36404cd3121e97e8308c2841987ef.tar.bz2
add the -j argument
-rw-r--r--src/scons/Job.py45
-rw-r--r--src/scons/JobTests.py18
-rw-r--r--test/t0001.py68
-rw-r--r--test/t0002.py72
4 files changed, 191 insertions, 12 deletions
diff --git a/src/scons/Job.py b/src/scons/Job.py
index 6da7e40..5e542d4 100644
--- a/src/scons/Job.py
+++ b/src/scons/Job.py
@@ -1,12 +1,55 @@
"""scons.Job
This module defines the Serial and Parallel classes that execute tasks to
-complete a build.
+complete a build. The Jobs class provides a higher level interface to start,
+stop, and wait on jobs.
"""
__revision__ = "Job.py __REVISION__ __DATE__ __DEVELOPER__"
+class Jobs:
+ """An instance of this class initializes N jobs, and provides
+ methods for starting, stopping, and waiting on all N jobs.
+ """
+
+ def __init__(self, num, taskmaster):
+ """
+ create 'num' jobs using the given taskmaster.
+
+ If 'num' is equal to 0, then a serial job will be used,
+ otherwise 'num' parallel jobs will be used.
+ """
+
+ if num > 1:
+ self.jobs = []
+ for i in range(num):
+ self.jobs.append(Parallel(taskmaster))
+ else:
+ self.jobs = [Serial(taskmaster)]
+
+ def start(self):
+ """start the jobs"""
+
+ for job in self.jobs:
+ job.start()
+
+ def wait(self):
+ """ wait for the jobs started with start() to finish"""
+
+ for job in self.jobs:
+ job.wait()
+
+ def stop(self):
+ """
+ stop the jobs started with start()
+
+ This function does not wait for the jobs to finish.
+ """
+
+ for job in self.jobs:
+ job.stop()
+
class Serial:
"""This class is used to execute tasks in series, and is more efficient
than Parallel, but is only appropriate for non-parallel builds. Only
diff --git a/src/scons/JobTests.py b/src/scons/JobTests.py
index 80ae6cd..4b8b558 100644
--- a/src/scons/JobTests.py
+++ b/src/scons/JobTests.py
@@ -121,15 +121,9 @@ class ParallelTestCase(unittest.TestCase):
raise NoThreadsException()
taskmaster = Taskmaster(num_tasks, self)
- jobs = []
- for i in range(num_jobs):
- jobs.append(scons.Job.Parallel(taskmaster))
-
- for job in jobs:
- job.start()
-
- for job in jobs:
- job.wait()
+ jobs = scons.Job.Jobs(num_jobs, taskmaster)
+ jobs.start()
+ jobs.wait()
self.failUnless(not taskmaster.tasks_were_serial(),
"the tasks were not executed in parallel")
@@ -143,8 +137,10 @@ class SerialTestCase(unittest.TestCase):
"test a serial job"
taskmaster = Taskmaster(num_tasks, self)
- job = scons.Job.Serial(taskmaster)
- job.start()
+ jobs = scons.Job.Jobs(1, taskmaster)
+ jobs.start()
+ jobs.wait()
+
self.failUnless(taskmaster.tasks_were_serial(),
"the tasks were not executed in series")
self.failUnless(taskmaster.all_tasks_are_executed(),
diff --git a/test/t0001.py b/test/t0001.py
new file mode 100644
index 0000000..824e046
--- /dev/null
+++ b/test/t0001.py
@@ -0,0 +1,68 @@
+#!/usr/bin/env python
+
+__revision__ = "test/t0001.py __REVISION__ __DATE__ __DEVELOPER__"
+
+from TestCmd import TestCmd
+import string
+import sys
+
+
+try:
+ import threading
+except ImportError:
+ # if threads are not supported, then
+ # there is nothing to test
+ test.pass_test()
+ sys.exit()
+
+
+test = TestCmd(program = 'scons.py',
+ workdir = '',
+ interpreter = 'python')
+
+test.write('build.py', r"""
+import time
+import sys
+file = open(sys.argv[1], 'w')
+file.write(str(time.time()) + '\n')
+time.sleep(1)
+file.write(str(time.time()))
+file.close()
+""")
+
+test.write('SConstruct', """
+MyBuild = Builder(name = "MyBuild",
+ action = "python build.py %(target)s")
+env = Environment(BUILDERS = [MyBuild])
+env.MyBuild(target = 'f1', source = 'f1.in')
+env.MyBuild(target = 'f2', source = 'f2.in')
+""")
+
+def RunTest(args):
+ test.write('f1.in', 'f1.in')
+ test.write('f2.in', 'f2.in')
+
+ test.run(chdir = '.', arguments = args)
+
+ str = test.read("f1")
+ start1,finish1 = map(float, string.split(str, "\n"))
+
+ str = test.read("f2")
+ start2,finish2 = map(float, string.split(str, "\n"))
+
+ return start2, finish1
+
+start2, finish1 = RunTest('-j 2 f1 f2')
+
+# fail if the second file was not started
+# before the first one was finished
+test.fail_test(not (start2 < finish1))
+
+start2, finish1 = RunTest('f1 f2')
+
+# fail if the second file was started
+# before the first one was finished
+test.fail_test(start2 < finish1)
+
+test.pass_test()
+
diff --git a/test/t0002.py b/test/t0002.py
new file mode 100644
index 0000000..0cdfa81
--- /dev/null
+++ b/test/t0002.py
@@ -0,0 +1,72 @@
+#!/usr/bin/env python
+
+__revision__ = "test/t0002.py __REVISION__ __DATE__ __DEVELOPER__"
+
+from TestCmd import TestCmd
+
+test = TestCmd(program = 'scons.py',
+ workdir = '',
+ interpreter = 'python')
+
+test.write('SConstruct', """
+env = Environment()
+env.Program(target = 'f1', source = 'f1.c')
+env.Program(target = 'f2', source = 'f2.c')
+env.Program(target = 'f3', source = 'f3.c')
+env.Program(target = 'f4', source = 'f4.c')
+""")
+
+test.write('f1.c', """
+int
+main(int argc, char *argv[])
+{
+ printf(\"f1.c\n\");
+ exit (0);
+}
+""")
+
+test.write('f2.c', """
+int
+main(int argc, char *argv[])
+{
+ printf(\"f2.c\n\");
+ exit (0);
+}
+""")
+
+
+test.write('f3.c', """
+int
+main(int argc, char *argv[])
+{
+ printf(\"f3.c\n\");
+ exit (0);
+}
+""")
+
+test.write('f4.c', """
+int
+main(int argc, char *argv[])
+{
+ printf(\"f4.c\n\");
+ exit (0);
+}
+""")
+
+
+test.run(chdir = '.', arguments = '-j 3 f1 f2 f3 f4')
+
+test.run(program = test.workpath('f1'))
+test.fail_test(test.stdout() != "f1.c\n")
+
+test.run(program = test.workpath('f2'))
+test.fail_test(test.stdout() != "f2.c\n")
+
+test.run(program = test.workpath('f3'))
+test.fail_test(test.stdout() != "f3.c\n")
+
+test.run(program = test.workpath('f4'))
+test.fail_test(test.stdout() != "f4.c\n")
+
+
+test.pass_test()