Merge "Some functional tests for object versioning"
This commit is contained in:
commit
8426edced5
@ -40,7 +40,7 @@ class RequestError(Exception):
|
||||
|
||||
|
||||
class ResponseError(Exception):
|
||||
def __init__(self, response, method, path):
|
||||
def __init__(self, response, method=None, path=None):
|
||||
self.status = response.status
|
||||
self.reason = response.reason
|
||||
self.method = method
|
||||
@ -310,10 +310,11 @@ class Base:
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def header_fields(self, fields):
|
||||
def header_fields(self, required_fields, optional_fields=()):
|
||||
headers = dict(self.conn.response.getheaders())
|
||||
ret = {}
|
||||
for field in fields:
|
||||
|
||||
for field in required_fields:
|
||||
if field[1] not in headers:
|
||||
raise ValueError("%s was not found in response header" %
|
||||
(field[1]))
|
||||
@ -322,6 +323,15 @@ class Base:
|
||||
ret[field[0]] = int(headers[field[1]])
|
||||
except ValueError:
|
||||
ret[field[0]] = headers[field[1]]
|
||||
|
||||
for field in optional_fields:
|
||||
if field[1] not in headers:
|
||||
continue
|
||||
try:
|
||||
ret[field[0]] = int(headers[field[1]])
|
||||
except ValueError:
|
||||
ret[field[0]] = headers[field[1]]
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
@ -480,10 +490,11 @@ class Container(Base):
|
||||
parms=parms, cfg=cfg)
|
||||
|
||||
if self.conn.response.status == 204:
|
||||
fields = [['bytes_used', 'x-container-bytes-used'],
|
||||
['object_count', 'x-container-object-count']]
|
||||
required_fields = [['bytes_used', 'x-container-bytes-used'],
|
||||
['object_count', 'x-container-object-count']]
|
||||
optional_fields = [['versions', 'x-versions-location']]
|
||||
|
||||
return self.header_fields(fields)
|
||||
return self.header_fields(required_fields, optional_fields)
|
||||
|
||||
raise ResponseError(self.conn.response, 'HEAD',
|
||||
self.conn.make_path(self.path))
|
||||
|
@ -2001,5 +2001,84 @@ class TestSloUTF8(Base2, TestSlo):
|
||||
set_up = False
|
||||
|
||||
|
||||
class TestObjectVersioningEnv(object):
|
||||
versioning_enabled = None # tri-state: None initially, then True/False
|
||||
|
||||
@classmethod
|
||||
def setUp(cls):
|
||||
cls.conn = Connection(config)
|
||||
cls.conn.authenticate()
|
||||
|
||||
cls.account = Account(cls.conn, config.get('account',
|
||||
config['username']))
|
||||
|
||||
# avoid getting a prefix that stops halfway through an encoded
|
||||
# character
|
||||
prefix = Utils.create_name().decode("utf-8")[:10].encode("utf-8")
|
||||
|
||||
cls.versions_container = cls.account.container(prefix + "-versions")
|
||||
if not cls.versions_container.create():
|
||||
raise ResponseError(cls.conn.response)
|
||||
|
||||
cls.container = cls.account.container(prefix + "-objs")
|
||||
if not cls.container.create(
|
||||
hdrs={'X-Versions-Location': cls.versions_container.name}):
|
||||
raise ResponseError(cls.conn.response)
|
||||
|
||||
container_info = cls.container.info()
|
||||
# if versioning is off, then X-Versions-Location won't persist
|
||||
cls.versioning_enabled = 'versions' in container_info
|
||||
|
||||
|
||||
class TestObjectVersioning(Base):
|
||||
env = TestObjectVersioningEnv
|
||||
set_up = False
|
||||
|
||||
def setUp(self):
|
||||
super(TestObjectVersioning, self).setUp()
|
||||
if self.env.versioning_enabled is False:
|
||||
raise SkipTest("Object versioning not enabled")
|
||||
elif self.env.versioning_enabled is not True:
|
||||
# just some sanity checking
|
||||
raise Exception(
|
||||
"Expected versioning_enabled to be True/False, got %r" %
|
||||
(self.env.versioning_enabled,))
|
||||
|
||||
def test_overwriting(self):
|
||||
container = self.env.container
|
||||
versions_container = self.env.versions_container
|
||||
obj_name = Utils.create_name()
|
||||
|
||||
versioned_obj = container.file(obj_name)
|
||||
versioned_obj.write("aaaaa")
|
||||
|
||||
self.assertEqual(0, versions_container.info()['object_count'])
|
||||
|
||||
versioned_obj.write("bbbbb")
|
||||
|
||||
# the old version got saved off
|
||||
self.assertEqual(1, versions_container.info()['object_count'])
|
||||
versioned_obj_name = versions_container.files()[0]
|
||||
self.assertEqual(
|
||||
"aaaaa", versions_container.file(versioned_obj_name).read())
|
||||
|
||||
# if we overwrite it again, there are two versions
|
||||
versioned_obj.write("ccccc")
|
||||
self.assertEqual(2, versions_container.info()['object_count'])
|
||||
|
||||
# as we delete things, the old contents return
|
||||
self.assertEqual("ccccc", versioned_obj.read())
|
||||
versioned_obj.delete()
|
||||
self.assertEqual("bbbbb", versioned_obj.read())
|
||||
versioned_obj.delete()
|
||||
self.assertEqual("aaaaa", versioned_obj.read())
|
||||
versioned_obj.delete()
|
||||
self.assertRaises(ResponseError, versioned_obj.read)
|
||||
|
||||
|
||||
class TestObjectVersioningUTF8(Base2, TestObjectVersioning):
|
||||
set_up = False
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
Loading…
x
Reference in New Issue
Block a user