/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

  • Committer: John Arbash Meinel
  • Date: 2009-12-10 17:16:19 UTC
  • mfrom: (4884 +trunk)
  • mto: This revision was merged to the branch mainline in revision 4889.
  • Revision ID: john@arbash-meinel.com-20091210171619-ehdcxjbl8afhq9g1
Bring in bzr.dev 4884

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
 
29
29
import atexit
30
30
import codecs
 
31
from copy import copy
31
32
from cStringIO import StringIO
32
33
import difflib
33
34
import doctest
53
54
    branchbuilder,
54
55
    bzrdir,
55
56
    chk_map,
 
57
    config,
56
58
    debug,
57
59
    errors,
58
60
    hooks,
90
92
    deprecated_passed,
91
93
    )
92
94
import bzrlib.trace
93
 
from bzrlib.transport import get_transport
 
95
from bzrlib.transport import get_transport, pathfilter
94
96
import bzrlib.transport
95
97
from bzrlib.transport.local import LocalURLServer
96
98
from bzrlib.transport.memory import MemoryServer
175
177
        self._overall_start_time = time.time()
176
178
        self._strict = strict
177
179
 
178
 
    def done(self):
179
 
        # nb: called stopTestRun in the version of this that Python merged
180
 
        # upstream, according to lifeless 20090803
 
180
    def stopTestRun(self):
 
181
        run = self.testsRun
 
182
        actionTaken = "Ran"
 
183
        stopTime = time.time()
 
184
        timeTaken = stopTime - self.startTime
 
185
        self.printErrors()
 
186
        self.stream.writeln(self.separator2)
 
187
        self.stream.writeln("%s %d test%s in %.3fs" % (actionTaken,
 
188
                            run, run != 1 and "s" or "", timeTaken))
 
189
        self.stream.writeln()
 
190
        if not self.wasSuccessful():
 
191
            self.stream.write("FAILED (")
 
192
            failed, errored = map(len, (self.failures, self.errors))
 
193
            if failed:
 
194
                self.stream.write("failures=%d" % failed)
 
195
            if errored:
 
196
                if failed: self.stream.write(", ")
 
197
                self.stream.write("errors=%d" % errored)
 
198
            if self.known_failure_count:
 
199
                if failed or errored: self.stream.write(", ")
 
200
                self.stream.write("known_failure_count=%d" %
 
201
                    self.known_failure_count)
 
202
            self.stream.writeln(")")
 
203
        else:
 
204
            if self.known_failure_count:
 
205
                self.stream.writeln("OK (known_failures=%d)" %
 
206
                    self.known_failure_count)
 
207
            else:
 
208
                self.stream.writeln("OK")
 
209
        if self.skip_count > 0:
 
210
            skipped = self.skip_count
 
211
            self.stream.writeln('%d test%s skipped' %
 
212
                                (skipped, skipped != 1 and "s" or ""))
 
213
        if self.unsupported:
 
214
            for feature, count in sorted(self.unsupported.items()):
 
215
                self.stream.writeln("Missing feature '%s' skipped %d tests." %
 
216
                    (feature, count))
181
217
        if self._strict:
182
218
            ok = self.wasStrictlySuccessful()
183
219
        else:
184
220
            ok = self.wasSuccessful()
185
 
        if ok:
186
 
            self.stream.write('tests passed\n')
187
 
        else:
188
 
            self.stream.write('tests failed\n')
189
221
        if TestCase._first_thread_leaker_id:
190
222
            self.stream.write(
191
223
                '%s is leaking threads among %d leaking tests.\n' % (
192
224
                TestCase._first_thread_leaker_id,
193
225
                TestCase._leaking_threads_tests))
 
226
            # We don't report the main thread as an active one.
 
227
            self.stream.write(
 
228
                '%d non-main threads were left active in the end.\n'
 
229
                % (TestCase._active_threads - 1))
194
230
 
195
231
    def _extractBenchmarkTime(self, testCase):
196
232
        """Add a benchmark time for the current test case."""
262
298
        Called from the TestCase run() method when the test
263
299
        fails with an unexpected error.
264
300
        """
265
 
        self._testConcluded(test)
266
 
        if isinstance(err[1], TestNotApplicable):
267
 
            return self._addNotApplicable(test, err)
268
 
        elif isinstance(err[1], UnavailableFeature):
269
 
            return self.addNotSupported(test, err[1].args[0])
270
 
        else:
271
 
            unittest.TestResult.addError(self, test, err)
272
 
            self.error_count += 1
273
 
            self.report_error(test, err)
274
 
            if self.stop_early:
275
 
                self.stop()
276
 
            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)
277
308
 
278
309
    def addFailure(self, test, err):
279
310
        """Tell result that test failed.
281
312
        Called from the TestCase run() method when the test
282
313
        fails because e.g. an assert() method failed.
283
314
        """
284
 
        self._testConcluded(test)
285
 
        if isinstance(err[1], KnownFailure):
286
 
            return self._addKnownFailure(test, err)
287
 
        else:
288
 
            unittest.TestResult.addFailure(self, test, err)
289
 
            self.failure_count += 1
290
 
            self.report_failure(test, err)
291
 
            if self.stop_early:
292
 
                self.stop()
293
 
            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)
294
322
 
295
323
    def addSuccess(self, test):
296
324
        """Tell result that test completed successfully.
297
325
 
298
326
        Called from the TestCase run()
299
327
        """
300
 
        self._testConcluded(test)
301
328
        if self._bench_history is not None:
302
329
            benchmark_time = self._extractBenchmarkTime(test)
303
330
            if benchmark_time is not None:
309
336
        unittest.TestResult.addSuccess(self, test)
310
337
        test._log_contents = ''
311
338
 
312
 
    def _testConcluded(self, test):
313
 
        """Common code when a test has finished.
314
 
 
315
 
        Called regardless of whether it succeded, failed, etc.
316
 
        """
317
 
        pass
318
 
 
319
 
    def _addKnownFailure(self, test, err):
 
339
    def addExpectedFailure(self, test, err):
320
340
        self.known_failure_count += 1
321
341
        self.report_known_failure(test, err)
322
342
 
324
344
        """The test will not be run because of a missing feature.
325
345
        """
326
346
        # this can be called in two different ways: it may be that the
327
 
        # test started running, and then raised (through addError)
 
347
        # test started running, and then raised (through requireFeature)
328
348
        # UnavailableFeature.  Alternatively this method can be called
329
 
        # while probing for features before running the tests; in that
330
 
        # case we will see startTest and stopTest, but the test will never
331
 
        # 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.
332
352
        self.unsupported.setdefault(str(feature), 0)
333
353
        self.unsupported[str(feature)] += 1
334
354
        self.report_unsupported(test, feature)
338
358
        self.skip_count += 1
339
359
        self.report_skip(test, reason)
340
360
 
341
 
    def _addNotApplicable(self, test, skip_excinfo):
342
 
        if isinstance(skip_excinfo[1], TestNotApplicable):
343
 
            self.not_applicable_count += 1
344
 
            self.report_not_applicable(test, skip_excinfo)
345
 
        try:
346
 
            test.tearDown()
347
 
        except KeyboardInterrupt:
348
 
            raise
349
 
        except:
350
 
            self.addError(test, test.exc_info())
351
 
        else:
352
 
            # seems best to treat this as success from point-of-view of unittest
353
 
            # -- it actually does nothing so it barely matters :)
354
 
            unittest.TestResult.addSuccess(self, test)
355
 
            test._log_contents = ''
 
361
    def addNotApplicable(self, test, reason):
 
362
        self.not_applicable_count += 1
 
363
        self.report_not_applicable(test, reason)
356
364
 
357
365
    def printErrorList(self, flavour, errors):
358
366
        for test, err in errors:
374
382
            self.stream.writeln(self.separator2)
375
383
            self.stream.writeln("%s" % err)
376
384
 
 
385
    def _post_mortem(self):
 
386
        """Start a PDB post mortem session."""
 
387
        if os.environ.get('BZR_TEST_PDB', None):
 
388
            import pdb;pdb.post_mortem()
 
389
 
377
390
    def progress(self, offset, whence):
378
391
        """The test is adjusting the count of tests to run."""
379
392
        if whence == SUBUNIT_SEEK_SET:
383
396
        else:
384
397
            raise errors.BzrError("Unknown whence %r" % whence)
385
398
 
386
 
    def finished(self):
387
 
        pass
388
 
 
389
399
    def report_cleaning_up(self):
390
400
        pass
391
401
 
 
402
    def startTestRun(self):
 
403
        self.startTime = time.time()
 
404
 
392
405
    def report_success(self, test):
393
406
        pass
394
407
 
421
434
        self.pb.update_latency = 0
422
435
        self.pb.show_transport_activity = False
423
436
 
424
 
    def done(self):
 
437
    def stopTestRun(self):
425
438
        # called when the tests that are going to run have run
426
439
        self.pb.clear()
427
 
        super(TextTestResult, self).done()
428
 
 
429
 
    def finished(self):
430
440
        self.pb.finished()
 
441
        super(TextTestResult, self).stopTestRun()
431
442
 
432
 
    def report_starting(self):
 
443
    def startTestRun(self):
 
444
        super(TextTestResult, self).startTestRun()
433
445
        self.pb.update('[test 0/%d] Starting' % (self.num_tests))
434
446
 
435
447
    def printErrors(self):
459
471
            a += ', %d err' % self.error_count
460
472
        if self.failure_count:
461
473
            a += ', %d fail' % self.failure_count
462
 
        if self.unsupported:
463
 
            a += ', %d missing' % len(self.unsupported)
 
474
        # if self.unsupported:
 
475
        #     a += ', %d missing' % len(self.unsupported)
464
476
        a += ']'
465
477
        return a
466
478
 
475
487
        return self._shortened_test_description(test)
476
488
 
477
489
    def report_error(self, test, err):
478
 
        self.pb.note('ERROR: %s\n    %s\n',
 
490
        ui.ui_factory.note('ERROR: %s\n    %s\n' % (
479
491
            self._test_description(test),
480
492
            err[1],
481
 
            )
 
493
            ))
482
494
 
483
495
    def report_failure(self, test, err):
484
 
        self.pb.note('FAIL: %s\n    %s\n',
 
496
        ui.ui_factory.note('FAIL: %s\n    %s\n' % (
485
497
            self._test_description(test),
486
498
            err[1],
487
 
            )
 
499
            ))
488
500
 
489
501
    def report_known_failure(self, test, err):
490
 
        self.pb.note('XFAIL: %s\n%s\n',
491
 
            self._test_description(test), err[1])
 
502
        ui.ui_factory.note('XFAIL: %s\n%s\n' % (
 
503
            self._test_description(test), err[1]))
492
504
 
493
505
    def report_skip(self, test, reason):
494
506
        pass
495
507
 
496
 
    def report_not_applicable(self, test, skip_excinfo):
 
508
    def report_not_applicable(self, test, reason):
497
509
        pass
498
510
 
499
511
    def report_unsupported(self, test, feature):
514
526
            result = a_string
515
527
        return result.ljust(final_width)
516
528
 
517
 
    def report_starting(self):
 
529
    def startTestRun(self):
 
530
        super(VerboseTestResult, self).startTestRun()
518
531
        self.stream.write('running %d tests...\n' % self.num_tests)
519
532
 
520
533
    def report_test_start(self, test):
521
534
        self.count += 1
522
535
        name = self._shortened_test_description(test)
523
 
        # width needs space for 6 char status, plus 1 for slash, plus an
524
 
        # 11-char time string, plus a trailing blank
525
 
        # when NUMBERED_DIRS: plus 5 chars on test number, plus 1 char on space
526
 
        self.stream.write(self._ellipsize_to_right(name,
527
 
                          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)
528
545
        self.stream.flush()
529
546
 
530
547
    def _error_summary(self, err):
559
576
        self.stream.writeln(' SKIP %s\n%s'
560
577
                % (self._testTimeString(test), reason))
561
578
 
562
 
    def report_not_applicable(self, test, skip_excinfo):
563
 
        self.stream.writeln('  N/A %s\n%s'
564
 
                % (self._testTimeString(test),
565
 
                   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))
566
582
 
567
583
    def report_unsupported(self, test, feature):
568
584
        """test cannot be run because feature is missing."""
578
594
                 descriptions=0,
579
595
                 verbosity=1,
580
596
                 bench_history=None,
581
 
                 list_only=False,
582
597
                 strict=False,
 
598
                 result_decorators=None,
583
599
                 ):
 
600
        """Create a TextTestRunner.
 
601
 
 
602
        :param result_decorators: An optional list of decorators to apply
 
603
            to the result object being used by the runner. Decorators are
 
604
            applied left to right - the first element in the list is the 
 
605
            innermost decorator.
 
606
        """
584
607
        self.stream = unittest._WritelnDecorator(stream)
585
608
        self.descriptions = descriptions
586
609
        self.verbosity = verbosity
587
610
        self._bench_history = bench_history
588
 
        self.list_only = list_only
589
611
        self._strict = strict
 
612
        self._result_decorators = result_decorators or []
590
613
 
591
614
    def run(self, test):
592
615
        "Run the given test case or test suite."
593
 
        startTime = time.time()
594
616
        if self.verbosity == 1:
595
617
            result_class = TextTestResult
596
618
        elif self.verbosity >= 2:
597
619
            result_class = VerboseTestResult
598
 
        result = result_class(self.stream,
 
620
        original_result = result_class(self.stream,
599
621
                              self.descriptions,
600
622
                              self.verbosity,
601
623
                              bench_history=self._bench_history,
602
624
                              strict=self._strict,
603
625
                              )
604
 
        result.stop_early = self.stop_on_failure
605
 
        result.report_starting()
606
 
        if self.list_only:
607
 
            if self.verbosity >= 2:
608
 
                self.stream.writeln("Listing tests only ...\n")
609
 
            run = 0
610
 
            for t in iter_suite_tests(test):
611
 
                self.stream.writeln("%s" % (t.id()))
612
 
                run += 1
613
 
            return None
614
 
        else:
615
 
            try:
616
 
                import testtools
617
 
            except ImportError:
618
 
                test.run(result)
619
 
            else:
620
 
                if isinstance(test, testtools.ConcurrentTestSuite):
621
 
                    # We need to catch bzr specific behaviors
622
 
                    test.run(BZRTransformingResult(result))
623
 
                else:
624
 
                    test.run(result)
625
 
            run = result.testsRun
626
 
            actionTaken = "Ran"
627
 
        stopTime = time.time()
628
 
        timeTaken = stopTime - startTime
629
 
        result.printErrors()
630
 
        self.stream.writeln(result.separator2)
631
 
        self.stream.writeln("%s %d test%s in %.3fs" % (actionTaken,
632
 
                            run, run != 1 and "s" or "", timeTaken))
633
 
        self.stream.writeln()
634
 
        if not result.wasSuccessful():
635
 
            self.stream.write("FAILED (")
636
 
            failed, errored = map(len, (result.failures, result.errors))
637
 
            if failed:
638
 
                self.stream.write("failures=%d" % failed)
639
 
            if errored:
640
 
                if failed: self.stream.write(", ")
641
 
                self.stream.write("errors=%d" % errored)
642
 
            if result.known_failure_count:
643
 
                if failed or errored: self.stream.write(", ")
644
 
                self.stream.write("known_failure_count=%d" %
645
 
                    result.known_failure_count)
646
 
            self.stream.writeln(")")
647
 
        else:
648
 
            if result.known_failure_count:
649
 
                self.stream.writeln("OK (known_failures=%d)" %
650
 
                    result.known_failure_count)
651
 
            else:
652
 
                self.stream.writeln("OK")
653
 
        if result.skip_count > 0:
654
 
            skipped = result.skip_count
655
 
            self.stream.writeln('%d test%s skipped' %
656
 
                                (skipped, skipped != 1 and "s" or ""))
657
 
        if result.unsupported:
658
 
            for feature, count in sorted(result.unsupported.items()):
659
 
                self.stream.writeln("Missing feature '%s' skipped %d tests." %
660
 
                    (feature, count))
661
 
        result.finished()
662
 
        return result
 
626
        # Signal to result objects that look at stop early policy to stop,
 
627
        original_result.stop_early = self.stop_on_failure
 
628
        result = original_result
 
629
        for decorator in self._result_decorators:
 
630
            result = decorator(result)
 
631
            result.stop_early = self.stop_on_failure
 
632
        try:
 
633
            import testtools
 
634
        except ImportError:
 
635
            pass
 
636
        else:
 
637
            if isinstance(test, testtools.ConcurrentTestSuite):
 
638
                # We need to catch bzr specific behaviors
 
639
                result = BZRTransformingResult(result)
 
640
        result.startTestRun()
 
641
        try:
 
642
            test.run(result)
 
643
        finally:
 
644
            result.stopTestRun()
 
645
        # higher level code uses our extended protocol to determine
 
646
        # what exit code to give.
 
647
        return original_result
663
648
 
664
649
 
665
650
def iter_suite_tests(suite):
701
686
class UnavailableFeature(Exception):
702
687
    """A feature required for this test was not available.
703
688
 
 
689
    This can be considered a specialised form of SkippedTest.
 
690
 
704
691
    The feature should be used to construct the exception.
705
692
    """
706
693
 
813
800
        self._cleanups = []
814
801
        self._bzr_test_setUp_run = False
815
802
        self._bzr_test_tearDown_run = False
 
803
        self._directory_isolation = True
816
804
 
817
805
    def setUp(self):
818
806
        unittest.TestCase.setUp(self)
823
811
        self._benchcalls = []
824
812
        self._benchtime = None
825
813
        self._clear_hooks()
 
814
        self._track_transports()
826
815
        self._track_locks()
827
816
        self._clear_debug_flags()
828
817
        TestCase._active_threads = threading.activeCount()
837
826
        active = threading.activeCount()
838
827
        leaked_threads = active - TestCase._active_threads
839
828
        TestCase._active_threads = active
840
 
        if leaked_threads:
 
829
        # If some tests make the number of threads *decrease*, we'll consider
 
830
        # that they are just observing old threads dieing, not agressively kill
 
831
        # random threads. So we don't report these tests as leaking. The risk
 
832
        # is that we have false positives that way (the test see 2 threads
 
833
        # going away but leak one) but it seems less likely than the actual
 
834
        # false positives (the test see threads going away and does not leak).
 
835
        if leaked_threads > 0:
841
836
            TestCase._leaking_threads_tests += 1
842
837
            if TestCase._first_thread_leaker_id is None:
843
838
                TestCase._first_thread_leaker_id = self.id()
869
864
        # this hook should always be installed
870
865
        request._install_hook()
871
866
 
 
867
    def disable_directory_isolation(self):
 
868
        """Turn off directory isolation checks."""
 
869
        self._directory_isolation = False
 
870
 
 
871
    def enable_directory_isolation(self):
 
872
        """Enable directory isolation checks."""
 
873
        self._directory_isolation = True
 
874
 
872
875
    def _silenceUI(self):
873
876
        """Turn off UI for duration of test"""
874
877
        # by default the UI is off; tests can turn it on if they want it.
929
932
    def _lock_broken(self, result):
930
933
        self._lock_actions.append(('broken', result))
931
934
 
 
935
    def permit_dir(self, name):
 
936
        """Permit a directory to be used by this test. See permit_url."""
 
937
        name_transport = get_transport(name)
 
938
        self.permit_url(name)
 
939
        self.permit_url(name_transport.base)
 
940
 
 
941
    def permit_url(self, url):
 
942
        """Declare that url is an ok url to use in this test.
 
943
        
 
944
        Do this for memory transports, temporary test directory etc.
 
945
        
 
946
        Do not do this for the current working directory, /tmp, or any other
 
947
        preexisting non isolated url.
 
948
        """
 
949
        if not url.endswith('/'):
 
950
            url += '/'
 
951
        self._bzr_selftest_roots.append(url)
 
952
 
 
953
    def permit_source_tree_branch_repo(self):
 
954
        """Permit the source tree bzr is running from to be opened.
 
955
 
 
956
        Some code such as bzrlib.version attempts to read from the bzr branch
 
957
        that bzr is executing from (if any). This method permits that directory
 
958
        to be used in the test suite.
 
959
        """
 
960
        path = self.get_source_path()
 
961
        self.record_directory_isolation()
 
962
        try:
 
963
            try:
 
964
                workingtree.WorkingTree.open(path)
 
965
            except (errors.NotBranchError, errors.NoWorkingTree):
 
966
                return
 
967
        finally:
 
968
            self.enable_directory_isolation()
 
969
 
 
970
    def _preopen_isolate_transport(self, transport):
 
971
        """Check that all transport openings are done in the test work area."""
 
972
        while isinstance(transport, pathfilter.PathFilteringTransport):
 
973
            # Unwrap pathfiltered transports
 
974
            transport = transport.server.backing_transport.clone(
 
975
                transport._filter('.'))
 
976
        url = transport.base
 
977
        # ReadonlySmartTCPServer_for_testing decorates the backing transport
 
978
        # urls it is given by prepending readonly+. This is appropriate as the
 
979
        # client shouldn't know that the server is readonly (or not readonly).
 
980
        # We could register all servers twice, with readonly+ prepending, but
 
981
        # that makes for a long list; this is about the same but easier to
 
982
        # read.
 
983
        if url.startswith('readonly+'):
 
984
            url = url[len('readonly+'):]
 
985
        self._preopen_isolate_url(url)
 
986
 
 
987
    def _preopen_isolate_url(self, url):
 
988
        if not self._directory_isolation:
 
989
            return
 
990
        if self._directory_isolation == 'record':
 
991
            self._bzr_selftest_roots.append(url)
 
992
            return
 
993
        # This prevents all transports, including e.g. sftp ones backed on disk
 
994
        # from working unless they are explicitly granted permission. We then
 
995
        # depend on the code that sets up test transports to check that they are
 
996
        # appropriately isolated and enable their use by calling
 
997
        # self.permit_transport()
 
998
        if not osutils.is_inside_any(self._bzr_selftest_roots, url):
 
999
            raise errors.BzrError("Attempt to escape test isolation: %r %r"
 
1000
                % (url, self._bzr_selftest_roots))
 
1001
 
 
1002
    def record_directory_isolation(self):
 
1003
        """Gather accessed directories to permit later access.
 
1004
        
 
1005
        This is used for tests that access the branch bzr is running from.
 
1006
        """
 
1007
        self._directory_isolation = "record"
 
1008
 
 
1009
    def start_server(self, transport_server, backing_server=None):
 
1010
        """Start transport_server for this test.
 
1011
 
 
1012
        This starts the server, registers a cleanup for it and permits the
 
1013
        server's urls to be used.
 
1014
        """
 
1015
        if backing_server is None:
 
1016
            transport_server.setUp()
 
1017
        else:
 
1018
            transport_server.setUp(backing_server)
 
1019
        self.addCleanup(transport_server.tearDown)
 
1020
        # Obtain a real transport because if the server supplies a password, it
 
1021
        # will be hidden from the base on the client side.
 
1022
        t = get_transport(transport_server.get_url())
 
1023
        # Some transport servers effectively chroot the backing transport;
 
1024
        # others like SFTPServer don't - users of the transport can walk up the
 
1025
        # transport to read the entire backing transport. This wouldn't matter
 
1026
        # except that the workdir tests are given - and that they expect the
 
1027
        # server's url to point at - is one directory under the safety net. So
 
1028
        # Branch operations into the transport will attempt to walk up one
 
1029
        # directory. Chrooting all servers would avoid this but also mean that
 
1030
        # we wouldn't be testing directly against non-root urls. Alternatively
 
1031
        # getting the test framework to start the server with a backing server
 
1032
        # at the actual safety net directory would work too, but this then
 
1033
        # means that the self.get_url/self.get_transport methods would need
 
1034
        # to transform all their results. On balance its cleaner to handle it
 
1035
        # here, and permit a higher url when we have one of these transports.
 
1036
        if t.base.endswith('/work/'):
 
1037
            # we have safety net/test root/work
 
1038
            t = t.clone('../..')
 
1039
        elif isinstance(transport_server, server.SmartTCPServer_for_testing):
 
1040
            # The smart server adds a path similar to work, which is traversed
 
1041
            # up from by the client. But the server is chrooted - the actual
 
1042
            # backing transport is not escaped from, and VFS requests to the
 
1043
            # root will error (because they try to escape the chroot).
 
1044
            t2 = t.clone('..')
 
1045
            while t2.base != t.base:
 
1046
                t = t2
 
1047
                t2 = t.clone('..')
 
1048
        self.permit_url(t.base)
 
1049
 
 
1050
    def _track_transports(self):
 
1051
        """Install checks for transport usage."""
 
1052
        # TestCase has no safe place it can write to.
 
1053
        self._bzr_selftest_roots = []
 
1054
        # Currently the easiest way to be sure that nothing is going on is to
 
1055
        # hook into bzr dir opening. This leaves a small window of error for
 
1056
        # transport tests, but they are well known, and we can improve on this
 
1057
        # step.
 
1058
        bzrdir.BzrDir.hooks.install_named_hook("pre_open",
 
1059
            self._preopen_isolate_transport, "Check bzr directories are safe.")
 
1060
 
932
1061
    def _ndiff_strings(self, a, b):
933
1062
        """Return ndiff between two strings containing lines.
934
1063
 
971
1100
            return
972
1101
        if message is None:
973
1102
            message = "texts not equal:\n"
 
1103
        if a + '\n' == b:
 
1104
            message = 'first string is missing a final newline.\n'
974
1105
        if a == b + '\n':
975
 
            message = 'first string is missing a final newline.\n'
976
 
        if a + '\n' == b:
977
1106
            message = 'second string is missing a final newline.\n'
978
1107
        raise AssertionError(message +
979
1108
                             self._ndiff_strings(a, b))
990
1119
        :raises AssertionError: If the expected and actual stat values differ
991
1120
            other than by atime.
992
1121
        """
993
 
        self.assertEqual(expected.st_size, actual.st_size)
994
 
        self.assertEqual(expected.st_mtime, actual.st_mtime)
995
 
        self.assertEqual(expected.st_ctime, actual.st_ctime)
996
 
        self.assertEqual(expected.st_dev, actual.st_dev)
997
 
        self.assertEqual(expected.st_ino, actual.st_ino)
998
 
        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')
999
1139
 
1000
1140
    def assertLength(self, length, obj_with_len):
1001
1141
        """Assert that obj_with_len is of length length."""
1003
1143
            self.fail("Incorrect length: wanted %d, got %d for %r" % (
1004
1144
                length, len(obj_with_len), obj_with_len))
1005
1145
 
 
1146
    def assertLogsError(self, exception_class, func, *args, **kwargs):
 
1147
        """Assert that func(*args, **kwargs) quietly logs a specific exception.
 
1148
        """
 
1149
        from bzrlib import trace
 
1150
        captured = []
 
1151
        orig_log_exception_quietly = trace.log_exception_quietly
 
1152
        try:
 
1153
            def capture():
 
1154
                orig_log_exception_quietly()
 
1155
                captured.append(sys.exc_info())
 
1156
            trace.log_exception_quietly = capture
 
1157
            func(*args, **kwargs)
 
1158
        finally:
 
1159
            trace.log_exception_quietly = orig_log_exception_quietly
 
1160
        self.assertLength(1, captured)
 
1161
        err = captured[0][1]
 
1162
        self.assertIsInstance(err, exception_class)
 
1163
        return err
 
1164
 
1006
1165
    def assertPositive(self, val):
1007
1166
        """Assert that val is greater than 0."""
1008
1167
        self.assertTrue(val > 0, 'expected a positive value, but got %s' % val)
1369
1528
            'BZR_PROGRESS_BAR': None,
1370
1529
            'BZR_LOG': None,
1371
1530
            'BZR_PLUGIN_PATH': None,
 
1531
            'BZR_CONCURRENCY': None,
1372
1532
            # Make sure that any text ui tests are consistent regardless of
1373
1533
            # the environment the test case is run in; you may want tests that
1374
1534
            # test other combinations.  'dumb' is a reasonable guess for tests
1376
1536
            'TERM': 'dumb',
1377
1537
            'LINES': '25',
1378
1538
            'COLUMNS': '80',
 
1539
            'BZR_COLUMNS': '80',
1379
1540
            # SSH Agent
1380
1541
            'SSH_AUTH_SOCK': None,
1381
1542
            # Proxies
1422
1583
    def _do_skip(self, result, reason):
1423
1584
        addSkip = getattr(result, 'addSkip', None)
1424
1585
        if not callable(addSkip):
1425
 
            result.addError(self, sys.exc_info())
 
1586
            result.addSuccess(result)
1426
1587
        else:
1427
1588
            addSkip(self, reason)
1428
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
 
1429
1616
    def run(self, result=None):
1430
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):
1431
1626
        for feature in getattr(self, '_test_needs_features', []):
1432
1627
            if not feature.available():
1433
 
                result.startTest(self)
1434
 
                if getattr(result, 'addNotSupported', None):
1435
 
                    result.addNotSupported(self, feature)
1436
 
                else:
1437
 
                    result.addSuccess(self)
1438
 
                result.stopTest(self)
1439
 
                return result
 
1628
                return self._do_unsupported_or_skip(result, feature)
1440
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)
1441
1637
            try:
1442
 
                result.startTest(self)
1443
 
                absent_attr = object()
1444
 
                # Python 2.5
1445
 
                method_name = getattr(self, '_testMethodName', absent_attr)
1446
 
                if method_name is absent_attr:
1447
 
                    # Python 2.4
1448
 
                    method_name = getattr(self, '_TestCase__testMethodName')
1449
 
                testMethod = getattr(self, method_name)
1450
 
                try:
1451
 
                    try:
1452
 
                        self.setUp()
1453
 
                        if not self._bzr_test_setUp_run:
1454
 
                            self.fail(
1455
 
                                "test setUp did not invoke "
1456
 
                                "bzrlib.tests.TestCase's setUp")
1457
 
                    except KeyboardInterrupt:
1458
 
                        self._runCleanups()
1459
 
                        raise
1460
 
                    except TestSkipped, e:
1461
 
                        self._do_skip(result, e.args[0])
1462
 
                        self.tearDown()
1463
 
                        return result
1464
 
                    except:
1465
 
                        result.addError(self, sys.exc_info())
1466
 
                        self._runCleanups()
1467
 
                        return result
1468
 
 
 
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()
1469
1704
                    ok = False
1470
 
                    try:
1471
 
                        testMethod()
1472
 
                        ok = True
1473
 
                    except self.failureException:
1474
 
                        result.addFailure(self, sys.exc_info())
1475
 
                    except TestSkipped, e:
1476
 
                        if not e.args:
1477
 
                            reason = "No reason given."
1478
 
                        else:
1479
 
                            reason = e.args[0]
1480
 
                        self._do_skip(result, reason)
1481
 
                    except KeyboardInterrupt:
1482
 
                        self._runCleanups()
1483
 
                        raise
1484
 
                    except:
1485
 
                        result.addError(self, sys.exc_info())
1486
 
 
1487
 
                    try:
1488
 
                        self.tearDown()
1489
 
                        if not self._bzr_test_tearDown_run:
1490
 
                            self.fail(
1491
 
                                "test tearDown did not invoke "
1492
 
                                "bzrlib.tests.TestCase's tearDown")
1493
 
                    except KeyboardInterrupt:
1494
 
                        self._runCleanups()
1495
 
                        raise
1496
 
                    except:
1497
 
                        result.addError(self, sys.exc_info())
1498
 
                        self._runCleanups()
1499
 
                        ok = False
1500
 
                    if ok: result.addSuccess(self)
1501
 
                finally:
1502
 
                    result.stopTest(self)
 
1705
                if ok: result.addSuccess(self)
1503
1706
                return result
1504
 
            except TestNotApplicable:
1505
 
                # Not moved from the result [yet].
1506
 
                self._runCleanups()
1507
 
                raise
1508
1707
            except KeyboardInterrupt:
1509
1708
                self._runCleanups()
1510
1709
                raise
1643
1842
            os.chdir(working_dir)
1644
1843
 
1645
1844
        try:
1646
 
            result = self.apply_redirected(ui.ui_factory.stdin,
1647
 
                stdout, stderr,
1648
 
                bzrlib.commands.run_bzr_catch_user_errors,
1649
 
                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)
1650
1861
        finally:
1651
1862
            logger.removeHandler(handler)
1652
1863
            ui.ui_factory = old_ui_factory
1662
1873
        if retcode is not None:
1663
1874
            self.assertEquals(retcode, result,
1664
1875
                              message='Unexpected return code')
1665
 
        return out, err
 
1876
        return result, out, err
1666
1877
 
1667
1878
    def run_bzr(self, args, retcode=0, encoding=None, stdin=None,
1668
1879
                working_dir=None, error_regexes=[], output_encoding=None):
1697
1908
        :keyword error_regexes: A list of expected error messages.  If
1698
1909
            specified they must be seen in the error output of the command.
1699
1910
        """
1700
 
        out, err = self._run_bzr_autosplit(
 
1911
        retcode, out, err = self._run_bzr_autosplit(
1701
1912
            args=args,
1702
1913
            retcode=retcode,
1703
1914
            encoding=encoding,
1854
2065
        """
1855
2066
        return Popen(*args, **kwargs)
1856
2067
 
 
2068
    def get_source_path(self):
 
2069
        """Return the path of the directory containing bzrlib."""
 
2070
        return os.path.dirname(os.path.dirname(bzrlib.__file__))
 
2071
 
1857
2072
    def get_bzr_path(self):
1858
2073
        """Return the path of the 'bzr' executable for this test suite."""
1859
 
        bzr_path = os.path.dirname(os.path.dirname(bzrlib.__file__))+'/bzr'
 
2074
        bzr_path = self.get_source_path()+'/bzr'
1860
2075
        if not os.path.isfile(bzr_path):
1861
2076
            # We are probably installed. Assume sys.argv is the right file
1862
2077
            bzr_path = sys.argv[0]
2071
2286
        if self.__readonly_server is None:
2072
2287
            if self.transport_readonly_server is None:
2073
2288
                # readonly decorator requested
2074
 
                # bring up the server
2075
2289
                self.__readonly_server = ReadonlyServer()
2076
 
                self.__readonly_server.setUp(self.get_vfs_only_server())
2077
2290
            else:
 
2291
                # explicit readonly transport.
2078
2292
                self.__readonly_server = self.create_transport_readonly_server()
2079
 
                self.__readonly_server.setUp(self.get_vfs_only_server())
2080
 
            self.addCleanup(self.__readonly_server.tearDown)
 
2293
            self.start_server(self.__readonly_server,
 
2294
                self.get_vfs_only_server())
2081
2295
        return self.__readonly_server
2082
2296
 
2083
2297
    def get_readonly_url(self, relpath=None):
2102
2316
        """
2103
2317
        if self.__vfs_server is None:
2104
2318
            self.__vfs_server = MemoryServer()
2105
 
            self.__vfs_server.setUp()
2106
 
            self.addCleanup(self.__vfs_server.tearDown)
 
2319
            self.start_server(self.__vfs_server)
2107
2320
        return self.__vfs_server
2108
2321
 
2109
2322
    def get_server(self):
2116
2329
        then the self.get_vfs_server is returned.
2117
2330
        """
2118
2331
        if self.__server is None:
2119
 
            if self.transport_server is None or self.transport_server is self.vfs_transport_factory:
2120
 
                return self.get_vfs_only_server()
 
2332
            if (self.transport_server is None or self.transport_server is
 
2333
                self.vfs_transport_factory):
 
2334
                self.__server = self.get_vfs_only_server()
2121
2335
            else:
2122
2336
                # bring up a decorated means of access to the vfs only server.
2123
2337
                self.__server = self.transport_server()
2124
 
                try:
2125
 
                    self.__server.setUp(self.get_vfs_only_server())
2126
 
                except TypeError, e:
2127
 
                    # This should never happen; the try:Except here is to assist
2128
 
                    # developers having to update code rather than seeing an
2129
 
                    # uninformative TypeError.
2130
 
                    raise Exception, "Old server API in use: %s, %s" % (self.__server, e)
2131
 
            self.addCleanup(self.__server.tearDown)
 
2338
                self.start_server(self.__server, self.get_vfs_only_server())
2132
2339
        return self.__server
2133
2340
 
2134
2341
    def _adjust_url(self, base, relpath):
2196
2403
        propagating. This method ensures than a test did not leaked.
2197
2404
        """
2198
2405
        root = TestCaseWithMemoryTransport.TEST_ROOT
 
2406
        self.permit_url(get_transport(root).base)
2199
2407
        wt = workingtree.WorkingTree.open(root)
2200
2408
        last_rev = wt.last_revision()
2201
2409
        if last_rev != 'null:':
2203
2411
            # recreate a new one or all the followng tests will fail.
2204
2412
            # If you need to inspect its content uncomment the following line
2205
2413
            # import pdb; pdb.set_trace()
2206
 
            _rmtree_temp_dir(root + '/.bzr')
 
2414
            _rmtree_temp_dir(root + '/.bzr', test_id=self.id())
2207
2415
            self._create_safety_net()
2208
2416
            raise AssertionError('%s/.bzr should not be modified' % root)
2209
2417
 
2210
2418
    def _make_test_root(self):
2211
2419
        if TestCaseWithMemoryTransport.TEST_ROOT is None:
2212
 
            root = osutils.mkdtemp(prefix='testbzr-', suffix='.tmp')
 
2420
            # Watch out for tricky test dir (on OSX /tmp -> /private/tmp)
 
2421
            root = osutils.realpath(osutils.mkdtemp(prefix='testbzr-',
 
2422
                                                    suffix='.tmp'))
2213
2423
            TestCaseWithMemoryTransport.TEST_ROOT = root
2214
2424
 
2215
2425
            self._create_safety_net()
2218
2428
            # specifically told when all tests are finished.  This will do.
2219
2429
            atexit.register(_rmtree_temp_dir, root)
2220
2430
 
 
2431
        self.permit_dir(TestCaseWithMemoryTransport.TEST_ROOT)
2221
2432
        self.addCleanup(self._check_safety_net)
2222
2433
 
2223
2434
    def makeAndChdirToTestDir(self):
2231
2442
        os.chdir(TestCaseWithMemoryTransport.TEST_ROOT)
2232
2443
        self.test_dir = TestCaseWithMemoryTransport.TEST_ROOT
2233
2444
        self.test_home_dir = self.test_dir + "/MemoryTransportMissingHomeDir"
 
2445
        self.permit_dir(self.test_dir)
2234
2446
 
2235
2447
    def make_branch(self, relpath, format=None):
2236
2448
        """Create a branch on the transport at relpath."""
2267
2479
 
2268
2480
    def make_smart_server(self, path):
2269
2481
        smart_server = server.SmartTCPServer_for_testing()
2270
 
        smart_server.setUp(self.get_server())
 
2482
        self.start_server(smart_server, self.get_server())
2271
2483
        remote_transport = get_transport(smart_server.get_url()).clone(path)
2272
 
        self.addCleanup(smart_server.tearDown)
2273
2484
        return remote_transport
2274
2485
 
2275
2486
    def make_branch_and_memory_tree(self, relpath, format=None):
2282
2493
        return branchbuilder.BranchBuilder(branch=branch)
2283
2494
 
2284
2495
    def overrideEnvironmentForTesting(self):
2285
 
        os.environ['HOME'] = self.test_home_dir
2286
 
        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
2287
2501
 
2288
2502
    def setUp(self):
2289
2503
        super(TestCaseWithMemoryTransport, self).setUp()
2369
2583
            if os.path.exists(name):
2370
2584
                name = name_prefix + '_' + str(i)
2371
2585
            else:
2372
 
                os.mkdir(name)
 
2586
                # now create test and home directories within this dir
 
2587
                self.test_base_dir = name
 
2588
                self.addCleanup(self.deleteTestDir)
 
2589
                os.mkdir(self.test_base_dir)
2373
2590
                break
2374
 
        # now create test and home directories within this dir
2375
 
        self.test_base_dir = name
 
2591
        self.permit_dir(self.test_base_dir)
 
2592
        # 'sprouting' and 'init' of a branch both walk up the tree to find
 
2593
        # stacking policy to honour; create a bzr dir with an unshared
 
2594
        # repository (but not a branch - our code would be trying to escape
 
2595
        # then!) to stop them, and permit it to be read.
 
2596
        # control = bzrdir.BzrDir.create(self.test_base_dir)
 
2597
        # control.create_repository()
2376
2598
        self.test_home_dir = self.test_base_dir + '/home'
2377
2599
        os.mkdir(self.test_home_dir)
2378
2600
        self.test_dir = self.test_base_dir + '/work'
2384
2606
            f.write(self.id())
2385
2607
        finally:
2386
2608
            f.close()
2387
 
        self.addCleanup(self.deleteTestDir)
2388
2609
 
2389
2610
    def deleteTestDir(self):
2390
2611
        os.chdir(TestCaseWithMemoryTransport.TEST_ROOT)
2391
 
        _rmtree_temp_dir(self.test_base_dir)
 
2612
        _rmtree_temp_dir(self.test_base_dir, test_id=self.id())
2392
2613
 
2393
2614
    def build_tree(self, shape, line_endings='binary', transport=None):
2394
2615
        """Build a test tree according to a pattern.
2476
2697
        """
2477
2698
        if self.__vfs_server is None:
2478
2699
            self.__vfs_server = self.vfs_transport_factory()
2479
 
            self.__vfs_server.setUp()
2480
 
            self.addCleanup(self.__vfs_server.tearDown)
 
2700
            self.start_server(self.__vfs_server)
2481
2701
        return self.__vfs_server
2482
2702
 
2483
2703
    def make_branch_and_tree(self, relpath, format=None):
2490
2710
        repository will also be accessed locally. Otherwise a lightweight
2491
2711
        checkout is created and returned.
2492
2712
 
 
2713
        We do this because we can't physically create a tree in the local
 
2714
        path, with a branch reference to the transport_factory url, and
 
2715
        a branch + repository in the vfs_transport, unless the vfs_transport
 
2716
        namespace is distinct from the local disk - the two branch objects
 
2717
        would collide. While we could construct a tree with its branch object
 
2718
        pointing at the transport_factory transport in memory, reopening it
 
2719
        would behaving unexpectedly, and has in the past caused testing bugs
 
2720
        when we tried to do it that way.
 
2721
 
2493
2722
        :param format: The BzrDirFormat.
2494
2723
        :returns: the WorkingTree.
2495
2724
        """
2547
2776
        super(TestCaseWithTransport, self).setUp()
2548
2777
        self.__vfs_server = None
2549
2778
 
 
2779
    def disable_missing_extensions_warning(self):
 
2780
        """Some tests expect a precise stderr content.
 
2781
 
 
2782
        There is no point in forcing them to duplicate the extension related
 
2783
        warning.
 
2784
        """
 
2785
        config.GlobalConfig().set_user_option('ignore_missing_extensions', True)
 
2786
 
2550
2787
 
2551
2788
class ChrootedTestCase(TestCaseWithTransport):
2552
2789
    """A support class that provides readonly urls outside the local namespace.
2766
3003
              strict=False,
2767
3004
              runner_class=None,
2768
3005
              suite_decorators=None,
2769
 
              stream=None):
 
3006
              stream=None,
 
3007
              result_decorators=None,
 
3008
              ):
2770
3009
    """Run a test suite for bzr selftest.
2771
3010
 
2772
3011
    :param runner_class: The class of runner to use. Must support the
2787
3026
                            descriptions=0,
2788
3027
                            verbosity=verbosity,
2789
3028
                            bench_history=bench_history,
2790
 
                            list_only=list_only,
2791
3029
                            strict=strict,
 
3030
                            result_decorators=result_decorators,
2792
3031
                            )
2793
3032
    runner.stop_on_failure=stop_on_failure
2794
3033
    # built in decorator factories:
2809
3048
        decorators.append(CountingDecorator)
2810
3049
    for decorator in decorators:
2811
3050
        suite = decorator(suite)
 
3051
    if list_only:
 
3052
        # Done after test suite decoration to allow randomisation etc
 
3053
        # to take effect, though that is of marginal benefit.
 
3054
        if verbosity >= 2:
 
3055
            stream.write("Listing tests only ...\n")
 
3056
        for t in iter_suite_tests(suite):
 
3057
            stream.write("%s\n" % (t.id()))
 
3058
        return True
2812
3059
    result = runner.run(suite)
2813
 
    if list_only:
2814
 
        return True
2815
 
    result.done()
2816
3060
    if strict:
2817
3061
        return result.wasStrictlySuccessful()
2818
3062
    else:
3038
3282
    concurrency = osutils.local_concurrency()
3039
3283
    result = []
3040
3284
    from subunit import TestProtocolClient, ProtocolTestCase
3041
 
    try:
3042
 
        from subunit.test_results import AutoTimingTestResultDecorator
3043
 
    except ImportError:
3044
 
        AutoTimingTestResultDecorator = lambda x:x
3045
3285
    class TestInOtherProcess(ProtocolTestCase):
3046
3286
        # Should be in subunit, I think. RBC.
3047
3287
        def __init__(self, stream, pid):
3070
3310
                sys.stdin.close()
3071
3311
                sys.stdin = None
3072
3312
                stream = os.fdopen(c2pwrite, 'wb', 1)
3073
 
                subunit_result = AutoTimingTestResultDecorator(
 
3313
                subunit_result = BzrAutoTimingTestResultDecorator(
3074
3314
                    TestProtocolClient(stream))
3075
3315
                process_suite.run(subunit_result)
3076
3316
            finally:
3113
3353
        if not os.path.isfile(bzr_path):
3114
3354
            # We are probably installed. Assume sys.argv is the right file
3115
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
3116
3360
        fd, test_list_file_name = tempfile.mkstemp()
3117
3361
        test_list_file = os.fdopen(fd, 'wb', 1)
3118
3362
        for test in process_tests:
3119
3363
            test_list_file.write(test.id() + '\n')
3120
3364
        test_list_file.close()
3121
3365
        try:
3122
 
            argv = [bzr_path, 'selftest', '--load-list', test_list_file_name,
 
3366
            argv = bzr_path + ['selftest', '--load-list', test_list_file_name,
3123
3367
                '--subunit']
3124
3368
            if '--no-plugins' in sys.argv:
3125
3369
                argv.append('--no-plugins')
3135
3379
    return result
3136
3380
 
3137
3381
 
3138
 
class BZRTransformingResult(unittest.TestResult):
 
3382
class ForwardingResult(unittest.TestResult):
3139
3383
 
3140
3384
    def __init__(self, target):
3141
3385
        unittest.TestResult.__init__(self)
3147
3391
    def stopTest(self, test):
3148
3392
        self.result.stopTest(test)
3149
3393
 
 
3394
    def startTestRun(self):
 
3395
        self.result.startTestRun()
 
3396
 
 
3397
    def stopTestRun(self):
 
3398
        self.result.stopTestRun()
 
3399
 
 
3400
    def addSkip(self, test, reason):
 
3401
        self.result.addSkip(test, reason)
 
3402
 
 
3403
    def addSuccess(self, test):
 
3404
        self.result.addSuccess(test)
 
3405
 
 
3406
    def addError(self, test, err):
 
3407
        self.result.addError(test, err)
 
3408
 
 
3409
    def addFailure(self, test, err):
 
3410
        self.result.addFailure(test, err)
 
3411
 
 
3412
 
 
3413
class BZRTransformingResult(ForwardingResult):
 
3414
 
3150
3415
    def addError(self, test, err):
3151
3416
        feature = self._error_looks_like('UnavailableFeature: ', err)
3152
3417
        if feature is not None:
3157
3422
    def addFailure(self, test, err):
3158
3423
        known = self._error_looks_like('KnownFailure: ', err)
3159
3424
        if known is not None:
3160
 
            self.result._addKnownFailure(test, [KnownFailure,
3161
 
                                                KnownFailure(known), None])
 
3425
            self.result.addExpectedFailure(test,
 
3426
                [KnownFailure, KnownFailure(known), None])
3162
3427
        else:
3163
3428
            self.result.addFailure(test, err)
3164
3429
 
3165
 
    def addSkip(self, test, reason):
3166
 
        self.result.addSkip(test, reason)
3167
 
 
3168
 
    def addSuccess(self, test):
3169
 
        self.result.addSuccess(test)
3170
 
 
3171
3430
    def _error_looks_like(self, prefix, err):
3172
3431
        """Deserialize exception and returns the stringify value."""
3173
3432
        import subunit
3185
3444
        return value
3186
3445
 
3187
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
 
 
3463
class ProfileResult(ForwardingResult):
 
3464
    """Generate profiling data for all activity between start and success.
 
3465
    
 
3466
    The profile data is appended to the test's _benchcalls attribute and can
 
3467
    be accessed by the forwarded-to TestResult.
 
3468
 
 
3469
    While it might be cleaner do accumulate this in stopTest, addSuccess is
 
3470
    where our existing output support for lsprof is, and this class aims to
 
3471
    fit in with that: while it could be moved it's not necessary to accomplish
 
3472
    test profiling, nor would it be dramatically cleaner.
 
3473
    """
 
3474
 
 
3475
    def startTest(self, test):
 
3476
        self.profiler = bzrlib.lsprof.BzrProfiler()
 
3477
        self.profiler.start()
 
3478
        ForwardingResult.startTest(self, test)
 
3479
 
 
3480
    def addSuccess(self, test):
 
3481
        stats = self.profiler.stop()
 
3482
        try:
 
3483
            calls = test._benchcalls
 
3484
        except AttributeError:
 
3485
            test._benchcalls = []
 
3486
            calls = test._benchcalls
 
3487
        calls.append(((test.id(), "", ""), stats))
 
3488
        ForwardingResult.addSuccess(self, test)
 
3489
 
 
3490
    def stopTest(self, test):
 
3491
        ForwardingResult.stopTest(self, test)
 
3492
        self.profiler = None
 
3493
 
 
3494
 
3188
3495
# Controlled by "bzr selftest -E=..." option
3189
3496
# Currently supported:
3190
3497
#   -Eallow_debug           Will no longer clear debug.debug_flags() so it
3212
3519
             runner_class=None,
3213
3520
             suite_decorators=None,
3214
3521
             stream=None,
 
3522
             lsprof_tests=False,
3215
3523
             ):
3216
3524
    """Run the whole test suite under the enhanced runner"""
3217
3525
    # XXX: Very ugly way to do this...
3246
3554
        if starting_with:
3247
3555
            # But always filter as requested.
3248
3556
            suite = filter_suite_by_id_startswith(suite, starting_with)
 
3557
        result_decorators = []
 
3558
        if lsprof_tests:
 
3559
            result_decorators.append(ProfileResult)
3249
3560
        return run_suite(suite, 'testbzr', verbose=verbose, pattern=pattern,
3250
3561
                     stop_on_failure=stop_on_failure,
3251
3562
                     transport=transport,
3259
3570
                     runner_class=runner_class,
3260
3571
                     suite_decorators=suite_decorators,
3261
3572
                     stream=stream,
 
3573
                     result_decorators=result_decorators,
3262
3574
                     )
3263
3575
    finally:
3264
3576
        default_transport = old_transport
3420
3732
test_prefix_alias_registry.register('bp', 'bzrlib.plugins')
3421
3733
 
3422
3734
 
 
3735
def _test_suite_testmod_names():
 
3736
    """Return the standard list of test module names to test."""
 
3737
    return [
 
3738
        'bzrlib.doc',
 
3739
        'bzrlib.tests.blackbox',
 
3740
        'bzrlib.tests.commands',
 
3741
        'bzrlib.tests.per_branch',
 
3742
        'bzrlib.tests.per_bzrdir',
 
3743
        'bzrlib.tests.per_foreign_vcs',
 
3744
        'bzrlib.tests.per_interrepository',
 
3745
        'bzrlib.tests.per_intertree',
 
3746
        'bzrlib.tests.per_inventory',
 
3747
        'bzrlib.tests.per_interbranch',
 
3748
        'bzrlib.tests.per_lock',
 
3749
        'bzrlib.tests.per_transport',
 
3750
        'bzrlib.tests.per_tree',
 
3751
        'bzrlib.tests.per_pack_repository',
 
3752
        'bzrlib.tests.per_repository',
 
3753
        'bzrlib.tests.per_repository_chk',
 
3754
        'bzrlib.tests.per_repository_reference',
 
3755
        'bzrlib.tests.per_uifactory',
 
3756
        'bzrlib.tests.per_versionedfile',
 
3757
        'bzrlib.tests.per_workingtree',
 
3758
        'bzrlib.tests.test__annotator',
 
3759
        'bzrlib.tests.test__chk_map',
 
3760
        'bzrlib.tests.test__dirstate_helpers',
 
3761
        'bzrlib.tests.test__groupcompress',
 
3762
        'bzrlib.tests.test__known_graph',
 
3763
        'bzrlib.tests.test__rio',
 
3764
        'bzrlib.tests.test__simple_set',
 
3765
        'bzrlib.tests.test__static_tuple',
 
3766
        'bzrlib.tests.test__walkdirs_win32',
 
3767
        'bzrlib.tests.test_ancestry',
 
3768
        'bzrlib.tests.test_annotate',
 
3769
        'bzrlib.tests.test_api',
 
3770
        'bzrlib.tests.test_atomicfile',
 
3771
        'bzrlib.tests.test_bad_files',
 
3772
        'bzrlib.tests.test_bencode',
 
3773
        'bzrlib.tests.test_bisect_multi',
 
3774
        'bzrlib.tests.test_branch',
 
3775
        'bzrlib.tests.test_branchbuilder',
 
3776
        'bzrlib.tests.test_btree_index',
 
3777
        'bzrlib.tests.test_bugtracker',
 
3778
        'bzrlib.tests.test_bundle',
 
3779
        'bzrlib.tests.test_bzrdir',
 
3780
        'bzrlib.tests.test__chunks_to_lines',
 
3781
        'bzrlib.tests.test_cache_utf8',
 
3782
        'bzrlib.tests.test_chk_map',
 
3783
        'bzrlib.tests.test_chk_serializer',
 
3784
        'bzrlib.tests.test_chunk_writer',
 
3785
        'bzrlib.tests.test_clean_tree',
 
3786
        'bzrlib.tests.test_cleanup',
 
3787
        'bzrlib.tests.test_commands',
 
3788
        'bzrlib.tests.test_commit',
 
3789
        'bzrlib.tests.test_commit_merge',
 
3790
        'bzrlib.tests.test_config',
 
3791
        'bzrlib.tests.test_conflicts',
 
3792
        'bzrlib.tests.test_counted_lock',
 
3793
        'bzrlib.tests.test_crash',
 
3794
        'bzrlib.tests.test_decorators',
 
3795
        'bzrlib.tests.test_delta',
 
3796
        'bzrlib.tests.test_debug',
 
3797
        'bzrlib.tests.test_deprecated_graph',
 
3798
        'bzrlib.tests.test_diff',
 
3799
        'bzrlib.tests.test_directory_service',
 
3800
        'bzrlib.tests.test_dirstate',
 
3801
        'bzrlib.tests.test_email_message',
 
3802
        'bzrlib.tests.test_eol_filters',
 
3803
        'bzrlib.tests.test_errors',
 
3804
        'bzrlib.tests.test_export',
 
3805
        'bzrlib.tests.test_extract',
 
3806
        'bzrlib.tests.test_fetch',
 
3807
        'bzrlib.tests.test_fifo_cache',
 
3808
        'bzrlib.tests.test_filters',
 
3809
        'bzrlib.tests.test_ftp_transport',
 
3810
        'bzrlib.tests.test_foreign',
 
3811
        'bzrlib.tests.test_generate_docs',
 
3812
        'bzrlib.tests.test_generate_ids',
 
3813
        'bzrlib.tests.test_globbing',
 
3814
        'bzrlib.tests.test_gpg',
 
3815
        'bzrlib.tests.test_graph',
 
3816
        'bzrlib.tests.test_groupcompress',
 
3817
        'bzrlib.tests.test_hashcache',
 
3818
        'bzrlib.tests.test_help',
 
3819
        'bzrlib.tests.test_hooks',
 
3820
        'bzrlib.tests.test_http',
 
3821
        'bzrlib.tests.test_http_response',
 
3822
        'bzrlib.tests.test_https_ca_bundle',
 
3823
        'bzrlib.tests.test_identitymap',
 
3824
        'bzrlib.tests.test_ignores',
 
3825
        'bzrlib.tests.test_index',
 
3826
        'bzrlib.tests.test_info',
 
3827
        'bzrlib.tests.test_inv',
 
3828
        'bzrlib.tests.test_inventory_delta',
 
3829
        'bzrlib.tests.test_knit',
 
3830
        'bzrlib.tests.test_lazy_import',
 
3831
        'bzrlib.tests.test_lazy_regex',
 
3832
        'bzrlib.tests.test_lock',
 
3833
        'bzrlib.tests.test_lockable_files',
 
3834
        'bzrlib.tests.test_lockdir',
 
3835
        'bzrlib.tests.test_log',
 
3836
        'bzrlib.tests.test_lru_cache',
 
3837
        'bzrlib.tests.test_lsprof',
 
3838
        'bzrlib.tests.test_mail_client',
 
3839
        'bzrlib.tests.test_memorytree',
 
3840
        'bzrlib.tests.test_merge',
 
3841
        'bzrlib.tests.test_merge3',
 
3842
        'bzrlib.tests.test_merge_core',
 
3843
        'bzrlib.tests.test_merge_directive',
 
3844
        'bzrlib.tests.test_missing',
 
3845
        'bzrlib.tests.test_msgeditor',
 
3846
        'bzrlib.tests.test_multiparent',
 
3847
        'bzrlib.tests.test_mutabletree',
 
3848
        'bzrlib.tests.test_nonascii',
 
3849
        'bzrlib.tests.test_options',
 
3850
        'bzrlib.tests.test_osutils',
 
3851
        'bzrlib.tests.test_osutils_encodings',
 
3852
        'bzrlib.tests.test_pack',
 
3853
        'bzrlib.tests.test_patch',
 
3854
        'bzrlib.tests.test_patches',
 
3855
        'bzrlib.tests.test_permissions',
 
3856
        'bzrlib.tests.test_plugins',
 
3857
        'bzrlib.tests.test_progress',
 
3858
        'bzrlib.tests.test_read_bundle',
 
3859
        'bzrlib.tests.test_reconcile',
 
3860
        'bzrlib.tests.test_reconfigure',
 
3861
        'bzrlib.tests.test_registry',
 
3862
        'bzrlib.tests.test_remote',
 
3863
        'bzrlib.tests.test_rename_map',
 
3864
        'bzrlib.tests.test_repository',
 
3865
        'bzrlib.tests.test_revert',
 
3866
        'bzrlib.tests.test_revision',
 
3867
        'bzrlib.tests.test_revisionspec',
 
3868
        'bzrlib.tests.test_revisiontree',
 
3869
        'bzrlib.tests.test_rio',
 
3870
        'bzrlib.tests.test_rules',
 
3871
        'bzrlib.tests.test_sampler',
 
3872
        'bzrlib.tests.test_script',
 
3873
        'bzrlib.tests.test_selftest',
 
3874
        'bzrlib.tests.test_serializer',
 
3875
        'bzrlib.tests.test_setup',
 
3876
        'bzrlib.tests.test_sftp_transport',
 
3877
        'bzrlib.tests.test_shelf',
 
3878
        'bzrlib.tests.test_shelf_ui',
 
3879
        'bzrlib.tests.test_smart',
 
3880
        'bzrlib.tests.test_smart_add',
 
3881
        'bzrlib.tests.test_smart_request',
 
3882
        'bzrlib.tests.test_smart_transport',
 
3883
        'bzrlib.tests.test_smtp_connection',
 
3884
        'bzrlib.tests.test_source',
 
3885
        'bzrlib.tests.test_ssh_transport',
 
3886
        'bzrlib.tests.test_status',
 
3887
        'bzrlib.tests.test_store',
 
3888
        'bzrlib.tests.test_strace',
 
3889
        'bzrlib.tests.test_subsume',
 
3890
        'bzrlib.tests.test_switch',
 
3891
        'bzrlib.tests.test_symbol_versioning',
 
3892
        'bzrlib.tests.test_tag',
 
3893
        'bzrlib.tests.test_testament',
 
3894
        'bzrlib.tests.test_textfile',
 
3895
        'bzrlib.tests.test_textmerge',
 
3896
        'bzrlib.tests.test_timestamp',
 
3897
        'bzrlib.tests.test_trace',
 
3898
        'bzrlib.tests.test_transactions',
 
3899
        'bzrlib.tests.test_transform',
 
3900
        'bzrlib.tests.test_transport',
 
3901
        'bzrlib.tests.test_transport_log',
 
3902
        'bzrlib.tests.test_tree',
 
3903
        'bzrlib.tests.test_treebuilder',
 
3904
        'bzrlib.tests.test_tsort',
 
3905
        'bzrlib.tests.test_tuned_gzip',
 
3906
        'bzrlib.tests.test_ui',
 
3907
        'bzrlib.tests.test_uncommit',
 
3908
        'bzrlib.tests.test_upgrade',
 
3909
        'bzrlib.tests.test_upgrade_stacked',
 
3910
        'bzrlib.tests.test_urlutils',
 
3911
        'bzrlib.tests.test_version',
 
3912
        'bzrlib.tests.test_version_info',
 
3913
        'bzrlib.tests.test_weave',
 
3914
        'bzrlib.tests.test_whitebox',
 
3915
        'bzrlib.tests.test_win32utils',
 
3916
        'bzrlib.tests.test_workingtree',
 
3917
        'bzrlib.tests.test_workingtree_4',
 
3918
        'bzrlib.tests.test_wsgi',
 
3919
        'bzrlib.tests.test_xml',
 
3920
        ]
 
3921
 
 
3922
 
 
3923
def _test_suite_modules_to_doctest():
 
3924
    """Return the list of modules to doctest."""   
 
3925
    return [
 
3926
        'bzrlib',
 
3927
        'bzrlib.branchbuilder',
 
3928
        'bzrlib.export',
 
3929
        'bzrlib.inventory',
 
3930
        'bzrlib.iterablefile',
 
3931
        'bzrlib.lockdir',
 
3932
        'bzrlib.merge3',
 
3933
        'bzrlib.option',
 
3934
        'bzrlib.symbol_versioning',
 
3935
        'bzrlib.tests',
 
3936
        'bzrlib.timestamp',
 
3937
        'bzrlib.version_info_formats.format_custom',
 
3938
        ]
 
3939
 
 
3940
 
3423
3941
def test_suite(keep_only=None, starting_with=None):
3424
3942
    """Build and return TestSuite for the whole of bzrlib.
3425
3943
 
3431
3949
    This function can be replaced if you need to change the default test
3432
3950
    suite on a global basis, but it is not encouraged.
3433
3951
    """
3434
 
    testmod_names = [
3435
 
                   'bzrlib.doc',
3436
 
                   'bzrlib.tests.blackbox',
3437
 
                   'bzrlib.tests.commands',
3438
 
                   'bzrlib.tests.per_branch',
3439
 
                   'bzrlib.tests.per_bzrdir',
3440
 
                   'bzrlib.tests.per_interrepository',
3441
 
                   'bzrlib.tests.per_intertree',
3442
 
                   'bzrlib.tests.per_inventory',
3443
 
                   'bzrlib.tests.per_interbranch',
3444
 
                   'bzrlib.tests.per_lock',
3445
 
                   'bzrlib.tests.per_transport',
3446
 
                   'bzrlib.tests.per_tree',
3447
 
                   'bzrlib.tests.per_pack_repository',
3448
 
                   'bzrlib.tests.per_repository',
3449
 
                   'bzrlib.tests.per_repository_chk',
3450
 
                   'bzrlib.tests.per_repository_reference',
3451
 
                   'bzrlib.tests.per_versionedfile',
3452
 
                   'bzrlib.tests.per_workingtree',
3453
 
                   'bzrlib.tests.test__annotator',
3454
 
                   'bzrlib.tests.test__chk_map',
3455
 
                   'bzrlib.tests.test__dirstate_helpers',
3456
 
                   'bzrlib.tests.test__groupcompress',
3457
 
                   'bzrlib.tests.test__known_graph',
3458
 
                   'bzrlib.tests.test__rio',
3459
 
                   'bzrlib.tests.test__walkdirs_win32',
3460
 
                   'bzrlib.tests.test_ancestry',
3461
 
                   'bzrlib.tests.test_annotate',
3462
 
                   'bzrlib.tests.test_api',
3463
 
                   'bzrlib.tests.test_atomicfile',
3464
 
                   'bzrlib.tests.test_bad_files',
3465
 
                   'bzrlib.tests.test_bencode',
3466
 
                   'bzrlib.tests.test_bisect_multi',
3467
 
                   'bzrlib.tests.test_branch',
3468
 
                   'bzrlib.tests.test_branchbuilder',
3469
 
                   'bzrlib.tests.test_btree_index',
3470
 
                   'bzrlib.tests.test_bugtracker',
3471
 
                   'bzrlib.tests.test_bundle',
3472
 
                   'bzrlib.tests.test_bzrdir',
3473
 
                   'bzrlib.tests.test__chunks_to_lines',
3474
 
                   'bzrlib.tests.test_cache_utf8',
3475
 
                   'bzrlib.tests.test_chk_map',
3476
 
                   'bzrlib.tests.test_chk_serializer',
3477
 
                   'bzrlib.tests.test_chunk_writer',
3478
 
                   'bzrlib.tests.test_clean_tree',
3479
 
                   'bzrlib.tests.test_commands',
3480
 
                   'bzrlib.tests.test_commit',
3481
 
                   'bzrlib.tests.test_commit_merge',
3482
 
                   'bzrlib.tests.test_config',
3483
 
                   'bzrlib.tests.test_conflicts',
3484
 
                   'bzrlib.tests.test_counted_lock',
3485
 
                   'bzrlib.tests.test_crash',
3486
 
                   'bzrlib.tests.test_decorators',
3487
 
                   'bzrlib.tests.test_delta',
3488
 
                   'bzrlib.tests.test_debug',
3489
 
                   'bzrlib.tests.test_deprecated_graph',
3490
 
                   'bzrlib.tests.test_diff',
3491
 
                   'bzrlib.tests.test_directory_service',
3492
 
                   'bzrlib.tests.test_dirstate',
3493
 
                   'bzrlib.tests.test_email_message',
3494
 
                   'bzrlib.tests.test_eol_filters',
3495
 
                   'bzrlib.tests.test_errors',
3496
 
                   'bzrlib.tests.test_export',
3497
 
                   'bzrlib.tests.test_extract',
3498
 
                   'bzrlib.tests.test_fetch',
3499
 
                   'bzrlib.tests.test_fifo_cache',
3500
 
                   'bzrlib.tests.test_filters',
3501
 
                   'bzrlib.tests.test_ftp_transport',
3502
 
                   'bzrlib.tests.test_foreign',
3503
 
                   'bzrlib.tests.test_generate_docs',
3504
 
                   'bzrlib.tests.test_generate_ids',
3505
 
                   'bzrlib.tests.test_globbing',
3506
 
                   'bzrlib.tests.test_gpg',
3507
 
                   'bzrlib.tests.test_graph',
3508
 
                   'bzrlib.tests.test_groupcompress',
3509
 
                   'bzrlib.tests.test_hashcache',
3510
 
                   'bzrlib.tests.test_help',
3511
 
                   'bzrlib.tests.test_hooks',
3512
 
                   'bzrlib.tests.test_http',
3513
 
                   'bzrlib.tests.test_http_response',
3514
 
                   'bzrlib.tests.test_https_ca_bundle',
3515
 
                   'bzrlib.tests.test_identitymap',
3516
 
                   'bzrlib.tests.test_ignores',
3517
 
                   'bzrlib.tests.test_index',
3518
 
                   'bzrlib.tests.test_info',
3519
 
                   'bzrlib.tests.test_inv',
3520
 
                   'bzrlib.tests.test_inventory_delta',
3521
 
                   'bzrlib.tests.test_knit',
3522
 
                   'bzrlib.tests.test_lazy_import',
3523
 
                   'bzrlib.tests.test_lazy_regex',
3524
 
                   'bzrlib.tests.test_lock',
3525
 
                   'bzrlib.tests.test_lockable_files',
3526
 
                   'bzrlib.tests.test_lockdir',
3527
 
                   'bzrlib.tests.test_log',
3528
 
                   'bzrlib.tests.test_lru_cache',
3529
 
                   'bzrlib.tests.test_lsprof',
3530
 
                   'bzrlib.tests.test_mail_client',
3531
 
                   'bzrlib.tests.test_memorytree',
3532
 
                   'bzrlib.tests.test_merge',
3533
 
                   'bzrlib.tests.test_merge3',
3534
 
                   'bzrlib.tests.test_merge_core',
3535
 
                   'bzrlib.tests.test_merge_directive',
3536
 
                   'bzrlib.tests.test_missing',
3537
 
                   'bzrlib.tests.test_msgeditor',
3538
 
                   'bzrlib.tests.test_multiparent',
3539
 
                   'bzrlib.tests.test_mutabletree',
3540
 
                   'bzrlib.tests.test_nonascii',
3541
 
                   'bzrlib.tests.test_options',
3542
 
                   'bzrlib.tests.test_osutils',
3543
 
                   'bzrlib.tests.test_osutils_encodings',
3544
 
                   'bzrlib.tests.test_pack',
3545
 
                   'bzrlib.tests.test_patch',
3546
 
                   'bzrlib.tests.test_patches',
3547
 
                   'bzrlib.tests.test_permissions',
3548
 
                   'bzrlib.tests.test_plugins',
3549
 
                   'bzrlib.tests.test_progress',
3550
 
                   'bzrlib.tests.test_read_bundle',
3551
 
                   'bzrlib.tests.test_reconcile',
3552
 
                   'bzrlib.tests.test_reconfigure',
3553
 
                   'bzrlib.tests.test_registry',
3554
 
                   'bzrlib.tests.test_remote',
3555
 
                   'bzrlib.tests.test_rename_map',
3556
 
                   'bzrlib.tests.test_repository',
3557
 
                   'bzrlib.tests.test_revert',
3558
 
                   'bzrlib.tests.test_revision',
3559
 
                   'bzrlib.tests.test_revisionspec',
3560
 
                   'bzrlib.tests.test_revisiontree',
3561
 
                   'bzrlib.tests.test_rio',
3562
 
                   'bzrlib.tests.test_rules',
3563
 
                   'bzrlib.tests.test_sampler',
3564
 
                   'bzrlib.tests.test_selftest',
3565
 
                   'bzrlib.tests.test_serializer',
3566
 
                   'bzrlib.tests.test_setup',
3567
 
                   'bzrlib.tests.test_sftp_transport',
3568
 
                   'bzrlib.tests.test_shelf',
3569
 
                   'bzrlib.tests.test_shelf_ui',
3570
 
                   'bzrlib.tests.test_smart',
3571
 
                   'bzrlib.tests.test_smart_add',
3572
 
                   'bzrlib.tests.test_smart_request',
3573
 
                   'bzrlib.tests.test_smart_transport',
3574
 
                   'bzrlib.tests.test_smtp_connection',
3575
 
                   'bzrlib.tests.test_source',
3576
 
                   'bzrlib.tests.test_ssh_transport',
3577
 
                   'bzrlib.tests.test_status',
3578
 
                   'bzrlib.tests.test_store',
3579
 
                   'bzrlib.tests.test_strace',
3580
 
                   'bzrlib.tests.test_subsume',
3581
 
                   'bzrlib.tests.test_switch',
3582
 
                   'bzrlib.tests.test_symbol_versioning',
3583
 
                   'bzrlib.tests.test_tag',
3584
 
                   'bzrlib.tests.test_testament',
3585
 
                   'bzrlib.tests.test_textfile',
3586
 
                   'bzrlib.tests.test_textmerge',
3587
 
                   'bzrlib.tests.test_timestamp',
3588
 
                   'bzrlib.tests.test_trace',
3589
 
                   'bzrlib.tests.test_transactions',
3590
 
                   'bzrlib.tests.test_transform',
3591
 
                   'bzrlib.tests.test_transport',
3592
 
                   'bzrlib.tests.test_transport_log',
3593
 
                   'bzrlib.tests.test_tree',
3594
 
                   'bzrlib.tests.test_treebuilder',
3595
 
                   'bzrlib.tests.test_tsort',
3596
 
                   'bzrlib.tests.test_tuned_gzip',
3597
 
                   'bzrlib.tests.test_ui',
3598
 
                   'bzrlib.tests.test_uncommit',
3599
 
                   'bzrlib.tests.test_upgrade',
3600
 
                   'bzrlib.tests.test_upgrade_stacked',
3601
 
                   'bzrlib.tests.test_urlutils',
3602
 
                   'bzrlib.tests.test_version',
3603
 
                   'bzrlib.tests.test_version_info',
3604
 
                   'bzrlib.tests.test_weave',
3605
 
                   'bzrlib.tests.test_whitebox',
3606
 
                   'bzrlib.tests.test_win32utils',
3607
 
                   'bzrlib.tests.test_workingtree',
3608
 
                   'bzrlib.tests.test_workingtree_4',
3609
 
                   'bzrlib.tests.test_wsgi',
3610
 
                   'bzrlib.tests.test_xml',
3611
 
                   ]
3612
3952
 
3613
3953
    loader = TestUtil.TestLoader()
3614
3954
 
3643
3983
    suite = loader.suiteClass()
3644
3984
 
3645
3985
    # modules building their suite with loadTestsFromModuleNames
3646
 
    suite.addTest(loader.loadTestsFromModuleNames(testmod_names))
3647
 
 
3648
 
    modules_to_doctest = [
3649
 
        'bzrlib',
3650
 
        'bzrlib.branchbuilder',
3651
 
        'bzrlib.export',
3652
 
        'bzrlib.inventory',
3653
 
        'bzrlib.iterablefile',
3654
 
        'bzrlib.lockdir',
3655
 
        'bzrlib.merge3',
3656
 
        'bzrlib.option',
3657
 
        'bzrlib.symbol_versioning',
3658
 
        'bzrlib.tests',
3659
 
        'bzrlib.timestamp',
3660
 
        'bzrlib.version_info_formats.format_custom',
3661
 
        ]
3662
 
 
3663
 
    for mod in modules_to_doctest:
 
3986
    suite.addTest(loader.loadTestsFromModuleNames(_test_suite_testmod_names()))
 
3987
 
 
3988
    for mod in _test_suite_modules_to_doctest():
3664
3989
        if not interesting_module(mod):
3665
3990
            # No tests to keep here, move along
3666
3991
            continue
3807
4132
    :param new_id: The id to assign to it.
3808
4133
    :return: The new test.
3809
4134
    """
3810
 
    from copy import deepcopy
3811
 
    new_test = deepcopy(test)
 
4135
    new_test = copy(test)
3812
4136
    new_test.id = lambda: new_id
3813
4137
    return new_test
3814
4138
 
3815
4139
 
3816
 
def _rmtree_temp_dir(dirname):
 
4140
def _rmtree_temp_dir(dirname, test_id=None):
3817
4141
    # If LANG=C we probably have created some bogus paths
3818
4142
    # which rmtree(unicode) will fail to delete
3819
4143
    # so make sure we are using rmtree(str) to delete everything
3831
4155
        # We don't want to fail here because some useful display will be lost
3832
4156
        # otherwise. Polluting the tmp dir is bad, but not giving all the
3833
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,))
3834
4161
        sys.stderr.write('Unable to remove testing dir %s\n%s'
3835
4162
                         % (os.path.basename(dirname), e))
3836
4163
 
3920
4247
UnicodeFilenameFeature = _UnicodeFilenameFeature()
3921
4248
 
3922
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
 
3923
4281
def probe_unicode_in_user_encoding():
3924
4282
    """Try to encode several unicode strings to use in unicode-aware tests.
3925
4283
    Return first successfull match.
3974
4332
HTTPSServerFeature = _HTTPSServerFeature()
3975
4333
 
3976
4334
 
 
4335
class _ParamikoFeature(Feature):
 
4336
    """Is paramiko available?"""
 
4337
 
 
4338
    def _probe(self):
 
4339
        try:
 
4340
            from bzrlib.transport.sftp import SFTPAbsoluteServer
 
4341
            return True
 
4342
        except errors.ParamikoNotPresent:
 
4343
            return False
 
4344
 
 
4345
    def feature_name(self):
 
4346
        return "Paramiko"
 
4347
 
 
4348
 
 
4349
ParamikoFeature = _ParamikoFeature()
 
4350
 
 
4351
 
3977
4352
class _UnicodeFilename(Feature):
3978
4353
    """Does the filesystem support Unicode filenames?"""
3979
4354
 
4005
4380
UTF8Filesystem = _UTF8Filesystem()
4006
4381
 
4007
4382
 
 
4383
class _BreakinFeature(Feature):
 
4384
    """Does this platform support the breakin feature?"""
 
4385
 
 
4386
    def _probe(self):
 
4387
        from bzrlib import breakin
 
4388
        if breakin.determine_signal() is None:
 
4389
            return False
 
4390
        if sys.platform == 'win32':
 
4391
            # Windows doesn't have os.kill, and we catch the SIGBREAK signal.
 
4392
            # We trigger SIGBREAK via a Console api so we need ctypes to
 
4393
            # access the function
 
4394
            try:
 
4395
                import ctypes
 
4396
            except OSError:
 
4397
                return False
 
4398
        return True
 
4399
 
 
4400
    def feature_name(self):
 
4401
        return "SIGQUIT or SIGBREAK w/ctypes on win32"
 
4402
 
 
4403
 
 
4404
BreakinFeature = _BreakinFeature()
 
4405
 
 
4406
 
4008
4407
class _CaseInsCasePresFilenameFeature(Feature):
4009
4408
    """Is the file-system case insensitive, but case-preserving?"""
4010
4409
 
4077
4476
# Only define SubUnitBzrRunner if subunit is available.
4078
4477
try:
4079
4478
    from subunit import TestProtocolClient
4080
 
    try:
4081
 
        from subunit.test_results import AutoTimingTestResultDecorator
4082
 
    except ImportError:
4083
 
        AutoTimingTestResultDecorator = lambda x:x
4084
4479
    class SubUnitBzrRunner(TextTestRunner):
4085
4480
        def run(self, test):
4086
 
            result = AutoTimingTestResultDecorator(
 
4481
            result = BzrAutoTimingTestResultDecorator(
4087
4482
                TestProtocolClient(self.stream))
4088
4483
            test.run(result)
4089
4484
            return result