[Zope3-checkins] SVN: zope.testing/branches/benji-optimize/src/zope/testing/testrunner/ checkpoint failed idea

Benji York benji at zope.com
Sat Jul 12 08:13:14 EDT 2008


Log message for revision 88282:
  checkpoint failed idea
  

Changed:
  U   zope.testing/branches/benji-optimize/src/zope/testing/testrunner/formatter.py
  U   zope.testing/branches/benji-optimize/src/zope/testing/testrunner/runner.py

-=-
Modified: zope.testing/branches/benji-optimize/src/zope/testing/testrunner/formatter.py
===================================================================
--- zope.testing/branches/benji-optimize/src/zope/testing/testrunner/formatter.py	2008-07-12 10:45:38 UTC (rev 88281)
+++ zope.testing/branches/benji-optimize/src/zope/testing/testrunner/formatter.py	2008-07-12 12:13:13 UTC (rev 88282)
@@ -46,12 +46,14 @@
     max_width = 80
 
     def __init__(self, options):
-        self.options = options
+#        self.options = options
+        self.progress = options.progress
+        self.verbose = options.verbose
         self.last_width = 0
         self.compute_max_width()
 
-    progress = property(lambda self: self.options.progress)
-    verbose = property(lambda self: self.options.verbose)
+#    progress = property(lambda self: self.options.progress)
+#    verbose = property(lambda self: self.options.verbose)
 
     def compute_max_width(self):
         """Try to determine the terminal width."""

Modified: zope.testing/branches/benji-optimize/src/zope/testing/testrunner/runner.py
===================================================================
--- zope.testing/branches/benji-optimize/src/zope/testing/testrunner/runner.py	2008-07-12 10:45:38 UTC (rev 88281)
+++ zope.testing/branches/benji-optimize/src/zope/testing/testrunner/runner.py	2008-07-12 12:13:13 UTC (rev 88282)
@@ -80,18 +80,41 @@
         return func(*args, **kws)
 
     read_pipe, write_pipe = os.pipe()
+
+    # it's generally a good idea to flush stdout and stderr before forking
+    sys.stdout.flush()
+    sys.stderr.flush()
+
     pid = os.fork()
     if pid: # am parent
         os.close(write_pipe)
-        child_exit = os.waitpid(pid)
+        _, child_exit = os.waitpid(pid, 0)
         assert child_exit == 0
-        result = pickle.loads(os.read(read_pipe, 999999))
+        stdout, was_exception, result = pickle.loads(os.read(read_pipe, 10000000))
+        if stdout is not None:
+            sys.stdout.write(stdout.getvalue())
+        if was_exception:
+            raise result
     else: # am child
         os.close(read_pipe)
+        was_exception = False
         result = func(*args, **kws)
-        os.write(write_pipe, pickle.dumps(result))
-        os.exit(0)
+#        try:
+#            result = func(*args, **kws)
+#        except:
+#            e = sys.exc_info()[1]
+#            was_exception = True
+#            result = e
+        to_pickle = [sys.stdout, was_exception, result]
+        do_pickle = lambda: os.write(write_pipe, pickle.dumps(to_pickle))
+        try:
+            do_pickle()
+        except:
+            to_pickle[0] = None
+            do_pickle()
 
+        os._exit(0)
+
     return result # will only get here in the parent
 
 
@@ -232,15 +255,15 @@
             layer_name, layer, tests = layers_to_run[0]
             for feature in self.features:
                 feature.layer_setup(layer)
-            try:
-                (ran, self.options, layer, tests, setup_layers, self.failures,
-                    self.errors) = run_layer(self.options, layer_name, layer,
-                        tests, setup_layers, self.failures, self.errors)
-                self.ran += ran
-            except EndRun:
+            (ran, end, can_not_tear_down, self.options.output, layer, setup_layers, self.failures,
+                self.errors) = fork_and_call(run_layer, self.options,
+                    layer_name, layer, tests, setup_layers, self.failures,
+                    self.errors)
+            self.ran += ran
+            if end:
                 self.failed = True
                 return
-            except CanNotTearDown:
+            if can_not_tear_down:
                 if not self.options.resume_layer:
                     should_resume = True
                     break
@@ -256,7 +279,7 @@
                 self.ran += resume_tests(self.options, self.features,
                     layers_to_run, self.failures, self.errors)
 
-        if setup_layers:
+        if setup_layers and not hasattr(os, 'fork'):
             if self.options.resume_layer == None:
                 self.options.output.info("Tearing down left over layers:")
             tear_down_unneeded(self.options, (), setup_layers, True)
@@ -364,12 +387,17 @@
               failures, errors):
 
     output = options.output
+    end = False
+    can_not_tear_down = False
     gathered = []
     gather_layers(layer, gathered)
     needed = dict([(l, 1) for l in gathered])
     if options.resume_number != 0:
         output.info("Running %s tests:" % layer_name)
-    tear_down_unneeded(options, needed, setup_layers)
+    try:
+        tear_down_unneeded(options, needed, setup_layers)
+    except CanNotTearDown:
+        can_not_tear_down = True
 
     if options.resume_layer != None:
         output.info_suboptimal( "  Running in a subprocess.")
@@ -377,7 +405,7 @@
     try:
         setup_layer(options, layer, setup_layers)
     except EndRun:
-        raise
+        end = True
     except Exception:
         f = cStringIO.StringIO()
         traceback.print_exc(file=f)
@@ -387,8 +415,13 @@
     else:
         ran = run_tests(options, tests, layer_name, failures, errors)
 
-    return ran, options, layer, tests, setup_layers, failures, errors
+    # make "failures" pickleable
+    for x, y in failures:
+        del x._dt_checker
 
+    return (ran, end, can_not_tear_down, options.output, layer, setup_layers,
+        failures, errors)
+
 class SetUpLayerFailure(unittest.TestCase):
 
     def runTest(self):



More information about the Zope3-Checkins mailing list