385
375
self.assertEqual(url, t.clone('..').base)
378
class MockProgress(_BaseProgressBar):
379
"""Progress-bar standin that records calls.
381
Useful for testing pb using code.
385
_BaseProgressBar.__init__(self)
389
self.calls.append(('tick',))
391
def update(self, msg=None, current=None, total=None):
392
self.calls.append(('update', msg, current, total))
395
self.calls.append(('clear',))
398
class TestTestResult(TestCase):
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,
411
self.assertEqual(last_calls, mypb.calls)
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[:]
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[:]
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[:]
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[:]
446
def test_elapsed_time_with_benchmarking(self):
447
result = bzrlib.tests._MyResult(self._log_file,
451
result._recordTestStartTime()
453
result.extractBenchmarkTime(self)
454
timed_string = result._testTimeString()
455
# without explicit benchmarking, we should get a simple time.
456
self.assertContainsRe(timed_string, "^ [ 1-9][0-9]ms$")
457
# if a benchmark time is given, we want a x of y style result.
458
self.time(time.sleep, 0.001)
459
result.extractBenchmarkTime(self)
460
timed_string = result._testTimeString()
461
self.assertContainsRe(timed_string, "^ [0-9]ms/ [ 1-9][0-9]ms$")
462
# extracting the time from a non-bzrlib testcase sets to None
463
result._recordTestStartTime()
464
result.extractBenchmarkTime(
465
unittest.FunctionTestCase(self.test_elapsed_time_with_benchmarking))
466
timed_string = result._testTimeString()
467
self.assertContainsRe(timed_string, "^ [0-9]ms$")
468
# cheat. Yes, wash thy mouth out with soap.
469
self._benchtime = None
471
def _time_hello_world_encoding(self):
472
"""Profile two sleep calls
474
This is used to exercise the test framework.
476
self.time(unicode, 'hello', errors='replace')
477
self.time(unicode, 'world', errors='replace')
479
def test_lsprofiling(self):
480
"""Verbose test result prints lsprof statistics from test cases."""
484
raise TestSkipped("lsprof not installed.")
485
result_stream = StringIO()
486
result = bzrlib.tests._MyResult(
487
unittest._WritelnDecorator(result_stream),
491
# we want profile a call of some sort and check it is output by
492
# addSuccess. We dont care about addError or addFailure as they
493
# are not that interesting for performance tuning.
494
# make a new test instance that when run will generate a profile
495
example_test_case = TestTestResult("_time_hello_world_encoding")
496
example_test_case._gather_lsprof_in_benchmarks = True
497
# execute the test, which should succeed and record profiles
498
example_test_case.run(result)
499
# lsprofile_something()
500
# if this worked we want
501
# LSProf output for <built in function unicode> (['hello'], {'errors': 'replace'})
502
# CallCount Recursive Total(ms) Inline(ms) module:lineno(function)
503
# (the lsprof header)
504
# ... an arbitrary number of lines
505
# and the function call which is time.sleep.
506
# 1 0 ??? ??? ???(sleep)
507
# and then repeated but with 'world', rather than 'hello'.
508
# 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)?"
519
class TestRunner(TestCase):
521
def dummy_test(self):
524
def run_test_runner(self, testrunner, test):
525
"""Run suite in testrunner, saving global state and restoring it.
527
This current saves and restores:
528
TestCaseInTempDir.TEST_ROOT
530
There should be no tests in this file that use bzrlib.tests.TextTestRunner
531
without using this convenience method, because of our use of global state.
533
old_root = TestCaseInTempDir.TEST_ROOT
535
TestCaseInTempDir.TEST_ROOT = None
536
return testrunner.run(test)
538
TestCaseInTempDir.TEST_ROOT = old_root
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))
554
def test_skipped_test(self):
555
# run a test that is skipped, and check the suite as a whole still
557
# skipping_test must be hidden in here so it's not run as a real test
559
raise TestSkipped('test intentionally skipped')
560
runner = TextTestRunner(stream=self._log_file, keep_output=True)
561
test = unittest.FunctionTestCase(skipping_test)
562
result = self.run_test_runner(runner, test)
563
self.assertTrue(result.wasSuccessful())
566
class TestTestCase(TestCase):
567
"""Tests that test the core bzrlib TestCase."""
569
def inner_test(self):
570
# the inner child test
573
def outer_child(self):
574
# the outer child test
576
self.inner_test = TestTestCase("inner_child")
577
result = bzrlib.tests._MyResult(self._log_file,
580
self.inner_test.run(result)
583
def test_trace_nesting(self):
584
# this tests that each test case nests its trace facility correctly.
585
# we do this by running a test case manually. That test case (A)
586
# should setup a new log, log content to it, setup a child case (B),
587
# which should log independently, then case (A) should log a trailer
589
# we do two nested children so that we can verify the state of the
590
# logs after the outer child finishes is correct, which a bad clean
591
# up routine in tearDown might trigger a fault in our test with only
592
# one child, we should instead see the bad result inside our test with
594
# the outer child test
595
original_trace = bzrlib.trace._trace_file
596
outer_test = TestTestCase("outer_child")
597
result = bzrlib.tests._MyResult(self._log_file,
600
outer_test.run(result)
601
self.assertEqual(original_trace, bzrlib.trace._trace_file)
603
def method_that_times_a_bit_twice(self):
604
# call self.time twice to ensure it aggregates
605
self.time(time.sleep, 0.007)
606
self.time(time.sleep, 0.007)
608
def test_time_creates_benchmark_in_result(self):
609
"""Test that the TestCase.time() method accumulates a benchmark time."""
610
sample_test = TestTestCase("method_that_times_a_bit_twice")
611
output_stream = StringIO()
612
result = bzrlib.tests._MyResult(
613
unittest._WritelnDecorator(output_stream),
616
sample_test.run(result)
617
self.assertContainsRe(
618
output_stream.getvalue(),
619
"[1-9][0-9]ms/ [1-9][0-9]ms\n$")
621
def test__gather_lsprof_in_benchmarks(self):
622
"""When _gather_lsprof_in_benchmarks is on, accumulate profile data.
624
Each self.time() call is individually and separately profiled.
629
raise TestSkipped("lsprof not installed.")
630
# overrides the class member with an instance member so no cleanup
632
self._gather_lsprof_in_benchmarks = True
633
self.time(time.sleep, 0.000)
634
self.time(time.sleep, 0.003)
635
self.assertEqual(2, len(self._benchcalls))
636
self.assertEqual((time.sleep, (0.000,), {}), self._benchcalls[0][0])
637
self.assertEqual((time.sleep, (0.003,), {}), self._benchcalls[1][0])
638
self.assertIsInstance(self._benchcalls[0][1], bzrlib.lsprof.Stats)
639
self.assertIsInstance(self._benchcalls[1][1], bzrlib.lsprof.Stats)
388
642
class TestExtraAssertions(TestCase):
389
643
"""Tests for new test assertions in bzrlib test suite"""