68
48
def test_transport(self):
69
49
# test that --transport=sftp works
71
import bzrlib.transport.sftp
72
except ParamikoNotPresent:
73
raise TestSkipped("Paramiko not present")
50
# FIXME RBC 20060123 this should raise TestSkipped if sftp is not
74
52
old_transport = bzrlib.tests.default_transport
75
old_root = TestCaseWithMemoryTransport.TEST_ROOT
76
TestCaseWithMemoryTransport.TEST_ROOT = None
53
old_root = TestCaseInTempDir.TEST_ROOT
54
TestCaseInTempDir.TEST_ROOT = None
78
56
TestOptions.current_test = "test_transport_set_to_sftp"
79
stdout = self.run_bzr(
80
'selftest --transport=sftp test_transport_set_to_sftp')[0]
57
stdout = self.capture('selftest --transport=sftp test_transport_set_to_sftp')
81
59
self.assertContainsRe(stdout, 'Ran 1 test')
82
60
self.assertEqual(old_transport, bzrlib.tests.default_transport)
84
62
TestOptions.current_test = "test_transport_set_to_memory"
85
stdout = self.run_bzr(
86
'selftest --transport=memory test_transport_set_to_memory')[0]
63
stdout = self.capture('selftest --transport=memory test_transport_set_to_memory')
87
64
self.assertContainsRe(stdout, 'Ran 1 test')
88
65
self.assertEqual(old_transport, bzrlib.tests.default_transport)
90
67
bzrlib.tests.default_transport = old_transport
91
68
TestOptions.current_test = None
92
TestCaseWithMemoryTransport.TEST_ROOT = old_root
94
def test_subunit(self):
95
"""Passing --subunit results in subunit output."""
96
self.requireFeature(SubUnitFeature)
97
from subunit import ProtocolTestCase
98
stdout = self.run_bzr(
99
'selftest --subunit --no-plugins '
100
'tests.test_selftest.SelftestTests.test_import_tests')[0]
101
stream = StringIO(str(stdout))
102
test = ProtocolTestCase(stream)
103
result = unittest.TestResult()
105
# 1 to deal with the 'test:' noise at the start, and 1 for the one we
107
self.assertEqual(2, result.testsRun)
110
class TestRunBzr(ExternalBase):
112
def _run_bzr_core(self, argv, retcode=0, encoding=None, stdin=None,
114
"""Override _run_bzr_core to test how it is invoked by run_bzr.
116
Attempts to run bzr from inside this class don't actually run it.
118
We test how run_bzr actually invokes bzr in another location.
119
Here we only need to test that it is run_bzr passes the right
120
parameters to run_bzr.
122
self.argv = list(argv)
123
self.retcode = retcode
124
self.encoding = encoding
126
self.working_dir = working_dir
129
def test_encoding(self):
130
"""Test that run_bzr passes encoding to _run_bzr_core"""
131
self.run_bzr('foo bar')
132
self.assertEqual(None, self.encoding)
133
self.assertEqual(['foo', 'bar'], self.argv)
135
self.run_bzr('foo bar', encoding='baz')
136
self.assertEqual('baz', self.encoding)
137
self.assertEqual(['foo', 'bar'], self.argv)
139
def test_retcode(self):
140
"""Test that run_bzr passes retcode to _run_bzr_core"""
141
# Default is retcode == 0
142
self.run_bzr('foo bar')
143
self.assertEqual(0, self.retcode)
144
self.assertEqual(['foo', 'bar'], self.argv)
146
self.run_bzr('foo bar', retcode=1)
147
self.assertEqual(1, self.retcode)
148
self.assertEqual(['foo', 'bar'], self.argv)
150
self.run_bzr('foo bar', retcode=None)
151
self.assertEqual(None, self.retcode)
152
self.assertEqual(['foo', 'bar'], self.argv)
154
self.run_bzr(['foo', 'bar'], retcode=3)
155
self.assertEqual(3, self.retcode)
156
self.assertEqual(['foo', 'bar'], self.argv)
158
def test_stdin(self):
159
# test that the stdin keyword to run_bzr is passed through to
160
# _run_bzr_core as-is. We do this by overriding
161
# _run_bzr_core in this class, and then calling run_bzr,
162
# which is a convenience function for _run_bzr_core, so
164
self.run_bzr('foo bar', stdin='gam')
165
self.assertEqual('gam', self.stdin)
166
self.assertEqual(['foo', 'bar'], self.argv)
168
self.run_bzr('foo bar', stdin='zippy')
169
self.assertEqual('zippy', self.stdin)
170
self.assertEqual(['foo', 'bar'], self.argv)
172
def test_working_dir(self):
173
"""Test that run_bzr passes working_dir to _run_bzr_core"""
174
self.run_bzr('foo bar')
175
self.assertEqual(None, self.working_dir)
176
self.assertEqual(['foo', 'bar'], self.argv)
178
self.run_bzr('foo bar', working_dir='baz')
179
self.assertEqual('baz', self.working_dir)
180
self.assertEqual(['foo', 'bar'], self.argv)
182
def test_reject_extra_keyword_arguments(self):
183
self.assertRaises(TypeError, self.run_bzr, "foo bar",
184
error_regex=['error message'])
187
class TestBenchmarkTests(TestCaseWithTransport):
189
def test_benchmark_runs_benchmark_tests(self):
190
"""bzr selftest --benchmark should not run the default test suite."""
191
# We test this by passing a regression test name to --benchmark, which
192
# should result in 0 tests run.
193
old_root = TestCaseWithMemoryTransport.TEST_ROOT
195
TestCaseWithMemoryTransport.TEST_ROOT = None
196
out, err = self.run_bzr('selftest --benchmark'
197
' workingtree_implementations')
199
TestCaseWithMemoryTransport.TEST_ROOT = old_root
200
self.assertContainsRe(out, 'Ran 0 tests.*\n\nOK')
204
benchfile = open(".perf_history", "rt")
206
lines = benchfile.readlines()
209
self.assertEqual(1, len(lines))
210
self.assertContainsRe(lines[0], "--date [0-9.]+")
213
class TestRunBzrCaptured(ExternalBase):
215
def apply_redirected(self, stdin=None, stdout=None, stderr=None,
216
a_callable=None, *args, **kwargs):
218
self.factory_stdin = getattr(bzrlib.ui.ui_factory, "stdin", None)
219
self.factory = bzrlib.ui.ui_factory
220
self.working_dir = osutils.getcwd()
221
stdout.write('foo\n')
222
stderr.write('bar\n')
225
def test_stdin(self):
226
# test that the stdin keyword to _run_bzr_core is passed through to
227
# apply_redirected as a StringIO. We do this by overriding
228
# apply_redirected in this class, and then calling _run_bzr_core,
229
# which calls apply_redirected.
230
self.run_bzr(['foo', 'bar'], stdin='gam')
231
self.assertEqual('gam', self.stdin.read())
232
self.assertTrue(self.stdin is self.factory_stdin)
233
self.run_bzr(['foo', 'bar'], stdin='zippy')
234
self.assertEqual('zippy', self.stdin.read())
235
self.assertTrue(self.stdin is self.factory_stdin)
237
def test_ui_factory(self):
238
# each invocation of self.run_bzr should get its
239
# own UI factory, which is an instance of TestUIFactory,
240
# with stdin, stdout and stderr attached to the stdin,
241
# stdout and stderr of the invoked run_bzr
242
current_factory = bzrlib.ui.ui_factory
243
self.run_bzr(['foo'])
244
self.failIf(current_factory is self.factory)
245
self.assertNotEqual(sys.stdout, self.factory.stdout)
246
self.assertNotEqual(sys.stderr, self.factory.stderr)
247
self.assertEqual('foo\n', self.factory.stdout.getvalue())
248
self.assertEqual('bar\n', self.factory.stderr.getvalue())
249
self.assertIsInstance(self.factory, TestUIFactory)
251
def test_working_dir(self):
252
self.build_tree(['one/', 'two/'])
253
cwd = osutils.getcwd()
255
# Default is to work in the current directory
256
self.run_bzr(['foo', 'bar'])
257
self.assertEqual(cwd, self.working_dir)
259
self.run_bzr(['foo', 'bar'], working_dir=None)
260
self.assertEqual(cwd, self.working_dir)
262
# The function should be run in the alternative directory
263
# but afterwards the current working dir shouldn't be changed
264
self.run_bzr(['foo', 'bar'], working_dir='one')
265
self.assertNotEqual(cwd, self.working_dir)
266
self.assertEndsWith(self.working_dir, 'one')
267
self.assertEqual(cwd, osutils.getcwd())
269
self.run_bzr(['foo', 'bar'], working_dir='two')
270
self.assertNotEqual(cwd, self.working_dir)
271
self.assertEndsWith(self.working_dir, 'two')
272
self.assertEqual(cwd, osutils.getcwd())
275
class TestRunBzrSubprocess(TestCaseWithTransport):
277
def test_run_bzr_subprocess(self):
278
"""The run_bzr_helper_external command behaves nicely."""
279
result = self.run_bzr_subprocess('--version')
280
result = self.run_bzr_subprocess(['--version'])
281
result = self.run_bzr_subprocess('--version', retcode=None)
282
self.assertContainsRe(result[0], 'is free software')
283
self.assertRaises(AssertionError, self.run_bzr_subprocess,
285
result = self.run_bzr_subprocess('--versionn', retcode=3)
286
result = self.run_bzr_subprocess('--versionn', retcode=None)
287
self.assertContainsRe(result[1], 'unknown command')
288
err = self.run_bzr_subprocess(['merge', '--merge-type',
289
'magic merge'], retcode=3)[1]
290
self.assertContainsRe(err, 'Bad value "magic merge" for option'
293
def test_run_bzr_subprocess_env(self):
294
"""run_bzr_subprocess can set environment variables in the child only.
296
These changes should not change the running process, only the child.
298
# The test suite should unset this variable
299
self.assertEqual(None, os.environ.get('BZR_EMAIL'))
300
out, err = self.run_bzr_subprocess('whoami', env_changes={
301
'BZR_EMAIL':'Joe Foo <joe@foo.com>'
302
}, universal_newlines=True)
303
self.assertEqual('', err)
304
self.assertEqual('Joe Foo <joe@foo.com>\n', out)
305
# And it should not be modified
306
self.assertEqual(None, os.environ.get('BZR_EMAIL'))
308
# Do it again with a different address, just to make sure
309
# it is actually changing
310
out, err = self.run_bzr_subprocess('whoami', env_changes={
311
'BZR_EMAIL':'Barry <bar@foo.com>'
312
}, universal_newlines=True)
313
self.assertEqual('', err)
314
self.assertEqual('Barry <bar@foo.com>\n', out)
315
self.assertEqual(None, os.environ.get('BZR_EMAIL'))
317
def test_run_bzr_subprocess_env_del(self):
318
"""run_bzr_subprocess can remove environment variables too."""
319
# Create a random email, so we are sure this won't collide
320
rand_bzr_email = 'John Doe <jdoe@%s.com>' % (osutils.rand_chars(20),)
321
rand_email = 'Jane Doe <jdoe@%s.com>' % (osutils.rand_chars(20),)
322
os.environ['BZR_EMAIL'] = rand_bzr_email
323
os.environ['EMAIL'] = rand_email
325
# By default, the child will inherit the current env setting
326
out, err = self.run_bzr_subprocess('whoami', universal_newlines=True)
327
self.assertEqual('', err)
328
self.assertEqual(rand_bzr_email + '\n', out)
330
# Now that BZR_EMAIL is not set, it should fall back to EMAIL
331
out, err = self.run_bzr_subprocess('whoami',
332
env_changes={'BZR_EMAIL':None},
333
universal_newlines=True)
334
self.assertEqual('', err)
335
self.assertEqual(rand_email + '\n', out)
337
# This switches back to the default email guessing logic
338
# Which shouldn't match either of the above addresses
339
out, err = self.run_bzr_subprocess('whoami',
340
env_changes={'BZR_EMAIL':None, 'EMAIL':None},
341
universal_newlines=True)
343
self.assertEqual('', err)
344
self.assertNotEqual(rand_bzr_email + '\n', out)
345
self.assertNotEqual(rand_email + '\n', out)
347
# TestCase cleans up BZR_EMAIL, and EMAIL at startup
348
del os.environ['BZR_EMAIL']
349
del os.environ['EMAIL']
351
def test_run_bzr_subprocess_env_del_missing(self):
352
"""run_bzr_subprocess won't fail if deleting a nonexistant env var"""
353
self.failIf('NON_EXISTANT_ENV_VAR' in os.environ)
354
out, err = self.run_bzr_subprocess('rocks',
355
env_changes={'NON_EXISTANT_ENV_VAR':None},
356
universal_newlines=True)
357
self.assertEqual('It sure does!\n', out)
358
self.assertEqual('', err)
360
def test_run_bzr_subprocess_working_dir(self):
361
"""Test that we can specify the working dir for the child"""
362
cwd = osutils.getcwd()
364
self.make_branch_and_tree('.')
365
self.make_branch_and_tree('one')
366
self.make_branch_and_tree('two')
368
def get_root(**kwargs):
369
"""Spawn a process to get the 'root' of the tree.
371
You can pass in arbitrary new arguments. This just makes
372
sure that the returned path doesn't have trailing whitespace.
374
return self.run_bzr_subprocess('root', **kwargs)[0].rstrip()
376
self.assertEqual(cwd, get_root())
377
self.assertEqual(cwd, get_root(working_dir=None))
378
# Has our path changed?
379
self.assertEqual(cwd, osutils.getcwd())
381
dir1 = get_root(working_dir='one')
382
self.assertEndsWith(dir1, 'one')
383
self.assertEqual(cwd, osutils.getcwd())
385
dir2 = get_root(working_dir='two')
386
self.assertEndsWith(dir2, 'two')
387
self.assertEqual(cwd, osutils.getcwd())
390
class _DontSpawnProcess(Exception):
391
"""A simple exception which just allows us to skip unnecessary steps"""
394
class TestRunBzrSubprocessCommands(TestCaseWithTransport):
396
def _popen(self, *args, **kwargs):
397
"""Record the command that is run, so that we can ensure it is correct"""
398
self._popen_args = args
399
self._popen_kwargs = kwargs
400
raise _DontSpawnProcess()
402
def test_run_bzr_subprocess_no_plugins(self):
403
self.assertRaises(_DontSpawnProcess, self.run_bzr_subprocess, '')
404
command = self._popen_args[0]
405
self.assertEqual(sys.executable, command[0])
406
self.assertEqual(self.get_bzr_path(), command[1])
407
self.assertEqual(['--no-plugins'], command[2:])
409
def test_allow_plugins(self):
410
self.assertRaises(_DontSpawnProcess,
411
self.run_bzr_subprocess, '', allow_plugins=True)
412
command = self._popen_args[0]
413
self.assertEqual([], command[2:])
416
class TestBzrSubprocess(TestCaseWithTransport):
418
def test_start_and_stop_bzr_subprocess(self):
419
"""We can start and perform other test actions while that process is
422
process = self.start_bzr_subprocess(['--version'])
423
result = self.finish_bzr_subprocess(process)
424
self.assertContainsRe(result[0], 'is free software')
425
self.assertEqual('', result[1])
427
def test_start_and_stop_bzr_subprocess_with_error(self):
428
"""finish_bzr_subprocess allows specification of the desired exit code.
430
process = self.start_bzr_subprocess(['--versionn'])
431
result = self.finish_bzr_subprocess(process, retcode=3)
432
self.assertEqual('', result[0])
433
self.assertContainsRe(result[1], 'unknown command')
435
def test_start_and_stop_bzr_subprocess_ignoring_retcode(self):
436
"""finish_bzr_subprocess allows the exit code to be ignored."""
437
process = self.start_bzr_subprocess(['--versionn'])
438
result = self.finish_bzr_subprocess(process, retcode=None)
439
self.assertEqual('', result[0])
440
self.assertContainsRe(result[1], 'unknown command')
442
def test_start_and_stop_bzr_subprocess_with_unexpected_retcode(self):
443
"""finish_bzr_subprocess raises self.failureException if the retcode is
444
not the expected one.
446
process = self.start_bzr_subprocess(['--versionn'])
447
self.assertRaises(self.failureException, self.finish_bzr_subprocess,
450
def test_start_and_stop_bzr_subprocess_send_signal(self):
451
"""finish_bzr_subprocess raises self.failureException if the retcode is
452
not the expected one.
454
process = self.start_bzr_subprocess(['wait-until-signalled'],
455
skip_if_plan_to_signal=True)
456
self.assertEqual('running\n', process.stdout.readline())
457
result = self.finish_bzr_subprocess(process, send_signal=signal.SIGINT,
459
self.assertEqual('', result[0])
460
self.assertEqual('bzr: interrupted\n', result[1])
462
def test_start_and_stop_working_dir(self):
463
cwd = osutils.getcwd()
465
self.make_branch_and_tree('one')
467
process = self.start_bzr_subprocess(['root'], working_dir='one')
468
result = self.finish_bzr_subprocess(process, universal_newlines=True)
469
self.assertEndsWith(result[0], 'one\n')
470
self.assertEqual('', result[1])
473
class TestRunBzrError(ExternalBase):
475
def test_run_bzr_error(self):
476
# retcode=0 is specially needed here because run_bzr_error expects
477
# an error (oddly enough) but we want to test the case of not
478
# actually getting one
479
out, err = self.run_bzr_error(['^$'], ['rocks'], retcode=0)
480
self.assertEqual(out, 'It sure does!\n')
481
# now test actually getting an error
482
out, err = self.run_bzr_error(
483
["bzr: ERROR: foobarbaz is not versioned"],
484
['file-id', 'foobarbaz'])
487
class TestSelftestListOnly(TestCase):
490
def _parse_test_list(lines, newlines_in_header=1):
491
"Parse a list of lines into a tuple of 3 lists (header,body,footer)."
497
header_newlines_found = 0
501
header_newlines_found += 1
502
if header_newlines_found >= newlines_in_header:
507
if line.startswith('-------'):
513
# If the last body line is blank, drop it off the list
514
if len(body) > 0 and body[-1] == '':
516
return (header,body,footer)
518
def test_list_only(self):
519
# check that bzr selftest --list-only works correctly
520
out,err = self.run_bzr('selftest selftest --list-only')
521
self.assertEndsWith(err, 'tests passed\n')
522
(header,body,footer) = self._parse_test_list(out.splitlines())
523
num_tests = len(body)
524
self.assertContainsRe(footer[0], 'Listed %s tests in' % num_tests)
526
def test_list_only_filtered(self):
527
# check that a filtered --list-only works, both include and exclude
528
out_all,err_all = self.run_bzr('selftest --list-only')
529
tests_all = self._parse_test_list(out_all.splitlines())[1]
530
out_incl,err_incl = self.run_bzr('selftest --list-only selftest')
531
tests_incl = self._parse_test_list(out_incl.splitlines())[1]
532
self.assertSubset(tests_incl, tests_all)
533
out_excl,err_excl = self.run_bzr(['selftest', '--list-only',
534
'--exclude', 'selftest'])
535
tests_excl = self._parse_test_list(out_excl.splitlines())[1]
536
self.assertSubset(tests_excl, tests_all)
537
set_incl = set(tests_incl)
538
set_excl = set(tests_excl)
539
intersection = set_incl.intersection(set_excl)
540
self.assertEquals(0, len(intersection))
541
self.assertEquals(len(tests_all), len(tests_incl) + len(tests_excl))
543
def test_list_only_random(self):
544
# check that --randomize works correctly
545
out_all,err_all = self.run_bzr('selftest --list-only selftest')
546
tests_all = self._parse_test_list(out_all.splitlines())[1]
547
# XXX: It looks like there are some orders for generating tests that
548
# fail as of 20070504 - maybe because of import order dependencies.
549
# So unfortunately this will rarely intermittently fail at the moment.
551
out_rand,err_rand = self.run_bzr(['selftest', '--list-only',
552
'selftest', '--randomize', 'now'])
553
(header_rand,tests_rand,dummy) = self._parse_test_list(
554
out_rand.splitlines(), 2)
555
# XXX: The following line asserts that the randomized order is not the
556
# same as the default order. It is just possible that they'll get
557
# randomized into the same order and this will falsely fail, but
558
# that's very unlikely in practice because there are thousands of
560
self.assertNotEqual(tests_all, tests_rand)
561
self.assertEqual(sorted(tests_all), sorted(tests_rand))
562
# Check that the seed can be reused to get the exact same order
563
seed_re = re.compile('Randomizing test order using seed (\w+)')
564
match_obj = seed_re.search(header_rand[-1])
565
seed = match_obj.group(1)
566
out_rand2,err_rand2 = self.run_bzr(['selftest', '--list-only',
567
'selftest', '--randomize', seed])
568
(header_rand2,tests_rand2,dummy) = self._parse_test_list(
569
out_rand2.splitlines(), 2)
570
self.assertEqual(tests_rand, tests_rand2)
573
class TestSelftestWithIdList(TestCaseInTempDir):
575
def test_load_list(self):
576
# We don't want to call selftest for the whole suite, so we start with
578
test_list_fname = 'test.list'
579
fl = open(test_list_fname, 'wt')
580
fl.write('%s\n' % self.id())
582
out, err = self.run_bzr(
583
['selftest', '--load-list', test_list_fname, '--list'])
584
self.assertContainsRe(out, "Listed 1 test in")
586
def test_load_unknown(self):
587
out, err = self.run_bzr('selftest --load-list I_do_not_exist ',
591
class TestSelftestStartingWith(TestCase):
593
def test_starting_with_single_argument(self):
594
out, err = self.run_bzr(
595
['selftest', '--starting-with', self.id(), '--list'])
596
self.assertContainsRe(out, "Listed 1 test in")
597
self.assertContainsRe(out, self.id())
599
def test_starting_with_multiple_argument(self):
600
out, err = self.run_bzr(
602
'--starting-with', self.id(),
603
'--starting-with', 'bzrlib.tests.test_sampler',
605
self.assertContainsRe(out, "Listed 2 tests in")
606
self.assertContainsRe(out, self.id())
607
self.assertContainsRe(out, 'bzrlib.tests.test_sampler')
69
TestCaseInTempDir.TEST_ROOT = old_root