def test_scrubber_app_against_swift(self): """ test that the glance-scrubber script runs successfully against a swift backend when not in daemon mode """ config_path = os.environ.get('GLANCE_TEST_SWIFT_CONF') if not config_path: msg = "GLANCE_TEST_SWIFT_CONF environ not set." self.skipTest(msg) raw_config = read_config(config_path) swift_config = parse_config(raw_config) self.cleanup() self.start_servers(delayed_delete=True, daemon=False, default_store='swift', **swift_config) # add an image headers = { 'x-image-meta-name': 'test_image', 'x-image-meta-is_public': 'true', 'x-image-meta-disk_format': 'raw', 'x-image-meta-container_format': 'ovf', 'content-type': 'application/octet-stream', } path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'POST', body='XXX', headers=headers) # ensure the request was successful and the image is active self.assertEqual(response.status, 201) image = json.loads(content)['image'] self.assertEqual('active', image['status']) image_id = image['id'] # delete the image path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) http = httplib2.Http() response, content = http.request(path, 'DELETE') self.assertEqual(response.status, 200) # ensure the image is marked pending delete response, content = http.request(path, 'HEAD') self.assertEqual(response.status, 200) self.assertEqual('pending_delete', response['x-image-meta-status']) # wait for the scrub time on the image to pass time.sleep(self.api_server.scrub_time) # call the scrubber to scrub images cmd = ("glance-scrubber --config-file %s" % self.scrubber_daemon.conf_file_name) exitcode, out, err = execute(cmd, raise_error=False) self.assertEqual(0, exitcode) # ensure the image has been successfully deleted self.wait_for_scrub(path) self.stop_servers()
def setUp(self): config_path = os.environ.get('GLANCE_TEST_CINDER_CONF') if not config_path: msg = "GLANCE_TEST_CINDER_CONF environ not set." self.skipTest(msg) oslo.config.cfg.CONF(args=[], default_config_files=[config_path]) raw_config = store_tests_swift.read_config(config_path) try: self.cinder_config = parse_config(raw_config) ret = store_tests_swift.keystone_authenticate( self.cinder_config['test_cinder_store_auth_address'], self.cinder_config['test_cinder_store_auth_version'], self.cinder_config['test_cinder_store_tenant'], self.cinder_config['test_cinder_store_user'], self.cinder_config['test_cinder_store_key']) (tenant_id, auth_token, service_catalog) = ret self.context = glance.context.RequestContext( tenant=tenant_id, service_catalog=service_catalog, auth_tok=auth_token) self.cinder_client = cinder.get_cinderclient(self.context) except Exception as e: msg = "Cinder backend isn't set up: %s" % e self.skipTest(msg) super(TestCinderStore, self).setUp()
def test_scrubber_with_metadata_enc(self): """ test that files written to scrubber_data_dir use metadata_encryption_key when available to encrypt the location """ config_path = os.environ.get("GLANCE_TEST_SWIFT_CONF") if not config_path: msg = "GLANCE_TEST_SWIFT_CONF environ not set." self.skipTest(msg) raw_config = read_config(config_path) swift_config = parse_config(raw_config) self.cleanup() self.start_servers(delayed_delete=True, daemon=True, default_store="swift", **swift_config) # add an image headers = { "x-image-meta-name": "test_image", "x-image-meta-is_public": "true", "x-image-meta-disk_format": "raw", "x-image-meta-container_format": "ovf", "content-type": "application/octet-stream", } path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, "POST", body="XXX", headers=headers) self.assertEqual(response.status, 201) image = json.loads(content)["image"] self.assertEqual("active", image["status"]) image_id = image["id"] # delete the image path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) http = httplib2.Http() response, content = http.request(path, "DELETE") self.assertEqual(response.status, 200) response, content = http.request(path, "HEAD") self.assertEqual(response.status, 200) self.assertEqual("pending_delete", response["x-image-meta-status"]) # ensure the marker file has encrypted the image location by decrypting # it and checking the image_id is intact file_path = os.path.join(self.api_server.scrubber_datadir, str(image_id)) marker_uri = None with open(file_path, "r") as f: marker_uri = f.readline().strip() self.assertTrue(marker_uri is not None) decrypted_uri = crypt.urlsafe_decrypt(self.api_server.metadata_encryption_key, marker_uri) loc = StoreLocation({}) loc.parse_uri(decrypted_uri) self.assertIn(loc.scheme, ("swift+http", "swift+https")) self.assertEqual(image["id"], loc.obj) self.wait_for_scrub(path) self.stop_servers()
def test_scrubber_app_against_swift(self): """ test that the glance-scrubber script runs successfully against a swift backend when not in daemon mode """ config_path = os.environ.get('GLANCE_TEST_SWIFT_CONF') if not config_path: msg = "GLANCE_TEST_SWIFT_CONF environ not set." self.skipTest(msg) raw_config = read_config(config_path) swift_config = parse_config(raw_config) self.cleanup() self.start_servers(delayed_delete=True, daemon=False, default_store='swift', **swift_config) # add an image headers = { 'x-image-meta-name': 'test_image', 'x-image-meta-is_public': 'true', 'x-image-meta-disk_format': 'raw', 'x-image-meta-container_format': 'ovf', 'content-type': 'application/octet-stream', } path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'POST', body='XXX', headers=headers) # ensure the request was successful and the image is active self.assertEqual(response.status, 201) image = json.loads(content)['image'] self.assertEqual('active', image['status']) image_id = image['id'] # delete the image path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) http = httplib2.Http() response, content = http.request(path, 'DELETE') self.assertEqual(response.status, 200) # ensure the image is marked pending delete response, content = http.request(path, 'HEAD') self.assertEqual(response.status, 200) self.assertEqual('pending_delete', response['x-image-meta-status']) # wait for the scrub time on the image to pass time.sleep(self.api_server.scrub_time) # call the scrubber to scrub images cmd = ("bin/glance-scrubber --config-file %s" % self.scrubber_daemon.conf_file_name) exitcode, out, err = execute(cmd, raise_error=False) self.assertEqual(0, exitcode) # ensure the image has been successfully deleted wait_for_scrub(path) self.stop_servers()
def test_scrubber_app_against_swift(self): """ test that the glance-scrubber script runs successfully against a swift backend when not in daemon mode """ config_path = os.environ.get("GLANCE_TEST_SWIFT_CONF") if not config_path: msg = "GLANCE_TEST_SWIFT_CONF environ not set." self.skipTest(msg) raw_config = read_config(config_path) swift_config = parse_config(raw_config) self.cleanup() self.start_servers(delayed_delete=True, daemon=False, default_store="swift", **swift_config) # add an image headers = { "x-image-meta-name": "test_image", "x-image-meta-is_public": "true", "x-image-meta-disk_format": "raw", "x-image-meta-container_format": "ovf", "content-type": "application/octet-stream", } path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, "POST", body="XXX", headers=headers) # ensure the request was successful and the image is active self.assertEqual(response.status, 201) image = json.loads(content)["image"] self.assertEqual("active", image["status"]) image_id = image["id"] # delete the image path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) http = httplib2.Http() response, content = http.request(path, "DELETE") self.assertEqual(response.status, 200) # ensure the image is marked pending delete response, content = http.request(path, "HEAD") self.assertEqual(response.status, 200) self.assertEqual("pending_delete", response["x-image-meta-status"]) # wait for the scrub time on the image to pass time.sleep(self.api_server.scrub_time) # call the scrubber to scrub images exe_cmd = "%s -m glance.cmd.scrubber" % sys.executable cmd = "%s --config-file %s" % (exe_cmd, self.scrubber_daemon.conf_file_name) exitcode, out, err = execute(cmd, raise_error=False) self.assertEqual(0, exitcode) # ensure the image has been successfully deleted self.wait_for_scrub(path) self.stop_servers()
def test_scrubber_handles_swift_missing(self): """ Test that the scrubber handles the case where the image to be scrubbed is missing from swift """ config_path = os.environ.get('GLANCE_TEST_SWIFT_CONF') if not config_path: msg = "GLANCE_TEST_SWIFT_CONF environ not set." self.skipTest(msg) raw_config = read_config(config_path) swift_config = parse_config(raw_config) self.cleanup() self.start_servers(delayed_delete=True, daemon=False, default_store='swift', **swift_config) # add an image headers = { 'x-image-meta-name': 'test_image', 'x-image-meta-is_public': 'true', 'x-image-meta-disk_format': 'raw', 'x-image-meta-container_format': 'ovf', 'content-type': 'application/octet-stream', } path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'POST', body='XXX', headers=headers) self.assertEqual(response.status, 201) image = json.loads(content)['image'] self.assertEqual('active', image['status']) image_id = image['id'] # delete the image path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) http = httplib2.Http() response, content = http.request(path, 'DELETE') self.assertEqual(response.status, 200) # ensure the image is marked pending delete response, content = http.request(path, 'HEAD') self.assertEqual(response.status, 200) self.assertEqual('pending_delete', response['x-image-meta-status']) # go directly to swift and remove the image object swift = swift_connect(swift_config['swift_store_auth_address'], swift_config['swift_store_auth_version'], swift_config['swift_store_user'], swift_config['swift_store_key']) swift.delete_object(swift_config['swift_store_container'], image_id) try: swift.head_object(swift_config['swift_store_container'], image_id) self.fail('image should have been deleted from swift') except swiftclient.ClientException as e: self.assertEquals(e.http_status, 404) # wait for the scrub time on the image to pass time.sleep(self.api_server.scrub_time) # run the scrubber app, and ensure it doesn't fall over cmd = ("glance-scrubber --config-file %s" % self.scrubber_daemon.conf_file_name) exitcode, out, err = execute(cmd, raise_error=False) self.assertEqual(0, exitcode) self.wait_for_scrub(path) self.stop_servers()
def test_scrubber_with_metadata_enc(self): """ test that files written to scrubber_data_dir use metadata_encryption_key when available to encrypt the location """ config_path = os.environ.get('GLANCE_TEST_SWIFT_CONF') if not config_path: msg = "GLANCE_TEST_SWIFT_CONF environ not set." self.skipTest(msg) raw_config = read_config(config_path) swift_config = parse_config(raw_config) self.cleanup() self.start_servers(delayed_delete=True, daemon=True, default_store='swift', **swift_config) # add an image headers = { 'x-image-meta-name': 'test_image', 'x-image-meta-is_public': 'true', 'x-image-meta-disk_format': 'raw', 'x-image-meta-container_format': 'ovf', 'content-type': 'application/octet-stream', } path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'POST', body='XXX', headers=headers) self.assertEqual(response.status, 201) image = json.loads(content)['image'] self.assertEqual('active', image['status']) image_id = image['id'] # delete the image path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) http = httplib2.Http() response, content = http.request(path, 'DELETE') self.assertEqual(response.status, 200) response, content = http.request(path, 'HEAD') self.assertEqual(response.status, 200) self.assertEqual('pending_delete', response['x-image-meta-status']) # ensure the marker file has encrypted the image location by decrypting # it and checking the image_id is intact file_path = os.path.join(self.api_server.scrubber_datadir, str(image_id)) marker_uri = '' with open(file_path, 'r') as f: marker_uri = f.readline().strip() self.assertTrue(marker_uri is not None) decrypted_uri = crypt.urlsafe_decrypt( self.api_server.metadata_encryption_key, marker_uri) loc = StoreLocation({}) loc.parse_uri(decrypted_uri) self.assertIn(loc.scheme, ("swift+http", "swift+https")) self.assertEqual(image['id'], loc.obj) self.wait_for_scrub(path) self.stop_servers()
def test_scrubber_handles_swift_missing(self): """ Test that the scrubber handles the case where the image to be scrubbed is missing from swift """ config_path = os.environ.get('GLANCE_TEST_SWIFT_CONF') if not config_path: msg = "GLANCE_TEST_SWIFT_CONF environ not set." self.skipTest(msg) raw_config = read_config(config_path) swift_config = parse_config(raw_config) self.cleanup() self.start_servers(delayed_delete=True, daemon=False, default_store='swift', **swift_config) # add an image headers = { 'x-image-meta-name': 'test_image', 'x-image-meta-is_public': 'true', 'x-image-meta-disk_format': 'raw', 'x-image-meta-container_format': 'ovf', 'content-type': 'application/octet-stream', } path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'POST', body='XXX', headers=headers) self.assertEqual(response.status, 201) image = json.loads(content)['image'] self.assertEqual('active', image['status']) image_id = image['id'] # delete the image path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) http = httplib2.Http() response, content = http.request(path, 'DELETE') self.assertEqual(response.status, 200) # ensure the image is marked pending delete response, content = http.request(path, 'HEAD') self.assertEqual(response.status, 200) self.assertEqual('pending_delete', response['x-image-meta-status']) # go directly to swift and remove the image object swift = swift_connect(swift_config['swift_store_auth_address'], swift_config['swift_store_auth_version'], swift_config['swift_store_user'], swift_config['swift_store_key']) swift.delete_object(swift_config['swift_store_container'], image_id) try: swift.head_object(swift_config['swift_store_container'], image_id) self.fail('image should have been deleted from swift') except swiftclient.ClientException as e: self.assertEquals(e.http_status, 404) # wait for the scrub time on the image to pass time.sleep(self.api_server.scrub_time) # run the scrubber app, and ensure it doesn't fall over cmd = ("bin/glance-scrubber --config-file %s" % self.scrubber_daemon.conf_file_name) exitcode, out, err = execute(cmd, raise_error=False) self.assertEqual(0, exitcode) wait_for_scrub(path) self.stop_servers()
def test_scrubber_with_metadata_enc(self): """ test that files written to scrubber_data_dir use metadata_encryption_key when available to encrypt the location """ config_path = os.environ.get('GLANCE_TEST_SWIFT_CONF') if not config_path: msg = "GLANCE_TEST_SWIFT_CONF environ not set." self.skipTest(msg) raw_config = read_config(config_path) swift_config = parse_config(raw_config) self.cleanup() self.start_servers(delayed_delete=True, daemon=True, default_store='swift', **swift_config) # add an image headers = { 'x-image-meta-name': 'test_image', 'x-image-meta-is_public': 'true', 'x-image-meta-disk_format': 'raw', 'x-image-meta-container_format': 'ovf', 'content-type': 'application/octet-stream', } path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'POST', body='XXX', headers=headers) self.assertEqual(response.status, 201) image = json.loads(content)['image'] self.assertEqual('active', image['status']) image_id = image['id'] # delete the image path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) http = httplib2.Http() response, content = http.request(path, 'DELETE') self.assertEqual(response.status, 200) response, content = http.request(path, 'HEAD') self.assertEqual(response.status, 200) self.assertEqual('pending_delete', response['x-image-meta-status']) # ensure the marker file has encrypted the image location by decrypting # it and checking the image_id is intact file_path = os.path.join(self.api_server.scrubber_datadir, str(image_id)) marker_uri = '' with open(file_path, 'r') as f: marker_uri = f.readline().strip() self.assertTrue(marker_uri is not None) decrypted_uri = crypt.urlsafe_decrypt( self.api_server.metadata_encryption_key, marker_uri) loc = StoreLocation({}) loc.parse_uri(decrypted_uri) self.assertEqual("swift+http", loc.scheme) self.assertEqual(image['id'], loc.obj) wait_for_scrub(path) self.stop_servers()
def test_scrubber_with_metadata_enc(self): """ test that files written to scrubber_data_dir use metadata_encryption_key when available to encrypt the location """ config_path = os.environ.get("GLANCE_TEST_SWIFT_CONF") if not config_path: msg = "GLANCE_TEST_SWIFT_CONF environ not set." self.skipTest(msg) raw_config = read_config(config_path) swift_config = parse_config(raw_config) self.cleanup() self.start_servers(delayed_delete=True, daemon=True, default_store="swift", **swift_config) # add an image headers = { "x-image-meta-name": "test_image", "x-image-meta-is_public": "true", "x-image-meta-disk_format": "raw", "x-image-meta-container_format": "ovf", "content-type": "application/octet-stream", } path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, "POST", body="XXX", headers=headers) self.assertEqual(response.status, 201) image = json.loads(content)["image"] self.assertEqual("active", image["status"]) image_id = image["id"] # delete the image path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) http = httplib2.Http() response, content = http.request(path, "DELETE") self.assertEqual(response.status, 200) response, content = http.request(path, "HEAD") self.assertEqual(response.status, 200) self.assertEqual("pending_delete", response["x-image-meta-status"]) # ensure the marker file has encrypted the image location by decrypting # it and checking the image_id is intact file_path = os.path.join(self.api_server.scrubber_datadir, str(image_id)) marker_uri = "" with open(file_path, "r") as f: marker_uri = f.readline().strip() self.assertTrue(marker_uri is not None) decrypted_uri = crypt.urlsafe_decrypt(self.api_server.metadata_encryption_key, marker_uri) loc = StoreLocation({}) loc.parse_uri(decrypted_uri) self.assertEqual("swift+http", loc.scheme) self.assertEqual(image["id"], loc.obj) # NOTE(jkoelker) The build servers sometimes take longer than # 15 seconds to scrub. Give it up to 5 min, checking # checking every 15 seconds. When/if it flips to # deleted, bail immediately. for _ in xrange(3): time.sleep(5) response, content = http.request(path, "HEAD") if response["x-image-meta-status"] == "deleted" and response["x-image-meta-deleted"] == "True": break else: continue else: self.fail("image was never scrubbed") self.stop_servers()
def test_scrubber_app_against_swift(self): """ test that the glance-scrubber script runs successfully against a swift backend when not in daemon mode """ config_path = os.environ.get("GLANCE_TEST_SWIFT_CONF") if not config_path: msg = "GLANCE_TEST_SWIFT_CONF environ not set." self.skipTest(msg) raw_config = read_config(config_path) swift_config = parse_config(raw_config) self.cleanup() self.start_servers(delayed_delete=True, daemon=False, default_store="swift", **swift_config) # add an image headers = { "x-image-meta-name": "test_image", "x-image-meta-is_public": "true", "x-image-meta-disk_format": "raw", "x-image-meta-container_format": "ovf", "content-type": "application/octet-stream", } path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, "POST", body="XXX", headers=headers) # ensure the request was successful and the image is active self.assertEqual(response.status, 201) image = json.loads(content)["image"] self.assertEqual("active", image["status"]) image_id = image["id"] # delete the image path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) http = httplib2.Http() response, content = http.request(path, "DELETE") self.assertEqual(response.status, 200) # ensure the image is marked pending delete response, content = http.request(path, "HEAD") self.assertEqual(response.status, 200) self.assertEqual("pending_delete", response["x-image-meta-status"]) # wait for the scrub time on the image to pass time.sleep(self.api_server.scrub_time) # call the scrubber to scrub images cmd = "bin/glance-scrubber --config-file %s" % self.scrubber_daemon.conf_file_name exitcode, out, err = execute(cmd, raise_error=False) self.assertEqual(0, exitcode) # ensure the image has been successfully deleted # NOTE(jkoelker) The build servers sometimes take longer than # 15 seconds to scrub. Give it up to 5 min, checking # checking every 15 seconds. When/if it flips to # deleted, bail immediately. for _ in xrange(3): time.sleep(5) response, content = http.request(path, "HEAD") if response["x-image-meta-status"] == "deleted" and response["x-image-meta-deleted"] == "True": break else: continue else: self.fail("image was never scrubbed") self.stop_servers()
def test_scrubber_app_against_swift(self): """ test that the glance-scrubber script runs successfully against a swift backend when not in daemon mode """ config_path = os.environ.get('GLANCE_TEST_SWIFT_CONF') if not config_path: msg = "GLANCE_TEST_SWIFT_CONF environ not set." raise nose.SkipTest(msg) raw_config = read_config(config_path) swift_config = parse_config(raw_config) self.cleanup() self.start_servers(delayed_delete=True, daemon=False, default_store='swift', **swift_config) # add an image headers = { 'x-image-meta-name': 'test_image', 'x-image-meta-is_public': 'true', 'x-image-meta-disk_format': 'raw', 'x-image-meta-container_format': 'ovf', 'content-type': 'application/octet-stream', } path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'POST', body='XXX', headers=headers) # ensure the request was successful and the image is active self.assertEqual(response.status, 201) image = json.loads(content)['image'] self.assertEqual('active', image['status']) image_id = image['id'] # delete the image path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) http = httplib2.Http() response, content = http.request(path, 'DELETE') self.assertEqual(response.status, 200) # ensure the image is marked pending delete response, content = http.request(path, 'HEAD') self.assertEqual(response.status, 200) self.assertEqual('pending_delete', response['x-image-meta-status']) # wait for the scrub time on the image to pass time.sleep(self.api_server.scrub_time) # call the scrubber to scrub images cmd = ("bin/glance-scrubber --config-file %s" % self.scrubber_daemon.conf_file_name) exitcode, out, err = execute(cmd, raise_error=False) self.assertEqual(0, exitcode) # ensure the image has been successfully deleted # NOTE(jkoelker) The build servers sometimes take longer than # 15 seconds to scrub. Give it up to 5 min, checking # checking every 15 seconds. When/if it flips to # deleted, bail immediately. for _ in xrange(3): time.sleep(5) response, content = http.request(path, 'HEAD') if (response['x-image-meta-status'] == 'deleted' and response['x-image-meta-deleted'] == 'True'): break else: continue else: self.fail('image was never scrubbed') self.stop_servers()
def test_scrubber_handles_swift_missing(self): """ Test that the scrubber handles the case where the image to be scrubbed is missing from swift """ config_path = os.environ.get("GLANCE_TEST_SWIFT_CONF") if not config_path: msg = "GLANCE_TEST_SWIFT_CONF environ not set." self.skipTest(msg) raw_config = read_config(config_path) swift_config = parse_config(raw_config) self.cleanup() self.start_servers(delayed_delete=True, daemon=False, default_store="swift", **swift_config) # add an image headers = { "x-image-meta-name": "test_image", "x-image-meta-is_public": "true", "x-image-meta-disk_format": "raw", "x-image-meta-container_format": "ovf", "content-type": "application/octet-stream", } path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, "POST", body="XXX", headers=headers) self.assertEqual(response.status, 201) image = json.loads(content)["image"] self.assertEqual("active", image["status"]) image_id = image["id"] # delete the image path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) http = httplib2.Http() response, content = http.request(path, "DELETE") self.assertEqual(response.status, 200) # ensure the image is marked pending delete response, content = http.request(path, "HEAD") self.assertEqual(response.status, 200) self.assertEqual("pending_delete", response["x-image-meta-status"]) # go directly to swift and remove the image object swift = swift_connect( swift_config["swift_store_auth_address"], swift_config["swift_store_auth_version"], swift_config["swift_store_user"], swift_config["swift_store_key"], ) swift.delete_object(swift_config["swift_store_container"], image_id) try: swift.head_object(swift_config["swift_store_container"], image_id) self.fail("image should have been deleted from swift") except swiftclient.ClientException as e: self.assertEquals(e.http_status, 404) # wait for the scrub time on the image to pass time.sleep(self.api_server.scrub_time) # run the scrubber app, and ensure it doesn't fall over exe_cmd = "%s -m glance.cmd.scrubber" % sys.executable cmd = "%s --config-file %s" % (exe_cmd, self.scrubber_daemon.conf_file_name) exitcode, out, err = execute(cmd, raise_error=False) self.assertEqual(0, exitcode) self.wait_for_scrub(path) self.stop_servers()