def raise_keyb_from_match(): if sys.version_info > (2, 5): matcher = Raises(MatchesException(Exception)) else: # On Python 2.4 KeyboardInterrupt is a StandardError subclass # but should propogate from less generic exception matchers matcher = Raises(MatchesException(EnvironmentError)) matcher.match(self.raiser)
def __exit__(self, exc_type, exc_value, traceback): if exc_type is None: raise AssertionError('%s not raised.' % self.exc_type.__name__) if exc_type != self.exc_type: return False if self.value_re: matcher = MatchesException(self.exc_type, self.value_re) mismatch = matcher.match((exc_type, exc_value, traceback)) if mismatch: raise AssertionError(mismatch.describe()) return True
def __exit__(self, exc_type, exc_value, traceback): if exc_type is None: raise AssertionError("%s not raised." % self.exc_type.__name__) if exc_type != self.exc_type: return False if self.value_re: matcher = MatchesException(self.exc_type, self.value_re) mismatch = matcher.match((exc_type, exc_value, traceback)) if mismatch: raise AssertionError(mismatch.describe()) return True
class TestMatchesExceptionTypeInterface(TestCase, TestMatchersInterface): matches_matcher = MatchesException(ValueError) error_foo = make_error(ValueError, 'foo') error_sub = make_error(UnicodeError, 'bar') error_base_foo = make_error(Exception, 'foo') matches_matches = [error_foo, error_sub] matches_mismatches = [error_base_foo] str_examples = [("MatchesException(%r)" % Exception, MatchesException(Exception))] describe_examples = [ ("%r is not a %r" % (Exception, ValueError), error_base_foo, MatchesException(ValueError)), ]
class TestMatchesExceptionTypeReInterface(TestCase, TestMatchersInterface): matches_matcher = MatchesException(ValueError, 'fo.') error_foo = make_error(ValueError, 'foo') error_sub = make_error(UnicodeError, 'foo') error_bar = make_error(ValueError, 'bar') matches_matches = [error_foo, error_sub] matches_mismatches = [error_bar] str_examples = [("MatchesException(%r)" % Exception, MatchesException(Exception, 'fo.'))] describe_examples = [ ("'bar' does not match /fo./", error_bar, MatchesException(ValueError, "fo.")), ]
def test_execute_raises_PowerActionFail_when_script_fails(self): path = self._create_template_file("this_is_not_valid_shell") self.assertThat( lambda: self.run_action(path), Raises( MatchesException(PowerActionFail, "ether_wake failed.* return.* 127")))
def test_fires_after_timeout(self): # If we timeout, but the Deferred actually ends up firing after the # time out (perhaps because Spinner's clean-up code is buggy, or # perhaps because the code responsible for the callback is in a # thread), then the next run of a spinner works as intended, # completely isolated from the previous run. # Ensure we've timed out, and that we have a handle on the Deferred # that didn't fire. reactor = self.make_reactor() spinner1 = self.make_spinner(reactor) timeout = self.make_timeout() deferred1 = defer.Deferred() self.expectThat(lambda: spinner1.run(timeout, lambda: deferred1), Raises(MatchesException(_spinner.TimeoutError))) # Make a Deferred that will fire *after* deferred1 as long as the # reactor keeps spinning. We don't care that it's a callback of # deferred1 per se, only that it strictly fires afterwards. marker = object() deferred2 = defer.Deferred() deferred1.addCallback( lambda ignored: reactor.callLater(0, deferred2.callback, marker)) def fire_other(): """Fire Deferred from the last spin while waiting for this one.""" deferred1.callback(object()) return deferred2 spinner2 = self.make_spinner(reactor) self.assertThat(spinner2.run(timeout, fire_other), Is(marker))
def __exit__(self, exc_type, exc_value, traceback): if exc_type is None: error_msg = '%s not raised.' % self.exc_type.__name__ if self.msg: error_msg = error_msg + ' : ' + self.msg raise AssertionError(error_msg) if exc_type != self.exc_type: return False if self.value_re: matcher = MatchesException(self.exc_type, self.value_re) if self.msg: matcher = Annotate(self.msg, matcher) mismatch = matcher.match((exc_type, exc_value, traceback)) if mismatch: raise AssertionError(mismatch.describe()) return True
def test_dash_dash_help_shows_help(self): bytestream = BytesIO() stdout = TextIOWrapper(bytestream, 'utf8', line_buffering=True) stdin = StringIO() stderr = StringIO() ui = cli.UI(['--help'], stdin, stdout, stderr) cmd = commands.Command(ui) cmd.args = [arguments.string.StringArgument('foo')] cmd.name = "bar" # By definition SystemExit is not caught by 'except Exception'. try: ui.set_command(cmd) except SystemExit: exc_info = sys.exc_info() self.assertThat(exc_info, MatchesException(SystemExit(0))) else: self.fail('ui.set_command did not raise') self.assertThat( bytestream.getvalue().decode('utf8'), DocTestMatches( """Usage: run.py bar [options] foo ... A command that can be run... ... -d HERE, --here=HERE... ...""", doctest.ELLIPSIS))
def test_not_reentrant(self): # run_in_reactor raises an error if it is called inside another call # to run_in_reactor. spinner = self.make_spinner() self.assertThat(lambda: spinner.run( self.make_timeout(), spinner.run, self.make_timeout(), lambda: None), Raises(MatchesException(_spinner.ReentryError)))
def test_next_stream_corruption_error(self): repo = self.useFixture(FileRepositoryFixture(self)).repo open(os.path.join(repo.base, 'next-stream'), 'wb').close() self.assertThat( repo.count, Raises(MatchesException( ValueError("Corrupt next-stream file: ''"))))
def test_timeout(self): # If the function takes too long to run, we raise a # _spinner.TimeoutError. timeout = self.make_timeout() self.assertThat( lambda: self.make_spinner().run(timeout, lambda: defer.Deferred()), Raises(MatchesException(_spinner.TimeoutError)))
def test_exception_reraised(self): # If the given function raises an error, run_in_reactor re-raises that # error. self.assertThat( lambda: self.make_spinner().run(self.make_timeout(), lambda: 1 / 0 ), Raises(MatchesException(ZeroDivisionError)))
def test_keyboard_interrupt_not_caught(self): # If a cleanup raises KeyboardInterrupt, it gets reraised. def raiseKeyboardInterrupt(): raise KeyboardInterrupt() self.test.addCleanup(raiseKeyboardInterrupt) self.assertThat(lambda:self.test.run(self.logging_result), Raises(MatchesException(KeyboardInterrupt)))
def test_no_config_file_errors(self): ui, cmd = self.get_test_ui_and_cmd() self.assertEqual(3, cmd.execute()) self.assertEqual(1, len(ui.outputs)) self.assertEqual('error', ui.outputs[0][0]) self.assertThat( ui.outputs[0][1], MatchesException(ValueError('No .testr.conf config file')))
class TestMatchesExceptionInstanceInterface(TestCase, TestMatchersInterface): matches_matcher = MatchesException(ValueError("foo")) error_foo = make_error(ValueError, 'foo') error_bar = make_error(ValueError, 'bar') error_base_foo = make_error(Exception, 'foo') matches_matches = [error_foo] matches_mismatches = [error_bar, error_base_foo] str_examples = [("MatchesException(Exception('foo',))", MatchesException(Exception('foo')))] describe_examples = [ ("%r is not a %r" % (Exception, ValueError), error_base_foo, MatchesException(ValueError("foo"))), ("ValueError('bar',) has different arguments to ValueError('foo',).", error_bar, MatchesException(ValueError("foo"))), ]
class TestMatchesExceptionTypeMatcherInterface(TestCase, TestMatchersInterface): matches_matcher = MatchesException(ValueError, AfterPreprocessing(str, Equals('foo'))) error_foo = make_error(ValueError, 'foo') error_sub = make_error(UnicodeError, 'foo') error_bar = make_error(ValueError, 'bar') matches_matches = [error_foo, error_sub] matches_mismatches = [error_bar] str_examples = [("MatchesException(%r)" % Exception, MatchesException(Exception, Equals('foo')))] describe_examples = [ ("5 != %r" % (error_bar[1], ), error_bar, MatchesException(ValueError, Equals(5))), ]
def test_KeyboardInterrupt_propogates(self): # The default 'it raised' propogates KeyboardInterrupt. match_keyb = Raises(MatchesException(KeyboardInterrupt)) def raise_keyb_from_match(): matcher = Raises() matcher.match(self.raiser) self.assertThat(raise_keyb_from_match, match_keyb)
def test_fails_if_repo_doesnt_exist(self): ui, cmd = self.get_test_ui_and_cmd(args=()) cmd.repository_factory = memory.RepositoryFactory() self.set_config( '[DEFAULT]\ntest_command=foo $IDOPTION\ntest_id_option=--load-list $IDFILE\n' ) self.assertEqual(3, cmd.execute()) self.assertEqual(1, len(ui.outputs)) self.assertEqual('error', ui.outputs[0][0]) self.assertThat(ui.outputs[0][1], MatchesException(RepositoryNotFound))
def test_nested_effect_exception_passes_to_outer_error_handler(self): """ If an inner effect raises an exception, it bubbles up and the exc_info is passed to the outer effect's error handlers. """ self.assertThat( sync_perform( Effect(StubIntent(Effect( ErrorIntent()))).on_error(lambda x: x)), MatchesException(ValueError('oh dear')))
def test_failure(self): # _spinner.extract_result raises the failure's exception if it's given # a Deferred that is failing. try: 1 / 0 except ZeroDivisionError: f = Failure() d = defer.fail(f) self.assertThat(lambda: _spinner.extract_result(d), Raises(MatchesException(ZeroDivisionError)))
def test_will_not_run_with_previous_junk(self): # If 'run' is called and there's still junk in the spinner's junk # list, then the spinner will refuse to run. from twisted.internet.protocol import ServerFactory reactor = self.make_reactor() spinner = self.make_spinner(reactor) timeout = self.make_timeout() spinner.run(timeout, reactor.listenTCP, 0, ServerFactory()) self.assertThat(lambda: spinner.run(timeout, lambda: None), Raises(MatchesException(_spinner.StaleJunkError)))
def test_assertRaises_function_repr_in_exception(self): # When assertRaises fails, it includes the repr of the invoked # function in the error message, so it's easy to locate the problem. def foo(): """An arbitrary function.""" pass self.assertThat( lambda: self.assertRaises(Exception, foo), Raises( MatchesException(self.failureException, '.*%r.*' % (foo,))))
def test_no_config_settings_errors(self): ui, cmd = self.get_test_ui_and_cmd() cmd.repository_factory.initialise(ui.here) self.set_config('') self.assertEqual(3, cmd.execute()) self.assertEqual(1, len(ui.outputs)) self.assertEqual('error', ui.outputs[0][0]) self.assertThat( ui.outputs[0][1], MatchesException( ValueError('No test_command option present in .testr.conf')))
def matches_failure(exception, value_re=None): """ Matches an twisted :py:`Failure` with the given exception. See :py:`testtools.matches.MatchesException`. """ def as_exc_info_tuple(failure): return failure.type, failure.value, failure.tb return AfterPreprocessing(as_exc_info_tuple, MatchesException(exception, value_re=value_re))
def test_shows_errors_from_execute_returns_3(self): class FailCommand(commands.Command): def run(self): raise Exception("foo") ui = model.UI() cmd = FailCommand(ui) self.assertEqual(3, cmd.execute()) self.assertEqual(1, len(ui.outputs)) self.assertEqual('error', ui.outputs[0][0]) self.assertThat(ui.outputs[0][1], MatchesException(Exception('foo')))
def test_oops_directory_without_reporter(self): # It is an error to omit the OOPS reporter if directory is specified. config = ( 'oops:\n' ' directory: /tmp/oops\n' ) expected = MatchesException( formencode.Invalid, "oops: You must give a value for reporter") self.assertThat( partial(Config.parse, config), Raises(expected))
def test_dispatcher_raises(self): """ When a dispatcher raises an exception, the exc_info is passed to the error handler. """ calls = [] eff = Effect('meaningless').on(error=calls.append) dispatcher = lambda i: raise_(ValueError('oh dear')) perform(dispatcher, eff) self.assertThat( calls, MatchesListwise([MatchesException(ValueError('oh dear'))]))
def test_fast_sigint_raises_no_result_error(self): # If we get a SIGINT during a run, we raise _spinner.NoResultError. SIGINT = getattr(signal, 'SIGINT', None) if not SIGINT: self.skipTest("SIGINT not available") reactor = self.make_reactor() spinner = self.make_spinner(reactor) timeout = self.make_timeout() reactor.callWhenRunning(os.kill, os.getpid(), SIGINT) self.assertThat(lambda: spinner.run(timeout * 5, defer.Deferred), Raises(MatchesException(_spinner.NoResultError))) self.assertEqual([], spinner._clean())
def test_not_reentrant(self): # A function decorated as not being re-entrant will raise a # _spinner.ReentryError if it is called while it is running. calls = [] @_spinner.not_reentrant def log_something(): calls.append(None) if len(calls) < 5: log_something() self.assertThat( log_something, Raises(MatchesException(_spinner.ReentryError))) self.assertEqual(1, len(calls))
def test_resolve_effect_cb_exception(self): """ When a callback raises an exception, the next error handler is called with the exception info. """ self.assertThat( resolve_effect( Effect("orig").on(success=lambda r: 1 / 0).on( error=lambda exc: ('handled', exc)), 'result'), MatchesListwise( [Equals('handled'), MatchesException(ZeroDivisionError)]))
def __eq__(self, other): matcher = MatchesException(self.exception) return ( isinstance(other, Failure) and other.check(type(self.exception)) is not None and matcher.match((type(other.value), other.value, None)) is None)