Use a named enum for capability values
In Iedf0d4f829e46ca64c3f4fc6a7dfee54d9b0605b we added support for driver capabilities in glance_store. That same change also used (mutable) module globals to check driver capabilities. By moving the capability definitions inside a subclass of IntEnum we retain all of the previous functionality with the guarantee that the enum values will not change once defined. Change-Id: I13c7bd507252e793b2c790cc9b77c7b8db432d02
This commit is contained in:
parent
138875b7c3
commit
ac9bd0d83a
@ -131,7 +131,7 @@ class Store(glance_store.driver.Store):
|
|||||||
|
|
||||||
"""Cinder backend store adapter."""
|
"""Cinder backend store adapter."""
|
||||||
|
|
||||||
_CAPABILITIES = capabilities.DRIVER_REUSABLE
|
_CAPABILITIES = capabilities.BitMasks.DRIVER_REUSABLE
|
||||||
OPTIONS = _CINDER_OPTS
|
OPTIONS = _CINDER_OPTS
|
||||||
EXAMPLE_URL = "cinder://<VOLUME_ID>"
|
EXAMPLE_URL = "cinder://<VOLUME_ID>"
|
||||||
|
|
||||||
|
@ -149,9 +149,9 @@ class ChunkedFile(object):
|
|||||||
|
|
||||||
class Store(glance_store.driver.Store):
|
class Store(glance_store.driver.Store):
|
||||||
|
|
||||||
_CAPABILITIES = (capabilities.READ_RANDOM |
|
_CAPABILITIES = (capabilities.BitMasks.READ_RANDOM |
|
||||||
capabilities.WRITE_ACCESS |
|
capabilities.BitMasks.WRITE_ACCESS |
|
||||||
capabilities.DRIVER_REUSABLE)
|
capabilities.BitMasks.DRIVER_REUSABLE)
|
||||||
OPTIONS = _FILESYSTEM_CONFIGS
|
OPTIONS = _FILESYSTEM_CONFIGS
|
||||||
READ_CHUNKSIZE = 64 * units.Ki
|
READ_CHUNKSIZE = 64 * units.Ki
|
||||||
WRITE_CHUNKSIZE = READ_CHUNKSIZE
|
WRITE_CHUNKSIZE = READ_CHUNKSIZE
|
||||||
|
@ -81,7 +81,7 @@ class StoreLocation(glance_store.location.StoreLocation):
|
|||||||
class Store(glance_store.driver.Store):
|
class Store(glance_store.driver.Store):
|
||||||
"""GridFS adapter"""
|
"""GridFS adapter"""
|
||||||
|
|
||||||
_CAPABILITIES = capabilities.RW_ACCESS
|
_CAPABILITIES = capabilities.BitMasks.RW_ACCESS
|
||||||
OPTIONS = _GRIDFS_OPTS
|
OPTIONS = _GRIDFS_OPTS
|
||||||
EXAMPLE_URL = "gridfs://<IMAGE_ID>"
|
EXAMPLE_URL = "gridfs://<IMAGE_ID>"
|
||||||
|
|
||||||
|
@ -112,8 +112,8 @@ class Store(glance_store.driver.Store):
|
|||||||
|
|
||||||
"""An implementation of the HTTP(S) Backend Adapter"""
|
"""An implementation of the HTTP(S) Backend Adapter"""
|
||||||
|
|
||||||
_CAPABILITIES = (capabilities.READ_ACCESS |
|
_CAPABILITIES = (capabilities.BitMasks.READ_ACCESS |
|
||||||
capabilities.DRIVER_REUSABLE)
|
capabilities.BitMasks.DRIVER_REUSABLE)
|
||||||
|
|
||||||
@capabilities.check
|
@capabilities.check
|
||||||
def get(self, location, offset=0, chunk_size=None, context=None):
|
def get(self, location, offset=0, chunk_size=None, context=None):
|
||||||
|
@ -176,7 +176,7 @@ class ImageIterator(object):
|
|||||||
class Store(driver.Store):
|
class Store(driver.Store):
|
||||||
"""An implementation of the RBD backend adapter."""
|
"""An implementation of the RBD backend adapter."""
|
||||||
|
|
||||||
_CAPABILITIES = capabilities.RW_ACCESS
|
_CAPABILITIES = capabilities.BitMasks.RW_ACCESS
|
||||||
OPTIONS = _RBD_OPTS
|
OPTIONS = _RBD_OPTS
|
||||||
|
|
||||||
EXAMPLE_URL = "rbd://<FSID>/<POOL>/<IMAGE>/<SNAP>"
|
EXAMPLE_URL = "rbd://<FSID>/<POOL>/<IMAGE>/<SNAP>"
|
||||||
|
@ -294,7 +294,7 @@ class ChunkedFile(object):
|
|||||||
class Store(glance_store.driver.Store):
|
class Store(glance_store.driver.Store):
|
||||||
"""An implementation of the s3 adapter."""
|
"""An implementation of the s3 adapter."""
|
||||||
|
|
||||||
_CAPABILITIES = capabilities.RW_ACCESS
|
_CAPABILITIES = capabilities.BitMasks.RW_ACCESS
|
||||||
OPTIONS = _S3_OPTS
|
OPTIONS = _S3_OPTS
|
||||||
EXAMPLE_URL = "s3://<ACCESS_KEY>:<SECRET_KEY>@<S3_URL>/<BUCKET>/<OBJ>"
|
EXAMPLE_URL = "s3://<ACCESS_KEY>:<SECRET_KEY>@<S3_URL>/<BUCKET>/<OBJ>"
|
||||||
|
|
||||||
|
@ -174,7 +174,8 @@ class ImageIterator(object):
|
|||||||
class Store(glance_store.driver.Store):
|
class Store(glance_store.driver.Store):
|
||||||
"""Sheepdog backend adapter."""
|
"""Sheepdog backend adapter."""
|
||||||
|
|
||||||
_CAPABILITIES = (capabilities.RW_ACCESS | capabilities.DRIVER_REUSABLE)
|
_CAPABILITIES = (capabilities.BitMasks.RW_ACCESS |
|
||||||
|
capabilities.BitMasks.DRIVER_REUSABLE)
|
||||||
OPTIONS = _SHEEPDOG_OPTS
|
OPTIONS = _SHEEPDOG_OPTS
|
||||||
EXAMPLE_URL = "sheepdog://image"
|
EXAMPLE_URL = "sheepdog://image"
|
||||||
|
|
||||||
|
@ -375,7 +375,7 @@ Store.OPTIONS = _SWIFT_OPTS + sutils.swift_opts
|
|||||||
|
|
||||||
class BaseStore(driver.Store):
|
class BaseStore(driver.Store):
|
||||||
|
|
||||||
_CAPABILITIES = capabilities.RW_ACCESS
|
_CAPABILITIES = capabilities.BitMasks.RW_ACCESS
|
||||||
CHUNKSIZE = 65536
|
CHUNKSIZE = 65536
|
||||||
OPTIONS = _SWIFT_OPTS + sutils.swift_opts
|
OPTIONS = _SWIFT_OPTS + sutils.swift_opts
|
||||||
|
|
||||||
|
@ -221,7 +221,7 @@ class StoreLocation(location.StoreLocation):
|
|||||||
class Store(glance_store.Store):
|
class Store(glance_store.Store):
|
||||||
"""An implementation of the VMware datastore adapter."""
|
"""An implementation of the VMware datastore adapter."""
|
||||||
|
|
||||||
_CAPABILITIES = capabilities.RW_ACCESS
|
_CAPABILITIES = capabilities.BitMasks.RW_ACCESS
|
||||||
OPTIONS = _VMWARE_OPTS
|
OPTIONS = _VMWARE_OPTS
|
||||||
WRITE_CHUNKSIZE = units.Mi
|
WRITE_CHUNKSIZE = units.Mi
|
||||||
# FIXME(arnaud): re-visit this code once the store API is cleaned up.
|
# FIXME(arnaud): re-visit this code once the store API is cleaned up.
|
||||||
|
@ -231,7 +231,7 @@ def get_store_from_scheme(scheme):
|
|||||||
raise exceptions.UnknownScheme(scheme=scheme)
|
raise exceptions.UnknownScheme(scheme=scheme)
|
||||||
scheme_info = location.SCHEME_TO_CLS_MAP[scheme]
|
scheme_info = location.SCHEME_TO_CLS_MAP[scheme]
|
||||||
store = scheme_info['store']
|
store = scheme_info['store']
|
||||||
if not store.is_capable(capabilities.DRIVER_REUSABLE):
|
if not store.is_capable(capabilities.BitMasks.DRIVER_REUSABLE):
|
||||||
# Driver instance isn't stateless so it can't
|
# Driver instance isn't stateless so it can't
|
||||||
# be reused safely and need recreation.
|
# be reused safely and need recreation.
|
||||||
store_entry = scheme_info['store_entry']
|
store_entry = scheme_info['store_entry']
|
||||||
|
@ -19,6 +19,7 @@ import logging
|
|||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
import enum
|
||||||
from eventlet import tpool
|
from eventlet import tpool
|
||||||
|
|
||||||
from glance_store import exceptions
|
from glance_store import exceptions
|
||||||
@ -29,22 +30,34 @@ _STORE_CAPABILITES_UPDATE_SCHEDULING_BOOK = {}
|
|||||||
_STORE_CAPABILITES_UPDATE_SCHEDULING_LOCK = threading.Lock()
|
_STORE_CAPABILITES_UPDATE_SCHEDULING_LOCK = threading.Lock()
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
# Store capability constants
|
|
||||||
|
class BitMasks(enum.IntEnum):
|
||||||
NONE = 0b00000000
|
NONE = 0b00000000
|
||||||
ALL = 0b11111111
|
ALL = 0b11111111
|
||||||
READ_ACCESS = 0b00000001
|
READ_ACCESS = 0b00000001
|
||||||
READ_OFFSET = 0b00000011 # Included READ_ACCESS
|
# Included READ_ACCESS
|
||||||
READ_CHUNK = 0b00000101 # Included READ_ACCESS
|
READ_OFFSET = 0b00000011
|
||||||
READ_RANDOM = 0b00000111 # READ_OFFSET | READ_CHUNK
|
# Included READ_ACCESS
|
||||||
|
READ_CHUNK = 0b00000101
|
||||||
|
# READ_OFFSET | READ_CHUNK
|
||||||
|
READ_RANDOM = 0b00000111
|
||||||
WRITE_ACCESS = 0b00001000
|
WRITE_ACCESS = 0b00001000
|
||||||
WRITE_OFFSET = 0b00011000 # Included WRITE_ACCESS
|
# Included WRITE_ACCESS
|
||||||
WRITE_CHUNK = 0b00101000 # Included WRITE_ACCESS
|
WRITE_OFFSET = 0b00011000
|
||||||
WRITE_RANDOM = 0b00111000 # WRITE_OFFSET | WRITE_CHUNK
|
# Included WRITE_ACCESS
|
||||||
RW_ACCESS = 0b00001001 # READ_ACCESS | WRITE_ACCESS
|
WRITE_CHUNK = 0b00101000
|
||||||
RW_OFFSET = 0b00011011 # READ_OFFSET | WRITE_OFFSET
|
# WRITE_OFFSET | WRITE_CHUNK
|
||||||
RW_CHUNK = 0b00101101 # READ_CHUNK | WRITE_CHUNK
|
WRITE_RANDOM = 0b00111000
|
||||||
RW_RANDOM = 0b00111111 # RW_OFFSET | RW_CHUNK
|
# READ_ACCESS | WRITE_ACCESS
|
||||||
DRIVER_REUSABLE = 0b01000000 # driver is stateless and can be reused safely
|
RW_ACCESS = 0b00001001
|
||||||
|
# READ_OFFSET | WRITE_OFFSET
|
||||||
|
RW_OFFSET = 0b00011011
|
||||||
|
# READ_CHUNK | WRITE_CHUNK
|
||||||
|
RW_CHUNK = 0b00101101
|
||||||
|
# RW_OFFSET | RW_CHUNK
|
||||||
|
RW_RANDOM = 0b00111111
|
||||||
|
# driver is stateless and can be reused safely
|
||||||
|
DRIVER_REUSABLE = 0b01000000
|
||||||
|
|
||||||
|
|
||||||
class StoreCapability(object):
|
class StoreCapability(object):
|
||||||
@ -178,12 +191,16 @@ def check(store_op_fun):
|
|||||||
if store.conf.glance_store.store_capabilities_update_min_interval > 0:
|
if store.conf.glance_store.store_capabilities_update_min_interval > 0:
|
||||||
_schedule_capabilities_update(store)
|
_schedule_capabilities_update(store)
|
||||||
|
|
||||||
|
get_capabilities = [
|
||||||
|
BitMasks.READ_ACCESS,
|
||||||
|
BitMasks.READ_OFFSET if kwargs.get('offset') else BitMasks.NONE,
|
||||||
|
BitMasks.READ_CHUNK if kwargs.get('chunk_size') else BitMasks.NONE
|
||||||
|
]
|
||||||
|
|
||||||
op_cap_map = {
|
op_cap_map = {
|
||||||
'get': [READ_ACCESS,
|
'get': get_capabilities,
|
||||||
READ_OFFSET if kwargs.get('offset') else NONE,
|
'add': [BitMasks.WRITE_ACCESS],
|
||||||
READ_CHUNK if kwargs.get('chunk_size') else NONE],
|
'delete': [BitMasks.WRITE_ACCESS]}
|
||||||
'add': [WRITE_ACCESS],
|
|
||||||
'delete': [WRITE_ACCESS]}
|
|
||||||
|
|
||||||
op_exec_map = {
|
op_exec_map = {
|
||||||
'get': (exceptions.StoreRandomGetNotSupported
|
'get': (exceptions.StoreRandomGetNotSupported
|
||||||
|
@ -70,7 +70,7 @@ class Store(capabilities.StoreCapability):
|
|||||||
try:
|
try:
|
||||||
self.configure_add()
|
self.configure_add()
|
||||||
except exceptions.BadStoreConfiguration as e:
|
except exceptions.BadStoreConfiguration as e:
|
||||||
self.unset_capabilities(capabilities.WRITE_ACCESS)
|
self.unset_capabilities(capabilities.BitMasks.WRITE_ACCESS)
|
||||||
msg = (_(u"Failed to configure store correctly: %s "
|
msg = (_(u"Failed to configure store correctly: %s "
|
||||||
"Disabling add method.") % utils.exception_to_str(e))
|
"Disabling add method.") % utils.exception_to_str(e))
|
||||||
LOG.warn(msg)
|
LOG.warn(msg)
|
||||||
|
@ -4,6 +4,7 @@ oslo.serialization>=1.0.0 # Apache-2.0
|
|||||||
oslo.utils>=1.2.0 # Apache-2.0
|
oslo.utils>=1.2.0 # Apache-2.0
|
||||||
oslo.concurrency>=1.4.1 # Apache-2.0
|
oslo.concurrency>=1.4.1 # Apache-2.0
|
||||||
stevedore>=0.12
|
stevedore>=0.12
|
||||||
|
enum34
|
||||||
|
|
||||||
python-cinderclient>=1.0.6
|
python-cinderclient>=1.0.6
|
||||||
|
|
||||||
|
@ -489,7 +489,8 @@ class TestStore(base.StoreBaseTest,
|
|||||||
self.config(**conf)
|
self.config(**conf)
|
||||||
self.store = s3.Store(self.conf)
|
self.store = s3.Store(self.conf)
|
||||||
self.store.configure()
|
self.store.configure()
|
||||||
return not self.store.is_capable(capabilities.WRITE_ACCESS)
|
return not self.store.is_capable(
|
||||||
|
capabilities.BitMasks.WRITE_ACCESS)
|
||||||
except Exception:
|
except Exception:
|
||||||
return False
|
return False
|
||||||
return False
|
return False
|
||||||
|
@ -19,23 +19,24 @@ from glance_store.tests import base
|
|||||||
|
|
||||||
|
|
||||||
class FakeStoreWithStaticCapabilities(caps.StoreCapability):
|
class FakeStoreWithStaticCapabilities(caps.StoreCapability):
|
||||||
_CAPABILITIES = caps.READ_RANDOM | caps.DRIVER_REUSABLE
|
_CAPABILITIES = caps.BitMasks.READ_RANDOM | caps.BitMasks.DRIVER_REUSABLE
|
||||||
|
|
||||||
|
|
||||||
class FakeStoreWithDynamicCapabilities(caps.StoreCapability):
|
class FakeStoreWithDynamicCapabilities(caps.StoreCapability):
|
||||||
def __init__(self, *cap_list):
|
def __init__(self, *cap_list):
|
||||||
super(FakeStoreWithDynamicCapabilities, self).__init__()
|
super(FakeStoreWithDynamicCapabilities, self).__init__()
|
||||||
if not cap_list:
|
if not cap_list:
|
||||||
cap_list = [caps.READ_RANDOM, caps.DRIVER_REUSABLE]
|
cap_list = [caps.BitMasks.READ_RANDOM,
|
||||||
|
caps.BitMasks.DRIVER_REUSABLE]
|
||||||
self.set_capabilities(*cap_list)
|
self.set_capabilities(*cap_list)
|
||||||
|
|
||||||
|
|
||||||
class FakeStoreWithMixedCapabilities(caps.StoreCapability):
|
class FakeStoreWithMixedCapabilities(caps.StoreCapability):
|
||||||
_CAPABILITIES = caps.READ_RANDOM
|
_CAPABILITIES = caps.BitMasks.READ_RANDOM
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(FakeStoreWithMixedCapabilities, self).__init__()
|
super(FakeStoreWithMixedCapabilities, self).__init__()
|
||||||
self.set_capabilities(caps.DRIVER_REUSABLE)
|
self.set_capabilities(caps.BitMasks.DRIVER_REUSABLE)
|
||||||
|
|
||||||
|
|
||||||
class TestStoreCapabilitiesChecking(object):
|
class TestStoreCapabilitiesChecking(object):
|
||||||
@ -50,9 +51,9 @@ class TestStoreCapabilities(base.StoreBaseTest):
|
|||||||
|
|
||||||
def _verify_store_capabilities(self, store):
|
def _verify_store_capabilities(self, store):
|
||||||
# This function tested is_capable() as well.
|
# This function tested is_capable() as well.
|
||||||
self.assertTrue(store.is_capable(caps.READ_RANDOM))
|
self.assertTrue(store.is_capable(caps.BitMasks.READ_RANDOM))
|
||||||
self.assertTrue(store.is_capable(caps.DRIVER_REUSABLE))
|
self.assertTrue(store.is_capable(caps.BitMasks.DRIVER_REUSABLE))
|
||||||
self.assertFalse(store.is_capable(caps.WRITE_ACCESS))
|
self.assertFalse(store.is_capable(caps.BitMasks.WRITE_ACCESS))
|
||||||
|
|
||||||
def test_static_capabilities_setup(self):
|
def test_static_capabilities_setup(self):
|
||||||
self._verify_store_capabilities(FakeStoreWithStaticCapabilities())
|
self._verify_store_capabilities(FakeStoreWithStaticCapabilities())
|
||||||
@ -65,16 +66,16 @@ class TestStoreCapabilities(base.StoreBaseTest):
|
|||||||
|
|
||||||
def test_set_unset_capabilities(self):
|
def test_set_unset_capabilities(self):
|
||||||
store = FakeStoreWithStaticCapabilities()
|
store = FakeStoreWithStaticCapabilities()
|
||||||
self.assertFalse(store.is_capable(caps.WRITE_ACCESS))
|
self.assertFalse(store.is_capable(caps.BitMasks.WRITE_ACCESS))
|
||||||
|
|
||||||
# Set and unset single capability on one time
|
# Set and unset single capability on one time
|
||||||
store.set_capabilities(caps.WRITE_ACCESS)
|
store.set_capabilities(caps.BitMasks.WRITE_ACCESS)
|
||||||
self.assertTrue(store.is_capable(caps.WRITE_ACCESS))
|
self.assertTrue(store.is_capable(caps.BitMasks.WRITE_ACCESS))
|
||||||
store.unset_capabilities(caps.WRITE_ACCESS)
|
store.unset_capabilities(caps.BitMasks.WRITE_ACCESS)
|
||||||
self.assertFalse(store.is_capable(caps.WRITE_ACCESS))
|
self.assertFalse(store.is_capable(caps.BitMasks.WRITE_ACCESS))
|
||||||
|
|
||||||
# Set and unset multiple capabilities on one time
|
# Set and unset multiple capabilities on one time
|
||||||
cap_list = [caps.WRITE_ACCESS, caps.WRITE_OFFSET]
|
cap_list = [caps.BitMasks.WRITE_ACCESS, caps.BitMasks.WRITE_OFFSET]
|
||||||
store.set_capabilities(*cap_list)
|
store.set_capabilities(*cap_list)
|
||||||
self.assertTrue(store.is_capable(*cap_list))
|
self.assertTrue(store.is_capable(*cap_list))
|
||||||
store.unset_capabilities(*cap_list)
|
store.unset_capabilities(*cap_list)
|
||||||
@ -90,54 +91,54 @@ class TestStoreCapabilities(base.StoreBaseTest):
|
|||||||
# Test read capability
|
# Test read capability
|
||||||
store = FakeStoreWithMixedCapabilities()
|
store = FakeStoreWithMixedCapabilities()
|
||||||
self._verify_store_capabilities(store)
|
self._verify_store_capabilities(store)
|
||||||
store.unset_capabilities(caps.READ_ACCESS)
|
store.unset_capabilities(caps.BitMasks.READ_ACCESS)
|
||||||
cap_list = [caps.READ_ACCESS, caps.READ_OFFSET,
|
cap_list = [caps.BitMasks.READ_ACCESS, caps.BitMasks.READ_OFFSET,
|
||||||
caps.READ_CHUNK, caps.READ_RANDOM]
|
caps.BitMasks.READ_CHUNK, caps.BitMasks.READ_RANDOM]
|
||||||
for cap in cap_list:
|
for cap in cap_list:
|
||||||
# To make sure all of them are unsetted.
|
# To make sure all of them are unsetted.
|
||||||
self.assertFalse(store.is_capable(cap))
|
self.assertFalse(store.is_capable(cap))
|
||||||
self.assertTrue(store.is_capable(caps.DRIVER_REUSABLE))
|
self.assertTrue(store.is_capable(caps.BitMasks.DRIVER_REUSABLE))
|
||||||
|
|
||||||
# Test write capability
|
# Test write capability
|
||||||
store = FakeStoreWithDynamicCapabilities(caps.WRITE_RANDOM,
|
store = FakeStoreWithDynamicCapabilities(caps.BitMasks.WRITE_RANDOM,
|
||||||
caps.DRIVER_REUSABLE)
|
caps.BitMasks.DRIVER_REUSABLE)
|
||||||
self.assertTrue(store.is_capable(caps.WRITE_RANDOM))
|
self.assertTrue(store.is_capable(caps.BitMasks.WRITE_RANDOM))
|
||||||
self.assertTrue(store.is_capable(caps.DRIVER_REUSABLE))
|
self.assertTrue(store.is_capable(caps.BitMasks.DRIVER_REUSABLE))
|
||||||
store.unset_capabilities(caps.WRITE_ACCESS)
|
store.unset_capabilities(caps.BitMasks.WRITE_ACCESS)
|
||||||
cap_list = [caps.WRITE_ACCESS, caps.WRITE_OFFSET,
|
cap_list = [caps.BitMasks.WRITE_ACCESS, caps.BitMasks.WRITE_OFFSET,
|
||||||
caps.WRITE_CHUNK, caps.WRITE_RANDOM]
|
caps.BitMasks.WRITE_CHUNK, caps.BitMasks.WRITE_RANDOM]
|
||||||
for cap in cap_list:
|
for cap in cap_list:
|
||||||
# To make sure all of them are unsetted.
|
# To make sure all of them are unsetted.
|
||||||
self.assertFalse(store.is_capable(cap))
|
self.assertFalse(store.is_capable(cap))
|
||||||
self.assertTrue(store.is_capable(caps.DRIVER_REUSABLE))
|
self.assertTrue(store.is_capable(caps.BitMasks.DRIVER_REUSABLE))
|
||||||
|
|
||||||
|
|
||||||
class TestStoreCapabilityConstants(base.StoreBaseTest):
|
class TestStoreCapabilityConstants(base.StoreBaseTest):
|
||||||
|
|
||||||
def test_one_single_capability_own_one_bit(self):
|
def test_one_single_capability_own_one_bit(self):
|
||||||
cap_list = [
|
cap_list = [
|
||||||
caps.READ_ACCESS,
|
caps.BitMasks.READ_ACCESS,
|
||||||
caps.WRITE_ACCESS,
|
caps.BitMasks.WRITE_ACCESS,
|
||||||
caps.DRIVER_REUSABLE,
|
caps.BitMasks.DRIVER_REUSABLE,
|
||||||
]
|
]
|
||||||
for cap in cap_list:
|
for cap in cap_list:
|
||||||
self.assertEqual(1, bin(cap).count('1'))
|
self.assertEqual(1, bin(cap).count('1'))
|
||||||
|
|
||||||
def test_combined_capability_bits(self):
|
def test_combined_capability_bits(self):
|
||||||
check = caps.StoreCapability.contains
|
check = caps.StoreCapability.contains
|
||||||
check(caps.READ_OFFSET, caps.READ_ACCESS)
|
check(caps.BitMasks.READ_OFFSET, caps.BitMasks.READ_ACCESS)
|
||||||
check(caps.READ_CHUNK, caps.READ_ACCESS)
|
check(caps.BitMasks.READ_CHUNK, caps.BitMasks.READ_ACCESS)
|
||||||
check(caps.READ_RANDOM, caps.READ_CHUNK)
|
check(caps.BitMasks.READ_RANDOM, caps.BitMasks.READ_CHUNK)
|
||||||
check(caps.READ_RANDOM, caps.READ_OFFSET)
|
check(caps.BitMasks.READ_RANDOM, caps.BitMasks.READ_OFFSET)
|
||||||
check(caps.WRITE_OFFSET, caps.WRITE_ACCESS)
|
check(caps.BitMasks.WRITE_OFFSET, caps.BitMasks.WRITE_ACCESS)
|
||||||
check(caps.WRITE_CHUNK, caps.WRITE_ACCESS)
|
check(caps.BitMasks.WRITE_CHUNK, caps.BitMasks.WRITE_ACCESS)
|
||||||
check(caps.WRITE_RANDOM, caps.WRITE_CHUNK)
|
check(caps.BitMasks.WRITE_RANDOM, caps.BitMasks.WRITE_CHUNK)
|
||||||
check(caps.WRITE_RANDOM, caps.WRITE_OFFSET)
|
check(caps.BitMasks.WRITE_RANDOM, caps.BitMasks.WRITE_OFFSET)
|
||||||
check(caps.RW_ACCESS, caps.READ_ACCESS)
|
check(caps.BitMasks.RW_ACCESS, caps.BitMasks.READ_ACCESS)
|
||||||
check(caps.RW_ACCESS, caps.WRITE_ACCESS)
|
check(caps.BitMasks.RW_ACCESS, caps.BitMasks.WRITE_ACCESS)
|
||||||
check(caps.RW_OFFSET, caps.READ_OFFSET)
|
check(caps.BitMasks.RW_OFFSET, caps.BitMasks.READ_OFFSET)
|
||||||
check(caps.RW_OFFSET, caps.WRITE_OFFSET)
|
check(caps.BitMasks.RW_OFFSET, caps.BitMasks.WRITE_OFFSET)
|
||||||
check(caps.RW_CHUNK, caps.READ_CHUNK)
|
check(caps.BitMasks.RW_CHUNK, caps.BitMasks.READ_CHUNK)
|
||||||
check(caps.RW_CHUNK, caps.WRITE_CHUNK)
|
check(caps.BitMasks.RW_CHUNK, caps.BitMasks.WRITE_CHUNK)
|
||||||
check(caps.RW_RANDOM, caps.READ_RANDOM)
|
check(caps.BitMasks.RW_RANDOM, caps.BitMasks.READ_RANDOM)
|
||||||
check(caps.RW_RANDOM, caps.WRITE_RANDOM)
|
check(caps.BitMasks.RW_RANDOM, caps.BitMasks.WRITE_RANDOM)
|
||||||
|
@ -761,7 +761,8 @@ class SwiftTests(object):
|
|||||||
try:
|
try:
|
||||||
self.config(**conf)
|
self.config(**conf)
|
||||||
self.store = Store(self.conf)
|
self.store = Store(self.conf)
|
||||||
return not self.store.is_capable(capabilities.WRITE_ACCESS)
|
return not self.store.is_capable(
|
||||||
|
capabilities.BitMasks.WRITE_ACCESS)
|
||||||
except Exception:
|
except Exception:
|
||||||
return False
|
return False
|
||||||
return False
|
return False
|
||||||
@ -775,7 +776,8 @@ class SwiftTests(object):
|
|||||||
'authurl.com', 'user': '',
|
'authurl.com', 'user': '',
|
||||||
'key': ''}}
|
'key': ''}}
|
||||||
self.store.configure()
|
self.store.configure()
|
||||||
self.assertFalse(self.store.is_capable(capabilities.WRITE_ACCESS))
|
self.assertFalse(self.store.is_capable(
|
||||||
|
capabilities.BitMasks.WRITE_ACCESS))
|
||||||
|
|
||||||
def test_no_auth_address(self):
|
def test_no_auth_address(self):
|
||||||
"""
|
"""
|
||||||
@ -786,7 +788,8 @@ class SwiftTests(object):
|
|||||||
'', 'user': 'user1',
|
'', 'user': 'user1',
|
||||||
'key': 'key1'}}
|
'key': 'key1'}}
|
||||||
self.store.configure()
|
self.store.configure()
|
||||||
self.assertFalse(self.store.is_capable(capabilities.WRITE_ACCESS))
|
self.assertFalse(self.store.is_capable(
|
||||||
|
capabilities.BitMasks.WRITE_ACCESS))
|
||||||
|
|
||||||
def test_delete(self):
|
def test_delete(self):
|
||||||
"""
|
"""
|
||||||
|
Loading…
Reference in New Issue
Block a user