~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/__init__.py

  • Committer: Robert Collins
  • Date: 2007-08-22 01:41:24 UTC
  • mfrom: (2740 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2741.
  • Revision ID: robertc@robertcollins.net-20070822014124-wiinlne4nin2f2tm
Merge bzr.dev to resolve conflicts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
80
80
from bzrlib.symbol_versioning import (
81
81
    deprecated_method,
82
82
    zero_eighteen,
 
83
    zero_ninetyone,
83
84
    )
84
85
import bzrlib.trace
85
86
from bzrlib.transport import get_transport
157
158
class ExtendedTestResult(unittest._TextTestResult):
158
159
    """Accepts, reports and accumulates the results of running tests.
159
160
 
160
 
    Compared to this unittest version this class adds support for profiling,
161
 
    benchmarking, stopping as soon as a test fails,  and skipping tests.
162
 
    There are further-specialized subclasses for different types of display.
 
161
    Compared to this unittest version this class adds support for
 
162
    profiling, benchmarking, stopping as soon as a test fails,  and
 
163
    skipping tests.  There are further-specialized subclasses for
 
164
    different types of display.
 
165
 
 
166
    When a test finishes, in whatever way, it calls one of the addSuccess,
 
167
    addFailure or addError classes.  These in turn may redirect to a more
 
168
    specific case for the special test results supported by our extended
 
169
    tests.
 
170
 
 
171
    Note that just one of these objects is fed the results from many tests.
163
172
    """
164
173
 
165
174
    stop_early = False
199
208
        self.count = 0
200
209
        self._overall_start_time = time.time()
201
210
    
202
 
    def extractBenchmarkTime(self, testCase):
 
211
    def _extractBenchmarkTime(self, testCase):
203
212
        """Add a benchmark time for the current test case."""
204
 
        self._benchmarkTime = getattr(testCase, "_benchtime", None)
 
213
        return getattr(testCase, "_benchtime", None)
205
214
    
206
215
    def _elapsedTestTimeString(self):
207
216
        """Return a time string for the overall time the current test has taken."""
208
217
        return self._formatTime(time.time() - self._start_time)
209
218
 
210
 
    def _testTimeString(self):
211
 
        if self._benchmarkTime is not None:
 
219
    def _testTimeString(self, testCase):
 
220
        benchmark_time = self._extractBenchmarkTime(testCase)
 
221
        if benchmark_time is not None:
212
222
            return "%s/%s" % (
213
 
                self._formatTime(self._benchmarkTime),
 
223
                self._formatTime(benchmark_time),
214
224
                self._elapsedTestTimeString())
215
225
        else:
216
226
            return "           %s" % self._elapsedTestTimeString()
244
254
            setKeepLogfile()
245
255
 
246
256
    def addError(self, test, err):
247
 
        self.extractBenchmarkTime(test)
248
 
        self._cleanupLogFile(test)
 
257
        """Tell result that test finished with an error.
 
258
 
 
259
        Called from the TestCase run() method when the test
 
260
        fails with an unexpected error.
 
261
        """
 
262
        self._testConcluded(test)
249
263
        if isinstance(err[1], TestSkipped):
250
 
            return self.addSkipped(test, err)
 
264
            return self._addSkipped(test, err)
251
265
        elif isinstance(err[1], UnavailableFeature):
252
266
            return self.addNotSupported(test, err[1].args[0])
253
 
        unittest.TestResult.addError(self, test, err)
254
 
        self.error_count += 1
255
 
        self.report_error(test, err)
256
 
        if self.stop_early:
257
 
            self.stop()
 
267
        else:
 
268
            unittest.TestResult.addError(self, test, err)
 
269
            self.error_count += 1
 
270
            self.report_error(test, err)
 
271
            if self.stop_early:
 
272
                self.stop()
258
273
 
259
274
    def addFailure(self, test, err):
260
 
        self._cleanupLogFile(test)
261
 
        self.extractBenchmarkTime(test)
 
275
        """Tell result that test failed.
 
276
 
 
277
        Called from the TestCase run() method when the test
 
278
        fails because e.g. an assert() method failed.
 
279
        """
 
280
        self._testConcluded(test)
262
281
        if isinstance(err[1], KnownFailure):
263
 
            return self.addKnownFailure(test, err)
264
 
        unittest.TestResult.addFailure(self, test, err)
265
 
        self.failure_count += 1
266
 
        self.report_failure(test, err)
267
 
        if self.stop_early:
268
 
            self.stop()
269
 
 
270
 
    def addKnownFailure(self, test, err):
 
282
            return self._addKnownFailure(test, err)
 
283
        else:
 
284
            unittest.TestResult.addFailure(self, test, err)
 
285
            self.failure_count += 1
 
286
            self.report_failure(test, err)
 
287
            if self.stop_early:
 
288
                self.stop()
 
289
 
 
290
    def addSuccess(self, test):
 
291
        """Tell result that test completed successfully.
 
292
 
 
293
        Called from the TestCase run()
 
294
        """
 
295
        self._testConcluded(test)
 
296
        if self._bench_history is not None:
 
297
            benchmark_time = self._extractBenchmarkTime(test)
 
298
            if benchmark_time is not None:
 
299
                self._bench_history.write("%s %s\n" % (
 
300
                    self._formatTime(benchmark_time),
 
301
                    test.id()))
 
302
        self.report_success(test)
 
303
        unittest.TestResult.addSuccess(self, test)
 
304
 
 
305
    def _testConcluded(self, test):
 
306
        """Common code when a test has finished.
 
307
 
 
308
        Called regardless of whether it succeded, failed, etc.
 
309
        """
 
310
        self._cleanupLogFile(test)
 
311
 
 
312
    def _addKnownFailure(self, test, err):
271
313
        self.known_failure_count += 1
272
314
        self.report_known_failure(test, err)
273
315
 
274
316
    def addNotSupported(self, test, feature):
 
317
        """The test will not be run because of a missing feature.
 
318
        """
 
319
        # this can be called in two different ways: it may be that the
 
320
        # test started running, and then raised (through addError) 
 
321
        # UnavailableFeature.  Alternatively this method can be called
 
322
        # while probing for features before running the tests; in that
 
323
        # case we will see startTest and stopTest, but the test will never
 
324
        # actually run.
275
325
        self.unsupported.setdefault(str(feature), 0)
276
326
        self.unsupported[str(feature)] += 1
277
327
        self.report_unsupported(test, feature)
278
328
 
279
 
    def addSuccess(self, test):
280
 
        self.extractBenchmarkTime(test)
281
 
        if self._bench_history is not None:
282
 
            if self._benchmarkTime is not None:
283
 
                self._bench_history.write("%s %s\n" % (
284
 
                    self._formatTime(self._benchmarkTime),
285
 
                    test.id()))
286
 
        self.report_success(test)
287
 
        unittest.TestResult.addSuccess(self, test)
288
 
 
289
 
    def addSkipped(self, test, skip_excinfo):
 
329
    def _addSkipped(self, test, skip_excinfo):
290
330
        self.report_skip(test, skip_excinfo)
291
 
        # seems best to treat this as success from point-of-view of unittest
292
 
        # -- it actually does nothing so it barely matters :)
 
331
        # seems best to treat this as success from point-of-view of
 
332
        # unittest -- it actually does nothing so it barely matters :)
293
333
        try:
294
334
            test.tearDown()
295
335
        except KeyboardInterrupt:
457
497
 
458
498
    def report_error(self, test, err):
459
499
        self.stream.writeln('ERROR %s\n%s'
460
 
                % (self._testTimeString(),
 
500
                % (self._testTimeString(test),
461
501
                   self._error_summary(err)))
462
502
 
463
503
    def report_failure(self, test, err):
464
504
        self.stream.writeln(' FAIL %s\n%s'
465
 
                % (self._testTimeString(),
 
505
                % (self._testTimeString(test),
466
506
                   self._error_summary(err)))
467
507
 
468
508
    def report_known_failure(self, test, err):
469
509
        self.stream.writeln('XFAIL %s\n%s'
470
 
                % (self._testTimeString(),
 
510
                % (self._testTimeString(test),
471
511
                   self._error_summary(err)))
472
512
 
473
513
    def report_success(self, test):
474
 
        self.stream.writeln('   OK %s' % self._testTimeString())
 
514
        self.stream.writeln('   OK %s' % self._testTimeString(test))
475
515
        for bench_called, stats in getattr(test, '_benchcalls', []):
476
516
            self.stream.writeln('LSProf output for %s(%s, %s)' % bench_called)
477
517
            stats.pprint(file=self.stream)
482
522
    def report_skip(self, test, skip_excinfo):
483
523
        self.skip_count += 1
484
524
        self.stream.writeln(' SKIP %s\n%s'
485
 
                % (self._testTimeString(),
 
525
                % (self._testTimeString(test),
486
526
                   self._error_summary(skip_excinfo)))
487
527
 
488
528
    def report_unsupported(self, test, feature):
489
529
        """test cannot be run because feature is missing."""
490
530
        self.stream.writeln("NODEP %s\n    The feature '%s' is not available."
491
 
                %(self._testTimeString(), feature))
492
 
                  
 
531
                %(self._testTimeString(test), feature))
493
532
 
494
533
 
495
534
class TextTestRunner(object):
862
901
 
863
902
    def assertSubset(self, sublist, superlist):
864
903
        """Assert that every entry in sublist is present in superlist."""
865
 
        missing = []
866
 
        for entry in sublist:
867
 
            if entry not in superlist:
868
 
                missing.append(entry)
 
904
        missing = set(sublist) - set(superlist)
869
905
        if len(missing) > 0:
870
 
            raise AssertionError("value(s) %r not present in container %r" % 
 
906
            raise AssertionError("value(s) %r not present in container %r" %
871
907
                                 (missing, superlist))
872
908
 
873
909
    def assertListRaises(self, excClass, func, *args, **kwargs):
1006
1042
        Note that this only captures warnings raised by symbol_versioning.warn,
1007
1043
        not other callers that go direct to the warning module.
1008
1044
 
 
1045
        To test that a deprecated method raises an error, do something like
 
1046
        this::
 
1047
 
 
1048
        self.assertRaises(errors.ReservedId,
 
1049
            self.applyDeprecated, zero_ninetyone,
 
1050
                br.append_revision, 'current:')
 
1051
 
1009
1052
        :param deprecation_format: The deprecation format that the callable
1010
1053
            should have been deprecated with. This is the same type as the
1011
1054
            parameter to deprecated_method/deprecated_function. If the
1197
1240
        mutter(*args)
1198
1241
 
1199
1242
    def _get_log(self, keep_log_file=False):
1200
 
        """Return as a string the log for this test. If the file is still
1201
 
        on disk and keep_log_file=False, delete the log file and store the
1202
 
        content in self._log_contents."""
 
1243
        """Get the log from bzrlib.trace calls from this test.
 
1244
 
 
1245
        :param keep_log_file: When True, if the log is still a file on disk
 
1246
            leave it as a file on disk. When False, if the log is still a file
 
1247
            on disk, the log file is deleted and the log preserved as
 
1248
            self._log_contents.
 
1249
        :return: A string containing the log.
 
1250
        """
1203
1251
        # flush the log file, to get all content
1204
1252
        import bzrlib.trace
1205
1253
        bzrlib.trace._trace_file.flush()
1433
1481
        env_changes = kwargs.get('env_changes', {})
1434
1482
        working_dir = kwargs.get('working_dir', None)
1435
1483
        allow_plugins = kwargs.get('allow_plugins', False)
 
1484
        if len(args) == 1:
 
1485
            if isinstance(args[0], list):
 
1486
                args = args[0]
 
1487
            elif isinstance(args[0], basestring):
 
1488
                args = list(shlex.split(args[0]))
 
1489
        else:
 
1490
            symbol_versioning.warn(zero_ninetyone %
 
1491
                                   "passing varargs to run_bzr_subprocess",
 
1492
                                   DeprecationWarning, stacklevel=3)
1436
1493
        process = self.start_bzr_subprocess(args, env_changes=env_changes,
1437
1494
                                            working_dir=working_dir,
1438
1495
                                            allow_plugins=allow_plugins)
2327
2384
                   'bzrlib.tests.test_lockable_files',
2328
2385
                   'bzrlib.tests.test_log',
2329
2386
                   'bzrlib.tests.test_lsprof',
 
2387
                   'bzrlib.tests.test_mail_client',
2330
2388
                   'bzrlib.tests.test_memorytree',
2331
2389
                   'bzrlib.tests.test_merge',
2332
2390
                   'bzrlib.tests.test_merge3',