SVN: zope.testing/branches/ctheune-cleanup/src/zope/testing/testrunner/ Moved profiling into its own feature.

Christian Theune <[email protected]>
Newsgroups gmane.comp.web.zope.zope3.cvs
Message-ID <20080504123739.2AED1399BB__18674.5890220211$1209904717$gmane$org@mail.zope.org>
Log message for revision 86351:
  Moved profiling into its own feature.
  

Changed:
  U   zope.testing/branches/ctheune-cleanup/src/zope/testing/testrunner/profiling.py
  U   zope.testing/branches/ctheune-cleanup/src/zope/testing/testrunner/runner.py

-=-
Modified: zope.testing/branches/ctheune-cleanup/src/zope/testing/testrunner/profiling.py
===================================================================
--- zope.testing/branches/ctheune-cleanup/src/zope/testing/testrunner/profiling.py	2008-05-04 12:31:57 UTC (rev 86350)
+++ zope.testing/branches/ctheune-cleanup/src/zope/testing/testrunner/profiling.py	2008-05-04 12:37:38 UTC (rev 86351)
@@ -16,7 +16,11 @@
 $Id: __init__.py 86218 2008-05-03 14:17:26Z ctheune $
 """
 
+import os
 import glob
+import sys
+import tempfile
+import zope.testing.testrunner.feature
 
 available_profilers = {}
 
@@ -79,3 +83,54 @@
             return stats
 
     available_profilers['hotshot'] = HotshotProfiler
+
+
+class Profiling(zope.testing.testrunner.feature.Feature):
+
+    def __init__(self, runner):
+        super(Profiling, self).__init__(runner)
+
+        if (self.runner.options.profile
+            and sys.version_info[:3] <= (2,4,1)
+            and __debug__):
+            self.runner.options.output.error(
+                'Because of a bug in Python < 2.4.1, profiling '
+                'during tests requires the -O option be passed to '
+                'Python (not the test runner).')
+            sys.exit()
+
+        self.active = bool(self.runner.options.profile)
+        self.profiler = self.runner.options.profile
+
+    def global_setup(self):
+        self.prof_prefix = 'tests_profile.'
+        self.prof_suffix = '.prof'
+        self.prof_glob = self.prof_prefix + '*' + self.prof_suffix
+        # if we are going to be profiling, and this isn't a subprocess,
+        # clean up any stale results files
+        if not self.runner.options.resume_layer:
+            for file_name in glob.glob(self.prof_glob):
+                os.unlink(file_name)
+        # set up the output file
+        self.oshandle, self.file_path = tempfile.mkstemp(self.prof_suffix,
+                                                         self.prof_prefix, '.')
+        self.profiler = available_profilers[self.runner.options.profile](self.file_path)
+
+        # Need to do this rebinding to support the stack-frame annoyance with
+        # hotshot.
+        self.late_setup = self.profiler.enable
+        self.early_teardown = self.profiler.disable
+
+    def global_teardown(self):
+        self.profiler.finish()
+        # We must explicitly close the handle mkstemp returned, else on
+        # Windows this dies the next time around just above due to an
+        # attempt to unlink a still-open file.
+        os.close(self.oshandle)
+        if not self.runner.options.resume_layer:
+            self.profiler_stats = self.profiler.loadStats(self.prof_glob)
+            self.profiler_stats.sort_stats('cumulative', 'calls')
+
+    def report(self):
+        if not self.runner.options.resume_layer:
+            self.runner.options.output.profiler_stats(self.profiler_stats)

Modified: zope.testing/branches/ctheune-cleanup/src/zope/testing/testrunner/runner.py
===================================================================
--- zope.testing/branches/ctheune-cleanup/src/zope/testing/testrunner/runner.py	2008-05-04 12:31:57 UTC (rev 86350)
+++ zope.testing/branches/ctheune-cleanup/src/zope/testing/testrunner/runner.py	2008-05-04 12:37:38 UTC (rev 86351)
@@ -30,7 +30,6 @@
 import unittest
 
 from zope.testing import doctest
-from zope.testing.testrunner.profiling import available_profilers
 from zope.testing.testrunner.find import find_tests, test_dirs
 from zope.testing.testrunner.find import StartUpFailure, import_name
 from zope.testing.testrunner.find import name_from_layer, _layer_name_cache
@@ -40,6 +39,7 @@
 import zope.testing.testrunner.doctest
 import zope.testing.testrunner.logsupport
 import zope.testing.testrunner.selftest
+import zope.testing.testrunner.profiling
 
 
 PYREFCOUNT_PATTERN = re.compile('\[[0-9]+ refs\]')
@@ -172,37 +172,12 @@
         self.features.append(zope.testing.testrunner.logsupport.Logging(self))
         self.features.append(zope.testing.testrunner.coverage.Coverage(self))
         self.features.append(zope.testing.testrunner.doctest.DocTest(self))
+        self.features.append(zope.testing.testrunner.profiling.Profiling(self))
 
         # Remove all features that aren't activated
         self.features = [f for f in self.features if f.active]
 
     def setup_features(self):
-        # Setup profiling
-        if (self.options.profile
-            and sys.version_info[:3] <= (2,4,1)
-            and __debug__):
-            self.options.output.error(
-                'Because of a bug in Python < 2.4.1, profiling '
-                'during tests requires the -O option be passed to '
-                'Python (not the test runner).')
-            sys.exit()
-
-        if self.options.profile:
-            self.prof_prefix = 'tests_profile.'
-            self.prof_suffix = '.prof'
-            self.prof_glob = self.prof_prefix + '*' + self.prof_suffix
-            # if we are going to be profiling, and this isn't a subprocess,
-            # clean up any stale results files
-            if not self.options.resume_layer:
-                for file_name in glob.glob(self.prof_glob):
-                    os.unlink(file_name)
-            # set up the output file
-            self.oshandle, self.file_path = tempfile.mkstemp(self.prof_suffix,
-                                                             self.prof_prefix, '.')
-            self.profiler = available_profilers[self.options.profile](self.file_path)
-            self.late_initializers.append(self.profiler.enable)
-            self.early_shutdown.append(self.profiler.disable)
-
         # Setup garbage collection threshold
         self.old_threshold = gc.get_threshold()
         if self.options.gc:
@@ -227,7 +202,6 @@
                 new_flags |= getattr(gc, op)
             gc.set_debug(new_flags)
 
-
         # Set up time measurement
         def start_time_recording():
             self.start_time = time.time()
@@ -349,16 +323,6 @@
         if self.options.gc:
             gc.set_threshold(*self.old_threshold)
 
-        if self.options.profile:
-            self.profiler.finish()
-            # We must explicitly close the handle mkstemp returned, else on
-            # Windows this dies the next time around just above due to an
-            # attempt to unlink a still-open file.
-            os.close(self.oshandle)
-            if not self.options.resume_layer:
-                self.profiler_stats = self.profiler.loadStats(self.prof_glob)
-                self.profiler_stats.sort_stats('cumulative', 'calls')
-
     def report(self):
         if self.options.resume_layer:
             sys.stdout.close()
@@ -381,10 +345,7 @@
             self.options.output.modules_with_import_problems(
                 self.import_errors)
 
-        if self.options.profile and not self.options.resume_layer:
-            self.options.output.profiler_stats(self.profiler_stats)
 
-
 def run_tests(options, tests, name, failures, errors):
     repeat = options.repeat or 1
     repeat_range = iter(range(repeat))
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.