~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_selftest.py

  • Committer: John Arbash Meinel
  • Date: 2006-09-11 22:48:57 UTC
  • mto: This revision was merged to the branch mainline in revision 2004.
  • Revision ID: john@arbash-meinel.com-20060911224857-d7008be21aeee33e
Switch from individual functions to a class

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
import unittest
23
23
import warnings
24
24
 
 
25
from bzrlib import osutils
25
26
import bzrlib
26
27
from bzrlib.progress import _BaseProgressBar
27
28
from bzrlib.tests import (
35
36
                          )
36
37
from bzrlib.tests.TestUtil import _load_module_by_name
37
38
import bzrlib.errors as errors
 
39
from bzrlib import symbol_versioning
 
40
from bzrlib.symbol_versioning import zero_ten, zero_eleven
 
41
from bzrlib.trace import note
 
42
from bzrlib.version import _get_bzr_source_tree
38
43
 
39
44
 
40
45
class SelftestTests(TestCase):
322
327
        self.assertEqual(tests[1].transport_readonly_server, server2)
323
328
 
324
329
 
 
330
class TestTreeProviderAdapter(TestCase):
 
331
    """Test the setup of tree_implementation tests."""
 
332
 
 
333
    def test_adapted_tests(self):
 
334
        # the tree implementation adapter is meant to setup one instance for
 
335
        # each working tree format, and one additional instance that will
 
336
        # use the default wt format, but create a revision tree for the tests.
 
337
        # this means that the wt ones should have the workingtree_to_test_tree
 
338
        # attribute set to 'return_parameter' and the revision one set to
 
339
        # revision_tree_from_workingtree.
 
340
 
 
341
        from bzrlib.tests.tree_implementations import (
 
342
            TreeTestProviderAdapter,
 
343
            return_parameter,
 
344
            revision_tree_from_workingtree
 
345
            )
 
346
        from bzrlib.workingtree import WorkingTreeFormat
 
347
        input_test = TestTreeProviderAdapter(
 
348
            "test_adapted_tests")
 
349
        server1 = "a"
 
350
        server2 = "b"
 
351
        formats = [("c", "C"), ("d", "D")]
 
352
        adapter = TreeTestProviderAdapter(server1, server2, formats)
 
353
        suite = adapter.adapt(input_test)
 
354
        tests = list(iter(suite))
 
355
        self.assertEqual(3, len(tests))
 
356
        default_format = WorkingTreeFormat.get_default_format()
 
357
        self.assertEqual(tests[0].workingtree_format, formats[0][0])
 
358
        self.assertEqual(tests[0].bzrdir_format, formats[0][1])
 
359
        self.assertEqual(tests[0].transport_server, server1)
 
360
        self.assertEqual(tests[0].transport_readonly_server, server2)
 
361
        self.assertEqual(tests[0].workingtree_to_test_tree, return_parameter)
 
362
        self.assertEqual(tests[1].workingtree_format, formats[1][0])
 
363
        self.assertEqual(tests[1].bzrdir_format, formats[1][1])
 
364
        self.assertEqual(tests[1].transport_server, server1)
 
365
        self.assertEqual(tests[1].transport_readonly_server, server2)
 
366
        self.assertEqual(tests[1].workingtree_to_test_tree, return_parameter)
 
367
        self.assertEqual(tests[2].workingtree_format, default_format)
 
368
        self.assertEqual(tests[2].bzrdir_format, default_format._matchingbzrdir)
 
369
        self.assertEqual(tests[2].transport_server, server1)
 
370
        self.assertEqual(tests[2].transport_readonly_server, server2)
 
371
        self.assertEqual(tests[2].workingtree_to_test_tree,
 
372
            revision_tree_from_workingtree)
 
373
 
 
374
 
 
375
class TestInterTreeProviderAdapter(TestCase):
 
376
    """A group of tests that test the InterTreeTestAdapter."""
 
377
 
 
378
    def test_adapted_tests(self):
 
379
        # check that constructor parameters are passed through to the adapted
 
380
        # test.
 
381
        # for InterTree tests we want the machinery to bring up two trees in
 
382
        # each instance: the base one, and the one we are interacting with.
 
383
        # because each optimiser can be direction specific, we need to test
 
384
        # each optimiser in its chosen direction.
 
385
        # unlike the TestProviderAdapter we dont want to automatically add a
 
386
        # parameterised one for WorkingTree - the optimisers will tell us what
 
387
        # ones to add.
 
388
        from bzrlib.tests.tree_implementations import (
 
389
            return_parameter,
 
390
            revision_tree_from_workingtree
 
391
            )
 
392
        from bzrlib.tests.intertree_implementations import (
 
393
            InterTreeTestProviderAdapter,
 
394
            )
 
395
        from bzrlib.workingtree import WorkingTreeFormat2, WorkingTreeFormat3
 
396
        input_test = TestInterTreeProviderAdapter(
 
397
            "test_adapted_tests")
 
398
        server1 = "a"
 
399
        server2 = "b"
 
400
        format1 = WorkingTreeFormat2()
 
401
        format2 = WorkingTreeFormat3()
 
402
        formats = [(str, format1, format2, False, True),
 
403
            (int, format2, format1, False, True)]
 
404
        adapter = InterTreeTestProviderAdapter(server1, server2, formats)
 
405
        suite = adapter.adapt(input_test)
 
406
        tests = list(iter(suite))
 
407
        self.assertEqual(2, len(tests))
 
408
        self.assertEqual(tests[0].intertree_class, formats[0][0])
 
409
        self.assertEqual(tests[0].workingtree_format, formats[0][1])
 
410
        self.assertEqual(tests[0].workingtree_to_test_tree, formats[0][2])
 
411
        self.assertEqual(tests[0].workingtree_format_to, formats[0][3])
 
412
        self.assertEqual(tests[0].workingtree_to_test_tree_to, formats[0][4])
 
413
        self.assertEqual(tests[0].transport_server, server1)
 
414
        self.assertEqual(tests[0].transport_readonly_server, server2)
 
415
        self.assertEqual(tests[1].intertree_class, formats[1][0])
 
416
        self.assertEqual(tests[1].workingtree_format, formats[1][1])
 
417
        self.assertEqual(tests[1].workingtree_to_test_tree, formats[1][2])
 
418
        self.assertEqual(tests[1].workingtree_format_to, formats[1][3])
 
419
        self.assertEqual(tests[1].workingtree_to_test_tree_to, formats[1][4])
 
420
        self.assertEqual(tests[1].transport_server, server1)
 
421
        self.assertEqual(tests[1].transport_readonly_server, server2)
 
422
 
 
423
 
 
424
class TestTestCaseInTempDir(TestCaseInTempDir):
 
425
 
 
426
    def test_home_is_not_working(self):
 
427
        self.assertNotEqual(self.test_dir, self.test_home_dir)
 
428
        cwd = osutils.getcwd()
 
429
        self.assertEqual(self.test_dir, cwd)
 
430
        self.assertEqual(self.test_home_dir, os.environ['HOME'])
 
431
 
 
432
 
325
433
class TestTestCaseWithTransport(TestCaseWithTransport):
326
434
    """Tests for the convenience functions TestCaseWithTransport introduces."""
327
435
 
394
502
    def clear(self):
395
503
        self.calls.append(('clear',))
396
504
 
397
 
 
398
 
class TestResult(TestCase):
 
505
    def note(self, msg, *args):
 
506
        self.calls.append(('note', msg, args))
 
507
 
 
508
 
 
509
class TestTestResult(TestCase):
399
510
 
400
511
    def test_progress_bar_style_quiet(self):
401
512
        # test using a progress bar.
402
 
        dummy_test = TestResult('test_progress_bar_style_quiet')
 
513
        dummy_test = TestTestResult('test_progress_bar_style_quiet')
403
514
        dummy_error = (Exception, None, [])
404
515
        mypb = MockProgress()
405
516
        mypb.update('Running tests', 0, 4)
406
517
        last_calls = mypb.calls[:]
 
518
 
407
519
        result = bzrlib.tests._MyResult(self._log_file,
408
520
                                        descriptions=0,
409
521
                                        verbosity=1,
410
522
                                        pb=mypb)
411
523
        self.assertEqual(last_calls, mypb.calls)
412
524
 
 
525
        def shorten(s):
 
526
            """Shorten a string based on the terminal width"""
 
527
            return result._ellipsise_unimportant_words(s,
 
528
                                 osutils.terminal_width())
 
529
 
413
530
        # an error 
414
531
        result.startTest(dummy_test)
415
532
        # starting a test prints the test name
416
 
        self.assertEqual(last_calls + [('update', '...tyle_quiet', 0, None)], mypb.calls)
417
 
        last_calls = mypb.calls[:]
 
533
        last_calls += [('update', '...tyle_quiet', 0, None)]
 
534
        self.assertEqual(last_calls, mypb.calls)
418
535
        result.addError(dummy_test, dummy_error)
419
 
        self.assertEqual(last_calls + [('update', 'ERROR        ', 1, None)], mypb.calls)
420
 
        last_calls = mypb.calls[:]
 
536
        last_calls += [('update', 'ERROR        ', 1, None),
 
537
                       ('note', shorten(dummy_test.id() + ': ERROR'), ())
 
538
                      ]
 
539
        self.assertEqual(last_calls, mypb.calls)
421
540
 
422
541
        # a failure
423
542
        result.startTest(dummy_test)
424
 
        self.assertEqual(last_calls + [('update', '...tyle_quiet', 1, None)], mypb.calls)
425
 
        last_calls = mypb.calls[:]
 
543
        last_calls += [('update', '...tyle_quiet', 1, None)]
 
544
        self.assertEqual(last_calls, mypb.calls)
 
545
        last_calls += [('update', 'FAIL         ', 2, None),
 
546
                       ('note', shorten(dummy_test.id() + ': FAIL'), ())
 
547
                      ]
426
548
        result.addFailure(dummy_test, dummy_error)
427
 
        self.assertEqual(last_calls + [('update', 'FAIL         ', 2, None)], mypb.calls)
428
 
        last_calls = mypb.calls[:]
 
549
        self.assertEqual(last_calls, mypb.calls)
429
550
 
430
551
        # a success
431
552
        result.startTest(dummy_test)
432
 
        self.assertEqual(last_calls + [('update', '...tyle_quiet', 2, None)], mypb.calls)
433
 
        last_calls = mypb.calls[:]
 
553
        last_calls += [('update', '...tyle_quiet', 2, None)]
 
554
        self.assertEqual(last_calls, mypb.calls)
434
555
        result.addSuccess(dummy_test)
435
 
        self.assertEqual(last_calls + [('update', 'OK           ', 3, None)], mypb.calls)
436
 
        last_calls = mypb.calls[:]
 
556
        last_calls += [('update', 'OK           ', 3, None)]
 
557
        self.assertEqual(last_calls, mypb.calls)
437
558
 
438
559
        # a skip
439
560
        result.startTest(dummy_test)
440
 
        self.assertEqual(last_calls + [('update', '...tyle_quiet', 3, None)], mypb.calls)
441
 
        last_calls = mypb.calls[:]
 
561
        last_calls += [('update', '...tyle_quiet', 3, None)]
 
562
        self.assertEqual(last_calls, mypb.calls)
442
563
        result.addSkipped(dummy_test, dummy_error)
443
 
        self.assertEqual(last_calls + [('update', 'SKIP         ', 4, None)], mypb.calls)
444
 
        last_calls = mypb.calls[:]
 
564
        last_calls += [('update', 'SKIP         ', 4, None)]
 
565
        self.assertEqual(last_calls, mypb.calls)
445
566
 
446
567
    def test_elapsed_time_with_benchmarking(self):
447
568
        result = bzrlib.tests._MyResult(self._log_file,
458
579
        self.time(time.sleep, 0.001)
459
580
        result.extractBenchmarkTime(self)
460
581
        timed_string = result._testTimeString()
461
 
        self.assertContainsRe(timed_string, "^    [0-9]ms/   [ 1-9][0-9]ms$")
 
582
        self.assertContainsRe(timed_string, "^   [ 1-9][0-9]ms/   [ 1-9][0-9]ms$")
462
583
        # extracting the time from a non-bzrlib testcase sets to None
463
584
        result._recordTestStartTime()
464
585
        result.extractBenchmarkTime(
465
586
            unittest.FunctionTestCase(self.test_elapsed_time_with_benchmarking))
466
587
        timed_string = result._testTimeString()
467
 
        self.assertContainsRe(timed_string, "^          [0-9]ms$")
 
588
        self.assertContainsRe(timed_string, "^         [ 1-9][0-9]ms$")
468
589
        # cheat. Yes, wash thy mouth out with soap.
469
590
        self._benchtime = None
470
591
 
 
592
    def test_assigned_benchmark_file_stores_date(self):
 
593
        output = StringIO()
 
594
        result = bzrlib.tests._MyResult(self._log_file,
 
595
                                        descriptions=0,
 
596
                                        verbosity=1,
 
597
                                        bench_history=output
 
598
                                        )
 
599
        output_string = output.getvalue()
 
600
        # if you are wondering about the regexp please read the comment in
 
601
        # test_bench_history (bzrlib.tests.test_selftest.TestRunner)
 
602
        # XXX: what comment?  -- Andrew Bennetts
 
603
        self.assertContainsRe(output_string, "--date [0-9.]+")
 
604
 
 
605
    def test_benchhistory_records_test_times(self):
 
606
        result_stream = StringIO()
 
607
        result = bzrlib.tests._MyResult(
 
608
            self._log_file,
 
609
            descriptions=0,
 
610
            verbosity=1,
 
611
            bench_history=result_stream
 
612
            )
 
613
 
 
614
        # we want profile a call and check that its test duration is recorded
 
615
        # make a new test instance that when run will generate a benchmark
 
616
        example_test_case = TestTestResult("_time_hello_world_encoding")
 
617
        # execute the test, which should succeed and record times
 
618
        example_test_case.run(result)
 
619
        lines = result_stream.getvalue().splitlines()
 
620
        self.assertEqual(2, len(lines))
 
621
        self.assertContainsRe(lines[1],
 
622
            " *[0-9]+ms bzrlib.tests.test_selftest.TestTestResult"
 
623
            "._time_hello_world_encoding")
 
624
 
 
625
    def _time_hello_world_encoding(self):
 
626
        """Profile two sleep calls
 
627
        
 
628
        This is used to exercise the test framework.
 
629
        """
 
630
        self.time(unicode, 'hello', errors='replace')
 
631
        self.time(unicode, 'world', errors='replace')
 
632
 
 
633
    def test_lsprofiling(self):
 
634
        """Verbose test result prints lsprof statistics from test cases."""
 
635
        try:
 
636
            import bzrlib.lsprof
 
637
        except ImportError:
 
638
            raise TestSkipped("lsprof not installed.")
 
639
        result_stream = StringIO()
 
640
        result = bzrlib.tests._MyResult(
 
641
            unittest._WritelnDecorator(result_stream),
 
642
            descriptions=0,
 
643
            verbosity=2,
 
644
            )
 
645
        # we want profile a call of some sort and check it is output by
 
646
        # addSuccess. We dont care about addError or addFailure as they
 
647
        # are not that interesting for performance tuning.
 
648
        # make a new test instance that when run will generate a profile
 
649
        example_test_case = TestTestResult("_time_hello_world_encoding")
 
650
        example_test_case._gather_lsprof_in_benchmarks = True
 
651
        # execute the test, which should succeed and record profiles
 
652
        example_test_case.run(result)
 
653
        # lsprofile_something()
 
654
        # if this worked we want 
 
655
        # LSProf output for <built in function unicode> (['hello'], {'errors': 'replace'})
 
656
        #    CallCount    Recursive    Total(ms)   Inline(ms) module:lineno(function)
 
657
        # (the lsprof header)
 
658
        # ... an arbitrary number of lines
 
659
        # and the function call which is time.sleep.
 
660
        #           1        0            ???         ???       ???(sleep) 
 
661
        # and then repeated but with 'world', rather than 'hello'.
 
662
        # this should appear in the output stream of our test result.
 
663
        output = result_stream.getvalue()
 
664
        self.assertContainsRe(output,
 
665
            r"LSProf output for <type 'unicode'>\(\('hello',\), {'errors': 'replace'}\)")
 
666
        self.assertContainsRe(output,
 
667
            r" *CallCount *Recursive *Total\(ms\) *Inline\(ms\) *module:lineno\(function\)\n")
 
668
        self.assertContainsRe(output,
 
669
            r"( +1 +0 +0\.\d+ +0\.\d+ +<method 'disable' of '_lsprof\.Profiler' objects>\n)?")
 
670
        self.assertContainsRe(output,
 
671
            r"LSProf output for <type 'unicode'>\(\('world',\), {'errors': 'replace'}\)\n")
 
672
 
471
673
 
472
674
class TestRunner(TestCase):
473
675
 
515
717
        result = self.run_test_runner(runner, test)
516
718
        self.assertTrue(result.wasSuccessful())
517
719
 
 
720
    def test_bench_history(self):
 
721
        # tests that the running the benchmark produces a history file
 
722
        # containing a timestamp and the revision id of the bzrlib source which
 
723
        # was tested.
 
724
        workingtree = _get_bzr_source_tree()
 
725
        test = TestRunner('dummy_test')
 
726
        output = StringIO()
 
727
        runner = TextTestRunner(stream=self._log_file, bench_history=output)
 
728
        result = self.run_test_runner(runner, test)
 
729
        output_string = output.getvalue()
 
730
        self.assertContainsRe(output_string, "--date [0-9.]+")
 
731
        if workingtree is not None:
 
732
            revision_id = workingtree.get_parent_ids()[0]
 
733
            self.assertEndsWith(output_string.rstrip(), revision_id)
 
734
 
518
735
 
519
736
class TestTestCase(TestCase):
520
737
    """Tests that test the core bzrlib TestCase."""
571
788
            output_stream.getvalue(),
572
789
            "[1-9][0-9]ms/   [1-9][0-9]ms\n$")
573
790
        
 
791
    def test__gather_lsprof_in_benchmarks(self):
 
792
        """When _gather_lsprof_in_benchmarks is on, accumulate profile data.
 
793
        
 
794
        Each self.time() call is individually and separately profiled.
 
795
        """
 
796
        try:
 
797
            import bzrlib.lsprof
 
798
        except ImportError:
 
799
            raise TestSkipped("lsprof not installed.")
 
800
        # overrides the class member with an instance member so no cleanup 
 
801
        # needed.
 
802
        self._gather_lsprof_in_benchmarks = True
 
803
        self.time(time.sleep, 0.000)
 
804
        self.time(time.sleep, 0.003)
 
805
        self.assertEqual(2, len(self._benchcalls))
 
806
        self.assertEqual((time.sleep, (0.000,), {}), self._benchcalls[0][0])
 
807
        self.assertEqual((time.sleep, (0.003,), {}), self._benchcalls[1][0])
 
808
        self.assertIsInstance(self._benchcalls[0][1], bzrlib.lsprof.Stats)
 
809
        self.assertIsInstance(self._benchcalls[1][1], bzrlib.lsprof.Stats)
 
810
 
 
811
 
 
812
@symbol_versioning.deprecated_function(zero_eleven)
 
813
def sample_deprecated_function():
 
814
    """A deprecated function to test applyDeprecated with."""
 
815
    return 2
 
816
 
 
817
 
 
818
def sample_undeprecated_function(a_param):
 
819
    """A undeprecated function to test applyDeprecated with."""
 
820
 
 
821
 
 
822
class ApplyDeprecatedHelper(object):
 
823
    """A helper class for ApplyDeprecated tests."""
 
824
 
 
825
    @symbol_versioning.deprecated_method(zero_eleven)
 
826
    def sample_deprecated_method(self, param_one):
 
827
        """A deprecated method for testing with."""
 
828
        return param_one
 
829
 
 
830
    def sample_normal_method(self):
 
831
        """A undeprecated method."""
 
832
 
 
833
    @symbol_versioning.deprecated_method(zero_ten)
 
834
    def sample_nested_deprecation(self):
 
835
        return sample_deprecated_function()
 
836
 
574
837
 
575
838
class TestExtraAssertions(TestCase):
576
839
    """Tests for new test assertions in bzrlib test suite"""
585
848
        self.assertEndsWith('foo', 'oo')
586
849
        self.assertRaises(AssertionError, self.assertEndsWith, 'o', 'oo')
587
850
 
 
851
    def test_applyDeprecated_not_deprecated(self):
 
852
        sample_object = ApplyDeprecatedHelper()
 
853
        # calling an undeprecated callable raises an assertion
 
854
        self.assertRaises(AssertionError, self.applyDeprecated, zero_eleven,
 
855
            sample_object.sample_normal_method)
 
856
        self.assertRaises(AssertionError, self.applyDeprecated, zero_eleven,
 
857
            sample_undeprecated_function, "a param value")
 
858
        # calling a deprecated callable (function or method) with the wrong
 
859
        # expected deprecation fails.
 
860
        self.assertRaises(AssertionError, self.applyDeprecated, zero_ten,
 
861
            sample_object.sample_deprecated_method, "a param value")
 
862
        self.assertRaises(AssertionError, self.applyDeprecated, zero_ten,
 
863
            sample_deprecated_function)
 
864
        # calling a deprecated callable (function or method) with the right
 
865
        # expected deprecation returns the functions result.
 
866
        self.assertEqual("a param value", self.applyDeprecated(zero_eleven,
 
867
            sample_object.sample_deprecated_method, "a param value"))
 
868
        self.assertEqual(2, self.applyDeprecated(zero_eleven,
 
869
            sample_deprecated_function))
 
870
        # calling a nested deprecation with the wrong deprecation version
 
871
        # fails even if a deeper nested function was deprecated with the 
 
872
        # supplied version.
 
873
        self.assertRaises(AssertionError, self.applyDeprecated,
 
874
            zero_eleven, sample_object.sample_nested_deprecation)
 
875
        # calling a nested deprecation with the right deprecation value
 
876
        # returns the calls result.
 
877
        self.assertEqual(2, self.applyDeprecated(zero_ten,
 
878
            sample_object.sample_nested_deprecation))
 
879
 
 
880
    def test_callDeprecated(self):
 
881
        def testfunc(be_deprecated, result=None):
 
882
            if be_deprecated is True:
 
883
                symbol_versioning.warn('i am deprecated', DeprecationWarning, 
 
884
                                       stacklevel=1)
 
885
            return result
 
886
        result = self.callDeprecated(['i am deprecated'], testfunc, True)
 
887
        self.assertIs(None, result)
 
888
        result = self.callDeprecated([], testfunc, False, 'result')
 
889
        self.assertEqual('result', result)
 
890
        self.callDeprecated(['i am deprecated'], testfunc, be_deprecated=True)
 
891
        self.callDeprecated([], testfunc, be_deprecated=False)
 
892
 
588
893
 
589
894
class TestConvenienceMakers(TestCaseWithTransport):
590
895
    """Test for the make_* convenience functions."""