~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/__init__.py

merge shell-like-tests into description resolving conflicts

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):
562
533
    def report_test_start(self, test):
563
534
        self.count += 1
564
535
        name = self._shortened_test_description(test)
565
 
        # width needs space for 6 char status, plus 1 for slash, plus an
566
 
        # 11-char time string, plus a trailing blank
567
 
        # when NUMBERED_DIRS: plus 5 chars on test number, plus 1 char on space
568
 
        self.stream.write(self._ellipsize_to_right(name,
569
 
                          osutils.terminal_width()-18))
 
536
        width = osutils.terminal_width()
 
537
        if width is not None:
 
538
            # width needs space for 6 char status, plus 1 for slash, plus an
 
539
            # 11-char time string, plus a trailing blank
 
540
            # when NUMBERED_DIRS: plus 5 chars on test number, plus 1 char on
 
541
            # space
 
542
            self.stream.write(self._ellipsize_to_right(name, width-18))
 
543
        else:
 
544
            self.stream.write(name)
570
545
        self.stream.flush()
571
546
 
572
547
    def _error_summary(self, err):
601
576
        self.stream.writeln(' SKIP %s\n%s'
602
577
                % (self._testTimeString(test), reason))
603
578
 
604
 
    def report_not_applicable(self, test, skip_excinfo):
605
 
        self.stream.writeln('  N/A %s\n%s'
606
 
                % (self._testTimeString(test),
607
 
                   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))
608
582
 
609
583
    def report_unsupported(self, test, feature):
610
584
        """test cannot be run because feature is missing."""
712
686
class UnavailableFeature(Exception):
713
687
    """A feature required for this test was not available.
714
688
 
 
689
    This can be considered a specialised form of SkippedTest.
 
690
 
715
691
    The feature should be used to construct the exception.
716
692
    """
717
693
 
1143
1119
        :raises AssertionError: If the expected and actual stat values differ
1144
1120
            other than by atime.
1145
1121
        """
1146
 
        self.assertEqual(expected.st_size, actual.st_size)
1147
 
        self.assertEqual(expected.st_mtime, actual.st_mtime)
1148
 
        self.assertEqual(expected.st_ctime, actual.st_ctime)
1149
 
        self.assertEqual(expected.st_dev, actual.st_dev)
1150
 
        self.assertEqual(expected.st_ino, actual.st_ino)
1151
 
        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')
1152
1139
 
1153
1140
    def assertLength(self, length, obj_with_len):
1154
1141
        """Assert that obj_with_len is of length length."""
1541
1528
            'BZR_PROGRESS_BAR': None,
1542
1529
            'BZR_LOG': None,
1543
1530
            'BZR_PLUGIN_PATH': None,
 
1531
            'BZR_CONCURRENCY': None,
1544
1532
            # Make sure that any text ui tests are consistent regardless of
1545
1533
            # the environment the test case is run in; you may want tests that
1546
1534
            # test other combinations.  'dumb' is a reasonable guess for tests
1548
1536
            'TERM': 'dumb',
1549
1537
            'LINES': '25',
1550
1538
            'COLUMNS': '80',
 
1539
            'BZR_COLUMNS': '80',
1551
1540
            # SSH Agent
1552
1541
            'SSH_AUTH_SOCK': None,
1553
1542
            # Proxies
1594
1583
    def _do_skip(self, result, reason):
1595
1584
        addSkip = getattr(result, 'addSkip', None)
1596
1585
        if not callable(addSkip):
1597
 
            result.addError(self, sys.exc_info())
 
1586
            result.addSuccess(result)
1598
1587
        else:
1599
1588
            addSkip(self, reason)
1600
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
 
1601
1616
    def run(self, result=None):
1602
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):
1603
1626
        for feature in getattr(self, '_test_needs_features', []):
1604
1627
            if not feature.available():
1605
 
                result.startTest(self)
1606
 
                if getattr(result, 'addNotSupported', None):
1607
 
                    result.addNotSupported(self, feature)
1608
 
                else:
1609
 
                    result.addSuccess(self)
1610
 
                result.stopTest(self)
1611
 
                return result
 
1628
                return self._do_unsupported_or_skip(result, feature)
1612
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)
1613
1637
            try:
1614
 
                result.startTest(self)
1615
 
                absent_attr = object()
1616
 
                # Python 2.5
1617
 
                method_name = getattr(self, '_testMethodName', absent_attr)
1618
 
                if method_name is absent_attr:
1619
 
                    # Python 2.4
1620
 
                    method_name = getattr(self, '_TestCase__testMethodName')
1621
 
                testMethod = getattr(self, method_name)
1622
 
                try:
1623
 
                    try:
1624
 
                        self.setUp()
1625
 
                        if not self._bzr_test_setUp_run:
1626
 
                            self.fail(
1627
 
                                "test setUp did not invoke "
1628
 
                                "bzrlib.tests.TestCase's setUp")
1629
 
                    except KeyboardInterrupt:
1630
 
                        self._runCleanups()
1631
 
                        raise
1632
 
                    except TestSkipped, e:
1633
 
                        self._do_skip(result, e.args[0])
1634
 
                        self.tearDown()
1635
 
                        return result
1636
 
                    except:
1637
 
                        result.addError(self, sys.exc_info())
1638
 
                        self._runCleanups()
1639
 
                        return result
1640
 
 
 
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()
1641
1704
                    ok = False
1642
 
                    try:
1643
 
                        testMethod()
1644
 
                        ok = True
1645
 
                    except self.failureException:
1646
 
                        result.addFailure(self, sys.exc_info())
1647
 
                    except TestSkipped, e:
1648
 
                        if not e.args:
1649
 
                            reason = "No reason given."
1650
 
                        else:
1651
 
                            reason = e.args[0]
1652
 
                        self._do_skip(result, reason)
1653
 
                    except KeyboardInterrupt:
1654
 
                        self._runCleanups()
1655
 
                        raise
1656
 
                    except:
1657
 
                        result.addError(self, sys.exc_info())
1658
 
 
1659
 
                    try:
1660
 
                        self.tearDown()
1661
 
                        if not self._bzr_test_tearDown_run:
1662
 
                            self.fail(
1663
 
                                "test tearDown did not invoke "
1664
 
                                "bzrlib.tests.TestCase's tearDown")
1665
 
                    except KeyboardInterrupt:
1666
 
                        self._runCleanups()
1667
 
                        raise
1668
 
                    except:
1669
 
                        result.addError(self, sys.exc_info())
1670
 
                        self._runCleanups()
1671
 
                        ok = False
1672
 
                    if ok: result.addSuccess(self)
1673
 
                finally:
1674
 
                    result.stopTest(self)
 
1705
                if ok: result.addSuccess(self)
1675
1706
                return result
1676
 
            except TestNotApplicable:
1677
 
                # Not moved from the result [yet].
1678
 
                self._runCleanups()
1679
 
                raise
1680
1707
            except KeyboardInterrupt:
1681
1708
                self._runCleanups()
1682
1709
                raise
1790
1817
 
1791
1818
    def _run_bzr_core(self, args, retcode, encoding, stdin,
1792
1819
            working_dir):
 
1820
        # Clear chk_map page cache, because the contents are likely to mask
 
1821
        # locking errors.
 
1822
        chk_map.clear_cache()
1793
1823
        if encoding is None:
1794
1824
            encoding = osutils.get_user_encoding()
1795
1825
        stdout = StringIOWrapper()
1812
1842
            os.chdir(working_dir)
1813
1843
 
1814
1844
        try:
1815
 
            result = self.apply_redirected(ui.ui_factory.stdin,
1816
 
                stdout, stderr,
1817
 
                bzrlib.commands.run_bzr_catch_user_errors,
1818
 
                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)
1819
1861
        finally:
1820
1862
            logger.removeHandler(handler)
1821
1863
            ui.ui_factory = old_ui_factory
2369
2411
            # recreate a new one or all the followng tests will fail.
2370
2412
            # If you need to inspect its content uncomment the following line
2371
2413
            # import pdb; pdb.set_trace()
2372
 
            _rmtree_temp_dir(root + '/.bzr')
 
2414
            _rmtree_temp_dir(root + '/.bzr', test_id=self.id())
2373
2415
            self._create_safety_net()
2374
2416
            raise AssertionError('%s/.bzr should not be modified' % root)
2375
2417
 
2451
2493
        return branchbuilder.BranchBuilder(branch=branch)
2452
2494
 
2453
2495
    def overrideEnvironmentForTesting(self):
2454
 
        os.environ['HOME'] = self.test_home_dir
2455
 
        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
2456
2501
 
2457
2502
    def setUp(self):
2458
2503
        super(TestCaseWithMemoryTransport, self).setUp()
2564
2609
 
2565
2610
    def deleteTestDir(self):
2566
2611
        os.chdir(TestCaseWithMemoryTransport.TEST_ROOT)
2567
 
        _rmtree_temp_dir(self.test_base_dir)
 
2612
        _rmtree_temp_dir(self.test_base_dir, test_id=self.id())
2568
2613
 
2569
2614
    def build_tree(self, shape, line_endings='binary', transport=None):
2570
2615
        """Build a test tree according to a pattern.
3237
3282
    concurrency = osutils.local_concurrency()
3238
3283
    result = []
3239
3284
    from subunit import TestProtocolClient, ProtocolTestCase
3240
 
    try:
3241
 
        from subunit.test_results import AutoTimingTestResultDecorator
3242
 
    except ImportError:
3243
 
        AutoTimingTestResultDecorator = lambda x:x
3244
3285
    class TestInOtherProcess(ProtocolTestCase):
3245
3286
        # Should be in subunit, I think. RBC.
3246
3287
        def __init__(self, stream, pid):
3269
3310
                sys.stdin.close()
3270
3311
                sys.stdin = None
3271
3312
                stream = os.fdopen(c2pwrite, 'wb', 1)
3272
 
                subunit_result = AutoTimingTestResultDecorator(
 
3313
                subunit_result = BzrAutoTimingTestResultDecorator(
3273
3314
                    TestProtocolClient(stream))
3274
3315
                process_suite.run(subunit_result)
3275
3316
            finally:
3312
3353
        if not os.path.isfile(bzr_path):
3313
3354
            # We are probably installed. Assume sys.argv is the right file
3314
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
3315
3360
        fd, test_list_file_name = tempfile.mkstemp()
3316
3361
        test_list_file = os.fdopen(fd, 'wb', 1)
3317
3362
        for test in process_tests:
3318
3363
            test_list_file.write(test.id() + '\n')
3319
3364
        test_list_file.close()
3320
3365
        try:
3321
 
            argv = [bzr_path, 'selftest', '--load-list', test_list_file_name,
 
3366
            argv = bzr_path + ['selftest', '--load-list', test_list_file_name,
3322
3367
                '--subunit']
3323
3368
            if '--no-plugins' in sys.argv:
3324
3369
                argv.append('--no-plugins')
3377
3422
    def addFailure(self, test, err):
3378
3423
        known = self._error_looks_like('KnownFailure: ', err)
3379
3424
        if known is not None:
3380
 
            self.result._addKnownFailure(test, [KnownFailure,
3381
 
                                                KnownFailure(known), None])
 
3425
            self.result.addExpectedFailure(test,
 
3426
                [KnownFailure, KnownFailure(known), None])
3382
3427
        else:
3383
3428
            self.result.addFailure(test, err)
3384
3429
 
3399
3444
        return value
3400
3445
 
3401
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
 
3402
3463
class ProfileResult(ForwardingResult):
3403
3464
    """Generate profiling data for all activity between start and success.
3404
3465
    
3722
3783
        'bzrlib.tests.test_chk_serializer',
3723
3784
        'bzrlib.tests.test_chunk_writer',
3724
3785
        'bzrlib.tests.test_clean_tree',
 
3786
        'bzrlib.tests.test_cleanup',
3725
3787
        'bzrlib.tests.test_commands',
3726
3788
        'bzrlib.tests.test_commit',
3727
3789
        'bzrlib.tests.test_commit_merge',
4075
4137
    return new_test
4076
4138
 
4077
4139
 
4078
 
def _rmtree_temp_dir(dirname):
 
4140
def _rmtree_temp_dir(dirname, test_id=None):
4079
4141
    # If LANG=C we probably have created some bogus paths
4080
4142
    # which rmtree(unicode) will fail to delete
4081
4143
    # so make sure we are using rmtree(str) to delete everything
4093
4155
        # We don't want to fail here because some useful display will be lost
4094
4156
        # otherwise. Polluting the tmp dir is bad, but not giving all the
4095
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('\nWhile running: %s\n' % (test_id,))
4096
4161
        sys.stderr.write('Unable to remove testing dir %s\n%s'
4097
4162
                         % (os.path.basename(dirname), e))
4098
4163
 
4182
4247
UnicodeFilenameFeature = _UnicodeFilenameFeature()
4183
4248
 
4184
4249
 
 
4250
class ModuleAvailableFeature(Feature):
 
4251
    """This is a feature than describes a module we want to be available.
 
4252
 
 
4253
    Declare the name of the module in __init__(), and then after probing, the
 
4254
    module will be available as 'self.module'.
 
4255
 
 
4256
    :ivar module: The module if it is available, else None.
 
4257
    """
 
4258
 
 
4259
    def __init__(self, module_name):
 
4260
        super(ModuleAvailableFeature, self).__init__()
 
4261
        self.module_name = module_name
 
4262
 
 
4263
    def _probe(self):
 
4264
        try:
 
4265
            self._module = __import__(self.module_name, {}, {}, [''])
 
4266
            return True
 
4267
        except ImportError:
 
4268
            return False
 
4269
 
 
4270
    @property
 
4271
    def module(self):
 
4272
        if self.available(): # Make sure the probe has been done
 
4273
            return self._module
 
4274
        return None
 
4275
    
 
4276
    def feature_name(self):
 
4277
        return self.module_name
 
4278
 
 
4279
 
 
4280
 
4185
4281
def probe_unicode_in_user_encoding():
4186
4282
    """Try to encode several unicode strings to use in unicode-aware tests.
4187
4283
    Return first successfull match.
4295
4391
            # Windows doesn't have os.kill, and we catch the SIGBREAK signal.
4296
4392
            # We trigger SIGBREAK via a Console api so we need ctypes to
4297
4393
            # access the function
4298
 
            if not have_ctypes:
 
4394
            try:
 
4395
                import ctypes
 
4396
            except OSError:
4299
4397
                return False
4300
4398
        return True
4301
4399
 
4378
4476
# Only define SubUnitBzrRunner if subunit is available.
4379
4477
try:
4380
4478
    from subunit import TestProtocolClient
4381
 
    try:
4382
 
        from subunit.test_results import AutoTimingTestResultDecorator
4383
 
    except ImportError:
4384
 
        AutoTimingTestResultDecorator = lambda x:x
4385
4479
    class SubUnitBzrRunner(TextTestRunner):
4386
4480
        def run(self, test):
4387
 
            result = AutoTimingTestResultDecorator(
 
4481
            result = BzrAutoTimingTestResultDecorator(
4388
4482
                TestProtocolClient(self.stream))
4389
4483
            test.run(result)
4390
4484
            return result