def setUp(self): """Register a new permission and a fake store selector.""" zope.testing.cleanup.cleanUp() super(TestCheckPermissionCaching, self).setUp() self.factory = ObjectFactory() provideUtility(FakeStoreSelector, IStoreSelector) self.addCleanup(zope.testing.cleanup.cleanUp)
class TestWorkerProtocol(TestCaseInTempDir, PullerWorkerMixin): """Tests for the client-side implementation of the protocol used to communicate to the master process. """ def setUp(self): TestCaseInTempDir.setUp(self) self.output = StringIO() self.protocol = PullerWorkerProtocol(self.output) self.factory = ObjectFactory() def assertSentNetstrings(self, expected_netstrings): """Assert that the protocol sent the given netstrings (in order).""" observed_netstrings = get_netstrings(self.output.getvalue()) self.assertEqual(expected_netstrings, observed_netstrings) def resetBuffers(self): # Empty the test output and error buffers. self.output.truncate(0) self.assertEqual('', self.output.getvalue()) def test_nothingSentOnConstruction(self): # The protocol sends nothing until it receives an event. self.branch_to_mirror = self.makePullerWorker(protocol=self.protocol) self.assertSentNetstrings([]) def test_startMirror(self): # Calling startMirroring sends 'startMirroring' as a netstring. self.protocol.startMirroring() self.assertSentNetstrings(['startMirroring', '0']) def test_branchChanged(self): # Calling 'branchChanged' sends the arguments. arbitrary_args = [self.factory.getUniqueString() for x in range(6)] self.protocol.startMirroring() self.resetBuffers() self.protocol.branchChanged(*arbitrary_args) self.assertSentNetstrings(['branchChanged', '6'] + arbitrary_args) def test_mirrorFailed(self): # Calling 'mirrorFailed' sends the error message. self.protocol.startMirroring() self.resetBuffers() self.protocol.mirrorFailed('Error Message', 'OOPS') self.assertSentNetstrings( ['mirrorFailed', '2', 'Error Message', 'OOPS']) def test_progressMade(self): # Calling 'progressMade' sends an arbitrary string indicating # progress. self.protocol.progressMade('test') self.assertSentNetstrings(['progressMade', '0']) def test_log(self): # Calling 'log' sends 'log' as a netstring and its arguments, after # formatting as a string. self.protocol.log('logged %s', 'message') self.assertSentNetstrings(['log', '1', 'logged message'])
def setUp(self): TestCaseInTempDir.setUp(self) self.output = StringIO() self.protocol = PullerWorkerProtocol(self.output) self.factory = ObjectFactory()
class TestCheckPermissionCaching(TestCase): """Test the caching done by `LaunchpadSecurityPolicy.checkPermission`.""" def setUp(self): """Register a new permission and a fake store selector.""" zope.testing.cleanup.cleanUp() super(TestCheckPermissionCaching, self).setUp() self.factory = ObjectFactory() provideUtility(FakeStoreSelector, IStoreSelector) self.addCleanup(zope.testing.cleanup.cleanUp) def makeRequest(self): """Construct an arbitrary `LaunchpadBrowserRequest` object.""" data = StringIO.StringIO() env = {} return LaunchpadBrowserRequest(data, env) def getObjectPermissionAndCheckerFactory(self): """Return an object, a permission and a `CheckerFactory` for them. :return: A tuple ``(obj, permission, checker_factory)``, such that ``queryAdapter(obj, IAuthorization, permission)`` will return a `Checker` created by ``checker_factory``. """ permission = self.factory.getUniqueString() provideUtility( PermissionAccessLevel(), ILaunchpadPermission, permission) checker_factory = CheckerFactory() provideAdapter( checker_factory, [Object], IAuthorization, name=permission) return Object(), permission, checker_factory def test_checkPermission_cache_unauthenticated(self): # checkPermission caches the result of checkUnauthenticated for a # particular object and permission. request = self.makeRequest() policy = LaunchpadSecurityPolicy(request) obj, permission, checker_factory = ( self.getObjectPermissionAndCheckerFactory()) # When we call checkPermission for the first time, the security policy # calls the checker. policy.checkPermission(permission, obj) self.assertEqual( ['checkUnauthenticated'], checker_factory.calls) # A subsequent identical call does not call the checker. policy.checkPermission(permission, obj) self.assertEqual( ['checkUnauthenticated'], checker_factory.calls) def test_checkPermission_delegated_cache_unauthenticated(self): # checkPermission caches the result of checkUnauthenticated for a # particular object and permission, even if that object's # authorization has been delegated. request = self.makeRequest() policy = LaunchpadSecurityPolicy(request) # Delegate auth for Object to AnotherObject{One,Two}. permission = self.factory.getUniqueString() self.useFixture( ZopeAdapterFixture(Delegate, [Object], name=permission)) # Allow auth to AnotherObjectOne. self.useFixture( ZopeAdapterFixture( Allow, [AnotherObjectOne], name=Delegate.permission)) # Deny auth to AnotherObjectTwo. self.useFixture( ZopeAdapterFixture( Deny, [AnotherObjectTwo], name=Delegate.permission)) # Calling checkPermission() populates the participation cache. objecttoauthorize = Object() policy.checkPermission(permission, objecttoauthorize) # It contains results for objecttoauthorize and the two objects that # its authorization was delegated to. cache = request.annotations[LAUNCHPAD_SECURITY_POLICY_CACHE_KEY] cache_expected = { objecttoauthorize: {permission: False}, Delegate.object_one: {Delegate.permission: True}, Delegate.object_two: {Delegate.permission: False}, } self.assertEqual(cache_expected, dict(cache)) def test_checkPermission_cache_authenticated(self): # checkPermission caches the result of checkAuthenticated for a # particular object and permission. principal = FakeLaunchpadPrincipal() request = self.makeRequest() request.setPrincipal(principal) policy = LaunchpadSecurityPolicy(request) obj, permission, checker_factory = ( self.getObjectPermissionAndCheckerFactory()) # When we call checkPermission for the first time, the security policy # calls the checker. policy.checkPermission(permission, obj) self.assertEqual( [('checkAuthenticated', principal.person)], checker_factory.calls) # A subsequent identical call does not call the checker. policy.checkPermission(permission, obj) self.assertEqual( [('checkAuthenticated', principal.person)], checker_factory.calls) def test_checkPermission_clearSecurityPolicyCache_resets_cache(self): # Calling clearSecurityPolicyCache on the request clears the cache. request = self.makeRequest() policy = LaunchpadSecurityPolicy(request) obj, permission, checker_factory = ( self.getObjectPermissionAndCheckerFactory()) # When we call checkPermission for the first time, the security policy # calls checkUnauthenticated on the checker. policy.checkPermission(permission, obj) self.assertEqual( ['checkUnauthenticated'], checker_factory.calls) request.clearSecurityPolicyCache() # After clearing the cache the policy calls checkUnauthenticated # again. policy.checkPermission(permission, obj) self.assertEqual( ['checkUnauthenticated', 'checkUnauthenticated'], checker_factory.calls) def test_checkPermission_setPrincipal_resets_cache(self): # Setting the principal on the request clears the cache of results # (this is important during login). principal = FakeLaunchpadPrincipal() request = self.makeRequest() policy = LaunchpadSecurityPolicy(request) obj, permission, checker_factory = ( self.getObjectPermissionAndCheckerFactory()) # When we call checkPermission before setting the principal, the # security policy calls checkUnauthenticated on the checker. policy.checkPermission(permission, obj) self.assertEqual( ['checkUnauthenticated'], checker_factory.calls) request.setPrincipal(principal) # After setting the principal, the policy calls checkAuthenticated # rather than finding a value in the cache. policy.checkPermission(permission, obj) self.assertEqual( ['checkUnauthenticated', ('checkAuthenticated', principal.person)], checker_factory.calls) def test_checkPermission_commit_clears_cache(self): # Committing a transaction clears the cache. request = self.makeRequest() policy = LaunchpadSecurityPolicy(request) obj, permission, checker_factory = ( self.getObjectPermissionAndCheckerFactory()) # When we call checkPermission before setting the principal, the # security policy calls checkUnauthenticated on the checker. policy.checkPermission(permission, obj) self.assertEqual( ['checkUnauthenticated'], checker_factory.calls) transaction.commit() # After committing a transaction, the policy calls # checkUnauthenticated again rather than finding a value in the cache. policy.checkPermission(permission, obj) self.assertEqual( ['checkUnauthenticated', 'checkUnauthenticated'], checker_factory.calls)
def setUp(self): super(TestSwiftFixture, self).setUp() self.swift_fixture = SwiftFixture() self.useFixture(self.swift_fixture) self.factory = ObjectFactory()
class TestSwiftFixture(TestCase): layer = BaseLayer def setUp(self): super(TestSwiftFixture, self).setUp() self.swift_fixture = SwiftFixture() self.useFixture(self.swift_fixture) self.factory = ObjectFactory() def makeSampleObject(self, client, contents, content_type=None): """Create a new container and a new sample object within it.""" cname = self.factory.getUniqueString() oname = self.factory.getUniqueString() client.put_container(cname) client.put_object(cname, oname, contents, content_type=content_type) return cname, oname def test_get(self): client = self.swift_fixture.connect() size = 30 headers, body = client.get_object("size", str(size)) self.assertEqual("0" * size, body) self.assertEqual(str(size), headers["content-length"]) self.assertEqual("text/plain", headers["content-type"]) def test_get_404(self): client = self.swift_fixture.connect() cname = self.factory.getUniqueString() client.put_container(cname) exc = self.assertRaises(swiftclient.ClientException, client.get_object, cname, "nonexistent") self.assertEqual(404, exc.http_status) def test_get_403(self): client = self.swift_fixture.connect(key="bad key") exc = self.assertRaises(swiftclient.ClientException, client.get_container, "size") # swiftclient should possibly set exc.http_status here, but doesn't. self.assertEqual( 'Authorization Failure. ' 'Authorization Failed: Forbidden (HTTP 403)', exc.message) def test_put(self): client = self.swift_fixture.connect() message = "Hello World!" cname, oname = self.makeSampleObject(client, message, "text/something") for x in range(1, 10): headers, body = client.get_object(cname, oname) self.assertEqual(message * x, body) self.assertEqual(str(len(message) * x), headers["content-length"]) self.assertEqual("text/something", headers["content-type"]) client.put_object(cname, oname, message * (x + 1), content_type="text/something") def test_get_container(self): # Basic container listing. start = datetime.utcnow().replace(microsecond=0) client = self.swift_fixture.connect() message = "42" cname, oname = self.makeSampleObject(client, message, "text/something") client.put_object(cname, oname + ".2", message) _, container = client.get_container(cname) self.assertEqual(2, len(container)) obj = container[0] self.assertEqual(oname, obj["name"]) self.assertEqual(len(message), obj["bytes"]) self.assertEqual(md5(message).hexdigest(), obj["hash"]) self.assertEqual("text/something", obj["content-type"]) last_modified = datetime.strptime(obj["last_modified"], "%Y-%m-%dT%H:%M:%S.%f") # ISO format self.assertThat(last_modified, Not(LessThan(start))) self.assertThat(last_modified, Not(GreaterThan(datetime.utcnow()))) def test_get_container_marker(self): # Container listing supports the marker parameter. client = self.swift_fixture.connect() message = "Hello" cname, oname = self.makeSampleObject(client, message, "text/something") oname2 = oname + ".2" oname3 = oname + ".3" client.put_object(cname, oname2, message) client.put_object(cname, oname3, message) # List contents found after name == marker. _, container = client.get_container(cname, marker=oname) self.assertEqual(2, len(container)) self.assertEqual(oname2, container[0]["name"]) self.assertEqual(oname3, container[1]["name"]) def test_get_container_end_marker(self): # Container listing supports the end_marker parameter. client = self.swift_fixture.connect() message = "Hello" cname, oname = self.makeSampleObject(client, message, "text/something") oname2 = oname + ".2" oname3 = oname + ".3" client.put_object(cname, oname2, message) client.put_object(cname, oname3, message) # List contents found before name == end_marker. _, container = client.get_container(cname, end_marker=oname3) self.assertEqual(2, len(container)) self.assertEqual(oname, container[0]["name"]) self.assertEqual(oname2, container[1]["name"]) def test_get_container_limit(self): # Container listing supports the limit parameter. client = self.swift_fixture.connect() message = "Hello" cname, oname = self.makeSampleObject(client, message, "text/something") oname2 = oname + ".2" oname3 = oname + ".3" client.put_object(cname, oname2, message) client.put_object(cname, oname3, message) # Limit list to two objects. _, container = client.get_container(cname, limit=2) self.assertEqual(2, len(container)) self.assertEqual(oname, container[0]["name"]) self.assertEqual(oname2, container[1]["name"]) def test_get_container_prefix(self): client = self.swift_fixture.connect() message = "Hello" cname, oname = self.makeSampleObject(client, message, "text/something") oname2 = "different" oname3 = oname + ".3" client.put_object(cname, oname2, message) client.put_object(cname, oname3, message) # List contents whose object names start with prefix. _, container = client.get_container(cname, prefix=oname) self.assertEqual(2, len(container)) self.assertEqual(oname, container[0]["name"]) self.assertEqual(oname3, container[1]["name"]) def test_get_container_full_listing(self): client = self.swift_fixture.connect() message = "42" cname, oname = self.makeSampleObject(client, message, "text/something") _, container = client.get_container(cname, full_listing=True) self.assertEqual(1, len(container)) def test_shutdown_and_startup(self): # This test demonstrates how the Swift client deals with a # flapping Swift server. In particular, that once a connection # has started failing it will continue failing so we need to # ensure that once we encounter a fail we open a fresh # connection. This is probably a property of our mock Swift # server rather than reality but the mock is a required target. size = 30 # With no Swift server, a fresh connection fails with # a swiftclient.ClientException when it fails to # authenticate. self.swift_fixture.shutdown() client = self.swift_fixture.connect() self.assertRaises(swiftclient.ClientException, client.get_object, "size", str(size)) # Things work fine when the Swift server is up. self.swift_fixture.startup() headers, body = client.get_object("size", str(size)) self.assertEqual(body, "0" * size) # But if the Swift server goes away again, we end up with # different failures since the connection has already # authenticated. self.swift_fixture.shutdown() self.assertRaises(ConnectionError, client.get_object, "size", str(size)) # And even if we bring it back up, existing connections # continue to fail self.swift_fixture.startup() self.assertRaises(ClientException, client.get_object, "size", str(size)) # But fresh connections are fine. client = self.swift_fixture.connect() headers, body = client.get_object("size", str(size)) self.assertEqual(body, "0" * size) def test_env(self): self.assertEqual(fakeswift.DEFAULT_USERNAME, config.librarian_server.os_username) self.assertEqual(fakeswift.DEFAULT_PASSWORD, config.librarian_server.os_password) self.assertEqual( 'http://localhost:{0}/keystone/v2.0/'.format( self.swift_fixture.daemon_port), config.librarian_server.os_auth_url) self.assertEqual(fakeswift.DEFAULT_TENANT_NAME, config.librarian_server.os_tenant_name)