~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/blackbox/test_selftest.py

  • Committer: Aaron Bentley
  • Date: 2007-02-06 14:52:16 UTC
  • mfrom: (2266 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2268.
  • Revision ID: abentley@panoramicfeedback.com-20070206145216-fcpi8o3ufvuzwbp9
Merge bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2007 Canonical Ltd
 
1
# Copyright (C) 2005 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
17
17
"""UI tests for the test framework."""
18
18
 
19
19
import os
20
 
import re
21
20
import signal
22
21
import sys
23
22
 
31
30
                          TestCaseInTempDir,
32
31
                          TestCaseWithMemoryTransport,
33
32
                          TestCaseWithTransport,
34
 
                          TestUIFactory,
35
33
                          TestSkipped,
36
34
                          )
37
35
from bzrlib.tests.blackbox import ExternalBase
73
71
        TestCaseWithMemoryTransport.TEST_ROOT = None
74
72
        try:
75
73
            TestOptions.current_test = "test_transport_set_to_sftp"
76
 
            stdout = self.run_bzr(
77
 
                'selftest --transport=sftp test_transport_set_to_sftp')[0]
 
74
            stdout = self.capture('selftest --transport=sftp test_transport_set_to_sftp')
 
75
            
78
76
            self.assertContainsRe(stdout, 'Ran 1 test')
79
77
            self.assertEqual(old_transport, bzrlib.tests.default_transport)
80
78
 
81
79
            TestOptions.current_test = "test_transport_set_to_memory"
82
 
            stdout = self.run_bzr(
83
 
                'selftest --transport=memory test_transport_set_to_memory')[0]
 
80
            stdout = self.capture('selftest --transport=memory test_transport_set_to_memory')
84
81
            self.assertContainsRe(stdout, 'Ran 1 test')
85
82
            self.assertEqual(old_transport, bzrlib.tests.default_transport)
86
83
        finally:
91
88
 
92
89
class TestRunBzr(ExternalBase):
93
90
 
94
 
    def _run_bzr_core(self, argv, retcode=0, encoding=None, stdin=None,
 
91
    def run_bzr_captured(self, argv, retcode=0, encoding=None, stdin=None,
95
92
                         working_dir=None):
96
 
        """Override _run_bzr_core to test how it is invoked by run_bzr.
97
 
 
98
 
        Attempts to run bzr from inside this class don't actually run it.
99
 
 
100
 
        We test how run_bzr actually invokes bzr in another location.
 
93
        """Override run_bzr_captured to test how it is invoked by run_bzr.
 
94
 
 
95
        We test how run_bzr_captured actually invokes bzr in another location.
101
96
        Here we only need to test that it is run_bzr passes the right
102
 
        parameters to run_bzr.
 
97
        parameters to run_bzr_captured.
103
98
        """
104
 
        self.argv = list(argv)
 
99
        self.argv = argv
105
100
        self.retcode = retcode
106
101
        self.encoding = encoding
107
102
        self.stdin = stdin
108
103
        self.working_dir = working_dir
109
 
        return '', ''
 
104
 
 
105
    def test_args(self):
 
106
        """Test that run_bzr passes args correctly to run_bzr_captured"""
 
107
        self.run_bzr('arg1', 'arg2', 'arg3', retcode=1)
 
108
        self.assertEqual(('arg1', 'arg2', 'arg3'), self.argv)
110
109
 
111
110
    def test_encoding(self):
112
 
        """Test that run_bzr passes encoding to _run_bzr_core"""
113
 
        self.run_bzr('foo bar')
 
111
        """Test that run_bzr passes encoding to run_bzr_captured"""
 
112
        self.run_bzr('foo', 'bar')
114
113
        self.assertEqual(None, self.encoding)
115
 
        self.assertEqual(['foo', 'bar'], self.argv)
 
114
        self.assertEqual(('foo', 'bar'), self.argv)
116
115
 
117
 
        self.run_bzr('foo bar', encoding='baz')
 
116
        self.run_bzr('foo', 'bar', encoding='baz')
118
117
        self.assertEqual('baz', self.encoding)
119
 
        self.assertEqual(['foo', 'bar'], self.argv)
 
118
        self.assertEqual(('foo', 'bar'), self.argv)
120
119
 
121
120
    def test_retcode(self):
122
 
        """Test that run_bzr passes retcode to _run_bzr_core"""
 
121
        """Test that run_bzr passes retcode to run_bzr_captured"""
123
122
        # Default is retcode == 0
124
 
        self.run_bzr('foo bar')
 
123
        self.run_bzr('foo', 'bar')
125
124
        self.assertEqual(0, self.retcode)
126
 
        self.assertEqual(['foo', 'bar'], self.argv)
 
125
        self.assertEqual(('foo', 'bar'), self.argv)
127
126
 
128
 
        self.run_bzr('foo bar', retcode=1)
 
127
        self.run_bzr('foo', 'bar', retcode=1)
129
128
        self.assertEqual(1, self.retcode)
130
 
        self.assertEqual(['foo', 'bar'], self.argv)
 
129
        self.assertEqual(('foo', 'bar'), self.argv)
131
130
 
132
 
        self.run_bzr('foo bar', retcode=None)
 
131
        self.run_bzr('foo', 'bar', retcode=None)
133
132
        self.assertEqual(None, self.retcode)
134
 
        self.assertEqual(['foo', 'bar'], self.argv)
 
133
        self.assertEqual(('foo', 'bar'), self.argv)
135
134
 
136
 
        self.run_bzr(['foo', 'bar'], retcode=3)
 
135
        self.run_bzr('foo', 'bar', retcode=3)
137
136
        self.assertEqual(3, self.retcode)
138
 
        self.assertEqual(['foo', 'bar'], self.argv)
 
137
        self.assertEqual(('foo', 'bar'), self.argv)
139
138
 
140
139
    def test_stdin(self):
141
140
        # 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 
 
141
        # run_bzr_captured as-is. We do this by overriding
 
142
        # run_bzr_captured in this class, and then calling run_bzr,
 
143
        # which is a convenience function for run_bzr_captured, so 
145
144
        # should invoke it.
146
 
        self.run_bzr('foo bar', stdin='gam')
 
145
        self.run_bzr('foo', 'bar', stdin='gam')
147
146
        self.assertEqual('gam', self.stdin)
148
 
        self.assertEqual(['foo', 'bar'], self.argv)
 
147
        self.assertEqual(('foo', 'bar'), self.argv)
149
148
 
150
 
        self.run_bzr('foo bar', stdin='zippy')
 
149
        self.run_bzr('foo', 'bar', stdin='zippy')
151
150
        self.assertEqual('zippy', self.stdin)
152
 
        self.assertEqual(['foo', 'bar'], self.argv)
 
151
        self.assertEqual(('foo', 'bar'), self.argv)
153
152
 
154
153
    def test_working_dir(self):
155
 
        """Test that run_bzr passes working_dir to _run_bzr_core"""
156
 
        self.run_bzr('foo bar')
 
154
        """Test that run_bzr passes working_dir to run_bzr_captured"""
 
155
        self.run_bzr('foo', 'bar')
157
156
        self.assertEqual(None, self.working_dir)
158
 
        self.assertEqual(['foo', 'bar'], self.argv)
 
157
        self.assertEqual(('foo', 'bar'), self.argv)
159
158
 
160
 
        self.run_bzr('foo bar', working_dir='baz')
 
159
        self.run_bzr('foo', 'bar', working_dir='baz')
161
160
        self.assertEqual('baz', self.working_dir)
162
 
        self.assertEqual(['foo', 'bar'], self.argv)
163
 
 
164
 
    def test_reject_extra_keyword_arguments(self):
165
 
        self.assertRaises(TypeError, self.run_bzr, "foo bar",
166
 
                          error_regex=['error message'])
 
161
        self.assertEqual(('foo', 'bar'), self.argv)
167
162
 
168
163
 
169
164
class TestBenchmarkTests(TestCaseWithTransport):
171
166
    def test_benchmark_runs_benchmark_tests(self):
172
167
        """bzr selftest --benchmark should not run the default test suite."""
173
168
        # We test this by passing a regression test name to --benchmark, which
174
 
        # should result in 0 tests run.
 
169
        # should result in 0 rests run.
175
170
        old_root = TestCaseWithMemoryTransport.TEST_ROOT
176
171
        try:
177
172
            TestCaseWithMemoryTransport.TEST_ROOT = None
178
 
            out, err = self.run_bzr('selftest --benchmark'
179
 
                                    ' workingtree_implementations')
 
173
            out, err = self.run_bzr('selftest', '--benchmark', 'workingtree_implementations')
180
174
        finally:
181
175
            TestCaseWithMemoryTransport.TEST_ROOT = old_root
182
176
        self.assertContainsRe(out, 'Ran 0 tests.*\n\nOK')
205
199
        return 0
206
200
 
207
201
    def test_stdin(self):
208
 
        # test that the stdin keyword to _run_bzr_core is passed through to
 
202
        # test that the stdin keyword to run_bzr_captured is passed through to
209
203
        # apply_redirected as a StringIO. We do this by overriding
210
 
        # apply_redirected in this class, and then calling _run_bzr_core,
 
204
        # apply_redirected in this class, and then calling run_bzr_captured,
211
205
        # which calls apply_redirected. 
212
 
        self.run_bzr(['foo', 'bar'], stdin='gam')
 
206
        self.run_bzr_captured(['foo', 'bar'], stdin='gam')
213
207
        self.assertEqual('gam', self.stdin.read())
214
208
        self.assertTrue(self.stdin is self.factory_stdin)
215
 
        self.run_bzr(['foo', 'bar'], stdin='zippy')
 
209
        self.run_bzr_captured(['foo', 'bar'], stdin='zippy')
216
210
        self.assertEqual('zippy', self.stdin.read())
217
211
        self.assertTrue(self.stdin is self.factory_stdin)
218
212
 
219
213
    def test_ui_factory(self):
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
 
214
        # each invocation of self.run_bzr_captured should get its own UI
 
215
        # factory, which is an instance of TestUIFactory, with stdout and
 
216
        # stderr attached to the stdout and stderr of the invoked
 
217
        # run_bzr_captured
224
218
        current_factory = bzrlib.ui.ui_factory
225
 
        self.run_bzr(['foo'])
 
219
        self.run_bzr_captured(['foo'])
226
220
        self.failIf(current_factory is self.factory)
227
221
        self.assertNotEqual(sys.stdout, self.factory.stdout)
228
222
        self.assertNotEqual(sys.stderr, self.factory.stderr)
229
223
        self.assertEqual('foo\n', self.factory.stdout.getvalue())
230
224
        self.assertEqual('bar\n', self.factory.stderr.getvalue())
231
 
        self.assertIsInstance(self.factory, TestUIFactory)
 
225
        self.assertIsInstance(self.factory, bzrlib.tests.blackbox.TestUIFactory)
232
226
 
233
227
    def test_working_dir(self):
234
228
        self.build_tree(['one/', 'two/'])
235
229
        cwd = osutils.getcwd()
236
230
 
237
231
        # Default is to work in the current directory
238
 
        self.run_bzr(['foo', 'bar'])
 
232
        self.run_bzr_captured(['foo', 'bar'])
239
233
        self.assertEqual(cwd, self.working_dir)
240
234
 
241
 
        self.run_bzr(['foo', 'bar'], working_dir=None)
 
235
        self.run_bzr_captured(['foo', 'bar'], working_dir=None)
242
236
        self.assertEqual(cwd, self.working_dir)
243
237
 
244
238
        # The function should be run in the alternative directory
245
239
        # but afterwards the current working dir shouldn't be changed
246
 
        self.run_bzr(['foo', 'bar'], working_dir='one')
 
240
        self.run_bzr_captured(['foo', 'bar'], working_dir='one')
247
241
        self.assertNotEqual(cwd, self.working_dir)
248
242
        self.assertEndsWith(self.working_dir, 'one')
249
243
        self.assertEqual(cwd, osutils.getcwd())
250
244
 
251
 
        self.run_bzr(['foo', 'bar'], working_dir='two')
 
245
        self.run_bzr_captured(['foo', 'bar'], working_dir='two')
252
246
        self.assertNotEqual(cwd, self.working_dir)
253
247
        self.assertEndsWith(self.working_dir, 'two')
254
248
        self.assertEqual(cwd, osutils.getcwd())
257
251
class TestRunBzrSubprocess(TestCaseWithTransport):
258
252
 
259
253
    def test_run_bzr_subprocess(self):
260
 
        """The run_bzr_helper_external command behaves nicely."""
 
254
        """The run_bzr_helper_external comand behaves nicely."""
261
255
        result = self.run_bzr_subprocess('--version')
262
 
        result = self.run_bzr_subprocess(['--version'])
263
256
        result = self.run_bzr_subprocess('--version', retcode=None)
264
257
        self.assertContainsRe(result[0], 'is free software')
265
258
        self.assertRaises(AssertionError, self.run_bzr_subprocess, 
267
260
        result = self.run_bzr_subprocess('--versionn', retcode=3)
268
261
        result = self.run_bzr_subprocess('--versionn', retcode=None)
269
262
        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'
273
 
                              ' "merge-type"')
 
263
        err = self.run_bzr_subprocess('merge', '--merge-type', 'magic merge', 
 
264
                                      retcode=3)[1]
 
265
        self.assertContainsRe(err, 'No known merge type magic merge')
274
266
 
275
267
    def test_run_bzr_subprocess_env(self):
276
268
        """run_bzr_subprocess can set environment variables in the child only.
336
328
        out, err = self.run_bzr_subprocess('rocks',
337
329
                        env_changes={'NON_EXISTANT_ENV_VAR':None},
338
330
                        universal_newlines=True)
339
 
        self.assertEqual('It sure does!\n', out)
 
331
        self.assertEqual('it sure does!\n', out)
340
332
        self.assertEqual('', err)
341
333
 
342
334
    def test_run_bzr_subprocess_working_dir(self):
382
374
        raise _DontSpawnProcess()
383
375
 
384
376
    def test_run_bzr_subprocess_no_plugins(self):
385
 
        self.assertRaises(_DontSpawnProcess, self.run_bzr_subprocess, '')
 
377
        self.assertRaises(_DontSpawnProcess, self.run_bzr_subprocess)
386
378
        command = self._popen_args[0]
387
379
        self.assertEqual(sys.executable, command[0])
388
380
        self.assertEqual(self.get_bzr_path(), command[1])
390
382
 
391
383
    def test_allow_plugins(self):
392
384
        self.assertRaises(_DontSpawnProcess,
393
 
                          self.run_bzr_subprocess, '', allow_plugins=True)
 
385
                          self.run_bzr_subprocess, allow_plugins=True)
394
386
        command = self._popen_args[0]
395
387
        self.assertEqual([], command[2:])
396
388
 
427
419
        """
428
420
        process = self.start_bzr_subprocess(['--versionn'])
429
421
        self.assertRaises(self.failureException, self.finish_bzr_subprocess,
430
 
                          process)
 
422
                          process, retcode=0)
431
423
        
432
424
    def test_start_and_stop_bzr_subprocess_send_signal(self):
433
425
        """finish_bzr_subprocess raises self.failureException if the retcode is
455
447
class TestRunBzrError(ExternalBase):
456
448
 
457
449
    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'])
467
 
 
468
 
 
469
 
class TestSelftestListOnly(TestCase):
470
 
 
471
 
    @staticmethod
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)."
474
 
        in_header = True
475
 
        in_footer = False
476
 
        header = []
477
 
        body = []
478
 
        footer = []
479
 
        header_newlines_found = 0
480
 
        for line in lines:
481
 
            if in_header:
482
 
                if line == '':
483
 
                    header_newlines_found += 1
484
 
                    if header_newlines_found >= newlines_in_header:
485
 
                        in_header = False
486
 
                        continue
487
 
                header.append(line)
488
 
            elif not in_footer:
489
 
                if line.startswith('-------'):
490
 
                    in_footer = True
491
 
                else:
492
 
                    body.append(line)
493
 
            else:
494
 
                footer.append(line)
495
 
        # If the last body line is blank, drop it off the list
496
 
        if len(body) > 0 and body[-1] == '':
497
 
            body.pop()
498
 
        return (header,body,footer)
499
 
 
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)
507
 
 
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))
524
 
 
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.
532
 
        # -- mbp 20070504
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
541
 
        # tests.
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)
553
 
 
554
 
 
555
 
class TestSelftestWithIdList(TestCaseInTempDir):
556
 
 
557
 
    def test_load_list(self):
558
 
        # We don't want to call selftest for the whole suite, so we start with
559
 
        # a reduced list.
560
 
        test_list_fname = 'test.list'
561
 
        fl = open(test_list_fname, 'wt')
562
 
        fl.write('%s\n' % self.id())
563
 
        fl.close()
564
 
        out, err = self.run_bzr(
565
 
            ['selftest', '--load-list', test_list_fname, '--list'])
566
 
        self.assertContainsRe(out, "Listed 1 test in")
567
 
 
568
 
    def test_load_unknown(self):
569
 
        out, err = self.run_bzr('selftest --load-list I_do_not_exist ',
570
 
                                retcode=3)
571
 
 
572
 
 
573
 
class TestSelftestStartingWith(TestCase):
574
 
 
575
 
    def test_starting_with(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())
580
 
 
 
450
        out, err = self.run_bzr_error(['^$'], 'rocks', retcode=0)
 
451
        self.assertEqual(out, 'it sure does!\n')
 
452
 
 
453
        out, err = self.run_bzr_error(["bzr: ERROR: foobarbaz is not versioned"],
 
454
                                      'file-id', 'foobarbaz')
 
455
 
 
456
 
 
457
class TestSelftestCleanOutput(TestCaseInTempDir):
 
458
 
 
459
    def test_clean_output(self):
 
460
        # check that 'bzr selftest --clean-output' works correct
 
461
        dirs = ('test0000.tmp', 'test0001.tmp', 'bzrlib', 'tests')
 
462
        files = ('bzr', 'setup.py', 'test9999.tmp')
 
463
        for i in dirs:
 
464
            os.mkdir(i)
 
465
        for i in files:
 
466
            f = file(i, 'wb')
 
467
            f.write('content of ')
 
468
            f.write(i)
 
469
            f.close()
 
470
 
 
471
        root = os.getcwdu()
 
472
        before = os.listdir(root)
 
473
        before.sort()
 
474
        self.assertEquals(['bzr','bzrlib','setup.py',
 
475
                           'test0000.tmp','test0001.tmp',
 
476
                           'test9999.tmp','tests'],
 
477
                           before)
 
478
 
 
479
        out,err = self.run_bzr_captured(['selftest','--clean-output'],
 
480
                                        working_dir=root)
 
481
 
 
482
        self.assertEquals(['delete directory: test0000.tmp',
 
483
                          'delete directory: test0001.tmp'],
 
484
                          sorted(out.splitlines()))
 
485
        self.assertEquals('', err)
 
486
 
 
487
        after = os.listdir(root)
 
488
        after.sort()
 
489
        self.assertEquals(['bzr','bzrlib','setup.py',
 
490
                           'test9999.tmp','tests'],
 
491
                           after)