1
# Copyright (C) 2005 Canonical Ltd
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
# GNU General Public License for more details.
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
"""UI tests for the test framework."""
27
from bzrlib.errors import ParamikoNotPresent
28
from bzrlib.tests import (
30
TestCaseWithMemoryTransport,
31
TestCaseWithTransport,
34
from bzrlib.tests.blackbox import ExternalBase
37
class TestOptions(TestCase):
41
def test_transport_set_to_sftp(self):
42
# test the --transport option has taken effect from within the
45
import bzrlib.transport.sftp
46
except ParamikoNotPresent:
47
raise TestSkipped("Paramiko not present")
48
if TestOptions.current_test != "test_transport_set_to_sftp":
50
self.assertEqual(bzrlib.transport.sftp.SFTPAbsoluteServer,
51
bzrlib.tests.default_transport)
53
def test_transport_set_to_memory(self):
54
# test the --transport option has taken effect from within the
56
import bzrlib.transport.memory
57
if TestOptions.current_test != "test_transport_set_to_memory":
59
self.assertEqual(bzrlib.transport.memory.MemoryServer,
60
bzrlib.tests.default_transport)
62
def test_transport(self):
63
# test that --transport=sftp works
65
import bzrlib.transport.sftp
66
except ParamikoNotPresent:
67
raise TestSkipped("Paramiko not present")
68
old_transport = bzrlib.tests.default_transport
69
old_root = TestCaseWithMemoryTransport.TEST_ROOT
70
TestCaseWithMemoryTransport.TEST_ROOT = None
72
TestOptions.current_test = "test_transport_set_to_sftp"
73
stdout = self.capture('selftest --transport=sftp test_transport_set_to_sftp')
75
self.assertContainsRe(stdout, 'Ran 1 test')
76
self.assertEqual(old_transport, bzrlib.tests.default_transport)
78
TestOptions.current_test = "test_transport_set_to_memory"
79
stdout = self.capture('selftest --transport=memory test_transport_set_to_memory')
80
self.assertContainsRe(stdout, 'Ran 1 test')
81
self.assertEqual(old_transport, bzrlib.tests.default_transport)
83
bzrlib.tests.default_transport = old_transport
84
TestOptions.current_test = None
85
TestCaseWithMemoryTransport.TEST_ROOT = old_root
88
class TestRunBzr(ExternalBase):
90
def run_bzr_captured(self, argv, retcode=0, encoding=None, stdin=None,
92
"""Override run_bzr_captured to test how it is invoked by run_bzr.
94
We test how run_bzr_captured actually invokes bzr in another location.
95
Here we only need to test that it is run_bzr passes the right
96
parameters to run_bzr_captured.
99
self.retcode = retcode
100
self.encoding = encoding
102
self.working_dir = working_dir
105
"""Test that run_bzr passes args correctly to run_bzr_captured"""
106
self.run_bzr('arg1', 'arg2', 'arg3', retcode=1)
107
self.assertEqual(('arg1', 'arg2', 'arg3'), self.argv)
109
def test_encoding(self):
110
"""Test that run_bzr passes encoding to run_bzr_captured"""
111
self.run_bzr('foo', 'bar')
112
self.assertEqual(None, self.encoding)
113
self.assertEqual(('foo', 'bar'), self.argv)
115
self.run_bzr('foo', 'bar', encoding='baz')
116
self.assertEqual('baz', self.encoding)
117
self.assertEqual(('foo', 'bar'), self.argv)
119
def test_retcode(self):
120
"""Test that run_bzr passes retcode to run_bzr_captured"""
121
# Default is retcode == 0
122
self.run_bzr('foo', 'bar')
123
self.assertEqual(0, self.retcode)
124
self.assertEqual(('foo', 'bar'), self.argv)
126
self.run_bzr('foo', 'bar', retcode=1)
127
self.assertEqual(1, self.retcode)
128
self.assertEqual(('foo', 'bar'), self.argv)
130
self.run_bzr('foo', 'bar', retcode=None)
131
self.assertEqual(None, self.retcode)
132
self.assertEqual(('foo', 'bar'), self.argv)
134
self.run_bzr('foo', 'bar', retcode=3)
135
self.assertEqual(3, self.retcode)
136
self.assertEqual(('foo', 'bar'), self.argv)
138
def test_stdin(self):
139
# test that the stdin keyword to run_bzr is passed through to
140
# run_bzr_captured as-is. We do this by overriding
141
# run_bzr_captured in this class, and then calling run_bzr,
142
# which is a convenience function for run_bzr_captured, so
144
self.run_bzr('foo', 'bar', stdin='gam')
145
self.assertEqual('gam', self.stdin)
146
self.assertEqual(('foo', 'bar'), self.argv)
148
self.run_bzr('foo', 'bar', stdin='zippy')
149
self.assertEqual('zippy', self.stdin)
150
self.assertEqual(('foo', 'bar'), self.argv)
152
def test_working_dir(self):
153
"""Test that run_bzr passes working_dir to run_bzr_captured"""
154
self.run_bzr('foo', 'bar')
155
self.assertEqual(None, self.working_dir)
156
self.assertEqual(('foo', 'bar'), self.argv)
158
self.run_bzr('foo', 'bar', working_dir='baz')
159
self.assertEqual('baz', self.working_dir)
160
self.assertEqual(('foo', 'bar'), self.argv)
163
class TestBenchmarkTests(TestCaseWithTransport):
165
def test_benchmark_runs_benchmark_tests(self):
166
"""bzr selftest --benchmark should not run the default test suite."""
167
# We test this by passing a regression test name to --benchmark, which
168
# should result in 0 rests run.
169
old_root = TestCaseWithMemoryTransport.TEST_ROOT
171
TestCaseWithMemoryTransport.TEST_ROOT = None
172
out, err = self.run_bzr('selftest', '--benchmark', 'workingtree_implementations')
174
TestCaseWithMemoryTransport.TEST_ROOT = old_root
175
self.assertContainsRe(out, 'Ran 0 tests.*\n\nOK')
179
benchfile = open(".perf_history", "rt")
181
lines = benchfile.readlines()
184
self.assertEqual(1, len(lines))
185
self.assertContainsRe(lines[0], "--date [0-9.]+")
188
class TestRunBzrCaptured(ExternalBase):
190
def apply_redirected(self, stdin=None, stdout=None, stderr=None,
191
a_callable=None, *args, **kwargs):
193
self.factory_stdin = getattr(bzrlib.ui.ui_factory, "stdin", None)
194
self.factory = bzrlib.ui.ui_factory
195
self.working_dir = osutils.getcwd()
196
stdout.write('foo\n')
197
stderr.write('bar\n')
200
def test_stdin(self):
201
# test that the stdin keyword to run_bzr_captured is passed through to
202
# apply_redirected as a StringIO. We do this by overriding
203
# apply_redirected in this class, and then calling run_bzr_captured,
204
# which calls apply_redirected.
205
self.run_bzr_captured(['foo', 'bar'], stdin='gam')
206
self.assertEqual('gam', self.stdin.read())
207
self.assertTrue(self.stdin is self.factory_stdin)
208
self.run_bzr_captured(['foo', 'bar'], stdin='zippy')
209
self.assertEqual('zippy', self.stdin.read())
210
self.assertTrue(self.stdin is self.factory_stdin)
212
def test_ui_factory(self):
213
# each invocation of self.run_bzr_captured should get its own UI
214
# factory, which is an instance of TestUIFactory, with stdout and
215
# stderr attached to the stdout and stderr of the invoked
217
current_factory = bzrlib.ui.ui_factory
218
self.run_bzr_captured(['foo'])
219
self.failIf(current_factory is self.factory)
220
self.assertNotEqual(sys.stdout, self.factory.stdout)
221
self.assertNotEqual(sys.stderr, self.factory.stderr)
222
self.assertEqual('foo\n', self.factory.stdout.getvalue())
223
self.assertEqual('bar\n', self.factory.stderr.getvalue())
224
self.assertIsInstance(self.factory, bzrlib.tests.blackbox.TestUIFactory)
226
def test_working_dir(self):
227
self.build_tree(['one/', 'two/'])
228
cwd = osutils.getcwd()
230
# Default is to work in the current directory
231
self.run_bzr_captured(['foo', 'bar'])
232
self.assertEqual(cwd, self.working_dir)
234
self.run_bzr_captured(['foo', 'bar'], working_dir=None)
235
self.assertEqual(cwd, self.working_dir)
237
# The function should be run in the alternative directory
238
# but afterwards the current working dir shouldn't be changed
239
self.run_bzr_captured(['foo', 'bar'], working_dir='one')
240
self.assertNotEqual(cwd, self.working_dir)
241
self.assertEndsWith(self.working_dir, 'one')
242
self.assertEqual(cwd, osutils.getcwd())
244
self.run_bzr_captured(['foo', 'bar'], working_dir='two')
245
self.assertNotEqual(cwd, self.working_dir)
246
self.assertEndsWith(self.working_dir, 'two')
247
self.assertEqual(cwd, osutils.getcwd())
250
class TestRunBzrSubprocess(TestCaseWithTransport):
252
def test_run_bzr_subprocess(self):
253
"""The run_bzr_helper_external comand behaves nicely."""
254
result = self.run_bzr_subprocess('--version')
255
result = self.run_bzr_subprocess('--version', retcode=None)
256
self.assertContainsRe(result[0], 'is free software')
257
self.assertRaises(AssertionError, self.run_bzr_subprocess,
259
result = self.run_bzr_subprocess('--versionn', retcode=3)
260
result = self.run_bzr_subprocess('--versionn', retcode=None)
261
self.assertContainsRe(result[1], 'unknown command')
262
err = self.run_bzr_subprocess('merge', '--merge-type', 'magic merge',
264
self.assertContainsRe(err, 'No known merge type magic merge')
266
def test_run_bzr_subprocess_env(self):
267
"""run_bzr_subprocess can set environment variables in the child only.
269
These changes should not change the running process, only the child.
271
# The test suite should unset this variable
272
self.assertEqual(None, os.environ.get('BZR_EMAIL'))
273
out, err = self.run_bzr_subprocess('whoami', env_changes={
274
'BZR_EMAIL':'Joe Foo <joe@foo.com>'
275
}, universal_newlines=True)
276
self.assertEqual('', err)
277
self.assertEqual('Joe Foo <joe@foo.com>\n', out)
278
# And it should not be modified
279
self.assertEqual(None, os.environ.get('BZR_EMAIL'))
281
# Do it again with a different address, just to make sure
282
# it is actually changing
283
out, err = self.run_bzr_subprocess('whoami', env_changes={
284
'BZR_EMAIL':'Barry <bar@foo.com>'
285
}, universal_newlines=True)
286
self.assertEqual('', err)
287
self.assertEqual('Barry <bar@foo.com>\n', out)
288
self.assertEqual(None, os.environ.get('BZR_EMAIL'))
290
def test_run_bzr_subprocess_env_del(self):
291
"""run_bzr_subprocess can remove environment variables too."""
292
# Create a random email, so we are sure this won't collide
293
rand_bzr_email = 'John Doe <jdoe@%s.com>' % (osutils.rand_chars(20),)
294
rand_email = 'Jane Doe <jdoe@%s.com>' % (osutils.rand_chars(20),)
295
os.environ['BZR_EMAIL'] = rand_bzr_email
296
os.environ['EMAIL'] = rand_email
298
# By default, the child will inherit the current env setting
299
out, err = self.run_bzr_subprocess('whoami', universal_newlines=True)
300
self.assertEqual('', err)
301
self.assertEqual(rand_bzr_email + '\n', out)
303
# Now that BZR_EMAIL is not set, it should fall back to EMAIL
304
out, err = self.run_bzr_subprocess('whoami',
305
env_changes={'BZR_EMAIL':None},
306
universal_newlines=True)
307
self.assertEqual('', err)
308
self.assertEqual(rand_email + '\n', out)
310
# This switches back to the default email guessing logic
311
# Which shouldn't match either of the above addresses
312
out, err = self.run_bzr_subprocess('whoami',
313
env_changes={'BZR_EMAIL':None, 'EMAIL':None},
314
universal_newlines=True)
316
self.assertEqual('', err)
317
self.assertNotEqual(rand_bzr_email + '\n', out)
318
self.assertNotEqual(rand_email + '\n', out)
320
# TestCase cleans up BZR_EMAIL, and EMAIL at startup
321
del os.environ['BZR_EMAIL']
322
del os.environ['EMAIL']
324
def test_run_bzr_subprocess_env_del_missing(self):
325
"""run_bzr_subprocess won't fail if deleting a nonexistant env var"""
326
self.failIf('NON_EXISTANT_ENV_VAR' in os.environ)
327
out, err = self.run_bzr_subprocess('rocks',
328
env_changes={'NON_EXISTANT_ENV_VAR':None},
329
universal_newlines=True)
330
self.assertEqual('it sure does!\n', out)
331
self.assertEqual('', err)
333
def test_run_bzr_subprocess_working_dir(self):
334
"""Test that we can specify the working dir for the child"""
335
cwd = osutils.getcwd()
337
self.make_branch_and_tree('.')
338
self.make_branch_and_tree('one')
339
self.make_branch_and_tree('two')
341
def get_root(**kwargs):
342
"""Spawn a process to get the 'root' of the tree.
344
You can pass in arbitrary new arguments. This just makes
345
sure that the returned path doesn't have trailing whitespace.
347
return self.run_bzr_subprocess('root', **kwargs)[0].rstrip()
349
self.assertEqual(cwd, get_root())
350
self.assertEqual(cwd, get_root(working_dir=None))
351
# Has our path changed?
352
self.assertEqual(cwd, osutils.getcwd())
354
dir1 = get_root(working_dir='one')
355
self.assertEndsWith(dir1, 'one')
356
self.assertEqual(cwd, osutils.getcwd())
358
dir2 = get_root(working_dir='two')
359
self.assertEndsWith(dir2, 'two')
360
self.assertEqual(cwd, osutils.getcwd())
363
class _DontSpawnProcess(Exception):
364
"""A simple exception which just allows us to skip unnecessary steps"""
367
class TestRunBzrSubprocessCommands(TestCaseWithTransport):
369
def _popen(self, *args, **kwargs):
370
"""Record the command that is run, so that we can ensure it is correct"""
371
self._popen_args = args
372
self._popen_kwargs = kwargs
373
raise _DontSpawnProcess()
375
def test_run_bzr_subprocess_no_plugins(self):
376
self.assertRaises(_DontSpawnProcess, self.run_bzr_subprocess)
377
command = self._popen_args[0]
378
self.assertEqual(sys.executable, command[0])
379
self.assertEqual(self.get_bzr_path(), command[1])
380
self.assertEqual(['--no-plugins'], command[2:])
382
def test_allow_plugins(self):
383
self.assertRaises(_DontSpawnProcess,
384
self.run_bzr_subprocess, allow_plugins=True)
385
command = self._popen_args[0]
386
self.assertEqual([], command[2:])
389
class TestBzrSubprocess(TestCaseWithTransport):
391
def test_start_and_stop_bzr_subprocess(self):
392
"""We can start and perform other test actions while that process is
395
process = self.start_bzr_subprocess(['--version'])
396
result = self.finish_bzr_subprocess(process)
397
self.assertContainsRe(result[0], 'is free software')
398
self.assertEqual('', result[1])
400
def test_start_and_stop_bzr_subprocess_with_error(self):
401
"""finish_bzr_subprocess allows specification of the desired exit code.
403
process = self.start_bzr_subprocess(['--versionn'])
404
result = self.finish_bzr_subprocess(process, retcode=3)
405
self.assertEqual('', result[0])
406
self.assertContainsRe(result[1], 'unknown command')
408
def test_start_and_stop_bzr_subprocess_ignoring_retcode(self):
409
"""finish_bzr_subprocess allows the exit code to be ignored."""
410
process = self.start_bzr_subprocess(['--versionn'])
411
result = self.finish_bzr_subprocess(process, retcode=None)
412
self.assertEqual('', result[0])
413
self.assertContainsRe(result[1], 'unknown command')
415
def test_start_and_stop_bzr_subprocess_with_unexpected_retcode(self):
416
"""finish_bzr_subprocess raises self.failureException if the retcode is
417
not the expected one.
419
process = self.start_bzr_subprocess(['--versionn'])
420
self.assertRaises(self.failureException, self.finish_bzr_subprocess,
423
def test_start_and_stop_bzr_subprocess_send_signal(self):
424
"""finish_bzr_subprocess raises self.failureException if the retcode is
425
not the expected one.
427
process = self.start_bzr_subprocess(['wait-until-signalled'],
428
skip_if_plan_to_signal=True)
429
self.assertEqual('running\n', process.stdout.readline())
430
result = self.finish_bzr_subprocess(process, send_signal=signal.SIGINT,
432
self.assertEqual('', result[0])
433
self.assertEqual('bzr: interrupted\n', result[1])
435
def test_start_and_stop_working_dir(self):
436
cwd = osutils.getcwd()
438
self.make_branch_and_tree('one')
440
process = self.start_bzr_subprocess(['root'], working_dir='one')
441
result = self.finish_bzr_subprocess(process)
442
self.assertEndsWith(result[0], 'one\n')
443
self.assertEqual('', result[1])
446
class TestRunBzrError(ExternalBase):
448
def test_run_bzr_error(self):
449
out, err = self.run_bzr_error(['^$'], 'rocks', retcode=0)
450
self.assertEqual(out, 'it sure does!\n')
452
out, err = self.run_bzr_error(["bzr: ERROR: foobarbaz is not versioned"],
453
'file-id', 'foobarbaz')