[MERGE] Turn --coverage into a global option

Andrew Bennetts andrew at canonical.com
Mon Jan 7 12:12:42 GMT 2008


This is a quick tweak that turns --coverage into a global option, rather than
one that is specific to “bzr selftest”.  Otherwise the meaning of the option is
unchanged.

This has the advantage that you can generate a code coverage report for any
operation, not just a selftest.  Also, because the trace function is installed
much sooner, the report is more accurate: most imports will now occur *after*
the trace function is installed, so module-level coverage will typically be
accurate.  That should eliminate most of the distracting “>>>>>>” flagging of
class and def statements even when everything else in the module is exercised.

It should also resolve Robert's qualms about where this logic had been hooked
into the test runner.

-Andrew.

-------------- next part --------------
# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: andrew.bennetts at canonical.com-20080107120712-\
#   06hptn3zo84exauj
# target_branch: http://bazaar-vcs.org/bzr/bzr.dev
# testament_sha1: 3c26bcce9c3887a040d569895bac7d628c5a9690
# timestamp: 2008-01-07 23:11:01 +1100
# source_branch: http://people.ubuntu.com/~andrew/bzr/global-coverage
# base_revision_id: pqm at pqm.ubuntu.com-20080105015401-67wgbytv81394cl1
# 
# Begin patch
=== modified file 'NEWS'
--- NEWS	2008-01-05 01:54:01 +0000
+++ NEWS	2008-01-07 12:07:12 +0000
@@ -62,6 +62,9 @@
    * ``split`` now supported, to enable splitting large trees into smaller
      pieces.  (Aaron Bentley)
 
+   * The ``--coverage`` option is now global, rather specific to ``bzr
+     selftest``.  (Andrew Bennetts)
+
   BUGFIXES:
 
    * Avoid AttributeError when unlocking a pack repository when an error occurs.

=== modified file 'bzrlib/builtins.py'
--- bzrlib/builtins.py	2007-12-29 18:55:20 +0000
+++ bzrlib/builtins.py	2008-01-07 12:07:12 +0000
@@ -2598,9 +2598,6 @@
                                  ' expression.'),
                      Option('strict', help='Fail on missing dependencies or '
                             'known failures.'),
-                     Option('coverage', type=str, argname="DIRECTORY",
-                            help='Generate line coverage report in this '
-                                 'directory.'),
                      ]
     encoding_type = 'replace'
 
@@ -2608,7 +2605,7 @@
             transport=None, benchmark=None,
             lsprof_timed=None, cache_dir=None,
             first=False, list_only=False,
-            randomize=None, exclude=None, strict=False, coverage=None):
+            randomize=None, exclude=None, strict=False):
         import bzrlib.ui
         from bzrlib.tests import selftest
         import bzrlib.benchmarks as benchmarks
@@ -2650,7 +2647,6 @@
                               random_seed=randomize,
                               exclude_pattern=exclude,
                               strict=strict,
-                              coverage_dir=coverage,
                               )
         finally:
             if benchfile is not None:

=== modified file 'bzrlib/commands.py'
--- bzrlib/commands.py	2007-12-27 02:28:14 +0000
+++ bzrlib/commands.py	2008-01-07 12:07:12 +0000
@@ -590,6 +590,20 @@
 
     return argdict
 
+def apply_coveraged(dirname, the_callable, *args, **kwargs):
+    # Cannot use "import trace", as that would import bzrlib.trace instead of
+    # the standard library's trace.
+    trace = __import__('trace')
+
+    tracer = trace.Trace(count=1, trace=0)
+    sys.settrace(tracer.globaltrace)
+
+    ret = the_callable(*args, **kwargs)
+
+    sys.settrace(None)
+    results = tracer.results()
+    results.write_results(show_missing=1, summary=False,
+                          coverdir=dirname)
 
 
 def apply_profiled(the_callable, *args, **kwargs):
@@ -682,13 +696,16 @@
 
     --lsprof
         Run under the Python lsprof profiler.
+
+    --coverage
+        Generate line coverage report in the specified directory.
     """
     argv = list(argv)
     trace.mutter("bzr arguments: %r", argv)
 
     opt_lsprof = opt_profile = opt_no_plugins = opt_builtin =  \
                 opt_no_aliases = False
-    opt_lsprof_file = None
+    opt_lsprof_file = opt_coverage_dir = None
 
     # --no-plugins is handled specially at a very early stage. We need
     # to load plugins before doing other command parsing so that they
@@ -712,6 +729,9 @@
             opt_no_aliases = True
         elif a == '--builtin':
             opt_builtin = True
+        elif a == '--coverage':
+            opt_coverage_dir = argv[i + 1]
+            i += 1
         elif a.startswith('-D'):
             debug.debug_flags.add(a[2:])
         else:
@@ -758,6 +778,8 @@
             ret = apply_lsprofiled(opt_lsprof_file, run, *run_argv)
         elif opt_profile:
             ret = apply_profiled(run, *run_argv)
+        elif opt_coverage_dir:
+            ret = apply_coveraged(opt_coverage_dir, run, *run_argv)
         else:
             ret = run(*run_argv)
         return ret or 0

=== modified file 'bzrlib/help_topics/__init__.py'
--- bzrlib/help_topics/__init__.py	2008-01-03 02:17:12 +0000
+++ bzrlib/help_topics/__init__.py	2008-01-07 12:07:12 +0000
@@ -271,6 +271,7 @@
                "callgrind.out" or end with ".callgrind", the output will be
                formatted for use with KCacheGrind. Otherwise, the output
                will be a pickle.
+--coverage     Generate line coverage report in the specified directory.
 
 See doc/developers/profiling.txt for more information on profiling.
 A number of debug flags are also available to assist troubleshooting and

=== modified file 'bzrlib/tests/__init__.py'
--- bzrlib/tests/__init__.py	2007-12-19 09:32:56 +0000
+++ bzrlib/tests/__init__.py	2008-01-07 12:07:12 +0000
@@ -43,7 +43,6 @@
 import sys
 import tempfile
 import time
-import trace
 import unittest
 import warnings
 
@@ -2425,9 +2424,7 @@
               list_only=False,
               random_seed=None,
               exclude_pattern=None,
-              strict=False,
-              coverage_dir=None,
-              ):
+              strict=False):
     TestCase._gather_lsprof_in_benchmarks = lsprof_timed
     if verbose:
         verbosity = 2
@@ -2470,19 +2467,8 @@
         else:
             suite = order_changer(filter_suite_by_re(suite, pattern))
 
-    # Activate code coverage.
-    if coverage_dir is not None:
-        tracer = trace.Trace(count=1, trace=0)
-        sys.settrace(tracer.globaltrace)
-
     result = runner.run(suite)
 
-    if coverage_dir is not None:
-        sys.settrace(None)
-        results = tracer.results()
-        results.write_results(show_missing=1, summary=False,
-                              coverdir=coverage_dir)
-
     if strict:
         return result.wasStrictlySuccessful()
 
@@ -2499,7 +2485,6 @@
              random_seed=None,
              exclude_pattern=None,
              strict=False,
-             coverage_dir=None,
              ):
     """Run the whole test suite under the enhanced runner"""
     # XXX: Very ugly way to do this...
@@ -2527,8 +2512,7 @@
                      list_only=list_only,
                      random_seed=random_seed,
                      exclude_pattern=exclude_pattern,
-                     strict=strict,
-                     coverage_dir=coverage_dir)
+                     strict=strict)
     finally:
         default_transport = old_transport
 

# Begin bundle
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
cKEhn6bC4g==


More information about the bazaar mailing list