Merge upstream updates to support the new Liberty release
Conflicts: swiftonhpss.spec swiftonhpss/swift/__init__.py test/functional/tests.py
This commit is contained in:
commit
14599e460b
@ -8,10 +8,11 @@ greenlet>=0.3.1
|
|||||||
netifaces>=0.5,!=0.10.0,!=0.10.1
|
netifaces>=0.5,!=0.10.0,!=0.10.1
|
||||||
pastedeploy>=1.3.3
|
pastedeploy>=1.3.3
|
||||||
simplejson>=2.0.9
|
simplejson>=2.0.9
|
||||||
|
six>=1.9.0
|
||||||
xattr>=0.4
|
xattr>=0.4
|
||||||
PyECLib==1.0.7
|
PyECLib==1.0.7
|
||||||
|
|
||||||
# HPSS-specific package requirements. Get these from your HPSS support
|
# HPSS-specific package requirements. Get these from your HPSS support
|
||||||
# representative.
|
# representative.
|
||||||
hpss
|
hpss
|
||||||
hpssfs
|
hpssfs
|
||||||
|
@ -17,7 +17,7 @@ BuildRequires: python-devel
|
|||||||
BuildRequires: python-setuptools
|
BuildRequires: python-setuptools
|
||||||
Requires : python
|
Requires : python
|
||||||
Requires : python-setuptools
|
Requires : python-setuptools
|
||||||
Requires : openstack-swift-object = 2.3.0
|
Requires : openstack-swift-object = 2.5.0
|
||||||
|
|
||||||
%description
|
%description
|
||||||
SwiftOnHPSS is a Swift Object Server implementation that enables users to
|
SwiftOnHPSS is a Swift Object Server implementation that enables users to
|
||||||
@ -58,6 +58,9 @@ cp -r etc/* %{buildroot}/%{_confdir}/
|
|||||||
rm -rf %{buildroot}
|
rm -rf %{buildroot}
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Wed Dec 23 2015 Prashanth Pai <ppai@redhat.com> - 2.5.0-0
|
||||||
|
- Update spec file to support Liberty release of Swift
|
||||||
|
|
||||||
* Thu Dec 10 2015 Phil Bridges <pgbridge@us.ibm.com>
|
* Thu Dec 10 2015 Phil Bridges <pgbridge@us.ibm.com>
|
||||||
- Fork SwiftOnFile into SwiftOnHPSS, add HPSS-specific features
|
- Fork SwiftOnFile into SwiftOnHPSS, add HPSS-specific features
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ class PkgInfo(object):
|
|||||||
|
|
||||||
|
|
||||||
# Change the Package version here
|
# Change the Package version here
|
||||||
_pkginfo = PkgInfo(canonical_version='2.3.0',
|
_pkginfo = PkgInfo(canonical_version='2.5.0',
|
||||||
release='0',
|
release='0',
|
||||||
name='swiftonhpss',
|
name='swiftonhpss',
|
||||||
final=False)
|
final=False)
|
||||||
|
@ -30,7 +30,7 @@ from contextlib import contextmanager
|
|||||||
from swiftonhpss.swift.common.exceptions import AlreadyExistsAsFile, \
|
from swiftonhpss.swift.common.exceptions import AlreadyExistsAsFile, \
|
||||||
AlreadyExistsAsDir
|
AlreadyExistsAsDir
|
||||||
from swift.common.utils import ThreadPool, hash_path, \
|
from swift.common.utils import ThreadPool, hash_path, \
|
||||||
normalize_timestamp, fallocate
|
normalize_timestamp, fallocate, Timestamp
|
||||||
from swift.common.exceptions import DiskFileNotExist, DiskFileError, \
|
from swift.common.exceptions import DiskFileNotExist, DiskFileError, \
|
||||||
DiskFileNoSpace, DiskFileDeviceUnavailable, DiskFileNotOpen, \
|
DiskFileNoSpace, DiskFileDeviceUnavailable, DiskFileNotOpen, \
|
||||||
DiskFileExpired
|
DiskFileExpired
|
||||||
@ -53,7 +53,7 @@ from swift.obj.diskfile import get_async_dir
|
|||||||
|
|
||||||
# FIXME: Hopefully we'll be able to move to Python 2.7+ where O_CLOEXEC will
|
# FIXME: Hopefully we'll be able to move to Python 2.7+ where O_CLOEXEC will
|
||||||
# be back ported. See http://www.python.org/dev/peps/pep-0433/
|
# be back ported. See http://www.python.org/dev/peps/pep-0433/
|
||||||
O_CLOEXEC = 02000000
|
O_CLOEXEC = 0o2000000
|
||||||
|
|
||||||
MAX_RENAME_ATTEMPTS = 10
|
MAX_RENAME_ATTEMPTS = 10
|
||||||
MAX_OPEN_ATTEMPTS = 10
|
MAX_OPEN_ATTEMPTS = 10
|
||||||
@ -583,7 +583,7 @@ class DiskFile(object):
|
|||||||
"""
|
"""
|
||||||
def __init__(self, mgr, dev_path, threadpool, partition,
|
def __init__(self, mgr, dev_path, threadpool, partition,
|
||||||
account=None, container=None, obj=None,
|
account=None, container=None, obj=None,
|
||||||
policy=None, uid=DEFAULT_UID, gid=DEFAULT_GID):
|
policy=None, uid=DEFAULT_UID, gid=DEFAULT_GID, **kwargs):
|
||||||
# Variables partition and policy is currently unused.
|
# Variables partition and policy is currently unused.
|
||||||
self._mgr = mgr
|
self._mgr = mgr
|
||||||
self._device_path = dev_path
|
self._device_path = dev_path
|
||||||
@ -617,6 +617,18 @@ class DiskFile(object):
|
|||||||
|
|
||||||
self._data_file = os.path.join(self._put_datadir, self._obj)
|
self._data_file = os.path.join(self._put_datadir, self._obj)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def timestamp(self):
|
||||||
|
if self._metadata is None:
|
||||||
|
raise DiskFileNotOpen()
|
||||||
|
return Timestamp(self._metadata.get('X-Timestamp'))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def data_timestamp(self):
|
||||||
|
if self._metadata is None:
|
||||||
|
raise DiskFileNotOpen()
|
||||||
|
return Timestamp(self._metadata.get('X-Timestamp'))
|
||||||
|
|
||||||
def open(self):
|
def open(self):
|
||||||
"""
|
"""
|
||||||
Open the object.
|
Open the object.
|
||||||
@ -733,7 +745,6 @@ class DiskFile(object):
|
|||||||
the REST API *before* the object has actually been read. It is the
|
the REST API *before* the object has actually been read. It is the
|
||||||
responsibility of the implementation to properly handle that.
|
responsibility of the implementation to properly handle that.
|
||||||
"""
|
"""
|
||||||
self._metadata = None
|
|
||||||
self._close_fd()
|
self._close_fd()
|
||||||
|
|
||||||
def get_metadata(self):
|
def get_metadata(self):
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
# process, which may cause wedges in the gate later.
|
# process, which may cause wedges in the gate later.
|
||||||
|
|
||||||
# Hacking already pins down pep8, pyflakes and flake8
|
# Hacking already pins down pep8, pyflakes and flake8
|
||||||
hacking>=0.8.0,<0.9
|
hacking>=0.10.0,<0.11
|
||||||
coverage
|
coverage
|
||||||
nose
|
nose
|
||||||
nosexcover
|
nosexcover
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
# See http://code.google.com/p/python-nose/issues/detail?id=373
|
# See http://code.google.com/p/python-nose/issues/detail?id=373
|
||||||
# The code below enables nosetests to work with i18n _() blocks
|
# The code below enables nosetests to work with i18n _() blocks
|
||||||
|
from __future__ import print_function
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
try:
|
try:
|
||||||
@ -63,15 +63,12 @@ def get_config(section_name=None, defaults=None):
|
|||||||
config = readconf(config_file, section_name)
|
config = readconf(config_file, section_name)
|
||||||
except SystemExit:
|
except SystemExit:
|
||||||
if not os.path.exists(config_file):
|
if not os.path.exists(config_file):
|
||||||
print >>sys.stderr, \
|
print('Unable to read test config %s - file not found'
|
||||||
'Unable to read test config %s - file not found' \
|
% config_file, file=sys.stderr)
|
||||||
% config_file
|
|
||||||
elif not os.access(config_file, os.R_OK):
|
elif not os.access(config_file, os.R_OK):
|
||||||
print >>sys.stderr, \
|
print('Unable to read test config %s - permission denied'
|
||||||
'Unable to read test config %s - permission denied' \
|
% config_file, file=sys.stderr)
|
||||||
% config_file
|
|
||||||
else:
|
else:
|
||||||
print >>sys.stderr, \
|
print('Unable to read test config %s - section %s not found'
|
||||||
'Unable to read test config %s - section %s not found' \
|
% (config_file, section_name), file=sys.stderr)
|
||||||
% (config_file, section_name)
|
return config
|
||||||
return config
|
|
@ -13,6 +13,7 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
import mock
|
import mock
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
@ -23,20 +24,24 @@ import eventlet
|
|||||||
import eventlet.debug
|
import eventlet.debug
|
||||||
import functools
|
import functools
|
||||||
import random
|
import random
|
||||||
from ConfigParser import ConfigParser, NoSectionError
|
|
||||||
from time import time, sleep
|
from time import time, sleep
|
||||||
from httplib import HTTPException
|
|
||||||
from urlparse import urlparse
|
from urlparse import urlparse
|
||||||
from nose import SkipTest
|
from nose import SkipTest
|
||||||
from contextlib import closing
|
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 six.moves.configparser import ConfigParser, NoSectionError
|
||||||
|
from six.moves import http_client
|
||||||
|
from six.moves.http_client import HTTPException
|
||||||
|
|
||||||
from swift.common.middleware.memcache import MemcacheMiddleware
|
from swift.common.middleware.memcache import MemcacheMiddleware
|
||||||
from swift.common.storage_policy import parse_storage_policies, PolicyError
|
from swift.common.storage_policy import parse_storage_policies, PolicyError
|
||||||
|
|
||||||
from test import get_config
|
from test import get_config
|
||||||
from test.functional.swift_test_client import Account, Connection, \
|
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
|
# 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
|
# (and in this case, when in-process functional tests are called for) can run
|
||||||
@ -46,13 +51,13 @@ from test.unit import debug_logger, FakeMemcache
|
|||||||
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
|
||||||
from swift.common.wsgi import monkey_patch_mimetools, loadapp
|
from swift.common.wsgi import monkey_patch_mimetools, loadapp
|
||||||
from swift.common.utils import config_true_value
|
from swift.common.utils import config_true_value, split_path
|
||||||
from swift.account import server as account_server
|
from swift.account import server as account_server
|
||||||
from swift.container import server as container_server
|
from swift.container import server as container_server
|
||||||
from swift.obj import server as object_server, mem_server as mem_object_server
|
from swift.obj import server as object_server, mem_server as mem_object_server
|
||||||
import swift.proxy.controllers.obj
|
import swift.proxy.controllers.obj
|
||||||
|
|
||||||
|
http_client._MAXHEADERS = constraints.MAX_HEADER_COUNT
|
||||||
DEBUG = True
|
DEBUG = True
|
||||||
|
|
||||||
# In order to get the proper blocking behavior of sockets without using
|
# In order to get the proper blocking behavior of sockets without using
|
||||||
@ -105,6 +110,7 @@ orig_swift_conf_name = None
|
|||||||
|
|
||||||
in_process = False
|
in_process = False
|
||||||
_testdir = _test_servers = _test_coros = None
|
_testdir = _test_servers = _test_coros = None
|
||||||
|
policy_specified = None
|
||||||
|
|
||||||
|
|
||||||
class FakeMemcacheMiddleware(MemcacheMiddleware):
|
class FakeMemcacheMiddleware(MemcacheMiddleware):
|
||||||
@ -123,7 +129,7 @@ class InProcessException(BaseException):
|
|||||||
|
|
||||||
|
|
||||||
def _info(msg):
|
def _info(msg):
|
||||||
print >> sys.stderr, msg
|
print(msg, file=sys.stderr)
|
||||||
|
|
||||||
|
|
||||||
def _debug(msg):
|
def _debug(msg):
|
||||||
@ -209,7 +215,6 @@ def _in_process_setup_ring(swift_conf, conf_src_dir, testdir):
|
|||||||
for policy in policies:
|
for policy in policies:
|
||||||
conf.remove_section(sp_prefix + str(policy.idx))
|
conf.remove_section(sp_prefix + str(policy.idx))
|
||||||
|
|
||||||
policy_specified = os.environ.get('SWIFT_TEST_POLICY')
|
|
||||||
if policy_specified:
|
if policy_specified:
|
||||||
policy_to_test = policies.get_by_name(policy_specified)
|
policy_to_test = policies.get_by_name(policy_specified)
|
||||||
if policy_to_test is None:
|
if policy_to_test is None:
|
||||||
@ -497,7 +502,7 @@ def get_cluster_info():
|
|||||||
# Most likely the swift cluster has "expose_info = false" set
|
# Most likely the swift cluster has "expose_info = false" set
|
||||||
# in its proxy-server.conf file, so we'll just do the best we
|
# in its proxy-server.conf file, so we'll just do the best we
|
||||||
# can.
|
# can.
|
||||||
print >>sys.stderr, "** Swift Cluster not exposing /info **"
|
print("** Swift Cluster not exposing /info **", file=sys.stderr)
|
||||||
|
|
||||||
# Finally, we'll allow any constraint present in the swift-constraints
|
# Finally, we'll allow any constraint present in the swift-constraints
|
||||||
# section of test.conf to override everything. Note that only those
|
# section of test.conf to override everything. Note that only those
|
||||||
@ -509,8 +514,8 @@ def get_cluster_info():
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
except ValueError:
|
except ValueError:
|
||||||
print >>sys.stderr, "Invalid constraint value: %s = %s" % (
|
print("Invalid constraint value: %s = %s" % (
|
||||||
k, test_constraints[k])
|
k, test_constraints[k]), file=sys.stderr)
|
||||||
eff_constraints.update(test_constraints)
|
eff_constraints.update(test_constraints)
|
||||||
|
|
||||||
# Just make it look like these constraints were loaded from a /info call,
|
# Just make it look like these constraints were loaded from a /info call,
|
||||||
@ -520,6 +525,9 @@ def get_cluster_info():
|
|||||||
|
|
||||||
|
|
||||||
def setup_package():
|
def setup_package():
|
||||||
|
|
||||||
|
global policy_specified
|
||||||
|
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:
|
||||||
use_in_process = utils.config_true_value(in_process_env)
|
use_in_process = utils.config_true_value(in_process_env)
|
||||||
@ -557,8 +565,8 @@ def setup_package():
|
|||||||
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))
|
||||||
except InProcessException as exc:
|
except InProcessException as exc:
|
||||||
print >> sys.stderr, ('Exception during in-process setup: %s'
|
print(('Exception during in-process setup: %s'
|
||||||
% str(exc))
|
% str(exc)), file=sys.stderr)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
global web_front_end
|
global web_front_end
|
||||||
@ -667,20 +675,19 @@ def setup_package():
|
|||||||
global skip
|
global skip
|
||||||
skip = not all([swift_test_auth, swift_test_user[0], swift_test_key[0]])
|
skip = not all([swift_test_auth, swift_test_user[0], swift_test_key[0]])
|
||||||
if skip:
|
if skip:
|
||||||
print >>sys.stderr, 'SKIPPING FUNCTIONAL TESTS DUE TO NO CONFIG'
|
print('SKIPPING FUNCTIONAL TESTS DUE TO NO CONFIG', file=sys.stderr)
|
||||||
|
|
||||||
global skip2
|
global skip2
|
||||||
skip2 = not all([not skip, swift_test_user[1], swift_test_key[1]])
|
skip2 = not all([not skip, swift_test_user[1], swift_test_key[1]])
|
||||||
if not skip and skip2:
|
if not skip and skip2:
|
||||||
print >>sys.stderr, \
|
print('SKIPPING SECOND ACCOUNT FUNCTIONAL TESTS '
|
||||||
'SKIPPING SECOND ACCOUNT FUNCTIONAL TESTS' \
|
'DUE TO NO CONFIG FOR THEM', file=sys.stderr)
|
||||||
' DUE TO NO CONFIG FOR THEM'
|
|
||||||
|
|
||||||
global skip3
|
global skip3
|
||||||
skip3 = not all([not skip, swift_test_user[2], swift_test_key[2]])
|
skip3 = not all([not skip, swift_test_user[2], swift_test_key[2]])
|
||||||
if not skip and skip3:
|
if not skip and skip3:
|
||||||
print >>sys.stderr, \
|
print('SKIPPING THIRD ACCOUNT FUNCTIONAL TESTS'
|
||||||
'SKIPPING THIRD ACCOUNT FUNCTIONAL TESTS DUE TO NO CONFIG FOR THEM'
|
'DUE TO NO CONFIG FOR THEM', file=sys.stderr)
|
||||||
|
|
||||||
global skip_if_not_v3
|
global skip_if_not_v3
|
||||||
skip_if_not_v3 = (swift_test_auth_version != '3'
|
skip_if_not_v3 = (swift_test_auth_version != '3'
|
||||||
@ -688,16 +695,33 @@ def setup_package():
|
|||||||
swift_test_user[3],
|
swift_test_user[3],
|
||||||
swift_test_key[3]]))
|
swift_test_key[3]]))
|
||||||
if not skip and skip_if_not_v3:
|
if not skip and skip_if_not_v3:
|
||||||
print >>sys.stderr, \
|
print('SKIPPING FUNCTIONAL TESTS SPECIFIC TO AUTH VERSION 3',
|
||||||
'SKIPPING FUNCTIONAL TESTS SPECIFIC TO AUTH VERSION 3'
|
file=sys.stderr)
|
||||||
|
|
||||||
global skip_service_tokens
|
global skip_service_tokens
|
||||||
skip_service_tokens = not all([not skip, swift_test_user[4],
|
skip_service_tokens = not all([not skip, swift_test_user[4],
|
||||||
swift_test_key[4], swift_test_tenant[4],
|
swift_test_key[4], swift_test_tenant[4],
|
||||||
swift_test_service_prefix])
|
swift_test_service_prefix])
|
||||||
if not skip and skip_service_tokens:
|
if not skip and skip_service_tokens:
|
||||||
print >>sys.stderr, \
|
print(
|
||||||
'SKIPPING FUNCTIONAL TESTS SPECIFIC TO SERVICE TOKENS'
|
'SKIPPING FUNCTIONAL TESTS SPECIFIC TO SERVICE TOKENS',
|
||||||
|
file=sys.stderr)
|
||||||
|
|
||||||
|
if policy_specified:
|
||||||
|
policies = FunctionalStoragePolicyCollection.from_info()
|
||||||
|
for p in policies:
|
||||||
|
# policy names are case-insensitive
|
||||||
|
if policy_specified.lower() == p['name'].lower():
|
||||||
|
_info('Using specified policy %s' % policy_specified)
|
||||||
|
FunctionalStoragePolicyCollection.policy_specified = p
|
||||||
|
Container.policy_specified = policy_specified
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
_info(
|
||||||
|
'SKIPPING FUNCTIONAL TESTS: Failed to find specified policy %s'
|
||||||
|
% policy_specified)
|
||||||
|
raise Exception('Failed to find specified policy %s'
|
||||||
|
% policy_specified)
|
||||||
|
|
||||||
get_cluster_info()
|
get_cluster_info()
|
||||||
|
|
||||||
@ -746,8 +770,24 @@ conn = [None, None, None, None, None]
|
|||||||
|
|
||||||
def connection(url):
|
def connection(url):
|
||||||
if has_insecure:
|
if has_insecure:
|
||||||
return http_connection(url, insecure=insecure)
|
parsed_url, http_conn = http_connection(url, insecure=insecure)
|
||||||
return http_connection(url)
|
else:
|
||||||
|
parsed_url, http_conn = http_connection(url)
|
||||||
|
|
||||||
|
orig_request = http_conn.request
|
||||||
|
|
||||||
|
# Add the policy header if policy_specified is set
|
||||||
|
def request_with_policy(method, url, body=None, headers={}):
|
||||||
|
version, account, container, obj = split_path(url, 1, 4, True)
|
||||||
|
if policy_specified and method == 'PUT' and container and not obj \
|
||||||
|
and 'X-Storage-Policy' not in headers:
|
||||||
|
headers['X-Storage-Policy'] = policy_specified
|
||||||
|
|
||||||
|
return orig_request(method, url, body, headers)
|
||||||
|
|
||||||
|
http_conn.request = request_with_policy
|
||||||
|
|
||||||
|
return parsed_url, http_conn
|
||||||
|
|
||||||
|
|
||||||
def get_url_token(user_index, os_options):
|
def get_url_token(user_index, os_options):
|
||||||
@ -898,6 +938,9 @@ def requires_acls(f):
|
|||||||
|
|
||||||
class FunctionalStoragePolicyCollection(object):
|
class FunctionalStoragePolicyCollection(object):
|
||||||
|
|
||||||
|
# policy_specified is set in __init__.py when tests are being set up.
|
||||||
|
policy_specified = None
|
||||||
|
|
||||||
def __init__(self, policies):
|
def __init__(self, policies):
|
||||||
self._all = policies
|
self._all = policies
|
||||||
self.default = None
|
self.default = None
|
||||||
@ -939,7 +982,12 @@ class FunctionalStoragePolicyCollection(object):
|
|||||||
p.get(k) != v for k, v in kwargs.items())])
|
p.get(k) != v for k, v in kwargs.items())])
|
||||||
|
|
||||||
def select(self):
|
def select(self):
|
||||||
return random.choice(self)
|
# check that a policy was specified and that it is available
|
||||||
|
# in the current list (i.e., hasn't been excluded of the current list)
|
||||||
|
if self.policy_specified and self.policy_specified in self:
|
||||||
|
return self.policy_specified
|
||||||
|
else:
|
||||||
|
return random.choice(self)
|
||||||
|
|
||||||
|
|
||||||
def requires_policies(f):
|
def requires_policies(f):
|
||||||
|
@ -14,25 +14,27 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
import hashlib
|
import hashlib
|
||||||
import httplib
|
|
||||||
import os
|
import os
|
||||||
import random
|
import random
|
||||||
import socket
|
import socket
|
||||||
import StringIO
|
|
||||||
import time
|
import time
|
||||||
import urllib
|
import urllib
|
||||||
|
|
||||||
import simplejson as json
|
import simplejson as json
|
||||||
|
|
||||||
from nose import SkipTest
|
from nose import SkipTest
|
||||||
from xml.dom import minidom
|
from xml.dom import minidom
|
||||||
|
|
||||||
|
import six
|
||||||
|
from six.moves import http_client
|
||||||
from swiftclient import get_auth
|
from swiftclient import get_auth
|
||||||
|
|
||||||
|
from swift.common import constraints
|
||||||
from swift.common.utils import config_true_value
|
from swift.common.utils import config_true_value
|
||||||
|
|
||||||
from test import safe_repr
|
from test import safe_repr
|
||||||
|
|
||||||
|
http_client._MAXHEADERS = constraints.MAX_HEADER_COUNT
|
||||||
|
|
||||||
|
|
||||||
class AuthenticationFailed(Exception):
|
class AuthenticationFailed(Exception):
|
||||||
pass
|
pass
|
||||||
@ -68,7 +70,7 @@ class ResponseError(Exception):
|
|||||||
|
|
||||||
|
|
||||||
def listing_empty(method):
|
def listing_empty(method):
|
||||||
for i in xrange(6):
|
for i in range(6):
|
||||||
if len(method()) == 0:
|
if len(method()) == 0:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ -163,10 +165,10 @@ class Connection(object):
|
|||||||
x = storage_url.split('/')
|
x = storage_url.split('/')
|
||||||
|
|
||||||
if x[0] == 'http:':
|
if x[0] == 'http:':
|
||||||
self.conn_class = httplib.HTTPConnection
|
self.conn_class = http_client.HTTPConnection
|
||||||
self.storage_port = 80
|
self.storage_port = 80
|
||||||
elif x[0] == 'https:':
|
elif x[0] == 'https:':
|
||||||
self.conn_class = httplib.HTTPSConnection
|
self.conn_class = http_client.HTTPSConnection
|
||||||
self.storage_port = 443
|
self.storage_port = 443
|
||||||
else:
|
else:
|
||||||
raise ValueError('unexpected protocol %s' % (x[0]))
|
raise ValueError('unexpected protocol %s' % (x[0]))
|
||||||
@ -181,7 +183,11 @@ class Connection(object):
|
|||||||
self.storage_url = str('/%s/%s' % (x[3], x[4]))
|
self.storage_url = str('/%s/%s' % (x[3], x[4]))
|
||||||
self.account_name = str(x[4])
|
self.account_name = str(x[4])
|
||||||
self.auth_user = auth_user
|
self.auth_user = auth_user
|
||||||
self.storage_token = storage_token
|
# With v2 keystone, storage_token is unicode.
|
||||||
|
# We want it to be string otherwise this would cause
|
||||||
|
# troubles when doing query with already encoded
|
||||||
|
# non ascii characters in its headers.
|
||||||
|
self.storage_token = str(storage_token)
|
||||||
self.user_acl = '%s:%s' % (self.account, self.username)
|
self.user_acl = '%s:%s' % (self.account, self.username)
|
||||||
|
|
||||||
self.http_connect()
|
self.http_connect()
|
||||||
@ -202,7 +208,7 @@ class Connection(object):
|
|||||||
def http_connect(self):
|
def http_connect(self):
|
||||||
self.connection = self.conn_class(self.storage_host,
|
self.connection = self.conn_class(self.storage_host,
|
||||||
port=self.storage_port)
|
port=self.storage_port)
|
||||||
#self.connection.set_debuglevel(3)
|
# self.connection.set_debuglevel(3)
|
||||||
|
|
||||||
def make_path(self, path=None, cfg=None):
|
def make_path(self, path=None, cfg=None):
|
||||||
if path is None:
|
if path is None:
|
||||||
@ -230,6 +236,9 @@ class Connection(object):
|
|||||||
if not cfg.get('no_auth_token'):
|
if not cfg.get('no_auth_token'):
|
||||||
headers['X-Auth-Token'] = self.storage_token
|
headers['X-Auth-Token'] = self.storage_token
|
||||||
|
|
||||||
|
if cfg.get('use_token'):
|
||||||
|
headers['X-Auth-Token'] = cfg.get('use_token')
|
||||||
|
|
||||||
if isinstance(hdrs, dict):
|
if isinstance(hdrs, dict):
|
||||||
headers.update(hdrs)
|
headers.update(hdrs)
|
||||||
return headers
|
return headers
|
||||||
@ -276,7 +285,7 @@ class Connection(object):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
self.response = try_request()
|
self.response = try_request()
|
||||||
except httplib.HTTPException as e:
|
except http_client.HTTPException as e:
|
||||||
fail_messages.append(safe_repr(e))
|
fail_messages.append(safe_repr(e))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@ -328,9 +337,9 @@ class Connection(object):
|
|||||||
|
|
||||||
self.connection = self.conn_class(self.storage_host,
|
self.connection = self.conn_class(self.storage_host,
|
||||||
port=self.storage_port)
|
port=self.storage_port)
|
||||||
#self.connection.set_debuglevel(3)
|
# self.connection.set_debuglevel(3)
|
||||||
self.connection.putrequest('PUT', path)
|
self.connection.putrequest('PUT', path)
|
||||||
for key, value in headers.iteritems():
|
for key, value in headers.items():
|
||||||
self.connection.putheader(key, value)
|
self.connection.putheader(key, value)
|
||||||
self.connection.endheaders()
|
self.connection.endheaders()
|
||||||
|
|
||||||
@ -481,6 +490,9 @@ class Account(Base):
|
|||||||
|
|
||||||
|
|
||||||
class Container(Base):
|
class Container(Base):
|
||||||
|
# policy_specified is set in __init__.py when tests are being set up.
|
||||||
|
policy_specified = None
|
||||||
|
|
||||||
def __init__(self, conn, account, name):
|
def __init__(self, conn, account, name):
|
||||||
self.conn = conn
|
self.conn = conn
|
||||||
self.account = str(account)
|
self.account = str(account)
|
||||||
@ -493,9 +505,23 @@ class Container(Base):
|
|||||||
parms = {}
|
parms = {}
|
||||||
if cfg is None:
|
if cfg is None:
|
||||||
cfg = {}
|
cfg = {}
|
||||||
|
if self.policy_specified and 'X-Storage-Policy' not in hdrs:
|
||||||
|
hdrs['X-Storage-Policy'] = self.policy_specified
|
||||||
return self.conn.make_request('PUT', self.path, hdrs=hdrs,
|
return self.conn.make_request('PUT', self.path, hdrs=hdrs,
|
||||||
parms=parms, cfg=cfg) in (201, 202)
|
parms=parms, cfg=cfg) in (201, 202)
|
||||||
|
|
||||||
|
def update_metadata(self, hdrs=None, cfg=None):
|
||||||
|
if hdrs is None:
|
||||||
|
hdrs = {}
|
||||||
|
if cfg is None:
|
||||||
|
cfg = {}
|
||||||
|
|
||||||
|
self.conn.make_request('POST', self.path, hdrs=hdrs, cfg=cfg)
|
||||||
|
if not 200 <= self.conn.response.status <= 299:
|
||||||
|
raise ResponseError(self.conn.response, 'POST',
|
||||||
|
self.conn.make_path(self.path))
|
||||||
|
return True
|
||||||
|
|
||||||
def delete(self, hdrs=None, parms=None):
|
def delete(self, hdrs=None, parms=None):
|
||||||
if hdrs is None:
|
if hdrs is None:
|
||||||
hdrs = {}
|
hdrs = {}
|
||||||
@ -626,6 +652,9 @@ class File(Base):
|
|||||||
else:
|
else:
|
||||||
headers['Content-Length'] = 0
|
headers['Content-Length'] = 0
|
||||||
|
|
||||||
|
if cfg.get('use_token'):
|
||||||
|
headers['X-Auth-Token'] = cfg.get('use_token')
|
||||||
|
|
||||||
if cfg.get('no_content_type'):
|
if cfg.get('no_content_type'):
|
||||||
pass
|
pass
|
||||||
elif self.content_type:
|
elif self.content_type:
|
||||||
@ -643,7 +672,7 @@ class File(Base):
|
|||||||
block_size = 4096
|
block_size = 4096
|
||||||
|
|
||||||
if isinstance(data, str):
|
if isinstance(data, str):
|
||||||
data = StringIO.StringIO(data)
|
data = six.StringIO(data)
|
||||||
|
|
||||||
checksum = hashlib.md5()
|
checksum = hashlib.md5()
|
||||||
buff = data.read(block_size)
|
buff = data.read(block_size)
|
||||||
@ -700,13 +729,13 @@ class File(Base):
|
|||||||
return self.conn.make_request('COPY', self.path, hdrs=headers,
|
return self.conn.make_request('COPY', self.path, hdrs=headers,
|
||||||
parms=parms) == 201
|
parms=parms) == 201
|
||||||
|
|
||||||
def delete(self, hdrs=None, parms=None):
|
def delete(self, hdrs=None, parms=None, cfg=None):
|
||||||
if hdrs is None:
|
if hdrs is None:
|
||||||
hdrs = {}
|
hdrs = {}
|
||||||
if parms is None:
|
if parms is None:
|
||||||
parms = {}
|
parms = {}
|
||||||
if self.conn.make_request('DELETE', self.path, hdrs=hdrs,
|
if self.conn.make_request('DELETE', self.path, hdrs=hdrs,
|
||||||
parms=parms) != 204:
|
cfg=cfg, parms=parms) != 204:
|
||||||
|
|
||||||
raise ResponseError(self.conn.response, 'DELETE',
|
raise ResponseError(self.conn.response, 'DELETE',
|
||||||
self.conn.make_path(self.path))
|
self.conn.make_path(self.path))
|
||||||
@ -847,7 +876,7 @@ class File(Base):
|
|||||||
finally:
|
finally:
|
||||||
fobj.close()
|
fobj.close()
|
||||||
|
|
||||||
def sync_metadata(self, metadata=None, cfg=None):
|
def sync_metadata(self, metadata=None, cfg=None, parms=None):
|
||||||
if metadata is None:
|
if metadata is None:
|
||||||
metadata = {}
|
metadata = {}
|
||||||
if cfg is None:
|
if cfg is None:
|
||||||
@ -864,7 +893,8 @@ class File(Base):
|
|||||||
else:
|
else:
|
||||||
headers['Content-Length'] = 0
|
headers['Content-Length'] = 0
|
||||||
|
|
||||||
self.conn.make_request('POST', self.path, hdrs=headers, cfg=cfg)
|
self.conn.make_request('POST', self.path, hdrs=headers,
|
||||||
|
parms=parms, cfg=cfg)
|
||||||
|
|
||||||
if self.conn.response.status not in (201, 202):
|
if self.conn.response.status not in (201, 202):
|
||||||
raise ResponseError(self.conn.response, 'POST',
|
raise ResponseError(self.conn.response, 'POST',
|
||||||
@ -917,7 +947,7 @@ class File(Base):
|
|||||||
pass
|
pass
|
||||||
self.size = int(os.fstat(data.fileno())[6])
|
self.size = int(os.fstat(data.fileno())[6])
|
||||||
else:
|
else:
|
||||||
data = StringIO.StringIO(data)
|
data = six.StringIO(data)
|
||||||
self.size = data.len
|
self.size = data.len
|
||||||
|
|
||||||
headers = self.make_headers(cfg=cfg)
|
headers = self.make_headers(cfg=cfg)
|
||||||
@ -969,7 +999,7 @@ class File(Base):
|
|||||||
if not self.write(data, hdrs=hdrs, parms=parms, cfg=cfg):
|
if not self.write(data, hdrs=hdrs, parms=parms, cfg=cfg):
|
||||||
raise ResponseError(self.conn.response, 'PUT',
|
raise ResponseError(self.conn.response, 'PUT',
|
||||||
self.conn.make_path(self.path))
|
self.conn.make_path(self.path))
|
||||||
self.md5 = self.compute_md5sum(StringIO.StringIO(data))
|
self.md5 = self.compute_md5sum(six.StringIO(data))
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def write_random_return_resp(self, size=None, hdrs=None, parms=None,
|
def write_random_return_resp(self, size=None, hdrs=None, parms=None,
|
||||||
@ -986,5 +1016,28 @@ class File(Base):
|
|||||||
return_resp=True)
|
return_resp=True)
|
||||||
if not resp:
|
if not resp:
|
||||||
raise ResponseError(self.conn.response)
|
raise ResponseError(self.conn.response)
|
||||||
self.md5 = self.compute_md5sum(StringIO.StringIO(data))
|
self.md5 = self.compute_md5sum(six.StringIO(data))
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
|
def post(self, hdrs=None, parms=None, cfg=None, return_resp=False):
|
||||||
|
if hdrs is None:
|
||||||
|
hdrs = {}
|
||||||
|
if parms is None:
|
||||||
|
parms = {}
|
||||||
|
if cfg is None:
|
||||||
|
cfg = {}
|
||||||
|
|
||||||
|
headers = self.make_headers(cfg=cfg)
|
||||||
|
headers.update(hdrs)
|
||||||
|
|
||||||
|
self.conn.make_request('POST', self.path, hdrs=headers,
|
||||||
|
parms=parms, cfg=cfg)
|
||||||
|
|
||||||
|
if self.conn.response.status not in (201, 202):
|
||||||
|
raise ResponseError(self.conn.response, 'POST',
|
||||||
|
self.conn.make_path(self.path))
|
||||||
|
|
||||||
|
if return_resp:
|
||||||
|
return self.conn.response
|
||||||
|
|
||||||
|
return True
|
||||||
|
@ -21,6 +21,7 @@ from uuid import uuid4
|
|||||||
from nose import SkipTest
|
from nose import SkipTest
|
||||||
from string import letters
|
from string import letters
|
||||||
|
|
||||||
|
from six.moves import range
|
||||||
from swift.common.middleware.acl import format_acl
|
from swift.common.middleware.acl import format_acl
|
||||||
|
|
||||||
from test.functional import check_response, retry, requires_acls, \
|
from test.functional import check_response, retry, requires_acls, \
|
||||||
@ -88,22 +89,22 @@ class TestAccount(unittest.TestCase):
|
|||||||
self.assertEqual(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
resp = retry(head)
|
resp = retry(head)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assert_(resp.status in (200, 204), resp.status)
|
self.assertIn(resp.status, (200, 204))
|
||||||
self.assertEqual(resp.getheader('x-account-meta-test'), None)
|
self.assertEqual(resp.getheader('x-account-meta-test'), None)
|
||||||
resp = retry(get)
|
resp = retry(get)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assert_(resp.status in (200, 204), resp.status)
|
self.assertIn(resp.status, (200, 204))
|
||||||
self.assertEqual(resp.getheader('x-account-meta-test'), None)
|
self.assertEqual(resp.getheader('x-account-meta-test'), None)
|
||||||
resp = retry(post, 'Value')
|
resp = retry(post, 'Value')
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEqual(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
resp = retry(head)
|
resp = retry(head)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assert_(resp.status in (200, 204), resp.status)
|
self.assertIn(resp.status, (200, 204))
|
||||||
self.assertEqual(resp.getheader('x-account-meta-test'), 'Value')
|
self.assertEqual(resp.getheader('x-account-meta-test'), 'Value')
|
||||||
resp = retry(get)
|
resp = retry(get)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assert_(resp.status in (200, 204), resp.status)
|
self.assertIn(resp.status, (200, 204))
|
||||||
self.assertEqual(resp.getheader('x-account-meta-test'), 'Value')
|
self.assertEqual(resp.getheader('x-account-meta-test'), 'Value')
|
||||||
|
|
||||||
def test_invalid_acls(self):
|
def test_invalid_acls(self):
|
||||||
@ -189,7 +190,7 @@ class TestAccount(unittest.TestCase):
|
|||||||
# cannot read account
|
# cannot read account
|
||||||
resp = retry(get, use_account=3)
|
resp = retry(get, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 403)
|
self.assertEqual(resp.status, 403)
|
||||||
|
|
||||||
# grant read access
|
# grant read access
|
||||||
acl_user = tf.swift_test_user[2]
|
acl_user = tf.swift_test_user[2]
|
||||||
@ -203,7 +204,7 @@ class TestAccount(unittest.TestCase):
|
|||||||
# read-only can read account headers
|
# read-only can read account headers
|
||||||
resp = retry(get, use_account=3)
|
resp = retry(get, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assert_(resp.status in (200, 204))
|
self.assertIn(resp.status, (200, 204))
|
||||||
# but not acls
|
# but not acls
|
||||||
self.assertEqual(resp.getheader('X-Account-Access-Control'), None)
|
self.assertEqual(resp.getheader('X-Account-Access-Control'), None)
|
||||||
|
|
||||||
@ -220,7 +221,7 @@ class TestAccount(unittest.TestCase):
|
|||||||
self.assertEqual(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
resp = retry(get, use_account=3)
|
resp = retry(get, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assert_(resp.status in (200, 204))
|
self.assertIn(resp.status, (200, 204))
|
||||||
self.assertEqual(resp.getheader('X-Account-Meta-Test'), 'value')
|
self.assertEqual(resp.getheader('X-Account-Meta-Test'), 'value')
|
||||||
|
|
||||||
@requires_acls
|
@requires_acls
|
||||||
@ -240,7 +241,7 @@ class TestAccount(unittest.TestCase):
|
|||||||
# cannot read account
|
# cannot read account
|
||||||
resp = retry(get, use_account=3)
|
resp = retry(get, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 403)
|
self.assertEqual(resp.status, 403)
|
||||||
|
|
||||||
# grant read-write access
|
# grant read-write access
|
||||||
acl_user = tf.swift_test_user[2]
|
acl_user = tf.swift_test_user[2]
|
||||||
@ -254,7 +255,7 @@ class TestAccount(unittest.TestCase):
|
|||||||
# read-write can read account headers
|
# read-write can read account headers
|
||||||
resp = retry(get, use_account=3)
|
resp = retry(get, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assert_(resp.status in (200, 204))
|
self.assertIn(resp.status, (200, 204))
|
||||||
# but not acls
|
# but not acls
|
||||||
self.assertEqual(resp.getheader('X-Account-Access-Control'), None)
|
self.assertEqual(resp.getheader('X-Account-Access-Control'), None)
|
||||||
|
|
||||||
@ -281,7 +282,7 @@ class TestAccount(unittest.TestCase):
|
|||||||
# cannot read account
|
# cannot read account
|
||||||
resp = retry(get, use_account=3)
|
resp = retry(get, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 403)
|
self.assertEqual(resp.status, 403)
|
||||||
|
|
||||||
# grant admin access
|
# grant admin access
|
||||||
acl_user = tf.swift_test_user[2]
|
acl_user = tf.swift_test_user[2]
|
||||||
@ -295,7 +296,7 @@ class TestAccount(unittest.TestCase):
|
|||||||
# admin can read account headers
|
# admin can read account headers
|
||||||
resp = retry(get, use_account=3)
|
resp = retry(get, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assert_(resp.status in (200, 204))
|
self.assertIn(resp.status, (200, 204))
|
||||||
# including acls
|
# including acls
|
||||||
self.assertEqual(resp.getheader('X-Account-Access-Control'),
|
self.assertEqual(resp.getheader('X-Account-Access-Control'),
|
||||||
acl_json_str)
|
acl_json_str)
|
||||||
@ -308,7 +309,7 @@ class TestAccount(unittest.TestCase):
|
|||||||
self.assertEqual(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
resp = retry(get, use_account=3)
|
resp = retry(get, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assert_(resp.status in (200, 204))
|
self.assertIn(resp.status, (200, 204))
|
||||||
self.assertEqual(resp.getheader('X-Account-Meta-Test'), value)
|
self.assertEqual(resp.getheader('X-Account-Meta-Test'), value)
|
||||||
|
|
||||||
# admin can even revoke their own access
|
# admin can even revoke their own access
|
||||||
@ -320,7 +321,7 @@ class TestAccount(unittest.TestCase):
|
|||||||
# and again, cannot read account
|
# and again, cannot read account
|
||||||
resp = retry(get, use_account=3)
|
resp = retry(get, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 403)
|
self.assertEqual(resp.status, 403)
|
||||||
|
|
||||||
@requires_acls
|
@requires_acls
|
||||||
def test_protected_tempurl(self):
|
def test_protected_tempurl(self):
|
||||||
@ -358,8 +359,9 @@ class TestAccount(unittest.TestCase):
|
|||||||
# read-only tester3 can read account metadata
|
# read-only tester3 can read account metadata
|
||||||
resp = retry(get, use_account=3)
|
resp = retry(get, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assert_(resp.status in (200, 204),
|
self.assertTrue(
|
||||||
'Expected status in (200, 204), got %s' % resp.status)
|
resp.status in (200, 204),
|
||||||
|
'Expected status in (200, 204), got %s' % resp.status)
|
||||||
self.assertEqual(resp.getheader('X-Account-Meta-Test'), value)
|
self.assertEqual(resp.getheader('X-Account-Meta-Test'), value)
|
||||||
# but not temp-url-key
|
# but not temp-url-key
|
||||||
self.assertEqual(resp.getheader('X-Account-Meta-Temp-Url-Key'), None)
|
self.assertEqual(resp.getheader('X-Account-Meta-Temp-Url-Key'), None)
|
||||||
@ -376,8 +378,9 @@ class TestAccount(unittest.TestCase):
|
|||||||
# read-write tester3 can read account metadata
|
# read-write tester3 can read account metadata
|
||||||
resp = retry(get, use_account=3)
|
resp = retry(get, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assert_(resp.status in (200, 204),
|
self.assertTrue(
|
||||||
'Expected status in (200, 204), got %s' % resp.status)
|
resp.status in (200, 204),
|
||||||
|
'Expected status in (200, 204), got %s' % resp.status)
|
||||||
self.assertEqual(resp.getheader('X-Account-Meta-Test'), value)
|
self.assertEqual(resp.getheader('X-Account-Meta-Test'), value)
|
||||||
# but not temp-url-key
|
# but not temp-url-key
|
||||||
self.assertEqual(resp.getheader('X-Account-Meta-Temp-Url-Key'), None)
|
self.assertEqual(resp.getheader('X-Account-Meta-Temp-Url-Key'), None)
|
||||||
@ -394,8 +397,9 @@ class TestAccount(unittest.TestCase):
|
|||||||
# admin tester3 can read account metadata
|
# admin tester3 can read account metadata
|
||||||
resp = retry(get, use_account=3)
|
resp = retry(get, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assert_(resp.status in (200, 204),
|
self.assertTrue(
|
||||||
'Expected status in (200, 204), got %s' % resp.status)
|
resp.status in (200, 204),
|
||||||
|
'Expected status in (200, 204), got %s' % resp.status)
|
||||||
self.assertEqual(resp.getheader('X-Account-Meta-Test'), value)
|
self.assertEqual(resp.getheader('X-Account-Meta-Test'), value)
|
||||||
# including temp-url-key
|
# including temp-url-key
|
||||||
self.assertEqual(resp.getheader('X-Account-Meta-Temp-Url-Key'),
|
self.assertEqual(resp.getheader('X-Account-Meta-Temp-Url-Key'),
|
||||||
@ -411,8 +415,9 @@ class TestAccount(unittest.TestCase):
|
|||||||
self.assertEqual(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
resp = retry(get, use_account=3)
|
resp = retry(get, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assert_(resp.status in (200, 204),
|
self.assertTrue(
|
||||||
'Expected status in (200, 204), got %s' % resp.status)
|
resp.status in (200, 204),
|
||||||
|
'Expected status in (200, 204), got %s' % resp.status)
|
||||||
self.assertEqual(resp.getheader('X-Account-Meta-Temp-Url-Key'),
|
self.assertEqual(resp.getheader('X-Account-Meta-Temp-Url-Key'),
|
||||||
secret)
|
secret)
|
||||||
|
|
||||||
@ -688,17 +693,17 @@ class TestAccount(unittest.TestCase):
|
|||||||
if (tf.web_front_end == 'integral'):
|
if (tf.web_front_end == 'integral'):
|
||||||
resp = retry(post, uni_key, '1')
|
resp = retry(post, uni_key, '1')
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertTrue(resp.status in (201, 204))
|
self.assertIn(resp.status, (201, 204))
|
||||||
resp = retry(head)
|
resp = retry(head)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assert_(resp.status in (200, 204), resp.status)
|
self.assertIn(resp.status, (200, 204))
|
||||||
self.assertEqual(resp.getheader(uni_key.encode('utf-8')), '1')
|
self.assertEqual(resp.getheader(uni_key.encode('utf-8')), '1')
|
||||||
resp = retry(post, 'X-Account-Meta-uni', uni_value)
|
resp = retry(post, 'X-Account-Meta-uni', uni_value)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEqual(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
resp = retry(head)
|
resp = retry(head)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assert_(resp.status in (200, 204), resp.status)
|
self.assertIn(resp.status, (200, 204))
|
||||||
self.assertEqual(resp.getheader('X-Account-Meta-uni'),
|
self.assertEqual(resp.getheader('X-Account-Meta-uni'),
|
||||||
uni_value.encode('utf-8'))
|
uni_value.encode('utf-8'))
|
||||||
if (tf.web_front_end == 'integral'):
|
if (tf.web_front_end == 'integral'):
|
||||||
@ -707,7 +712,7 @@ class TestAccount(unittest.TestCase):
|
|||||||
self.assertEqual(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
resp = retry(head)
|
resp = retry(head)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assert_(resp.status in (200, 204), resp.status)
|
self.assertIn(resp.status, (200, 204))
|
||||||
self.assertEqual(resp.getheader(uni_key.encode('utf-8')),
|
self.assertEqual(resp.getheader(uni_key.encode('utf-8')),
|
||||||
uni_value.encode('utf-8'))
|
uni_value.encode('utf-8'))
|
||||||
|
|
||||||
@ -729,24 +734,23 @@ class TestAccount(unittest.TestCase):
|
|||||||
self.assertEqual(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
resp = retry(head)
|
resp = retry(head)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assert_(resp.status in (200, 204), resp.status)
|
self.assertIn(resp.status, (200, 204))
|
||||||
self.assertEqual(resp.getheader('x-account-meta-one'), '1')
|
self.assertEqual(resp.getheader('x-account-meta-one'), '1')
|
||||||
resp = retry(post, 'X-Account-Meta-Two', '2')
|
resp = retry(post, 'X-Account-Meta-Two', '2')
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEqual(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
resp = retry(head)
|
resp = retry(head)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assert_(resp.status in (200, 204), resp.status)
|
self.assertIn(resp.status, (200, 204))
|
||||||
self.assertEqual(resp.getheader('x-account-meta-one'), '1')
|
self.assertEqual(resp.getheader('x-account-meta-one'), '1')
|
||||||
self.assertEqual(resp.getheader('x-account-meta-two'), '2')
|
self.assertEqual(resp.getheader('x-account-meta-two'), '2')
|
||||||
|
|
||||||
def test_bad_metadata(self):
|
def test_bad_metadata(self):
|
||||||
|
|
||||||
raise SkipTest('SOF constraints middleware enforces constraints.')
|
|
||||||
|
|
||||||
if tf.skip:
|
if tf.skip:
|
||||||
raise SkipTest
|
raise SkipTest
|
||||||
|
|
||||||
|
raise SkipTest('SOF constraints middleware enforces constraints.')
|
||||||
|
|
||||||
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)
|
||||||
@ -793,13 +797,13 @@ class TestAccount(unittest.TestCase):
|
|||||||
resp = retry(post, headers)
|
resp = retry(post, headers)
|
||||||
|
|
||||||
headers = {}
|
headers = {}
|
||||||
for x in xrange(self.max_meta_count):
|
for x in range(self.max_meta_count):
|
||||||
headers['X-Account-Meta-%d' % x] = 'v'
|
headers['X-Account-Meta-%d' % x] = 'v'
|
||||||
resp = retry(post, headers)
|
resp = retry(post, headers)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEqual(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
headers = {}
|
headers = {}
|
||||||
for x in xrange(self.max_meta_count + 1):
|
for x in range(self.max_meta_count + 1):
|
||||||
headers['X-Account-Meta-%d' % x] = 'v'
|
headers['X-Account-Meta-%d' % x] = 'v'
|
||||||
resp = retry(post, headers)
|
resp = retry(post, headers)
|
||||||
resp.read()
|
resp.read()
|
||||||
@ -830,8 +834,23 @@ class TestAccount(unittest.TestCase):
|
|||||||
resp = retry(post, headers)
|
resp = retry(post, headers)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEqual(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
|
# this POST includes metadata size that is over limit
|
||||||
headers['X-Account-Meta-k'] = \
|
headers['X-Account-Meta-k'] = \
|
||||||
'v' * (self.max_meta_overall_size - size)
|
'x' * (self.max_meta_overall_size - size)
|
||||||
|
resp = retry(post, headers)
|
||||||
|
resp.read()
|
||||||
|
self.assertEqual(resp.status, 400)
|
||||||
|
# this POST would be ok and the aggregate backend metadata
|
||||||
|
# size is on the border
|
||||||
|
headers = {'X-Account-Meta-k':
|
||||||
|
'y' * (self.max_meta_overall_size - size - 1)}
|
||||||
|
resp = retry(post, headers)
|
||||||
|
resp.read()
|
||||||
|
self.assertEqual(resp.status, 204)
|
||||||
|
# this last POST would be ok by itself but takes the aggregate
|
||||||
|
# backend metadata size over limit
|
||||||
|
headers = {'X-Account-Meta-k':
|
||||||
|
'z' * (self.max_meta_overall_size - size)}
|
||||||
resp = retry(post, headers)
|
resp = retry(post, headers)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEqual(resp.status, 400)
|
self.assertEqual(resp.status, 400)
|
||||||
@ -862,7 +881,7 @@ class TestAccountInNonDefaultDomain(unittest.TestCase):
|
|||||||
resp = retry(head, use_account=4)
|
resp = retry(head, use_account=4)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEqual(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
self.assertTrue('X-Account-Project-Domain-Id' in resp.headers)
|
self.assertIn('X-Account-Project-Domain-Id', resp.headers)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
@ -24,6 +24,8 @@ from test.functional import check_response, retry, requires_acls, \
|
|||||||
load_constraint, requires_policies
|
load_constraint, requires_policies
|
||||||
import test.functional as tf
|
import test.functional as tf
|
||||||
|
|
||||||
|
from six.moves import range
|
||||||
|
|
||||||
|
|
||||||
class TestContainer(unittest.TestCase):
|
class TestContainer(unittest.TestCase):
|
||||||
|
|
||||||
@ -70,7 +72,7 @@ class TestContainer(unittest.TestCase):
|
|||||||
body = resp.read()
|
body = resp.read()
|
||||||
if resp.status == 404:
|
if resp.status == 404:
|
||||||
break
|
break
|
||||||
self.assert_(resp.status // 100 == 2, resp.status)
|
self.assertTrue(resp.status // 100 == 2, resp.status)
|
||||||
objs = json.loads(body)
|
objs = json.loads(body)
|
||||||
if not objs:
|
if not objs:
|
||||||
break
|
break
|
||||||
@ -91,7 +93,7 @@ class TestContainer(unittest.TestCase):
|
|||||||
# container may have not been created
|
# container may have not been created
|
||||||
resp = retry(delete, self.container)
|
resp = retry(delete, self.container)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assert_(resp.status in (204, 404))
|
self.assertIn(resp.status, (204, 404))
|
||||||
|
|
||||||
def test_multi_metadata(self):
|
def test_multi_metadata(self):
|
||||||
if tf.skip:
|
if tf.skip:
|
||||||
@ -112,14 +114,14 @@ class TestContainer(unittest.TestCase):
|
|||||||
self.assertEqual(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
resp = retry(head)
|
resp = retry(head)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assert_(resp.status in (200, 204), resp.status)
|
self.assertIn(resp.status, (200, 204))
|
||||||
self.assertEqual(resp.getheader('x-container-meta-one'), '1')
|
self.assertEqual(resp.getheader('x-container-meta-one'), '1')
|
||||||
resp = retry(post, 'X-Container-Meta-Two', '2')
|
resp = retry(post, 'X-Container-Meta-Two', '2')
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEqual(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
resp = retry(head)
|
resp = retry(head)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assert_(resp.status in (200, 204), resp.status)
|
self.assertIn(resp.status, (200, 204))
|
||||||
self.assertEqual(resp.getheader('x-container-meta-one'), '1')
|
self.assertEqual(resp.getheader('x-container-meta-one'), '1')
|
||||||
self.assertEqual(resp.getheader('x-container-meta-two'), '2')
|
self.assertEqual(resp.getheader('x-container-meta-two'), '2')
|
||||||
|
|
||||||
@ -145,14 +147,14 @@ class TestContainer(unittest.TestCase):
|
|||||||
self.assertEqual(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
resp = retry(head)
|
resp = retry(head)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assert_(resp.status in (200, 204), resp.status)
|
self.assertIn(resp.status, (200, 204))
|
||||||
self.assertEqual(resp.getheader(uni_key.encode('utf-8')), '1')
|
self.assertEqual(resp.getheader(uni_key.encode('utf-8')), '1')
|
||||||
resp = retry(post, 'X-Container-Meta-uni', uni_value)
|
resp = retry(post, 'X-Container-Meta-uni', uni_value)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEqual(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
resp = retry(head)
|
resp = retry(head)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assert_(resp.status in (200, 204), resp.status)
|
self.assertIn(resp.status, (200, 204))
|
||||||
self.assertEqual(resp.getheader('X-Container-Meta-uni'),
|
self.assertEqual(resp.getheader('X-Container-Meta-uni'),
|
||||||
uni_value.encode('utf-8'))
|
uni_value.encode('utf-8'))
|
||||||
if (tf.web_front_end == 'integral'):
|
if (tf.web_front_end == 'integral'):
|
||||||
@ -161,7 +163,7 @@ class TestContainer(unittest.TestCase):
|
|||||||
self.assertEqual(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
resp = retry(head)
|
resp = retry(head)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assert_(resp.status in (200, 204), resp.status)
|
self.assertIn(resp.status, (200, 204))
|
||||||
self.assertEqual(resp.getheader(uni_key.encode('utf-8')),
|
self.assertEqual(resp.getheader(uni_key.encode('utf-8')),
|
||||||
uni_value.encode('utf-8'))
|
uni_value.encode('utf-8'))
|
||||||
|
|
||||||
@ -196,11 +198,11 @@ class TestContainer(unittest.TestCase):
|
|||||||
self.assertEqual(resp.status, 201)
|
self.assertEqual(resp.status, 201)
|
||||||
resp = retry(head, name)
|
resp = retry(head, name)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assert_(resp.status in (200, 204), resp.status)
|
self.assertIn(resp.status, (200, 204))
|
||||||
self.assertEqual(resp.getheader('x-container-meta-test'), 'Value')
|
self.assertEqual(resp.getheader('x-container-meta-test'), 'Value')
|
||||||
resp = retry(get, name)
|
resp = retry(get, name)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assert_(resp.status in (200, 204), resp.status)
|
self.assertIn(resp.status, (200, 204))
|
||||||
self.assertEqual(resp.getheader('x-container-meta-test'), 'Value')
|
self.assertEqual(resp.getheader('x-container-meta-test'), 'Value')
|
||||||
resp = retry(delete, name)
|
resp = retry(delete, name)
|
||||||
resp.read()
|
resp.read()
|
||||||
@ -212,11 +214,11 @@ class TestContainer(unittest.TestCase):
|
|||||||
self.assertEqual(resp.status, 201)
|
self.assertEqual(resp.status, 201)
|
||||||
resp = retry(head, name)
|
resp = retry(head, name)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assert_(resp.status in (200, 204), resp.status)
|
self.assertIn(resp.status, (200, 204))
|
||||||
self.assertEqual(resp.getheader('x-container-meta-test'), None)
|
self.assertEqual(resp.getheader('x-container-meta-test'), None)
|
||||||
resp = retry(get, name)
|
resp = retry(get, name)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assert_(resp.status in (200, 204), resp.status)
|
self.assertIn(resp.status, (200, 204))
|
||||||
self.assertEqual(resp.getheader('x-container-meta-test'), None)
|
self.assertEqual(resp.getheader('x-container-meta-test'), None)
|
||||||
resp = retry(delete, name)
|
resp = retry(delete, name)
|
||||||
resp.read()
|
resp.read()
|
||||||
@ -244,22 +246,22 @@ class TestContainer(unittest.TestCase):
|
|||||||
|
|
||||||
resp = retry(head)
|
resp = retry(head)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assert_(resp.status in (200, 204), resp.status)
|
self.assertIn(resp.status, (200, 204))
|
||||||
self.assertEqual(resp.getheader('x-container-meta-test'), None)
|
self.assertEqual(resp.getheader('x-container-meta-test'), None)
|
||||||
resp = retry(get)
|
resp = retry(get)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assert_(resp.status in (200, 204), resp.status)
|
self.assertIn(resp.status, (200, 204))
|
||||||
self.assertEqual(resp.getheader('x-container-meta-test'), None)
|
self.assertEqual(resp.getheader('x-container-meta-test'), None)
|
||||||
resp = retry(post, 'Value')
|
resp = retry(post, 'Value')
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEqual(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
resp = retry(head)
|
resp = retry(head)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assert_(resp.status in (200, 204), resp.status)
|
self.assertIn(resp.status, (200, 204))
|
||||||
self.assertEqual(resp.getheader('x-container-meta-test'), 'Value')
|
self.assertEqual(resp.getheader('x-container-meta-test'), 'Value')
|
||||||
resp = retry(get)
|
resp = retry(get)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assert_(resp.status in (200, 204), resp.status)
|
self.assertIn(resp.status, (200, 204))
|
||||||
self.assertEqual(resp.getheader('x-container-meta-test'), 'Value')
|
self.assertEqual(resp.getheader('x-container-meta-test'), 'Value')
|
||||||
|
|
||||||
def test_PUT_bad_metadata(self):
|
def test_PUT_bad_metadata(self):
|
||||||
@ -319,7 +321,7 @@ class TestContainer(unittest.TestCase):
|
|||||||
|
|
||||||
name = uuid4().hex
|
name = uuid4().hex
|
||||||
headers = {}
|
headers = {}
|
||||||
for x in xrange(self.max_meta_count):
|
for x in range(self.max_meta_count):
|
||||||
headers['X-Container-Meta-%d' % x] = 'v'
|
headers['X-Container-Meta-%d' % x] = 'v'
|
||||||
resp = retry(put, name, headers)
|
resp = retry(put, name, headers)
|
||||||
resp.read()
|
resp.read()
|
||||||
@ -329,7 +331,7 @@ class TestContainer(unittest.TestCase):
|
|||||||
self.assertEqual(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
name = uuid4().hex
|
name = uuid4().hex
|
||||||
headers = {}
|
headers = {}
|
||||||
for x in xrange(self.max_meta_count + 1):
|
for x in range(self.max_meta_count + 1):
|
||||||
headers['X-Container-Meta-%d' % x] = 'v'
|
headers['X-Container-Meta-%d' % x] = 'v'
|
||||||
resp = retry(put, name, headers)
|
resp = retry(put, name, headers)
|
||||||
resp.read()
|
resp.read()
|
||||||
@ -368,12 +370,11 @@ class TestContainer(unittest.TestCase):
|
|||||||
self.assertEqual(resp.status, 404)
|
self.assertEqual(resp.status, 404)
|
||||||
|
|
||||||
def test_POST_bad_metadata(self):
|
def test_POST_bad_metadata(self):
|
||||||
|
|
||||||
raise SkipTest('SOF constraints middleware enforces constraints.')
|
|
||||||
|
|
||||||
if tf.skip:
|
if tf.skip:
|
||||||
raise SkipTest
|
raise SkipTest
|
||||||
|
|
||||||
|
raise SkipTest('SOF constraints middleware enforces constraints.')
|
||||||
|
|
||||||
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)
|
||||||
@ -415,13 +416,13 @@ class TestContainer(unittest.TestCase):
|
|||||||
return check_response(conn)
|
return check_response(conn)
|
||||||
|
|
||||||
headers = {}
|
headers = {}
|
||||||
for x in xrange(self.max_meta_count):
|
for x in range(self.max_meta_count):
|
||||||
headers['X-Container-Meta-%d' % x] = 'v'
|
headers['X-Container-Meta-%d' % x] = 'v'
|
||||||
resp = retry(post, headers)
|
resp = retry(post, headers)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEqual(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
headers = {}
|
headers = {}
|
||||||
for x in xrange(self.max_meta_count + 1):
|
for x in range(self.max_meta_count + 1):
|
||||||
headers['X-Container-Meta-%d' % x] = 'v'
|
headers['X-Container-Meta-%d' % x] = 'v'
|
||||||
resp = retry(post, headers)
|
resp = retry(post, headers)
|
||||||
resp.read()
|
resp.read()
|
||||||
@ -452,8 +453,23 @@ class TestContainer(unittest.TestCase):
|
|||||||
resp = retry(post, headers)
|
resp = retry(post, headers)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEqual(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
|
# this POST includes metadata size that is over limit
|
||||||
headers['X-Container-Meta-k'] = \
|
headers['X-Container-Meta-k'] = \
|
||||||
'v' * (self.max_meta_overall_size - size)
|
'x' * (self.max_meta_overall_size - size)
|
||||||
|
resp = retry(post, headers)
|
||||||
|
resp.read()
|
||||||
|
self.assertEqual(resp.status, 400)
|
||||||
|
# this POST would be ok and the aggregate backend metadata
|
||||||
|
# size is on the border
|
||||||
|
headers = {'X-Container-Meta-k':
|
||||||
|
'y' * (self.max_meta_overall_size - size - 1)}
|
||||||
|
resp = retry(post, headers)
|
||||||
|
resp.read()
|
||||||
|
self.assertEqual(resp.status, 204)
|
||||||
|
# this last POST would be ok by itself but takes the aggregate
|
||||||
|
# backend metadata size over limit
|
||||||
|
headers = {'X-Container-Meta-k':
|
||||||
|
'z' * (self.max_meta_overall_size - size)}
|
||||||
resp = retry(post, headers)
|
resp = retry(post, headers)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEqual(resp.status, 400)
|
self.assertEqual(resp.status, 400)
|
||||||
@ -470,7 +486,7 @@ class TestContainer(unittest.TestCase):
|
|||||||
resp = retry(get)
|
resp = retry(get)
|
||||||
raise Exception('Should not have been able to GET')
|
raise Exception('Should not have been able to GET')
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
self.assert_(str(err).startswith('No result after '), err)
|
self.assertTrue(str(err).startswith('No result after '), err)
|
||||||
|
|
||||||
def post(url, token, parsed, conn):
|
def post(url, token, parsed, conn):
|
||||||
conn.request('POST', parsed.path + '/' + self.name, '',
|
conn.request('POST', parsed.path + '/' + self.name, '',
|
||||||
@ -497,7 +513,7 @@ class TestContainer(unittest.TestCase):
|
|||||||
resp = retry(get)
|
resp = retry(get)
|
||||||
raise Exception('Should not have been able to GET')
|
raise Exception('Should not have been able to GET')
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
self.assert_(str(err).startswith('No result after '), err)
|
self.assertTrue(str(err).startswith('No result after '), err)
|
||||||
|
|
||||||
def test_cross_account_container(self):
|
def test_cross_account_container(self):
|
||||||
if tf.skip or tf.skip2:
|
if tf.skip or tf.skip2:
|
||||||
@ -715,7 +731,7 @@ class TestContainer(unittest.TestCase):
|
|||||||
# cannot list containers
|
# cannot list containers
|
||||||
resp = retry(get, use_account=3)
|
resp = retry(get, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 403)
|
self.assertEqual(resp.status, 403)
|
||||||
|
|
||||||
# grant read-only access
|
# grant read-only access
|
||||||
acl_user = tf.swift_test_user[2]
|
acl_user = tf.swift_test_user[2]
|
||||||
@ -728,23 +744,23 @@ class TestContainer(unittest.TestCase):
|
|||||||
# read-only can list containers
|
# read-only can list containers
|
||||||
resp = retry(get, use_account=3)
|
resp = retry(get, use_account=3)
|
||||||
listing = resp.read()
|
listing = resp.read()
|
||||||
self.assertEquals(resp.status, 200)
|
self.assertEqual(resp.status, 200)
|
||||||
self.assert_(self.name in listing)
|
self.assertIn(self.name, listing)
|
||||||
|
|
||||||
# read-only can not create containers
|
# read-only can not create containers
|
||||||
new_container_name = str(uuid4())
|
new_container_name = str(uuid4())
|
||||||
resp = retry(put, new_container_name, use_account=3)
|
resp = retry(put, new_container_name, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 403)
|
self.assertEqual(resp.status, 403)
|
||||||
|
|
||||||
# but it can see newly created ones
|
# but it can see newly created ones
|
||||||
resp = retry(put, new_container_name, use_account=1)
|
resp = retry(put, new_container_name, use_account=1)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 201)
|
self.assertEqual(resp.status, 201)
|
||||||
resp = retry(get, use_account=3)
|
resp = retry(get, use_account=3)
|
||||||
listing = resp.read()
|
listing = resp.read()
|
||||||
self.assertEquals(resp.status, 200)
|
self.assertEqual(resp.status, 200)
|
||||||
self.assert_(new_container_name in listing)
|
self.assertIn(new_container_name, listing)
|
||||||
|
|
||||||
@requires_acls
|
@requires_acls
|
||||||
def test_read_only_acl_metadata(self):
|
def test_read_only_acl_metadata(self):
|
||||||
@ -774,13 +790,13 @@ class TestContainer(unittest.TestCase):
|
|||||||
self.assertEqual(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
resp = retry(get, self.name, use_account=1)
|
resp = retry(get, self.name, use_account=1)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
self.assertEqual(resp.getheader('X-Container-Meta-Test'), value)
|
self.assertEqual(resp.getheader('X-Container-Meta-Test'), value)
|
||||||
|
|
||||||
# cannot see metadata
|
# cannot see metadata
|
||||||
resp = retry(get, self.name, use_account=3)
|
resp = retry(get, self.name, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 403)
|
self.assertEqual(resp.status, 403)
|
||||||
|
|
||||||
# grant read-only access
|
# grant read-only access
|
||||||
acl_user = tf.swift_test_user[2]
|
acl_user = tf.swift_test_user[2]
|
||||||
@ -800,7 +816,7 @@ class TestContainer(unittest.TestCase):
|
|||||||
# read-only can read container metadata
|
# read-only can read container metadata
|
||||||
resp = retry(get, self.name, use_account=3)
|
resp = retry(get, self.name, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
self.assertEqual(resp.getheader('X-Container-Meta-Test'), value)
|
self.assertEqual(resp.getheader('X-Container-Meta-Test'), value)
|
||||||
|
|
||||||
@requires_acls
|
@requires_acls
|
||||||
@ -830,7 +846,7 @@ class TestContainer(unittest.TestCase):
|
|||||||
# cannot list containers
|
# cannot list containers
|
||||||
resp = retry(get, use_account=3)
|
resp = retry(get, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 403)
|
self.assertEqual(resp.status, 403)
|
||||||
|
|
||||||
# grant read-write access
|
# grant read-write access
|
||||||
acl_user = tf.swift_test_user[2]
|
acl_user = tf.swift_test_user[2]
|
||||||
@ -843,36 +859,36 @@ class TestContainer(unittest.TestCase):
|
|||||||
# can list containers
|
# can list containers
|
||||||
resp = retry(get, use_account=3)
|
resp = retry(get, use_account=3)
|
||||||
listing = resp.read()
|
listing = resp.read()
|
||||||
self.assertEquals(resp.status, 200)
|
self.assertEqual(resp.status, 200)
|
||||||
self.assert_(self.name in listing)
|
self.assertIn(self.name, listing)
|
||||||
|
|
||||||
# can create new containers
|
# can create new containers
|
||||||
new_container_name = str(uuid4())
|
new_container_name = str(uuid4())
|
||||||
resp = retry(put, new_container_name, use_account=3)
|
resp = retry(put, new_container_name, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 201)
|
self.assertEqual(resp.status, 201)
|
||||||
resp = retry(get, use_account=3)
|
resp = retry(get, use_account=3)
|
||||||
listing = resp.read()
|
listing = resp.read()
|
||||||
self.assertEquals(resp.status, 200)
|
self.assertEqual(resp.status, 200)
|
||||||
self.assert_(new_container_name in listing)
|
self.assertIn(new_container_name, listing)
|
||||||
|
|
||||||
# can also delete them
|
# can also delete them
|
||||||
resp = retry(delete, new_container_name, use_account=3)
|
resp = retry(delete, new_container_name, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
resp = retry(get, use_account=3)
|
resp = retry(get, use_account=3)
|
||||||
listing = resp.read()
|
listing = resp.read()
|
||||||
self.assertEquals(resp.status, 200)
|
self.assertEqual(resp.status, 200)
|
||||||
self.assert_(new_container_name not in listing)
|
self.assertNotIn(new_container_name, listing)
|
||||||
|
|
||||||
# even if they didn't create them
|
# even if they didn't create them
|
||||||
empty_container_name = str(uuid4())
|
empty_container_name = str(uuid4())
|
||||||
resp = retry(put, empty_container_name, use_account=1)
|
resp = retry(put, empty_container_name, use_account=1)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 201)
|
self.assertEqual(resp.status, 201)
|
||||||
resp = retry(delete, empty_container_name, use_account=3)
|
resp = retry(delete, empty_container_name, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
|
|
||||||
@requires_acls
|
@requires_acls
|
||||||
def test_read_write_acl_metadata(self):
|
def test_read_write_acl_metadata(self):
|
||||||
@ -902,13 +918,13 @@ class TestContainer(unittest.TestCase):
|
|||||||
self.assertEqual(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
resp = retry(get, self.name, use_account=1)
|
resp = retry(get, self.name, use_account=1)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
self.assertEqual(resp.getheader('X-Container-Meta-Test'), value)
|
self.assertEqual(resp.getheader('X-Container-Meta-Test'), value)
|
||||||
|
|
||||||
# cannot see metadata
|
# cannot see metadata
|
||||||
resp = retry(get, self.name, use_account=3)
|
resp = retry(get, self.name, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 403)
|
self.assertEqual(resp.status, 403)
|
||||||
|
|
||||||
# grant read-write access
|
# grant read-write access
|
||||||
acl_user = tf.swift_test_user[2]
|
acl_user = tf.swift_test_user[2]
|
||||||
@ -921,7 +937,7 @@ class TestContainer(unittest.TestCase):
|
|||||||
# read-write can read container metadata
|
# read-write can read container metadata
|
||||||
resp = retry(get, self.name, use_account=3)
|
resp = retry(get, self.name, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
self.assertEqual(resp.getheader('X-Container-Meta-Test'), value)
|
self.assertEqual(resp.getheader('X-Container-Meta-Test'), value)
|
||||||
|
|
||||||
# read-write can also write container metadata
|
# read-write can also write container metadata
|
||||||
@ -929,20 +945,20 @@ class TestContainer(unittest.TestCase):
|
|||||||
headers = {'x-container-meta-test': new_value}
|
headers = {'x-container-meta-test': new_value}
|
||||||
resp = retry(post, self.name, headers=headers, use_account=3)
|
resp = retry(post, self.name, headers=headers, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
resp = retry(get, self.name, use_account=3)
|
resp = retry(get, self.name, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
self.assertEqual(resp.getheader('X-Container-Meta-Test'), new_value)
|
self.assertEqual(resp.getheader('X-Container-Meta-Test'), new_value)
|
||||||
|
|
||||||
# and remove it
|
# and remove it
|
||||||
headers = {'x-remove-container-meta-test': 'true'}
|
headers = {'x-remove-container-meta-test': 'true'}
|
||||||
resp = retry(post, self.name, headers=headers, use_account=3)
|
resp = retry(post, self.name, headers=headers, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
resp = retry(get, self.name, use_account=3)
|
resp = retry(get, self.name, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
self.assertEqual(resp.getheader('X-Container-Meta-Test'), None)
|
self.assertEqual(resp.getheader('X-Container-Meta-Test'), None)
|
||||||
|
|
||||||
@requires_acls
|
@requires_acls
|
||||||
@ -972,7 +988,7 @@ class TestContainer(unittest.TestCase):
|
|||||||
# cannot list containers
|
# cannot list containers
|
||||||
resp = retry(get, use_account=3)
|
resp = retry(get, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 403)
|
self.assertEqual(resp.status, 403)
|
||||||
|
|
||||||
# grant admin access
|
# grant admin access
|
||||||
acl_user = tf.swift_test_user[2]
|
acl_user = tf.swift_test_user[2]
|
||||||
@ -985,36 +1001,36 @@ class TestContainer(unittest.TestCase):
|
|||||||
# can list containers
|
# can list containers
|
||||||
resp = retry(get, use_account=3)
|
resp = retry(get, use_account=3)
|
||||||
listing = resp.read()
|
listing = resp.read()
|
||||||
self.assertEquals(resp.status, 200)
|
self.assertEqual(resp.status, 200)
|
||||||
self.assert_(self.name in listing)
|
self.assertIn(self.name, listing)
|
||||||
|
|
||||||
# can create new containers
|
# can create new containers
|
||||||
new_container_name = str(uuid4())
|
new_container_name = str(uuid4())
|
||||||
resp = retry(put, new_container_name, use_account=3)
|
resp = retry(put, new_container_name, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 201)
|
self.assertEqual(resp.status, 201)
|
||||||
resp = retry(get, use_account=3)
|
resp = retry(get, use_account=3)
|
||||||
listing = resp.read()
|
listing = resp.read()
|
||||||
self.assertEquals(resp.status, 200)
|
self.assertEqual(resp.status, 200)
|
||||||
self.assert_(new_container_name in listing)
|
self.assertIn(new_container_name, listing)
|
||||||
|
|
||||||
# can also delete them
|
# can also delete them
|
||||||
resp = retry(delete, new_container_name, use_account=3)
|
resp = retry(delete, new_container_name, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
resp = retry(get, use_account=3)
|
resp = retry(get, use_account=3)
|
||||||
listing = resp.read()
|
listing = resp.read()
|
||||||
self.assertEquals(resp.status, 200)
|
self.assertEqual(resp.status, 200)
|
||||||
self.assert_(new_container_name not in listing)
|
self.assertNotIn(new_container_name, listing)
|
||||||
|
|
||||||
# even if they didn't create them
|
# even if they didn't create them
|
||||||
empty_container_name = str(uuid4())
|
empty_container_name = str(uuid4())
|
||||||
resp = retry(put, empty_container_name, use_account=1)
|
resp = retry(put, empty_container_name, use_account=1)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 201)
|
self.assertEqual(resp.status, 201)
|
||||||
resp = retry(delete, empty_container_name, use_account=3)
|
resp = retry(delete, empty_container_name, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
|
|
||||||
@requires_acls
|
@requires_acls
|
||||||
def test_admin_acl_metadata(self):
|
def test_admin_acl_metadata(self):
|
||||||
@ -1044,13 +1060,13 @@ class TestContainer(unittest.TestCase):
|
|||||||
self.assertEqual(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
resp = retry(get, self.name, use_account=1)
|
resp = retry(get, self.name, use_account=1)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
self.assertEqual(resp.getheader('X-Container-Meta-Test'), value)
|
self.assertEqual(resp.getheader('X-Container-Meta-Test'), value)
|
||||||
|
|
||||||
# cannot see metadata
|
# cannot see metadata
|
||||||
resp = retry(get, self.name, use_account=3)
|
resp = retry(get, self.name, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 403)
|
self.assertEqual(resp.status, 403)
|
||||||
|
|
||||||
# grant access
|
# grant access
|
||||||
acl_user = tf.swift_test_user[2]
|
acl_user = tf.swift_test_user[2]
|
||||||
@ -1063,7 +1079,7 @@ class TestContainer(unittest.TestCase):
|
|||||||
# can read container metadata
|
# can read container metadata
|
||||||
resp = retry(get, self.name, use_account=3)
|
resp = retry(get, self.name, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
self.assertEqual(resp.getheader('X-Container-Meta-Test'), value)
|
self.assertEqual(resp.getheader('X-Container-Meta-Test'), value)
|
||||||
|
|
||||||
# can also write container metadata
|
# can also write container metadata
|
||||||
@ -1071,20 +1087,20 @@ class TestContainer(unittest.TestCase):
|
|||||||
headers = {'x-container-meta-test': new_value}
|
headers = {'x-container-meta-test': new_value}
|
||||||
resp = retry(post, self.name, headers=headers, use_account=3)
|
resp = retry(post, self.name, headers=headers, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
resp = retry(get, self.name, use_account=3)
|
resp = retry(get, self.name, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
self.assertEqual(resp.getheader('X-Container-Meta-Test'), new_value)
|
self.assertEqual(resp.getheader('X-Container-Meta-Test'), new_value)
|
||||||
|
|
||||||
# and remove it
|
# and remove it
|
||||||
headers = {'x-remove-container-meta-test': 'true'}
|
headers = {'x-remove-container-meta-test': 'true'}
|
||||||
resp = retry(post, self.name, headers=headers, use_account=3)
|
resp = retry(post, self.name, headers=headers, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
resp = retry(get, self.name, use_account=3)
|
resp = retry(get, self.name, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
self.assertEqual(resp.getheader('X-Container-Meta-Test'), None)
|
self.assertEqual(resp.getheader('X-Container-Meta-Test'), None)
|
||||||
|
|
||||||
@requires_acls
|
@requires_acls
|
||||||
@ -1118,7 +1134,7 @@ class TestContainer(unittest.TestCase):
|
|||||||
self.assertEqual(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
resp = retry(get, self.name, use_account=1)
|
resp = retry(get, self.name, use_account=1)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
self.assertEqual(resp.getheader('X-Container-Sync-Key'), 'secret')
|
self.assertEqual(resp.getheader('X-Container-Sync-Key'), 'secret')
|
||||||
self.assertEqual(resp.getheader('X-Container-Meta-Test'), value)
|
self.assertEqual(resp.getheader('X-Container-Meta-Test'), value)
|
||||||
|
|
||||||
@ -1133,7 +1149,7 @@ class TestContainer(unittest.TestCase):
|
|||||||
# can read container metadata
|
# can read container metadata
|
||||||
resp = retry(get, self.name, use_account=3)
|
resp = retry(get, self.name, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
self.assertEqual(resp.getheader('X-Container-Meta-Test'), value)
|
self.assertEqual(resp.getheader('X-Container-Meta-Test'), value)
|
||||||
# but not sync-key
|
# but not sync-key
|
||||||
self.assertEqual(resp.getheader('X-Container-Sync-Key'), None)
|
self.assertEqual(resp.getheader('X-Container-Sync-Key'), None)
|
||||||
@ -1155,7 +1171,7 @@ class TestContainer(unittest.TestCase):
|
|||||||
# can read container metadata
|
# can read container metadata
|
||||||
resp = retry(get, self.name, use_account=3)
|
resp = retry(get, self.name, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
self.assertEqual(resp.getheader('X-Container-Meta-Test'), value)
|
self.assertEqual(resp.getheader('X-Container-Meta-Test'), value)
|
||||||
# but not sync-key
|
# but not sync-key
|
||||||
self.assertEqual(resp.getheader('X-Container-Sync-Key'), None)
|
self.assertEqual(resp.getheader('X-Container-Sync-Key'), None)
|
||||||
@ -1163,7 +1179,7 @@ class TestContainer(unittest.TestCase):
|
|||||||
# sanity check sync-key w/ account1
|
# sanity check sync-key w/ account1
|
||||||
resp = retry(get, self.name, use_account=1)
|
resp = retry(get, self.name, use_account=1)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
self.assertEqual(resp.getheader('X-Container-Sync-Key'), 'secret')
|
self.assertEqual(resp.getheader('X-Container-Sync-Key'), 'secret')
|
||||||
|
|
||||||
# and can write
|
# and can write
|
||||||
@ -1177,7 +1193,7 @@ class TestContainer(unittest.TestCase):
|
|||||||
self.assertEqual(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
resp = retry(get, self.name, use_account=1) # validate w/ account1
|
resp = retry(get, self.name, use_account=1) # validate w/ account1
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
self.assertEqual(resp.getheader('X-Container-Meta-Test'), new_value)
|
self.assertEqual(resp.getheader('X-Container-Meta-Test'), new_value)
|
||||||
# but can not write sync-key
|
# but can not write sync-key
|
||||||
self.assertEqual(resp.getheader('X-Container-Sync-Key'), 'secret')
|
self.assertEqual(resp.getheader('X-Container-Sync-Key'), 'secret')
|
||||||
@ -1193,7 +1209,7 @@ class TestContainer(unittest.TestCase):
|
|||||||
# admin can read container metadata
|
# admin can read container metadata
|
||||||
resp = retry(get, self.name, use_account=3)
|
resp = retry(get, self.name, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
self.assertEqual(resp.getheader('X-Container-Meta-Test'), new_value)
|
self.assertEqual(resp.getheader('X-Container-Meta-Test'), new_value)
|
||||||
# and ALSO sync-key
|
# and ALSO sync-key
|
||||||
self.assertEqual(resp.getheader('X-Container-Sync-Key'), 'secret')
|
self.assertEqual(resp.getheader('X-Container-Sync-Key'), 'secret')
|
||||||
@ -1206,7 +1222,7 @@ class TestContainer(unittest.TestCase):
|
|||||||
self.assertEqual(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
resp = retry(get, self.name, use_account=3)
|
resp = retry(get, self.name, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
self.assertEqual(resp.getheader('X-Container-Sync-Key'), new_secret)
|
self.assertEqual(resp.getheader('X-Container-Sync-Key'), new_secret)
|
||||||
|
|
||||||
@requires_acls
|
@requires_acls
|
||||||
@ -1241,7 +1257,7 @@ class TestContainer(unittest.TestCase):
|
|||||||
self.assertEqual(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
resp = retry(get, self.name, use_account=1)
|
resp = retry(get, self.name, use_account=1)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
self.assertEqual(resp.getheader('X-Container-Read'), 'jdoe')
|
self.assertEqual(resp.getheader('X-Container-Read'), 'jdoe')
|
||||||
self.assertEqual(resp.getheader('X-Container-Write'), 'jdoe')
|
self.assertEqual(resp.getheader('X-Container-Write'), 'jdoe')
|
||||||
self.assertEqual(resp.getheader('X-Container-Meta-Test'), value)
|
self.assertEqual(resp.getheader('X-Container-Meta-Test'), value)
|
||||||
@ -1257,7 +1273,7 @@ class TestContainer(unittest.TestCase):
|
|||||||
# can read container metadata
|
# can read container metadata
|
||||||
resp = retry(get, self.name, use_account=3)
|
resp = retry(get, self.name, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
self.assertEqual(resp.getheader('X-Container-Meta-Test'), value)
|
self.assertEqual(resp.getheader('X-Container-Meta-Test'), value)
|
||||||
# but not container acl
|
# but not container acl
|
||||||
self.assertEqual(resp.getheader('X-Container-Read'), None)
|
self.assertEqual(resp.getheader('X-Container-Read'), None)
|
||||||
@ -1283,7 +1299,7 @@ class TestContainer(unittest.TestCase):
|
|||||||
# can read container metadata
|
# can read container metadata
|
||||||
resp = retry(get, self.name, use_account=3)
|
resp = retry(get, self.name, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
self.assertEqual(resp.getheader('X-Container-Meta-Test'), value)
|
self.assertEqual(resp.getheader('X-Container-Meta-Test'), value)
|
||||||
# but not container acl
|
# but not container acl
|
||||||
self.assertEqual(resp.getheader('X-Container-Read'), None)
|
self.assertEqual(resp.getheader('X-Container-Read'), None)
|
||||||
@ -1292,7 +1308,7 @@ class TestContainer(unittest.TestCase):
|
|||||||
# sanity check container acls with account1
|
# sanity check container acls with account1
|
||||||
resp = retry(get, self.name, use_account=1)
|
resp = retry(get, self.name, use_account=1)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
self.assertEqual(resp.getheader('X-Container-Read'), 'jdoe')
|
self.assertEqual(resp.getheader('X-Container-Read'), 'jdoe')
|
||||||
self.assertEqual(resp.getheader('X-Container-Write'), 'jdoe')
|
self.assertEqual(resp.getheader('X-Container-Write'), 'jdoe')
|
||||||
|
|
||||||
@ -1308,7 +1324,7 @@ class TestContainer(unittest.TestCase):
|
|||||||
self.assertEqual(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
resp = retry(get, self.name, use_account=1) # validate w/ account1
|
resp = retry(get, self.name, use_account=1) # validate w/ account1
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
self.assertEqual(resp.getheader('X-Container-Meta-Test'), new_value)
|
self.assertEqual(resp.getheader('X-Container-Meta-Test'), new_value)
|
||||||
# but can not write container acls
|
# but can not write container acls
|
||||||
self.assertEqual(resp.getheader('X-Container-Read'), 'jdoe')
|
self.assertEqual(resp.getheader('X-Container-Read'), 'jdoe')
|
||||||
@ -1325,7 +1341,7 @@ class TestContainer(unittest.TestCase):
|
|||||||
# admin can read container metadata
|
# admin can read container metadata
|
||||||
resp = retry(get, self.name, use_account=3)
|
resp = retry(get, self.name, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
self.assertEqual(resp.getheader('X-Container-Meta-Test'), new_value)
|
self.assertEqual(resp.getheader('X-Container-Meta-Test'), new_value)
|
||||||
# and ALSO container acls
|
# and ALSO container acls
|
||||||
self.assertEqual(resp.getheader('X-Container-Read'), 'jdoe')
|
self.assertEqual(resp.getheader('X-Container-Read'), 'jdoe')
|
||||||
@ -1341,7 +1357,7 @@ class TestContainer(unittest.TestCase):
|
|||||||
self.assertEqual(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
resp = retry(get, self.name, use_account=3)
|
resp = retry(get, self.name, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
self.assertEqual(resp.getheader('X-Container-Read'), '.r:*')
|
self.assertEqual(resp.getheader('X-Container-Read'), '.r:*')
|
||||||
|
|
||||||
def test_long_name_content_type(self):
|
def test_long_name_content_type(self):
|
||||||
@ -1384,8 +1400,11 @@ class TestContainer(unittest.TestCase):
|
|||||||
raise SkipTest()
|
raise SkipTest()
|
||||||
|
|
||||||
def put(url, token, parsed, conn):
|
def put(url, token, parsed, conn):
|
||||||
|
# using the empty storage policy header value here to ensure
|
||||||
|
# that the default policy is chosen in case policy_specified is set
|
||||||
|
# see __init__.py for details on policy_specified
|
||||||
conn.request('PUT', parsed.path + '/' + self.container, '',
|
conn.request('PUT', parsed.path + '/' + self.container, '',
|
||||||
{'X-Auth-Token': token})
|
{'X-Auth-Token': token, 'X-Storage-Policy': ''})
|
||||||
return check_response(conn)
|
return check_response(conn)
|
||||||
resp = retry(put)
|
resp = retry(put)
|
||||||
resp.read()
|
resp.read()
|
||||||
@ -1398,8 +1417,8 @@ class TestContainer(unittest.TestCase):
|
|||||||
resp = retry(head)
|
resp = retry(head)
|
||||||
resp.read()
|
resp.read()
|
||||||
headers = dict((k.lower(), v) for k, v in resp.getheaders())
|
headers = dict((k.lower(), v) for k, v in resp.getheaders())
|
||||||
self.assertEquals(headers.get('x-storage-policy'),
|
self.assertEqual(headers.get('x-storage-policy'),
|
||||||
default_policy['name'])
|
default_policy['name'])
|
||||||
|
|
||||||
def test_error_invalid_storage_policy_name(self):
|
def test_error_invalid_storage_policy_name(self):
|
||||||
def put(url, token, parsed, conn, headers):
|
def put(url, token, parsed, conn, headers):
|
||||||
@ -1436,8 +1455,8 @@ class TestContainer(unittest.TestCase):
|
|||||||
resp = retry(head)
|
resp = retry(head)
|
||||||
resp.read()
|
resp.read()
|
||||||
headers = dict((k.lower(), v) for k, v in resp.getheaders())
|
headers = dict((k.lower(), v) for k, v in resp.getheaders())
|
||||||
self.assertEquals(headers.get('x-storage-policy'),
|
self.assertEqual(headers.get('x-storage-policy'),
|
||||||
policy['name'])
|
policy['name'])
|
||||||
|
|
||||||
# and test recreate with-out specifying Storage Policy
|
# and test recreate with-out specifying Storage Policy
|
||||||
resp = retry(put)
|
resp = retry(put)
|
||||||
@ -1447,8 +1466,8 @@ class TestContainer(unittest.TestCase):
|
|||||||
resp = retry(head)
|
resp = retry(head)
|
||||||
resp.read()
|
resp.read()
|
||||||
headers = dict((k.lower(), v) for k, v in resp.getheaders())
|
headers = dict((k.lower(), v) for k, v in resp.getheaders())
|
||||||
self.assertEquals(headers.get('x-storage-policy'),
|
self.assertEqual(headers.get('x-storage-policy'),
|
||||||
policy['name'])
|
policy['name'])
|
||||||
|
|
||||||
# delete it
|
# delete it
|
||||||
def delete(url, token, parsed, conn):
|
def delete(url, token, parsed, conn):
|
||||||
@ -1463,7 +1482,7 @@ class TestContainer(unittest.TestCase):
|
|||||||
resp = retry(head)
|
resp = retry(head)
|
||||||
resp.read()
|
resp.read()
|
||||||
headers = dict((k.lower(), v) for k, v in resp.getheaders())
|
headers = dict((k.lower(), v) for k, v in resp.getheaders())
|
||||||
self.assertEquals(headers.get('x-storage-policy'), None)
|
self.assertEqual(headers.get('x-storage-policy'), None)
|
||||||
|
|
||||||
@requires_policies
|
@requires_policies
|
||||||
def test_conflict_change_storage_policy_with_put(self):
|
def test_conflict_change_storage_policy_with_put(self):
|
||||||
@ -1493,8 +1512,8 @@ class TestContainer(unittest.TestCase):
|
|||||||
resp = retry(head)
|
resp = retry(head)
|
||||||
resp.read()
|
resp.read()
|
||||||
headers = dict((k.lower(), v) for k, v in resp.getheaders())
|
headers = dict((k.lower(), v) for k, v in resp.getheaders())
|
||||||
self.assertEquals(headers.get('x-storage-policy'),
|
self.assertEqual(headers.get('x-storage-policy'),
|
||||||
policy['name'])
|
policy['name'])
|
||||||
|
|
||||||
@requires_policies
|
@requires_policies
|
||||||
def test_noop_change_storage_policy_with_post(self):
|
def test_noop_change_storage_policy_with_post(self):
|
||||||
@ -1530,8 +1549,8 @@ class TestContainer(unittest.TestCase):
|
|||||||
resp = retry(head)
|
resp = retry(head)
|
||||||
resp.read()
|
resp.read()
|
||||||
headers = dict((k.lower(), v) for k, v in resp.getheaders())
|
headers = dict((k.lower(), v) for k, v in resp.getheaders())
|
||||||
self.assertEquals(headers.get('x-storage-policy'),
|
self.assertEqual(headers.get('x-storage-policy'),
|
||||||
policy['name'])
|
policy['name'])
|
||||||
|
|
||||||
|
|
||||||
class BaseTestContainerACLs(unittest.TestCase):
|
class BaseTestContainerACLs(unittest.TestCase):
|
||||||
@ -1578,7 +1597,7 @@ class BaseTestContainerACLs(unittest.TestCase):
|
|||||||
while True:
|
while True:
|
||||||
resp = retry(get, use_account=self.account)
|
resp = retry(get, use_account=self.account)
|
||||||
body = resp.read()
|
body = resp.read()
|
||||||
self.assert_(resp.status // 100 == 2, resp.status)
|
self.assertTrue(resp.status // 100 == 2, resp.status)
|
||||||
objs = json.loads(body)
|
objs = json.loads(body)
|
||||||
if not objs:
|
if not objs:
|
||||||
break
|
break
|
||||||
|
@ -15,11 +15,12 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
import json
|
||||||
import unittest
|
import unittest
|
||||||
from nose import SkipTest
|
from nose import SkipTest
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
|
||||||
from swift.common.utils import json
|
from six.moves import range
|
||||||
|
|
||||||
from test.functional import check_response, retry, requires_acls, \
|
from test.functional import check_response, retry, requires_acls, \
|
||||||
requires_policies
|
requires_policies
|
||||||
@ -88,7 +89,7 @@ class TestObject(unittest.TestCase):
|
|||||||
body = resp.read()
|
body = resp.read()
|
||||||
if resp.status == 404:
|
if resp.status == 404:
|
||||||
break
|
break
|
||||||
self.assert_(resp.status // 100 == 2, resp.status)
|
self.assertTrue(resp.status // 100 == 2, resp.status)
|
||||||
objs = json.loads(body)
|
objs = json.loads(body)
|
||||||
if not objs:
|
if not objs:
|
||||||
break
|
break
|
||||||
@ -106,7 +107,7 @@ class TestObject(unittest.TestCase):
|
|||||||
for container in self.containers:
|
for container in self.containers:
|
||||||
resp = retry(delete, container)
|
resp = retry(delete, container)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assert_(resp.status in (204, 404))
|
self.assertIn(resp.status, (204, 404))
|
||||||
|
|
||||||
def test_if_none_match(self):
|
def test_if_none_match(self):
|
||||||
def put(url, token, parsed, conn):
|
def put(url, token, parsed, conn):
|
||||||
@ -118,10 +119,10 @@ class TestObject(unittest.TestCase):
|
|||||||
return check_response(conn)
|
return check_response(conn)
|
||||||
resp = retry(put)
|
resp = retry(put)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 201)
|
self.assertEqual(resp.status, 201)
|
||||||
resp = retry(put)
|
resp = retry(put)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 412)
|
self.assertEqual(resp.status, 412)
|
||||||
|
|
||||||
def put(url, token, parsed, conn):
|
def put(url, token, parsed, conn):
|
||||||
conn.request('PUT', '%s/%s/%s' % (
|
conn.request('PUT', '%s/%s/%s' % (
|
||||||
@ -132,7 +133,7 @@ class TestObject(unittest.TestCase):
|
|||||||
return check_response(conn)
|
return check_response(conn)
|
||||||
resp = retry(put)
|
resp = retry(put)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 400)
|
self.assertEqual(resp.status, 400)
|
||||||
|
|
||||||
def test_non_integer_x_delete_after(self):
|
def test_non_integer_x_delete_after(self):
|
||||||
def put(url, token, parsed, conn):
|
def put(url, token, parsed, conn):
|
||||||
@ -144,7 +145,7 @@ class TestObject(unittest.TestCase):
|
|||||||
return check_response(conn)
|
return check_response(conn)
|
||||||
resp = retry(put)
|
resp = retry(put)
|
||||||
body = resp.read()
|
body = resp.read()
|
||||||
self.assertEquals(resp.status, 400)
|
self.assertEqual(resp.status, 400)
|
||||||
self.assertEqual(body, 'Non-integer X-Delete-After')
|
self.assertEqual(body, 'Non-integer X-Delete-After')
|
||||||
|
|
||||||
def test_non_integer_x_delete_at(self):
|
def test_non_integer_x_delete_at(self):
|
||||||
@ -157,7 +158,7 @@ class TestObject(unittest.TestCase):
|
|||||||
return check_response(conn)
|
return check_response(conn)
|
||||||
resp = retry(put)
|
resp = retry(put)
|
||||||
body = resp.read()
|
body = resp.read()
|
||||||
self.assertEquals(resp.status, 400)
|
self.assertEqual(resp.status, 400)
|
||||||
self.assertEqual(body, 'Non-integer X-Delete-At')
|
self.assertEqual(body, 'Non-integer X-Delete-At')
|
||||||
|
|
||||||
def test_x_delete_at_in_the_past(self):
|
def test_x_delete_at_in_the_past(self):
|
||||||
@ -170,7 +171,7 @@ class TestObject(unittest.TestCase):
|
|||||||
return check_response(conn)
|
return check_response(conn)
|
||||||
resp = retry(put)
|
resp = retry(put)
|
||||||
body = resp.read()
|
body = resp.read()
|
||||||
self.assertEquals(resp.status, 400)
|
self.assertEqual(resp.status, 400)
|
||||||
self.assertEqual(body, 'X-Delete-At in past')
|
self.assertEqual(body, 'X-Delete-At in past')
|
||||||
|
|
||||||
def test_copy_object(self):
|
def test_copy_object(self):
|
||||||
@ -242,6 +243,23 @@ class TestObject(unittest.TestCase):
|
|||||||
self.assertEqual(resp.status, 200)
|
self.assertEqual(resp.status, 200)
|
||||||
self.assertEqual(dest_contents, source_contents)
|
self.assertEqual(dest_contents, source_contents)
|
||||||
|
|
||||||
|
# copy source to dest with COPY and range
|
||||||
|
def copy(url, token, parsed, conn):
|
||||||
|
conn.request('COPY', '%s/%s' % (parsed.path, source), '',
|
||||||
|
{'X-Auth-Token': token,
|
||||||
|
'Destination': dest,
|
||||||
|
'Range': 'bytes=1-2'})
|
||||||
|
return check_response(conn)
|
||||||
|
resp = retry(copy)
|
||||||
|
resp.read()
|
||||||
|
self.assertEqual(resp.status, 201)
|
||||||
|
|
||||||
|
# contents of dest should be the same as source
|
||||||
|
resp = retry(get_dest)
|
||||||
|
dest_contents = resp.read()
|
||||||
|
self.assertEqual(resp.status, 200)
|
||||||
|
self.assertEqual(dest_contents, source_contents[1:3])
|
||||||
|
|
||||||
# delete the copy
|
# delete the copy
|
||||||
resp = retry(delete)
|
resp = retry(delete)
|
||||||
resp.read()
|
resp.read()
|
||||||
@ -369,7 +387,7 @@ class TestObject(unittest.TestCase):
|
|||||||
resp = retry(get)
|
resp = retry(get)
|
||||||
raise Exception('Should not have been able to GET')
|
raise Exception('Should not have been able to GET')
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
self.assert_(str(err).startswith('No result after '))
|
self.assertTrue(str(err).startswith('No result after '))
|
||||||
|
|
||||||
def post(url, token, parsed, conn):
|
def post(url, token, parsed, conn):
|
||||||
conn.request('POST', parsed.path + '/' + self.container, '',
|
conn.request('POST', parsed.path + '/' + self.container, '',
|
||||||
@ -394,7 +412,7 @@ class TestObject(unittest.TestCase):
|
|||||||
resp = retry(get)
|
resp = retry(get)
|
||||||
raise Exception('Should not have been able to GET')
|
raise Exception('Should not have been able to GET')
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
self.assert_(str(err).startswith('No result after '))
|
self.assertTrue(str(err).startswith('No result after '))
|
||||||
|
|
||||||
def test_private_object(self):
|
def test_private_object(self):
|
||||||
if tf.skip or tf.skip3:
|
if tf.skip or tf.skip3:
|
||||||
@ -525,12 +543,12 @@ class TestObject(unittest.TestCase):
|
|||||||
# cannot list objects
|
# cannot list objects
|
||||||
resp = retry(get_listing, use_account=3)
|
resp = retry(get_listing, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 403)
|
self.assertEqual(resp.status, 403)
|
||||||
|
|
||||||
# cannot get object
|
# cannot get object
|
||||||
resp = retry(get, self.obj, use_account=3)
|
resp = retry(get, self.obj, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 403)
|
self.assertEqual(resp.status, 403)
|
||||||
|
|
||||||
# grant read-only access
|
# grant read-only access
|
||||||
acl_user = tf.swift_test_user[2]
|
acl_user = tf.swift_test_user[2]
|
||||||
@ -543,32 +561,32 @@ class TestObject(unittest.TestCase):
|
|||||||
# can list objects
|
# can list objects
|
||||||
resp = retry(get_listing, use_account=3)
|
resp = retry(get_listing, use_account=3)
|
||||||
listing = resp.read()
|
listing = resp.read()
|
||||||
self.assertEquals(resp.status, 200)
|
self.assertEqual(resp.status, 200)
|
||||||
self.assert_(self.obj in listing)
|
self.assertIn(self.obj, listing)
|
||||||
|
|
||||||
# can get object
|
# can get object
|
||||||
resp = retry(get, self.obj, use_account=3)
|
resp = retry(get, self.obj, use_account=3)
|
||||||
body = resp.read()
|
body = resp.read()
|
||||||
self.assertEquals(resp.status, 200)
|
self.assertEqual(resp.status, 200)
|
||||||
self.assertEquals(body, 'test')
|
self.assertEqual(body, 'test')
|
||||||
|
|
||||||
# can not put an object
|
# can not put an object
|
||||||
obj_name = str(uuid4())
|
obj_name = str(uuid4())
|
||||||
resp = retry(put, obj_name, use_account=3)
|
resp = retry(put, obj_name, use_account=3)
|
||||||
body = resp.read()
|
body = resp.read()
|
||||||
self.assertEquals(resp.status, 403)
|
self.assertEqual(resp.status, 403)
|
||||||
|
|
||||||
# can not delete an object
|
# can not delete an object
|
||||||
resp = retry(delete, self.obj, use_account=3)
|
resp = retry(delete, self.obj, use_account=3)
|
||||||
body = resp.read()
|
body = resp.read()
|
||||||
self.assertEquals(resp.status, 403)
|
self.assertEqual(resp.status, 403)
|
||||||
|
|
||||||
# sanity with account1
|
# sanity with account1
|
||||||
resp = retry(get_listing, use_account=3)
|
resp = retry(get_listing, use_account=3)
|
||||||
listing = resp.read()
|
listing = resp.read()
|
||||||
self.assertEquals(resp.status, 200)
|
self.assertEqual(resp.status, 200)
|
||||||
self.assert_(obj_name not in listing)
|
self.assertNotIn(obj_name, listing)
|
||||||
self.assert_(self.obj in listing)
|
self.assertIn(self.obj, listing)
|
||||||
|
|
||||||
@requires_acls
|
@requires_acls
|
||||||
def test_read_write(self):
|
def test_read_write(self):
|
||||||
@ -606,12 +624,12 @@ class TestObject(unittest.TestCase):
|
|||||||
# cannot list objects
|
# cannot list objects
|
||||||
resp = retry(get_listing, use_account=3)
|
resp = retry(get_listing, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 403)
|
self.assertEqual(resp.status, 403)
|
||||||
|
|
||||||
# cannot get object
|
# cannot get object
|
||||||
resp = retry(get, self.obj, use_account=3)
|
resp = retry(get, self.obj, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 403)
|
self.assertEqual(resp.status, 403)
|
||||||
|
|
||||||
# grant read-write access
|
# grant read-write access
|
||||||
acl_user = tf.swift_test_user[2]
|
acl_user = tf.swift_test_user[2]
|
||||||
@ -624,32 +642,32 @@ class TestObject(unittest.TestCase):
|
|||||||
# can list objects
|
# can list objects
|
||||||
resp = retry(get_listing, use_account=3)
|
resp = retry(get_listing, use_account=3)
|
||||||
listing = resp.read()
|
listing = resp.read()
|
||||||
self.assertEquals(resp.status, 200)
|
self.assertEqual(resp.status, 200)
|
||||||
self.assert_(self.obj in listing)
|
self.assertIn(self.obj, listing)
|
||||||
|
|
||||||
# can get object
|
# can get object
|
||||||
resp = retry(get, self.obj, use_account=3)
|
resp = retry(get, self.obj, use_account=3)
|
||||||
body = resp.read()
|
body = resp.read()
|
||||||
self.assertEquals(resp.status, 200)
|
self.assertEqual(resp.status, 200)
|
||||||
self.assertEquals(body, 'test')
|
self.assertEqual(body, 'test')
|
||||||
|
|
||||||
# can put an object
|
# can put an object
|
||||||
obj_name = str(uuid4())
|
obj_name = str(uuid4())
|
||||||
resp = retry(put, obj_name, use_account=3)
|
resp = retry(put, obj_name, use_account=3)
|
||||||
body = resp.read()
|
body = resp.read()
|
||||||
self.assertEquals(resp.status, 201)
|
self.assertEqual(resp.status, 201)
|
||||||
|
|
||||||
# can delete an object
|
# can delete an object
|
||||||
resp = retry(delete, self.obj, use_account=3)
|
resp = retry(delete, self.obj, use_account=3)
|
||||||
body = resp.read()
|
body = resp.read()
|
||||||
self.assertEquals(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
|
|
||||||
# sanity with account1
|
# sanity with account1
|
||||||
resp = retry(get_listing, use_account=3)
|
resp = retry(get_listing, use_account=3)
|
||||||
listing = resp.read()
|
listing = resp.read()
|
||||||
self.assertEquals(resp.status, 200)
|
self.assertEqual(resp.status, 200)
|
||||||
self.assert_(obj_name in listing)
|
self.assertIn(obj_name, listing)
|
||||||
self.assert_(self.obj not in listing)
|
self.assertNotIn(self.obj, listing)
|
||||||
|
|
||||||
@requires_acls
|
@requires_acls
|
||||||
def test_admin(self):
|
def test_admin(self):
|
||||||
@ -687,12 +705,12 @@ class TestObject(unittest.TestCase):
|
|||||||
# cannot list objects
|
# cannot list objects
|
||||||
resp = retry(get_listing, use_account=3)
|
resp = retry(get_listing, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 403)
|
self.assertEqual(resp.status, 403)
|
||||||
|
|
||||||
# cannot get object
|
# cannot get object
|
||||||
resp = retry(get, self.obj, use_account=3)
|
resp = retry(get, self.obj, use_account=3)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 403)
|
self.assertEqual(resp.status, 403)
|
||||||
|
|
||||||
# grant admin access
|
# grant admin access
|
||||||
acl_user = tf.swift_test_user[2]
|
acl_user = tf.swift_test_user[2]
|
||||||
@ -705,32 +723,32 @@ class TestObject(unittest.TestCase):
|
|||||||
# can list objects
|
# can list objects
|
||||||
resp = retry(get_listing, use_account=3)
|
resp = retry(get_listing, use_account=3)
|
||||||
listing = resp.read()
|
listing = resp.read()
|
||||||
self.assertEquals(resp.status, 200)
|
self.assertEqual(resp.status, 200)
|
||||||
self.assert_(self.obj in listing)
|
self.assertIn(self.obj, listing)
|
||||||
|
|
||||||
# can get object
|
# can get object
|
||||||
resp = retry(get, self.obj, use_account=3)
|
resp = retry(get, self.obj, use_account=3)
|
||||||
body = resp.read()
|
body = resp.read()
|
||||||
self.assertEquals(resp.status, 200)
|
self.assertEqual(resp.status, 200)
|
||||||
self.assertEquals(body, 'test')
|
self.assertEqual(body, 'test')
|
||||||
|
|
||||||
# can put an object
|
# can put an object
|
||||||
obj_name = str(uuid4())
|
obj_name = str(uuid4())
|
||||||
resp = retry(put, obj_name, use_account=3)
|
resp = retry(put, obj_name, use_account=3)
|
||||||
body = resp.read()
|
body = resp.read()
|
||||||
self.assertEquals(resp.status, 201)
|
self.assertEqual(resp.status, 201)
|
||||||
|
|
||||||
# can delete an object
|
# can delete an object
|
||||||
resp = retry(delete, self.obj, use_account=3)
|
resp = retry(delete, self.obj, use_account=3)
|
||||||
body = resp.read()
|
body = resp.read()
|
||||||
self.assertEquals(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
|
|
||||||
# sanity with account1
|
# sanity with account1
|
||||||
resp = retry(get_listing, use_account=3)
|
resp = retry(get_listing, use_account=3)
|
||||||
listing = resp.read()
|
listing = resp.read()
|
||||||
self.assertEquals(resp.status, 200)
|
self.assertEqual(resp.status, 200)
|
||||||
self.assert_(obj_name in listing)
|
self.assertIn(obj_name, listing)
|
||||||
self.assert_(self.obj not in listing)
|
self.assertNotIn(self.obj, listing)
|
||||||
|
|
||||||
def test_manifest(self):
|
def test_manifest(self):
|
||||||
if tf.skip:
|
if tf.skip:
|
||||||
@ -746,7 +764,7 @@ class TestObject(unittest.TestCase):
|
|||||||
parsed.path, self.container, str(objnum)), segments1[objnum],
|
parsed.path, self.container, str(objnum)), segments1[objnum],
|
||||||
{'X-Auth-Token': token})
|
{'X-Auth-Token': token})
|
||||||
return check_response(conn)
|
return check_response(conn)
|
||||||
for objnum in xrange(len(segments1)):
|
for objnum in range(len(segments1)):
|
||||||
resp = retry(put, objnum)
|
resp = retry(put, objnum)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEqual(resp.status, 201)
|
self.assertEqual(resp.status, 201)
|
||||||
@ -809,7 +827,7 @@ class TestObject(unittest.TestCase):
|
|||||||
parsed.path, self.container, str(objnum)), segments2[objnum],
|
parsed.path, self.container, str(objnum)), segments2[objnum],
|
||||||
{'X-Auth-Token': token})
|
{'X-Auth-Token': token})
|
||||||
return check_response(conn)
|
return check_response(conn)
|
||||||
for objnum in xrange(len(segments2)):
|
for objnum in range(len(segments2)):
|
||||||
resp = retry(put, objnum)
|
resp = retry(put, objnum)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEqual(resp.status, 201)
|
self.assertEqual(resp.status, 201)
|
||||||
@ -891,7 +909,7 @@ class TestObject(unittest.TestCase):
|
|||||||
parsed.path, acontainer, str(objnum)), segments3[objnum],
|
parsed.path, acontainer, str(objnum)), segments3[objnum],
|
||||||
{'X-Auth-Token': token})
|
{'X-Auth-Token': token})
|
||||||
return check_response(conn)
|
return check_response(conn)
|
||||||
for objnum in xrange(len(segments3)):
|
for objnum in range(len(segments3)):
|
||||||
resp = retry(put, objnum)
|
resp = retry(put, objnum)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEqual(resp.status, 201)
|
self.assertEqual(resp.status, 201)
|
||||||
@ -966,7 +984,7 @@ class TestObject(unittest.TestCase):
|
|||||||
parsed.path, acontainer, str(objnum)), '',
|
parsed.path, acontainer, str(objnum)), '',
|
||||||
{'X-Auth-Token': token})
|
{'X-Auth-Token': token})
|
||||||
return check_response(conn)
|
return check_response(conn)
|
||||||
for objnum in xrange(len(segments3)):
|
for objnum in range(len(segments3)):
|
||||||
resp = retry(delete, objnum)
|
resp = retry(delete, objnum)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEqual(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
@ -977,7 +995,7 @@ class TestObject(unittest.TestCase):
|
|||||||
parsed.path, self.container, str(objnum)), '',
|
parsed.path, self.container, str(objnum)), '',
|
||||||
{'X-Auth-Token': token})
|
{'X-Auth-Token': token})
|
||||||
return check_response(conn)
|
return check_response(conn)
|
||||||
for objnum in xrange(len(segments2)):
|
for objnum in range(len(segments2)):
|
||||||
resp = retry(delete, objnum)
|
resp = retry(delete, objnum)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEqual(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
@ -988,7 +1006,7 @@ class TestObject(unittest.TestCase):
|
|||||||
parsed.path, self.container, str(objnum)), '',
|
parsed.path, self.container, str(objnum)), '',
|
||||||
{'X-Auth-Token': token})
|
{'X-Auth-Token': token})
|
||||||
return check_response(conn)
|
return check_response(conn)
|
||||||
for objnum in xrange(len(segments1)):
|
for objnum in range(len(segments1)):
|
||||||
resp = retry(delete, objnum)
|
resp = retry(delete, objnum)
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEqual(resp.status, 204)
|
self.assertEqual(resp.status, 204)
|
||||||
@ -1095,78 +1113,78 @@ class TestObject(unittest.TestCase):
|
|||||||
|
|
||||||
resp = retry(put_cors_cont, '*')
|
resp = retry(put_cors_cont, '*')
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status // 100, 2)
|
self.assertEqual(resp.status // 100, 2)
|
||||||
|
|
||||||
resp = retry(put_obj, 'cat')
|
resp = retry(put_obj, 'cat')
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status // 100, 2)
|
self.assertEqual(resp.status // 100, 2)
|
||||||
|
|
||||||
resp = retry(check_cors,
|
resp = retry(check_cors,
|
||||||
'OPTIONS', 'cat', {'Origin': 'http://m.com'})
|
'OPTIONS', 'cat', {'Origin': 'http://m.com'})
|
||||||
self.assertEquals(resp.status, 401)
|
self.assertEqual(resp.status, 401)
|
||||||
|
|
||||||
resp = retry(check_cors,
|
resp = retry(check_cors,
|
||||||
'OPTIONS', 'cat',
|
'OPTIONS', 'cat',
|
||||||
{'Origin': 'http://m.com',
|
{'Origin': 'http://m.com',
|
||||||
'Access-Control-Request-Method': 'GET'})
|
'Access-Control-Request-Method': 'GET'})
|
||||||
|
|
||||||
self.assertEquals(resp.status, 200)
|
self.assertEqual(resp.status, 200)
|
||||||
resp.read()
|
resp.read()
|
||||||
headers = dict((k.lower(), v) for k, v in resp.getheaders())
|
headers = dict((k.lower(), v) for k, v in resp.getheaders())
|
||||||
self.assertEquals(headers.get('access-control-allow-origin'),
|
self.assertEqual(headers.get('access-control-allow-origin'),
|
||||||
'*')
|
'*')
|
||||||
|
|
||||||
resp = retry(check_cors,
|
resp = retry(check_cors,
|
||||||
'GET', 'cat', {'Origin': 'http://m.com'})
|
'GET', 'cat', {'Origin': 'http://m.com'})
|
||||||
self.assertEquals(resp.status, 200)
|
self.assertEqual(resp.status, 200)
|
||||||
headers = dict((k.lower(), v) for k, v in resp.getheaders())
|
headers = dict((k.lower(), v) for k, v in resp.getheaders())
|
||||||
self.assertEquals(headers.get('access-control-allow-origin'),
|
self.assertEqual(headers.get('access-control-allow-origin'),
|
||||||
'*')
|
'*')
|
||||||
|
|
||||||
resp = retry(check_cors,
|
resp = retry(check_cors,
|
||||||
'GET', 'cat', {'Origin': 'http://m.com',
|
'GET', 'cat', {'Origin': 'http://m.com',
|
||||||
'X-Web-Mode': 'True'})
|
'X-Web-Mode': 'True'})
|
||||||
self.assertEquals(resp.status, 200)
|
self.assertEqual(resp.status, 200)
|
||||||
headers = dict((k.lower(), v) for k, v in resp.getheaders())
|
headers = dict((k.lower(), v) for k, v in resp.getheaders())
|
||||||
self.assertEquals(headers.get('access-control-allow-origin'),
|
self.assertEqual(headers.get('access-control-allow-origin'),
|
||||||
'*')
|
'*')
|
||||||
|
|
||||||
####################
|
####################
|
||||||
|
|
||||||
resp = retry(put_cors_cont, 'http://secret.com')
|
resp = retry(put_cors_cont, 'http://secret.com')
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status // 100, 2)
|
self.assertEqual(resp.status // 100, 2)
|
||||||
|
|
||||||
resp = retry(check_cors,
|
resp = retry(check_cors,
|
||||||
'OPTIONS', 'cat',
|
'OPTIONS', 'cat',
|
||||||
{'Origin': 'http://m.com',
|
{'Origin': 'http://m.com',
|
||||||
'Access-Control-Request-Method': 'GET'})
|
'Access-Control-Request-Method': 'GET'})
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 401)
|
self.assertEqual(resp.status, 401)
|
||||||
|
|
||||||
if strict_cors:
|
if strict_cors:
|
||||||
resp = retry(check_cors,
|
resp = retry(check_cors,
|
||||||
'GET', 'cat', {'Origin': 'http://m.com'})
|
'GET', 'cat', {'Origin': 'http://m.com'})
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 200)
|
self.assertEqual(resp.status, 200)
|
||||||
headers = dict((k.lower(), v) for k, v in resp.getheaders())
|
headers = dict((k.lower(), v) for k, v in resp.getheaders())
|
||||||
self.assertTrue('access-control-allow-origin' not in headers)
|
self.assertNotIn('access-control-allow-origin', headers)
|
||||||
|
|
||||||
resp = retry(check_cors,
|
resp = retry(check_cors,
|
||||||
'GET', 'cat', {'Origin': 'http://secret.com'})
|
'GET', 'cat', {'Origin': 'http://secret.com'})
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 200)
|
self.assertEqual(resp.status, 200)
|
||||||
headers = dict((k.lower(), v) for k, v in resp.getheaders())
|
headers = dict((k.lower(), v) for k, v in resp.getheaders())
|
||||||
self.assertEquals(headers.get('access-control-allow-origin'),
|
self.assertEqual(headers.get('access-control-allow-origin'),
|
||||||
'http://secret.com')
|
'http://secret.com')
|
||||||
else:
|
else:
|
||||||
resp = retry(check_cors,
|
resp = retry(check_cors,
|
||||||
'GET', 'cat', {'Origin': 'http://m.com'})
|
'GET', 'cat', {'Origin': 'http://m.com'})
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 200)
|
self.assertEqual(resp.status, 200)
|
||||||
headers = dict((k.lower(), v) for k, v in resp.getheaders())
|
headers = dict((k.lower(), v) for k, v in resp.getheaders())
|
||||||
self.assertEquals(headers.get('access-control-allow-origin'),
|
self.assertEqual(headers.get('access-control-allow-origin'),
|
||||||
'http://m.com')
|
'http://m.com')
|
||||||
|
|
||||||
@requires_policies
|
@requires_policies
|
||||||
def test_cross_policy_copy(self):
|
def test_cross_policy_copy(self):
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -15,10 +15,12 @@
|
|||||||
|
|
||||||
""" Swift tests """
|
""" Swift tests """
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
import os
|
import os
|
||||||
import copy
|
import copy
|
||||||
import logging
|
import logging
|
||||||
import errno
|
import errno
|
||||||
|
from six.moves import range
|
||||||
import sys
|
import sys
|
||||||
from contextlib import contextmanager, closing
|
from contextlib import contextmanager, closing
|
||||||
from collections import defaultdict, Iterable
|
from collections import defaultdict, Iterable
|
||||||
@ -30,17 +32,18 @@ import eventlet
|
|||||||
from eventlet.green import socket
|
from eventlet.green import socket
|
||||||
from tempfile import mkdtemp
|
from tempfile import mkdtemp
|
||||||
from shutil import rmtree
|
from shutil import rmtree
|
||||||
from swift.common.utils import Timestamp
|
from swift.common.utils import Timestamp, NOTICE
|
||||||
from test import get_config
|
from test import get_config
|
||||||
from swift.common import swob, utils
|
from swift.common import swob, utils
|
||||||
from swift.common.ring import Ring, RingData
|
from swift.common.ring import Ring, RingData
|
||||||
from hashlib import md5
|
from hashlib import md5
|
||||||
import logging.handlers
|
import logging.handlers
|
||||||
from httplib import HTTPException
|
|
||||||
|
from six.moves.http_client import HTTPException
|
||||||
from swift.common import storage_policy
|
from swift.common import storage_policy
|
||||||
from swift.common.storage_policy import StoragePolicy, ECStoragePolicy
|
from swift.common.storage_policy import StoragePolicy, ECStoragePolicy
|
||||||
import functools
|
import functools
|
||||||
import cPickle as pickle
|
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
|
||||||
@ -226,9 +229,7 @@ class FakeRing(Ring):
|
|||||||
return [dict(node, index=i) for i, node in enumerate(list(self._devs))]
|
return [dict(node, index=i) for i, node in enumerate(list(self._devs))]
|
||||||
|
|
||||||
def get_more_nodes(self, part):
|
def get_more_nodes(self, part):
|
||||||
# replicas^2 is the true cap
|
for x in range(self.replicas, (self.replicas + self.max_more_nodes)):
|
||||||
for x in xrange(self.replicas, min(self.replicas + self.max_more_nodes,
|
|
||||||
self.replicas * self.replicas)):
|
|
||||||
yield {'ip': '10.0.0.%s' % x,
|
yield {'ip': '10.0.0.%s' % x,
|
||||||
'replication_ip': '10.0.0.%s' % x,
|
'replication_ip': '10.0.0.%s' % x,
|
||||||
'port': self._base_port + x,
|
'port': self._base_port + x,
|
||||||
@ -478,8 +479,18 @@ class FakeLogger(logging.Logger, object):
|
|||||||
logging.INFO: 'info',
|
logging.INFO: 'info',
|
||||||
logging.DEBUG: 'debug',
|
logging.DEBUG: 'debug',
|
||||||
logging.CRITICAL: 'critical',
|
logging.CRITICAL: 'critical',
|
||||||
|
NOTICE: 'notice',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def notice(self, msg, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
Convenience function for syslog priority LOG_NOTICE. The python
|
||||||
|
logging lvl is set to 25, just above info. SysLogHandler is
|
||||||
|
monkey patched to map this log lvl to the LOG_NOTICE syslog
|
||||||
|
priority.
|
||||||
|
"""
|
||||||
|
self.log(NOTICE, msg, *args, **kwargs)
|
||||||
|
|
||||||
def _log(self, level, msg, *args, **kwargs):
|
def _log(self, level, msg, *args, **kwargs):
|
||||||
store_name = self.store_in[level]
|
store_name = self.store_in[level]
|
||||||
cargs = [msg]
|
cargs = [msg]
|
||||||
@ -495,7 +506,9 @@ class FakeLogger(logging.Logger, object):
|
|||||||
def _clear(self):
|
def _clear(self):
|
||||||
self.log_dict = defaultdict(list)
|
self.log_dict = defaultdict(list)
|
||||||
self.lines_dict = {'critical': [], 'error': [], 'info': [],
|
self.lines_dict = {'critical': [], 'error': [], 'info': [],
|
||||||
'warning': [], 'debug': []}
|
'warning': [], 'debug': [], 'notice': []}
|
||||||
|
|
||||||
|
clear = _clear # this is a public interface
|
||||||
|
|
||||||
def get_lines_for_level(self, level):
|
def get_lines_for_level(self, level):
|
||||||
if level not in self.lines_dict:
|
if level not in self.lines_dict:
|
||||||
@ -560,8 +573,8 @@ class FakeLogger(logging.Logger, object):
|
|||||||
try:
|
try:
|
||||||
line = record.getMessage()
|
line = record.getMessage()
|
||||||
except TypeError:
|
except TypeError:
|
||||||
print 'WARNING: unable to format log message %r %% %r' % (
|
print('WARNING: unable to format log message %r %% %r' % (
|
||||||
record.msg, record.args)
|
record.msg, record.args))
|
||||||
raise
|
raise
|
||||||
self.lines_dict[record.levelname.lower()].append(line)
|
self.lines_dict[record.levelname.lower()].append(line)
|
||||||
|
|
||||||
@ -585,7 +598,7 @@ class DebugLogger(FakeLogger):
|
|||||||
|
|
||||||
def handle(self, record):
|
def handle(self, record):
|
||||||
self._handle(record)
|
self._handle(record)
|
||||||
print self.formatter.format(record)
|
print(self.formatter.format(record))
|
||||||
|
|
||||||
|
|
||||||
class DebugLogAdapter(utils.LogAdapter):
|
class DebugLogAdapter(utils.LogAdapter):
|
||||||
@ -704,6 +717,74 @@ def mock(update):
|
|||||||
delattr(module, attr)
|
delattr(module, attr)
|
||||||
|
|
||||||
|
|
||||||
|
class FakeStatus(object):
|
||||||
|
"""
|
||||||
|
This will work with our fake_http_connect, if you hand in one of these
|
||||||
|
instead of a status int or status int tuple to the "codes" iter you can
|
||||||
|
add some eventlet sleep to the expect and response stages of the
|
||||||
|
connection.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, status, expect_sleep=None, response_sleep=None):
|
||||||
|
"""
|
||||||
|
:param status: the response status int, or a tuple of
|
||||||
|
([expect_status, ...], response_status)
|
||||||
|
:param expect_sleep: float, time to eventlet sleep during expect, can
|
||||||
|
be a iter of floats
|
||||||
|
:param response_sleep: float, time to eventlet sleep during response
|
||||||
|
"""
|
||||||
|
# connect exception
|
||||||
|
if isinstance(status, (Exception, eventlet.Timeout)):
|
||||||
|
raise status
|
||||||
|
if isinstance(status, tuple):
|
||||||
|
self.expect_status = list(status[:-1])
|
||||||
|
self.status = status[-1]
|
||||||
|
self.explicit_expect_list = True
|
||||||
|
else:
|
||||||
|
self.expect_status, self.status = ([], status)
|
||||||
|
self.explicit_expect_list = False
|
||||||
|
if not self.expect_status:
|
||||||
|
# when a swift backend service returns a status before reading
|
||||||
|
# from the body (mostly an error response) eventlet.wsgi will
|
||||||
|
# respond with that status line immediately instead of 100
|
||||||
|
# Continue, even if the client sent the Expect 100 header.
|
||||||
|
# BufferedHttp and the proxy both see these error statuses
|
||||||
|
# when they call getexpect, so our FakeConn tries to act like
|
||||||
|
# our backend services and return certain types of responses
|
||||||
|
# as expect statuses just like a real backend server would do.
|
||||||
|
if self.status in (507, 412, 409):
|
||||||
|
self.expect_status = [status]
|
||||||
|
else:
|
||||||
|
self.expect_status = [100, 100]
|
||||||
|
|
||||||
|
# setup sleep attributes
|
||||||
|
if not isinstance(expect_sleep, (list, tuple)):
|
||||||
|
expect_sleep = [expect_sleep] * len(self.expect_status)
|
||||||
|
self.expect_sleep_list = list(expect_sleep)
|
||||||
|
while len(self.expect_sleep_list) < len(self.expect_status):
|
||||||
|
self.expect_sleep_list.append(None)
|
||||||
|
self.response_sleep = response_sleep
|
||||||
|
|
||||||
|
def get_response_status(self):
|
||||||
|
if self.response_sleep is not None:
|
||||||
|
eventlet.sleep(self.response_sleep)
|
||||||
|
if self.expect_status and self.explicit_expect_list:
|
||||||
|
raise Exception('Test did not consume all fake '
|
||||||
|
'expect status: %r' % (self.expect_status,))
|
||||||
|
if isinstance(self.status, (Exception, eventlet.Timeout)):
|
||||||
|
raise self.status
|
||||||
|
return self.status
|
||||||
|
|
||||||
|
def get_expect_status(self):
|
||||||
|
expect_sleep = self.expect_sleep_list.pop(0)
|
||||||
|
if expect_sleep is not None:
|
||||||
|
eventlet.sleep(expect_sleep)
|
||||||
|
expect_status = self.expect_status.pop(0)
|
||||||
|
if isinstance(expect_status, (Exception, eventlet.Timeout)):
|
||||||
|
raise expect_status
|
||||||
|
return expect_status
|
||||||
|
|
||||||
|
|
||||||
class SlowBody(object):
|
class SlowBody(object):
|
||||||
"""
|
"""
|
||||||
This will work with our fake_http_connect, if you hand in these
|
This will work with our fake_http_connect, if you hand in these
|
||||||
@ -741,29 +822,9 @@ def fake_http_connect(*code_iter, **kwargs):
|
|||||||
def __init__(self, status, etag=None, body='', timestamp='1',
|
def __init__(self, status, etag=None, body='', timestamp='1',
|
||||||
headers=None, expect_headers=None, connection_id=None,
|
headers=None, expect_headers=None, connection_id=None,
|
||||||
give_send=None):
|
give_send=None):
|
||||||
# connect exception
|
if not isinstance(status, FakeStatus):
|
||||||
if isinstance(status, (Exception, eventlet.Timeout)):
|
status = FakeStatus(status)
|
||||||
raise status
|
self._status = status
|
||||||
if isinstance(status, tuple):
|
|
||||||
self.expect_status = list(status[:-1])
|
|
||||||
self.status = status[-1]
|
|
||||||
self.explicit_expect_list = True
|
|
||||||
else:
|
|
||||||
self.expect_status, self.status = ([], status)
|
|
||||||
self.explicit_expect_list = False
|
|
||||||
if not self.expect_status:
|
|
||||||
# when a swift backend service returns a status before reading
|
|
||||||
# from the body (mostly an error response) eventlet.wsgi will
|
|
||||||
# respond with that status line immediately instead of 100
|
|
||||||
# Continue, even if the client sent the Expect 100 header.
|
|
||||||
# BufferedHttp and the proxy both see these error statuses
|
|
||||||
# when they call getexpect, so our FakeConn tries to act like
|
|
||||||
# our backend services and return certain types of responses
|
|
||||||
# as expect statuses just like a real backend server would do.
|
|
||||||
if self.status in (507, 412, 409):
|
|
||||||
self.expect_status = [status]
|
|
||||||
else:
|
|
||||||
self.expect_status = [100, 100]
|
|
||||||
self.reason = 'Fake'
|
self.reason = 'Fake'
|
||||||
self.host = '1.2.3.4'
|
self.host = '1.2.3.4'
|
||||||
self.port = '1234'
|
self.port = '1234'
|
||||||
@ -785,11 +846,6 @@ def fake_http_connect(*code_iter, **kwargs):
|
|||||||
eventlet.sleep()
|
eventlet.sleep()
|
||||||
|
|
||||||
def getresponse(self):
|
def getresponse(self):
|
||||||
if self.expect_status and self.explicit_expect_list:
|
|
||||||
raise Exception('Test did not consume all fake '
|
|
||||||
'expect status: %r' % (self.expect_status,))
|
|
||||||
if isinstance(self.status, (Exception, eventlet.Timeout)):
|
|
||||||
raise self.status
|
|
||||||
exc = kwargs.get('raise_exc')
|
exc = kwargs.get('raise_exc')
|
||||||
if exc:
|
if exc:
|
||||||
if isinstance(exc, (Exception, eventlet.Timeout)):
|
if isinstance(exc, (Exception, eventlet.Timeout)):
|
||||||
@ -797,16 +853,19 @@ def fake_http_connect(*code_iter, **kwargs):
|
|||||||
raise Exception('test')
|
raise Exception('test')
|
||||||
if kwargs.get('raise_timeout_exc'):
|
if kwargs.get('raise_timeout_exc'):
|
||||||
raise eventlet.Timeout()
|
raise eventlet.Timeout()
|
||||||
|
self.status = self._status.get_response_status()
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def getexpect(self):
|
def getexpect(self):
|
||||||
expect_status = self.expect_status.pop(0)
|
expect_status = self._status.get_expect_status()
|
||||||
if isinstance(self.expect_status, (Exception, eventlet.Timeout)):
|
|
||||||
raise self.expect_status
|
|
||||||
headers = dict(self.expect_headers)
|
headers = dict(self.expect_headers)
|
||||||
if expect_status == 409:
|
if expect_status == 409:
|
||||||
headers['X-Backend-Timestamp'] = self.timestamp
|
headers['X-Backend-Timestamp'] = self.timestamp
|
||||||
return FakeConn(expect_status, headers=headers)
|
response = FakeConn(expect_status,
|
||||||
|
timestamp=self.timestamp,
|
||||||
|
headers=headers)
|
||||||
|
response.status = expect_status
|
||||||
|
return response
|
||||||
|
|
||||||
def getheaders(self):
|
def getheaders(self):
|
||||||
etag = self.etag
|
etag = self.etag
|
||||||
@ -834,7 +893,7 @@ def fake_http_connect(*code_iter, **kwargs):
|
|||||||
# when timestamp is None, HeaderKeyDict raises KeyError
|
# when timestamp is None, HeaderKeyDict raises KeyError
|
||||||
headers.pop('x-timestamp', None)
|
headers.pop('x-timestamp', None)
|
||||||
try:
|
try:
|
||||||
if container_ts_iter.next() is False:
|
if next(container_ts_iter) is False:
|
||||||
headers['x-container-timestamp'] = '1'
|
headers['x-container-timestamp'] = '1'
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
pass
|
pass
|
||||||
@ -911,24 +970,24 @@ def fake_http_connect(*code_iter, **kwargs):
|
|||||||
kwargs['give_content_type'](args[6]['Content-Type'])
|
kwargs['give_content_type'](args[6]['Content-Type'])
|
||||||
else:
|
else:
|
||||||
kwargs['give_content_type']('')
|
kwargs['give_content_type']('')
|
||||||
i, status = conn_id_and_code_iter.next()
|
i, status = next(conn_id_and_code_iter)
|
||||||
if 'give_connect' in kwargs:
|
if 'give_connect' in kwargs:
|
||||||
give_conn_fn = kwargs['give_connect']
|
give_conn_fn = kwargs['give_connect']
|
||||||
argspec = inspect.getargspec(give_conn_fn)
|
argspec = inspect.getargspec(give_conn_fn)
|
||||||
if argspec.keywords or 'connection_id' in argspec.args:
|
if argspec.keywords or 'connection_id' in argspec.args:
|
||||||
ckwargs['connection_id'] = i
|
ckwargs['connection_id'] = i
|
||||||
give_conn_fn(*args, **ckwargs)
|
give_conn_fn(*args, **ckwargs)
|
||||||
etag = etag_iter.next()
|
etag = next(etag_iter)
|
||||||
headers = headers_iter.next()
|
headers = next(headers_iter)
|
||||||
expect_headers = expect_headers_iter.next()
|
expect_headers = next(expect_headers_iter)
|
||||||
timestamp = timestamps_iter.next()
|
timestamp = next(timestamps_iter)
|
||||||
|
|
||||||
if status <= 0:
|
if status <= 0:
|
||||||
raise HTTPException()
|
raise HTTPException()
|
||||||
if body_iter is None:
|
if body_iter is None:
|
||||||
body = static_body or ''
|
body = static_body or ''
|
||||||
else:
|
else:
|
||||||
body = body_iter.next()
|
body = next(body_iter)
|
||||||
return FakeConn(status, etag, body=body, timestamp=timestamp,
|
return FakeConn(status, etag, body=body, timestamp=timestamp,
|
||||||
headers=headers, expect_headers=expect_headers,
|
headers=headers, expect_headers=expect_headers,
|
||||||
connection_id=i, give_send=kwargs.get('give_send'))
|
connection_id=i, give_send=kwargs.get('give_send'))
|
||||||
|
@ -207,9 +207,6 @@ class TestDiskFile(unittest.TestCase):
|
|||||||
assert not gdf._is_dir
|
assert not gdf._is_dir
|
||||||
assert gdf._fd is not None
|
assert gdf._fd is not None
|
||||||
assert gdf._metadata == exp_md
|
assert gdf._metadata == exp_md
|
||||||
self.assertRaises(DiskFileNotOpen, gdf.get_metadata)
|
|
||||||
self.assertRaises(DiskFileNotOpen, gdf.reader)
|
|
||||||
self.assertRaises(DiskFileNotOpen, gdf.__enter__)
|
|
||||||
|
|
||||||
def test_open_and_close(self):
|
def test_open_and_close(self):
|
||||||
mock_close = Mock()
|
mock_close = Mock()
|
||||||
@ -480,7 +477,6 @@ class TestDiskFile(unittest.TestCase):
|
|||||||
gdf = self._get_diskfile("vol0", "p57", "ufo47", "bar", "z")
|
gdf = self._get_diskfile("vol0", "p57", "ufo47", "bar", "z")
|
||||||
md = {'Content-Type': 'application/octet-stream', 'a': 'b'}
|
md = {'Content-Type': 'application/octet-stream', 'a': 'b'}
|
||||||
gdf.write_metadata(md.copy())
|
gdf.write_metadata(md.copy())
|
||||||
self.assertEqual(None, gdf._metadata)
|
|
||||||
fmd = _metadata[_mapit(the_dir)]
|
fmd = _metadata[_mapit(the_dir)]
|
||||||
md.update({'X-Object-Type': 'file', 'X-Type': 'Object'})
|
md.update({'X-Object-Type': 'file', 'X-Type': 'Object'})
|
||||||
self.assertTrue(fmd['a'], md['a'])
|
self.assertTrue(fmd['a'], md['a'])
|
||||||
|
32
tox.ini
32
tox.ini
@ -1,5 +1,5 @@
|
|||||||
[tox]
|
[tox]
|
||||||
envlist = py26,py27,pep8,functest,functest-ci
|
envlist = py27,pep8,functest
|
||||||
minversion = 1.6
|
minversion = 1.6
|
||||||
skipsdist = True
|
skipsdist = True
|
||||||
|
|
||||||
@ -15,11 +15,12 @@ deps =
|
|||||||
# Note: pip supports installing from git repos.
|
# Note: pip supports installing from git repos.
|
||||||
# https://pip.pypa.io/en/latest/reference/pip_install.html#git
|
# https://pip.pypa.io/en/latest/reference/pip_install.html#git
|
||||||
# Example: git+https://github.com/openstack/swift.git@2.0.0
|
# Example: git+https://github.com/openstack/swift.git@2.0.0
|
||||||
https://launchpad.net/swift/kilo/2.3.0/+download/swift-2.3.0.tar.gz
|
https://launchpad.net/swift/liberty/2.5.0/+download/swift-2.5.0.tar.gz
|
||||||
PyECLib==1.0.7
|
PyECLib==1.0.7
|
||||||
-r{toxinidir}/test-requirements.txt
|
-r{toxinidir}/test-requirements.txt
|
||||||
changedir = {toxinidir}/test/unit
|
changedir = {toxinidir}/test/unit
|
||||||
commands = nosetests -v {posargs}
|
commands = nosetests -v {posargs}
|
||||||
|
passenv = SWIFT_* *_proxy
|
||||||
|
|
||||||
[testenv:cover]
|
[testenv:cover]
|
||||||
setenv = VIRTUAL_ENV={envdir}
|
setenv = VIRTUAL_ENV={envdir}
|
||||||
@ -28,9 +29,6 @@ setenv = VIRTUAL_ENV={envdir}
|
|||||||
NOSE_COVER_HTML=1
|
NOSE_COVER_HTML=1
|
||||||
NOSE_COVER_HTML_DIR={toxinidir}/cover
|
NOSE_COVER_HTML_DIR={toxinidir}/cover
|
||||||
|
|
||||||
[tox:jenkins]
|
|
||||||
downloadcache = ~/cache/pip
|
|
||||||
|
|
||||||
[testenv:functest]
|
[testenv:functest]
|
||||||
changedir = {toxinidir}
|
changedir = {toxinidir}
|
||||||
commands = bash ./.functests -q
|
commands = bash ./.functests -q
|
||||||
@ -46,14 +44,20 @@ changedir = {toxinidir}
|
|||||||
commands = {posargs}
|
commands = {posargs}
|
||||||
|
|
||||||
[flake8]
|
[flake8]
|
||||||
# it's not a bug that we aren't using all of hacking
|
# it's not a bug that we aren't using all of hacking, ignore:
|
||||||
# H102 -> apache2 license exists
|
# F812: list comprehension redefines ...
|
||||||
# H103 -> license is apache
|
# H101: Use TODO(NAME)
|
||||||
# H201 -> no bare excepts (unless marked with " # noqa")
|
# H202: assertRaises Exception too broad
|
||||||
# H231 -> Check for except statements to be Python 3.x compatible
|
# H233: Python 3.x incompatible use of print operator
|
||||||
# H501 -> don't use locals() for str formatting
|
# H234: assertEquals is deprecated, use assertEqual
|
||||||
# H903 -> \n not \r\n
|
# H301: one import per line
|
||||||
ignore = H
|
# H306: imports not in alphabetical order (time, os)
|
||||||
select = F,E,W,H102,H103,H201,H231,H501,H903
|
# H401: docstring should not start with a space
|
||||||
|
# H403: multi line docstrings should end on a new line
|
||||||
|
# H404: multi line docstring should start without a leading new line
|
||||||
|
# H405: multi line docstring summary not separated with an empty line
|
||||||
|
# H501: Do not use self.__dict__ for string formatting
|
||||||
|
# H703: Multiple positional placeholders
|
||||||
|
ignore = F812,H101,H202,H233,H234,H301,H306,H401,H403,H404,H405,H501,H703
|
||||||
exclude = .venv,.tox,dist,doc,*egg,test
|
exclude = .venv,.tox,dist,doc,*egg,test
|
||||||
show-source = True
|
show-source = True
|
||||||
|
Loading…
Reference in New Issue
Block a user