Rev 3199: (vila) Add --load-list option to selftest in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Wed Jan 23 18:01:53 GMT 2008


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 3199
revision-id:pqm at pqm.ubuntu.com-20080123180146-9pkott489spjwv8q
parent: pqm at pqm.ubuntu.com-20080123015828-qtxnooia7jjqdkbp
parent: v.ladeuil+lp at free.fr-20080123162518-2idbvqo9kqg75u3k
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Wed 2008-01-23 18:01:46 +0000
message:
  (vila) Add --load-list option to selftest
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
  bzrlib/doc/api/__init__.py     __init__.py-20051224020744-7b87d590843855bc
  bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
  bzrlib/tests/blackbox/test_selftest.py test_selftest.py-20060123024542-01c5f1bbcb596d78
  bzrlib/tests/test_selftest.py  test_selftest.py-20051202044319-c110a115d8c0456a
    ------------------------------------------------------------
    revno: 3198.1.1
    revision-id:v.ladeuil+lp at free.fr-20080123162518-2idbvqo9kqg75u3k
    parent: pqm at pqm.ubuntu.com-20080123015828-qtxnooia7jjqdkbp
    parent: v.ladeuil+lp at free.fr-20080121151638-8fgekd4payq1e58o
    committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
    branch nick: trunk
    timestamp: Wed 2008-01-23 17:25:18 +0100
    message:
      Add --load-list option to selftest
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/doc/api/__init__.py     __init__.py-20051224020744-7b87d590843855bc
      bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
      bzrlib/tests/blackbox/test_selftest.py test_selftest.py-20060123024542-01c5f1bbcb596d78
      bzrlib/tests/test_selftest.py  test_selftest.py-20051202044319-c110a115d8c0456a
    ------------------------------------------------------------
    revno: 3193.1.12
    revision-id:v.ladeuil+lp at free.fr-20080121151638-8fgekd4payq1e58o
    parent: v.ladeuil+lp at free.fr-20080121144918-xx5wtw3ddfm0iauh
    committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
    branch nick: selftest
    timestamp: Mon 2008-01-21 16:16:38 +0100
    message:
      Fix typo (using test id list is no replacement for running the whole test suite QED).
      
      * bzrlib/tests/test_selftest.py:
      (TestTestIdList.test_test_suite): Fix test name.
    modified:
      bzrlib/tests/test_selftest.py  test_selftest.py-20051202044319-c110a115d8c0456a
    ------------------------------------------------------------
    revno: 3193.1.11
    revision-id:v.ladeuil+lp at free.fr-20080121144918-xx5wtw3ddfm0iauh
    parent: v.ladeuil+lp at free.fr-20080121112100-8qaiys24wb2nqowe
    committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
    branch nick: selftest
    timestamp: Mon 2008-01-21 15:49:18 +0100
    message:
      Relax constraint on test ids, simplify implementation and update tests.
      
      * bzrlib/tests/test_selftest.py:
      (TestSelftestFiltering.test_condition_id_in_list,
      TestSelftestFiltering.test_filter_suite_by_id_list): Updated.
      (TestTestIdList): Renamed from TestTestIdListFilter and updated.
      
      * bzrlib/tests/__init__.py:
      (TestIdList): Relax the constraint on test ids, they just have to
      start with their module name.
      
      * bzrlib/doc/api/__init__.py:
      (test_suite): Adding module name in test id is now enough.
    modified:
      bzrlib/doc/api/__init__.py     __init__.py-20051224020744-7b87d590843855bc
      bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
      bzrlib/tests/test_selftest.py  test_selftest.py-20051202044319-c110a115d8c0456a
    ------------------------------------------------------------
    revno: 3193.1.10
    revision-id:v.ladeuil+lp at free.fr-20080121112100-8qaiys24wb2nqowe
    parent: v.ladeuil+lp at free.fr-20080121111827-q19d8fx8t9le47os
    committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
    branch nick: selftest
    timestamp: Mon 2008-01-21 12:21:00 +0100
    message:
      Update NEWS.
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
    ------------------------------------------------------------
    revno: 3193.1.9
    revision-id:v.ladeuil+lp at free.fr-20080121111827-q19d8fx8t9le47os
    parent: v.ladeuil+lp at free.fr-20080121105102-j5q7nmtbqw3vbrle
    committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
    branch nick: selftest
    timestamp: Mon 2008-01-21 12:18:27 +0100
    message:
      Better test ids for bzrlib/doc/api doc tests.
      
      * bzrlib/doc/api/__init__.py:
      (test_suite): Provides a better id than 'branch_txt' when creating
      a DocFileCase for bzrlib/doc/api/branch.txt.
    modified:
      bzrlib/doc/api/__init__.py     __init__.py-20051224020744-7b87d590843855bc
      bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
    ------------------------------------------------------------
    revno: 3193.1.8
    revision-id:v.ladeuil+lp at free.fr-20080121105102-j5q7nmtbqw3vbrle
    parent: v.ladeuil+lp at free.fr-20080121101622-pj98frqla59g5olb
    committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
    branch nick: selftest
    timestamp: Mon 2008-01-21 11:51:02 +0100
    message:
      Add '--load-list' option to selftest.
      
      * bzrlib/tests/test_selftest.py:
      (TestTestIdListFilter.test_test_suite): Delete the plugin test, it
      is indeed fragile.
      
      * bzrlib/tests/blackbox/test_selftest.py:
      (TestSelftestWithIdList): Test the --load-list-option.
      
      * bzrlib/tests/__init__.py:
      (selftest): Add a --load-list option.
      
      * bzrlib/builtins.py:
      (cmd_selftest): Add a --load-list option.
    modified:
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
      bzrlib/tests/blackbox/test_selftest.py test_selftest.py-20060123024542-01c5f1bbcb596d78
      bzrlib/tests/test_selftest.py  test_selftest.py-20051202044319-c110a115d8c0456a
    ------------------------------------------------------------
    revno: 3193.1.7
    revision-id:v.ladeuil+lp at free.fr-20080121101622-pj98frqla59g5olb
    parent: v.ladeuil+lp at free.fr-20080120225939-i38w6p3mgfkr53mo
    committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
    branch nick: selftest
    timestamp: Mon 2008-01-21 11:16:22 +0100
    message:
      Load test id list from a text file.
      
      * bzrlib/tests/test_selftest.py:
      (TestLoadTestIdList): Test loading test id lists.
      
      * bzrlib/tests/__init__.py:
      (load_test_id_list): Load a test id list from a text file.
    modified:
      bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
      bzrlib/tests/test_selftest.py  test_selftest.py-20051202044319-c110a115d8c0456a
    ------------------------------------------------------------
    revno: 3193.1.6
    revision-id:v.ladeuil+lp at free.fr-20080120225939-i38w6p3mgfkr53mo
    parent: v.ladeuil+lp at free.fr-20080120204831-y36y3qprboygeb4a
    committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
    branch nick: selftest
    timestamp: Sun 2008-01-20 23:59:39 +0100
    message:
      Filter the whole test suite.
      
      * bzrlib/tests/__init__.py:
      (test_suite): Add a new 'keep_only' parameter listing the wanted
      test ids.
      
      * bzrlib/tests/test_selftest.py:
      (TestTestIdListFilter): Add tests filtering the whole test suite.
    modified:
      bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
      bzrlib/tests/test_selftest.py  test_selftest.py-20051202044319-c110a115d8c0456a
    ------------------------------------------------------------
    revno: 3193.1.5
    revision-id:v.ladeuil+lp at free.fr-20080120204831-y36y3qprboygeb4a
    parent: v.ladeuil+lp at free.fr-20080120174523-n84kq5xsin1vualx
    committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
    branch nick: selftest
    timestamp: Sun 2008-01-20 21:48:31 +0100
    message:
      Add helper method to get only listed tests from a module test suite.
      
      * bzrlib/tests/test_selftest.py:
      (TestTestIdListFilter): Add tests for filtering helper method
      for_module_and_below.
      
      * bzrlib/tests/__init__.py:
      (TestIdListFilter.for_module_and_below): Helper to filter module
      test suite retaining only the listed tests.
    modified:
      bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
      bzrlib/tests/test_selftest.py  test_selftest.py-20051202044319-c110a115d8c0456a
    ------------------------------------------------------------
    revno: 3193.1.4
    revision-id:v.ladeuil+lp at free.fr-20080120174523-n84kq5xsin1vualx
    parent: v.ladeuil+lp at free.fr-20080120101950-dj7a3l2vdb9w9yxc
    committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
    branch nick: selftest
    timestamp: Sun 2008-01-20 18:45:23 +0100
    message:
      Make TestTestIdListFilter aware that a test exists for a module or one of
      its sub modules.
      
      * bzrlib/tests/test_selftest.py:
      (TestTestIdListFilter): Some refactoring, some fixes, add new
      tests for get_tests_under and is_module_name_used.
      
      * bzrlib/tests/__init__.py:
      (TestIdListFilter): Fix typo, thks Jelmer.
      (TestIdListFilter.__init__): Build module hierarchies for fast
      access.
      (TestIdListFilter.get_tests): Renamed from module_tests.
      (TestIdListFilter.get_tests_under): Get module tests and all sub
      module tests.
      (TestIdListFilter.is_module_name_used): Is there a test for a
      module or one of its sub modules.
    modified:
      bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
      bzrlib/tests/test_selftest.py  test_selftest.py-20051202044319-c110a115d8c0456a
    ------------------------------------------------------------
    revno: 3193.1.3
    revision-id:v.ladeuil+lp at free.fr-20080120101950-dj7a3l2vdb9w9yxc
    parent: v.ladeuil+lp at free.fr-20080119101219-gjdsba7mxzyhkjhy
    committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
    branch nick: selftest
    timestamp: Sun 2008-01-20 11:19:50 +0100
    message:
      Create a TestIdListFilter helper object to make testing easier.
      
      * bzrlib/tests/__init__.py:
      (TestIdListFilter): Use split_test_list_by_module as a constructor
      and delete it.
      
      * bzrlib/tests/test_selftest.py:
      (TestSplitTestListByModules): Refactor the tests to use a
      TestIdListFilter helper object.
    modified:
      bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
      bzrlib/tests/test_selftest.py  test_selftest.py-20051202044319-c110a115d8c0456a
    ------------------------------------------------------------
    revno: 3193.1.2
    revision-id:v.ladeuil+lp at free.fr-20080119101219-gjdsba7mxzyhkjhy
    parent: v.ladeuil+lp at free.fr-20080118172031-5npzafmxac8pvq2v
    committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
    branch nick: selftest
    timestamp: Sat 2008-01-19 11:12:19 +0100
    message:
      Add condition_id_in_list and filter_suite_by_id_list capabilities.
      
      * bzrlib/tests/test_selftest.py:
      (TestSelftestFiltering.test_condition_id_in_list,
      TestSelftestFiltering.test_filter_suite_by_id_list): Tests for
      filtering test suite by test id.
      
      * bzrlib/tests/__init__.py:
      (filter_suite_by_id_list, condition_id_in_list): New test
      filtering helpers to select tests by their id.
    modified:
      bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
      bzrlib/tests/test_selftest.py  test_selftest.py-20051202044319-c110a115d8c0456a
    ------------------------------------------------------------
    revno: 3193.1.1
    revision-id:v.ladeuil+lp at free.fr-20080118172031-5npzafmxac8pvq2v
    parent: pqm at pqm.ubuntu.com-20080118055224-sskoia4bcpxd8wzu
    committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
    branch nick: selftest
    timestamp: Fri 2008-01-18 18:20:31 +0100
    message:
      Helper to filter test suite building by module when loading a list.
      
      * bzrlib/tests/__init__.py:
      (split_test_list_by_module): Split test name list by module.
      
      * bzrlib/tests/test_selftest.py:
      (TestSplitTestListByModules): Test plitting a test names list by
      modules.
    modified:
      bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
      bzrlib/tests/test_selftest.py  test_selftest.py-20051202044319-c110a115d8c0456a
=== modified file 'NEWS'
--- a/NEWS	2008-01-23 01:58:28 +0000
+++ b/NEWS	2008-01-23 16:25:18 +0000
@@ -61,6 +61,12 @@
     * Classes implementing Merge types like Merge3Merger must now accept (and
       honour) a do_merge flag in their constructor.  (Aaron Bentley)
 
+  TESTING:
+
+   * selftest now accepts --load-list <file> to load a test id list. This
+     speeds up running the test suite on a limited set of tests.
+     (Vincent Ladeuil)
+
   INTERNALS:
 
     * Add a new method ``get_result`` to graph search objects. The resulting

=== modified file 'bzrlib/builtins.py'
--- a/bzrlib/builtins.py	2008-01-21 00:46:32 +0000
+++ b/bzrlib/builtins.py	2008-01-23 16:25:18 +0000
@@ -2598,6 +2598,8 @@
                                  ' expression.'),
                      Option('strict', help='Fail on missing dependencies or '
                             'known failures.'),
+                     Option('load-list', type=str, argname='TESTLISTFILE',
+                            help='Load a test id list from a text file.'),
                      ]
     encoding_type = 'replace'
 
@@ -2605,7 +2607,8 @@
             transport=None, benchmark=None,
             lsprof_timed=None, cache_dir=None,
             first=False, list_only=False,
-            randomize=None, exclude=None, strict=False):
+            randomize=None, exclude=None, strict=False,
+            load_list=None):
         import bzrlib.ui
         from bzrlib.tests import selftest
         import bzrlib.benchmarks as benchmarks
@@ -2647,6 +2650,7 @@
                               random_seed=randomize,
                               exclude_pattern=exclude,
                               strict=strict,
+                              load_list=load_list,
                               )
         finally:
             if benchfile is not None:

=== modified file 'bzrlib/doc/api/__init__.py'
--- a/bzrlib/doc/api/__init__.py	2006-10-05 05:37:25 +0000
+++ b/bzrlib/doc/api/__init__.py	2008-01-21 14:49:18 +0000
@@ -26,7 +26,9 @@
 
 import doctest
 import os
-    
+
+from bzrlib import tests
+
 def test_suite():
     dir_ = os.path.dirname(__file__)
     if os.path.isdir(dir_):
@@ -35,4 +37,12 @@
         candidates = []
     scripts = [candidate for candidate in candidates
                if candidate.endswith('.txt')]
-    return doctest.DocFileSuite(*scripts)
+    suite = doctest.DocFileSuite(*scripts)
+    # DocFileCase reduces the test id to the base name of the tested file, we
+    # want the module to appears there.
+    for t in tests.iter_suite_tests(suite):
+        def make_new_test_id():
+            new_id = '%s(%s)' % ( __name__, t)
+            return lambda: new_id
+        t.id = make_new_test_id()
+    return suite

=== modified file 'bzrlib/tests/__init__.py'
--- a/bzrlib/tests/__init__.py	2008-01-21 00:46:32 +0000
+++ b/bzrlib/tests/__init__.py	2008-01-23 16:25:18 +0000
@@ -2260,6 +2260,17 @@
     return condition
 
 
+def condition_id_in_list(id_list):
+    """Create a condition filter which verify that test's id in a list.
+    
+    :param name: A TestIdList object.
+    :return: A callable that returns True if the test's id appears in the list.
+    """
+    def condition(test):
+        return id_list.test_in(test.id())
+    return condition
+
+
 def exclude_tests_by_condition(suite, condition):
     """Create a test suite which excludes some tests from suite.
 
@@ -2323,6 +2334,18 @@
     return result_suite
 
 
+def filter_suite_by_id_list(suite, test_id_list):
+    """Create a test suite by filtering another one.
+
+    :param suite: The source suite.
+    :param test_id_list: A list of the test ids to keep as strings.
+    :returns: the newly created suite
+    """
+    condition = condition_id_in_list(test_id_list)
+    result_suite = filter_suite_by_condition(suite, condition)
+    return result_suite
+
+
 def exclude_tests_by_re(suite, pattern):
     """Create a test suite which excludes some tests from suite.
 
@@ -2485,6 +2508,7 @@
              random_seed=None,
              exclude_pattern=None,
              strict=False,
+             load_list=None,
              ):
     """Run the whole test suite under the enhanced runner"""
     # XXX: Very ugly way to do this...
@@ -2499,8 +2523,12 @@
     old_transport = default_transport
     default_transport = transport
     try:
+        if load_list is None:
+            keep_only = None
+        else:
+            keep_only = load_test_id_list(load_list)
         if test_suite_factory is None:
-            suite = test_suite()
+            suite = test_suite(keep_only)
         else:
             suite = test_suite_factory()
         return run_suite(suite, 'testbzr', verbose=verbose, pattern=pattern,
@@ -2517,9 +2545,78 @@
         default_transport = old_transport
 
 
-def test_suite():
+def load_test_id_list(file_name):
+    """Load a test id list from a text file.
+
+    The format is one test id by line.  No special care is taken to impose
+    strict rules, these test ids are used to filter the test suite so a test id
+    that do not match an existing test will do no harm. This allows user to add
+    comments, leave blank lines, etc.
+    """
+    test_list = []
+    try:
+        ftest = open(file_name, 'rt')
+    except IOError, e:
+        if e.errno != errno.ENOENT:
+            raise
+        else:
+            raise errors.NoSuchFile(file_name)
+
+    for test_name in ftest.readlines():
+        test_list.append(test_name.strip())
+    ftest.close()
+    return test_list
+
+
+class TestIdList(object):
+    """Test id list to filter a test suite.
+
+    Relying on the assumption that test ids are built as:
+    <module>[.<class>.<method>][(<param>+)], <module> being in python dotted
+    notation, this class offers methods to :
+    - avoid building a test suite for modules not refered to in the test list,
+    - keep only the tests listed from the module test suite.
+    """
+
+    def __init__(self, test_id_list):
+        # When a test suite needs to be filtered against us we compare test ids
+        # for equality, so a simple dict offers a quick and simple solution.
+        self.tests = dict().fromkeys(test_id_list, True)
+
+        # While unittest.TestCase have ids like:
+        # <module>.<class>.<method>[(<param+)],
+        # doctest.DocTestCase can have ids like:
+        # <module>
+        # <module>.<class>
+        # <module>.<function>
+        # <module>.<class>.<method>
+
+        # Since we can't predict a test class from its name only, we settle on
+        # a simple constraint: a test id always begins with its module name.
+
+        modules = {}
+        for test_id in test_id_list:
+            parts = test_id.split('.')
+            mod_name = parts.pop(0)
+            modules[mod_name] = True
+            for part in parts:
+                mod_name += '.' + part
+                modules[mod_name] = True
+        self.modules = modules
+
+    def is_module_name_used(self, module_name):
+        """Is there tests for the module or one of its sub modules."""
+        return self.modules.has_key(module_name)
+
+    def test_in(self, test_id):
+        return self.tests.has_key(test_id)
+
+
+def test_suite(keep_only=None):
     """Build and return TestSuite for the whole of bzrlib.
-    
+
+    :param keep_only: A list of test ids limiting the suite returned.
+
     This function can be replaced if you need to change the default test
     suite on a global basis, but it is not encouraged.
     """
@@ -2658,22 +2755,66 @@
         ]
     suite = TestUtil.TestSuite()
     loader = TestUtil.TestLoader()
-    suite.addTest(loader.loadTestsFromModuleNames(testmod_names))
+
+    if keep_only is not None:
+        id_filter = TestIdList(keep_only)
+
+    # modules building their suite with loadTestsFromModuleNames
+    if keep_only is None:
+        suite.addTest(loader.loadTestsFromModuleNames(testmod_names))
+    else:
+        for mod in [m for m in testmod_names
+                    if id_filter.is_module_name_used(m)]:
+            mod_suite = loader.loadTestsFromModuleNames([mod])
+            mod_suite = filter_suite_by_id_list(mod_suite, id_filter)
+            suite.addTest(mod_suite)
+
+    # modules adapted for transport implementations
     from bzrlib.tests.test_transport_implementations import TransportTestProviderAdapter
     adapter = TransportTestProviderAdapter()
-    adapt_modules(test_transport_implementations, adapter, loader, suite)
-    for package in packages_to_test():
-        suite.addTest(package.test_suite())
-    for m in MODULES_TO_TEST:
-        suite.addTest(loader.loadTestsFromModule(m))
-    for m in MODULES_TO_DOCTEST:
+    if keep_only is None:
+        adapt_modules(test_transport_implementations, adapter, loader, suite)
+    else:
+        for mod in [m for m in test_transport_implementations
+                    if id_filter.is_module_name_used(m)]:
+            mod_suite = TestUtil.TestSuite()
+            adapt_modules([mod], adapter, loader, mod_suite)
+            mod_suite = filter_suite_by_id_list(mod_suite, id_filter)
+            suite.addTest(mod_suite)
+
+    # modules defining their own test_suite()
+    for package in [p for p in packages_to_test()
+                    if (keep_only is None
+                        or id_filter.is_module_name_used(p.__name__))]:
+        pack_suite = package.test_suite()
+        if keep_only is not None:
+            pack_suite = filter_suite_by_id_list(pack_suite, id_filter)
+        suite.addTest(pack_suite)
+
+    # XXX: MODULES_TO_TEST should be obsoleted ?
+    for mod in [m for m in MODULES_TO_TEST
+                if keep_only is None or id_filter.is_module_name_used(m)]:
+        mod_suite = loader.loadTestsFromModule(mod)
+        if keep_only is not None:
+            mod_suite = filter_suite_by_id_list(mod_suite, id_filter)
+        suite.addTest(mod_suite)
+
+    for mod in MODULES_TO_DOCTEST:
         try:
-            suite.addTest(doctest.DocTestSuite(m))
+            doc_suite = doctest.DocTestSuite(mod)
         except ValueError, e:
-            print '**failed to get doctest for: %s\n%s' %(m,e)
+            print '**failed to get doctest for: %s\n%s' % (mod, e)
             raise
+        if keep_only is not None:
+            # DocTests may use ids which doesn't contain the module name
+            doc_suite = filter_suite_by_id_list(doc_suite, id_filter)
+        suite.addTest(doc_suite)
+
     default_encoding = sys.getdefaultencoding()
-    for name, plugin in bzrlib.plugin.plugins().items():
+    for name, plugin in  [(n, p) for (n, p) in bzrlib.plugin.plugins().items()
+                          if (keep_only is None
+                              or id_filter.is_module_name_used(
+                p.module.__name__))]:
         try:
             plugin_suite = plugin.test_suite()
         except ImportError, e:
@@ -2681,6 +2822,9 @@
                 'Unable to test plugin "%s": %s', name, e)
         else:
             if plugin_suite is not None:
+                if keep_only is not None:
+                    plugin_suite = filter_suite_by_id_list(plugin_suite,
+                                                           id_filter)
                 suite.addTest(plugin_suite)
         if default_encoding != sys.getdefaultencoding():
             bzrlib.trace.warning(

=== modified file 'bzrlib/tests/blackbox/test_selftest.py'
--- a/bzrlib/tests/blackbox/test_selftest.py	2007-12-24 10:31:24 +0000
+++ b/bzrlib/tests/blackbox/test_selftest.py	2008-01-21 10:51:02 +0000
@@ -558,3 +558,20 @@
             out_rand2.splitlines(), 2)
         self.assertEqual(tests_rand, tests_rand2)
 
+
+class TestSelftestWithIdList(TestCaseInTempDir):
+
+    def test_load_list(self):
+        # We don't want to call selftest for the whole suite, so we start with
+        # a reduced list.
+        test_list_fname = 'test.list'
+        fl = open(test_list_fname, 'wt')
+        fl.write('%s\n' % self.id())
+        fl.close()
+        out, err = self.run_bzr(
+            ['selftest', '--load-list', test_list_fname, '--list'])
+        self.assertContainsRe(out, "Listed 1 test in")
+
+    def test_load_unknown(self):
+        out, err = self.run_bzr('selftest --load-list I_do_not_exist ',
+                                retcode=3)

=== modified file 'bzrlib/tests/test_selftest.py'
--- a/bzrlib/tests/test_selftest.py	2008-01-03 19:12:30 +0000
+++ b/bzrlib/tests/test_selftest.py	2008-01-21 15:16:38 +0000
@@ -32,6 +32,7 @@
     osutils,
     repository,
     symbol_versioning,
+    tests,
     )
 from bzrlib.progress import _BaseProgressBar
 from bzrlib.repofmt import weaverepo
@@ -1682,6 +1683,17 @@
             condition_id_re('test_condition_id_re'))
         self.assertEqual([test_name], self._test_ids(filtered_suite))
 
+    def test_condition_id_in_list(self):
+        test_names = ['bzrlib.tests.test_selftest.TestSelftestFiltering.'
+                      'test_condition_id_in_list']
+        id_list = tests.TestIdList(test_names)
+        filtered_suite = filter_suite_by_condition(
+            self.suite, tests.condition_id_in_list(id_list))
+        my_pattern = 'TestSelftestFiltering.*test_condition_id_in_list'
+        re_filtered = filter_suite_by_re(self.suite, my_pattern)
+        self.assertEqual(self._test_ids(re_filtered),
+                         self._test_ids(filtered_suite))
+
     def test_condition_isinstance(self):
         filtered_suite = filter_suite_by_condition(self.suite,
             condition_isinstance(self.__class__))
@@ -1727,6 +1739,17 @@
         self.assertEqual(filtered_names, ['bzrlib.tests.test_selftest.'
             'TestSelftestFiltering.test_filter_suite_by_re'])
 
+    def test_filter_suite_by_id_list(self):
+        test_list = ['bzrlib.tests.test_selftest.'
+                     'TestSelftestFiltering.test_filter_suite_by_id_list']
+        filtered_suite = tests.filter_suite_by_id_list(
+            self.suite, tests.TestIdList(test_list))
+        filtered_names = self._test_ids(filtered_suite)
+        self.assertEqual(
+            filtered_names,
+            ['bzrlib.tests.test_selftest.'
+             'TestSelftestFiltering.test_filter_suite_by_id_list'])
+
     def test_preserve_input(self):
         # NB: Surely this is something in the stdlib to do this?
         self.assertTrue(self.suite is preserve_input(self.suite))
@@ -1842,3 +1865,112 @@
         module.__class__.load_tests = load_tests
         self.assertEqual(2, loader.loadTestsFromModule(module).countTestCases())
 
+
+class TestTestIdList(tests.TestCase):
+
+    def _create_id_list(self, test_list):
+        return tests.TestIdList(test_list)
+
+    def _create_suite(self, test_id_list):
+
+        class Stub(TestCase):
+            def test_foo(self):
+                pass
+
+        def _create_test_id(id):
+            return lambda: id
+
+        suite = TestUtil.TestSuite()
+        for id in test_id_list:
+            t  = Stub('test_foo')
+            t.id = _create_test_id(id)
+            suite.addTest(t)
+        return suite
+
+    def _test_ids(self, test_suite):
+        """Get the ids for the tests in a test suite."""
+        return [t.id() for t in iter_suite_tests(test_suite)]
+
+    def test_empty_list(self):
+        id_list = self._create_id_list([])
+        self.assertEquals({}, id_list.tests)
+        self.assertEquals({}, id_list.modules)
+
+    def test_valid_list(self):
+        id_list = self._create_id_list(
+            ['mod1.cl1.meth1', 'mod1.cl1.meth2',
+             'mod1.func1', 'mod1.cl2.meth2',
+             'mod1.submod1',
+             'mod1.submod2.cl1.meth1', 'mod1.submod2.cl2.meth2',
+             ])
+        self.assertTrue(id_list.is_module_name_used('mod1'))
+        self.assertTrue(id_list.is_module_name_used('mod1.submod1'))
+        self.assertTrue(id_list.is_module_name_used('mod1.submod2'))
+        self.assertTrue(id_list.test_in('mod1.cl1.meth1'))
+        self.assertTrue(id_list.test_in('mod1.submod1'))
+        self.assertTrue(id_list.test_in('mod1.func1'))
+
+    def test_bad_chars_in_params(self):
+        id_list = self._create_id_list(['mod1.cl1.meth1(xx.yy)'])
+        self.assertTrue(id_list.is_module_name_used('mod1'))
+        self.assertTrue(id_list.test_in('mod1.cl1.meth1(xx.yy)'))
+
+    def test_module_used(self):
+        id_list = self._create_id_list(['mod.class.meth'])
+        self.assertTrue(id_list.is_module_name_used('mod'))
+        self.assertTrue(id_list.is_module_name_used('mod.class'))
+        self.assertTrue(id_list.is_module_name_used('mod.class.meth'))
+
+    def test_test_suite(self):
+        # This test is slow, so we do a single test with one test in each
+        # category
+        test_list = [
+            # testmod_names
+            'bzrlib.tests.test_selftest.TestTestIdList.test_test_suite',
+            # transport implementations
+            'bzrlib.tests.test_transport_implementations.TransportTests'
+            '.test_abspath(LocalURLServer)',
+            # packages_to_test()
+            'bzrlib.tests.blackbox.test_branch.TestBranch.test_branch',
+            # MODULES_TO_DOCTEST
+            'bzrlib.timestamp.format_highres_date',
+            # plugins can't be tested that way since selftest may be run with
+            # --no-plugins
+            ]
+        suite = tests.test_suite(test_list)
+        self.assertEquals(test_list, self._test_ids(suite))
+
+
+class TestLoadTestIdList(tests.TestCaseInTempDir):
+
+    def _create_test_list_file(self, file_name, content):
+        fl = open(file_name, 'wt')
+        fl.write(content)
+        fl.close()
+
+    def test_load_unknown(self):
+        self.assertRaises(errors.NoSuchFile,
+                          tests.load_test_id_list, 'i_do_not_exist')
+
+    def test_load_test_list(self):
+        test_list_fname = 'test.list'
+        self._create_test_list_file(test_list_fname,
+                                    'mod1.cl1.meth1\nmod2.cl2.meth2\n')
+        tlist = tests.load_test_id_list(test_list_fname)
+        self.assertEquals(2, len(tlist))
+        self.assertEquals('mod1.cl1.meth1', tlist[0])
+        self.assertEquals('mod2.cl2.meth2', tlist[1])
+
+    def test_load_dirty_file(self):
+        test_list_fname = 'test.list'
+        self._create_test_list_file(test_list_fname,
+                                    '  mod1.cl1.meth1\n\nmod2.cl2.meth2  \n'
+                                    'bar baz\n')
+        tlist = tests.load_test_id_list(test_list_fname)
+        self.assertEquals(4, len(tlist))
+        self.assertEquals('mod1.cl1.meth1', tlist[0])
+        self.assertEquals('', tlist[1])
+        self.assertEquals('mod2.cl2.meth2', tlist[2])
+        self.assertEquals('bar baz', tlist[3])
+
+




More information about the bazaar-commits mailing list