def test_put_voucher(self, get_config, voucher): """ When a voucher is ``PUT`` to ``VoucherCollection`` it is passed in to the redemption model object for handling and an ``OK`` response is returned. """ tempdir = self.useFixture(TempDir()) config = get_config(tempdir.join(b"tahoe"), b"tub.port") root = root_from_config(config, datetime.now) agent = RequestTraversalAgent(root) producer = FileBodyProducer( BytesIO(dumps({u"voucher": voucher})), cooperator=uncooperator(), ) requesting = agent.request( b"PUT", b"http://127.0.0.1/voucher", bodyProducer=producer, ) self.addDetail( u"requesting result", text_content(u"{}".format(vars(requesting.result))), ) self.assertThat( requesting, succeeded(ok_response(), ), )
def test_stalePidFile(self): """TacTestFixture complains about stale pid files.""" tempdir = self.useFixture(TempDir()).path fixture = SimpleTac("okay", tempdir, 9876) # Run a short-lived process with the intention of using its pid in the # next step. Linux uses pids sequentially (from the information I've # been able to discover) so this approach is safe as long as we don't # delay until pids wrap... which should be a very long time unless the # machine is seriously busy. process = subprocess.Popen("true") process.wait() # Put the (now bogus) pid in the pid file. with open(fixture.pidfile, "w") as pidfile: pidfile.write(str(process.pid)) # Fire up the fixture, capturing warnings. with warnings.catch_warnings(record=True) as warnings_log: self.assertRaises(TacException, self.useFixture, fixture) self.assertThat(fixture, Not(IsRunning())) # One deprecation warning is emitted. self.assertEqual(1, len(warnings_log)) self.assertIs(UserWarning, warnings_log[0].category)
def setUp(self): super(StoragePluginWebPresence, self).setUp() self.useFixture(UseTestPlugins()) self.port_assigner = SameProcessStreamEndpointAssigner() self.port_assigner.setUp() self.addCleanup(self.port_assigner.tearDown) self.storage_plugin = u"tahoe-lafs-dummy-v1" from twisted.internet import reactor _, port_endpoint = self.port_assigner.assign(reactor) tempdir = TempDir() self.useFixture(tempdir) self.basedir = FilePath(tempdir.path) self.basedir.child(u"private").makedirs() self.node_fixture = self.useFixture( UseNode( plugin_config={ "web": "1", }, node_config={ "tub.location": "127.0.0.1:1", "web.port": ensure_text(port_endpoint), }, storage_plugin=self.storage_plugin, basedir=self.basedir, introducer_furl=SOME_FURL, )) self.node = yield self.node_fixture.create_node() self.webish = self.node.getServiceNamed(WebishServer.name) self.node.startService() self.addCleanup(self.node.stopService) self.port = self.webish.getPortnum()
def test_put_invalid_body(self, get_config, api_auth_token, body): """ If the body of a ``PUT`` to ``VoucherCollection`` does not consist of an object with a single *voucher* property then the response is *BAD REQUEST*. """ config = get_config_with_api_token( self.useFixture(TempDir()), get_config, api_auth_token, ) root = root_from_config(config, datetime.now) agent = RequestTraversalAgent(root) requesting = authorized_request( api_auth_token, agent, b"PUT", b"http://127.0.0.1/voucher", data=BytesIO(body), ) self.addDetail( u"requesting result", text_content(u"{}".format(vars(requesting.result))), ) self.assertThat( requesting, succeeded(bad_request_response(), ), )
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 test_load(self): # Configuration can be loaded and parsed from a file. filename = os.path.join(self.useFixture(TempDir()).path, "config.yaml") with open(filename, "wb") as stream: stream.write(b'logfile: "/some/where.log"') observed = Config.load(filename) self.assertEqual("/some/where.log", observed["logfile"])
def test_version(self, get_config, api_auth_token): """ The ZKAPAuthorizer package version is available in a JSON response to a **GET** to ``/version``. """ config = get_config_with_api_token( self.useFixture(TempDir()), get_config, api_auth_token, ) root = root_from_config(config, datetime.now) agent = RequestTraversalAgent(root) requesting = authorized_request( api_auth_token, agent, b"GET", b"http://127.0.0.1/version", ) self.assertThat( requesting, succeeded( matches_response( code_matcher=Equals(OK), body_matcher=AfterPreprocessing( loads, Equals({"version": zkapauthorizer_version}), ), ), ), )
def test_bad_ca_certificate(self): """ If no CA certificate is found in the service account directory, ``authenticate_with_serviceaccount`` raises ``ValueError``. """ t = FilePath(self.useFixture(TempDir()).join(b"")) serviceaccount = t.child(b"serviceaccount") serviceaccount.makedirs() serviceaccount.child(b"ca.crt").setContent( b"-----BEGIN CERTIFICATE-----\n" b"not a cert pem\n" b"-----END CERTIFICATE-----\n") serviceaccount.child(b"token").setContent(b"token") self.patch( os, "environ", { b"KUBERNETES_SERVICE_HOST": b"example.invalid.", b"KUBERNETES_SERVICE_PORT": b"443", }, ) self.assertThat( lambda: authenticate_with_serviceaccount( MemoryReactor(), path=serviceaccount.path, ), raises( ValueError( "Invalid certificate authority certificate found.", "[('PEM routines', 'PEM_read_bio', 'bad base64 decode')]", )), )
def test_encode_multipart_data_multiple_params(self): tmpdir = Path(self.useFixture(TempDir()).path) file2 = tmpdir / "file2" file2.write_text("f2") file3 = tmpdir / "file3" file3.write_text("f3") # Sequences of parameters and files passed to # encode_multipart_data() permit use of the same name for # multiple parameters and/or files. See `make_payloads` to # understand how it processes different types of parameter # values. params_in = [("one", "ABC"), ("one", "XYZ"), ("two", ["DEF", "UVW"])] files_in = [ ("f-one", BytesIO(b"f1")), ("f-two", file2.open("rb")), ("f-three", lambda: file3.open("rb")), ] body, headers = encode_multipart_data(params_in, files_in) self.assertEqual("%s" % len(body), headers["Content-Length"]) self.assertTrue(headers["Content-Type"].startswith( "multipart/form-data; boundary=")) # Round-trip through Django's multipart code. params_out, files_out = self.parse_headers_and_body_with_django( headers, body) params_out_expected = MultiValueDict() params_out_expected.appendlist("one", "ABC") params_out_expected.appendlist("one", "XYZ") params_out_expected.appendlist("two", "DEF") params_out_expected.appendlist("two", "UVW") self.assertEqual(params_out_expected, params_out, ahem_django_ahem) files_expected = {"f-one": b"f1", "f-two": b"f2", "f-three": b"f3"} files_observed = {name: buf.read() for name, buf in files_out.items()} self.assertEqual(files_expected, files_observed, ahem_django_ahem)
def test_bad_ca_certificate(self): """ If no CA certificate is found in the service account directory, ``https_policy_from_config`` raises ``ValueError``. """ t = FilePath(self.useFixture(TempDir()).path) t = t.asBytesMode() serviceaccount = t.child(b"serviceaccount") serviceaccount.makedirs() serviceaccount.child(b"ca.crt").setContent( b"-----BEGIN CERTIFICATE-----\n" b"not a cert pem\n" b"-----END CERTIFICATE-----\n") serviceaccount.child(b"token").setContent(b"token") environ = encode_environ({ u"KUBERNETES_SERVICE_HOST": u"example.invalid.", u"KUBERNETES_SERVICE_PORT": u"443", }) self.patch(os, "environ", environ) config = KubeConfig.from_service_account( path=serviceaccount.asTextMode().path) self.assertThat( lambda: https_policy_from_config(config), raises( ValueError( "Invalid certificate authority certificate found.", "[('PEM routines', 'PEM_read_bio', 'bad base64 decode')]", )), )
def test_missing_ca_certificate(self): """ If no CA certificate is found in the service account directory, ``authenticate_with_serviceaccount`` raises ``ValueError``. """ t = FilePath(self.useFixture(TempDir()).join(b"")) serviceaccount = t.child(b"serviceaccount") serviceaccount.makedirs() serviceaccount.child(b"ca.crt").setContent(b"not a cert pem") serviceaccount.child(b"token").setContent(b"token") self.patch( os, "environ", { b"KUBERNETES_SERVICE_HOST": b"example.invalid.", b"KUBERNETES_SERVICE_PORT": b"443", }, ) self.assertThat( lambda: authenticate_with_serviceaccount( MemoryReactor(), path=serviceaccount.path, ), raises(ValueError("No certificate authority certificate found.")), )
def test_missing_ca_certificate(self): """ If no CA certificate is found in the service account directory, ``https_policy_from_config`` raises ``ValueError``. """ t = FilePath(self.useFixture(TempDir()).path) t = t.asBytesMode() serviceaccount = t.child(b"serviceaccount") serviceaccount.makedirs() serviceaccount.child(b"ca.crt").setContent(b"not a cert pem") serviceaccount.child(b"token").setContent(b"token") environ = encode_environ({ u"KUBERNETES_SERVICE_HOST": u"example.invalid.", u"KUBERNETES_SERVICE_PORT": u"443", }) self.patch(os, "environ", environ) config = KubeConfig.from_service_account( path=serviceaccount.asTextMode().path) self.assertThat( lambda: https_policy_from_config(config), raises(ValueError("No certificate authority certificate found.")), )
def test_storage_dir_provided(self): """ When the program is run with an argument, it should start up and run. The program is expected to fail because it is unable to connect to Marathon. This test takes a while because we have to let txacme go through it's initial sync (registration + issuing of 0 certificates) before things can be halted. """ temp_dir = self.useFixture(TempDir()) yield main( reactor, raw_args=[ temp_dir.path, '--acme', LETSENCRYPT_STAGING_DIRECTORY.asText(), '--marathon', 'http://localhost:28080' # An address we can't reach ]) # Expect a 'certs' directory to be created self.assertThat(os.path.isdir(temp_dir.join('certs')), Equals(True)) # Expect a default certificate to be created self.assertThat(os.path.isfile(temp_dir.join('default.pem')), Equals(True)) # Expect to be unable to connect to Marathon flush_logged_errors(ConnectionRefusedError)
def test_put_invalid_body(self, get_config, body): """ If the body of a ``PUT`` to ``VoucherCollection`` does not consist of an object with a single *voucher* property then the response is *BAD REQUEST*. """ tempdir = self.useFixture(TempDir()) config = get_config(tempdir.join(b"tahoe"), b"tub.port") root = root_from_config(config, datetime.now) agent = RequestTraversalAgent(root) producer = FileBodyProducer( BytesIO(body), cooperator=uncooperator(), ) requesting = agent.request( b"PUT", b"http://127.0.0.1/voucher", bodyProducer=producer, ) self.addDetail( u"requesting result", text_content(u"{}".format(vars(requesting.result))), ) self.assertThat( requesting, succeeded(bad_request_response(), ), )
def make_dir(self): """Create a temporary directory. This is a convenience wrapper around a fixture incantation. That's the only reason why it's on the test case and not in a factory. """ return self.useFixture(TempDir()).path
def test_truncateLog(self): """ truncateLog truncates the log, if it exists, leaving the record of the service start in place. """ tempdir = self.useFixture(TempDir()).path fixture = SimpleTac("okay.tac", tempdir) # Truncating the log is a no-op if the log does not exist. fixture.truncateLog() self.assertFalse(exists(fixture.logfile)) # Put something in the log file. with open(fixture.logfile, "wb") as logfile: logfile.write("Hello\n") # Truncating the log does not remove the log file. fixture.truncateLog() self.assertTrue(exists(fixture.logfile)) with open(fixture.logfile, "rb") as logfile: self.assertEqual("", logfile.read()) # Put something in the log again, along with LOG_MAGIC. with open(fixture.logfile, "wb") as logfile: logfile.write("One\n") logfile.write("Two\n") logfile.write("Three, %s\n" % LOG_MAGIC) logfile.write("Four\n") # Truncating the log leaves everything up to and including the line # containing LOG_MAGIC. fixture.truncateLog() with open(fixture.logfile, "rb") as logfile: self.assertEqual("One\nTwo\nThree, %s\n" % LOG_MAGIC, logfile.read())
def test_adds_missing_to_end_sys_path(self): uniquedir = self.useFixture(TempDir()).path fixture = PythonPathEntry(uniquedir) self.assertFalse(uniquedir in sys.path) with fixture: self.assertTrue(uniquedir in sys.path) self.assertFalse(uniquedir in sys.path)
def test_adds_missing_to_end_package_path(self): uniquedir = self.useFixture(TempDir()).path fixture = PackagePathEntry('fixtures', uniquedir) self.assertFalse(uniquedir in fixtures.__path__) with fixture: self.assertTrue(uniquedir in fixtures.__path__) self.assertFalse(uniquedir in fixtures.__path__)
def test_unauthorized(self, get_config, path): """ A request for any resource without the required authorization token receives a 401 response. """ tempdir = self.useFixture(TempDir()) config = get_config(tempdir.join(b"tahoe"), b"tub.port") root = root_from_config(config, datetime.now) agent = RequestTraversalAgent(root) requesting = agent.request( b"GET", b"http://127.0.0.1/" + b"/".join(path), ) responses = [] requesting.addCallback(responses.append) self.assertThat( requesting, succeeded(Always()), ) [response] = responses self.assertThat( response.code, Equals(UNAUTHORIZED), )
def test_initial_interval(self, random, mean): """ When constructed without a value for ``last_run``, ``lease_maintenance_service`` schedules its first run to take place after an interval that falls uniformly in range centered on ``mean`` with a size of ``range``. """ clock = Clock() # Construct a range that fits in with the mean range_ = timedelta( seconds=random.uniform(0, mean.total_seconds()), ) service = lease_maintenance_service( dummy_maintain_leases, clock, FilePath(self.useFixture(TempDir()).join(u"last-run")), random, mean, range_, ) service.startService() [maintenance_call] = clock.getDelayedCalls() datetime_now = datetime.utcfromtimestamp(clock.seconds()) low = datetime_now + mean - (range_ / 2) high = datetime_now + mean + (range_ / 2) self.assertThat( datetime.utcfromtimestamp(maintenance_call.getTime()), between(low, high), )
def test_put_voucher(self, get_config, api_auth_token, voucher): """ When a voucher is ``PUT`` to ``VoucherCollection`` it is passed in to the redemption model object for handling and an ``OK`` response is returned. """ config = get_config_with_api_token( self.useFixture(TempDir()), get_config, api_auth_token, ) root = root_from_config(config, datetime.now) agent = RequestTraversalAgent(root) data = BytesIO(dumps({u"voucher": voucher})) requesting = authorized_request( api_auth_token, agent, b"PUT", b"http://127.0.0.1/voucher", data=data, ) self.addDetail( u"requesting result", text_content(u"{}".format(vars(requesting.result))), ) self.assertThat( requesting, succeeded(ok_response(), ), )
def test_creates_directories(self): # When given directory specifications, it creates those directories. path = self.useFixture(TempDir()).path create_normal_shape(path, [('a/', None), ('b/', None)]) self.assertThat(path, DirContains(['a', 'b'])) self.assertThat(os.path.join(path, 'a'), DirExists()) self.assertThat(os.path.join(path, 'b'), DirExists())
def test_get_invalid_voucher(self, get_config, api_auth_token, not_voucher): """ When a syntactically invalid voucher is requested with a ``GET`` to a child of ``VoucherCollection`` the response is **BAD REQUEST**. """ config = get_config_with_api_token( self.useFixture(TempDir()), get_config, api_auth_token, ) root = root_from_config(config, datetime.now) agent = RequestTraversalAgent(root) url = u"http://127.0.0.1/voucher/{}".format( quote( not_voucher.encode("utf-8"), safe=b"", ).decode("utf-8"), ).encode("ascii") requesting = authorized_request( api_auth_token, agent, b"GET", url, ) self.assertThat( requesting, succeeded(bad_request_response(), ), )
def setUp(self): super(FunctionalTest, self).setUp() self.test_data_dir = ''.join((os.path.abspath(os.getcwd()), '/', self.test_data_subdir)) self.maildir = TempDir() self.useFixture(self.maildir) self.fake_getmtime_val = 123456.7 self.useFixture(MonkeyPatch('os.path.getmtime', self.fake_getmtime)) config = { 'app': { 'root': 'mailase.api.controllers.root.RootController', 'modules': ['mailase.api'], }, 'mail': { 'maildirs': self.maildir.path }, 'search': { 'server_url': ['http://localhost:9200'], 'index': 'mailase_test' } } self.app = load_test_app(config) self.mailboxes = {} self.mua_subdirs = {}
def test_stalePidFile(self): """TacTestSetup complains about stale pid files.""" tempdir = self.useFixture(TempDir()).path fixture = SimpleTac("okay", tempdir) # Create a pidfile for a process that is no longer running. process = subprocess.Popen("true") # Write the pidfile and wait for the process to complete. (This # would work in either order, but waiting only at the end may # waste infinitesimally less time). with open(fixture.pidfile, "w") as pidfile: pidfile.write(repr(process.pid)) process.wait() # Fire up the fixture, capturing warnings. with warnings.catch_warnings(record=True) as warnings_log: try: self.assertRaises(TacException, fixture.setUp) self.assertThat(fixture, Not(IsRunning())) finally: fixture.cleanUp() # One deprecation warning is emitted. self.assertEqual( [UserWarning], [item.category for item in warnings_log])
def setUp(self): super(TestOOPSService, self).setUp() # OOPSService relies upon LogService. self.tempdir = self.useFixture(TempDir()).path self.log_filename = os.path.join(self.tempdir, "test.log") self.log_service = LogService(self.log_filename) self.log_service.setServiceParent(self.services)
def make_node(self, introducer_furl, storage_plugin, plugin_config): """ Create a client node with the given configuration. :param bytes introducer_furl: The introducer furl with which to configure the client. :param bytes storage_plugin: The name of a storage plugin to enable. :param dict[bytes, bytes] plugin_config: Configuration to supply to the enabled plugin. May also be ``None`` for no configuration section (distinct from ``{}`` which creates an empty configuration section). """ tempdir = TempDir() self.useFixture(tempdir) self.basedir = FilePath(tempdir.path) self.basedir.child(u"private").makedirs() self.useFixture(UseTestPlugins()) self.node_fixture = self.useFixture( UseNode( plugin_config, storage_plugin, self.basedir, introducer_furl, )) self.config = self.node_fixture.config self.node = yield self.node_fixture.create_node() [self.introducer_client] = self.node.introducer_clients
def setUp(self): super(UbuntuAdvantageTest, self).setUp() tempdir = self.useFixture(TempDir()) self.repo_list = Path(tempdir.join('repo.list')) self.bin_dir = Path(tempdir.join('bin')) self.keyrings_dir = Path(tempdir.join('keyrings')) self.trusted_gpg_dir = Path(tempdir.join('trusted.gpg.d')) self.apt_method_https = self.bin_dir / 'apt-method-https' self.ca_certificates = self.bin_dir / 'update-ca-certificates' self.snapd = self.bin_dir / 'snapd' # setup directories and files self.bin_dir.mkdir() self.keyrings_dir.mkdir() self.trusted_gpg_dir.mkdir() (self.keyrings_dir / 'ubuntu-esm-keyring.gpg').write_text('GPG key') self.make_fake_binary('apt-get') self.make_fake_binary('apt-method-https') self.make_fake_binary('update-ca-certificates') self.make_fake_binary('id', command='echo 0') self.make_fake_binary('lsb_release', command='echo precise') self.make_fake_binary('snapd') # in our default setup the snap is installed and enabled self.make_fake_binary('snap', command=SNAP_LIVEPATCH_INSTALLED) self.make_fake_binary('canonical-livepatch', command=LIVEPATCH_ENABLED) self.make_fake_binary('uname', command='echo 4.4.0-89-generic') self.livepatch_token = '0123456789abcdef1234567890abcdef'
def test_uncreateable_store_directory(self, get_config, now): """ If the underlying directory in the node configuration cannot be created then ``VoucherStore.from_node_config`` raises ``StoreOpenError``. """ tempdir = self.useFixture(TempDir()) nodedir = tempdir.join(b"node") # Create the node directory without permission to create the # underlying directory. mkdir(nodedir, 0o500) config = get_config(nodedir, b"tub.port") self.assertThat( lambda: VoucherStore.from_node_config( config, lambda: now, memory_connect, ), Raises( AfterPreprocessing( lambda (type, exc, tb): exc, MatchesAll( IsInstance(StoreOpenError), MatchesStructure(reason=MatchesAll( IsInstance(OSError), MatchesStructure(errno=Equals(EACCES), ), ), ), ), ), ), )
def test_latest_lease_maintenance_spending(self, get_config, size_observations, now): """ The most recently completed record of lease maintenance spending activity is reported in the response to a **GET** request. """ tempdir = self.useFixture(TempDir()) config = get_config(tempdir.join(b"tahoe"), b"tub.port") root = root_from_config(config, lambda: now) # Put some activity into it. total = 0 activity = root.store.start_lease_maintenance() for sizes in size_observations: total += required_passes(root.store.pass_value, sizes) activity.observe(sizes) activity.finish() agent = RequestTraversalAgent(root) d = agent.request( b"GET", b"http://127.0.0.1/unblinded-token", ) d.addCallback(readBody) d.addCallback( lambda body: loads(body)[u"lease-maintenance-spending"], ) self.assertThat( d, succeeded(Equals({ "when": now.isoformat(), "count": total, })), )