59
69
except ParamikoNotPresent:
60
70
raise TestSkipped("Paramiko not present")
61
71
old_transport = bzrlib.tests.default_transport
62
old_root = TestCaseInTempDir.TEST_ROOT
63
TestCaseInTempDir.TEST_ROOT = None
72
old_root = TestCaseWithMemoryTransport.TEST_ROOT
73
TestCaseWithMemoryTransport.TEST_ROOT = None
65
75
TestOptions.current_test = "test_transport_set_to_sftp"
66
stdout = self.capture('selftest --transport=sftp test_transport_set_to_sftp')
76
stdout = self.run_bzr(
77
'selftest --transport=sftp test_transport_set_to_sftp')[0]
68
78
self.assertContainsRe(stdout, 'Ran 1 test')
69
79
self.assertEqual(old_transport, bzrlib.tests.default_transport)
71
81
TestOptions.current_test = "test_transport_set_to_memory"
72
stdout = self.capture('selftest --transport=memory test_transport_set_to_memory')
82
stdout = self.run_bzr(
83
'selftest --transport=memory test_transport_set_to_memory')[0]
73
84
self.assertContainsRe(stdout, 'Ran 1 test')
74
85
self.assertEqual(old_transport, bzrlib.tests.default_transport)
76
87
bzrlib.tests.default_transport = old_transport
77
88
TestOptions.current_test = None
78
TestCaseInTempDir.TEST_ROOT = old_root
89
TestCaseWithMemoryTransport.TEST_ROOT = old_root
92
class TestRunBzr(ExternalBase):
94
def _run_bzr_core(self, argv, retcode=0, encoding=None, stdin=None,
96
"""Override _run_bzr_core to test how it is invoked by run_bzr.
98
Attempts to run bzr from inside this class don't actually run it.
100
We test how run_bzr actually invokes bzr in another location.
101
Here we only need to test that it is run_bzr passes the right
102
parameters to run_bzr.
104
self.argv = list(argv)
105
self.retcode = retcode
106
self.encoding = encoding
108
self.working_dir = working_dir
111
def test_encoding(self):
112
"""Test that run_bzr passes encoding to _run_bzr_core"""
113
self.run_bzr('foo bar')
114
self.assertEqual(None, self.encoding)
115
self.assertEqual(['foo', 'bar'], self.argv)
117
self.run_bzr('foo bar', encoding='baz')
118
self.assertEqual('baz', self.encoding)
119
self.assertEqual(['foo', 'bar'], self.argv)
121
def test_retcode(self):
122
"""Test that run_bzr passes retcode to _run_bzr_core"""
123
# Default is retcode == 0
124
self.run_bzr('foo bar')
125
self.assertEqual(0, self.retcode)
126
self.assertEqual(['foo', 'bar'], self.argv)
128
self.run_bzr('foo bar', retcode=1)
129
self.assertEqual(1, self.retcode)
130
self.assertEqual(['foo', 'bar'], self.argv)
132
self.run_bzr('foo bar', retcode=None)
133
self.assertEqual(None, self.retcode)
134
self.assertEqual(['foo', 'bar'], self.argv)
136
self.run_bzr(['foo', 'bar'], retcode=3)
137
self.assertEqual(3, self.retcode)
138
self.assertEqual(['foo', 'bar'], self.argv)
140
def test_stdin(self):
141
# test that the stdin keyword to run_bzr is passed through to
142
# _run_bzr_core as-is. We do this by overriding
143
# _run_bzr_core in this class, and then calling run_bzr,
144
# which is a convenience function for _run_bzr_core, so
146
self.run_bzr('foo bar', stdin='gam')
147
self.assertEqual('gam', self.stdin)
148
self.assertEqual(['foo', 'bar'], self.argv)
150
self.run_bzr('foo bar', stdin='zippy')
151
self.assertEqual('zippy', self.stdin)
152
self.assertEqual(['foo', 'bar'], self.argv)
154
def test_working_dir(self):
155
"""Test that run_bzr passes working_dir to _run_bzr_core"""
156
self.run_bzr('foo bar')
157
self.assertEqual(None, self.working_dir)
158
self.assertEqual(['foo', 'bar'], self.argv)
160
self.run_bzr('foo bar', working_dir='baz')
161
self.assertEqual('baz', self.working_dir)
162
self.assertEqual(['foo', 'bar'], self.argv)
164
def test_reject_extra_keyword_arguments(self):
165
self.assertRaises(TypeError, self.run_bzr, "foo bar",
166
error_regex=['error message'])
169
class TestBenchmarkTests(TestCaseWithTransport):
80
171
def test_benchmark_runs_benchmark_tests(self):
81
172
"""bzr selftest --benchmark should not run the default test suite."""
82
173
# We test this by passing a regression test name to --benchmark, which
83
# should result in 0 rests run.
84
out, err = self.run_bzr('selftest', '--benchmark', 'workingtree_implementations')
174
# should result in 0 tests run.
175
old_root = TestCaseWithMemoryTransport.TEST_ROOT
177
TestCaseWithMemoryTransport.TEST_ROOT = None
178
out, err = self.run_bzr('selftest --benchmark'
179
' workingtree_implementations')
181
TestCaseWithMemoryTransport.TEST_ROOT = old_root
85
182
self.assertContainsRe(out, 'Ran 0 tests.*\n\nOK')
87
'running tests...\ntests passed\n',
91
class TestRunBzr(ExternalBase):
93
def run_bzr_captured(self, argv, retcode=0, encoding=None, stdin=None):
97
# test that the stdin keyword to run_bzr is passed through to
98
# run_bzr_captured as-is. We do this by overriding
99
# run_bzr_captured in this class, and then calling run_bzr,
100
# which is a convenience function for run_bzr_captured, so
102
self.run_bzr('foo', 'bar', stdin='gam')
103
self.assertEqual('gam', self.stdin)
104
self.run_bzr('foo', 'bar', stdin='zippy')
105
self.assertEqual('zippy', self.stdin)
186
benchfile = open(".perf_history", "rt")
188
lines = benchfile.readlines()
191
self.assertEqual(1, len(lines))
192
self.assertContainsRe(lines[0], "--date [0-9.]+")
108
195
class TestRunBzrCaptured(ExternalBase):
112
199
self.stdin = stdin
113
200
self.factory_stdin = getattr(bzrlib.ui.ui_factory, "stdin", None)
114
201
self.factory = bzrlib.ui.ui_factory
202
self.working_dir = osutils.getcwd()
115
203
stdout.write('foo\n')
116
204
stderr.write('bar\n')
119
207
def test_stdin(self):
120
# test that the stdin keyword to run_bzr_captured is passed through to
208
# test that the stdin keyword to _run_bzr_core is passed through to
121
209
# apply_redirected as a StringIO. We do this by overriding
122
# apply_redirected in this class, and then calling run_bzr_captured,
210
# apply_redirected in this class, and then calling _run_bzr_core,
123
211
# which calls apply_redirected.
124
self.run_bzr_captured(['foo', 'bar'], stdin='gam')
212
self.run_bzr(['foo', 'bar'], stdin='gam')
125
213
self.assertEqual('gam', self.stdin.read())
126
214
self.assertTrue(self.stdin is self.factory_stdin)
127
self.run_bzr_captured(['foo', 'bar'], stdin='zippy')
215
self.run_bzr(['foo', 'bar'], stdin='zippy')
128
216
self.assertEqual('zippy', self.stdin.read())
129
217
self.assertTrue(self.stdin is self.factory_stdin)
131
219
def test_ui_factory(self):
132
# each invocation of self.run_bzr_captured should get its own UI
133
# factory, which is an instance of TestUIFactory, with stdout and
134
# stderr attached to the stdout and stderr of the invoked
220
# each invocation of self.run_bzr should get its
221
# own UI factory, which is an instance of TestUIFactory,
222
# with stdin, stdout and stderr attached to the stdin,
223
# stdout and stderr of the invoked run_bzr
136
224
current_factory = bzrlib.ui.ui_factory
137
self.run_bzr_captured(['foo'])
225
self.run_bzr(['foo'])
138
226
self.failIf(current_factory is self.factory)
139
227
self.assertNotEqual(sys.stdout, self.factory.stdout)
140
228
self.assertNotEqual(sys.stderr, self.factory.stderr)
141
229
self.assertEqual('foo\n', self.factory.stdout.getvalue())
142
230
self.assertEqual('bar\n', self.factory.stderr.getvalue())
143
self.assertIsInstance(self.factory, bzrlib.tests.blackbox.TestUIFactory)
231
self.assertIsInstance(self.factory, TestUIFactory)
233
def test_working_dir(self):
234
self.build_tree(['one/', 'two/'])
235
cwd = osutils.getcwd()
237
# Default is to work in the current directory
238
self.run_bzr(['foo', 'bar'])
239
self.assertEqual(cwd, self.working_dir)
241
self.run_bzr(['foo', 'bar'], working_dir=None)
242
self.assertEqual(cwd, self.working_dir)
244
# The function should be run in the alternative directory
245
# but afterwards the current working dir shouldn't be changed
246
self.run_bzr(['foo', 'bar'], working_dir='one')
247
self.assertNotEqual(cwd, self.working_dir)
248
self.assertEndsWith(self.working_dir, 'one')
249
self.assertEqual(cwd, osutils.getcwd())
251
self.run_bzr(['foo', 'bar'], working_dir='two')
252
self.assertNotEqual(cwd, self.working_dir)
253
self.assertEndsWith(self.working_dir, 'two')
254
self.assertEqual(cwd, osutils.getcwd())
257
class TestRunBzrSubprocess(TestCaseWithTransport):
259
def test_run_bzr_subprocess(self):
260
"""The run_bzr_helper_external command behaves nicely."""
261
result = self.run_bzr_subprocess('--version')
262
result = self.run_bzr_subprocess(['--version'])
263
result = self.run_bzr_subprocess('--version', retcode=None)
264
self.assertContainsRe(result[0], 'is free software')
265
self.assertRaises(AssertionError, self.run_bzr_subprocess,
267
result = self.run_bzr_subprocess('--versionn', retcode=3)
268
result = self.run_bzr_subprocess('--versionn', retcode=None)
269
self.assertContainsRe(result[1], 'unknown command')
270
err = self.run_bzr_subprocess(['merge', '--merge-type',
271
'magic merge'], retcode=3)[1]
272
self.assertContainsRe(err, 'Bad value "magic merge" for option'
275
def test_run_bzr_subprocess_env(self):
276
"""run_bzr_subprocess can set environment variables in the child only.
278
These changes should not change the running process, only the child.
280
# The test suite should unset this variable
281
self.assertEqual(None, os.environ.get('BZR_EMAIL'))
282
out, err = self.run_bzr_subprocess('whoami', env_changes={
283
'BZR_EMAIL':'Joe Foo <joe@foo.com>'
284
}, universal_newlines=True)
285
self.assertEqual('', err)
286
self.assertEqual('Joe Foo <joe@foo.com>\n', out)
287
# And it should not be modified
288
self.assertEqual(None, os.environ.get('BZR_EMAIL'))
290
# Do it again with a different address, just to make sure
291
# it is actually changing
292
out, err = self.run_bzr_subprocess('whoami', env_changes={
293
'BZR_EMAIL':'Barry <bar@foo.com>'
294
}, universal_newlines=True)
295
self.assertEqual('', err)
296
self.assertEqual('Barry <bar@foo.com>\n', out)
297
self.assertEqual(None, os.environ.get('BZR_EMAIL'))
299
def test_run_bzr_subprocess_env_del(self):
300
"""run_bzr_subprocess can remove environment variables too."""
301
# Create a random email, so we are sure this won't collide
302
rand_bzr_email = 'John Doe <jdoe@%s.com>' % (osutils.rand_chars(20),)
303
rand_email = 'Jane Doe <jdoe@%s.com>' % (osutils.rand_chars(20),)
304
os.environ['BZR_EMAIL'] = rand_bzr_email
305
os.environ['EMAIL'] = rand_email
307
# By default, the child will inherit the current env setting
308
out, err = self.run_bzr_subprocess('whoami', universal_newlines=True)
309
self.assertEqual('', err)
310
self.assertEqual(rand_bzr_email + '\n', out)
312
# Now that BZR_EMAIL is not set, it should fall back to EMAIL
313
out, err = self.run_bzr_subprocess('whoami',
314
env_changes={'BZR_EMAIL':None},
315
universal_newlines=True)
316
self.assertEqual('', err)
317
self.assertEqual(rand_email + '\n', out)
319
# This switches back to the default email guessing logic
320
# Which shouldn't match either of the above addresses
321
out, err = self.run_bzr_subprocess('whoami',
322
env_changes={'BZR_EMAIL':None, 'EMAIL':None},
323
universal_newlines=True)
325
self.assertEqual('', err)
326
self.assertNotEqual(rand_bzr_email + '\n', out)
327
self.assertNotEqual(rand_email + '\n', out)
329
# TestCase cleans up BZR_EMAIL, and EMAIL at startup
330
del os.environ['BZR_EMAIL']
331
del os.environ['EMAIL']
333
def test_run_bzr_subprocess_env_del_missing(self):
334
"""run_bzr_subprocess won't fail if deleting a nonexistant env var"""
335
self.failIf('NON_EXISTANT_ENV_VAR' in os.environ)
336
out, err = self.run_bzr_subprocess('rocks',
337
env_changes={'NON_EXISTANT_ENV_VAR':None},
338
universal_newlines=True)
339
self.assertEqual('It sure does!\n', out)
340
self.assertEqual('', err)
342
def test_run_bzr_subprocess_working_dir(self):
343
"""Test that we can specify the working dir for the child"""
344
cwd = osutils.getcwd()
346
self.make_branch_and_tree('.')
347
self.make_branch_and_tree('one')
348
self.make_branch_and_tree('two')
350
def get_root(**kwargs):
351
"""Spawn a process to get the 'root' of the tree.
353
You can pass in arbitrary new arguments. This just makes
354
sure that the returned path doesn't have trailing whitespace.
356
return self.run_bzr_subprocess('root', **kwargs)[0].rstrip()
358
self.assertEqual(cwd, get_root())
359
self.assertEqual(cwd, get_root(working_dir=None))
360
# Has our path changed?
361
self.assertEqual(cwd, osutils.getcwd())
363
dir1 = get_root(working_dir='one')
364
self.assertEndsWith(dir1, 'one')
365
self.assertEqual(cwd, osutils.getcwd())
367
dir2 = get_root(working_dir='two')
368
self.assertEndsWith(dir2, 'two')
369
self.assertEqual(cwd, osutils.getcwd())
372
class _DontSpawnProcess(Exception):
373
"""A simple exception which just allows us to skip unnecessary steps"""
376
class TestRunBzrSubprocessCommands(TestCaseWithTransport):
378
def _popen(self, *args, **kwargs):
379
"""Record the command that is run, so that we can ensure it is correct"""
380
self._popen_args = args
381
self._popen_kwargs = kwargs
382
raise _DontSpawnProcess()
384
def test_run_bzr_subprocess_no_plugins(self):
385
self.assertRaises(_DontSpawnProcess, self.run_bzr_subprocess, '')
386
command = self._popen_args[0]
387
self.assertEqual(sys.executable, command[0])
388
self.assertEqual(self.get_bzr_path(), command[1])
389
self.assertEqual(['--no-plugins'], command[2:])
391
def test_allow_plugins(self):
392
self.assertRaises(_DontSpawnProcess,
393
self.run_bzr_subprocess, '', allow_plugins=True)
394
command = self._popen_args[0]
395
self.assertEqual([], command[2:])
398
class TestBzrSubprocess(TestCaseWithTransport):
400
def test_start_and_stop_bzr_subprocess(self):
401
"""We can start and perform other test actions while that process is
404
process = self.start_bzr_subprocess(['--version'])
405
result = self.finish_bzr_subprocess(process)
406
self.assertContainsRe(result[0], 'is free software')
407
self.assertEqual('', result[1])
409
def test_start_and_stop_bzr_subprocess_with_error(self):
410
"""finish_bzr_subprocess allows specification of the desired exit code.
412
process = self.start_bzr_subprocess(['--versionn'])
413
result = self.finish_bzr_subprocess(process, retcode=3)
414
self.assertEqual('', result[0])
415
self.assertContainsRe(result[1], 'unknown command')
417
def test_start_and_stop_bzr_subprocess_ignoring_retcode(self):
418
"""finish_bzr_subprocess allows the exit code to be ignored."""
419
process = self.start_bzr_subprocess(['--versionn'])
420
result = self.finish_bzr_subprocess(process, retcode=None)
421
self.assertEqual('', result[0])
422
self.assertContainsRe(result[1], 'unknown command')
424
def test_start_and_stop_bzr_subprocess_with_unexpected_retcode(self):
425
"""finish_bzr_subprocess raises self.failureException if the retcode is
426
not the expected one.
428
process = self.start_bzr_subprocess(['--versionn'])
429
self.assertRaises(self.failureException, self.finish_bzr_subprocess,
432
def test_start_and_stop_bzr_subprocess_send_signal(self):
433
"""finish_bzr_subprocess raises self.failureException if the retcode is
434
not the expected one.
436
process = self.start_bzr_subprocess(['wait-until-signalled'],
437
skip_if_plan_to_signal=True)
438
self.assertEqual('running\n', process.stdout.readline())
439
result = self.finish_bzr_subprocess(process, send_signal=signal.SIGINT,
441
self.assertEqual('', result[0])
442
self.assertEqual('bzr: interrupted\n', result[1])
444
def test_start_and_stop_working_dir(self):
445
cwd = osutils.getcwd()
447
self.make_branch_and_tree('one')
449
process = self.start_bzr_subprocess(['root'], working_dir='one')
450
result = self.finish_bzr_subprocess(process, universal_newlines=True)
451
self.assertEndsWith(result[0], 'one\n')
452
self.assertEqual('', result[1])
455
class TestRunBzrError(ExternalBase):
457
def test_run_bzr_error(self):
458
# retcode=0 is specially needed here because run_bzr_error expects
459
# an error (oddly enough) but we want to test the case of not
460
# actually getting one
461
out, err = self.run_bzr_error(['^$'], ['rocks'], retcode=0)
462
self.assertEqual(out, 'It sure does!\n')
463
# now test actually getting an error
464
out, err = self.run_bzr_error(
465
["bzr: ERROR: foobarbaz is not versioned"],
466
['file-id', 'foobarbaz'])
469
class TestSelftestListOnly(TestCase):
472
def _parse_test_list(lines, newlines_in_header=1):
473
"Parse a list of lines into a tuple of 3 lists (header,body,footer)."
479
header_newlines_found = 0
483
header_newlines_found += 1
484
if header_newlines_found >= newlines_in_header:
489
if line.startswith('-------'):
495
# If the last body line is blank, drop it off the list
496
if len(body) > 0 and body[-1] == '':
498
return (header,body,footer)
500
def test_list_only(self):
501
# check that bzr selftest --list-only works correctly
502
out,err = self.run_bzr('selftest selftest --list-only')
503
self.assertEndsWith(err, 'tests passed\n')
504
(header,body,footer) = self._parse_test_list(out.splitlines())
505
num_tests = len(body)
506
self.assertContainsRe(footer[0], 'Listed %s tests in' % num_tests)
508
def test_list_only_filtered(self):
509
# check that a filtered --list-only works, both include and exclude
510
out_all,err_all = self.run_bzr('selftest --list-only')
511
tests_all = self._parse_test_list(out_all.splitlines())[1]
512
out_incl,err_incl = self.run_bzr('selftest --list-only selftest')
513
tests_incl = self._parse_test_list(out_incl.splitlines())[1]
514
self.assertSubset(tests_incl, tests_all)
515
out_excl,err_excl = self.run_bzr(['selftest', '--list-only',
516
'--exclude', 'selftest'])
517
tests_excl = self._parse_test_list(out_excl.splitlines())[1]
518
self.assertSubset(tests_excl, tests_all)
519
set_incl = set(tests_incl)
520
set_excl = set(tests_excl)
521
intersection = set_incl.intersection(set_excl)
522
self.assertEquals(0, len(intersection))
523
self.assertEquals(len(tests_all), len(tests_incl) + len(tests_excl))
525
def test_list_only_random(self):
526
# check that --randomize works correctly
527
out_all,err_all = self.run_bzr('selftest --list-only selftest')
528
tests_all = self._parse_test_list(out_all.splitlines())[1]
529
# XXX: It looks like there are some orders for generating tests that
530
# fail as of 20070504 - maybe because of import order dependencies.
531
# So unfortunately this will rarely intermittently fail at the moment.
533
out_rand,err_rand = self.run_bzr(['selftest', '--list-only',
534
'selftest', '--randomize', 'now'])
535
(header_rand,tests_rand,dummy) = self._parse_test_list(
536
out_rand.splitlines(), 2)
537
# XXX: The following line asserts that the randomized order is not the
538
# same as the default order. It is just possible that they'll get
539
# randomized into the same order and this will falsely fail, but
540
# that's very unlikely in practice because there are thousands of
542
self.assertNotEqual(tests_all, tests_rand)
543
self.assertEqual(sorted(tests_all), sorted(tests_rand))
544
# Check that the seed can be reused to get the exact same order
545
seed_re = re.compile('Randomizing test order using seed (\w+)')
546
match_obj = seed_re.search(header_rand[-1])
547
seed = match_obj.group(1)
548
out_rand2,err_rand2 = self.run_bzr(['selftest', '--list-only',
549
'selftest', '--randomize', seed])
550
(header_rand2,tests_rand2,dummy) = self._parse_test_list(
551
out_rand2.splitlines(), 2)
552
self.assertEqual(tests_rand, tests_rand2)
555
class TestSelftestWithIdList(TestCaseInTempDir):
557
def test_load_list(self):
558
# We don't want to call selftest for the whole suite, so we start with
560
test_list_fname = 'test.list'
561
fl = open(test_list_fname, 'wt')
562
fl.write('%s\n' % self.id())
564
out, err = self.run_bzr(
565
['selftest', '--load-list', test_list_fname, '--list'])
566
self.assertContainsRe(out, "Listed 1 test in")
568
def test_load_unknown(self):
569
out, err = self.run_bzr('selftest --load-list I_do_not_exist ',
573
class TestSelftestStartingWith(TestCase):
575
def test_starting_with_single_argument(self):
576
out, err = self.run_bzr(
577
['selftest', '--starting-with', self.id(), '--list'])
578
self.assertContainsRe(out, "Listed 1 test in")
579
self.assertContainsRe(out, self.id())
581
def test_starting_with_multiple_argument(self):
582
out, err = self.run_bzr(
584
'--starting-with', self.id(),
585
'--starting-with', 'bzrlib.tests.test_sampler',
587
self.assertContainsRe(out, "Listed 2 tests in")
588
self.assertContainsRe(out, self.id())
589
self.assertContainsRe(out, 'bzrlib.tests.test_sampler')