def test_start_responding(self, token): """ Calling ``start_responding`` makes an appropriate entry appear in the host map. """ ckey = RSA_KEY_512_RAW challenge = challenges.TLSSNI01(token=token) response = challenge.response(RSA_KEY_512) server_name = response.z_domain.decode('ascii') host_map = {} responder = TLSSNI01Responder() responder._generate_private_key = lambda key_type: ckey wrapped_host_map = responder.wrap_host_map(host_map) self.assertThat(wrapped_host_map, Not(Contains(server_name))) responder.start_responding(u'example.com', challenge, response) self.assertThat( wrapped_host_map.get(server_name.encode('utf-8')).certificate, MatchesPredicate(response.verify_cert, '%r does not verify')) # Starting twice before stopping doesn't break things responder.start_responding(u'example.com', challenge, response) self.assertThat( wrapped_host_map.get(server_name.encode('utf-8')).certificate, MatchesPredicate(response.verify_cert, '%r does not verify')) responder.stop_responding(u'example.com', challenge, response) self.assertThat(wrapped_host_map, Not(Contains(server_name)))
class TestMatchesPredicate(TestCase, TestMatchersInterface): matches_matcher = MatchesPredicate(is_even, "%s is not even") matches_matches = [2, 4, 6, 8] matches_mismatches = [3, 5, 7, 9] str_examples = [ ("MatchesPredicate(%r, %r)" % (is_even, "%s is not even"), MatchesPredicate(is_even, "%s is not even")), ] describe_examples = [ ('7 is not even', 7, MatchesPredicate(is_even, "%s is not even")), ]
def test_decodedurl(self): """ If the decorated method returns a ``DecodedURL`` then a redirect to that location is rendered into the response. """ loc = u"http://example.invalid/foo?bar=baz" resource = StaticResource(DecodedURL.from_text(loc)) self.assertThat( render(resource, {}), succeeded( MatchesPredicate( lambda value: assert_soup_has_tag_with_attributes( self, BeautifulSoup(value, 'html5lib'), "meta", {"http-equiv": "refresh", "content": "0;URL={}".format(loc), }, ) # The assertion will raise if it has a problem, otherwise # return None. Turn the None into something # MatchesPredicate recognizes as success. or True, "did not find meta refresh tag in %r", ), ), )
def matches_stats(testcase): """ Create a matcher that matches a response that confirms to the OpenMetrics specification. * The ``Content-Type`` is **application/openmetrics-text; version=1.0.0; charset=utf-8**. * The status is **OK**. * The body can be parsed by an OpenMetrics parser. * The metric families in the body are grouped and sorted. * At least one of the expected families appears in the body. :param testtools.TestCase testcase: The case to which to add detail about the matching process. :return: A matcher. """ return MatchesAll( MatchesStructure( code=Equals(OK), # "The content type MUST be..." headers=has_header( "content-type", "application/openmetrics-text; version=1.0.0; charset=utf-8", ), ), AfterPreprocessing( readBodyText, succeeded( MatchesAll( MatchesPredicate(add_detail(testcase, "response body"), "%s dummy"), parses_as_openmetrics(), ) ), ), )
def test_sync_other_issue_failure(self): """ When a sync is run and we try to issue a certificate for a domain but some non-ACME server error occurs, the sync should fail. """ self.fake_marathon.add_app({ 'id': '/my-app_1', 'labels': { 'HAPROXY_GROUP': 'external', 'MARATHON_ACME_0_DOMAIN': 'example.com' }, 'portDefinitions': [{ 'port': 9000, 'protocol': 'tcp', 'labels': {} }] }) self.txacme_client.issuance_error = RuntimeError('Something bad') d = self.marathon_acme.sync() assert_that( d, failed( MatchesStructure(value=MatchesStructure( subFailure=MatchesStructure(value=MatchesAll( IsInstance(RuntimeError), MatchesPredicate(str, 'Something bad'))))))) # Nothing stored, nothing notified assert_that(self.cert_store.as_dict(), succeeded(Equals({}))) assert_that(self.fake_marathon_lb.check_signalled_usr1(), Equals(False))
def test_default_retry(self): """ If no value is given for the ``should_retry`` parameter, if the wrapped method raises an exception it is called again after a short delay. This is repeated using the elements of ``retry_some_times`` as the sleep times and stops when there are no more elements. """ time = [] sleep = time.append counter = iter(count()) wrapper = with_retry(partial(self.always_failing, counter), sleep=sleep) # XXX testtools ``raises`` helper generates a crummy message when this # assertion fails self.assertRaises(CustomException, wrapper) self.expectThat( next(counter), # The number of times we demonstrated (above) that retry_some_times # retries - plus one more for the initial call. Equals(EXPECTED_RETRY_SOME_TIMES_RETRIES + 1), ) self.expectThat( sum(time), # Floating point maths. Allow for some slop. MatchesPredicate( lambda t: 119.8 <= t <= 120.0, "Time value %r too far from expected value 119.9", ), )
def test_parser(self): """ ``AcmeParser`` creates an endpoint with the specified ACME directory and directory store. """ directory = URL.fromText(u'https://example.com/acme') parser = _AcmeParser(u'prefix', directory) tempdir = self.useFixture(TempDir()).path temp_path = FilePath(tempdir) key_path = temp_path.child('client.key') reactor = object() self.assertThat( parser.parseStreamServer(reactor, tempdir, 'tcp', '443'), MatchesAll( IsInstance(AutoTLSEndpoint), MatchesStructure( reactor=Is(reactor), directory=Equals(directory), cert_store=MatchesAll( IsInstance(DirectoryStore), MatchesStructure( path=Equals(temp_path))), cert_mapping=MatchesAll( IsInstance(HostDirectoryMap), MatchesStructure( directoryPath=Equals(temp_path))), sub_endpoint=MatchesPredicate( IStreamServerEndpoint.providedBy, '%r is not a stream server endpoint')))) self.assertThat(key_path.isfile(), Equals(True)) key_data = key_path.getContent() parser.parseStreamServer(reactor, tempdir, 'tcp', '443'), self.assertThat(key_path.getContent(), Equals(key_data))
def one_call(self): """ There is only zero or one calls to the function. """ self.case.assertThat( self.current_calls, MatchesPredicate(lambda l: len(l) <= 1, "There is more than one concurrent call."), )
def test_ctrl_shift_tab_switching(self): """Pressing Ctrl+Shift+Tab after launching command scope must switch to Photos or Social scope (Social can be hidden by default).""" self.unity.dash.reveal_command_scope() self.keybinding("dash/lens/prev") self.assertThat( self.unity.dash.active_scope, Eventually( MatchesPredicate( lambda x: x in ["photos.scope", "social.scope"], '%s is not last scope')))
def contained_by(container): """ Match an element in the given container. :param container: Anything that supports being the right-hand operand to ``in``. :return: A matcher. """ return MatchesPredicate( lambda element: element in container, "%r not found", )
def provides(*interfaces): """ Match an object that provides all of the given interfaces. :param InterfaceClass *interfaces: The required interfaces. :return: A matcher. """ return MatchesAll(*list( MatchesPredicate( lambda obj, iface=iface: iface.providedBy(obj), "%s does not provide {!r}".format(iface), ) for iface in interfaces))
def test_unknown_architecture(self): """Check that creating a non-special architecture returns metadata.""" check_methods = [ architecture.Alias.universal, architecture.Alias.qemu, architecture.Alias.debian ] def function_returns_input(function): """Return true if function returns input.""" return function("input") == "input" self.assertThat(check_methods, AllMatch(MatchesPredicate(function_returns_input, "% did not return same")))
def test_mutable_directories_distinct(self, children): """ Two mutable directories created with ``create_mutable_directory`` are distinct from one another. """ a = self.tahoe_client.create_mutable_directory() b = self.tahoe_client.create_mutable_directory() self.assertThat( gatherResults([a, b]), succeeded( MatchesPredicate( lambda caps: caps[0] != caps[1], "Capabilities must be distinct: %r", ), ), )
def test_namespaced(self): """ `namespaced` creates a function that when called produces a namespaced name. """ self.assertThat( namespaced(u'foo'), MatchesAll( MatchesPredicate(callable, '%s is not callable'), After( lambda f: f(u'bar'), MatchesAll( MatchesListwise([Equals(u'foo'), Equals(u'bar')]), MatchesStructure(prefix=Equals(u'foo'), name=Equals(u'bar'))))))
def is_hex_uuid(): """ Match unicode strings giving a hex representation of a UUID. :return: A matcher. """ def _is_hex_uuid(value): if not isinstance(value, unicode): return False try: UUID(hex=value) except ValueError: return False return True return MatchesPredicate( _is_hex_uuid, "%r is not a UUID hex representation.", )
def test_listen_starts_service(self): """ ``AutoTLSEndpoint.listen`` starts an ``AcmeIssuingService``. Stopping the port stops the service. """ factory = Factory() d = self.endpoint.listen(factory) self.assertThat( d, succeeded( MatchesPredicate(IListeningPort.providedBy, '%r does not provide IListeningPort'))) port = d.result self.assertThat(self.endpoint.service, MatchesStructure(running=Equals(True))) self.assertThat(port.stopListening(), succeeded(Always())) self.assertThat(self.endpoint.service, MatchesStructure(running=Equals(False)))
def test_some_ipv4_addresses(self): """ ``get_local_addresses_sync`` returns a list of IPv4 addresses as native strings. """ self.assertThat( get_local_addresses_sync(), MatchesAll( IsInstance(list), AllMatch( MatchesAll( IsInstance(native_str), MatchesPredicate( lambda addr: socket.inet_pton(socket.AF_INET, addr), "%r is not an IPv4 address.", ), ), ), ), )
def items_are_sorted(): """ Match an ObjectCollection if its items can be iterated in the Kubernetes canonical sort order - lexicographical by namespace, name. """ def key(obj): return ( getattr(obj.metadata, "namespace", None), obj.metadata.name, ) def is_sorted(items, key): return list(items) == sorted(items, key=key) return AfterPreprocessing( attrgetter("items"), MatchesPredicate( partial(is_sorted, key=key), u"%s is not sorted by namespace, name", ), )
def test_add_file_outside_magic_directory(self, to_add): """ ``LocalSnapshotService.add_file`` returns a ``Deferred`` that fires with a ``Failure`` wrapping ``ValueError`` if called with a path that is not contained by the Magic-Folder's magic directory. """ assume(not to_add.startswith(self.magic_path.path)) self.assertThat( self.snapshot_service.add_file(FilePath(to_add)), failed( AfterPreprocessing( lambda f: (f.type, f.value.args), MatchesListwise([ Equals(ValueError), MatchesPredicate( lambda args: args[0].startswith( "The path being added "), "%r does not start with 'The path being added '.", ), ]), ), ), )
def test_parser(self): """ ``AcmeParser`` creates an endpoint with the specified ACME directory and directory store. """ directory = URL.fromText(u'https://example.com/acme') parser = _AcmeParser(u'prefix', directory) tempdir = self.useFixture(TempDir()).path temp_path = FilePath(tempdir) key_path = temp_path.child('client.key') reactor = MemoryReactorClock() self.assertThat( parser.parseStreamServer(reactor, tempdir, 'tcp', '443', timeout=0), MatchesAll( IsInstance(AutoTLSEndpoint), MatchesStructure( reactor=Is(reactor), directory=Equals(directory), cert_store=MatchesAll( IsInstance(DirectoryStore), MatchesStructure(path=Equals(temp_path))), cert_mapping=MatchesAll( IsInstance(HostDirectoryMap), MatchesStructure(directoryPath=Equals(temp_path))), sub_endpoint=MatchesPredicate( IStreamServerEndpoint.providedBy, '%r is not a stream server endpoint')))) self.assertThat(key_path.isfile(), Equals(True)) key_data = key_path.getContent() # Multiple instances with certificates from the same local directory, # will serve the same certificates. parser.parseStreamServer(reactor, tempdir, 'tcp', '443', timeout=0) self.assertThat(key_path.getContent(), Equals(key_data)) # Check that reactor is clean. self.assertEquals(0, len(reactor.getDelayedCalls()))
def is_subclass(cls): return MatchesPredicate( lambda value: issubclass(value, cls), "%%s is not a subclass of %s" % (cls, ), )
def test_commit_a_file(self, mangled_name, content, upload_dircap): """ Add a file into localsnapshot store, start the service which should result in a remotesnapshot corresponding to the localsnapshot. """ f = self.useFixture( RemoteSnapshotCreatorFixture( temp=FilePath(self.mktemp()), author=self.author, upload_dircap=upload_dircap, )) config = f.config remote_snapshot_creator = f.remote_snapshot_creator # Make the upload dircap refer to a dirnode so the snapshot creator # can link files into it. f.root._uri.data[upload_dircap] = dumps([ u"dirnode", { u"children": {} }, ]) # create a local snapshot data = io.BytesIO(content) d = create_snapshot( name=mangled_name, author=self.author, data_producer=data, snapshot_stash_dir=config.stash_path, parents=[], ) snapshots = [] d.addCallback(snapshots.append) self.assertThat( d, succeeded(Always()), ) # push LocalSnapshot object into the SnapshotStore. # This should be picked up by the Uploader Service and should # result in a snapshot cap. config.store_local_snapshot(snapshots[0]) d = remote_snapshot_creator.upload_local_snapshots() self.assertThat( d, succeeded(Always()), ) remote_snapshot_cap = config.get_remotesnapshot(mangled_name) # Verify that the new snapshot was linked in to our upload directory. self.assertThat( loads(f.root._uri.data[upload_dircap])[1][u"children"], Equals({ mangled_name: [ u"dirnode", { u"ro_uri": remote_snapshot_cap.decode("utf-8"), u"verify_uri": uri_from_string(remote_snapshot_cap).get_verify_cap(). to_string().decode("utf-8"), u"mutable": False, u"format": u"CHK", }, ], }), ) # test whether we got a capability self.assertThat( remote_snapshot_cap, MatchesPredicate(is_uri, "%r is not a Tahoe-LAFS URI"), ) with ExpectedException(KeyError, escape(repr(mangled_name))): config.get_local_snapshot(mangled_name)
# Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Tests for asynchronous helpers.""" import asyncio from inspect import isawaitable from testtools.matchers import Equals, Is, MatchesPredicate from .. import maas_async from ...testing import TestCase IsAwaitable = MatchesPredicate(isawaitable, "%s is not awaitable") class TestAsynchronousWrapper(TestCase): """Tests for `asynchronous`.""" def test_returns_plain_result_unaltered_when_loop_not_running(self): token = object() func = maas_async.asynchronous(lambda: token) self.assertThat(func(), Is(token)) def test_returns_plain_result_unaltered_when_loop_running(self): token = object() func = maas_async.asynchronous(lambda: token) async def within_event_loop(): loop = asyncio.get_event_loop()
def test_delegates_to_agent_for_location(self, agent): """ When a request is made using the agent, the added agents are delegated to based on the URI location/authority. """ agent.add_agent(b'foo:8080', DummyAgent()) agent.add_agent(b'bar:8080', FailingAgent(RuntimeError('bar'))) agent.add_agent(b'foo:9090', FailingAgent(RuntimeError('9090'))) d = agent.request(b'GET', b'http://foo:8080') assert_that( d, succeeded( MatchesListwise([ MatchesListwise( [Equals(b'GET'), Equals(b'http://foo:8080')]), MatchesDict({ 'headers': Is(None), 'bodyProducer': Is(None) }) ]))) # Scheme doesn't matter d = agent.request(b'GET', b'https://foo:8080') assert_that( d, succeeded( MatchesListwise([ MatchesListwise( [Equals(b'GET'), Equals(b'https://foo:8080')]), MatchesDict({ 'headers': Is(None), 'bodyProducer': Is(None) }) ]))) # Path doesn't matter d = agent.request(b'GET', b'http://foo:8080/bar/baz') assert_that( d, succeeded( MatchesListwise([ MatchesListwise( [Equals(b'GET'), Equals(b'http://foo:8080/bar/baz')]), MatchesDict({ 'headers': Is(None), 'bodyProducer': Is(None) }) ]))) # Hostname *does* matter d = agent.request(b'GET', b'http://bar:8080') assert_that( d, failed( MatchesStructure( value=MatchesAll(IsInstance(RuntimeError), MatchesPredicate(str, Equals('bar')))))) # Port *does* matter d = agent.request(b'GET', b'http://foo:9090') assert_that( d, failed( MatchesStructure( value=MatchesAll(IsInstance(RuntimeError), MatchesPredicate(str, Equals('9090')))))) # Other args passed through d = agent.request(b'GET', b'http://foo:8080', 'bar', 'baz') assert_that( d, succeeded( MatchesListwise([ MatchesListwise( [Equals(b'GET'), Equals(b'http://foo:8080')]), MatchesDict({ 'headers': Equals('bar'), 'bodyProducer': Equals('baz') }) ])))
def is_lower(): return MatchesPredicate( lambda text: text.lower() == text, u"%s is not lowercase", )
# ndiff works better when lines consistently end with newlines. a = str(expected).splitlines(keepends=False) a = list(line + "\n" for line in a) b = str(observed).splitlines(keepends=False) b = list(line + "\n" for line in b) yield "--- expected\n" yield "+++ observed\n" yield from ndiff(a, b) # The matchee is a non-empty string. In addition a string containing only # whitespace will not match. IsNonEmptyString = MatchesAll( MatchesPredicate( (lambda observed: isinstance(observed, str)), "%r is not a string"), MatchesPredicate( (lambda observed: len(observed) != 0), "%r is empty"), MatchesPredicate( (lambda observed: not observed.isspace()), "%r is whitespace"), first_only=True) class ContainedBy(Matcher): """Test if the matchee is in the given container.""" def __init__(self, haystack): super(ContainedBy, self).__init__()