212
213
osutils.set_or_unset_env(var, value)
216
def _clear__type_equality_funcs(test):
217
"""Cleanup bound methods stored on TestCase instances
219
Clear the dict breaking a few (mostly) harmless cycles in the affected
220
unittests released with Python 2.6 and initial Python 2.7 versions.
222
For a few revisions between Python 2.7.1 and Python 2.7.2 that annoyingly
223
shipped in Oneiric, an object with no clear method was used, hence the
224
extra complications, see bug 809048 for details.
226
type_equality_funcs = getattr(test, "_type_equality_funcs", None)
227
if type_equality_funcs is not None:
228
tef_clear = getattr(type_equality_funcs, "clear", None)
229
if tef_clear is None:
230
tef_instance_dict = getattr(type_equality_funcs, "__dict__", None)
231
if tef_instance_dict is not None:
232
tef_clear = tef_instance_dict.clear
233
if tef_clear is not None:
215
237
class ExtendedTestResult(testtools.TextTestResult):
216
238
"""Accepts, reports and accumulates the results of running tests.
385
407
getDetails = getattr(test, "getDetails", None)
386
408
if getDetails is not None:
387
409
getDetails().clear()
388
# Clear _type_equality_funcs to try to stop TestCase instances
389
# from wasting memory. 'clear' is not available in all Python
390
# versions (bug 809048)
391
type_equality_funcs = getattr(test, "_type_equality_funcs", None)
392
if type_equality_funcs is not None:
393
tef_clear = getattr(type_equality_funcs, "clear", None)
394
if tef_clear is None:
395
tef_instance_dict = getattr(type_equality_funcs, "__dict__", None)
396
if tef_instance_dict is not None:
397
tef_clear = tef_instance_dict.clear
398
if tef_clear is not None:
410
_clear__type_equality_funcs(test)
400
411
self._traceback_from_test = None
402
413
def startTests(self):
503
514
self.not_applicable_count += 1
504
515
self.report_not_applicable(test, reason)
517
def _count_stored_tests(self):
518
"""Count of tests instances kept alive due to not succeeding"""
519
return self.error_count + self.failure_count + self.known_failure_count
506
521
def _post_mortem(self, tb=None):
507
522
"""Start a PDB post mortem session."""
508
523
if os.environ.get('BZR_TEST_PDB', None):
983
998
for feature in getattr(self, '_test_needs_features', []):
984
999
self.requireFeature(feature)
985
1000
self._cleanEnvironment()
986
self.overrideAttr(bzrlib.global_state, 'cmdline_overrides',
987
config.CommandLineSection())
1001
if bzrlib.global_state is not None:
1002
self.overrideAttr(bzrlib.global_state, 'cmdline_overrides',
1003
config.CommandLineStore())
988
1004
self._silenceUI()
989
1005
self._startLogFile()
990
1006
self._benchcalls = []
1719
1732
self.addCleanup(self._finishLogFile)
1721
1734
def _finishLogFile(self):
1722
"""Finished with the log file.
1724
Close the file and delete it.
1735
"""Flush and dereference the in-memory log for this testcase"""
1726
1736
if trace._trace_file:
1727
1737
# flush the log file, to get all content
1728
1738
trace._trace_file.flush()
1729
1739
trace.pop_log_file(self._log_memento)
1740
# The logging module now tracks references for cleanup so discard ours
1741
del self._log_memento
1731
1743
def thisFailsStrictLockCheck(self):
1732
1744
"""It is known that this test would fail with -Dstrict_locks.
2568
2580
root = TestCaseWithMemoryTransport.TEST_ROOT
2570
# Make sure we get a readable and accessible home for .bzr.log
2571
# and/or config files, and not fallback to weird defaults (see
2572
# http://pad.lv/825027).
2573
self.assertIs(None, os.environ.get('BZR_HOME', None))
2574
os.environ['BZR_HOME'] = root
2575
wt = bzrdir.BzrDir.create_standalone_workingtree(root)
2576
del os.environ['BZR_HOME']
2577
except Exception, e:
2578
self.fail("Fail to initialize the safety net: %r\nExiting\n" % (e,))
2581
# Make sure we get a readable and accessible home for .bzr.log
2582
# and/or config files, and not fallback to weird defaults (see
2583
# http://pad.lv/825027).
2584
self.assertIs(None, os.environ.get('BZR_HOME', None))
2585
os.environ['BZR_HOME'] = root
2586
wt = bzrdir.BzrDir.create_standalone_workingtree(root)
2587
del os.environ['BZR_HOME']
2579
2588
# Hack for speed: remember the raw bytes of the dirstate file so that
2580
2589
# we don't need to re-open the wt to check it hasn't changed.
2581
2590
TestCaseWithMemoryTransport._SAFETY_NET_PRISTINE_DIRSTATE = (
2947
2956
# so check for that by checking bzrdir.BzrDirFormat.get_default_format()
2949
2958
format = self.resolve_format(format=format)
2959
if not format.supports_workingtrees:
2960
b = self.make_branch(relpath+'.branch', format=format)
2961
return b.create_checkout(relpath, lightweight=True)
2950
2962
b = self.make_branch(relpath, format=format)
2952
2964
return b.bzrdir.create_workingtree()
3251
3263
result_decorators=result_decorators,
3253
3265
runner.stop_on_failure=stop_on_failure
3266
if isinstance(suite, unittest.TestSuite):
3267
# Empty out _tests list of passed suite and populate new TestSuite
3268
suite._tests[:], suite = [], TestSuite(suite)
3254
3269
# built in decorator factories:
3256
3271
random_order(random_seed, runner),
3355
3370
class TestDecorator(TestUtil.TestSuite):
3356
3371
"""A decorator for TestCase/TestSuite objects.
3358
Usually, subclasses should override __iter__(used when flattening test
3359
suites), which we do to filter, reorder, parallelise and so on, run() and
3373
Contains rather than flattening suite passed on construction
3363
def __init__(self, suite):
3364
TestUtil.TestSuite.__init__(self)
3367
def countTestCases(self):
3370
cases += test.countTestCases()
3377
def run(self, result):
3378
# Use iteration on self, not self._tests, to allow subclasses to hook
3381
if result.shouldStop:
3376
def __init__(self, suite=None):
3377
super(TestDecorator, self).__init__()
3378
if suite is not None:
3381
# Don't need subclass run method with suite emptying
3382
run = unittest.TestSuite.run
3387
3385
class CountingDecorator(TestDecorator):
3398
3396
"""A decorator which excludes test matching an exclude pattern."""
3400
3398
def __init__(self, suite, exclude_pattern):
3401
TestDecorator.__init__(self, suite)
3402
self.exclude_pattern = exclude_pattern
3403
self.excluded = False
3407
return iter(self._tests)
3408
self.excluded = True
3409
suite = exclude_tests_by_re(self, self.exclude_pattern)
3411
self.addTests(suite)
3412
return iter(self._tests)
3399
super(ExcludeDecorator, self).__init__(
3400
exclude_tests_by_re(suite, exclude_pattern))
3415
3403
class FilterTestsDecorator(TestDecorator):
3416
3404
"""A decorator which filters tests to those matching a pattern."""
3418
3406
def __init__(self, suite, pattern):
3419
TestDecorator.__init__(self, suite)
3420
self.pattern = pattern
3421
self.filtered = False
3425
return iter(self._tests)
3426
self.filtered = True
3427
suite = filter_suite_by_re(self, self.pattern)
3429
self.addTests(suite)
3430
return iter(self._tests)
3407
super(FilterTestsDecorator, self).__init__(
3408
filter_suite_by_re(suite, pattern))
3433
3411
class RandomDecorator(TestDecorator):
3434
3412
"""A decorator which randomises the order of its tests."""
3436
3414
def __init__(self, suite, random_seed, stream):
3437
TestDecorator.__init__(self, suite)
3438
self.random_seed = random_seed
3439
self.randomised = False
3440
self.stream = stream
3444
return iter(self._tests)
3445
self.randomised = True
3446
self.stream.write("Randomizing test order using seed %s\n\n" %
3447
(self.actual_seed()))
3415
random_seed = self.actual_seed(random_seed)
3416
stream.write("Randomizing test order using seed %s\n\n" %
3448
3418
# Initialise the random number generator.
3449
random.seed(self.actual_seed())
3450
suite = randomize_suite(self)
3452
self.addTests(suite)
3453
return iter(self._tests)
3419
random.seed(random_seed)
3420
super(RandomDecorator, self).__init__(randomize_suite(suite))
3455
def actual_seed(self):
3456
if self.random_seed == "now":
3423
def actual_seed(seed):
3457
3425
# We convert the seed to a long to make it reuseable across
3458
3426
# invocations (because the user can reenter it).
3459
self.random_seed = long(time.time())
3427
return long(time.time())
3461
3429
# Convert the seed to a long if we can
3463
self.random_seed = long(self.random_seed)
3432
except (TypeError, ValueError):
3466
return self.random_seed
3469
3437
class TestFirstDecorator(TestDecorator):
3470
3438
"""A decorator which moves named tests to the front."""
3472
3440
def __init__(self, suite, pattern):
3473
TestDecorator.__init__(self, suite)
3474
self.pattern = pattern
3475
self.filtered = False
3479
return iter(self._tests)
3480
self.filtered = True
3481
suites = split_suite_by_re(self, self.pattern)
3483
self.addTests(suites)
3484
return iter(self._tests)
3441
super(TestFirstDecorator, self).__init__()
3442
self.addTests(split_suite_by_re(suite, pattern))
3487
3445
def partition_tests(suite, count):
3532
3490
ProtocolTestCase.run(self, result)
3534
os.waitpid(self.pid, 0)
3492
pid, status = os.waitpid(self.pid, 0)
3493
# GZ 2011-10-18: If status is nonzero, should report to the result
3494
# that something went wrong.
3536
3496
test_blocks = partition_tests(suite, concurrency)
3497
# Clear the tests from the original suite so it doesn't keep them alive
3498
suite._tests[:] = []
3537
3499
for process_tests in test_blocks:
3538
process_suite = TestUtil.TestSuite()
3539
process_suite.addTests(process_tests)
3500
process_suite = TestUtil.TestSuite(process_tests)
3501
# Also clear each split list so new suite has only reference
3502
process_tests[:] = []
3540
3503
c2pread, c2pwrite = os.pipe()
3541
3504
pid = os.fork()
3543
workaround_zealous_crypto_random()
3507
stream = os.fdopen(c2pwrite, 'wb', 1)
3508
workaround_zealous_crypto_random()
3545
3509
os.close(c2pread)
3546
3510
# Leave stderr and stdout open so we can see test noise
3547
3511
# Close stdin so that the child goes away if it decides to
3548
3512
# read from stdin (otherwise its a roulette to see what
3549
3513
# child actually gets keystrokes for pdb etc).
3550
3514
sys.stdin.close()
3552
stream = os.fdopen(c2pwrite, 'wb', 1)
3553
3515
subunit_result = AutoTimingTestResultDecorator(
3554
TestProtocolClient(stream))
3516
SubUnitBzrProtocolClient(stream))
3555
3517
process_suite.run(subunit_result)
3519
# Try and report traceback on stream, but exit with error even
3520
# if stream couldn't be created or something else goes wrong.
3521
# The traceback is formatted to a string and written in one go
3522
# to avoid interleaving lines from multiple failing children.
3524
stream.write(traceback.format_exc())
3559
3529
os.close(c2pwrite)
3560
3530
stream = os.fdopen(c2pread, 'rb', 1)
3666
3636
# with proper exclusion rules.
3667
3637
# -Ethreads Will display thread ident at creation/join time to
3668
3638
# help track thread leaks
3639
# -Euncollected_cases Display the identity of any test cases that weren't
3640
# deallocated after being completed.
3670
3641
# -Econfig_stats Will collect statistics using addDetail
3671
3642
selftest_debug_flags = set()
4470
4441
from subunit.test_results import AutoTimingTestResultDecorator
4471
4442
class SubUnitBzrProtocolClient(TestProtocolClient):
4444
def stopTest(self, test):
4445
super(SubUnitBzrProtocolClient, self).stopTest(test)
4446
_clear__type_equality_funcs(test)
4473
4448
def addSuccess(self, test, details=None):
4474
4449
# The subunit client always includes the details in the subunit
4475
4450
# stream, but we don't want to include it in ours.
4491
@deprecated_function(deprecated_in((2, 5, 0)))
4492
def ModuleAvailableFeature(name):
4493
from bzrlib.tests import features
4494
return features.ModuleAvailableFeature(name)
4466
# API compatibility for old plugins; see bug 892622.
4469
'HTTPServerFeature',
4470
'ModuleAvailableFeature',
4471
'HTTPSServerFeature', 'SymlinkFeature', 'HardlinkFeature',
4472
'OsFifoFeature', 'UnicodeFilenameFeature',
4473
'ByteStringNamedFilesystem', 'UTF8Filesystem',
4474
'BreakinFeature', 'CaseInsCasePresFilenameFeature',
4475
'CaseInsensitiveFilesystemFeature', 'case_sensitive_filesystem_feature',
4476
'posix_permissions_feature',
4478
globals()[name] = _CompatabilityThunkFeature(
4479
symbol_versioning.deprecated_in((2, 5, 0)),
4480
'bzrlib.tests', name,
4481
name, 'bzrlib.tests.features')
4484
for (old_name, new_name) in [
4485
('UnicodeFilename', 'UnicodeFilenameFeature'),
4487
globals()[name] = _CompatabilityThunkFeature(
4488
symbol_versioning.deprecated_in((2, 5, 0)),
4489
'bzrlib.tests', old_name,
4490
new_name, 'bzrlib.tests.features')