/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/__init__.py

merge trunk and resolve conflicts to cleanup submission

Show diffs side-by-side

added added

removed removed

Lines of Context:
53
53
from bzrlib import (
54
54
    branchbuilder,
55
55
    bzrdir,
 
56
    chk_map,
56
57
    config,
57
58
    debug,
58
59
    errors,
297
298
        Called from the TestCase run() method when the test
298
299
        fails with an unexpected error.
299
300
        """
300
 
        self._testConcluded(test)
301
 
        if isinstance(err[1], TestNotApplicable):
302
 
            return self._addNotApplicable(test, err)
303
 
        elif isinstance(err[1], UnavailableFeature):
304
 
            return self.addNotSupported(test, err[1].args[0])
305
 
        else:
306
 
            self._post_mortem()
307
 
            unittest.TestResult.addError(self, test, err)
308
 
            self.error_count += 1
309
 
            self.report_error(test, err)
310
 
            if self.stop_early:
311
 
                self.stop()
312
 
            self._cleanupLogFile(test)
 
301
        self._post_mortem()
 
302
        unittest.TestResult.addError(self, test, err)
 
303
        self.error_count += 1
 
304
        self.report_error(test, err)
 
305
        if self.stop_early:
 
306
            self.stop()
 
307
        self._cleanupLogFile(test)
313
308
 
314
309
    def addFailure(self, test, err):
315
310
        """Tell result that test failed.
317
312
        Called from the TestCase run() method when the test
318
313
        fails because e.g. an assert() method failed.
319
314
        """
320
 
        self._testConcluded(test)
321
 
        if isinstance(err[1], KnownFailure):
322
 
            return self._addKnownFailure(test, err)
323
 
        else:
324
 
            self._post_mortem()
325
 
            unittest.TestResult.addFailure(self, test, err)
326
 
            self.failure_count += 1
327
 
            self.report_failure(test, err)
328
 
            if self.stop_early:
329
 
                self.stop()
330
 
            self._cleanupLogFile(test)
 
315
        self._post_mortem()
 
316
        unittest.TestResult.addFailure(self, test, err)
 
317
        self.failure_count += 1
 
318
        self.report_failure(test, err)
 
319
        if self.stop_early:
 
320
            self.stop()
 
321
        self._cleanupLogFile(test)
331
322
 
332
323
    def addSuccess(self, test):
333
324
        """Tell result that test completed successfully.
334
325
 
335
326
        Called from the TestCase run()
336
327
        """
337
 
        self._testConcluded(test)
338
328
        if self._bench_history is not None:
339
329
            benchmark_time = self._extractBenchmarkTime(test)
340
330
            if benchmark_time is not None:
346
336
        unittest.TestResult.addSuccess(self, test)
347
337
        test._log_contents = ''
348
338
 
349
 
    def _testConcluded(self, test):
350
 
        """Common code when a test has finished.
351
 
 
352
 
        Called regardless of whether it succeded, failed, etc.
353
 
        """
354
 
        pass
355
 
 
356
 
    def _addKnownFailure(self, test, err):
 
339
    def addExpectedFailure(self, test, err):
357
340
        self.known_failure_count += 1
358
341
        self.report_known_failure(test, err)
359
342
 
361
344
        """The test will not be run because of a missing feature.
362
345
        """
363
346
        # this can be called in two different ways: it may be that the
364
 
        # test started running, and then raised (through addError)
 
347
        # test started running, and then raised (through requireFeature)
365
348
        # UnavailableFeature.  Alternatively this method can be called
366
 
        # while probing for features before running the tests; in that
367
 
        # case we will see startTest and stopTest, but the test will never
368
 
        # actually run.
 
349
        # while probing for features before running the test code proper; in
 
350
        # that case we will see startTest and stopTest, but the test will
 
351
        # never actually run.
369
352
        self.unsupported.setdefault(str(feature), 0)
370
353
        self.unsupported[str(feature)] += 1
371
354
        self.report_unsupported(test, feature)
375
358
        self.skip_count += 1
376
359
        self.report_skip(test, reason)
377
360
 
378
 
    def _addNotApplicable(self, test, skip_excinfo):
379
 
        if isinstance(skip_excinfo[1], TestNotApplicable):
380
 
            self.not_applicable_count += 1
381
 
            self.report_not_applicable(test, skip_excinfo)
382
 
        try:
383
 
            test.tearDown()
384
 
        except KeyboardInterrupt:
385
 
            raise
386
 
        except:
387
 
            self.addError(test, test.exc_info())
388
 
        else:
389
 
            # seems best to treat this as success from point-of-view of unittest
390
 
            # -- it actually does nothing so it barely matters :)
391
 
            unittest.TestResult.addSuccess(self, test)
392
 
            test._log_contents = ''
 
361
    def addNotApplicable(self, test, reason):
 
362
        self.not_applicable_count += 1
 
363
        self.report_not_applicable(test, reason)
393
364
 
394
365
    def printErrorList(self, flavour, errors):
395
366
        for test, err in errors:
534
505
    def report_skip(self, test, reason):
535
506
        pass
536
507
 
537
 
    def report_not_applicable(self, test, skip_excinfo):
 
508
    def report_not_applicable(self, test, reason):
538
509
        pass
539
510
 
540
511
    def report_unsupported(self, test, feature):
605
576
        self.stream.writeln(' SKIP %s\n%s'
606
577
                % (self._testTimeString(test), reason))
607
578
 
608
 
    def report_not_applicable(self, test, skip_excinfo):
609
 
        self.stream.writeln('  N/A %s\n%s'
610
 
                % (self._testTimeString(test),
611
 
                   self._error_summary(skip_excinfo)))
 
579
    def report_not_applicable(self, test, reason):
 
580
        self.stream.writeln('  N/A %s\n    %s'
 
581
                % (self._testTimeString(test), reason))
612
582
 
613
583
    def report_unsupported(self, test, feature):
614
584
        """test cannot be run because feature is missing."""
716
686
class UnavailableFeature(Exception):
717
687
    """A feature required for this test was not available.
718
688
 
 
689
    This can be considered a specialised form of SkippedTest.
 
690
 
719
691
    The feature should be used to construct the exception.
720
692
    """
721
693
 
1147
1119
        :raises AssertionError: If the expected and actual stat values differ
1148
1120
            other than by atime.
1149
1121
        """
1150
 
        self.assertEqual(expected.st_size, actual.st_size)
1151
 
        self.assertEqual(expected.st_mtime, actual.st_mtime)
1152
 
        self.assertEqual(expected.st_ctime, actual.st_ctime)
1153
 
        self.assertEqual(expected.st_dev, actual.st_dev)
1154
 
        self.assertEqual(expected.st_ino, actual.st_ino)
1155
 
        self.assertEqual(expected.st_mode, actual.st_mode)
 
1122
        self.assertEqual(expected.st_size, actual.st_size,
 
1123
                         'st_size did not match')
 
1124
        self.assertEqual(expected.st_mtime, actual.st_mtime,
 
1125
                         'st_mtime did not match')
 
1126
        self.assertEqual(expected.st_ctime, actual.st_ctime,
 
1127
                         'st_ctime did not match')
 
1128
        if sys.platform != 'win32':
 
1129
            # On Win32 both 'dev' and 'ino' cannot be trusted. In python2.4 it
 
1130
            # is 'dev' that varies, in python 2.5 (6?) it is st_ino that is
 
1131
            # odd. Regardless we shouldn't actually try to assert anything
 
1132
            # about their values
 
1133
            self.assertEqual(expected.st_dev, actual.st_dev,
 
1134
                             'st_dev did not match')
 
1135
            self.assertEqual(expected.st_ino, actual.st_ino,
 
1136
                             'st_ino did not match')
 
1137
        self.assertEqual(expected.st_mode, actual.st_mode,
 
1138
                         'st_mode did not match')
1156
1139
 
1157
1140
    def assertLength(self, length, obj_with_len):
1158
1141
        """Assert that obj_with_len is of length length."""
1545
1528
            'BZR_PROGRESS_BAR': None,
1546
1529
            'BZR_LOG': None,
1547
1530
            'BZR_PLUGIN_PATH': None,
 
1531
            'BZR_CONCURRENCY': None,
1548
1532
            # Make sure that any text ui tests are consistent regardless of
1549
1533
            # the environment the test case is run in; you may want tests that
1550
1534
            # test other combinations.  'dumb' is a reasonable guess for tests
1599
1583
    def _do_skip(self, result, reason):
1600
1584
        addSkip = getattr(result, 'addSkip', None)
1601
1585
        if not callable(addSkip):
1602
 
            result.addError(self, sys.exc_info())
 
1586
            result.addSuccess(result)
1603
1587
        else:
1604
1588
            addSkip(self, reason)
1605
1589
 
 
1590
    def _do_known_failure(self, result):
 
1591
        err = sys.exc_info()
 
1592
        addExpectedFailure = getattr(result, 'addExpectedFailure', None)
 
1593
        if addExpectedFailure is not None:
 
1594
            addExpectedFailure(self, err)
 
1595
        else:
 
1596
            result.addSuccess(self)
 
1597
 
 
1598
    def _do_not_applicable(self, result, e):
 
1599
        if not e.args:
 
1600
            reason = 'No reason given'
 
1601
        else:
 
1602
            reason = e.args[0]
 
1603
        addNotApplicable = getattr(result, 'addNotApplicable', None)
 
1604
        if addNotApplicable is not None:
 
1605
            result.addNotApplicable(self, reason)
 
1606
        else:
 
1607
            self._do_skip(result, reason)
 
1608
 
 
1609
    def _do_unsupported_or_skip(self, result, reason):
 
1610
        addNotSupported = getattr(result, 'addNotSupported', None)
 
1611
        if addNotSupported is not None:
 
1612
            result.addNotSupported(self, reason)
 
1613
        else:
 
1614
            self._do_skip(result, reason)
 
1615
 
1606
1616
    def run(self, result=None):
1607
1617
        if result is None: result = self.defaultTestResult()
 
1618
        result.startTest(self)
 
1619
        try:
 
1620
            self._run(result)
 
1621
            return result
 
1622
        finally:
 
1623
            result.stopTest(self)
 
1624
 
 
1625
    def _run(self, result):
1608
1626
        for feature in getattr(self, '_test_needs_features', []):
1609
1627
            if not feature.available():
1610
 
                result.startTest(self)
1611
 
                if getattr(result, 'addNotSupported', None):
1612
 
                    result.addNotSupported(self, feature)
1613
 
                else:
1614
 
                    result.addSuccess(self)
1615
 
                result.stopTest(self)
1616
 
                return result
 
1628
                return self._do_unsupported_or_skip(result, feature)
1617
1629
        try:
 
1630
            absent_attr = object()
 
1631
            # Python 2.5
 
1632
            method_name = getattr(self, '_testMethodName', absent_attr)
 
1633
            if method_name is absent_attr:
 
1634
                # Python 2.4
 
1635
                method_name = getattr(self, '_TestCase__testMethodName')
 
1636
            testMethod = getattr(self, method_name)
1618
1637
            try:
1619
 
                result.startTest(self)
1620
 
                absent_attr = object()
1621
 
                # Python 2.5
1622
 
                method_name = getattr(self, '_testMethodName', absent_attr)
1623
 
                if method_name is absent_attr:
1624
 
                    # Python 2.4
1625
 
                    method_name = getattr(self, '_TestCase__testMethodName')
1626
 
                testMethod = getattr(self, method_name)
1627
 
                try:
1628
 
                    try:
1629
 
                        self.setUp()
1630
 
                        if not self._bzr_test_setUp_run:
1631
 
                            self.fail(
1632
 
                                "test setUp did not invoke "
1633
 
                                "bzrlib.tests.TestCase's setUp")
1634
 
                    except KeyboardInterrupt:
1635
 
                        self._runCleanups()
1636
 
                        raise
1637
 
                    except TestSkipped, e:
1638
 
                        self._do_skip(result, e.args[0])
1639
 
                        self.tearDown()
1640
 
                        return result
1641
 
                    except:
1642
 
                        result.addError(self, sys.exc_info())
1643
 
                        self._runCleanups()
1644
 
                        return result
1645
 
 
 
1638
                try:
 
1639
                    self.setUp()
 
1640
                    if not self._bzr_test_setUp_run:
 
1641
                        self.fail(
 
1642
                            "test setUp did not invoke "
 
1643
                            "bzrlib.tests.TestCase's setUp")
 
1644
                except KeyboardInterrupt:
 
1645
                    self._runCleanups()
 
1646
                    raise
 
1647
                except KnownFailure:
 
1648
                    self._do_known_failure(result)
 
1649
                    self.tearDown()
 
1650
                    return
 
1651
                except TestNotApplicable, e:
 
1652
                    self._do_not_applicable(result, e)
 
1653
                    self.tearDown()
 
1654
                    return
 
1655
                except TestSkipped, e:
 
1656
                    self._do_skip(result, e.args[0])
 
1657
                    self.tearDown()
 
1658
                    return result
 
1659
                except UnavailableFeature, e:
 
1660
                    self._do_unsupported_or_skip(result, e.args[0])
 
1661
                    self.tearDown()
 
1662
                    return
 
1663
                except:
 
1664
                    result.addError(self, sys.exc_info())
 
1665
                    self._runCleanups()
 
1666
                    return result
 
1667
 
 
1668
                ok = False
 
1669
                try:
 
1670
                    testMethod()
 
1671
                    ok = True
 
1672
                except KnownFailure:
 
1673
                    self._do_known_failure(result)
 
1674
                except self.failureException:
 
1675
                    result.addFailure(self, sys.exc_info())
 
1676
                except TestNotApplicable, e:
 
1677
                    self._do_not_applicable(result, e)
 
1678
                except TestSkipped, e:
 
1679
                    if not e.args:
 
1680
                        reason = "No reason given."
 
1681
                    else:
 
1682
                        reason = e.args[0]
 
1683
                    self._do_skip(result, reason)
 
1684
                except UnavailableFeature, e:
 
1685
                    self._do_unsupported_or_skip(result, e.args[0])
 
1686
                except KeyboardInterrupt:
 
1687
                    self._runCleanups()
 
1688
                    raise
 
1689
                except:
 
1690
                    result.addError(self, sys.exc_info())
 
1691
 
 
1692
                try:
 
1693
                    self.tearDown()
 
1694
                    if not self._bzr_test_tearDown_run:
 
1695
                        self.fail(
 
1696
                            "test tearDown did not invoke "
 
1697
                            "bzrlib.tests.TestCase's tearDown")
 
1698
                except KeyboardInterrupt:
 
1699
                    self._runCleanups()
 
1700
                    raise
 
1701
                except:
 
1702
                    result.addError(self, sys.exc_info())
 
1703
                    self._runCleanups()
1646
1704
                    ok = False
1647
 
                    try:
1648
 
                        testMethod()
1649
 
                        ok = True
1650
 
                    except self.failureException:
1651
 
                        result.addFailure(self, sys.exc_info())
1652
 
                    except TestSkipped, e:
1653
 
                        if not e.args:
1654
 
                            reason = "No reason given."
1655
 
                        else:
1656
 
                            reason = e.args[0]
1657
 
                        self._do_skip(result, reason)
1658
 
                    except KeyboardInterrupt:
1659
 
                        self._runCleanups()
1660
 
                        raise
1661
 
                    except:
1662
 
                        result.addError(self, sys.exc_info())
1663
 
 
1664
 
                    try:
1665
 
                        self.tearDown()
1666
 
                        if not self._bzr_test_tearDown_run:
1667
 
                            self.fail(
1668
 
                                "test tearDown did not invoke "
1669
 
                                "bzrlib.tests.TestCase's tearDown")
1670
 
                    except KeyboardInterrupt:
1671
 
                        self._runCleanups()
1672
 
                        raise
1673
 
                    except:
1674
 
                        result.addError(self, sys.exc_info())
1675
 
                        self._runCleanups()
1676
 
                        ok = False
1677
 
                    if ok: result.addSuccess(self)
1678
 
                finally:
1679
 
                    result.stopTest(self)
 
1705
                if ok: result.addSuccess(self)
1680
1706
                return result
1681
 
            except TestNotApplicable:
1682
 
                # Not moved from the result [yet].
1683
 
                self._runCleanups()
1684
 
                raise
1685
1707
            except KeyboardInterrupt:
1686
1708
                self._runCleanups()
1687
1709
                raise
1795
1817
 
1796
1818
    def _run_bzr_core(self, args, retcode, encoding, stdin,
1797
1819
            working_dir):
 
1820
        # Clear chk_map page cache, because the contents are likely to mask
 
1821
        # locking errors.
 
1822
        chk_map.clear_cache()
1798
1823
        if encoding is None:
1799
1824
            encoding = osutils.get_user_encoding()
1800
1825
        stdout = StringIOWrapper()
1817
1842
            os.chdir(working_dir)
1818
1843
 
1819
1844
        try:
1820
 
            result = self.apply_redirected(ui.ui_factory.stdin,
1821
 
                stdout, stderr,
1822
 
                bzrlib.commands.run_bzr_catch_user_errors,
1823
 
                args)
 
1845
            try:
 
1846
                result = self.apply_redirected(ui.ui_factory.stdin,
 
1847
                    stdout, stderr,
 
1848
                    bzrlib.commands.run_bzr_catch_user_errors,
 
1849
                    args)
 
1850
            except KeyboardInterrupt:
 
1851
                # Reraise KeyboardInterrupt with contents of redirected stdout
 
1852
                # and stderr as arguments, for tests which are interested in
 
1853
                # stdout and stderr and are expecting the exception.
 
1854
                out = stdout.getvalue()
 
1855
                err = stderr.getvalue()
 
1856
                if out:
 
1857
                    self.log('output:\n%r', out)
 
1858
                if err:
 
1859
                    self.log('errors:\n%r', err)
 
1860
                raise KeyboardInterrupt(out, err)
1824
1861
        finally:
1825
1862
            logger.removeHandler(handler)
1826
1863
            ui.ui_factory = old_ui_factory
2374
2411
            # recreate a new one or all the followng tests will fail.
2375
2412
            # If you need to inspect its content uncomment the following line
2376
2413
            # import pdb; pdb.set_trace()
2377
 
            _rmtree_temp_dir(root + '/.bzr')
 
2414
            _rmtree_temp_dir(root + '/.bzr', test_id=self.id())
2378
2415
            self._create_safety_net()
2379
2416
            raise AssertionError('%s/.bzr should not be modified' % root)
2380
2417
 
2456
2493
        return branchbuilder.BranchBuilder(branch=branch)
2457
2494
 
2458
2495
    def overrideEnvironmentForTesting(self):
2459
 
        os.environ['HOME'] = self.test_home_dir
2460
 
        os.environ['BZR_HOME'] = self.test_home_dir
 
2496
        test_home_dir = self.test_home_dir
 
2497
        if isinstance(test_home_dir, unicode):
 
2498
            test_home_dir = test_home_dir.encode(sys.getfilesystemencoding())
 
2499
        os.environ['HOME'] = test_home_dir
 
2500
        os.environ['BZR_HOME'] = test_home_dir
2461
2501
 
2462
2502
    def setUp(self):
2463
2503
        super(TestCaseWithMemoryTransport, self).setUp()
2569
2609
 
2570
2610
    def deleteTestDir(self):
2571
2611
        os.chdir(TestCaseWithMemoryTransport.TEST_ROOT)
2572
 
        _rmtree_temp_dir(self.test_base_dir)
 
2612
        _rmtree_temp_dir(self.test_base_dir, test_id=self.id())
2573
2613
 
2574
2614
    def build_tree(self, shape, line_endings='binary', transport=None):
2575
2615
        """Build a test tree according to a pattern.
3242
3282
    concurrency = osutils.local_concurrency()
3243
3283
    result = []
3244
3284
    from subunit import TestProtocolClient, ProtocolTestCase
3245
 
    try:
3246
 
        from subunit.test_results import AutoTimingTestResultDecorator
3247
 
    except ImportError:
3248
 
        AutoTimingTestResultDecorator = lambda x:x
3249
3285
    class TestInOtherProcess(ProtocolTestCase):
3250
3286
        # Should be in subunit, I think. RBC.
3251
3287
        def __init__(self, stream, pid):
3274
3310
                sys.stdin.close()
3275
3311
                sys.stdin = None
3276
3312
                stream = os.fdopen(c2pwrite, 'wb', 1)
3277
 
                subunit_result = AutoTimingTestResultDecorator(
 
3313
                subunit_result = BzrAutoTimingTestResultDecorator(
3278
3314
                    TestProtocolClient(stream))
3279
3315
                process_suite.run(subunit_result)
3280
3316
            finally:
3317
3353
        if not os.path.isfile(bzr_path):
3318
3354
            # We are probably installed. Assume sys.argv is the right file
3319
3355
            bzr_path = sys.argv[0]
 
3356
        bzr_path = [bzr_path]
 
3357
        if sys.platform == "win32":
 
3358
            # if we're on windows, we can't execute the bzr script directly
 
3359
            bzr_path = [sys.executable] + bzr_path
3320
3360
        fd, test_list_file_name = tempfile.mkstemp()
3321
3361
        test_list_file = os.fdopen(fd, 'wb', 1)
3322
3362
        for test in process_tests:
3323
3363
            test_list_file.write(test.id() + '\n')
3324
3364
        test_list_file.close()
3325
3365
        try:
3326
 
            argv = [bzr_path, 'selftest', '--load-list', test_list_file_name,
 
3366
            argv = bzr_path + ['selftest', '--load-list', test_list_file_name,
3327
3367
                '--subunit']
3328
3368
            if '--no-plugins' in sys.argv:
3329
3369
                argv.append('--no-plugins')
3382
3422
    def addFailure(self, test, err):
3383
3423
        known = self._error_looks_like('KnownFailure: ', err)
3384
3424
        if known is not None:
3385
 
            self.result._addKnownFailure(test, [KnownFailure,
3386
 
                                                KnownFailure(known), None])
 
3425
            self.result.addExpectedFailure(test,
 
3426
                [KnownFailure, KnownFailure(known), None])
3387
3427
        else:
3388
3428
            self.result.addFailure(test, err)
3389
3429
 
3404
3444
        return value
3405
3445
 
3406
3446
 
 
3447
try:
 
3448
    from subunit.test_results import AutoTimingTestResultDecorator
 
3449
    # Expected failure should be seen as a success not a failure Once subunit
 
3450
    # provide native support for that, BZRTransformingResult and this class
 
3451
    # will become useless.
 
3452
    class BzrAutoTimingTestResultDecorator(AutoTimingTestResultDecorator):
 
3453
 
 
3454
        def addExpectedFailure(self, test, err):
 
3455
            self._before_event()
 
3456
            return self._call_maybe("addExpectedFailure", self._degrade_skip,
 
3457
                                    test, err)
 
3458
except ImportError:
 
3459
    # Let's just define a no-op decorator
 
3460
    BzrAutoTimingTestResultDecorator = lambda x:x
 
3461
 
 
3462
 
3407
3463
class ProfileResult(ForwardingResult):
3408
3464
    """Generate profiling data for all activity between start and success.
3409
3465
    
3684
3740
        'bzrlib.tests.commands',
3685
3741
        'bzrlib.tests.per_branch',
3686
3742
        'bzrlib.tests.per_bzrdir',
 
3743
        'bzrlib.tests.per_foreign_vcs',
3687
3744
        'bzrlib.tests.per_interrepository',
3688
3745
        'bzrlib.tests.per_intertree',
3689
3746
        'bzrlib.tests.per_inventory',
3726
3783
        'bzrlib.tests.test_chk_serializer',
3727
3784
        'bzrlib.tests.test_chunk_writer',
3728
3785
        'bzrlib.tests.test_clean_tree',
 
3786
        'bzrlib.tests.test_cleanup',
3729
3787
        'bzrlib.tests.test_commands',
3730
3788
        'bzrlib.tests.test_commit',
3731
3789
        'bzrlib.tests.test_commit_merge',
4079
4137
    return new_test
4080
4138
 
4081
4139
 
4082
 
def _rmtree_temp_dir(dirname):
 
4140
def _rmtree_temp_dir(dirname, test_id=None):
4083
4141
    # If LANG=C we probably have created some bogus paths
4084
4142
    # which rmtree(unicode) will fail to delete
4085
4143
    # so make sure we are using rmtree(str) to delete everything
4097
4155
        # We don't want to fail here because some useful display will be lost
4098
4156
        # otherwise. Polluting the tmp dir is bad, but not giving all the
4099
4157
        # possible info to the test runner is even worse.
 
4158
        if test_id != None:
 
4159
            ui.ui_factory.clear_term()
 
4160
            sys.stderr.write('While running: %s\n' % (test_id,))
4100
4161
        sys.stderr.write('Unable to remove testing dir %s\n%s'
4101
4162
                         % (os.path.basename(dirname), e))
4102
4163
 
4299
4360
            # Windows doesn't have os.kill, and we catch the SIGBREAK signal.
4300
4361
            # We trigger SIGBREAK via a Console api so we need ctypes to
4301
4362
            # access the function
4302
 
            if not have_ctypes:
 
4363
            try:
 
4364
                import ctypes
 
4365
            except OSError:
4303
4366
                return False
4304
4367
        return True
4305
4368
 
4382
4445
# Only define SubUnitBzrRunner if subunit is available.
4383
4446
try:
4384
4447
    from subunit import TestProtocolClient
4385
 
    try:
4386
 
        from subunit.test_results import AutoTimingTestResultDecorator
4387
 
    except ImportError:
4388
 
        AutoTimingTestResultDecorator = lambda x:x
4389
4448
    class SubUnitBzrRunner(TextTestRunner):
4390
4449
        def run(self, test):
4391
 
            result = AutoTimingTestResultDecorator(
 
4450
            result = BzrAutoTimingTestResultDecorator(
4392
4451
                TestProtocolClient(self.stream))
4393
4452
            test.run(result)
4394
4453
            return result