~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_selftest.py

  • Committer: Robert Collins
  • Date: 2007-03-08 04:06:06 UTC
  • mfrom: (2323.1.1 integration)
  • mto: This revision was merged to the branch mainline in revision 2442.
  • Revision ID: robertc@robertcollins.net-20070308040606-84gsniv56huiyjt4
Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006 by Canonical Ltd
 
1
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
 
# it under the terms of the GNU General Public License version 2 as published by
5
 
# the Free Software Foundation.
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
6
7
#
7
8
# This program is distributed in the hope that it will be useful,
8
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15
16
 
16
17
"""Tests for the test framework."""
17
18
 
 
19
import cStringIO
18
20
import os
19
21
from StringIO import StringIO
20
22
import sys
23
25
import warnings
24
26
 
25
27
import bzrlib
 
28
from bzrlib import (
 
29
    bzrdir,
 
30
    errors,
 
31
    memorytree,
 
32
    osutils,
 
33
    repository,
 
34
    symbol_versioning,
 
35
    )
26
36
from bzrlib.progress import _BaseProgressBar
 
37
from bzrlib.repofmt import weaverepo
 
38
from bzrlib.symbol_versioning import zero_ten, zero_eleven
27
39
from bzrlib.tests import (
28
40
                          ChrootedTestCase,
29
41
                          TestCase,
30
42
                          TestCaseInTempDir,
 
43
                          TestCaseWithMemoryTransport,
31
44
                          TestCaseWithTransport,
32
45
                          TestSkipped,
33
46
                          TestSuite,
34
47
                          TextTestRunner,
35
48
                          )
 
49
from bzrlib.tests.test_sftp_transport import TestCaseWithSFTPServer
36
50
from bzrlib.tests.TestUtil import _load_module_by_name
37
 
import bzrlib.errors as errors
 
51
from bzrlib.trace import note
 
52
from bzrlib.transport.memory import MemoryServer, MemoryTransport
 
53
from bzrlib.version import _get_bzr_source_tree
38
54
 
39
55
 
40
56
class SelftestTests(TestCase):
48
64
                          _load_module_by_name,
49
65
                          'bzrlib.no-name-yet')
50
66
 
51
 
 
52
67
class MetaTestLog(TestCase):
53
68
 
54
69
    def test_logging(self):
55
70
        """Test logs are captured when a test fails."""
56
71
        self.log('a test message')
57
72
        self._log_file.flush()
58
 
        self.assertContainsRe(self._get_log(), 'a test message\n')
 
73
        self.assertContainsRe(self._get_log(keep_log_file=True),
 
74
                              'a test message\n')
59
75
 
60
76
 
61
77
class TestTreeShape(TestCaseInTempDir):
322
338
        self.assertEqual(tests[1].transport_readonly_server, server2)
323
339
 
324
340
 
 
341
class TestTreeProviderAdapter(TestCase):
 
342
    """Test the setup of tree_implementation tests."""
 
343
 
 
344
    def test_adapted_tests(self):
 
345
        # the tree implementation adapter is meant to setup one instance for
 
346
        # each working tree format, and one additional instance that will
 
347
        # use the default wt format, but create a revision tree for the tests.
 
348
        # this means that the wt ones should have the workingtree_to_test_tree
 
349
        # attribute set to 'return_parameter' and the revision one set to
 
350
        # revision_tree_from_workingtree.
 
351
 
 
352
        from bzrlib.tests.tree_implementations import (
 
353
            TreeTestProviderAdapter,
 
354
            return_parameter,
 
355
            revision_tree_from_workingtree
 
356
            )
 
357
        from bzrlib.workingtree import WorkingTreeFormat, WorkingTreeFormat3
 
358
        input_test = TestTreeProviderAdapter(
 
359
            "test_adapted_tests")
 
360
        server1 = "a"
 
361
        server2 = "b"
 
362
        formats = [("c", "C"), ("d", "D")]
 
363
        adapter = TreeTestProviderAdapter(server1, server2, formats)
 
364
        suite = adapter.adapt(input_test)
 
365
        tests = list(iter(suite))
 
366
        self.assertEqual(4, len(tests))
 
367
        # this must match the default format setp up in
 
368
        # TreeTestProviderAdapter.adapt
 
369
        default_format = WorkingTreeFormat3
 
370
        self.assertEqual(tests[0].workingtree_format, formats[0][0])
 
371
        self.assertEqual(tests[0].bzrdir_format, formats[0][1])
 
372
        self.assertEqual(tests[0].transport_server, server1)
 
373
        self.assertEqual(tests[0].transport_readonly_server, server2)
 
374
        self.assertEqual(tests[0].workingtree_to_test_tree, return_parameter)
 
375
        self.assertEqual(tests[1].workingtree_format, formats[1][0])
 
376
        self.assertEqual(tests[1].bzrdir_format, formats[1][1])
 
377
        self.assertEqual(tests[1].transport_server, server1)
 
378
        self.assertEqual(tests[1].transport_readonly_server, server2)
 
379
        self.assertEqual(tests[1].workingtree_to_test_tree, return_parameter)
 
380
        self.assertIsInstance(tests[2].workingtree_format, default_format)
 
381
        #self.assertEqual(tests[2].bzrdir_format,
 
382
        #                 default_format._matchingbzrdir)
 
383
        self.assertEqual(tests[2].transport_server, server1)
 
384
        self.assertEqual(tests[2].transport_readonly_server, server2)
 
385
        self.assertEqual(tests[2].workingtree_to_test_tree,
 
386
            revision_tree_from_workingtree)
 
387
 
 
388
 
 
389
class TestInterTreeProviderAdapter(TestCase):
 
390
    """A group of tests that test the InterTreeTestAdapter."""
 
391
 
 
392
    def test_adapted_tests(self):
 
393
        # check that constructor parameters are passed through to the adapted
 
394
        # test.
 
395
        # for InterTree tests we want the machinery to bring up two trees in
 
396
        # each instance: the base one, and the one we are interacting with.
 
397
        # because each optimiser can be direction specific, we need to test
 
398
        # each optimiser in its chosen direction.
 
399
        # unlike the TestProviderAdapter we dont want to automatically add a
 
400
        # parameterised one for WorkingTree - the optimisers will tell us what
 
401
        # ones to add.
 
402
        from bzrlib.tests.tree_implementations import (
 
403
            return_parameter,
 
404
            revision_tree_from_workingtree
 
405
            )
 
406
        from bzrlib.tests.intertree_implementations import (
 
407
            InterTreeTestProviderAdapter,
 
408
            )
 
409
        from bzrlib.workingtree import WorkingTreeFormat2, WorkingTreeFormat3
 
410
        input_test = TestInterTreeProviderAdapter(
 
411
            "test_adapted_tests")
 
412
        server1 = "a"
 
413
        server2 = "b"
 
414
        format1 = WorkingTreeFormat2()
 
415
        format2 = WorkingTreeFormat3()
 
416
        formats = [(str, format1, format2, "converter1"),
 
417
            (int, format2, format1, "converter2")]
 
418
        adapter = InterTreeTestProviderAdapter(server1, server2, formats)
 
419
        suite = adapter.adapt(input_test)
 
420
        tests = list(iter(suite))
 
421
        self.assertEqual(2, len(tests))
 
422
        self.assertEqual(tests[0].intertree_class, formats[0][0])
 
423
        self.assertEqual(tests[0].workingtree_format, formats[0][1])
 
424
        self.assertEqual(tests[0].workingtree_format_to, formats[0][2])
 
425
        self.assertEqual(tests[0].mutable_trees_to_test_trees, formats[0][3])
 
426
        self.assertEqual(tests[0].workingtree_to_test_tree, return_parameter)
 
427
        self.assertEqual(tests[0].transport_server, server1)
 
428
        self.assertEqual(tests[0].transport_readonly_server, server2)
 
429
        self.assertEqual(tests[1].intertree_class, formats[1][0])
 
430
        self.assertEqual(tests[1].workingtree_format, formats[1][1])
 
431
        self.assertEqual(tests[1].workingtree_format_to, formats[1][2])
 
432
        self.assertEqual(tests[1].mutable_trees_to_test_trees, formats[1][3])
 
433
        self.assertEqual(tests[1].workingtree_to_test_tree, return_parameter)
 
434
        self.assertEqual(tests[1].transport_server, server1)
 
435
        self.assertEqual(tests[1].transport_readonly_server, server2)
 
436
 
 
437
 
 
438
class TestTestCaseInTempDir(TestCaseInTempDir):
 
439
 
 
440
    def test_home_is_not_working(self):
 
441
        self.assertNotEqual(self.test_dir, self.test_home_dir)
 
442
        cwd = osutils.getcwd()
 
443
        self.assertEqual(self.test_dir, cwd)
 
444
        self.assertEqual(self.test_home_dir, os.environ['HOME'])
 
445
 
 
446
 
 
447
class TestTestCaseWithMemoryTransport(TestCaseWithMemoryTransport):
 
448
 
 
449
    def test_home_is_non_existant_dir_under_root(self):
 
450
        """The test_home_dir for TestCaseWithMemoryTransport is missing.
 
451
 
 
452
        This is because TestCaseWithMemoryTransport is for tests that do not
 
453
        need any disk resources: they should be hooked into bzrlib in such a 
 
454
        way that no global settings are being changed by the test (only a 
 
455
        few tests should need to do that), and having a missing dir as home is
 
456
        an effective way to ensure that this is the case.
 
457
        """
 
458
        self.assertEqual(self.TEST_ROOT + "/MemoryTransportMissingHomeDir",
 
459
            self.test_home_dir)
 
460
        self.assertEqual(self.test_home_dir, os.environ['HOME'])
 
461
        
 
462
    def test_cwd_is_TEST_ROOT(self):
 
463
        self.assertEqual(self.test_dir, self.TEST_ROOT)
 
464
        cwd = osutils.getcwd()
 
465
        self.assertEqual(self.test_dir, cwd)
 
466
 
 
467
    def test_make_branch_and_memory_tree(self):
 
468
        """In TestCaseWithMemoryTransport we should not make the branch on disk.
 
469
 
 
470
        This is hard to comprehensively robustly test, so we settle for making
 
471
        a branch and checking no directory was created at its relpath.
 
472
        """
 
473
        tree = self.make_branch_and_memory_tree('dir')
 
474
        # Guard against regression into MemoryTransport leaking
 
475
        # files to disk instead of keeping them in memory.
 
476
        self.failIf(osutils.lexists('dir'))
 
477
        self.assertIsInstance(tree, memorytree.MemoryTree)
 
478
 
 
479
    def test_make_branch_and_memory_tree_with_format(self):
 
480
        """make_branch_and_memory_tree should accept a format option."""
 
481
        format = bzrdir.BzrDirMetaFormat1()
 
482
        format.repository_format = weaverepo.RepositoryFormat7()
 
483
        tree = self.make_branch_and_memory_tree('dir', format=format)
 
484
        # Guard against regression into MemoryTransport leaking
 
485
        # files to disk instead of keeping them in memory.
 
486
        self.failIf(osutils.lexists('dir'))
 
487
        self.assertIsInstance(tree, memorytree.MemoryTree)
 
488
        self.assertEqual(format.repository_format.__class__,
 
489
            tree.branch.repository._format.__class__)
 
490
 
 
491
 
325
492
class TestTestCaseWithTransport(TestCaseWithTransport):
326
493
    """Tests for the convenience functions TestCaseWithTransport introduces."""
327
494
 
342
509
        self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
343
510
 
344
511
    def test_get_readonly_url_http(self):
 
512
        from bzrlib.tests.HttpServer import HttpServer
345
513
        from bzrlib.transport import get_transport
346
 
        from bzrlib.transport.local import LocalRelpathServer
347
 
        from bzrlib.transport.http import HttpServer, HttpTransportBase
348
 
        self.transport_server = LocalRelpathServer
 
514
        from bzrlib.transport.local import LocalURLServer
 
515
        from bzrlib.transport.http import HttpTransportBase
 
516
        self.transport_server = LocalURLServer
349
517
        self.transport_readonly_server = HttpServer
350
518
        # calling get_readonly_transport() gives us a HTTP server instance.
351
519
        url = self.get_readonly_url()
366
534
        self.assertRaises(AssertionError, self.assertIsDirectory, 'not_here', t)
367
535
 
368
536
 
 
537
class TestTestCaseTransports(TestCaseWithTransport):
 
538
 
 
539
    def setUp(self):
 
540
        super(TestTestCaseTransports, self).setUp()
 
541
        self.transport_server = MemoryServer
 
542
 
 
543
    def test_make_bzrdir_preserves_transport(self):
 
544
        t = self.get_transport()
 
545
        result_bzrdir = self.make_bzrdir('subdir')
 
546
        self.assertIsInstance(result_bzrdir.transport, 
 
547
                              MemoryTransport)
 
548
        # should not be on disk, should only be in memory
 
549
        self.failIfExists('subdir')
 
550
 
 
551
 
369
552
class TestChrootedTest(ChrootedTestCase):
370
553
 
371
554
    def test_root_is_root(self):
394
577
    def clear(self):
395
578
        self.calls.append(('clear',))
396
579
 
 
580
    def note(self, msg, *args):
 
581
        self.calls.append(('note', msg, args))
 
582
 
397
583
 
398
584
class TestTestResult(TestCase):
399
585
 
400
 
    def test_progress_bar_style_quiet(self):
401
 
        # test using a progress bar.
402
 
        dummy_test = TestTestResult('test_progress_bar_style_quiet')
403
 
        dummy_error = (Exception, None, [])
404
 
        mypb = MockProgress()
405
 
        mypb.update('Running tests', 0, 4)
406
 
        last_calls = mypb.calls[:]
407
 
        result = bzrlib.tests._MyResult(self._log_file,
408
 
                                        descriptions=0,
409
 
                                        verbosity=1,
410
 
                                        pb=mypb)
411
 
        self.assertEqual(last_calls, mypb.calls)
412
 
 
413
 
        # an error 
414
 
        result.startTest(dummy_test)
415
 
        # starting a test prints the test name
416
 
        self.assertEqual(last_calls + [('update', '...tyle_quiet', 0, None)], mypb.calls)
417
 
        last_calls = mypb.calls[:]
418
 
        result.addError(dummy_test, dummy_error)
419
 
        self.assertEqual(last_calls + [('update', 'ERROR        ', 1, None)], mypb.calls)
420
 
        last_calls = mypb.calls[:]
421
 
 
422
 
        # a failure
423
 
        result.startTest(dummy_test)
424
 
        self.assertEqual(last_calls + [('update', '...tyle_quiet', 1, None)], mypb.calls)
425
 
        last_calls = mypb.calls[:]
426
 
        result.addFailure(dummy_test, dummy_error)
427
 
        self.assertEqual(last_calls + [('update', 'FAIL         ', 2, None)], mypb.calls)
428
 
        last_calls = mypb.calls[:]
429
 
 
430
 
        # a success
431
 
        result.startTest(dummy_test)
432
 
        self.assertEqual(last_calls + [('update', '...tyle_quiet', 2, None)], mypb.calls)
433
 
        last_calls = mypb.calls[:]
434
 
        result.addSuccess(dummy_test)
435
 
        self.assertEqual(last_calls + [('update', 'OK           ', 3, None)], mypb.calls)
436
 
        last_calls = mypb.calls[:]
437
 
 
438
 
        # a skip
439
 
        result.startTest(dummy_test)
440
 
        self.assertEqual(last_calls + [('update', '...tyle_quiet', 3, None)], mypb.calls)
441
 
        last_calls = mypb.calls[:]
442
 
        result.addSkipped(dummy_test, dummy_error)
443
 
        self.assertEqual(last_calls + [('update', 'SKIP         ', 4, None)], mypb.calls)
444
 
        last_calls = mypb.calls[:]
445
 
 
446
586
    def test_elapsed_time_with_benchmarking(self):
447
 
        result = bzrlib.tests._MyResult(self._log_file,
 
587
        result = bzrlib.tests.TextTestResult(self._log_file,
448
588
                                        descriptions=0,
449
589
                                        verbosity=1,
450
590
                                        )
453
593
        result.extractBenchmarkTime(self)
454
594
        timed_string = result._testTimeString()
455
595
        # without explicit benchmarking, we should get a simple time.
456
 
        self.assertContainsRe(timed_string, "^         [ 1-9][0-9]ms$")
 
596
        self.assertContainsRe(timed_string, "^ *[ 1-9][0-9]ms$")
457
597
        # if a benchmark time is given, we want a x of y style result.
458
598
        self.time(time.sleep, 0.001)
459
599
        result.extractBenchmarkTime(self)
460
600
        timed_string = result._testTimeString()
461
 
        self.assertContainsRe(timed_string, "^    [0-9]ms/   [ 1-9][0-9]ms$")
 
601
        self.assertContainsRe(timed_string, "^ *[ 1-9][0-9]ms/ *[ 1-9][0-9]ms$")
462
602
        # extracting the time from a non-bzrlib testcase sets to None
463
603
        result._recordTestStartTime()
464
604
        result.extractBenchmarkTime(
465
605
            unittest.FunctionTestCase(self.test_elapsed_time_with_benchmarking))
466
606
        timed_string = result._testTimeString()
467
 
        self.assertContainsRe(timed_string, "^          [0-9]ms$")
 
607
        self.assertContainsRe(timed_string, "^ *[ 1-9][0-9]ms$")
468
608
        # cheat. Yes, wash thy mouth out with soap.
469
609
        self._benchtime = None
470
610
 
 
611
    def test_assigned_benchmark_file_stores_date(self):
 
612
        output = StringIO()
 
613
        result = bzrlib.tests.TextTestResult(self._log_file,
 
614
                                        descriptions=0,
 
615
                                        verbosity=1,
 
616
                                        bench_history=output
 
617
                                        )
 
618
        output_string = output.getvalue()
 
619
        
 
620
        # if you are wondering about the regexp please read the comment in
 
621
        # test_bench_history (bzrlib.tests.test_selftest.TestRunner)
 
622
        # XXX: what comment?  -- Andrew Bennetts
 
623
        self.assertContainsRe(output_string, "--date [0-9.]+")
 
624
 
 
625
    def test_benchhistory_records_test_times(self):
 
626
        result_stream = StringIO()
 
627
        result = bzrlib.tests.TextTestResult(
 
628
            self._log_file,
 
629
            descriptions=0,
 
630
            verbosity=1,
 
631
            bench_history=result_stream
 
632
            )
 
633
 
 
634
        # we want profile a call and check that its test duration is recorded
 
635
        # make a new test instance that when run will generate a benchmark
 
636
        example_test_case = TestTestResult("_time_hello_world_encoding")
 
637
        # execute the test, which should succeed and record times
 
638
        example_test_case.run(result)
 
639
        lines = result_stream.getvalue().splitlines()
 
640
        self.assertEqual(2, len(lines))
 
641
        self.assertContainsRe(lines[1],
 
642
            " *[0-9]+ms bzrlib.tests.test_selftest.TestTestResult"
 
643
            "._time_hello_world_encoding")
 
644
 
471
645
    def _time_hello_world_encoding(self):
472
646
        """Profile two sleep calls
473
647
        
483
657
        except ImportError:
484
658
            raise TestSkipped("lsprof not installed.")
485
659
        result_stream = StringIO()
486
 
        result = bzrlib.tests._MyResult(
 
660
        result = bzrlib.tests.VerboseTestResult(
487
661
            unittest._WritelnDecorator(result_stream),
488
662
            descriptions=0,
489
663
            verbosity=2,
506
680
        #           1        0            ???         ???       ???(sleep) 
507
681
        # and then repeated but with 'world', rather than 'hello'.
508
682
        # this should appear in the output stream of our test result.
509
 
        self.assertContainsRe(result_stream.getvalue(), 
510
 
            r"LSProf output for <type 'unicode'>\(\('hello',\), {'errors': 'replace'}\)\n"
511
 
            r" *CallCount *Recursive *Total\(ms\) *Inline\(ms\) *module:lineno\(function\)\n"
512
 
            r"( +1 +0 +0\.\d+ +0\.\d+ +<method 'disable' of '_lsprof\.Profiler' objects>\n)?"
513
 
            r"LSProf output for <type 'unicode'>\(\('world',\), {'errors': 'replace'}\)\n"
514
 
            r" *CallCount *Recursive *Total\(ms\) *Inline\(ms\) *module:lineno\(function\)\n"
515
 
            r"( +1 +0 +0\.\d+ +0\.\d+ +<method 'disable' of '_lsprof\.Profiler' objects>\n)?"
516
 
            )
 
683
        output = result_stream.getvalue()
 
684
        self.assertContainsRe(output,
 
685
            r"LSProf output for <type 'unicode'>\(\('hello',\), {'errors': 'replace'}\)")
 
686
        self.assertContainsRe(output,
 
687
            r" *CallCount *Recursive *Total\(ms\) *Inline\(ms\) *module:lineno\(function\)\n")
 
688
        self.assertContainsRe(output,
 
689
            r"( +1 +0 +0\.\d+ +0\.\d+ +<method 'disable' of '_lsprof\.Profiler' objects>\n)?")
 
690
        self.assertContainsRe(output,
 
691
            r"LSProf output for <type 'unicode'>\(\('world',\), {'errors': 'replace'}\)\n")
517
692
 
518
693
 
519
694
class TestRunner(TestCase):
537
712
        finally:
538
713
            TestCaseInTempDir.TEST_ROOT = old_root
539
714
 
540
 
    def test_accepts_and_uses_pb_parameter(self):
541
 
        test = TestRunner('dummy_test')
542
 
        mypb = MockProgress()
543
 
        self.assertEqual([], mypb.calls)
544
 
        runner = TextTestRunner(stream=self._log_file, pb=mypb)
545
 
        result = self.run_test_runner(runner, test)
546
 
        self.assertEqual(1, result.testsRun)
547
 
        self.assertEqual(('update', 'Running tests', 0, 1), mypb.calls[0])
548
 
        self.assertEqual(('update', '...dummy_test', 0, None), mypb.calls[1])
549
 
        self.assertEqual(('update', 'OK           ', 1, None), mypb.calls[2])
550
 
        self.assertEqual(('update', 'Cleaning up', 0, 1), mypb.calls[3])
551
 
        self.assertEqual(('clear',), mypb.calls[4])
552
 
        self.assertEqual(5, len(mypb.calls))
553
 
 
554
715
    def test_skipped_test(self):
555
716
        # run a test that is skipped, and check the suite as a whole still
556
717
        # succeeds.
562
723
        result = self.run_test_runner(runner, test)
563
724
        self.assertTrue(result.wasSuccessful())
564
725
 
 
726
    def test_bench_history(self):
 
727
        # tests that the running the benchmark produces a history file
 
728
        # containing a timestamp and the revision id of the bzrlib source which
 
729
        # was tested.
 
730
        workingtree = _get_bzr_source_tree()
 
731
        test = TestRunner('dummy_test')
 
732
        output = StringIO()
 
733
        runner = TextTestRunner(stream=self._log_file, bench_history=output)
 
734
        result = self.run_test_runner(runner, test)
 
735
        output_string = output.getvalue()
 
736
        self.assertContainsRe(output_string, "--date [0-9.]+")
 
737
        if workingtree is not None:
 
738
            revision_id = workingtree.get_parent_ids()[0]
 
739
            self.assertEndsWith(output_string.rstrip(), revision_id)
 
740
 
 
741
    def test_success_log_deleted(self):
 
742
        """Successful tests have their log deleted"""
 
743
 
 
744
        class LogTester(TestCase):
 
745
 
 
746
            def test_success(self):
 
747
                self.log('this will be removed\n')
 
748
 
 
749
        sio = cStringIO.StringIO()
 
750
        runner = TextTestRunner(stream=sio)
 
751
        test = LogTester('test_success')
 
752
        result = self.run_test_runner(runner, test)
 
753
 
 
754
        log = test._get_log()
 
755
        self.assertEqual("DELETED log file to reduce memory footprint", log)
 
756
        self.assertEqual('', test._log_contents)
 
757
        self.assertIs(None, test._log_file_name)
 
758
 
 
759
    def test_fail_log_kept(self):
 
760
        """Failed tests have their log kept"""
 
761
 
 
762
        class LogTester(TestCase):
 
763
 
 
764
            def test_fail(self):
 
765
                self.log('this will be kept\n')
 
766
                self.fail('this test fails')
 
767
 
 
768
        sio = cStringIO.StringIO()
 
769
        runner = TextTestRunner(stream=sio)
 
770
        test = LogTester('test_fail')
 
771
        result = self.run_test_runner(runner, test)
 
772
 
 
773
        text = sio.getvalue()
 
774
        self.assertContainsRe(text, 'this will be kept')
 
775
        self.assertContainsRe(text, 'this test fails')
 
776
 
 
777
        log = test._get_log()
 
778
        self.assertContainsRe(log, 'this will be kept')
 
779
        self.assertEqual(log, test._log_contents)
 
780
 
 
781
    def test_error_log_kept(self):
 
782
        """Tests with errors have their log kept"""
 
783
 
 
784
        class LogTester(TestCase):
 
785
 
 
786
            def test_error(self):
 
787
                self.log('this will be kept\n')
 
788
                raise ValueError('random exception raised')
 
789
 
 
790
        sio = cStringIO.StringIO()
 
791
        runner = TextTestRunner(stream=sio)
 
792
        test = LogTester('test_error')
 
793
        result = self.run_test_runner(runner, test)
 
794
 
 
795
        text = sio.getvalue()
 
796
        self.assertContainsRe(text, 'this will be kept')
 
797
        self.assertContainsRe(text, 'random exception raised')
 
798
 
 
799
        log = test._get_log()
 
800
        self.assertContainsRe(log, 'this will be kept')
 
801
        self.assertEqual(log, test._log_contents)
 
802
 
565
803
 
566
804
class TestTestCase(TestCase):
567
805
    """Tests that test the core bzrlib TestCase."""
574
812
        # the outer child test
575
813
        note("outer_start")
576
814
        self.inner_test = TestTestCase("inner_child")
577
 
        result = bzrlib.tests._MyResult(self._log_file,
 
815
        result = bzrlib.tests.TextTestResult(self._log_file,
578
816
                                        descriptions=0,
579
817
                                        verbosity=1)
580
818
        self.inner_test.run(result)
594
832
        # the outer child test
595
833
        original_trace = bzrlib.trace._trace_file
596
834
        outer_test = TestTestCase("outer_child")
597
 
        result = bzrlib.tests._MyResult(self._log_file,
 
835
        result = bzrlib.tests.TextTestResult(self._log_file,
598
836
                                        descriptions=0,
599
837
                                        verbosity=1)
600
838
        outer_test.run(result)
609
847
        """Test that the TestCase.time() method accumulates a benchmark time."""
610
848
        sample_test = TestTestCase("method_that_times_a_bit_twice")
611
849
        output_stream = StringIO()
612
 
        result = bzrlib.tests._MyResult(
 
850
        result = bzrlib.tests.VerboseTestResult(
613
851
            unittest._WritelnDecorator(output_stream),
614
852
            descriptions=0,
615
 
            verbosity=2)
 
853
            verbosity=2,
 
854
            num_tests=sample_test.countTestCases())
616
855
        sample_test.run(result)
617
856
        self.assertContainsRe(
618
857
            output_stream.getvalue(),
619
 
            "[1-9][0-9]ms/   [1-9][0-9]ms\n$")
620
 
        
 
858
            r"\d+ms/ +\d+ms\n$")
 
859
 
 
860
    def test_hooks_sanitised(self):
 
861
        """The bzrlib hooks should be sanitised by setUp."""
 
862
        self.assertEqual(bzrlib.branch.BranchHooks(),
 
863
            bzrlib.branch.Branch.hooks)
 
864
 
621
865
    def test__gather_lsprof_in_benchmarks(self):
622
866
        """When _gather_lsprof_in_benchmarks is on, accumulate profile data.
623
867
        
639
883
        self.assertIsInstance(self._benchcalls[1][1], bzrlib.lsprof.Stats)
640
884
 
641
885
 
 
886
@symbol_versioning.deprecated_function(zero_eleven)
 
887
def sample_deprecated_function():
 
888
    """A deprecated function to test applyDeprecated with."""
 
889
    return 2
 
890
 
 
891
 
 
892
def sample_undeprecated_function(a_param):
 
893
    """A undeprecated function to test applyDeprecated with."""
 
894
 
 
895
 
 
896
class ApplyDeprecatedHelper(object):
 
897
    """A helper class for ApplyDeprecated tests."""
 
898
 
 
899
    @symbol_versioning.deprecated_method(zero_eleven)
 
900
    def sample_deprecated_method(self, param_one):
 
901
        """A deprecated method for testing with."""
 
902
        return param_one
 
903
 
 
904
    def sample_normal_method(self):
 
905
        """A undeprecated method."""
 
906
 
 
907
    @symbol_versioning.deprecated_method(zero_ten)
 
908
    def sample_nested_deprecation(self):
 
909
        return sample_deprecated_function()
 
910
 
 
911
 
642
912
class TestExtraAssertions(TestCase):
643
913
    """Tests for new test assertions in bzrlib test suite"""
644
914
 
652
922
        self.assertEndsWith('foo', 'oo')
653
923
        self.assertRaises(AssertionError, self.assertEndsWith, 'o', 'oo')
654
924
 
 
925
    def test_applyDeprecated_not_deprecated(self):
 
926
        sample_object = ApplyDeprecatedHelper()
 
927
        # calling an undeprecated callable raises an assertion
 
928
        self.assertRaises(AssertionError, self.applyDeprecated, zero_eleven,
 
929
            sample_object.sample_normal_method)
 
930
        self.assertRaises(AssertionError, self.applyDeprecated, zero_eleven,
 
931
            sample_undeprecated_function, "a param value")
 
932
        # calling a deprecated callable (function or method) with the wrong
 
933
        # expected deprecation fails.
 
934
        self.assertRaises(AssertionError, self.applyDeprecated, zero_ten,
 
935
            sample_object.sample_deprecated_method, "a param value")
 
936
        self.assertRaises(AssertionError, self.applyDeprecated, zero_ten,
 
937
            sample_deprecated_function)
 
938
        # calling a deprecated callable (function or method) with the right
 
939
        # expected deprecation returns the functions result.
 
940
        self.assertEqual("a param value", self.applyDeprecated(zero_eleven,
 
941
            sample_object.sample_deprecated_method, "a param value"))
 
942
        self.assertEqual(2, self.applyDeprecated(zero_eleven,
 
943
            sample_deprecated_function))
 
944
        # calling a nested deprecation with the wrong deprecation version
 
945
        # fails even if a deeper nested function was deprecated with the 
 
946
        # supplied version.
 
947
        self.assertRaises(AssertionError, self.applyDeprecated,
 
948
            zero_eleven, sample_object.sample_nested_deprecation)
 
949
        # calling a nested deprecation with the right deprecation value
 
950
        # returns the calls result.
 
951
        self.assertEqual(2, self.applyDeprecated(zero_ten,
 
952
            sample_object.sample_nested_deprecation))
 
953
 
 
954
    def test_callDeprecated(self):
 
955
        def testfunc(be_deprecated, result=None):
 
956
            if be_deprecated is True:
 
957
                symbol_versioning.warn('i am deprecated', DeprecationWarning, 
 
958
                                       stacklevel=1)
 
959
            return result
 
960
        result = self.callDeprecated(['i am deprecated'], testfunc, True)
 
961
        self.assertIs(None, result)
 
962
        result = self.callDeprecated([], testfunc, False, 'result')
 
963
        self.assertEqual('result', result)
 
964
        self.callDeprecated(['i am deprecated'], testfunc, be_deprecated=True)
 
965
        self.callDeprecated([], testfunc, be_deprecated=False)
 
966
 
655
967
 
656
968
class TestConvenienceMakers(TestCaseWithTransport):
657
969
    """Test for the make_* convenience functions."""
665
977
        self.assertIsInstance(bzrlib.bzrdir.BzrDir.open('b')._format,
666
978
                              bzrlib.bzrdir.BzrDirFormat6)
667
979
 
 
980
    def test_make_branch_and_memory_tree(self):
 
981
        # we should be able to get a new branch and a mutable tree from
 
982
        # TestCaseWithTransport
 
983
        tree = self.make_branch_and_memory_tree('a')
 
984
        self.assertIsInstance(tree, bzrlib.memorytree.MemoryTree)
 
985
 
 
986
 
 
987
class TestSFTPMakeBranchAndTree(TestCaseWithSFTPServer):
 
988
 
 
989
    def test_make_tree_for_sftp_branch(self):
 
990
        """Transports backed by local directories create local trees."""
 
991
 
 
992
        tree = self.make_branch_and_tree('t1')
 
993
        base = tree.bzrdir.root_transport.base
 
994
        self.failIf(base.startswith('sftp'),
 
995
                'base %r is on sftp but should be local' % base)
 
996
        self.assertEquals(tree.bzrdir.root_transport,
 
997
                tree.branch.bzrdir.root_transport)
 
998
        self.assertEquals(tree.bzrdir.root_transport,
 
999
                tree.branch.repository.bzrdir.root_transport)
 
1000
 
668
1001
 
669
1002
class TestSelftest(TestCase):
670
1003
    """Tests of bzrlib.tests.selftest."""
679
1012
        self.apply_redirected(out, err, None, bzrlib.tests.selftest, 
680
1013
            test_suite_factory=factory)
681
1014
        self.assertEqual([True], factory_called)
 
1015
 
 
1016
 
 
1017
class TestSelftestCleanOutput(TestCaseInTempDir):
 
1018
 
 
1019
    def test_clean_output(self):
 
1020
        # test functionality of clean_selftest_output()
 
1021
        from bzrlib.tests import clean_selftest_output
 
1022
 
 
1023
        dirs = ('test0000.tmp', 'test0001.tmp', 'bzrlib', 'tests')
 
1024
        files = ('bzr', 'setup.py', 'test9999.tmp')
 
1025
        for i in dirs:
 
1026
            os.mkdir(i)
 
1027
        for i in files:
 
1028
            f = file(i, 'wb')
 
1029
            f.write('content of ')
 
1030
            f.write(i)
 
1031
            f.close()
 
1032
 
 
1033
        root = os.getcwdu()
 
1034
        before = os.listdir(root)
 
1035
        before.sort()
 
1036
        self.assertEquals(['bzr','bzrlib','setup.py',
 
1037
                           'test0000.tmp','test0001.tmp',
 
1038
                           'test9999.tmp','tests'],
 
1039
                           before)
 
1040
        clean_selftest_output(root, quiet=True)
 
1041
        after = os.listdir(root)
 
1042
        after.sort()
 
1043
        self.assertEquals(['bzr','bzrlib','setup.py',
 
1044
                           'test9999.tmp','tests'],
 
1045
                           after)