def test_list_no_containers(self): # List request to empty account # To test listing no containers, create new user other than # the base user of this instance. resp, container_list = \ self.os_operator.account_client.list_account_containers() # When sending a request to an account which has not received a PUT # container request, the response does not contain 'accept-ranges' # header. This is a special case, therefore the existence of response # headers is checked without custom matcher. self.assertIn('content-length', resp) self.assertIn('x-timestamp', resp) self.assertIn('x-account-bytes-used', resp) self.assertIn('x-account-container-count', resp) self.assertIn('x-account-object-count', resp) self.assertIn('content-type', resp) self.assertIn('x-trans-id', resp) self.assertIn('date', resp) # Check only the format of common headers with custom matcher self.assertThat(resp, custom_matchers.AreAllWellFormatted()) self.assertEqual(len(container_list), 0)
def test_list_no_containers(self): # List request to empty account # To test listing no containers, create new user other than # the base user of this instance. resp, container_list = \ self.os_operator.account_client.list_account_containers() # When sending a request to an account which has not received a PUT # container request, the response does not contain 'accept-ranges' # header. This is a special case, therefore the existence of response # headers is checked without custom matcher. # # As the expected response is 204 No Content, Content-Length presence # is not checked here intentionally. According to RFC 7230 a server # MUST NOT send the header in such responses. Thus, clients should not # depend on this header. However, the standard does not require them # to validate the server's behavior. We leverage that to not refuse # any implementation violating it like Swift [1] or some versions of # Ceph RadosGW [2]. # [1] https://bugs.launchpad.net/swift/+bug/1537811 # [2] http://tracker.ceph.com/issues/13582 self.assertIn('x-timestamp', resp) self.assertIn('x-account-bytes-used', resp) self.assertIn('x-account-container-count', resp) self.assertIn('x-account-object-count', resp) self.assertIn('content-type', resp) self.assertIn('x-trans-id', resp) self.assertIn('date', resp) # Check only the format of common headers with custom matcher self.assertThat(resp, custom_matchers.AreAllWellFormatted()) self.assertEqual(len(container_list), 0)
def test_web_listing(self): headers = {'web-listings': 'true'} self.container_client.update_container_metadata(self.container_name, metadata=headers) # test GET on http://account_url/container_name # we should retrieve a listing of objects resp, body = self.custom_account_client.request( "GET", self.container_name) # The target of the request is not any Swift resource. Therefore, the # existence of response header is checked without a custom matcher. self.assertIn('content-length', resp) self.assertIn('content-type', resp) self.assertIn('x-trans-id', resp) self.assertIn('date', resp) # Check only the format of common headers with custom matcher self.assertThat(resp, custom_matchers.AreAllWellFormatted()) self.assertIn(self.object_name, body) # clean up before exiting self.container_client.update_container_metadata( self.container_name, {'web-listings': ""}) _, body = self.container_client.list_container_metadata( self.container_name) self.assertNotIn('x-container-meta-web-listings', body)
def test_get_object_if_different(self): # http://en.wikipedia.org/wiki/HTTP_ETag # Make a conditional request for an object using the If-None-Match # header, it should get downloaded only if the local file is different, # otherwise the response code should be 304 Not Modified object_name, data = self.create_object(self.container_name) # local copy is identical, no download md5 = hashlib.md5(data).hexdigest() headers = {'If-None-Match': md5} url = "%s/%s" % (self.container_name, object_name) resp, _ = self.object_client.get(url, headers=headers) self.assertEqual(resp['status'], '304') # When the file is not downloaded from Swift server, response does # not contain 'X-Timestamp' header. This is the special case, therefore # the existence of response headers is checked without custom matcher. self.assertIn('date', resp) # Check only the format of common headers with custom matcher self.assertThat(resp, custom_matchers.AreAllWellFormatted()) # local copy is different, download local_data = "something different" md5 = hashlib.md5(local_data.encode()).hexdigest() headers = {'If-None-Match': md5} resp, body = self.object_client.get(url, headers=headers) self.assertHeaders(resp, 'Object', 'GET')
def test_delete_large_object(self): # delete static large object using multipart manifest object_name = self._create_large_object() params_del = {'multipart-manifest': 'delete'} resp, body = self.object_client.delete_object( self.container_name, object_name, params=params_del) # When deleting SLO using multipart manifest, the response contains # not 'content-length' but 'transfer-encoding' header. This is the # special case, therefore the existence of response headers is checked # outside of custom matcher. self.assertIn('transfer-encoding', resp) self.assertIn('content-type', resp) self.assertIn('x-trans-id', resp) self.assertIn('date', resp) # Check only the format of common headers with custom matcher self.assertThat(resp, custom_matchers.AreAllWellFormatted()) resp, body = self.container_client.list_container_contents( self.container_name) self.assertEqual(int(resp['x-container-object-count']), 0)
def test_bulk_delete_by_POST(self): # Test bulk operation of deleting multiple files filepath, container_name, object_name = self._create_archive() self._upload_archive(filepath) data = '%s/%s\n%s' % (container_name, object_name, container_name) params = {'bulk-delete': ''} resp, body = self.account_client.create_account_metadata( {}, data=data, params=params) # When deleting multiple files using the bulk operation, the response # does not contain 'content-length' header. This is the special case, # therefore the existence of response headers is checked without # custom matcher. self.assertIn('transfer-encoding', resp) self.assertIn('content-type', resp) self.assertIn('x-trans-id', resp) self.assertIn('date', resp) # Check only the format of common headers with custom matcher self.assertThat(resp, custom_matchers.AreAllWellFormatted()) # Check if uploaded contents are completely deleted self._check_contents_deleted(container_name)
def test_list_no_containers(self): # List request to empty account # To test listing no containers, create new user other than # the base user of this instance. self.data.setup_test_user() os_test_user = clients.Manager( self.data.test_user, self.data.test_password, self.data.test_tenant) # Retrieve the id of an operator role of object storage test_role_id = None swift_role = CONF.object_storage.operator_role try: _, roles = self.os_admin.identity_client.list_roles() test_role_id = next(r['id'] for r in roles if r['name'] == swift_role) except StopIteration: msg = "%s role found" % swift_role raise exceptions.NotFound(msg) # Retrieve the test_user id _, users = self.os_admin.identity_client.get_users() test_user_id = next(usr['id'] for usr in users if usr['name'] == self.data.test_user) # Retrieve the test_tenant id _, tenants = self.os_admin.identity_client.list_tenants() test_tenant_id = next(tnt['id'] for tnt in tenants if tnt['name'] == self.data.test_tenant) # Assign the newly created user the appropriate operator role self.os_admin.identity_client.assign_user_role( test_tenant_id, test_user_id, test_role_id) resp, container_list = \ os_test_user.account_client.list_account_containers() self.assertIn(int(resp['status']), test.HTTP_SUCCESS) # When sending a request to an account which has not received a PUT # container request, the response does not contain 'accept-ranges' # header. This is a special case, therefore the existence of response # headers is checked without custom matcher. self.assertIn('content-length', resp) self.assertIn('x-timestamp', resp) self.assertIn('x-account-bytes-used', resp) self.assertIn('x-account-container-count', resp) self.assertIn('x-account-object-count', resp) self.assertIn('content-type', resp) self.assertIn('x-trans-id', resp) self.assertIn('date', resp) # Check only the format of common headers with custom matcher self.assertThat(resp, custom_matchers.AreAllWellFormatted()) self.assertEqual(len(container_list), 0)
def test_extract_archive(self): # Test bulk operation of file upload with an archived file filepath, container_name, object_name = self._create_archive() resp, _ = self._upload_archive(filepath) self.containers.append(container_name) # When uploading an archived file with the bulk operation, the response # does not contain 'content-length' header. This is the special case, # therefore the existence of response headers is checked without # custom matcher. self.assertIn('transfer-encoding', resp) self.assertIn('content-type', resp) self.assertIn('x-trans-id', resp) self.assertIn('date', resp) # Check only the format of common headers with custom matcher self.assertThat(resp, custom_matchers.AreAllWellFormatted()) param = {'format': 'json'} resp, body = self.account_client.list_account_containers(param) self.assertHeaders(resp, 'Account', 'GET') self.assertIn(container_name, [b['name'] for b in body]) param = {'format': 'json'} resp, contents_list = self.container_client.list_container_contents( container_name, param) self.assertHeaders(resp, 'Container', 'GET') self.assertIn(object_name, [c['name'] for c in contents_list])
def assertHeaders(self, resp, target, method): """Check the existence and the format of response headers""" self.assertThat( resp, custom_matchers.ExistsAllResponseHeaders(target, method, self.policies)) self.assertThat(resp, custom_matchers.AreAllWellFormatted())
def test_get_healthcheck(self): resp, _ = self.account_client.get("healthcheck", {}) # The target of the request is not any Swift resource. Therefore, the # existence of response header is checked without a custom matcher. self.assertIn('content-length', resp) self.assertIn('content-type', resp) self.assertIn('x-trans-id', resp) self.assertIn('date', resp) # Check only the format of common headers with custom matcher self.assertThat(resp, custom_matchers.AreAllWellFormatted())
def test_get_healthcheck(self): url = self.account_client._get_base_version_url() + "healthcheck" resp, body = self.account_client.raw_request(url, "GET") self.account_client._error_checker(resp, body) # The target of the request is not any Swift resource. Therefore, the # existence of response header is checked without a custom matcher. self.assertIn('content-length', resp) self.assertIn('content-type', resp) self.assertIn('x-trans-id', resp) self.assertIn('date', resp) # Check only the format of common headers with custom matcher self.assertThat(resp, custom_matchers.AreAllWellFormatted())
def test_get_crossdomain_policy(self): resp, body = self.account_client.get("crossdomain.xml", {}) self.assertTrue( body.startswith(self.xml_start) and body.endswith(self.xml_end)) # The target of the request is not any Swift resource. Therefore, the # existence of response header is checked without a custom matcher. self.assertIn('content-length', resp) self.assertIn('content-type', resp) self.assertIn('x-trans-id', resp) self.assertIn('date', resp) # Check only the format of common headers with custom matcher self.assertThat(resp, custom_matchers.AreAllWellFormatted())
def test_get_crossdomain_policy(self): url = self.account_client._get_base_version_url() + "crossdomain.xml" resp, body = self.account_client.raw_request(url, "GET") self.account_client._error_checker(resp, body) body = body.decode() self.assertTrue(body.startswith(self.xml_start) and body.endswith(self.xml_end)) # The target of the request is not any Swift resource. Therefore, the # existence of response header is checked without a custom matcher. self.assertIn('content-length', resp) self.assertIn('content-type', resp) self.assertIn('x-trans-id', resp) self.assertIn('date', resp) # Check only the format of common headers with custom matcher self.assertThat(resp, custom_matchers.AreAllWellFormatted())
def test_bulk_delete(self): # Test bulk operation of deleting multiple files filepath, container_name, object_name = self._create_archive() params = {'extract-archive': 'tar'} with open(filepath) as fh: mydata = fh.read() resp, body = self.account_client.create_account(data=mydata, params=params) data = '%s/%s\n%s' % (container_name, object_name, container_name) params = {'bulk-delete': ''} resp, body = self.account_client.delete_account(data=data, params=params) self.assertIn(int(resp['status']), test.HTTP_SUCCESS) # When deleting multiple files using the bulk operation, the response # does not contain 'content-length' header. This is the special case, # therefore the existence of response headers is checked without # custom matcher. self.assertIn('transfer-encoding', resp) self.assertIn('content-type', resp) self.assertIn('x-trans-id', resp) self.assertIn('date', resp) # Check only the format of common headers with custom matcher self.assertThat(resp, custom_matchers.AreAllWellFormatted()) # Check if a container is deleted param = {'format': 'txt'} resp, body = self.account_client.list_account_containers(param) self.assertIn(int(resp['status']), test.HTTP_SUCCESS) self.assertHeaders(resp, 'Account', 'GET') self.assertNotIn(container_name, body)
def test_list_extensions(self): resp, extensions = self.account_client.list_extensions() self.assertIn(int(resp['status']), test.HTTP_SUCCESS) self.assertThat(resp, custom_matchers.AreAllWellFormatted())
def test_list_extensions(self): resp, extensions = self.account_client.list_extensions() self.assertThat(resp, custom_matchers.AreAllWellFormatted())
def test_list_extensions(self): resp = self.capabilities_client.list_capabilities() self.assertThat(resp, custom_matchers.AreAllWellFormatted())