~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: Martin Pool
  • Date: 2007-04-04 06:17:31 UTC
  • mto: This revision was merged to the branch mainline in revision 2397.
  • Revision ID: mbp@sourcefrog.net-20070404061731-tt2xrzllqhbodn83
Contents of TODO file moved into bug tracker

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
 
73
72
        TestCaseWithMemoryTransport.TEST_ROOT = None
74
73
        try:
75
74
            TestOptions.current_test = "test_transport_set_to_sftp"
76
 
            stdout = self.run_bzr(
77
 
                'selftest --transport=sftp test_transport_set_to_sftp')[0]
 
75
            stdout = self.capture('selftest --transport=sftp test_transport_set_to_sftp')
 
76
            
78
77
            self.assertContainsRe(stdout, 'Ran 1 test')
79
78
            self.assertEqual(old_transport, bzrlib.tests.default_transport)
80
79
 
81
80
            TestOptions.current_test = "test_transport_set_to_memory"
82
 
            stdout = self.run_bzr(
83
 
                'selftest --transport=memory test_transport_set_to_memory')[0]
 
81
            stdout = self.capture('selftest --transport=memory test_transport_set_to_memory')
84
82
            self.assertContainsRe(stdout, 'Ran 1 test')
85
83
            self.assertEqual(old_transport, bzrlib.tests.default_transport)
86
84
        finally:
91
89
 
92
90
class TestRunBzr(ExternalBase):
93
91
 
94
 
    def _run_bzr_core(self, argv, retcode=0, encoding=None, stdin=None,
 
92
    def run_bzr_captured(self, argv, retcode=0, encoding=None, stdin=None,
95
93
                         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.
 
94
        """Override run_bzr_captured to test how it is invoked by run_bzr.
 
95
 
 
96
        We test how run_bzr_captured actually invokes bzr in another location.
101
97
        Here we only need to test that it is run_bzr passes the right
102
 
        parameters to run_bzr.
 
98
        parameters to run_bzr_captured.
103
99
        """
104
 
        self.argv = list(argv)
 
100
        self.argv = argv
105
101
        self.retcode = retcode
106
102
        self.encoding = encoding
107
103
        self.stdin = stdin
108
104
        self.working_dir = working_dir
109
 
        return '', ''
 
105
 
 
106
    def test_args(self):
 
107
        """Test that run_bzr passes args correctly to run_bzr_captured"""
 
108
        self.run_bzr('arg1', 'arg2', 'arg3', retcode=1)
 
109
        self.assertEqual(('arg1', 'arg2', 'arg3'), self.argv)
110
110
 
111
111
    def test_encoding(self):
112
 
        """Test that run_bzr passes encoding to _run_bzr_core"""
113
 
        self.run_bzr('foo bar')
 
112
        """Test that run_bzr passes encoding to run_bzr_captured"""
 
113
        self.run_bzr('foo', 'bar')
114
114
        self.assertEqual(None, self.encoding)
115
 
        self.assertEqual(['foo', 'bar'], self.argv)
 
115
        self.assertEqual(('foo', 'bar'), self.argv)
116
116
 
117
 
        self.run_bzr('foo bar', encoding='baz')
 
117
        self.run_bzr('foo', 'bar', encoding='baz')
118
118
        self.assertEqual('baz', self.encoding)
119
 
        self.assertEqual(['foo', 'bar'], self.argv)
 
119
        self.assertEqual(('foo', 'bar'), self.argv)
120
120
 
121
121
    def test_retcode(self):
122
 
        """Test that run_bzr passes retcode to _run_bzr_core"""
 
122
        """Test that run_bzr passes retcode to run_bzr_captured"""
123
123
        # Default is retcode == 0
124
 
        self.run_bzr('foo bar')
 
124
        self.run_bzr('foo', 'bar')
125
125
        self.assertEqual(0, self.retcode)
126
 
        self.assertEqual(['foo', 'bar'], self.argv)
 
126
        self.assertEqual(('foo', 'bar'), self.argv)
127
127
 
128
 
        self.run_bzr('foo bar', retcode=1)
 
128
        self.run_bzr('foo', 'bar', retcode=1)
129
129
        self.assertEqual(1, self.retcode)
130
 
        self.assertEqual(['foo', 'bar'], self.argv)
 
130
        self.assertEqual(('foo', 'bar'), self.argv)
131
131
 
132
 
        self.run_bzr('foo bar', retcode=None)
 
132
        self.run_bzr('foo', 'bar', retcode=None)
133
133
        self.assertEqual(None, self.retcode)
134
 
        self.assertEqual(['foo', 'bar'], self.argv)
 
134
        self.assertEqual(('foo', 'bar'), self.argv)
135
135
 
136
 
        self.run_bzr(['foo', 'bar'], retcode=3)
 
136
        self.run_bzr('foo', 'bar', retcode=3)
137
137
        self.assertEqual(3, self.retcode)
138
 
        self.assertEqual(['foo', 'bar'], self.argv)
 
138
        self.assertEqual(('foo', 'bar'), self.argv)
139
139
 
140
140
    def test_stdin(self):
141
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 
 
142
        # run_bzr_captured as-is. We do this by overriding
 
143
        # run_bzr_captured in this class, and then calling run_bzr,
 
144
        # which is a convenience function for run_bzr_captured, so 
145
145
        # should invoke it.
146
 
        self.run_bzr('foo bar', stdin='gam')
 
146
        self.run_bzr('foo', 'bar', stdin='gam')
147
147
        self.assertEqual('gam', self.stdin)
148
 
        self.assertEqual(['foo', 'bar'], self.argv)
 
148
        self.assertEqual(('foo', 'bar'), self.argv)
149
149
 
150
 
        self.run_bzr('foo bar', stdin='zippy')
 
150
        self.run_bzr('foo', 'bar', stdin='zippy')
151
151
        self.assertEqual('zippy', self.stdin)
152
 
        self.assertEqual(['foo', 'bar'], self.argv)
 
152
        self.assertEqual(('foo', 'bar'), self.argv)
153
153
 
154
154
    def test_working_dir(self):
155
 
        """Test that run_bzr passes working_dir to _run_bzr_core"""
156
 
        self.run_bzr('foo bar')
 
155
        """Test that run_bzr passes working_dir to run_bzr_captured"""
 
156
        self.run_bzr('foo', 'bar')
157
157
        self.assertEqual(None, self.working_dir)
158
 
        self.assertEqual(['foo', 'bar'], self.argv)
 
158
        self.assertEqual(('foo', 'bar'), self.argv)
159
159
 
160
 
        self.run_bzr('foo bar', working_dir='baz')
 
160
        self.run_bzr('foo', 'bar', working_dir='baz')
161
161
        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'])
 
162
        self.assertEqual(('foo', 'bar'), self.argv)
167
163
 
168
164
 
169
165
class TestBenchmarkTests(TestCaseWithTransport):
171
167
    def test_benchmark_runs_benchmark_tests(self):
172
168
        """bzr selftest --benchmark should not run the default test suite."""
173
169
        # We test this by passing a regression test name to --benchmark, which
174
 
        # should result in 0 tests run.
 
170
        # should result in 0 rests run.
175
171
        old_root = TestCaseWithMemoryTransport.TEST_ROOT
176
172
        try:
177
173
            TestCaseWithMemoryTransport.TEST_ROOT = None
178
 
            out, err = self.run_bzr('selftest --benchmark'
179
 
                                    ' workingtree_implementations')
 
174
            out, err = self.run_bzr('selftest', '--benchmark', 'workingtree_implementations')
180
175
        finally:
181
176
            TestCaseWithMemoryTransport.TEST_ROOT = old_root
182
177
        self.assertContainsRe(out, 'Ran 0 tests.*\n\nOK')
205
200
        return 0
206
201
 
207
202
    def test_stdin(self):
208
 
        # test that the stdin keyword to _run_bzr_core is passed through to
 
203
        # test that the stdin keyword to run_bzr_captured is passed through to
209
204
        # apply_redirected as a StringIO. We do this by overriding
210
 
        # apply_redirected in this class, and then calling _run_bzr_core,
 
205
        # apply_redirected in this class, and then calling run_bzr_captured,
211
206
        # which calls apply_redirected. 
212
 
        self.run_bzr(['foo', 'bar'], stdin='gam')
 
207
        self.run_bzr_captured(['foo', 'bar'], stdin='gam')
213
208
        self.assertEqual('gam', self.stdin.read())
214
209
        self.assertTrue(self.stdin is self.factory_stdin)
215
 
        self.run_bzr(['foo', 'bar'], stdin='zippy')
 
210
        self.run_bzr_captured(['foo', 'bar'], stdin='zippy')
216
211
        self.assertEqual('zippy', self.stdin.read())
217
212
        self.assertTrue(self.stdin is self.factory_stdin)
218
213
 
219
214
    def test_ui_factory(self):
220
 
        # each invocation of self.run_bzr should get its
 
215
        # each invocation of self.run_bzr_captured should get its
221
216
        # own UI factory, which is an instance of TestUIFactory,
222
217
        # with stdin, stdout and stderr attached to the stdin,
223
 
        # stdout and stderr of the invoked run_bzr
 
218
        # stdout and stderr of the invoked run_bzr_captured
224
219
        current_factory = bzrlib.ui.ui_factory
225
 
        self.run_bzr(['foo'])
 
220
        self.run_bzr_captured(['foo'])
226
221
        self.failIf(current_factory is self.factory)
227
222
        self.assertNotEqual(sys.stdout, self.factory.stdout)
228
223
        self.assertNotEqual(sys.stderr, self.factory.stderr)
235
230
        cwd = osutils.getcwd()
236
231
 
237
232
        # Default is to work in the current directory
238
 
        self.run_bzr(['foo', 'bar'])
 
233
        self.run_bzr_captured(['foo', 'bar'])
239
234
        self.assertEqual(cwd, self.working_dir)
240
235
 
241
 
        self.run_bzr(['foo', 'bar'], working_dir=None)
 
236
        self.run_bzr_captured(['foo', 'bar'], working_dir=None)
242
237
        self.assertEqual(cwd, self.working_dir)
243
238
 
244
239
        # The function should be run in the alternative directory
245
240
        # but afterwards the current working dir shouldn't be changed
246
 
        self.run_bzr(['foo', 'bar'], working_dir='one')
 
241
        self.run_bzr_captured(['foo', 'bar'], working_dir='one')
247
242
        self.assertNotEqual(cwd, self.working_dir)
248
243
        self.assertEndsWith(self.working_dir, 'one')
249
244
        self.assertEqual(cwd, osutils.getcwd())
250
245
 
251
 
        self.run_bzr(['foo', 'bar'], working_dir='two')
 
246
        self.run_bzr_captured(['foo', 'bar'], working_dir='two')
252
247
        self.assertNotEqual(cwd, self.working_dir)
253
248
        self.assertEndsWith(self.working_dir, 'two')
254
249
        self.assertEqual(cwd, osutils.getcwd())
257
252
class TestRunBzrSubprocess(TestCaseWithTransport):
258
253
 
259
254
    def test_run_bzr_subprocess(self):
260
 
        """The run_bzr_helper_external command behaves nicely."""
 
255
        """The run_bzr_helper_external comand behaves nicely."""
261
256
        result = self.run_bzr_subprocess('--version')
262
 
        result = self.run_bzr_subprocess(['--version'])
263
257
        result = self.run_bzr_subprocess('--version', retcode=None)
264
258
        self.assertContainsRe(result[0], 'is free software')
265
259
        self.assertRaises(AssertionError, self.run_bzr_subprocess, 
267
261
        result = self.run_bzr_subprocess('--versionn', retcode=3)
268
262
        result = self.run_bzr_subprocess('--versionn', retcode=None)
269
263
        self.assertContainsRe(result[1], 'unknown command')
270
 
        err = self.run_bzr_subprocess(['merge', '--merge-type',
271
 
                                      'magic merge'], retcode=3)[1]
 
264
        err = self.run_bzr_subprocess('merge', '--merge-type', 'magic merge', 
 
265
                                      retcode=3)[1]
272
266
        self.assertContainsRe(err, 'Bad value "magic merge" for option'
273
267
                              ' "merge-type"')
274
268
 
382
376
        raise _DontSpawnProcess()
383
377
 
384
378
    def test_run_bzr_subprocess_no_plugins(self):
385
 
        self.assertRaises(_DontSpawnProcess, self.run_bzr_subprocess, '')
 
379
        self.assertRaises(_DontSpawnProcess, self.run_bzr_subprocess)
386
380
        command = self._popen_args[0]
387
381
        self.assertEqual(sys.executable, command[0])
388
382
        self.assertEqual(self.get_bzr_path(), command[1])
390
384
 
391
385
    def test_allow_plugins(self):
392
386
        self.assertRaises(_DontSpawnProcess,
393
 
                          self.run_bzr_subprocess, '', allow_plugins=True)
 
387
                          self.run_bzr_subprocess, allow_plugins=True)
394
388
        command = self._popen_args[0]
395
389
        self.assertEqual([], command[2:])
396
390
 
427
421
        """
428
422
        process = self.start_bzr_subprocess(['--versionn'])
429
423
        self.assertRaises(self.failureException, self.finish_bzr_subprocess,
430
 
                          process)
 
424
                          process, retcode=0)
431
425
        
432
426
    def test_start_and_stop_bzr_subprocess_send_signal(self):
433
427
        """finish_bzr_subprocess raises self.failureException if the retcode is
455
449
class TestRunBzrError(ExternalBase):
456
450
 
457
451
    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)
 
452
        out, err = self.run_bzr_error(['^$'], 'rocks', retcode=0)
462
453
        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_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())
580
 
 
581
 
    def test_starting_with_multiple_argument(self):
582
 
        out, err = self.run_bzr(
583
 
            ['selftest',
584
 
             '--starting-with', self.id(),
585
 
             '--starting-with', 'bzrlib.tests.test_sampler',
586
 
             '--list'])
587
 
        self.assertContainsRe(out, "Listed 2 tests in")
588
 
        self.assertContainsRe(out, self.id())
589
 
        self.assertContainsRe(out, 'bzrlib.tests.test_sampler')
 
454
 
 
455
        out, err = self.run_bzr_error(["bzr: ERROR: foobarbaz is not versioned"],
 
456
                                      'file-id', 'foobarbaz')
 
457
 
 
458
 
 
459
class TestSelftestCleanOutput(TestCaseInTempDir):
 
460
 
 
461
    def test_clean_output(self):
 
462
        # check that 'bzr selftest --clean-output' works correct
 
463
        dirs = ('test0000.tmp', 'test0001.tmp', 'bzrlib', 'tests')
 
464
        files = ('bzr', 'setup.py', 'test9999.tmp')
 
465
        for i in dirs:
 
466
            os.mkdir(i)
 
467
        for i in files:
 
468
            f = file(i, 'wb')
 
469
            f.write('content of ')
 
470
            f.write(i)
 
471
            f.close()
 
472
 
 
473
        root = os.getcwdu()
 
474
        before = os.listdir(root)
 
475
        before.sort()
 
476
        self.assertEquals(['bzr','bzrlib','setup.py',
 
477
                           'test0000.tmp','test0001.tmp',
 
478
                           'test9999.tmp','tests'],
 
479
                           before)
 
480
 
 
481
        out,err = self.run_bzr_captured(['selftest','--clean-output'],
 
482
                                        working_dir=root)
 
483
 
 
484
        self.assertEquals(['delete directory: test0000.tmp',
 
485
                          'delete directory: test0001.tmp'],
 
486
                          sorted(out.splitlines()))
 
487
        self.assertEquals('', err)
 
488
 
 
489
        after = os.listdir(root)
 
490
        after.sort()
 
491
        self.assertEquals(['bzr','bzrlib','setup.py',
 
492
                           'test9999.tmp','tests'],
 
493
                           after)