Merge "Add checksum to object extended attributes"
This commit is contained in:
commit
13e932066c
@ -82,6 +82,12 @@ You can run unit tests with ``.unittests``, functional tests with
|
|||||||
``.functests``, and probe tests with ``.probetests``. There is an
|
``.functests``, and probe tests with ``.probetests``. There is an
|
||||||
additional ``.alltests`` script that wraps the other three.
|
additional ``.alltests`` script that wraps the other three.
|
||||||
|
|
||||||
|
To fully run the tests, the target environment must use a filesystem that
|
||||||
|
supports large xattrs. XFS is strongly recommended. For unit tests and in-
|
||||||
|
process functional tests, either mount ``/tmp`` with XFS or provide another
|
||||||
|
XFS filesystem via the ``TMPDIR`` environment variable. Without this setting,
|
||||||
|
tests should still pass, but a very large number will be skipped.
|
||||||
|
|
||||||
Code Organization
|
Code Organization
|
||||||
~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -77,6 +77,9 @@ To execute the tests:
|
|||||||
--recreate`` or remove the ``.tox`` directory to force ``tox`` to recreate the
|
--recreate`` or remove the ``.tox`` directory to force ``tox`` to recreate the
|
||||||
dependency list.
|
dependency list.
|
||||||
|
|
||||||
|
Swift's tests require having an XFS directory available in ``/tmp`` or
|
||||||
|
in the ``TMPDIR`` environment variable.
|
||||||
|
|
||||||
Swift's functional tests may be executed against a :doc:`development_saio` or
|
Swift's functional tests may be executed against a :doc:`development_saio` or
|
||||||
other running Swift cluster using the command::
|
other running Swift cluster using the command::
|
||||||
|
|
||||||
|
@ -201,6 +201,23 @@ On Fedora 19 or later, you need to place these in ``/etc/rc.d/rc.local``.
|
|||||||
|
|
||||||
On OpenSuse you need to place these in ``/etc/init.d/boot.local``.
|
On OpenSuse you need to place these in ``/etc/init.d/boot.local``.
|
||||||
|
|
||||||
|
Creating an XFS tmp dir
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
Tests require having an XFS directory available in ``/tmp`` or in the
|
||||||
|
``TMPDIR`` environment variable. To set up ``/tmp`` with an XFS filesystem,
|
||||||
|
do the following::
|
||||||
|
|
||||||
|
cd ~
|
||||||
|
truncate -s 1GB xfs_file # create 1GB fil for XFS in your home directory
|
||||||
|
mkfs.xfs xfs_file
|
||||||
|
sudo mount -o loop,noatime,nodiratime xfs_file /tmp
|
||||||
|
sudo chmod -R 1777 /tmp
|
||||||
|
|
||||||
|
To persist this, edit and add the following to ``/etc/fstab``::
|
||||||
|
|
||||||
|
/home/swift/xfs_file /tmp xfs rw,noatime,nodiratime,attr2,inode64,noquota 0 0
|
||||||
|
|
||||||
----------------
|
----------------
|
||||||
Getting the code
|
Getting the code
|
||||||
----------------
|
----------------
|
||||||
|
@ -105,6 +105,10 @@ class DiskFileXattrNotSupported(DiskFileError):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class DiskFileBadMetadataChecksum(DiskFileError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class DeviceUnavailable(SwiftException):
|
class DeviceUnavailable(SwiftException):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ import time
|
|||||||
import subprocess
|
import subprocess
|
||||||
import re
|
import re
|
||||||
from swift import gettext_ as _
|
from swift import gettext_ as _
|
||||||
|
import tempfile
|
||||||
|
|
||||||
from swift.common.utils import search_tree, remove_file, write_file
|
from swift.common.utils import search_tree, remove_file, write_file
|
||||||
from swift.common.exceptions import InvalidPidFileException
|
from swift.common.exceptions import InvalidPidFileException
|
||||||
@ -82,7 +83,7 @@ def setup_env():
|
|||||||
"Running as non-root?"))
|
"Running as non-root?"))
|
||||||
|
|
||||||
# Set PYTHON_EGG_CACHE if it isn't already set
|
# Set PYTHON_EGG_CACHE if it isn't already set
|
||||||
os.environ.setdefault('PYTHON_EGG_CACHE', '/tmp')
|
os.environ.setdefault('PYTHON_EGG_CACHE', tempfile.gettempdir())
|
||||||
|
|
||||||
|
|
||||||
def command(func):
|
def command(func):
|
||||||
|
@ -70,7 +70,8 @@ from swift.common.splice import splice, tee
|
|||||||
from swift.common.exceptions import DiskFileQuarantined, DiskFileNotExist, \
|
from swift.common.exceptions import DiskFileQuarantined, DiskFileNotExist, \
|
||||||
DiskFileCollision, DiskFileNoSpace, DiskFileDeviceUnavailable, \
|
DiskFileCollision, DiskFileNoSpace, DiskFileDeviceUnavailable, \
|
||||||
DiskFileDeleted, DiskFileError, DiskFileNotOpen, PathNotDir, \
|
DiskFileDeleted, DiskFileError, DiskFileNotOpen, PathNotDir, \
|
||||||
ReplicationLockTimeout, DiskFileExpired, DiskFileXattrNotSupported
|
ReplicationLockTimeout, DiskFileExpired, DiskFileXattrNotSupported, \
|
||||||
|
DiskFileBadMetadataChecksum
|
||||||
from swift.common.swob import multi_range_iterator
|
from swift.common.swob import multi_range_iterator
|
||||||
from swift.common.storage_policy import (
|
from swift.common.storage_policy import (
|
||||||
get_policy_string, split_policy_string, PolicyError, POLICIES,
|
get_policy_string, split_policy_string, PolicyError, POLICIES,
|
||||||
@ -83,6 +84,7 @@ DEFAULT_RECLAIM_AGE = timedelta(weeks=1).total_seconds()
|
|||||||
HASH_FILE = 'hashes.pkl'
|
HASH_FILE = 'hashes.pkl'
|
||||||
HASH_INVALIDATIONS_FILE = 'hashes.invalid'
|
HASH_INVALIDATIONS_FILE = 'hashes.invalid'
|
||||||
METADATA_KEY = 'user.swift.metadata'
|
METADATA_KEY = 'user.swift.metadata'
|
||||||
|
METADATA_CHECKSUM_KEY = 'user.swift.metadata_checksum'
|
||||||
DROP_CACHE_WINDOW = 1024 * 1024
|
DROP_CACHE_WINDOW = 1024 * 1024
|
||||||
# These are system-set metadata keys that cannot be changed with a POST.
|
# These are system-set metadata keys that cannot be changed with a POST.
|
||||||
# They should be lowercase.
|
# They should be lowercase.
|
||||||
@ -145,16 +147,33 @@ def read_metadata(fd):
|
|||||||
(key or '')))
|
(key or '')))
|
||||||
key += 1
|
key += 1
|
||||||
except (IOError, OSError) as e:
|
except (IOError, OSError) as e:
|
||||||
for err in 'ENOTSUP', 'EOPNOTSUPP':
|
if errno.errorcode.get(e.errno) in ('ENOTSUP', 'EOPNOTSUPP'):
|
||||||
if hasattr(errno, err) and e.errno == getattr(errno, err):
|
msg = "Filesystem at %s does not support xattr"
|
||||||
msg = "Filesystem at %s does not support xattr" % \
|
logging.exception(msg, _get_filename(fd))
|
||||||
_get_filename(fd)
|
|
||||||
logging.exception(msg)
|
|
||||||
raise DiskFileXattrNotSupported(e)
|
raise DiskFileXattrNotSupported(e)
|
||||||
if e.errno == errno.ENOENT:
|
if e.errno == errno.ENOENT:
|
||||||
raise DiskFileNotExist()
|
raise DiskFileNotExist()
|
||||||
# TODO: we might want to re-raise errors that don't denote a missing
|
# TODO: we might want to re-raise errors that don't denote a missing
|
||||||
# xattr here. Seems to be ENODATA on linux and ENOATTR on BSD/OSX.
|
# xattr here. Seems to be ENODATA on linux and ENOATTR on BSD/OSX.
|
||||||
|
|
||||||
|
metadata_checksum = None
|
||||||
|
try:
|
||||||
|
metadata_checksum = xattr.getxattr(fd, METADATA_CHECKSUM_KEY)
|
||||||
|
except (IOError, OSError) as e:
|
||||||
|
# All the interesting errors were handled above; the only thing left
|
||||||
|
# here is ENODATA / ENOATTR to indicate that this attribute doesn't
|
||||||
|
# exist. This is fine; it just means that this object predates the
|
||||||
|
# introduction of metadata checksums.
|
||||||
|
pass
|
||||||
|
|
||||||
|
if metadata_checksum:
|
||||||
|
computed_checksum = hashlib.md5(metadata).hexdigest()
|
||||||
|
if metadata_checksum != computed_checksum:
|
||||||
|
raise DiskFileBadMetadataChecksum(
|
||||||
|
"Metadata checksum mismatch for %s: "
|
||||||
|
"stored checksum='%s', computed='%s'" % (
|
||||||
|
fd, metadata_checksum, computed_checksum))
|
||||||
|
|
||||||
# strings are utf-8 encoded when written, but have not always been
|
# strings are utf-8 encoded when written, but have not always been
|
||||||
# (see https://bugs.launchpad.net/swift/+bug/1678018) so encode them again
|
# (see https://bugs.launchpad.net/swift/+bug/1678018) so encode them again
|
||||||
# when read
|
# when read
|
||||||
@ -169,21 +188,23 @@ def write_metadata(fd, metadata, xattr_size=65536):
|
|||||||
:param metadata: metadata to write
|
:param metadata: metadata to write
|
||||||
"""
|
"""
|
||||||
metastr = pickle.dumps(_encode_metadata(metadata), PICKLE_PROTOCOL)
|
metastr = pickle.dumps(_encode_metadata(metadata), PICKLE_PROTOCOL)
|
||||||
|
metastr_md5 = hashlib.md5(metastr).hexdigest()
|
||||||
key = 0
|
key = 0
|
||||||
while metastr:
|
|
||||||
try:
|
try:
|
||||||
|
while metastr:
|
||||||
xattr.setxattr(fd, '%s%s' % (METADATA_KEY, key or ''),
|
xattr.setxattr(fd, '%s%s' % (METADATA_KEY, key or ''),
|
||||||
metastr[:xattr_size])
|
metastr[:xattr_size])
|
||||||
metastr = metastr[xattr_size:]
|
metastr = metastr[xattr_size:]
|
||||||
key += 1
|
key += 1
|
||||||
|
xattr.setxattr(fd, METADATA_CHECKSUM_KEY, metastr_md5)
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
for err in 'ENOTSUP', 'EOPNOTSUPP':
|
# errno module doesn't always have both of these, hence the ugly
|
||||||
if hasattr(errno, err) and e.errno == getattr(errno, err):
|
# check
|
||||||
msg = "Filesystem at %s does not support xattr" % \
|
if errno.errorcode.get(e.errno) in ('ENOTSUP', 'EOPNOTSUPP'):
|
||||||
_get_filename(fd)
|
msg = "Filesystem at %s does not support xattr"
|
||||||
logging.exception(msg)
|
logging.exception(msg, _get_filename(fd))
|
||||||
raise DiskFileXattrNotSupported(e)
|
raise DiskFileXattrNotSupported(e)
|
||||||
if e.errno in (errno.ENOSPC, errno.EDQUOT):
|
elif e.errno in (errno.ENOSPC, errno.EDQUOT):
|
||||||
msg = "No space left on device for %s" % _get_filename(fd)
|
msg = "No space left on device for %s" % _get_filename(fd)
|
||||||
logging.exception(msg)
|
logging.exception(msg)
|
||||||
raise DiskFileNoSpace()
|
raise DiskFileNoSpace()
|
||||||
@ -2389,6 +2410,8 @@ class BaseDiskFile(object):
|
|||||||
return read_metadata(source)
|
return read_metadata(source)
|
||||||
except (DiskFileXattrNotSupported, DiskFileNotExist):
|
except (DiskFileXattrNotSupported, DiskFileNotExist):
|
||||||
raise
|
raise
|
||||||
|
except DiskFileBadMetadataChecksum as err:
|
||||||
|
raise self._quarantine(quarantine_filename, str(err))
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
raise self._quarantine(
|
raise self._quarantine(
|
||||||
quarantine_filename,
|
quarantine_filename,
|
||||||
|
@ -31,7 +31,6 @@ from contextlib import closing
|
|||||||
from gzip import GzipFile
|
from gzip import GzipFile
|
||||||
from shutil import rmtree
|
from shutil import rmtree
|
||||||
from tempfile import mkdtemp
|
from tempfile import mkdtemp
|
||||||
from unittest2 import SkipTest
|
|
||||||
|
|
||||||
from six.moves.configparser import ConfigParser, NoSectionError
|
from six.moves.configparser import ConfigParser, NoSectionError
|
||||||
from six.moves import http_client
|
from six.moves import http_client
|
||||||
@ -44,10 +43,13 @@ from swift.common.utils import set_swift_dir
|
|||||||
from test import get_config, listen_zero
|
from test import get_config, listen_zero
|
||||||
from test.functional.swift_test_client import Account, Connection, Container, \
|
from test.functional.swift_test_client import Account, Connection, Container, \
|
||||||
ResponseError
|
ResponseError
|
||||||
# This has the side effect of mocking out the xattr module so that unit tests
|
|
||||||
# (and in this case, when in-process functional tests are called for) can run
|
|
||||||
# on file systems that don't support extended attributes.
|
|
||||||
from test.unit import debug_logger, FakeMemcache
|
from test.unit import debug_logger, FakeMemcache
|
||||||
|
# importing skip_if_no_xattrs so that functional tests can grab it from the
|
||||||
|
# test.functional namespace. Importing SkipTest so this works under both
|
||||||
|
# nose and testr test runners.
|
||||||
|
from test.unit import skip_if_no_xattrs as real_skip_if_no_xattrs
|
||||||
|
from test.unit import SkipTest
|
||||||
|
|
||||||
from swift.common import constraints, utils, ring, storage_policy
|
from swift.common import constraints, utils, ring, storage_policy
|
||||||
from swift.common.ring import Ring
|
from swift.common.ring import Ring
|
||||||
@ -110,6 +112,7 @@ insecure = False
|
|||||||
in_process = False
|
in_process = False
|
||||||
_testdir = _test_servers = _test_coros = _test_socks = None
|
_testdir = _test_servers = _test_coros = _test_socks = None
|
||||||
policy_specified = None
|
policy_specified = None
|
||||||
|
skip_if_no_xattrs = None
|
||||||
|
|
||||||
|
|
||||||
class FakeMemcacheMiddleware(MemcacheMiddleware):
|
class FakeMemcacheMiddleware(MemcacheMiddleware):
|
||||||
@ -660,6 +663,7 @@ def get_cluster_info():
|
|||||||
def setup_package():
|
def setup_package():
|
||||||
|
|
||||||
global policy_specified
|
global policy_specified
|
||||||
|
global skip_if_no_xattrs
|
||||||
policy_specified = os.environ.get('SWIFT_TEST_POLICY')
|
policy_specified = os.environ.get('SWIFT_TEST_POLICY')
|
||||||
in_process_env = os.environ.get('SWIFT_TEST_IN_PROCESS')
|
in_process_env = os.environ.get('SWIFT_TEST_IN_PROCESS')
|
||||||
if in_process_env is not None:
|
if in_process_env is not None:
|
||||||
@ -698,6 +702,7 @@ def setup_package():
|
|||||||
if in_process:
|
if in_process:
|
||||||
in_mem_obj_env = os.environ.get('SWIFT_TEST_IN_MEMORY_OBJ')
|
in_mem_obj_env = os.environ.get('SWIFT_TEST_IN_MEMORY_OBJ')
|
||||||
in_mem_obj = utils.config_true_value(in_mem_obj_env)
|
in_mem_obj = utils.config_true_value(in_mem_obj_env)
|
||||||
|
skip_if_no_xattrs = real_skip_if_no_xattrs
|
||||||
try:
|
try:
|
||||||
in_process_setup(the_object_server=(
|
in_process_setup(the_object_server=(
|
||||||
mem_object_server if in_mem_obj else object_server))
|
mem_object_server if in_mem_obj else object_server))
|
||||||
@ -705,6 +710,8 @@ def setup_package():
|
|||||||
print(('Exception during in-process setup: %s'
|
print(('Exception during in-process setup: %s'
|
||||||
% str(exc)), file=sys.stderr)
|
% str(exc)), file=sys.stderr)
|
||||||
raise
|
raise
|
||||||
|
else:
|
||||||
|
skip_if_no_xattrs = lambda: None
|
||||||
|
|
||||||
global web_front_end
|
global web_front_end
|
||||||
web_front_end = config.get('web_front_end', 'integral')
|
web_front_end = config.get('web_front_end', 'integral')
|
||||||
|
@ -834,6 +834,9 @@ class TestAccount(unittest2.TestCase):
|
|||||||
if tf.skip:
|
if tf.skip:
|
||||||
raise SkipTest
|
raise SkipTest
|
||||||
|
|
||||||
|
if tf.in_process:
|
||||||
|
tf.skip_if_no_xattrs()
|
||||||
|
|
||||||
def post(url, token, parsed, conn, extra_headers):
|
def post(url, token, parsed, conn, extra_headers):
|
||||||
headers = {'X-Auth-Token': token}
|
headers = {'X-Auth-Token': token}
|
||||||
headers.update(extra_headers)
|
headers.update(extra_headers)
|
||||||
|
@ -438,6 +438,9 @@ class TestContainer(unittest2.TestCase):
|
|||||||
if tf.skip:
|
if tf.skip:
|
||||||
raise SkipTest
|
raise SkipTest
|
||||||
|
|
||||||
|
if tf.in_process:
|
||||||
|
tf.skip_if_no_xattrs()
|
||||||
|
|
||||||
def post(url, token, parsed, conn, extra_headers):
|
def post(url, token, parsed, conn, extra_headers):
|
||||||
headers = {'X-Auth-Token': token}
|
headers = {'X-Auth-Token': token}
|
||||||
headers.update(extra_headers)
|
headers.update(extra_headers)
|
||||||
@ -580,6 +583,9 @@ class TestContainer(unittest2.TestCase):
|
|||||||
def test_cross_account_public_container(self):
|
def test_cross_account_public_container(self):
|
||||||
if tf.skip or tf.skip2:
|
if tf.skip or tf.skip2:
|
||||||
raise SkipTest
|
raise SkipTest
|
||||||
|
|
||||||
|
if tf.in_process:
|
||||||
|
tf.skip_if_no_xattrs()
|
||||||
# Obtain the first account's string
|
# Obtain the first account's string
|
||||||
first_account = ['unknown']
|
first_account = ['unknown']
|
||||||
|
|
||||||
@ -649,6 +655,9 @@ class TestContainer(unittest2.TestCase):
|
|||||||
def test_nonadmin_user(self):
|
def test_nonadmin_user(self):
|
||||||
if tf.skip or tf.skip3:
|
if tf.skip or tf.skip3:
|
||||||
raise SkipTest
|
raise SkipTest
|
||||||
|
|
||||||
|
if tf.in_process:
|
||||||
|
tf.skip_if_no_xattrs()
|
||||||
# Obtain the first account's string
|
# Obtain the first account's string
|
||||||
first_account = ['unknown']
|
first_account = ['unknown']
|
||||||
|
|
||||||
@ -1562,6 +1571,9 @@ class TestContainer(unittest2.TestCase):
|
|||||||
if 'container_quotas' not in cluster_info:
|
if 'container_quotas' not in cluster_info:
|
||||||
raise SkipTest('Container quotas not enabled')
|
raise SkipTest('Container quotas not enabled')
|
||||||
|
|
||||||
|
if tf.in_process:
|
||||||
|
tf.skip_if_no_xattrs()
|
||||||
|
|
||||||
def post(url, token, parsed, conn, name, value):
|
def post(url, token, parsed, conn, name, value):
|
||||||
conn.request('POST', parsed.path + '/' + self.name, '',
|
conn.request('POST', parsed.path + '/' + self.name, '',
|
||||||
{'X-Auth-Token': token, name: value})
|
{'X-Auth-Token': token, name: value})
|
||||||
|
@ -42,6 +42,9 @@ class TestObject(unittest2.TestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
if tf.skip or tf.skip2:
|
if tf.skip or tf.skip2:
|
||||||
raise SkipTest
|
raise SkipTest
|
||||||
|
|
||||||
|
if tf.in_process:
|
||||||
|
tf.skip_if_no_xattrs()
|
||||||
self.container = uuid4().hex
|
self.container = uuid4().hex
|
||||||
|
|
||||||
self.containers = []
|
self.containers = []
|
||||||
|
@ -379,6 +379,9 @@ class TestObjectVersioning(Base):
|
|||||||
self.assertNotIn('x-object-manifest', resp_headers)
|
self.assertNotIn('x-object-manifest', resp_headers)
|
||||||
|
|
||||||
def _test_versioning_dlo_setup(self):
|
def _test_versioning_dlo_setup(self):
|
||||||
|
if tf.in_process:
|
||||||
|
tf.skip_if_no_xattrs()
|
||||||
|
|
||||||
container = self.env.container
|
container = self.env.container
|
||||||
versions_container = self.env.versions_container
|
versions_container = self.env.versions_container
|
||||||
obj_name = Utils.create_name()
|
obj_name = Utils.create_name()
|
||||||
@ -695,6 +698,8 @@ class TestSloWithVersioning(unittest2.TestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
if 'slo' not in cluster_info:
|
if 'slo' not in cluster_info:
|
||||||
raise SkipTest("SLO not enabled")
|
raise SkipTest("SLO not enabled")
|
||||||
|
if tf.in_process:
|
||||||
|
tf.skip_if_no_xattrs()
|
||||||
|
|
||||||
self.conn = Connection(tf.config)
|
self.conn = Connection(tf.config)
|
||||||
self.conn.authenticate()
|
self.conn.authenticate()
|
||||||
|
@ -87,16 +87,19 @@ class BaseEnv(object):
|
|||||||
|
|
||||||
|
|
||||||
class Base(unittest2.TestCase):
|
class Base(unittest2.TestCase):
|
||||||
# subclasses may override env class
|
|
||||||
env = BaseEnv
|
env = BaseEnv
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def tearDownClass(cls):
|
||||||
|
cls.env.tearDown()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
cls.env.setUp()
|
cls.env.setUp()
|
||||||
|
|
||||||
@classmethod
|
def setUp(self):
|
||||||
def tearDownClass(cls):
|
if tf.in_process:
|
||||||
cls.env.tearDown()
|
tf.skip_if_no_xattrs()
|
||||||
|
|
||||||
def assert_body(self, body):
|
def assert_body(self, body):
|
||||||
response_body = self.env.conn.response.read()
|
response_body = self.env.conn.response.read()
|
||||||
@ -2721,6 +2724,9 @@ class TestServiceToken(unittest2.TestCase):
|
|||||||
if tf.skip_service_tokens:
|
if tf.skip_service_tokens:
|
||||||
raise SkipTest
|
raise SkipTest
|
||||||
|
|
||||||
|
if tf.in_process:
|
||||||
|
tf.skip_if_no_xattrs()
|
||||||
|
|
||||||
self.SET_TO_USERS_TOKEN = 1
|
self.SET_TO_USERS_TOKEN = 1
|
||||||
self.SET_TO_SERVICE_TOKEN = 2
|
self.SET_TO_SERVICE_TOKEN = 2
|
||||||
|
|
||||||
|
@ -19,7 +19,6 @@ from __future__ import print_function
|
|||||||
import os
|
import os
|
||||||
import copy
|
import copy
|
||||||
import logging
|
import logging
|
||||||
import errno
|
|
||||||
from six.moves import range
|
from six.moves import range
|
||||||
from six import BytesIO
|
from six import BytesIO
|
||||||
import sys
|
import sys
|
||||||
@ -32,11 +31,14 @@ import time
|
|||||||
import eventlet
|
import eventlet
|
||||||
from eventlet import greenpool, debug as eventlet_debug
|
from eventlet import greenpool, debug as eventlet_debug
|
||||||
from eventlet.green import socket
|
from eventlet.green import socket
|
||||||
from tempfile import mkdtemp
|
from tempfile import mkdtemp, mkstemp, gettempdir
|
||||||
from shutil import rmtree
|
from shutil import rmtree
|
||||||
import signal
|
import signal
|
||||||
import json
|
import json
|
||||||
import random
|
import random
|
||||||
|
import errno
|
||||||
|
import xattr
|
||||||
|
|
||||||
|
|
||||||
from swift.common.utils import Timestamp, NOTICE
|
from swift.common.utils import Timestamp, NOTICE
|
||||||
from test import get_config
|
from test import get_config
|
||||||
@ -57,7 +59,12 @@ import six.moves.cPickle as pickle
|
|||||||
from gzip import GzipFile
|
from gzip import GzipFile
|
||||||
import mock as mocklib
|
import mock as mocklib
|
||||||
import inspect
|
import inspect
|
||||||
from nose import SkipTest
|
import unittest
|
||||||
|
import unittest2
|
||||||
|
|
||||||
|
|
||||||
|
class SkipTest(unittest2.SkipTest, unittest.SkipTest):
|
||||||
|
pass
|
||||||
|
|
||||||
EMPTY_ETAG = md5().hexdigest()
|
EMPTY_ETAG = md5().hexdigest()
|
||||||
|
|
||||||
@ -402,36 +409,6 @@ def tmpfile(content):
|
|||||||
finally:
|
finally:
|
||||||
os.unlink(file_name)
|
os.unlink(file_name)
|
||||||
|
|
||||||
xattr_data = {}
|
|
||||||
|
|
||||||
|
|
||||||
def _get_inode(fd):
|
|
||||||
if not isinstance(fd, int):
|
|
||||||
try:
|
|
||||||
fd = fd.fileno()
|
|
||||||
except AttributeError:
|
|
||||||
return os.stat(fd).st_ino
|
|
||||||
return os.fstat(fd).st_ino
|
|
||||||
|
|
||||||
|
|
||||||
def _setxattr(fd, k, v):
|
|
||||||
inode = _get_inode(fd)
|
|
||||||
data = xattr_data.get(inode, {})
|
|
||||||
data[k] = v
|
|
||||||
xattr_data[inode] = data
|
|
||||||
|
|
||||||
|
|
||||||
def _getxattr(fd, k):
|
|
||||||
inode = _get_inode(fd)
|
|
||||||
data = xattr_data.get(inode, {}).get(k)
|
|
||||||
if not data:
|
|
||||||
raise IOError(errno.ENODATA, "Fake IOError")
|
|
||||||
return data
|
|
||||||
|
|
||||||
import xattr
|
|
||||||
xattr.setxattr = _setxattr
|
|
||||||
xattr.getxattr = _getxattr
|
|
||||||
|
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def temptree(files, contents=''):
|
def temptree(files, contents=''):
|
||||||
@ -1289,3 +1266,51 @@ def fake_ec_node_response(node_frags, policy):
|
|||||||
return StubResponse(200, body, headers)
|
return StubResponse(200, body, headers)
|
||||||
|
|
||||||
return get_response
|
return get_response
|
||||||
|
|
||||||
|
|
||||||
|
supports_xattr_cached_val = None
|
||||||
|
|
||||||
|
|
||||||
|
def xattr_supported_check():
|
||||||
|
"""
|
||||||
|
This check simply sets more than 4k of metadata on a tempfile and
|
||||||
|
returns True if it worked and False if not.
|
||||||
|
|
||||||
|
We want to use *more* than 4k of metadata in this check because
|
||||||
|
some filesystems (eg ext4) only allow one blocksize worth of
|
||||||
|
metadata. The XFS filesystem doesn't have this limit, and so this
|
||||||
|
check returns True when TMPDIR is XFS. This check will return
|
||||||
|
False under ext4 (which supports xattrs <= 4k) and tmpfs (which
|
||||||
|
doesn't support xattrs at all).
|
||||||
|
|
||||||
|
"""
|
||||||
|
global supports_xattr_cached_val
|
||||||
|
|
||||||
|
if supports_xattr_cached_val is not None:
|
||||||
|
return supports_xattr_cached_val
|
||||||
|
|
||||||
|
# assume the worst -- xattrs aren't supported
|
||||||
|
supports_xattr_cached_val = False
|
||||||
|
|
||||||
|
big_val = 'x' * (4096 + 1) # more than 4k of metadata
|
||||||
|
try:
|
||||||
|
fd, tmppath = mkstemp()
|
||||||
|
xattr.setxattr(fd, 'user.swift.testing_key', big_val)
|
||||||
|
except IOError as e:
|
||||||
|
if errno.errorcode.get(e.errno) in ('ENOSPC', 'ENOTSUP', 'EOPNOTSUPP'):
|
||||||
|
# filesystem does not support xattr of this size
|
||||||
|
return False
|
||||||
|
raise
|
||||||
|
else:
|
||||||
|
supports_xattr_cached_val = True
|
||||||
|
return True
|
||||||
|
finally:
|
||||||
|
# clean up the tmpfile
|
||||||
|
os.close(fd)
|
||||||
|
os.unlink(tmppath)
|
||||||
|
|
||||||
|
|
||||||
|
def skip_if_no_xattrs():
|
||||||
|
if not xattr_supported_check():
|
||||||
|
raise SkipTest('Large xattrs not supported in `%s`. Skipping test' %
|
||||||
|
gettempdir())
|
||||||
|
@ -20,7 +20,7 @@ from shutil import rmtree
|
|||||||
from tempfile import mkdtemp
|
from tempfile import mkdtemp
|
||||||
|
|
||||||
from six.moves import cStringIO as StringIO
|
from six.moves import cStringIO as StringIO
|
||||||
from test.unit import patch_policies, write_fake_ring
|
from test.unit import patch_policies, write_fake_ring, skip_if_no_xattrs
|
||||||
|
|
||||||
from swift.common import ring, utils
|
from swift.common import ring, utils
|
||||||
from swift.common.swob import Request
|
from swift.common.swob import Request
|
||||||
@ -40,6 +40,7 @@ from swift.obj.diskfile import write_metadata
|
|||||||
StoragePolicy(3, 'three', False)])
|
StoragePolicy(3, 'three', False)])
|
||||||
class TestCliInfoBase(unittest.TestCase):
|
class TestCliInfoBase(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
skip_if_no_xattrs()
|
||||||
self.orig_hp = utils.HASH_PATH_PREFIX, utils.HASH_PATH_SUFFIX
|
self.orig_hp = utils.HASH_PATH_PREFIX, utils.HASH_PATH_SUFFIX
|
||||||
utils.HASH_PATH_PREFIX = 'info'
|
utils.HASH_PATH_PREFIX = 'info'
|
||||||
utils.HASH_PATH_SUFFIX = 'info'
|
utils.HASH_PATH_SUFFIX = 'info'
|
||||||
|
@ -26,11 +26,12 @@ from swift.common.storage_policy import (
|
|||||||
|
|
||||||
from swift.obj.diskfile import write_metadata
|
from swift.obj.diskfile import write_metadata
|
||||||
|
|
||||||
from test.unit import FakeLogger
|
from test.unit import FakeLogger, skip_if_no_xattrs
|
||||||
|
|
||||||
|
|
||||||
class TestRelinker(unittest.TestCase):
|
class TestRelinker(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
skip_if_no_xattrs()
|
||||||
self.logger = FakeLogger()
|
self.logger = FakeLogger()
|
||||||
self.testdir = tempfile.mkdtemp()
|
self.testdir = tempfile.mkdtemp()
|
||||||
self.devices = os.path.join(self.testdir, 'node')
|
self.devices = os.path.join(self.testdir, 'node')
|
||||||
|
@ -1425,7 +1425,7 @@ class TestCommands(unittest.TestCase, RunSwiftRingBuilderMixin):
|
|||||||
self.assertSystemExit(EXIT_ERROR, ringbuilder.main, argv)
|
self.assertSystemExit(EXIT_ERROR, ringbuilder.main, argv)
|
||||||
|
|
||||||
def test_validate_non_existent_file(self):
|
def test_validate_non_existent_file(self):
|
||||||
rand_file = '%s/%s' % ('/tmp', str(uuid.uuid4()))
|
rand_file = '%s/%s' % (tempfile.gettempdir(), str(uuid.uuid4()))
|
||||||
argv = ["", rand_file, "validate"]
|
argv = ["", rand_file, "validate"]
|
||||||
self.assertSystemExit(EXIT_ERROR, ringbuilder.main, argv)
|
self.assertSystemExit(EXIT_ERROR, ringbuilder.main, argv)
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ from swift.common.ring import Ring
|
|||||||
from swift.common.swob import Request
|
from swift.common.swob import Request
|
||||||
from swift.obj import diskfile
|
from swift.obj import diskfile
|
||||||
|
|
||||||
from test.unit import FakeLogger
|
from test.unit import FakeLogger, skip_if_no_xattrs
|
||||||
from test.unit.common.middleware.crypto.crypto_helpers import (
|
from test.unit.common.middleware.crypto.crypto_helpers import (
|
||||||
md5hex, encrypt, TEST_KEYMASTER_CONF)
|
md5hex, encrypt, TEST_KEYMASTER_CONF)
|
||||||
from test.unit.helpers import setup_servers, teardown_servers
|
from test.unit.helpers import setup_servers, teardown_servers
|
||||||
@ -54,6 +54,7 @@ class TestCryptoPipelineChanges(unittest.TestCase):
|
|||||||
cls._test_context = None
|
cls._test_context = None
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
skip_if_no_xattrs()
|
||||||
self.plaintext = 'unencrypted body content'
|
self.plaintext = 'unencrypted body content'
|
||||||
self.plaintext_etag = md5hex(self.plaintext)
|
self.plaintext_etag = md5hex(self.plaintext)
|
||||||
self._setup_crypto_app()
|
self._setup_crypto_app()
|
||||||
|
@ -268,7 +268,8 @@ class TestReconSuccess(TestCase):
|
|||||||
return app
|
return app
|
||||||
|
|
||||||
def _create_ring(self, ringpath, replica_map, devs, part_shift):
|
def _create_ring(self, ringpath, replica_map, devs, part_shift):
|
||||||
ring.RingData(replica_map, devs, part_shift).save(ringpath)
|
ring.RingData(replica_map, devs, part_shift).save(ringpath,
|
||||||
|
mtime=None)
|
||||||
|
|
||||||
def _create_rings(self):
|
def _create_rings(self):
|
||||||
# make the rings unique so they have different md5 sums
|
# make the rings unique so they have different md5 sums
|
||||||
|
@ -20,6 +20,7 @@ import unittest
|
|||||||
import os
|
import os
|
||||||
import mock
|
import mock
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
from tempfile import gettempdir
|
||||||
|
|
||||||
from swift.common.linkat import linkat
|
from swift.common.linkat import linkat
|
||||||
from swift.common.utils import O_TMPFILE
|
from swift.common.utils import O_TMPFILE
|
||||||
@ -42,7 +43,7 @@ class TestLinkat(unittest.TestCase):
|
|||||||
with open('/dev/null', 'r') as fd:
|
with open('/dev/null', 'r') as fd:
|
||||||
self.assertRaises(IOError, linkat,
|
self.assertRaises(IOError, linkat,
|
||||||
linkat.AT_FDCWD, "/proc/self/fd/%s" % (fd),
|
linkat.AT_FDCWD, "/proc/self/fd/%s" % (fd),
|
||||||
linkat.AT_FDCWD, "/tmp/testlinkat",
|
linkat.AT_FDCWD, "%s/testlinkat" % gettempdir(),
|
||||||
linkat.AT_SYMLINK_FOLLOW)
|
linkat.AT_SYMLINK_FOLLOW)
|
||||||
self.assertEqual(ctypes.get_errno(), 0)
|
self.assertEqual(ctypes.get_errno(), 0)
|
||||||
|
|
||||||
@ -83,8 +84,8 @@ class TestLinkat(unittest.TestCase):
|
|||||||
path = None
|
path = None
|
||||||
ret = -1
|
ret = -1
|
||||||
try:
|
try:
|
||||||
fd = os.open('/tmp', O_TMPFILE | os.O_WRONLY)
|
fd = os.open(gettempdir(), O_TMPFILE | os.O_WRONLY)
|
||||||
path = os.path.join('/tmp', uuid4().hex)
|
path = os.path.join(gettempdir(), uuid4().hex)
|
||||||
ret = linkat(linkat.AT_FDCWD, "/proc/self/fd/%d" % (fd),
|
ret = linkat(linkat.AT_FDCWD, "/proc/self/fd/%d" % (fd),
|
||||||
linkat.AT_FDCWD, path, linkat.AT_SYMLINK_FOLLOW)
|
linkat.AT_FDCWD, path, linkat.AT_SYMLINK_FOLLOW)
|
||||||
self.assertEqual(ret, 0)
|
self.assertEqual(ret, 0)
|
||||||
|
@ -24,6 +24,7 @@ import signal
|
|||||||
import errno
|
import errno
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from time import sleep, time
|
from time import sleep, time
|
||||||
|
import tempfile
|
||||||
|
|
||||||
from six.moves import reload_module
|
from six.moves import reload_module
|
||||||
|
|
||||||
@ -115,7 +116,8 @@ class TestManagerModule(unittest.TestCase):
|
|||||||
]
|
]
|
||||||
self.assertEqual(manager.resource.called_with_args, expected)
|
self.assertEqual(manager.resource.called_with_args, expected)
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
manager.os.environ['PYTHON_EGG_CACHE'].startswith('/tmp'))
|
manager.os.environ['PYTHON_EGG_CACHE'].startswith(
|
||||||
|
tempfile.gettempdir()))
|
||||||
|
|
||||||
# test error condition
|
# test error condition
|
||||||
manager.resource = MockResource(error=ValueError())
|
manager.resource = MockResource(error=ValueError())
|
||||||
@ -123,7 +125,8 @@ class TestManagerModule(unittest.TestCase):
|
|||||||
manager.setup_env()
|
manager.setup_env()
|
||||||
self.assertEqual(manager.resource.called_with_args, [])
|
self.assertEqual(manager.resource.called_with_args, [])
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
manager.os.environ['PYTHON_EGG_CACHE'].startswith('/tmp'))
|
manager.os.environ['PYTHON_EGG_CACHE'].startswith(
|
||||||
|
tempfile.gettempdir()))
|
||||||
|
|
||||||
manager.resource = MockResource(error=OSError())
|
manager.resource = MockResource(error=OSError())
|
||||||
manager.os.environ = {}
|
manager.os.environ = {}
|
||||||
|
@ -2018,7 +2018,7 @@ foo = bar
|
|||||||
[section2]
|
[section2]
|
||||||
log_name = yarr'''
|
log_name = yarr'''
|
||||||
# setup a real file
|
# setup a real file
|
||||||
fd, temppath = tempfile.mkstemp(dir='/tmp')
|
fd, temppath = tempfile.mkstemp()
|
||||||
with os.fdopen(fd, 'wb') as f:
|
with os.fdopen(fd, 'wb') as f:
|
||||||
f.write(conf)
|
f.write(conf)
|
||||||
make_filename = lambda: temppath
|
make_filename = lambda: temppath
|
||||||
@ -2067,7 +2067,7 @@ foo = bar
|
|||||||
[section2]
|
[section2]
|
||||||
log_name = %(yarr)s'''
|
log_name = %(yarr)s'''
|
||||||
# setup a real file
|
# setup a real file
|
||||||
fd, temppath = tempfile.mkstemp(dir='/tmp')
|
fd, temppath = tempfile.mkstemp()
|
||||||
with os.fdopen(fd, 'wb') as f:
|
with os.fdopen(fd, 'wb') as f:
|
||||||
f.write(conf)
|
f.write(conf)
|
||||||
make_filename = lambda: temppath
|
make_filename = lambda: temppath
|
||||||
@ -3275,7 +3275,7 @@ cluster_dfw1 = http://dfw1.host/v1/
|
|||||||
tmpdir = mkdtemp()
|
tmpdir = mkdtemp()
|
||||||
try:
|
try:
|
||||||
link = os.path.join(tmpdir, "tmp")
|
link = os.path.join(tmpdir, "tmp")
|
||||||
os.symlink("/tmp", link)
|
os.symlink(tempfile.gettempdir(), link)
|
||||||
self.assertFalse(utils.ismount(link))
|
self.assertFalse(utils.ismount(link))
|
||||||
finally:
|
finally:
|
||||||
shutil.rmtree(tmpdir)
|
shutil.rmtree(tmpdir)
|
||||||
@ -3580,7 +3580,7 @@ cluster_dfw1 = http://dfw1.host/v1/
|
|||||||
tempdir = None
|
tempdir = None
|
||||||
fd = None
|
fd = None
|
||||||
try:
|
try:
|
||||||
tempdir = mkdtemp(dir='/tmp')
|
tempdir = mkdtemp()
|
||||||
fd, temppath = tempfile.mkstemp(dir=tempdir)
|
fd, temppath = tempfile.mkstemp(dir=tempdir)
|
||||||
|
|
||||||
_mock_fsync = mock.Mock()
|
_mock_fsync = mock.Mock()
|
||||||
@ -3618,7 +3618,7 @@ cluster_dfw1 = http://dfw1.host/v1/
|
|||||||
def test_renamer_with_fsync_dir(self):
|
def test_renamer_with_fsync_dir(self):
|
||||||
tempdir = None
|
tempdir = None
|
||||||
try:
|
try:
|
||||||
tempdir = mkdtemp(dir='/tmp')
|
tempdir = mkdtemp()
|
||||||
# Simulate part of object path already existing
|
# Simulate part of object path already existing
|
||||||
part_dir = os.path.join(tempdir, 'objects/1234/')
|
part_dir = os.path.join(tempdir, 'objects/1234/')
|
||||||
os.makedirs(part_dir)
|
os.makedirs(part_dir)
|
||||||
@ -3665,7 +3665,7 @@ cluster_dfw1 = http://dfw1.host/v1/
|
|||||||
tempdir = None
|
tempdir = None
|
||||||
fd = None
|
fd = None
|
||||||
try:
|
try:
|
||||||
tempdir = mkdtemp(dir='/tmp')
|
tempdir = mkdtemp()
|
||||||
os.makedirs(os.path.join(tempdir, 'a/b'))
|
os.makedirs(os.path.join(tempdir, 'a/b'))
|
||||||
# 4 new dirs created
|
# 4 new dirs created
|
||||||
dirpath = os.path.join(tempdir, 'a/b/1/2/3/4')
|
dirpath = os.path.join(tempdir, 'a/b/1/2/3/4')
|
||||||
@ -3788,7 +3788,7 @@ cluster_dfw1 = http://dfw1.host/v1/
|
|||||||
|
|
||||||
@requires_o_tmpfile_support
|
@requires_o_tmpfile_support
|
||||||
def test_link_fd_to_path_linkat_success(self):
|
def test_link_fd_to_path_linkat_success(self):
|
||||||
tempdir = mkdtemp(dir='/tmp')
|
tempdir = mkdtemp()
|
||||||
fd = os.open(tempdir, utils.O_TMPFILE | os.O_WRONLY)
|
fd = os.open(tempdir, utils.O_TMPFILE | os.O_WRONLY)
|
||||||
data = "I'm whatever Gotham needs me to be"
|
data = "I'm whatever Gotham needs me to be"
|
||||||
_m_fsync_dir = mock.Mock()
|
_m_fsync_dir = mock.Mock()
|
||||||
@ -3808,7 +3808,7 @@ cluster_dfw1 = http://dfw1.host/v1/
|
|||||||
|
|
||||||
@requires_o_tmpfile_support
|
@requires_o_tmpfile_support
|
||||||
def test_link_fd_to_path_target_exists(self):
|
def test_link_fd_to_path_target_exists(self):
|
||||||
tempdir = mkdtemp(dir='/tmp')
|
tempdir = mkdtemp()
|
||||||
# Create and write to a file
|
# Create and write to a file
|
||||||
fd, path = tempfile.mkstemp(dir=tempdir)
|
fd, path = tempfile.mkstemp(dir=tempdir)
|
||||||
os.write(fd, "hello world")
|
os.write(fd, "hello world")
|
||||||
@ -3843,7 +3843,7 @@ cluster_dfw1 = http://dfw1.host/v1/
|
|||||||
|
|
||||||
@requires_o_tmpfile_support
|
@requires_o_tmpfile_support
|
||||||
def test_linkat_race_dir_not_exists(self):
|
def test_linkat_race_dir_not_exists(self):
|
||||||
tempdir = mkdtemp(dir='/tmp')
|
tempdir = mkdtemp()
|
||||||
target_dir = os.path.join(tempdir, uuid4().hex)
|
target_dir = os.path.join(tempdir, uuid4().hex)
|
||||||
target_path = os.path.join(target_dir, uuid4().hex)
|
target_path = os.path.join(target_dir, uuid4().hex)
|
||||||
os.mkdir(target_dir)
|
os.mkdir(target_dir)
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from test import unit
|
|
||||||
import unittest
|
import unittest
|
||||||
import mock
|
import mock
|
||||||
import os
|
import os
|
||||||
@ -26,7 +25,7 @@ from tempfile import mkdtemp
|
|||||||
import textwrap
|
import textwrap
|
||||||
from os.path import dirname, basename
|
from os.path import dirname, basename
|
||||||
from test.unit import (debug_logger, patch_policies, make_timestamp_iter,
|
from test.unit import (debug_logger, patch_policies, make_timestamp_iter,
|
||||||
DEFAULT_TEST_EC_TYPE)
|
DEFAULT_TEST_EC_TYPE, skip_if_no_xattrs)
|
||||||
from swift.obj import auditor, replicator
|
from swift.obj import auditor, replicator
|
||||||
from swift.obj.diskfile import (
|
from swift.obj.diskfile import (
|
||||||
DiskFile, write_metadata, invalidate_hash, get_data_dir,
|
DiskFile, write_metadata, invalidate_hash, get_data_dir,
|
||||||
@ -63,6 +62,7 @@ def works_only_once(callable_thing, exception):
|
|||||||
class TestAuditor(unittest.TestCase):
|
class TestAuditor(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
skip_if_no_xattrs()
|
||||||
self.testdir = os.path.join(mkdtemp(), 'tmp_test_object_auditor')
|
self.testdir = os.path.join(mkdtemp(), 'tmp_test_object_auditor')
|
||||||
self.devices = os.path.join(self.testdir, 'node')
|
self.devices = os.path.join(self.testdir, 'node')
|
||||||
self.rcache = os.path.join(self.testdir, 'object.recon')
|
self.rcache = os.path.join(self.testdir, 'object.recon')
|
||||||
@ -118,7 +118,6 @@ class TestAuditor(unittest.TestCase):
|
|||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
rmtree(os.path.dirname(self.testdir), ignore_errors=1)
|
rmtree(os.path.dirname(self.testdir), ignore_errors=1)
|
||||||
unit.xattr_data = {}
|
|
||||||
|
|
||||||
def test_worker_conf_parms(self):
|
def test_worker_conf_parms(self):
|
||||||
def check_common_defaults():
|
def check_common_defaults():
|
||||||
|
@ -44,7 +44,8 @@ from swift.obj.diskfile import MD5_OF_EMPTY_STRING, update_auditor_status
|
|||||||
from test.unit import (mock as unit_mock, temptree, mock_check_drive,
|
from test.unit import (mock as unit_mock, temptree, mock_check_drive,
|
||||||
patch_policies, debug_logger, EMPTY_ETAG,
|
patch_policies, debug_logger, EMPTY_ETAG,
|
||||||
make_timestamp_iter, DEFAULT_TEST_EC_TYPE,
|
make_timestamp_iter, DEFAULT_TEST_EC_TYPE,
|
||||||
requires_o_tmpfile_support, encode_frag_archive_bodies)
|
requires_o_tmpfile_support, encode_frag_archive_bodies,
|
||||||
|
skip_if_no_xattrs)
|
||||||
from nose import SkipTest
|
from nose import SkipTest
|
||||||
from swift.obj import diskfile
|
from swift.obj import diskfile
|
||||||
from swift.common import utils
|
from swift.common import utils
|
||||||
@ -61,6 +62,7 @@ from swift.common.storage_policy import (
|
|||||||
BaseStoragePolicy, REPL_POLICY, EC_POLICY)
|
BaseStoragePolicy, REPL_POLICY, EC_POLICY)
|
||||||
from test.unit.obj.common import write_diskfile
|
from test.unit.obj.common import write_diskfile
|
||||||
|
|
||||||
|
|
||||||
test_policies = [
|
test_policies = [
|
||||||
StoragePolicy(0, name='zero', is_default=True),
|
StoragePolicy(0, name='zero', is_default=True),
|
||||||
ECStoragePolicy(1, name='one', is_default=False,
|
ECStoragePolicy(1, name='one', is_default=False,
|
||||||
@ -145,6 +147,7 @@ def _make_metafilename(meta_timestamp, ctype_timestamp=None):
|
|||||||
class TestDiskFileModuleMethods(unittest.TestCase):
|
class TestDiskFileModuleMethods(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
skip_if_no_xattrs()
|
||||||
utils.HASH_PATH_SUFFIX = 'endcap'
|
utils.HASH_PATH_SUFFIX = 'endcap'
|
||||||
utils.HASH_PATH_PREFIX = ''
|
utils.HASH_PATH_PREFIX = ''
|
||||||
# Setup a test ring per policy (stolen from common/test_ring.py)
|
# Setup a test ring per policy (stolen from common/test_ring.py)
|
||||||
@ -682,6 +685,7 @@ class BaseDiskFileTestMixin(object):
|
|||||||
mgr_cls = None
|
mgr_cls = None
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
skip_if_no_xattrs()
|
||||||
self.tmpdir = mkdtemp()
|
self.tmpdir = mkdtemp()
|
||||||
self.testdir = os.path.join(
|
self.testdir = os.path.join(
|
||||||
self.tmpdir, 'tmp_test_obj_server_DiskFile')
|
self.tmpdir, 'tmp_test_obj_server_DiskFile')
|
||||||
@ -3526,6 +3530,13 @@ class DiskFileMixin(BaseDiskFileTestMixin):
|
|||||||
wrong_byte = 'X' if meta_xattr[0] != 'X' else 'Y'
|
wrong_byte = 'X' if meta_xattr[0] != 'X' else 'Y'
|
||||||
xattr.setxattr(data_files[0], "user.swift.metadata",
|
xattr.setxattr(data_files[0], "user.swift.metadata",
|
||||||
wrong_byte + meta_xattr[1:])
|
wrong_byte + meta_xattr[1:])
|
||||||
|
elif invalid_type == 'Subtly-Corrupt-Xattrs':
|
||||||
|
# We have to go below read_metadata/write_metadata to get proper
|
||||||
|
# corruption.
|
||||||
|
meta_xattr = xattr.getxattr(data_files[0], "user.swift.metadata")
|
||||||
|
wrong_checksum = md5(meta_xattr + "some extra stuff").hexdigest()
|
||||||
|
xattr.setxattr(data_files[0], "user.swift.metadata_checksum",
|
||||||
|
wrong_checksum)
|
||||||
elif invalid_type == 'Truncated-Xattrs':
|
elif invalid_type == 'Truncated-Xattrs':
|
||||||
meta_xattr = xattr.getxattr(data_files[0], "user.swift.metadata")
|
meta_xattr = xattr.getxattr(data_files[0], "user.swift.metadata")
|
||||||
xattr.setxattr(data_files[0], "user.swift.metadata",
|
xattr.setxattr(data_files[0], "user.swift.metadata",
|
||||||
@ -3684,6 +3695,11 @@ class DiskFileMixin(BaseDiskFileTestMixin):
|
|||||||
def test_quarantine_corrupt_xattrs(self):
|
def test_quarantine_corrupt_xattrs(self):
|
||||||
self.run_quarantine_invalids('Corrupt-Xattrs')
|
self.run_quarantine_invalids('Corrupt-Xattrs')
|
||||||
|
|
||||||
|
def test_quarantine_subtly_corrupt_xattrs(self):
|
||||||
|
# xattrs that unpickle without error, but whose checksum does not
|
||||||
|
# match
|
||||||
|
self.run_quarantine_invalids('Subtly-Corrupt-Xattrs')
|
||||||
|
|
||||||
def test_quarantine_truncated_xattrs(self):
|
def test_quarantine_truncated_xattrs(self):
|
||||||
self.run_quarantine_invalids('Truncated-Xattrs')
|
self.run_quarantine_invalids('Truncated-Xattrs')
|
||||||
|
|
||||||
@ -3746,18 +3762,7 @@ class DiskFileMixin(BaseDiskFileTestMixin):
|
|||||||
invalid_type='Bad-Content-Length')
|
invalid_type='Bad-Content-Length')
|
||||||
|
|
||||||
def test_quarantine_fstat_oserror(self):
|
def test_quarantine_fstat_oserror(self):
|
||||||
invocations = [0]
|
with mock.patch('os.fstat', side_effect=OSError()):
|
||||||
orig_os_fstat = os.fstat
|
|
||||||
|
|
||||||
def bad_fstat(fd):
|
|
||||||
invocations[0] += 1
|
|
||||||
if invocations[0] == 4:
|
|
||||||
# FIXME - yes, this an icky way to get code coverage ... worth
|
|
||||||
# it?
|
|
||||||
raise OSError()
|
|
||||||
return orig_os_fstat(fd)
|
|
||||||
|
|
||||||
with mock.patch('os.fstat', bad_fstat):
|
|
||||||
self.assertRaises(
|
self.assertRaises(
|
||||||
DiskFileQuarantined,
|
DiskFileQuarantined,
|
||||||
self._get_open_disk_file)
|
self._get_open_disk_file)
|
||||||
@ -5957,6 +5962,7 @@ class TestSuffixHashes(unittest.TestCase):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
skip_if_no_xattrs()
|
||||||
self.testdir = tempfile.mkdtemp()
|
self.testdir = tempfile.mkdtemp()
|
||||||
self.logger = debug_logger('suffix-hash-test')
|
self.logger = debug_logger('suffix-hash-test')
|
||||||
self.devices = os.path.join(self.testdir, 'node')
|
self.devices = os.path.join(self.testdir, 'node')
|
||||||
|
@ -45,7 +45,7 @@ from swift.obj.reconstructor import REVERT
|
|||||||
from test.unit import (patch_policies, debug_logger, mocked_http_conn,
|
from test.unit import (patch_policies, debug_logger, mocked_http_conn,
|
||||||
FabricatedRing, make_timestamp_iter,
|
FabricatedRing, make_timestamp_iter,
|
||||||
DEFAULT_TEST_EC_TYPE, encode_frag_archive_bodies,
|
DEFAULT_TEST_EC_TYPE, encode_frag_archive_bodies,
|
||||||
quiet_eventlet_exceptions)
|
quiet_eventlet_exceptions, skip_if_no_xattrs)
|
||||||
from test.unit.obj.common import write_diskfile
|
from test.unit.obj.common import write_diskfile
|
||||||
|
|
||||||
|
|
||||||
@ -149,6 +149,7 @@ class TestGlobalSetupObjectReconstructor(unittest.TestCase):
|
|||||||
legacy_durable = False
|
legacy_durable = False
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
skip_if_no_xattrs()
|
||||||
self.testdir = tempfile.mkdtemp()
|
self.testdir = tempfile.mkdtemp()
|
||||||
_create_test_rings(self.testdir)
|
_create_test_rings(self.testdir)
|
||||||
POLICIES[0].object_ring = ring.Ring(self.testdir, ring_name='object')
|
POLICIES[0].object_ring = ring.Ring(self.testdir, ring_name='object')
|
||||||
@ -2387,6 +2388,7 @@ class TestWorkerReconstructor(unittest.TestCase):
|
|||||||
@patch_policies(with_ec_default=True)
|
@patch_policies(with_ec_default=True)
|
||||||
class BaseTestObjectReconstructor(unittest.TestCase):
|
class BaseTestObjectReconstructor(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
skip_if_no_xattrs()
|
||||||
self.policy = POLICIES.default
|
self.policy = POLICIES.default
|
||||||
self.policy.object_ring._rtime = time.time() + 3600
|
self.policy.object_ring._rtime = time.time() + 3600
|
||||||
self.testdir = tempfile.mkdtemp()
|
self.testdir = tempfile.mkdtemp()
|
||||||
|
@ -30,7 +30,8 @@ from eventlet.green import subprocess
|
|||||||
from eventlet import Timeout
|
from eventlet import Timeout
|
||||||
|
|
||||||
from test.unit import (debug_logger, patch_policies, make_timestamp_iter,
|
from test.unit import (debug_logger, patch_policies, make_timestamp_iter,
|
||||||
mocked_http_conn, FakeLogger, mock_check_drive)
|
mocked_http_conn, FakeLogger, mock_check_drive,
|
||||||
|
skip_if_no_xattrs)
|
||||||
from swift.common import utils
|
from swift.common import utils
|
||||||
from swift.common.utils import (hash_path, mkdirs, normalize_timestamp,
|
from swift.common.utils import (hash_path, mkdirs, normalize_timestamp,
|
||||||
storage_directory)
|
storage_directory)
|
||||||
@ -179,6 +180,7 @@ def _create_test_rings(path, devs=None, next_part_power=None):
|
|||||||
class TestObjectReplicator(unittest.TestCase):
|
class TestObjectReplicator(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
skip_if_no_xattrs()
|
||||||
utils.HASH_PATH_SUFFIX = 'endcap'
|
utils.HASH_PATH_SUFFIX = 'endcap'
|
||||||
utils.HASH_PATH_PREFIX = ''
|
utils.HASH_PATH_PREFIX = ''
|
||||||
# recon cache path
|
# recon cache path
|
||||||
|
@ -45,9 +45,9 @@ from swift import __version__ as swift_version
|
|||||||
from swift.common.http import is_success
|
from swift.common.http import is_success
|
||||||
from test import listen_zero
|
from test import listen_zero
|
||||||
from test.unit import FakeLogger, debug_logger, mocked_http_conn, \
|
from test.unit import FakeLogger, debug_logger, mocked_http_conn, \
|
||||||
make_timestamp_iter, DEFAULT_TEST_EC_TYPE, mock_check_drive
|
make_timestamp_iter, DEFAULT_TEST_EC_TYPE, skip_if_no_xattrs, \
|
||||||
from test.unit import connect_tcp, readuntil2crlfs, patch_policies, \
|
connect_tcp, readuntil2crlfs, patch_policies, encode_frag_archive_bodies, \
|
||||||
encode_frag_archive_bodies
|
mock_check_drive
|
||||||
from swift.obj import server as object_server
|
from swift.obj import server as object_server
|
||||||
from swift.obj import updater
|
from swift.obj import updater
|
||||||
from swift.obj import diskfile
|
from swift.obj import diskfile
|
||||||
@ -140,6 +140,7 @@ class TestObjectController(unittest.TestCase):
|
|||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
"""Set up for testing swift.object.server.ObjectController"""
|
"""Set up for testing swift.object.server.ObjectController"""
|
||||||
|
skip_if_no_xattrs()
|
||||||
utils.HASH_PATH_SUFFIX = 'endcap'
|
utils.HASH_PATH_SUFFIX = 'endcap'
|
||||||
utils.HASH_PATH_PREFIX = 'startcap'
|
utils.HASH_PATH_PREFIX = 'startcap'
|
||||||
self.tmpdir = mkdtemp()
|
self.tmpdir = mkdtemp()
|
||||||
@ -6942,6 +6943,7 @@ class TestObjectController(unittest.TestCase):
|
|||||||
class TestObjectServer(unittest.TestCase):
|
class TestObjectServer(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
skip_if_no_xattrs()
|
||||||
# dirs
|
# dirs
|
||||||
self.tmpdir = mkdtemp()
|
self.tmpdir = mkdtemp()
|
||||||
self.tempdir = os.path.join(self.tmpdir, 'tmp_test_obj_server')
|
self.tempdir = os.path.join(self.tmpdir, 'tmp_test_obj_server')
|
||||||
@ -7632,6 +7634,7 @@ class TestZeroCopy(unittest.TestCase):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
skip_if_no_xattrs()
|
||||||
if not self._system_can_zero_copy():
|
if not self._system_can_zero_copy():
|
||||||
raise SkipTest("zero-copy support is missing")
|
raise SkipTest("zero-copy support is missing")
|
||||||
|
|
||||||
|
@ -34,8 +34,9 @@ from swift.obj.reconstructor import RebuildingECDiskFileStream, \
|
|||||||
from swift.obj.replicator import ObjectReplicator
|
from swift.obj.replicator import ObjectReplicator
|
||||||
|
|
||||||
from test import listen_zero
|
from test import listen_zero
|
||||||
from test.unit import patch_policies, debug_logger, encode_frag_archive_bodies
|
|
||||||
from test.unit.obj.common import BaseTest
|
from test.unit.obj.common import BaseTest
|
||||||
|
from test.unit import patch_policies, debug_logger, \
|
||||||
|
encode_frag_archive_bodies, skip_if_no_xattrs
|
||||||
|
|
||||||
|
|
||||||
class TestBaseSsync(BaseTest):
|
class TestBaseSsync(BaseTest):
|
||||||
@ -47,6 +48,7 @@ class TestBaseSsync(BaseTest):
|
|||||||
about the final state of the sender and receiver diskfiles.
|
about the final state of the sender and receiver diskfiles.
|
||||||
"""
|
"""
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
skip_if_no_xattrs()
|
||||||
super(TestBaseSsync, self).setUp()
|
super(TestBaseSsync, self).setUp()
|
||||||
# rx side setup
|
# rx side setup
|
||||||
self.rx_testdir = os.path.join(self.tmpdir, 'tmp_test_ssync_receiver')
|
self.rx_testdir = os.path.join(self.tmpdir, 'tmp_test_ssync_receiver')
|
||||||
|
@ -35,7 +35,7 @@ from swift.obj.reconstructor import ObjectReconstructor
|
|||||||
|
|
||||||
from test import listen_zero, unit
|
from test import listen_zero, unit
|
||||||
from test.unit import (debug_logger, patch_policies, make_timestamp_iter,
|
from test.unit import (debug_logger, patch_policies, make_timestamp_iter,
|
||||||
mock_check_drive)
|
mock_check_drive, skip_if_no_xattrs)
|
||||||
from test.unit.obj.common import write_diskfile
|
from test.unit.obj.common import write_diskfile
|
||||||
|
|
||||||
|
|
||||||
@ -43,12 +43,11 @@ from test.unit.obj.common import write_diskfile
|
|||||||
class TestReceiver(unittest.TestCase):
|
class TestReceiver(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
skip_if_no_xattrs()
|
||||||
utils.HASH_PATH_SUFFIX = 'endcap'
|
utils.HASH_PATH_SUFFIX = 'endcap'
|
||||||
utils.HASH_PATH_PREFIX = 'startcap'
|
utils.HASH_PATH_PREFIX = 'startcap'
|
||||||
# Not sure why the test.unit stuff isn't taking effect here; so I'm
|
# Not sure why the test.unit stuff isn't taking effect here; so I'm
|
||||||
# reinforcing it.
|
# reinforcing it.
|
||||||
diskfile.getxattr = unit._getxattr
|
|
||||||
diskfile.setxattr = unit._setxattr
|
|
||||||
self.testdir = os.path.join(
|
self.testdir = os.path.join(
|
||||||
tempfile.mkdtemp(), 'tmp_test_ssync_receiver')
|
tempfile.mkdtemp(), 'tmp_test_ssync_receiver')
|
||||||
utils.mkdirs(os.path.join(self.testdir, 'sda1', 'tmp'))
|
utils.mkdirs(os.path.join(self.testdir, 'sda1', 'tmp'))
|
||||||
@ -1963,6 +1962,7 @@ class TestSsyncRxServer(unittest.TestCase):
|
|||||||
# server socket.
|
# server socket.
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
skip_if_no_xattrs()
|
||||||
# dirs
|
# dirs
|
||||||
self.tmpdir = tempfile.mkdtemp()
|
self.tmpdir = tempfile.mkdtemp()
|
||||||
self.tempdir = os.path.join(self.tmpdir, 'tmp_test_obj_server')
|
self.tempdir = os.path.join(self.tmpdir, 'tmp_test_obj_server')
|
||||||
|
@ -26,8 +26,9 @@ from swift.common.utils import Timestamp
|
|||||||
from swift.obj import ssync_sender, diskfile, ssync_receiver
|
from swift.obj import ssync_sender, diskfile, ssync_receiver
|
||||||
from swift.obj.replicator import ObjectReplicator
|
from swift.obj.replicator import ObjectReplicator
|
||||||
|
|
||||||
from test.unit import patch_policies, make_timestamp_iter, debug_logger
|
|
||||||
from test.unit.obj.common import BaseTest
|
from test.unit.obj.common import BaseTest
|
||||||
|
from test.unit import patch_policies, make_timestamp_iter, skip_if_no_xattrs, \
|
||||||
|
debug_logger
|
||||||
|
|
||||||
|
|
||||||
class NullBufferedHTTPConnection(object):
|
class NullBufferedHTTPConnection(object):
|
||||||
@ -84,6 +85,7 @@ class FakeConnection(object):
|
|||||||
class TestSender(BaseTest):
|
class TestSender(BaseTest):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
skip_if_no_xattrs()
|
||||||
super(TestSender, self).setUp()
|
super(TestSender, self).setUp()
|
||||||
self.daemon = ObjectReplicator(self.daemon_conf,
|
self.daemon = ObjectReplicator(self.daemon_conf,
|
||||||
debug_logger('test-ssync-sender'))
|
debug_logger('test-ssync-sender'))
|
||||||
|
@ -53,7 +53,8 @@ from test import listen_zero
|
|||||||
from test.unit import (
|
from test.unit import (
|
||||||
connect_tcp, readuntil2crlfs, FakeLogger, fake_http_connect, FakeRing,
|
connect_tcp, readuntil2crlfs, FakeLogger, fake_http_connect, FakeRing,
|
||||||
FakeMemcache, debug_logger, patch_policies, write_fake_ring,
|
FakeMemcache, debug_logger, patch_policies, write_fake_ring,
|
||||||
mocked_http_conn, DEFAULT_TEST_EC_TYPE, make_timestamp_iter)
|
mocked_http_conn, DEFAULT_TEST_EC_TYPE, make_timestamp_iter,
|
||||||
|
skip_if_no_xattrs)
|
||||||
from test.unit.helpers import setup_servers, teardown_servers
|
from test.unit.helpers import setup_servers, teardown_servers
|
||||||
from swift.proxy import server as proxy_server
|
from swift.proxy import server as proxy_server
|
||||||
from swift.proxy.controllers.obj import ReplicatedObjectController
|
from swift.proxy.controllers.obj import ReplicatedObjectController
|
||||||
@ -237,6 +238,7 @@ def _limit_max_file_size(f):
|
|||||||
class TestController(unittest.TestCase):
|
class TestController(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
skip_if_no_xattrs()
|
||||||
self.account_ring = FakeRing()
|
self.account_ring = FakeRing()
|
||||||
self.container_ring = FakeRing()
|
self.container_ring = FakeRing()
|
||||||
self.memcache = FakeMemcache()
|
self.memcache = FakeMemcache()
|
||||||
@ -1288,6 +1290,7 @@ class TestProxyServerLoading(unittest.TestCase):
|
|||||||
class TestProxyServerConfigLoading(unittest.TestCase):
|
class TestProxyServerConfigLoading(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
skip_if_no_xattrs()
|
||||||
self.tempdir = mkdtemp()
|
self.tempdir = mkdtemp()
|
||||||
account_ring_path = os.path.join(self.tempdir, 'account.ring.gz')
|
account_ring_path = os.path.join(self.tempdir, 'account.ring.gz')
|
||||||
write_fake_ring(account_ring_path)
|
write_fake_ring(account_ring_path)
|
||||||
@ -1987,6 +1990,7 @@ class TestReplicatedObjectController(
|
|||||||
Test suite for replication policy
|
Test suite for replication policy
|
||||||
"""
|
"""
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
skip_if_no_xattrs()
|
||||||
self.app = proxy_server.Application(
|
self.app = proxy_server.Application(
|
||||||
None, FakeMemcache(),
|
None, FakeMemcache(),
|
||||||
logger=debug_logger('proxy-ut'),
|
logger=debug_logger('proxy-ut'),
|
||||||
@ -6383,6 +6387,7 @@ class BaseTestECObjectController(BaseTestObjectController):
|
|||||||
|
|
||||||
class TestECObjectController(BaseTestECObjectController, unittest.TestCase):
|
class TestECObjectController(BaseTestECObjectController, unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
skip_if_no_xattrs()
|
||||||
self.ec_policy = POLICIES[3]
|
self.ec_policy = POLICIES[3]
|
||||||
super(TestECObjectController, self).setUp()
|
super(TestECObjectController, self).setUp()
|
||||||
|
|
||||||
@ -6390,11 +6395,15 @@ class TestECObjectController(BaseTestECObjectController, unittest.TestCase):
|
|||||||
class TestECDuplicationObjectController(
|
class TestECDuplicationObjectController(
|
||||||
BaseTestECObjectController, unittest.TestCase):
|
BaseTestECObjectController, unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
skip_if_no_xattrs()
|
||||||
self.ec_policy = POLICIES[4]
|
self.ec_policy = POLICIES[4]
|
||||||
super(TestECDuplicationObjectController, self).setUp()
|
super(TestECDuplicationObjectController, self).setUp()
|
||||||
|
|
||||||
|
|
||||||
class TestECMismatchedFA(unittest.TestCase):
|
class TestECMismatchedFA(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
skip_if_no_xattrs()
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
prosrv = _test_servers[0]
|
prosrv = _test_servers[0]
|
||||||
# don't leak error limits and poison other tests
|
# don't leak error limits and poison other tests
|
||||||
@ -6581,6 +6590,7 @@ class TestECMismatchedFA(unittest.TestCase):
|
|||||||
class TestECGets(unittest.TestCase):
|
class TestECGets(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestECGets, self).setUp()
|
super(TestECGets, self).setUp()
|
||||||
|
skip_if_no_xattrs()
|
||||||
self.tempdir = mkdtemp()
|
self.tempdir = mkdtemp()
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
@ -6852,6 +6862,7 @@ class TestObjectDisconnectCleanup(unittest.TestCase):
|
|||||||
mkdirs(data_path)
|
mkdirs(data_path)
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
skip_if_no_xattrs()
|
||||||
debug.hub_exceptions(False)
|
debug.hub_exceptions(False)
|
||||||
self._cleanup_devices()
|
self._cleanup_devices()
|
||||||
|
|
||||||
@ -6960,6 +6971,7 @@ class TestObjectECRangedGET(unittest.TestCase):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
|
skip_if_no_xattrs()
|
||||||
cls.obj_name = 'range-get-test'
|
cls.obj_name = 'range-get-test'
|
||||||
cls.tiny_obj_name = 'range-get-test-tiny'
|
cls.tiny_obj_name = 'range-get-test-tiny'
|
||||||
cls.aligned_obj_name = 'range-get-test-aligned'
|
cls.aligned_obj_name = 'range-get-test-aligned'
|
||||||
@ -9488,6 +9500,7 @@ class TestProxyObjectPerformance(unittest.TestCase):
|
|||||||
# This is just a simple test that can be used to verify and debug the
|
# This is just a simple test that can be used to verify and debug the
|
||||||
# various data paths between the proxy server and the object
|
# various data paths between the proxy server and the object
|
||||||
# server. Used as a play ground to debug buffer sizes for sockets.
|
# server. Used as a play ground to debug buffer sizes for sockets.
|
||||||
|
skip_if_no_xattrs()
|
||||||
prolis = _test_sockets[0]
|
prolis = _test_sockets[0]
|
||||||
sock = connect_tcp(('localhost', prolis.getsockname()[1]))
|
sock = connect_tcp(('localhost', prolis.getsockname()[1]))
|
||||||
# Client is transmitting in 2 MB chunks
|
# Client is transmitting in 2 MB chunks
|
||||||
@ -9601,6 +9614,7 @@ class TestSocketObjectVersions(unittest.TestCase):
|
|||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
global _test_sockets
|
global _test_sockets
|
||||||
|
skip_if_no_xattrs()
|
||||||
self.prolis = prolis = listen_zero()
|
self.prolis = prolis = listen_zero()
|
||||||
self._orig_prolis = _test_sockets[0]
|
self._orig_prolis = _test_sockets[0]
|
||||||
allowed_headers = ', '.join([
|
allowed_headers = ', '.join([
|
||||||
|
@ -30,7 +30,7 @@ from swift.proxy import server as proxy
|
|||||||
import swift.proxy.controllers
|
import swift.proxy.controllers
|
||||||
from swift.proxy.controllers.base import get_object_info
|
from swift.proxy.controllers.base import get_object_info
|
||||||
from test.unit import FakeMemcache, debug_logger, FakeRing, \
|
from test.unit import FakeMemcache, debug_logger, FakeRing, \
|
||||||
fake_http_connect, patch_policies
|
fake_http_connect, patch_policies, skip_if_no_xattrs
|
||||||
|
|
||||||
|
|
||||||
class FakeServerConnection(WSGIContext):
|
class FakeServerConnection(WSGIContext):
|
||||||
@ -132,6 +132,7 @@ class TestObjectSysmeta(unittest.TestCase):
|
|||||||
% (key, resp.headers))
|
% (key, resp.headers))
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
skip_if_no_xattrs()
|
||||||
self.app = proxy.Application(None, FakeMemcache(),
|
self.app = proxy.Application(None, FakeMemcache(),
|
||||||
logger=debug_logger('proxy-ut'),
|
logger=debug_logger('proxy-ut'),
|
||||||
account_ring=FakeRing(replicas=1),
|
account_ring=FakeRing(replicas=1),
|
||||||
|
Loading…
Reference in New Issue
Block a user