Remove moxstubout usage
As of version 3.5.0 moxstub will be deprecated, so remove it where it has been used. Change-Id: I2622c457871815311241d2eea562d7a3c70b0795 Signed-off-by: Chuck Short <chucks@redhat.com>
This commit is contained in:
parent
b8b873433e
commit
aefad17de8
|
@ -25,7 +25,6 @@ import uuid
|
|||
from oslo_config import cfg
|
||||
from oslo_utils import encodeutils
|
||||
from oslo_utils import units
|
||||
from oslotest import moxstubout
|
||||
import requests_mock
|
||||
import six
|
||||
from six import moves
|
||||
|
@ -51,6 +50,7 @@ CONF = cfg.CONF
|
|||
FAKE_UUID = lambda: str(uuid.uuid4())
|
||||
FAKE_UUID2 = lambda: str(uuid.uuid4())
|
||||
|
||||
|
||||
Store = swift.Store
|
||||
FIVE_KB = 5 * units.Ki
|
||||
FIVE_GB = 5 * units.Gi
|
||||
|
@ -66,174 +66,6 @@ SWIFT_CONF = {'swift_store_auth_address': 'localhost:8080',
|
|||
}
|
||||
|
||||
|
||||
# We stub out as little as possible to ensure that the code paths
|
||||
# between swift and swiftclient are tested
|
||||
# thoroughly
|
||||
def stub_out_swiftclient(stubs, swift_store_auth_version):
|
||||
fixture_containers = ['glance']
|
||||
fixture_container_headers = {}
|
||||
fixture_headers = {
|
||||
'glance/%s' % FAKE_UUID: {
|
||||
'content-length': FIVE_KB,
|
||||
'etag': 'c2e5db72bd7fd153f53ede5da5a06de3'
|
||||
},
|
||||
'glance/%s' % FAKE_UUID2: {'x-static-large-object': 'true', },
|
||||
}
|
||||
fixture_objects = {'glance/%s' % FAKE_UUID: six.BytesIO(b"*" * FIVE_KB),
|
||||
'glance/%s' % FAKE_UUID2: six.BytesIO(b"*" * FIVE_KB), }
|
||||
|
||||
def fake_head_container(url, token, container, **kwargs):
|
||||
if container not in fixture_containers:
|
||||
msg = "No container %s found" % container
|
||||
status = http_client.NOT_FOUND
|
||||
raise swiftclient.ClientException(msg, http_status=status)
|
||||
return fixture_container_headers
|
||||
|
||||
def fake_put_container(url, token, container, **kwargs):
|
||||
fixture_containers.append(container)
|
||||
|
||||
def fake_post_container(url, token, container, headers, **kwargs):
|
||||
for key, value in headers.items():
|
||||
fixture_container_headers[key] = value
|
||||
|
||||
def fake_put_object(url, token, container, name, contents, **kwargs):
|
||||
# PUT returns the ETag header for the newly-added object
|
||||
# Large object manifest...
|
||||
global SWIFT_PUT_OBJECT_CALLS
|
||||
SWIFT_PUT_OBJECT_CALLS += 1
|
||||
CHUNKSIZE = 64 * units.Ki
|
||||
fixture_key = "%s/%s" % (container, name)
|
||||
if fixture_key not in fixture_headers:
|
||||
if kwargs.get('headers'):
|
||||
etag = kwargs['headers']['ETag']
|
||||
manifest = kwargs.get('headers').get('X-Object-Manifest')
|
||||
fixture_headers[fixture_key] = {'manifest': True,
|
||||
'etag': etag,
|
||||
'x-object-manifest': manifest}
|
||||
fixture_objects[fixture_key] = None
|
||||
return etag
|
||||
if hasattr(contents, 'read'):
|
||||
fixture_object = six.BytesIO()
|
||||
read_len = 0
|
||||
chunk = contents.read(CHUNKSIZE)
|
||||
checksum = hashlib.md5()
|
||||
while chunk:
|
||||
fixture_object.write(chunk)
|
||||
read_len += len(chunk)
|
||||
checksum.update(chunk)
|
||||
chunk = contents.read(CHUNKSIZE)
|
||||
etag = checksum.hexdigest()
|
||||
else:
|
||||
fixture_object = six.BytesIO(contents)
|
||||
read_len = len(contents)
|
||||
etag = hashlib.md5(fixture_object.getvalue()).hexdigest()
|
||||
if read_len > MAX_SWIFT_OBJECT_SIZE:
|
||||
msg = ('Image size:%d exceeds Swift max:%d' %
|
||||
(read_len, MAX_SWIFT_OBJECT_SIZE))
|
||||
raise swiftclient.ClientException(
|
||||
msg, http_status=http_client.REQUEST_ENTITY_TOO_LARGE)
|
||||
fixture_objects[fixture_key] = fixture_object
|
||||
fixture_headers[fixture_key] = {
|
||||
'content-length': read_len,
|
||||
'etag': etag}
|
||||
return etag
|
||||
else:
|
||||
msg = ("Object PUT failed - Object with key %s already exists"
|
||||
% fixture_key)
|
||||
raise swiftclient.ClientException(msg,
|
||||
http_status=http_client.CONFLICT)
|
||||
|
||||
def fake_get_object(conn, container, name, **kwargs):
|
||||
# GET returns the tuple (list of headers, file object)
|
||||
fixture_key = "%s/%s" % (container, name)
|
||||
if fixture_key not in fixture_headers:
|
||||
msg = "Object GET failed"
|
||||
status = http_client.NOT_FOUND
|
||||
raise swiftclient.ClientException(msg, http_status=status)
|
||||
|
||||
byte_range = None
|
||||
headers = kwargs.get('headers', dict())
|
||||
if headers is not None:
|
||||
headers = dict((k.lower(), v) for k, v in headers.items())
|
||||
if 'range' in headers:
|
||||
byte_range = headers.get('range')
|
||||
|
||||
fixture = fixture_headers[fixture_key]
|
||||
if 'manifest' in fixture:
|
||||
# Large object manifest... we return a file containing
|
||||
# all objects with prefix of this fixture key
|
||||
chunk_keys = sorted([k for k in fixture_headers.keys()
|
||||
if k.startswith(fixture_key) and
|
||||
k != fixture_key])
|
||||
result = six.BytesIO()
|
||||
for key in chunk_keys:
|
||||
result.write(fixture_objects[key].getvalue())
|
||||
else:
|
||||
result = fixture_objects[fixture_key]
|
||||
|
||||
if byte_range is not None:
|
||||
start = int(byte_range.split('=')[1].strip('-'))
|
||||
result = six.BytesIO(result.getvalue()[start:])
|
||||
fixture_headers[fixture_key]['content-length'] = len(
|
||||
result.getvalue())
|
||||
|
||||
return fixture_headers[fixture_key], result
|
||||
|
||||
def fake_head_object(url, token, container, name, **kwargs):
|
||||
# HEAD returns the list of headers for an object
|
||||
try:
|
||||
fixture_key = "%s/%s" % (container, name)
|
||||
return fixture_headers[fixture_key]
|
||||
except KeyError:
|
||||
msg = "Object HEAD failed - Object does not exist"
|
||||
status = http_client.NOT_FOUND
|
||||
raise swiftclient.ClientException(msg, http_status=status)
|
||||
|
||||
def fake_delete_object(url, token, container, name, **kwargs):
|
||||
# DELETE returns nothing
|
||||
fixture_key = "%s/%s" % (container, name)
|
||||
if fixture_key not in fixture_headers:
|
||||
msg = "Object DELETE failed - Object does not exist"
|
||||
status = http_client.NOT_FOUND
|
||||
raise swiftclient.ClientException(msg, http_status=status)
|
||||
else:
|
||||
del fixture_headers[fixture_key]
|
||||
del fixture_objects[fixture_key]
|
||||
|
||||
def fake_http_connection(*args, **kwargs):
|
||||
return None
|
||||
|
||||
def fake_get_auth(url, user, key, auth_version, **kwargs):
|
||||
if url is None:
|
||||
return None, None
|
||||
if 'http' in url and '://' not in url:
|
||||
raise ValueError('Invalid url %s' % url)
|
||||
# Check the auth version against the configured value
|
||||
if swift_store_auth_version != auth_version:
|
||||
msg = 'AUTHENTICATION failed (version mismatch)'
|
||||
raise swiftclient.ClientException(msg)
|
||||
return None, None
|
||||
|
||||
stubs.Set(swiftclient.client,
|
||||
'head_container', fake_head_container)
|
||||
stubs.Set(swiftclient.client,
|
||||
'put_container', fake_put_container)
|
||||
stubs.Set(swiftclient.client,
|
||||
'post_container', fake_post_container)
|
||||
stubs.Set(swiftclient.client,
|
||||
'put_object', fake_put_object)
|
||||
stubs.Set(swiftclient.client,
|
||||
'delete_object', fake_delete_object)
|
||||
stubs.Set(swiftclient.client,
|
||||
'head_object', fake_head_object)
|
||||
stubs.Set(swiftclient.client.Connection,
|
||||
'get_object', fake_get_object)
|
||||
stubs.Set(swiftclient.client,
|
||||
'get_auth', fake_get_auth)
|
||||
stubs.Set(swiftclient.client,
|
||||
'http_connection', fake_http_connection)
|
||||
|
||||
|
||||
class SwiftTests(object):
|
||||
|
||||
def mock_keystone_client(self):
|
||||
|
@ -242,6 +74,174 @@ class SwiftTests(object):
|
|||
swift.ks_session = mock.MagicMock()
|
||||
swift.ks_client = mock.MagicMock()
|
||||
|
||||
def stub_out_swiftclient(self, swift_store_auth_version):
|
||||
fixture_containers = ['glance']
|
||||
fixture_container_headers = {}
|
||||
fixture_headers = {
|
||||
'glance/%s' % FAKE_UUID: {
|
||||
'content-length': FIVE_KB,
|
||||
'etag': 'c2e5db72bd7fd153f53ede5da5a06de3'
|
||||
},
|
||||
'glance/%s' % FAKE_UUID2: {'x-static-large-object': 'true', },
|
||||
}
|
||||
fixture_objects = {
|
||||
'glance/%s' % FAKE_UUID: six.BytesIO(b"*" * FIVE_KB),
|
||||
'glance/%s' % FAKE_UUID2: six.BytesIO(b"*" * FIVE_KB),
|
||||
}
|
||||
|
||||
def fake_head_container(url, token, container, **kwargs):
|
||||
if container not in fixture_containers:
|
||||
msg = "No container %s found" % container
|
||||
status = http_client.NOT_FOUND
|
||||
raise swiftclient.ClientException(msg, http_status=status)
|
||||
return fixture_container_headers
|
||||
|
||||
def fake_put_container(url, token, container, **kwargs):
|
||||
fixture_containers.append(container)
|
||||
|
||||
def fake_post_container(url, token, container, headers, **kwargs):
|
||||
for key, value in headers.items():
|
||||
fixture_container_headers[key] = value
|
||||
|
||||
def fake_put_object(url, token, container, name, contents, **kwargs):
|
||||
# PUT returns the ETag header for the newly-added object
|
||||
# Large object manifest...
|
||||
global SWIFT_PUT_OBJECT_CALLS
|
||||
SWIFT_PUT_OBJECT_CALLS += 1
|
||||
CHUNKSIZE = 64 * units.Ki
|
||||
fixture_key = "%s/%s" % (container, name)
|
||||
if fixture_key not in fixture_headers:
|
||||
if kwargs.get('headers'):
|
||||
etag = kwargs['headers']['ETag']
|
||||
manifest = kwargs.get('headers').get('X-Object-Manifest')
|
||||
fixture_headers[fixture_key] = {
|
||||
'manifest': True,
|
||||
'etag': etag,
|
||||
'x-object-manifest': manifest
|
||||
}
|
||||
fixture_objects[fixture_key] = None
|
||||
return etag
|
||||
if hasattr(contents, 'read'):
|
||||
fixture_object = six.BytesIO()
|
||||
read_len = 0
|
||||
chunk = contents.read(CHUNKSIZE)
|
||||
checksum = hashlib.md5()
|
||||
while chunk:
|
||||
fixture_object.write(chunk)
|
||||
read_len += len(chunk)
|
||||
checksum.update(chunk)
|
||||
chunk = contents.read(CHUNKSIZE)
|
||||
etag = checksum.hexdigest()
|
||||
else:
|
||||
fixture_object = six.BytesIO(contents)
|
||||
read_len = len(contents)
|
||||
etag = hashlib.md5(fixture_object.getvalue()).hexdigest()
|
||||
if read_len > MAX_SWIFT_OBJECT_SIZE:
|
||||
msg = ('Image size:%d exceeds Swift max:%d' %
|
||||
(read_len, MAX_SWIFT_OBJECT_SIZE))
|
||||
raise swiftclient.ClientException(
|
||||
msg, http_status=http_client.REQUEST_ENTITY_TOO_LARGE)
|
||||
fixture_objects[fixture_key] = fixture_object
|
||||
fixture_headers[fixture_key] = {
|
||||
'content-length': read_len,
|
||||
'etag': etag}
|
||||
return etag
|
||||
else:
|
||||
msg = ("Object PUT failed - Object with key %s already exists"
|
||||
% fixture_key)
|
||||
raise swiftclient.ClientException(
|
||||
msg, http_status=http_client.CONFLICT)
|
||||
|
||||
def fake_get_object(conn, container, name, **kwargs):
|
||||
# GET returns the tuple (list of headers, file object)
|
||||
fixture_key = "%s/%s" % (container, name)
|
||||
if fixture_key not in fixture_headers:
|
||||
msg = "Object GET failed"
|
||||
status = http_client.NOT_FOUND
|
||||
raise swiftclient.ClientException(msg, http_status=status)
|
||||
|
||||
byte_range = None
|
||||
headers = kwargs.get('headers', dict())
|
||||
if headers is not None:
|
||||
headers = dict((k.lower(), v) for k, v in headers.items())
|
||||
if 'range' in headers:
|
||||
byte_range = headers.get('range')
|
||||
|
||||
fixture = fixture_headers[fixture_key]
|
||||
if 'manifest' in fixture:
|
||||
# Large object manifest... we return a file containing
|
||||
# all objects with prefix of this fixture key
|
||||
chunk_keys = sorted([k for k in fixture_headers.keys()
|
||||
if k.startswith(fixture_key) and
|
||||
k != fixture_key])
|
||||
result = six.BytesIO()
|
||||
for key in chunk_keys:
|
||||
result.write(fixture_objects[key].getvalue())
|
||||
else:
|
||||
result = fixture_objects[fixture_key]
|
||||
|
||||
if byte_range is not None:
|
||||
start = int(byte_range.split('=')[1].strip('-'))
|
||||
result = six.BytesIO(result.getvalue()[start:])
|
||||
fixture_headers[fixture_key]['content-length'] = len(
|
||||
result.getvalue())
|
||||
|
||||
return fixture_headers[fixture_key], result
|
||||
|
||||
def fake_head_object(url, token, container, name, **kwargs):
|
||||
# HEAD returns the list of headers for an object
|
||||
try:
|
||||
fixture_key = "%s/%s" % (container, name)
|
||||
return fixture_headers[fixture_key]
|
||||
except KeyError:
|
||||
msg = "Object HEAD failed - Object does not exist"
|
||||
status = http_client.NOT_FOUND
|
||||
raise swiftclient.ClientException(msg, http_status=status)
|
||||
|
||||
def fake_delete_object(url, token, container, name, **kwargs):
|
||||
# DELETE returns nothing
|
||||
fixture_key = "%s/%s" % (container, name)
|
||||
if fixture_key not in fixture_headers:
|
||||
msg = "Object DELETE failed - Object does not exist"
|
||||
status = http_client.NOT_FOUND
|
||||
raise swiftclient.ClientException(msg, http_status=status)
|
||||
else:
|
||||
del fixture_headers[fixture_key]
|
||||
del fixture_objects[fixture_key]
|
||||
|
||||
def fake_http_connection(*args, **kwargs):
|
||||
return None
|
||||
|
||||
def fake_get_auth(url, user, key, auth_version, **kwargs):
|
||||
if url is None:
|
||||
return None, None
|
||||
if 'http' in url and '://' not in url:
|
||||
raise ValueError('Invalid url %s' % url)
|
||||
# Check the auth version against the configured value
|
||||
if swift_store_auth_version != auth_version:
|
||||
msg = 'AUTHENTICATION failed (version mismatch)'
|
||||
raise swiftclient.ClientException(msg)
|
||||
return None, None
|
||||
|
||||
self.useFixture(fixtures.MockPatch(
|
||||
'swiftclient.client.head_container', fake_head_container))
|
||||
self.useFixture(fixtures.MockPatch(
|
||||
'swiftclient.client.put_container', fake_put_container))
|
||||
self.useFixture(fixtures.MockPatch(
|
||||
'swiftclient.client.post_container', fake_post_container))
|
||||
self.useFixture(fixtures.MockPatch(
|
||||
'swiftclient.client.put_object', fake_put_object))
|
||||
self.useFixture(fixtures.MockPatch(
|
||||
'swiftclient.client.delete_object', fake_delete_object))
|
||||
self.useFixture(fixtures.MockPatch(
|
||||
'swiftclient.client.head_object', fake_head_object))
|
||||
self.useFixture(fixtures.MockPatch(
|
||||
'swiftclient.client.Connection.get_object', fake_get_object))
|
||||
self.useFixture(fixtures.MockPatch(
|
||||
'swiftclient.client.get_auth', fake_get_auth))
|
||||
self.useFixture(fixtures.MockPatch(
|
||||
'swiftclient.client.http_connection', fake_http_connection))
|
||||
|
||||
@property
|
||||
def swift_store_user(self):
|
||||
return 'tenant:user1'
|
||||
|
@ -1335,9 +1335,7 @@ class TestStoreAuthV1(base.StoreBaseTest, SwiftTests,
|
|||
self.swift_config_file = self.copy_data_file(conf_file, self.test_dir)
|
||||
conf.update({'swift_store_config_file': self.swift_config_file})
|
||||
|
||||
moxfixture = self.useFixture(moxstubout.MoxStubout())
|
||||
self.stubs = moxfixture.stubs
|
||||
stub_out_swiftclient(self.stubs, conf['swift_store_auth_version'])
|
||||
self.stub_out_swiftclient(conf['swift_store_auth_version'])
|
||||
self.mock_keystone_client()
|
||||
self.store = Store(self.conf)
|
||||
self.config(**conf)
|
||||
|
@ -1433,9 +1431,8 @@ class TestSingleTenantStoreConnections(base.StoreBaseTest):
|
|||
|
||||
def setUp(self):
|
||||
super(TestSingleTenantStoreConnections, self).setUp()
|
||||
moxfixture = self.useFixture(moxstubout.MoxStubout())
|
||||
self.stubs = moxfixture.stubs
|
||||
self.stubs.Set(swiftclient, 'Connection', FakeConnection)
|
||||
self.useFixture(
|
||||
fixtures.MockPatch('swiftclient.Connection', FakeConnection))
|
||||
self.store = swift.SingleTenantStore(self.conf)
|
||||
self.store.configure()
|
||||
specs = {'scheme': 'swift',
|
||||
|
@ -1619,9 +1616,8 @@ class TestSingleTenantStoreConnections(base.StoreBaseTest):
|
|||
class TestMultiTenantStoreConnections(base.StoreBaseTest):
|
||||
def setUp(self):
|
||||
super(TestMultiTenantStoreConnections, self).setUp()
|
||||
moxfixture = self.useFixture(moxstubout.MoxStubout())
|
||||
self.stubs = moxfixture.stubs
|
||||
self.stubs.Set(swiftclient, 'Connection', FakeConnection)
|
||||
self.useFixture(
|
||||
fixtures.MockPatch('swiftclient.Connection', FakeConnection))
|
||||
self.context = mock.MagicMock(
|
||||
user='tenant:user1', tenant='tenant', auth_token='0123')
|
||||
self.store = swift.MultiTenantStore(self.conf)
|
||||
|
@ -1767,8 +1763,6 @@ class TestCreatingLocations(base.StoreBaseTest):
|
|||
|
||||
def setUp(self):
|
||||
super(TestCreatingLocations, self).setUp()
|
||||
moxfixture = self.useFixture(moxstubout.MoxStubout())
|
||||
self.stubs = moxfixture.stubs
|
||||
conf = copy.deepcopy(SWIFT_CONF)
|
||||
self.store = Store(self.conf)
|
||||
self.config(**conf)
|
||||
|
|
|
@ -25,7 +25,6 @@ import uuid
|
|||
from oslo_config import cfg
|
||||
from oslo_utils import encodeutils
|
||||
from oslo_utils import units
|
||||
from oslotest import moxstubout
|
||||
import requests_mock
|
||||
import six
|
||||
from six import moves
|
||||
|
@ -64,174 +63,6 @@ SWIFT_CONF = {'swift_store_auth_address': 'localhost:8080',
|
|||
}
|
||||
|
||||
|
||||
# We stub out as little as possible to ensure that the code paths
|
||||
# between swift and swiftclient are tested
|
||||
# thoroughly
|
||||
def stub_out_swiftclient(stubs, swift_store_auth_version):
|
||||
fixture_containers = ['glance']
|
||||
fixture_container_headers = {}
|
||||
fixture_headers = {
|
||||
'glance/%s' % FAKE_UUID: {
|
||||
'content-length': FIVE_KB,
|
||||
'etag': 'c2e5db72bd7fd153f53ede5da5a06de3'
|
||||
},
|
||||
'glance/%s' % FAKE_UUID2: {'x-static-large-object': 'true', },
|
||||
}
|
||||
fixture_objects = {'glance/%s' % FAKE_UUID: six.BytesIO(b"*" * FIVE_KB),
|
||||
'glance/%s' % FAKE_UUID2: six.BytesIO(b"*" * FIVE_KB), }
|
||||
|
||||
def fake_head_container(url, token, container, **kwargs):
|
||||
if container not in fixture_containers:
|
||||
msg = "No container %s found" % container
|
||||
status = http_client.NOT_FOUND
|
||||
raise swiftclient.ClientException(msg, http_status=status)
|
||||
return fixture_container_headers
|
||||
|
||||
def fake_put_container(url, token, container, **kwargs):
|
||||
fixture_containers.append(container)
|
||||
|
||||
def fake_post_container(url, token, container, headers, **kwargs):
|
||||
for key, value in headers.items():
|
||||
fixture_container_headers[key] = value
|
||||
|
||||
def fake_put_object(url, token, container, name, contents, **kwargs):
|
||||
# PUT returns the ETag header for the newly-added object
|
||||
# Large object manifest...
|
||||
global SWIFT_PUT_OBJECT_CALLS
|
||||
SWIFT_PUT_OBJECT_CALLS += 1
|
||||
CHUNKSIZE = 64 * units.Ki
|
||||
fixture_key = "%s/%s" % (container, name)
|
||||
if fixture_key not in fixture_headers:
|
||||
if kwargs.get('headers'):
|
||||
etag = kwargs['headers']['ETag']
|
||||
manifest = kwargs.get('headers').get('X-Object-Manifest')
|
||||
fixture_headers[fixture_key] = {'manifest': True,
|
||||
'etag': etag,
|
||||
'x-object-manifest': manifest}
|
||||
fixture_objects[fixture_key] = None
|
||||
return etag
|
||||
if hasattr(contents, 'read'):
|
||||
fixture_object = six.BytesIO()
|
||||
read_len = 0
|
||||
chunk = contents.read(CHUNKSIZE)
|
||||
checksum = hashlib.md5()
|
||||
while chunk:
|
||||
fixture_object.write(chunk)
|
||||
read_len += len(chunk)
|
||||
checksum.update(chunk)
|
||||
chunk = contents.read(CHUNKSIZE)
|
||||
etag = checksum.hexdigest()
|
||||
else:
|
||||
fixture_object = six.BytesIO(contents)
|
||||
read_len = len(contents)
|
||||
etag = hashlib.md5(fixture_object.getvalue()).hexdigest()
|
||||
if read_len > MAX_SWIFT_OBJECT_SIZE:
|
||||
msg = ('Image size:%d exceeds Swift max:%d' %
|
||||
(read_len, MAX_SWIFT_OBJECT_SIZE))
|
||||
raise swiftclient.ClientException(
|
||||
msg, http_status=http_client.REQUEST_ENTITY_TOO_LARGE)
|
||||
fixture_objects[fixture_key] = fixture_object
|
||||
fixture_headers[fixture_key] = {
|
||||
'content-length': read_len,
|
||||
'etag': etag}
|
||||
return etag
|
||||
else:
|
||||
msg = ("Object PUT failed - Object with key %s already exists"
|
||||
% fixture_key)
|
||||
raise swiftclient.ClientException(msg,
|
||||
http_status=http_client.CONFLICT)
|
||||
|
||||
def fake_get_object(conn, container, name, **kwargs):
|
||||
# GET returns the tuple (list of headers, file object)
|
||||
fixture_key = "%s/%s" % (container, name)
|
||||
if fixture_key not in fixture_headers:
|
||||
msg = "Object GET failed"
|
||||
status = http_client.NOT_FOUND
|
||||
raise swiftclient.ClientException(msg, http_status=status)
|
||||
|
||||
byte_range = None
|
||||
headers = kwargs.get('headers', dict())
|
||||
if headers is not None:
|
||||
headers = dict((k.lower(), v) for k, v in headers.items())
|
||||
if 'range' in headers:
|
||||
byte_range = headers.get('range')
|
||||
|
||||
fixture = fixture_headers[fixture_key]
|
||||
if 'manifest' in fixture:
|
||||
# Large object manifest... we return a file containing
|
||||
# all objects with prefix of this fixture key
|
||||
chunk_keys = sorted([k for k in fixture_headers.keys()
|
||||
if k.startswith(fixture_key) and
|
||||
k != fixture_key])
|
||||
result = six.BytesIO()
|
||||
for key in chunk_keys:
|
||||
result.write(fixture_objects[key].getvalue())
|
||||
else:
|
||||
result = fixture_objects[fixture_key]
|
||||
|
||||
if byte_range is not None:
|
||||
start = int(byte_range.split('=')[1].strip('-'))
|
||||
result = six.BytesIO(result.getvalue()[start:])
|
||||
fixture_headers[fixture_key]['content-length'] = len(
|
||||
result.getvalue())
|
||||
|
||||
return fixture_headers[fixture_key], result
|
||||
|
||||
def fake_head_object(url, token, container, name, **kwargs):
|
||||
# HEAD returns the list of headers for an object
|
||||
try:
|
||||
fixture_key = "%s/%s" % (container, name)
|
||||
return fixture_headers[fixture_key]
|
||||
except KeyError:
|
||||
msg = "Object HEAD failed - Object does not exist"
|
||||
status = http_client.NOT_FOUND
|
||||
raise swiftclient.ClientException(msg, http_status=status)
|
||||
|
||||
def fake_delete_object(url, token, container, name, **kwargs):
|
||||
# DELETE returns nothing
|
||||
fixture_key = "%s/%s" % (container, name)
|
||||
if fixture_key not in fixture_headers:
|
||||
msg = "Object DELETE failed - Object does not exist"
|
||||
status = http_client.NOT_FOUND
|
||||
raise swiftclient.ClientException(msg, http_status=status)
|
||||
else:
|
||||
del fixture_headers[fixture_key]
|
||||
del fixture_objects[fixture_key]
|
||||
|
||||
def fake_http_connection(*args, **kwargs):
|
||||
return None
|
||||
|
||||
def fake_get_auth(url, user, key, auth_version, **kwargs):
|
||||
if url is None:
|
||||
return None, None
|
||||
if 'http' in url and '://' not in url:
|
||||
raise ValueError('Invalid url %s' % url)
|
||||
# Check the auth version against the configured value
|
||||
if swift_store_auth_version != auth_version:
|
||||
msg = 'AUTHENTICATION failed (version mismatch)'
|
||||
raise swiftclient.ClientException(msg)
|
||||
return None, None
|
||||
|
||||
stubs.Set(swiftclient.client,
|
||||
'head_container', fake_head_container)
|
||||
stubs.Set(swiftclient.client,
|
||||
'put_container', fake_put_container)
|
||||
stubs.Set(swiftclient.client,
|
||||
'post_container', fake_post_container)
|
||||
stubs.Set(swiftclient.client,
|
||||
'put_object', fake_put_object)
|
||||
stubs.Set(swiftclient.client,
|
||||
'delete_object', fake_delete_object)
|
||||
stubs.Set(swiftclient.client,
|
||||
'head_object', fake_head_object)
|
||||
stubs.Set(swiftclient.client.Connection,
|
||||
'get_object', fake_get_object)
|
||||
stubs.Set(swiftclient.client,
|
||||
'get_auth', fake_get_auth)
|
||||
stubs.Set(swiftclient.client,
|
||||
'http_connection', fake_http_connection)
|
||||
|
||||
|
||||
class SwiftTests(object):
|
||||
|
||||
def mock_keystone_client(self):
|
||||
|
@ -240,6 +71,174 @@ class SwiftTests(object):
|
|||
swift.ks_session = mock.MagicMock()
|
||||
swift.ks_client = mock.MagicMock()
|
||||
|
||||
def stub_out_swiftclient(self, swift_store_auth_version):
|
||||
fixture_containers = ['glance']
|
||||
fixture_container_headers = {}
|
||||
fixture_headers = {
|
||||
'glance/%s' % FAKE_UUID: {
|
||||
'content-length': FIVE_KB,
|
||||
'etag': 'c2e5db72bd7fd153f53ede5da5a06de3'
|
||||
},
|
||||
'glance/%s' % FAKE_UUID2: {'x-static-large-object': 'true', },
|
||||
}
|
||||
fixture_objects = {
|
||||
'glance/%s' % FAKE_UUID: six.BytesIO(b"*" * FIVE_KB),
|
||||
'glance/%s' % FAKE_UUID2: six.BytesIO(b"*" * FIVE_KB),
|
||||
}
|
||||
|
||||
def fake_head_container(url, token, container, **kwargs):
|
||||
if container not in fixture_containers:
|
||||
msg = "No container %s found" % container
|
||||
status = http_client.NOT_FOUND
|
||||
raise swiftclient.ClientException(msg, http_status=status)
|
||||
return fixture_container_headers
|
||||
|
||||
def fake_put_container(url, token, container, **kwargs):
|
||||
fixture_containers.append(container)
|
||||
|
||||
def fake_post_container(url, token, container, headers, **kwargs):
|
||||
for key, value in headers.items():
|
||||
fixture_container_headers[key] = value
|
||||
|
||||
def fake_put_object(url, token, container, name, contents, **kwargs):
|
||||
# PUT returns the ETag header for the newly-added object
|
||||
# Large object manifest...
|
||||
global SWIFT_PUT_OBJECT_CALLS
|
||||
SWIFT_PUT_OBJECT_CALLS += 1
|
||||
CHUNKSIZE = 64 * units.Ki
|
||||
fixture_key = "%s/%s" % (container, name)
|
||||
if fixture_key not in fixture_headers:
|
||||
if kwargs.get('headers'):
|
||||
etag = kwargs['headers']['ETag']
|
||||
manifest = kwargs.get('headers').get('X-Object-Manifest')
|
||||
fixture_headers[fixture_key] = {
|
||||
'manifest': True,
|
||||
'etag': etag,
|
||||
'x-object-manifest': manifest
|
||||
}
|
||||
fixture_objects[fixture_key] = None
|
||||
return etag
|
||||
if hasattr(contents, 'read'):
|
||||
fixture_object = six.BytesIO()
|
||||
read_len = 0
|
||||
chunk = contents.read(CHUNKSIZE)
|
||||
checksum = hashlib.md5()
|
||||
while chunk:
|
||||
fixture_object.write(chunk)
|
||||
read_len += len(chunk)
|
||||
checksum.update(chunk)
|
||||
chunk = contents.read(CHUNKSIZE)
|
||||
etag = checksum.hexdigest()
|
||||
else:
|
||||
fixture_object = six.BytesIO(contents)
|
||||
read_len = len(contents)
|
||||
etag = hashlib.md5(fixture_object.getvalue()).hexdigest()
|
||||
if read_len > MAX_SWIFT_OBJECT_SIZE:
|
||||
msg = ('Image size:%d exceeds Swift max:%d' %
|
||||
(read_len, MAX_SWIFT_OBJECT_SIZE))
|
||||
raise swiftclient.ClientException(
|
||||
msg, http_status=http_client.REQUEST_ENTITY_TOO_LARGE)
|
||||
fixture_objects[fixture_key] = fixture_object
|
||||
fixture_headers[fixture_key] = {
|
||||
'content-length': read_len,
|
||||
'etag': etag}
|
||||
return etag
|
||||
else:
|
||||
msg = ("Object PUT failed - Object with key %s already exists"
|
||||
% fixture_key)
|
||||
raise swiftclient.ClientException(
|
||||
msg, http_status=http_client.CONFLICT)
|
||||
|
||||
def fake_get_object(conn, container, name, **kwargs):
|
||||
# GET returns the tuple (list of headers, file object)
|
||||
fixture_key = "%s/%s" % (container, name)
|
||||
if fixture_key not in fixture_headers:
|
||||
msg = "Object GET failed"
|
||||
status = http_client.NOT_FOUND
|
||||
raise swiftclient.ClientException(msg, http_status=status)
|
||||
|
||||
byte_range = None
|
||||
headers = kwargs.get('headers', dict())
|
||||
if headers is not None:
|
||||
headers = dict((k.lower(), v) for k, v in headers.items())
|
||||
if 'range' in headers:
|
||||
byte_range = headers.get('range')
|
||||
|
||||
fixture = fixture_headers[fixture_key]
|
||||
if 'manifest' in fixture:
|
||||
# Large object manifest... we return a file containing
|
||||
# all objects with prefix of this fixture key
|
||||
chunk_keys = sorted([k for k in fixture_headers.keys()
|
||||
if k.startswith(fixture_key) and
|
||||
k != fixture_key])
|
||||
result = six.BytesIO()
|
||||
for key in chunk_keys:
|
||||
result.write(fixture_objects[key].getvalue())
|
||||
else:
|
||||
result = fixture_objects[fixture_key]
|
||||
|
||||
if byte_range is not None:
|
||||
start = int(byte_range.split('=')[1].strip('-'))
|
||||
result = six.BytesIO(result.getvalue()[start:])
|
||||
fixture_headers[fixture_key]['content-length'] = len(
|
||||
result.getvalue())
|
||||
|
||||
return fixture_headers[fixture_key], result
|
||||
|
||||
def fake_head_object(url, token, container, name, **kwargs):
|
||||
# HEAD returns the list of headers for an object
|
||||
try:
|
||||
fixture_key = "%s/%s" % (container, name)
|
||||
return fixture_headers[fixture_key]
|
||||
except KeyError:
|
||||
msg = "Object HEAD failed - Object does not exist"
|
||||
status = http_client.NOT_FOUND
|
||||
raise swiftclient.ClientException(msg, http_status=status)
|
||||
|
||||
def fake_delete_object(url, token, container, name, **kwargs):
|
||||
# DELETE returns nothing
|
||||
fixture_key = "%s/%s" % (container, name)
|
||||
if fixture_key not in fixture_headers:
|
||||
msg = "Object DELETE failed - Object does not exist"
|
||||
status = http_client.NOT_FOUND
|
||||
raise swiftclient.ClientException(msg, http_status=status)
|
||||
else:
|
||||
del fixture_headers[fixture_key]
|
||||
del fixture_objects[fixture_key]
|
||||
|
||||
def fake_http_connection(*args, **kwargs):
|
||||
return None
|
||||
|
||||
def fake_get_auth(url, user, key, auth_version, **kwargs):
|
||||
if url is None:
|
||||
return None, None
|
||||
if 'http' in url and '://' not in url:
|
||||
raise ValueError('Invalid url %s' % url)
|
||||
# Check the auth version against the configured value
|
||||
if swift_store_auth_version != auth_version:
|
||||
msg = 'AUTHENTICATION failed (version mismatch)'
|
||||
raise swiftclient.ClientException(msg)
|
||||
return None, None
|
||||
|
||||
self.useFixture(fixtures.MockPatch(
|
||||
'swiftclient.client.head_container', fake_head_container))
|
||||
self.useFixture(fixtures.MockPatch(
|
||||
'swiftclient.client.put_container', fake_put_container))
|
||||
self.useFixture(fixtures.MockPatch(
|
||||
'swiftclient.client.post_container', fake_post_container))
|
||||
self.useFixture(fixtures.MockPatch(
|
||||
'swiftclient.client.put_object', fake_put_object))
|
||||
self.useFixture(fixtures.MockPatch(
|
||||
'swiftclient.client.delete_object', fake_delete_object))
|
||||
self.useFixture(fixtures.MockPatch(
|
||||
'swiftclient.client.head_object', fake_head_object))
|
||||
self.useFixture(fixtures.MockPatch(
|
||||
'swiftclient.client.Connection.get_object', fake_get_object))
|
||||
self.useFixture(fixtures.MockPatch(
|
||||
'swiftclient.client.get_auth', fake_get_auth))
|
||||
self.useFixture(fixtures.MockPatch(
|
||||
'swiftclient.client.http_connection', fake_http_connection))
|
||||
|
||||
@property
|
||||
def swift_store_user(self):
|
||||
return 'tenant:user1'
|
||||
|
@ -1376,9 +1375,7 @@ class TestStoreAuthV1(base.MultiStoreBaseTest, SwiftTests,
|
|||
self.swift_config_file = self.copy_data_file(conf_file, self.test_dir)
|
||||
config.update({'swift_store_config_file': self.swift_config_file})
|
||||
|
||||
moxfixture = self.useFixture(moxstubout.MoxStubout())
|
||||
self.stubs = moxfixture.stubs
|
||||
stub_out_swiftclient(self.stubs, config['swift_store_auth_version'])
|
||||
self.stub_out_swiftclient(config['swift_store_auth_version'])
|
||||
self.mock_keystone_client()
|
||||
self.store = Store(self.conf, backend="swift1")
|
||||
self.config(group="swift1", **config)
|
||||
|
@ -1502,9 +1499,8 @@ class TestSingleTenantStoreConnections(base.MultiStoreBaseTest):
|
|||
dict())
|
||||
self.test_dir = self.useFixture(fixtures.TempDir()).path
|
||||
|
||||
moxfixture = self.useFixture(moxstubout.MoxStubout())
|
||||
self.stubs = moxfixture.stubs
|
||||
self.stubs.Set(swiftclient, 'Connection', FakeConnection)
|
||||
self.useFixture(fixtures.MockPatch(
|
||||
'swiftclient.Connection', FakeConnection))
|
||||
self.store = swift.SingleTenantStore(self.conf, backend="swift1")
|
||||
self.store.configure()
|
||||
specs = {'scheme': 'swift',
|
||||
|
@ -1717,9 +1713,8 @@ class TestMultiTenantStoreConnections(base.MultiStoreBaseTest):
|
|||
dict())
|
||||
self.test_dir = self.useFixture(fixtures.TempDir()).path
|
||||
|
||||
moxfixture = self.useFixture(moxstubout.MoxStubout())
|
||||
self.stubs = moxfixture.stubs
|
||||
self.stubs.Set(swiftclient, 'Connection', FakeConnection)
|
||||
self.useFixture(fixtures.MockPatch(
|
||||
'swiftclient.Connection', FakeConnection))
|
||||
self.context = mock.MagicMock(
|
||||
user='tenant:user1', tenant='tenant', auth_token='0123')
|
||||
self.store = swift.MultiTenantStore(self.conf, backend="swift1")
|
||||
|
@ -1913,8 +1908,6 @@ class TestCreatingLocations(base.MultiStoreBaseTest):
|
|||
dict())
|
||||
self.test_dir = self.useFixture(fixtures.TempDir()).path
|
||||
|
||||
moxfixture = self.useFixture(moxstubout.MoxStubout())
|
||||
self.stubs = moxfixture.stubs
|
||||
config = copy.deepcopy(SWIFT_CONF)
|
||||
self.store = Store(self.conf, backend="swift1")
|
||||
self.config(group="swift1", **config)
|
||||
|
|
Loading…
Reference in New Issue