summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gluster/swift/__init__.py2
m---------modules/swift0
-rw-r--r--test/functional/swift_test_client.py23
-rw-r--r--test/functional/tests.py79
-rw-r--r--test/unit/__init__.py6
-rw-r--r--test/unit/proxy/controllers/test_account.py102
-rw-r--r--test/unit/proxy/controllers/test_base.py113
-rw-r--r--test/unit/proxy/controllers/test_container.py62
-rw-r--r--test/unit/proxy/controllers/test_info.py293
-rw-r--r--test/unit/proxy/test_server.py561
-rw-r--r--tools/requirements.txt8
-rw-r--r--tools/test-requires2
-rw-r--r--tox.ini7
13 files changed, 994 insertions, 264 deletions
diff --git a/gluster/swift/__init__.py b/gluster/swift/__init__.py
index fbd38e6..9bfdc31 100644
--- a/gluster/swift/__init__.py
+++ b/gluster/swift/__init__.py
@@ -45,6 +45,6 @@ class PkgInfo(object):
###
### Change the Package version here
###
-_pkginfo = PkgInfo('1.10.2', '0', 'gluster_swift', False)
+_pkginfo = PkgInfo('1.11.0', '0', 'gluster_swift', False)
__version__ = _pkginfo.pretty_version
__canonical_version__ = _pkginfo.canonical_version
diff --git a/modules/swift b/modules/swift
-Subproject 4bfe6748fd8e746460f5428f3dd161c82b1443a
+Subproject f310006fae1af991097eee5929a1c73051eb1e0
diff --git a/test/functional/swift_test_client.py b/test/functional/swift_test_client.py
index d407a33..47e023e 100644
--- a/test/functional/swift_test_client.py
+++ b/test/functional/swift_test_client.py
@@ -65,7 +65,7 @@ class ResponseError(Exception):
def listing_empty(method):
- for i in xrange(0, 6):
+ for i in xrange(6):
if len(method()) == 0:
return True
@@ -208,7 +208,11 @@ class Connection(object):
def make_request(self, method, path=[], data='', hdrs={}, parms={},
cfg={}):
- path = self.make_path(path, cfg=cfg)
+ if not cfg.get('verbatim_path'):
+ # Set verbatim_path=True to make a request to exactly the given
+ # path, not storage path + given path. Useful for
+ # non-account/container/object requests.
+ path = self.make_path(path, cfg=cfg)
headers = self.make_headers(hdrs, cfg=cfg)
if isinstance(parms, dict) and parms:
quote = urllib.quote
@@ -719,7 +723,8 @@ class File(Base):
else:
raise RuntimeError
- def write(self, data='', hdrs={}, parms={}, callback=None, cfg={}):
+ def write(self, data='', hdrs={}, parms={}, callback=None, cfg={},
+ return_resp=False):
block_size = 2 ** 20
if isinstance(data, file):
@@ -763,6 +768,9 @@ class File(Base):
pass
self.md5 = self.compute_md5sum(data)
+ if return_resp:
+ return self.conn.response
+
return True
def write_random(self, size=None, hdrs={}, parms={}, cfg={}):
@@ -772,3 +780,12 @@ class File(Base):
self.conn.make_path(self.path))
self.md5 = self.compute_md5sum(StringIO.StringIO(data))
return data
+
+ def write_random_return_resp(self, size=None, hdrs={}, parms={}, cfg={}):
+ data = self.random_data(size)
+ resp = self.write(data, hdrs=hdrs, parms=parms, cfg=cfg,
+ return_resp=True)
+ if not resp:
+ raise ResponseError(self.conn.response)
+ self.md5 = self.compute_md5sum(StringIO.StringIO(data))
+ return resp
diff --git a/test/functional/tests.py b/test/functional/tests.py
index 808208d..e4b778b 100644
--- a/test/functional/tests.py
+++ b/test/functional/tests.py
@@ -1704,8 +1704,14 @@ class TestFileComparisonEnv:
file_item.write_random(cls.file_size)
cls.files.append(file_item)
- cls.time_old = time.asctime(time.localtime(time.time() - 86400))
- cls.time_new = time.asctime(time.localtime(time.time() + 86400))
+ cls.time_old_f1 = time.strftime("%a, %d %b %Y %H:%M:%S GMT",
+ time.gmtime(time.time() - 86400))
+ cls.time_old_f2 = time.strftime("%A, %d-%b-%y %H:%M:%S GMT",
+ time.gmtime(time.time() - 86400))
+ cls.time_old_f3 = time.strftime("%a %b %d %H:%M:%S %Y",
+ time.gmtime(time.time() - 86400))
+ cls.time_new = time.strftime("%a, %d %b %Y %H:%M:%S GMT",
+ time.gmtime(time.time() + 86400))
class TestFileComparison(Base):
@@ -1732,7 +1738,7 @@ class TestFileComparison(Base):
def testIfModifiedSince(self):
for file_item in self.env.files:
- hdrs = {'If-Modified-Since': self.env.time_old}
+ hdrs = {'If-Modified-Since': self.env.time_old_f1}
self.assert_(file_item.read(hdrs=hdrs))
hdrs = {'If-Modified-Since': self.env.time_new}
@@ -1744,7 +1750,7 @@ class TestFileComparison(Base):
hdrs = {'If-Unmodified-Since': self.env.time_new}
self.assert_(file_item.read(hdrs=hdrs))
- hdrs = {'If-Unmodified-Since': self.env.time_old}
+ hdrs = {'If-Unmodified-Since': self.env.time_old_f2}
self.assertRaises(ResponseError, file_item.read, hdrs=hdrs)
self.assert_status(412)
@@ -1760,10 +1766,32 @@ class TestFileComparison(Base):
self.assert_status(412)
hdrs = {'If-Match': file_item.md5,
- 'If-Unmodified-Since': self.env.time_old}
+ 'If-Unmodified-Since': self.env.time_old_f3}
self.assertRaises(ResponseError, file_item.read, hdrs=hdrs)
self.assert_status(412)
+ def testLastModified(self):
+ file_name = Utils.create_name()
+ content_type = Utils.create_name()
+
+ file = self.env.container.file(file_name)
+ file.content_type = content_type
+ resp = file.write_random_return_resp(self.env.file_size)
+ put_last_modified = resp.getheader('last-modified')
+
+ file = self.env.container.file(file_name)
+ info = file.info()
+ self.assert_('last_modified' in info)
+ last_modified = info['last_modified']
+ self.assertEqual(put_last_modified, info['last_modified'])
+
+ hdrs = {'If-Modified-Since': last_modified}
+ self.assertRaises(ResponseError, file.read, hdrs=hdrs)
+ self.assert_status(304)
+
+ hdrs = {'If-Unmodified-Since': last_modified}
+ self.assert_(file.read(hdrs=hdrs))
+
class TestFileComparisonUTF8(Base2, TestFileComparison):
set_up = False
@@ -1776,6 +1804,24 @@ class TestSloEnv(object):
def setUp(cls):
cls.conn = Connection(config)
cls.conn.authenticate()
+
+ if cls.slo_enabled is None:
+ status = cls.conn.make_request('GET', '/info',
+ cfg={'verbatim_path': True})
+ if not (200 <= status <= 299):
+ # Can't tell if SLO is enabled or not since we're running
+ # against an old cluster, so let's skip the tests instead of
+ # possibly having spurious failures.
+ cls.slo_enabled = False
+ else:
+ # Don't bother looking for ValueError here. If something is
+ # responding to a GET /info request with invalid JSON, then
+ # the cluster is broken and a test failure will let us know.
+ cluster_info = json.loads(cls.conn.response.read())
+ cls.slo_enabled = 'slo' in cluster_info
+ if not cls.slo_enabled:
+ return
+
cls.account = Account(cls.conn, config.get('account',
config['username']))
cls.account.delete_containers()
@@ -1785,28 +1831,6 @@ class TestSloEnv(object):
if not cls.container.create():
raise ResponseError(cls.conn.response)
- # TODO(seriously, anyone can do this): make this use the /info API once
- # it lands, both for detection of SLO and for minimum segment size
- if cls.slo_enabled is None:
- test_file = cls.container.file(".test-slo")
- try:
- # If SLO is enabled, this'll raise an error since
- # X-Static-Large-Object is a reserved header.
- #
- # If SLO is not enabled, then this will get the usual 2xx
- # response.
- test_file.write(
- "some contents",
- hdrs={'X-Static-Large-Object': 'true'})
- except ResponseError as err:
- if err.status == 400:
- cls.slo_enabled = True
- else:
- raise
- else:
- cls.slo_enabled = False
- return
-
seg_info = {}
for letter, size in (('a', 1024 * 1024),
('b', 1024 * 1024),
@@ -1865,6 +1889,7 @@ class TestSlo(Base):
set_up = False
def setUp(self):
+ raise SkipTest("SLO not enabled yet in gluster-swift")
super(TestSlo, self).setUp()
if self.env.slo_enabled is False:
raise SkipTest("SLO not enabled")
diff --git a/test/unit/__init__.py b/test/unit/__init__.py
index fa46715..847479a 100644
--- a/test/unit/__init__.py
+++ b/test/unit/__init__.py
@@ -17,9 +17,9 @@
import os
import copy
-import errno
import logging
-from sys import exc_info
+import errno
+import sys
from contextlib import contextmanager
from collections import defaultdict
from tempfile import NamedTemporaryFile
@@ -28,7 +28,7 @@ from eventlet.green import socket
from tempfile import mkdtemp
from shutil import rmtree
from test import get_config
-from swift.common.utils import config_true_value
+from swift.common.utils import config_true_value, LogAdapter
from hashlib import md5
from eventlet import sleep, Timeout
import logging.handlers
diff --git a/test/unit/proxy/controllers/test_account.py b/test/unit/proxy/controllers/test_account.py
index 394ada7..eefd57d 100644
--- a/test/unit/proxy/controllers/test_account.py
+++ b/test/unit/proxy/controllers/test_account.py
@@ -19,7 +19,9 @@ import unittest
from swift.common.swob import Request
from swift.proxy import server as proxy_server
from swift.proxy.controllers.base import headers_to_account_info
+from swift.common.constraints import MAX_ACCOUNT_NAME_LENGTH as MAX_ANAME_LEN
from test.unit import fake_http_connect, FakeRing, FakeMemcache
+from swift.common.request_helpers import get_sys_meta_prefix
class TestAccountController(unittest.TestCase):
@@ -32,8 +34,8 @@ class TestAccountController(unittest.TestCase):
def test_account_info_in_response_env(self):
controller = proxy_server.AccountController(self.app, 'AUTH_bob')
with mock.patch('swift.proxy.controllers.base.http_connect',
- fake_http_connect(200, 200, body='')):
- req = Request.blank('/AUTH_bob', {'PATH_INFO': '/AUTH_bob'})
+ fake_http_connect(200, body='')):
+ req = Request.blank('/v1/AUTH_bob', {'PATH_INFO': '/v1/AUTH_bob'})
resp = controller.HEAD(req)
self.assertEqual(2, resp.status_int // 100)
self.assertTrue('swift.account/AUTH_bob' in resp.environ)
@@ -46,22 +48,110 @@ class TestAccountController(unittest.TestCase):
'x-account-meta-temp-url-key-2': 'value'}
controller = proxy_server.AccountController(self.app, 'a')
- req = Request.blank('/a')
+ req = Request.blank('/v1/a')
with mock.patch('swift.proxy.controllers.base.http_connect',
- fake_http_connect(200, 200, headers=owner_headers)):
+ fake_http_connect(200, headers=owner_headers)):
resp = controller.HEAD(req)
self.assertEquals(2, resp.status_int // 100)
for key in owner_headers:
self.assertTrue(key not in resp.headers)
- req = Request.blank('/a', environ={'swift_owner': True})
+ req = Request.blank('/v1/a', environ={'swift_owner': True})
with mock.patch('swift.proxy.controllers.base.http_connect',
- fake_http_connect(200, 200, headers=owner_headers)):
+ fake_http_connect(200, headers=owner_headers)):
resp = controller.HEAD(req)
self.assertEquals(2, resp.status_int // 100)
for key in owner_headers:
self.assertTrue(key in resp.headers)
+ def test_get_deleted_account(self):
+ resp_headers = {
+ 'x-account-status': 'deleted',
+ }
+ controller = proxy_server.AccountController(self.app, 'a')
+
+ req = Request.blank('/v1/a')
+ with mock.patch('swift.proxy.controllers.base.http_connect',
+ fake_http_connect(404, headers=resp_headers)):
+ resp = controller.HEAD(req)
+ self.assertEquals(410, resp.status_int)
+
+ def test_long_acct_names(self):
+ long_acct_name = '%sLongAccountName' % ('Very' * (MAX_ANAME_LEN // 4))
+ controller = proxy_server.AccountController(self.app, long_acct_name)
+
+ req = Request.blank('/v1/%s' % long_acct_name)
+ with mock.patch('swift.proxy.controllers.base.http_connect',
+ fake_http_connect(200)):
+ resp = controller.HEAD(req)
+ self.assertEquals(400, resp.status_int)
+
+ with mock.patch('swift.proxy.controllers.base.http_connect',
+ fake_http_connect(200)):
+ resp = controller.GET(req)
+ self.assertEquals(400, resp.status_int)
+
+ with mock.patch('swift.proxy.controllers.base.http_connect',
+ fake_http_connect(200)):
+ resp = controller.POST(req)
+ self.assertEquals(400, resp.status_int)
+
+ def _make_callback_func(self, context):
+ def callback(ipaddr, port, device, partition, method, path,
+ headers=None, query_string=None, ssl=False):
+ context['method'] = method
+ context['path'] = path
+ context['headers'] = headers or {}
+ return callback
+
+ def test_sys_meta_headers_PUT(self):
+ # check that headers in sys meta namespace make it through
+ # the proxy controller
+ sys_meta_key = '%stest' % get_sys_meta_prefix('account')
+ sys_meta_key = sys_meta_key.title()
+ user_meta_key = 'X-Account-Meta-Test'
+ # allow PUTs to account...
+ self.app.allow_account_management = True
+ controller = proxy_server.AccountController(self.app, 'a')
+ context = {}
+ callback = self._make_callback_func(context)
+ hdrs_in = {sys_meta_key: 'foo',
+ user_meta_key: 'bar',
+ 'x-timestamp': '1.0'}
+ req = Request.blank('/v1/a', headers=hdrs_in)
+ with mock.patch('swift.proxy.controllers.base.http_connect',
+ fake_http_connect(200, 200, give_connect=callback)):
+ controller.PUT(req)
+ self.assertEqual(context['method'], 'PUT')
+ self.assertTrue(sys_meta_key in context['headers'])
+ self.assertEqual(context['headers'][sys_meta_key], 'foo')
+ self.assertTrue(user_meta_key in context['headers'])
+ self.assertEqual(context['headers'][user_meta_key], 'bar')
+ self.assertNotEqual(context['headers']['x-timestamp'], '1.0')
+
+ def test_sys_meta_headers_POST(self):
+ # check that headers in sys meta namespace make it through
+ # the proxy controller
+ sys_meta_key = '%stest' % get_sys_meta_prefix('account')
+ sys_meta_key = sys_meta_key.title()
+ user_meta_key = 'X-Account-Meta-Test'
+ controller = proxy_server.AccountController(self.app, 'a')
+ context = {}
+ callback = self._make_callback_func(context)
+ hdrs_in = {sys_meta_key: 'foo',
+ user_meta_key: 'bar',
+ 'x-timestamp': '1.0'}
+ req = Request.blank('/v1/a', headers=hdrs_in)
+ with mock.patch('swift.proxy.controllers.base.http_connect',
+ fake_http_connect(200, 200, give_connect=callback)):
+ controller.POST(req)
+ self.assertEqual(context['method'], 'POST')
+ self.assertTrue(sys_meta_key in context['headers'])
+ self.assertEqual(context['headers'][sys_meta_key], 'foo')
+ self.assertTrue(user_meta_key in context['headers'])
+ self.assertEqual(context['headers'][user_meta_key], 'bar')
+ self.assertNotEqual(context['headers']['x-timestamp'], '1.0')
+
if __name__ == '__main__':
unittest.main()
diff --git a/test/unit/proxy/controllers/test_base.py b/test/unit/proxy/controllers/test_base.py
index 8214b98..0c94f90 100644
--- a/test/unit/proxy/controllers/test_base.py
+++ b/test/unit/proxy/controllers/test_base.py
@@ -18,11 +18,13 @@ from mock import patch
from swift.proxy.controllers.base import headers_to_container_info, \
headers_to_account_info, headers_to_object_info, get_container_info, \
get_container_memcache_key, get_account_info, get_account_memcache_key, \
- get_object_env_key, _get_cache_key, get_info, get_object_info, Controller
-from swift.common.swob import Request
+ get_object_env_key, _get_cache_key, get_info, get_object_info, \
+ Controller, GetOrHeadHandler
+from swift.common.swob import Request, HTTPException, HeaderKeyDict
from swift.common.utils import split_path
from test.unit import fake_http_connect, FakeRing, FakeMemcache
from swift.proxy import server as proxy_server
+from swift.common.request_helpers import get_sys_meta_prefix
FakeResponse_status_int = 201
@@ -88,7 +90,7 @@ class TestFuncs(unittest.TestCase):
def test_GETorHEAD_base(self):
base = Controller(self.app)
- req = Request.blank('/a/c/o/with/slashes')
+ req = Request.blank('/v1/a/c/o/with/slashes')
with patch('swift.proxy.controllers.base.'
'http_connect', fake_http_connect(200)):
resp = base.GETorHEAD_base(req, 'object', FakeRing(), 'part',
@@ -96,14 +98,14 @@ class TestFuncs(unittest.TestCase):
self.assertTrue('swift.object/a/c/o/with/slashes' in resp.environ)
self.assertEqual(
resp.environ['swift.object/a/c/o/with/slashes']['status'], 200)
- req = Request.blank('/a/c/o')
+ req = Request.blank('/v1/a/c/o')
with patch('swift.proxy.controllers.base.'
'http_connect', fake_http_connect(200)):
resp = base.GETorHEAD_base(req, 'object', FakeRing(), 'part',
'/a/c/o')
self.assertTrue('swift.object/a/c/o' in resp.environ)
self.assertEqual(resp.environ['swift.object/a/c/o']['status'], 200)
- req = Request.blank('/a/c')
+ req = Request.blank('/v1/a/c')
with patch('swift.proxy.controllers.base.'
'http_connect', fake_http_connect(200)):
resp = base.GETorHEAD_base(req, 'container', FakeRing(), 'part',
@@ -111,7 +113,7 @@ class TestFuncs(unittest.TestCase):
self.assertTrue('swift.container/a/c' in resp.environ)
self.assertEqual(resp.environ['swift.container/a/c']['status'], 200)
- req = Request.blank('/a')
+ req = Request.blank('/v1/a')
with patch('swift.proxy.controllers.base.'
'http_connect', fake_http_connect(200)):
resp = base.GETorHEAD_base(req, 'account', FakeRing(), 'part',
@@ -250,7 +252,9 @@ class TestFuncs(unittest.TestCase):
def test_get_container_info_cache(self):
cached = {'status': 404,
'bytes': 3333,
- 'object_count': 10}
+ 'object_count': 10,
+ # simplejson sometimes hands back strings, sometimes unicodes
+ 'versions': u"\u1F4A9"}
req = Request.blank("/v1/account/cont",
environ={'swift.cache': FakeCache(cached)})
with patch('swift.proxy.controllers.base.'
@@ -259,6 +263,7 @@ class TestFuncs(unittest.TestCase):
self.assertEquals(resp['bytes'], 3333)
self.assertEquals(resp['object_count'], 10)
self.assertEquals(resp['status'], 404)
+ self.assertEquals(resp['versions'], "\xe1\xbd\x8a\x39")
def test_get_container_info_env(self):
cache_key = get_container_memcache_key("account", "cont")
@@ -361,6 +366,15 @@ class TestFuncs(unittest.TestCase):
self.assertEquals(resp['meta']['whatevs'], 14)
self.assertEquals(resp['meta']['somethingelse'], 0)
+ def test_headers_to_container_info_sys_meta(self):
+ prefix = get_sys_meta_prefix('container')
+ headers = {'%sWhatevs' % prefix: 14,
+ '%ssomethingelse' % prefix: 0}
+ resp = headers_to_container_info(headers.items(), 200)
+ self.assertEquals(len(resp['sysmeta']), 2)
+ self.assertEquals(resp['sysmeta']['whatevs'], 14)
+ self.assertEquals(resp['sysmeta']['somethingelse'], 0)
+
def test_headers_to_container_info_values(self):
headers = {
'x-container-read': 'readvalue',
@@ -392,6 +406,15 @@ class TestFuncs(unittest.TestCase):
self.assertEquals(resp['meta']['whatevs'], 14)
self.assertEquals(resp['meta']['somethingelse'], 0)
+ def test_headers_to_account_info_sys_meta(self):
+ prefix = get_sys_meta_prefix('account')
+ headers = {'%sWhatevs' % prefix: 14,
+ '%ssomethingelse' % prefix: 0}
+ resp = headers_to_account_info(headers.items(), 200)
+ self.assertEquals(len(resp['sysmeta']), 2)
+ self.assertEquals(resp['sysmeta']['whatevs'], 14)
+ self.assertEquals(resp['sysmeta']['somethingelse'], 0)
+
def test_headers_to_account_info_values(self):
headers = {
'x-account-object-count': '10',
@@ -433,3 +456,79 @@ class TestFuncs(unittest.TestCase):
self.assertEquals(
resp,
headers_to_object_info(headers.items(), 200))
+
+ def test_have_quorum(self):
+ base = Controller(self.app)
+ # just throw a bunch of test cases at it
+ self.assertEqual(base.have_quorum([201, 404], 3), False)
+ self.assertEqual(base.have_quorum([201, 201], 4), False)
+ self.assertEqual(base.have_quorum([201, 201, 404, 404], 4), False)
+ self.assertEqual(base.have_quorum([201, 503, 503, 201], 4), False)
+ self.assertEqual(base.have_quorum([201, 201], 3), True)
+ self.assertEqual(base.have_quorum([404, 404], 3), True)
+ self.assertEqual(base.have_quorum([201, 201], 2), True)
+ self.assertEqual(base.have_quorum([404, 404], 2), True)
+ self.assertEqual(base.have_quorum([201, 404, 201, 201], 4), True)
+
+ def test_range_fast_forward(self):
+ req = Request.blank('/')
+ handler = GetOrHeadHandler(None, req, None, None, None, None, {})
+ handler.fast_forward(50)
+ self.assertEquals(handler.backend_headers['Range'], 'bytes=50-')
+
+ handler = GetOrHeadHandler(None, req, None, None, None, None,
+ {'Range': 'bytes=23-50'})
+ handler.fast_forward(20)
+ self.assertEquals(handler.backend_headers['Range'], 'bytes=43-50')
+ self.assertRaises(HTTPException,
+ handler.fast_forward, 80)
+
+ handler = GetOrHeadHandler(None, req, None, None, None, None,
+ {'Range': 'bytes=23-'})
+ handler.fast_forward(20)
+ self.assertEquals(handler.backend_headers['Range'], 'bytes=43-')
+
+ handler = GetOrHeadHandler(None, req, None, None, None, None,
+ {'Range': 'bytes=-100'})
+ handler.fast_forward(20)
+ self.assertEquals(handler.backend_headers['Range'], 'bytes=-80')
+
+ def test_transfer_headers_with_sysmeta(self):
+ base = Controller(self.app)
+ good_hdrs = {'x-base-sysmeta-foo': 'ok',
+ 'X-Base-sysmeta-Bar': 'also ok'}
+ bad_hdrs = {'x-base-sysmeta-': 'too short'}
+ hdrs = dict(good_hdrs)
+ hdrs.update(bad_hdrs)
+ dst_hdrs = HeaderKeyDict()
+ base.transfer_headers(hdrs, dst_hdrs)
+ self.assertEqual(HeaderKeyDict(good_hdrs), dst_hdrs)
+
+ def test_generate_request_headers(self):
+ base = Controller(self.app)
+ src_headers = {'x-remove-base-meta-owner': 'x',
+ 'x-base-meta-size': '151M',
+ 'new-owner': 'Kun'}
+ req = Request.blank('/v1/a/c/o', headers=src_headers)
+ dst_headers = base.generate_request_headers(req, transfer=True)
+ expected_headers = {'x-base-meta-owner': '',
+ 'x-base-meta-size': '151M'}
+ for k, v in expected_headers.iteritems():
+ self.assertTrue(k in dst_headers)
+ self.assertEqual(v, dst_headers[k])
+ self.assertFalse('new-owner' in dst_headers)
+
+ def test_generate_request_headers_with_sysmeta(self):
+ base = Controller(self.app)
+ good_hdrs = {'x-base-sysmeta-foo': 'ok',
+ 'X-Base-sysmeta-Bar': 'also ok'}
+ bad_hdrs = {'x-base-sysmeta-': 'too short'}
+ hdrs = dict(good_hdrs)
+ hdrs.update(bad_hdrs)
+ req = Request.blank('/v1/a/c/o', headers=hdrs)
+ dst_headers = base.generate_request_headers(req, transfer=True)
+ for k, v in good_hdrs.iteritems():
+ self.assertTrue(k.lower() in dst_headers)
+ self.assertEqual(v, dst_headers[k.lower()])
+ for k, v in bad_hdrs.iteritems():
+ self.assertFalse(k.lower() in dst_headers)
diff --git a/test/unit/proxy/controllers/test_container.py b/test/unit/proxy/controllers/test_container.py
index 63e6b0e..7c8ecf7 100644
--- a/test/unit/proxy/controllers/test_container.py
+++ b/test/unit/proxy/controllers/test_container.py
@@ -20,6 +20,7 @@ from swift.common.swob import Request
from swift.proxy import server as proxy_server
from swift.proxy.controllers.base import headers_to_container_info
from test.unit import fake_http_connect, FakeRing, FakeMemcache
+from swift.common.request_helpers import get_sys_meta_prefix
class TestContainerController(unittest.TestCase):
@@ -33,7 +34,7 @@ class TestContainerController(unittest.TestCase):
controller = proxy_server.ContainerController(self.app, 'a', 'c')
with mock.patch('swift.proxy.controllers.base.http_connect',
fake_http_connect(200, 200, body='')):
- req = Request.blank('/a/c', {'PATH_INFO': '/a/c'})
+ req = Request.blank('/v1/a/c', {'PATH_INFO': '/v1/a/c'})
resp = controller.HEAD(req)
self.assertEqual(2, resp.status_int // 100)
self.assertTrue("swift.container/a/c" in resp.environ)
@@ -46,7 +47,7 @@ class TestContainerController(unittest.TestCase):
'x-container-sync-key': 'value', 'x-container-sync-to': 'value'}
controller = proxy_server.ContainerController(self.app, 'a', 'c')
- req = Request.blank('/a/c')
+ req = Request.blank('/v1/a/c')
with mock.patch('swift.proxy.controllers.base.http_connect',
fake_http_connect(200, 200, headers=owner_headers)):
resp = controller.HEAD(req)
@@ -54,7 +55,7 @@ class TestContainerController(unittest.TestCase):
for key in owner_headers:
self.assertTrue(key not in resp.headers)
- req = Request.blank('/a/c', environ={'swift_owner': True})
+ req = Request.blank('/v1/a/c', environ={'swift_owner': True})
with mock.patch('swift.proxy.controllers.base.http_connect',
fake_http_connect(200, 200, headers=owner_headers)):
resp = controller.HEAD(req)
@@ -62,6 +63,61 @@ class TestContainerController(unittest.TestCase):
for key in owner_headers:
self.assertTrue(key in resp.headers)
+ def _make_callback_func(self, context):
+ def callback(ipaddr, port, device, partition, method, path,
+ headers=None, query_string=None, ssl=False):
+ context['method'] = method
+ context['path'] = path
+ context['headers'] = headers or {}
+ return callback
+
+ def test_sys_meta_headers_PUT(self):
+ # check that headers in sys meta namespace make it through
+ # the container controller
+ sys_meta_key = '%stest' % get_sys_meta_prefix('container')
+ sys_meta_key = sys_meta_key.title()
+ user_meta_key = 'X-Container-Meta-Test'
+ controller = proxy_server.ContainerController(self.app, 'a', 'c')
+
+ context = {}
+ callback = self._make_callback_func(context)
+ hdrs_in = {sys_meta_key: 'foo',
+ user_meta_key: 'bar',
+ 'x-timestamp': '1.0'}
+ req = Request.blank('/v1/a/c', headers=hdrs_in)
+ with mock.patch('swift.proxy.controllers.base.http_connect',
+ fake_http_connect(200, 200, give_connect=callback)):
+ controller.PUT(req)
+ self.assertEqual(context['method'], 'PUT')
+ self.assertTrue(sys_meta_key in context['headers'])
+ self.assertEqual(context['headers'][sys_meta_key], 'foo')
+ self.assertTrue(user_meta_key in context['headers'])
+ self.assertEqual(context['headers'][user_meta_key], 'bar')
+ self.assertNotEqual(context['headers']['x-timestamp'], '1.0')
+
+ def test_sys_meta_headers_POST(self):
+ # check that headers in sys meta namespace make it through
+ # the container controller
+ sys_meta_key = '%stest' % get_sys_meta_prefix('container')
+ sys_meta_key = sys_meta_key.title()
+ user_meta_key = 'X-Container-Meta-Test'
+ controller = proxy_server.ContainerController(self.app, 'a', 'c')
+ context = {}
+ callback = self._make_callback_func(context)
+ hdrs_in = {sys_meta_key: 'foo',
+ user_meta_key: 'bar',
+ 'x-timestamp': '1.0'}
+ req = Request.blank('/v1/a/c', headers=hdrs_in)
+ with mock.patch('swift.proxy.controllers.base.http_connect',
+ fake_http_connect(200, 200, give_connect=callback)):
+ controller.POST(req)
+ self.assertEqual(context['method'], 'POST')
+ self.assertTrue(sys_meta_key in context['headers'])
+ self.assertEqual(context['headers'][sys_meta_key], 'foo')
+ self.assertTrue(user_meta_key in context['headers'])
+ self.assertEqual(context['headers'][user_meta_key], 'bar')
+ self.assertNotEqual(context['headers']['x-timestamp'], '1.0')
+
if __name__ == '__main__':
unittest.main()
diff --git a/test/unit/proxy/controllers/test_info.py b/test/unit/proxy/controllers/test_info.py
new file mode 100644
index 0000000..f33beba
--- /dev/null
+++ b/test/unit/proxy/controllers/test_info.py
@@ -0,0 +1,293 @@
+# Copyright (c) 2010-2012 OpenStack Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import unittest
+import time
+from mock import Mock
+
+from swift.proxy.controllers import InfoController
+from swift.proxy.server import Application as ProxyApp
+from swift.common import utils
+from swift.common.utils import json
+from swift.common.swob import Request, HTTPException
+
+
+class TestInfoController(unittest.TestCase):
+
+ def setUp(self):
+ utils._swift_info = {}
+ utils._swift_admin_info = {}
+
+ def get_controller(self, expose_info=None, disallowed_sections=None,
+ admin_key=None):
+ disallowed_sections = disallowed_sections or []
+
+ app = Mock(spec=ProxyApp)
+ return InfoController(app, None, expose_info,
+ disallowed_sections, admin_key)
+
+ def start_response(self, status, headers):
+ self.got_statuses.append(status)
+ for h in headers:
+ self.got_headers.append({h[0]: h[1]})
+
+ def test_disabled_info(self):
+ controller = self.get_controller(expose_info=False)
+
+ req = Request.blank(
+ '/info', environ={'REQUEST_METHOD': 'GET'})
+ resp = controller.GET(req)
+ self.assertTrue(isinstance(resp, HTTPException))
+ self.assertEqual('403 Forbidden', str(resp))
+
+ def test_get_info(self):
+ controller = self.get_controller(expose_info=True)
+ utils._swift_info = {'foo': {'bar': 'baz'}}
+ utils._swift_admin_info = {'qux': {'quux': 'corge'}}
+
+ req = Request.blank(
+ '/info', environ={'REQUEST_METHOD': 'GET'})
+ resp = controller.GET(req)
+ self.assertTrue(isinstance(resp, HTTPException))
+ self.assertEqual('200 OK', str(resp))
+ info = json.loads(resp.body)
+ self.assertTrue('admin' not in info)
+ self.assertTrue('foo' in info)
+ self.assertTrue('bar' in info['foo'])
+ self.assertEqual(info['foo']['bar'], 'baz')
+
+ def test_options_info(self):
+ controller = self.get_controller(expose_info=True)
+
+ req = Request.blank(
+ '/info', environ={'REQUEST_METHOD': 'GET'})
+ resp = controller.OPTIONS(req)
+ self.assertTrue(isinstance(resp, HTTPException))
+ self.assertEqual('200 OK', str(resp))
+ self.assertTrue('Allow' in resp.headers)
+
+ def test_get_info_cors(self):
+ controller = self.get_controller(expose_info=True)
+ utils._swift_info = {'foo': {'bar': 'baz'}}
+ utils._swift_admin_info = {'qux': {'quux': 'corge'}}
+
+ req = Request.blank(
+ '/info', environ={'REQUEST_METHOD': 'GET'},
+ headers={'Origin': 'http://example.com'})
+ resp = controller.GET(req)
+ self.assertTrue(isinstance(resp, HTTPException))
+ self.assertEqual('200 OK', str(resp))
+ info = json.loads(resp.body)
+ self.assertTrue('admin' not in info)
+ self.assertTrue('foo' in info)
+ self.assertTrue('bar' in info['foo'])
+ self.assertEqual(info['foo']['bar'], 'baz')
+ self.assertTrue('Access-Control-Allow-Origin' in resp.headers)
+ self.assertTrue('Access-Control-Expose-Headers' in resp.headers)
+
+ def test_head_info(self):
+ controller = self.get_controller(expose_info=True)
+ utils._swift_info = {'foo': {'bar': 'baz'}}
+ utils._swift_admin_info = {'qux': {'quux': 'corge'}}
+
+ req = Request.blank(
+ '/info', environ={'REQUEST_METHOD': 'HEAD'})
+ resp = controller.HEAD(req)
+ self.assertTrue(isinstance(resp, HTTPException))
+ self.assertEqual('200 OK', str(resp))
+
+ def test_disallow_info(self):
+ controller = self.get_controller(expose_info=True,
+ disallowed_sections=['foo2'])
+ utils._swift_info = {'foo': {'bar': 'baz'},
+ 'foo2': {'bar2': 'baz2'}}
+ utils._swift_admin_info = {'qux': {'quux': 'corge'}}
+
+ req = Request.blank(
+ '/info', environ={'REQUEST_METHOD': 'GET'})
+ resp = controller.GET(req)
+ self.assertTrue(isinstance(resp, HTTPException))
+ self.assertEqual('200 OK', str(resp))
+ info = json.loads(resp.body)
+ self.assertTrue('foo' in info)
+ self.assertTrue('bar' in info['foo'])
+ self.assertEqual(info['foo']['bar'], 'baz')
+ self.assertTrue('foo2' not in info)
+
+ def test_disabled_admin_info(self):
+ controller = self.get_controller(expose_info=True, admin_key='')
+ utils._swift_info = {'foo': {'bar': 'baz'}}
+ utils._swift_admin_info = {'qux': {'quux': 'corge'}}
+
+ expires = int(time.time() + 86400)
+ sig = utils.get_hmac('GET', '/info', expires, '')
+ path = '/info?swiftinfo_sig={sig}&swiftinfo_expires={expires}'.format(
+ sig=sig, expires=expires)
+ req = Request.blank(
+ path, environ={'REQUEST_METHOD': 'GET'})
+ resp = controller.GET(req)
+ self.assertTrue(isinstance(resp, HTTPException))
+ self.assertEqual('403 Forbidden', str(resp))
+
+ def test_get_admin_info(self):
+ controller = self.get_controller(expose_info=True,
+ admin_key='secret-admin-key')
+ utils._swift_info = {'foo': {'bar': 'baz'}}
+ utils._swift_admin_info = {'qux': {'quux': 'corge'}}
+
+ expires = int(time.time() + 86400)
+ sig = utils.get_hmac('GET', '/info', expires, 'secret-admin-key')
+ path = '/info?swiftinfo_sig={sig}&swiftinfo_expires={expires}'.format(
+ sig=sig, expires=expires)
+ req = Request.blank(
+ path, environ={'REQUEST_METHOD': 'GET'})
+ resp = controller.GET(req)
+ self.assertTrue(isinstance(resp, HTTPException))
+ self.assertEqual('200 OK', str(resp))
+ info = json.loads(resp.body)
+ self.assertTrue('admin' in info)
+ self.assertTrue('qux' in info['admin'])
+ self.assertTrue('quux' in info['admin']['qux'])
+ self.assertEqual(info['admin']['qux']['quux'], 'corge')
+
+ def test_head_admin_info(self):
+ controller = self.get_controller(expose_info=True,
+ admin_key='secret-admin-key')
+ utils._swift_info = {'foo': {'bar': 'baz'}}
+ utils._swift_admin_info = {'qux': {'quux': 'corge'}}
+
+ expires = int(time.time() + 86400)
+ sig = utils.get_hmac('GET', '/info', expires, 'secret-admin-key')
+ path = '/info?swiftinfo_sig={sig}&swiftinfo_expires={expires}'.format(
+ sig=sig, expires=expires)
+ req = Request.blank(
+ path, environ={'REQUEST_METHOD': 'HEAD'})
+ resp = controller.GET(req)
+ self.assertTrue(isinstance(resp, HTTPException))
+ self.assertEqual('200 OK', str(resp))
+
+ expires = int(time.time() + 86400)
+ sig = utils.get_hmac('HEAD', '/info', expires, 'secret-admin-key')
+ path = '/info?swiftinfo_sig={sig}&swiftinfo_expires={expires}'.format(
+ sig=sig, expires=expires)
+ req = Request.blank(
+ path, environ={'REQUEST_METHOD': 'HEAD'})
+ resp = controller.GET(req)
+ self.assertTrue(isinstance(resp, HTTPException))
+ self.assertEqual('200 OK', str(resp))
+
+ def test_get_admin_info_invalid_method(self):
+ controller = self.get_controller(expose_info=True,
+ admin_key='secret-admin-key')
+ utils._swift_info = {'foo': {'bar': 'baz'}}
+ utils._swift_admin_info = {'qux': {'quux': 'corge'}}
+
+ expires = int(time.time() + 86400)
+ sig = utils.get_hmac('HEAD', '/info', expires, 'secret-admin-key')
+ path = '/info?swiftinfo_sig={sig}&swiftinfo_expires={expires}'.format(
+ sig=sig, expires=expires)
+ req = Request.blank(
+ path, environ={'REQUEST_METHOD': 'GET'})
+ resp = controller.GET(req)
+ self.assertTrue(isinstance(resp, HTTPException))
+ self.assertEqual('401 Unauthorized', str(resp))
+
+ def test_get_admin_info_invalid_expires(self):
+ controller = self.get_controller(expose_info=True,
+ admin_key='secret-admin-key')
+ utils._swift_info = {'foo': {'bar': 'baz'}}
+ utils._swift_admin_info = {'qux': {'quux': 'corge'}}
+
+ expires = 1
+ sig = utils.get_hmac('GET', '/info', expires, 'secret-admin-key')
+ path = '/info?swiftinfo_sig={sig}&swiftinfo_expires={expires}'.format(
+ sig=sig, expires=expires)
+ req = Request.blank(
+ path, environ={'REQUEST_METHOD': 'GET'})
+ resp = controller.GET(req)
+ self.assertTrue(isinstance(resp, HTTPException))
+ self.assertEqual('401 Unauthorized', str(resp))
+
+ expires = 'abc'
+ sig = utils.get_hmac('GET', '/info', expires, 'secret-admin-key')
+ path = '/info?swiftinfo_sig={sig}&swiftinfo_expires={expires}'.format(
+ sig=sig, expires=expires)
+ req = Request.blank(
+ path, environ={'REQUEST_METHOD': 'GET'})
+ resp = controller.GET(req)
+ self.assertTrue(isinstance(resp, HTTPException))
+ self.assertEqual('401 Unauthorized', str(resp))
+
+ def test_get_admin_info_invalid_path(self):
+ controller = self.get_controller(expose_info=True,
+ admin_key='secret-admin-key')
+ utils._swift_info = {'foo': {'bar': 'baz'}}
+ utils._swift_admin_info = {'qux': {'quux': 'corge'}}
+
+ expires = int(time.time() + 86400)
+ sig = utils.get_hmac('GET', '/foo', expires, 'secret-admin-key')
+ path = '/info?swiftinfo_sig={sig}&swiftinfo_expires={expires}'.format(
+ sig=sig, expires=expires)
+ req = Request.blank(
+ path, environ={'REQUEST_METHOD': 'GET'})
+ resp = controller.GET(req)
+ self.assertTrue(isinstance(resp, HTTPException))
+ self.assertEqual('401 Unauthorized', str(resp))
+
+ def test_get_admin_info_invalid_key(self):
+ controller = self.get_controller(expose_info=True,
+ admin_key='secret-admin-key')
+ utils._swift_info = {'foo': {'bar': 'baz'}}
+ utils._swift_admin_info = {'qux': {'quux': 'corge'}}
+
+ expires = int(time.time() + 86400)
+ sig = utils.get_hmac('GET', '/foo', expires, 'invalid-admin-key')
+ path = '/info?swiftinfo_sig={sig}&swiftinfo_expires={expires}'.format(
+ sig=sig, expires=expires)
+ req = Request.blank(
+ path, environ={'REQUEST_METHOD': 'GET'})
+ resp = controller.GET(req)
+ self.assertTrue(isinstance(resp, HTTPException))
+ self.assertEqual('401 Unauthorized', str(resp))
+
+ def test_admin_disallow_info(self):
+ controller = self.get_controller(expose_info=True,
+ disallowed_sections=['foo2'],
+ admin_key='secret-admin-key')
+ utils._swift_info = {'foo': {'bar': 'baz'},
+ 'foo2': {'bar2': 'baz2'}}
+ utils._swift_admin_info = {'qux': {'quux': 'corge'}}
+
+ expires = int(time.time() + 86400)
+ sig = utils.get_hmac('GET', '/info', expires, 'secret-admin-key')
+ path = '/info?swiftinfo_sig={sig}&swiftinfo_expires={expires}'.format(
+ sig=sig, expires=expires)
+ req = Request.blank(
+ path, environ={'REQUEST_METHOD': 'GET'})
+ resp = controller.GET(req)
+ self.assertTrue(isinstance(resp, HTTPException))
+ self.assertEqual('200 OK', str(resp))
+ info = json.loads(resp.body)
+ self.assertTrue('foo2' not in info)
+ self.assertTrue('admin' in info)
+ self.assertTrue('disallowed_sections' in info['admin'])
+ self.assertTrue('foo2' in info['admin']['disallowed_sections'])
+ self.assertTrue('qux' in info['admin'])
+ self.assertTrue('quux' in info['admin']['qux'])
+ self.assertEqual(info['admin']['qux']['quux'], 'corge')
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/test/unit/proxy/test_server.py b/test/unit/proxy/test_server.py
index 4c75562..f669b9d 100644
--- a/test/unit/proxy/test_server.py
+++ b/test/unit/proxy/test_server.py
@@ -39,16 +39,18 @@ import gluster.swift.common.Glusterfs as gfs
gfs.RUN_DIR = mkdtemp()
from test.unit import connect_tcp, readuntil2crlfs, FakeLogger, \
- fake_http_connect, FakeRing, FakeMemcache, DebugLogger
+ fake_http_connect, FakeRing, FakeMemcache, debug_logger
from gluster.swift.proxy import server as proxy_server
from gluster.swift.account import server as account_server
from gluster.swift.container import server as container_server
from gluster.swift.obj import server as object_server
from swift.common import ring
+from swift.common.middleware import proxy_logging
from swift.common.exceptions import ChunkReadTimeout, SegmentError
from swift.common.constraints import MAX_META_NAME_LENGTH, \
MAX_META_VALUE_LENGTH, MAX_META_COUNT, MAX_META_OVERALL_SIZE, \
- MAX_FILE_SIZE, MAX_ACCOUNT_NAME_LENGTH, MAX_CONTAINER_NAME_LENGTH
+ MAX_FILE_SIZE, MAX_ACCOUNT_NAME_LENGTH, MAX_CONTAINER_NAME_LENGTH, \
+ ACCOUNT_LISTING_LIMIT, CONTAINER_LISTING_LIMIT, MAX_OBJECT_NAME_LENGTH
from swift.common import utils
from swift.common.utils import mkdirs, normalize_timestamp, NullLogger
from swift.common.wsgi import monkey_patch_mimetools
@@ -144,17 +146,26 @@ def do_setup(the_object_server):
{'id': 1, 'zone': 1, 'device': 'a', 'ip': '127.0.0.1',
'port': obj2lis.getsockname()[1]}], 30),
f)
- prosrv = proxy_server.Application(conf, FakeMemcacheReturnsNone())
- acc1srv = account_server.AccountController(conf)
- acc2srv = account_server.AccountController(conf)
- con1srv = container_server.ContainerController(conf)
- con2srv = container_server.ContainerController(conf)
- obj1srv = the_object_server.ObjectController(conf)
- obj2srv = the_object_server.ObjectController(conf)
+ prosrv = proxy_server.Application(conf, FakeMemcacheReturnsNone(),
+ logger=debug_logger('proxy'))
+ acc1srv = account_server.AccountController(
+ conf, logger=debug_logger('acct1'))
+ acc2srv = account_server.AccountController(
+ conf, logger=debug_logger('acct2'))
+ con1srv = container_server.ContainerController(
+ conf, logger=debug_logger('cont1'))
+ con2srv = container_server.ContainerController(
+ conf, logger=debug_logger('cont2'))
+ obj1srv = the_object_server.ObjectController(
+ conf, logger=debug_logger('obj1'))
+ obj2srv = the_object_server.ObjectController(
+ conf, logger=debug_logger('obj2'))
_test_servers = \
(prosrv, acc1srv, acc2srv, con1srv, con2srv, obj1srv, obj2srv)
- nl = DebugLogger()
- prospa = spawn(wsgi.server, prolis, prosrv, nl)
+ nl = NullLogger()
+ logging_prosv = proxy_logging.ProxyLoggingMiddleware(prosrv, conf,
+ logger=prosrv.logger)
+ prospa = spawn(wsgi.server, prolis, logging_prosv, nl)
acc1spa = spawn(wsgi.server, acc1lis, acc1srv, nl)
acc2spa = spawn(wsgi.server, acc2lis, acc2srv, nl)
con1spa = spawn(wsgi.server, con1lis, con1srv, nl)
@@ -348,7 +359,8 @@ class TestController(unittest.TestCase):
'container_count': '12345',
'total_object_count': None,
'bytes': None,
- 'meta': {}}
+ 'meta': {},
+ 'sysmeta': {}}
self.assertEquals(container_info,
self.memcache.get(cache_key))
@@ -374,7 +386,8 @@ class TestController(unittest.TestCase):
'container_count': None, # internally keep None
'total_object_count': None,
'bytes': None,
- 'meta': {}}
+ 'meta': {},
+ 'sysmeta': {}}
self.assertEquals(account_info,
self.memcache.get(cache_key))
@@ -523,7 +536,7 @@ class TestProxyServer(unittest.TestCase):
app = MyApp(None, FakeMemcache(), account_ring=FakeRing(),
container_ring=FakeRing(), object_ring=FakeRing())
- req = Request.blank('/account', environ={'REQUEST_METHOD': 'HEAD'})
+ req = Request.blank('/v1/account', environ={'REQUEST_METHOD': 'HEAD'})
app.update_request(req)
resp = app.handle_request(req)
self.assertEquals(resp.status_int, 500)
@@ -710,7 +723,7 @@ class TestObjectController(unittest.TestCase):
set_http_connect(*statuses, **kwargs)
self.app.memcache.store = {}
- req = Request.blank('/a/c/o',
+ req = Request.blank('/v1/a/c/o',
headers={'Content-Length': '0',
'Content-Type': 'text/plain'})
self.app.update_request(req)
@@ -720,7 +733,7 @@ class TestObjectController(unittest.TestCase):
# repeat test
set_http_connect(*statuses, **kwargs)
self.app.memcache.store = {}
- req = Request.blank('/a/c/o',
+ req = Request.blank('/v1/a/c/o',
headers={'Content-Length': '0',
'Content-Type': 'text/plain'})
self.app.update_request(req)
@@ -773,7 +786,7 @@ class TestObjectController(unittest.TestCase):
# 100. Perfectly straightforward.
set_http_connect(200, 200, (201, -4), (201, -4), (201, -4),
give_connect=test_connect)
- req = Request.blank('/a/c/o.jpg', {})
+ req = Request.blank('/v1/a/c/o.jpg', {})
req.content_length = 0
self.app.update_request(req)
self.app.memcache.store = {}
@@ -796,7 +809,7 @@ class TestObjectController(unittest.TestCase):
proxy_server.ObjectController(self.app, 'a', 'c', 'o.jpg')
set_http_connect(200, 200, 201, 201, 201,
give_connect=test_connect)
- req = Request.blank('/a/c/o.jpg', {})
+ req = Request.blank('/v1/a/c/o.jpg', {})
req.content_length = 1
req.body = 'a'
self.app.update_request(req)
@@ -824,7 +837,7 @@ class TestObjectController(unittest.TestCase):
proxy_server.ObjectController(self.app, 'a', 'c', 'o.jpg')
set_http_connect(200, 200, 201, 201, 201,
give_connect=test_connect)
- req = Request.blank('/a/c/o.jpg', {})
+ req = Request.blank('/v1/a/c/o.jpg', {})
req.content_length = 1
req.body = 'a'
self.app.memcache.store = {}
@@ -861,7 +874,7 @@ class TestObjectController(unittest.TestCase):
set_http_connect(200, 200, # account, container
201, 201, 201, # 3 working backends
give_connect=test_connect)
- req = Request.blank('/a/c/o.jpg', {})
+ req = Request.blank('/v1/a/c/o.jpg', {})
req.content_length = 1
req.body = 'a'
self.app.memcache.store = {}
@@ -1044,6 +1057,56 @@ class TestObjectController(unittest.TestCase):
finally:
swift.proxy.controllers.obj.MAX_FILE_SIZE = MAX_FILE_SIZE
+ def test_PUT_last_modified(self):
+ prolis = _test_sockets[0]
+ sock = connect_tcp(('localhost', prolis.getsockname()[1]))
+ fd = sock.makefile()
+ fd.write('PUT /v1/a/c/o.last_modified HTTP/1.1\r\n'
+ 'Host: localhost\r\nConnection: close\r\n'
+ 'X-Storage-Token: t\r\nContent-Length: 0\r\n\r\n')
+ fd.flush()
+ headers = readuntil2crlfs(fd)
+ exp = 'HTTP/1.1 201'
+ lm_hdr = 'Last-Modified: '
+ self.assertEqual(headers[:len(exp)], exp)
+
+ last_modified_put = [line for line in headers.split('\r\n')
+ if lm_hdr in line][0][len(lm_hdr):]
+ sock = connect_tcp(('localhost', prolis.getsockname()[1]))
+ fd = sock.makefile()
+ fd.write('HEAD /v1/a/c/o.last_modified HTTP/1.1\r\n'
+ 'Host: localhost\r\nConnection: close\r\n'
+ 'X-Storage-Token: t\r\n\r\n')
+ fd.flush()
+ headers = readuntil2crlfs(fd)
+ exp = 'HTTP/1.1 200'
+ self.assertEqual(headers[:len(exp)], exp)
+ last_modified_head = [line for line in headers.split('\r\n')
+ if lm_hdr in line][0][len(lm_hdr):]
+ self.assertEqual(last_modified_put, last_modified_head)
+
+ sock = connect_tcp(('localhost', prolis.getsockname()[1]))
+ fd = sock.makefile()
+ fd.write('GET /v1/a/c/o.last_modified HTTP/1.1\r\n'
+ 'Host: localhost\r\nConnection: close\r\n'
+ 'If-Modified-Since: %s\r\n'
+ 'X-Storage-Token: t\r\n\r\n' % last_modified_put)
+ fd.flush()
+ headers = readuntil2crlfs(fd)
+ exp = 'HTTP/1.1 304'
+ self.assertEqual(headers[:len(exp)], exp)
+
+ sock = connect_tcp(('localhost', prolis.getsockname()[1]))
+ fd = sock.makefile()
+ fd.write('GET /v1/a/c/o.last_modified HTTP/1.1\r\n'
+ 'Host: localhost\r\nConnection: close\r\n'
+ 'If-Unmodified-Since: %s\r\n'
+ 'X-Storage-Token: t\r\n\r\n' % last_modified_put)
+ fd.flush()
+ headers = readuntil2crlfs(fd)
+ exp = 'HTTP/1.1 200'
+ self.assertEqual(headers[:len(exp)], exp)
+
def test_expirer_DELETE_on_versioned_object(self):
test_errors = []
@@ -1070,7 +1133,7 @@ class TestObjectController(unittest.TestCase):
body_iter=body_iter,
headers={'x-versions-location': 'foo'})
self.app.memcache.store = {}
- req = Request.blank('/a/c/o',
+ req = Request.blank('/v1/a/c/o',
headers={'X-If-Delete-At': 1},
environ={'REQUEST_METHOD': 'DELETE'})
self.app.update_request(req)
@@ -1097,7 +1160,7 @@ class TestObjectController(unittest.TestCase):
headers=hdict,
body_iter=response_bodies)
- req = Request.blank('/a/c/manifest')
+ req = Request.blank('/v1/a/c/manifest')
resp = controller.GET(req)
self.assertEqual(resp.status_int, 200)
self.assertEqual(resp.body, '')
@@ -1176,7 +1239,7 @@ class TestObjectController(unittest.TestCase):
body_iter=response_bodies,
give_connect=capture_requested_paths)
- req = Request.blank('/a/c/manifest')
+ req = Request.blank('/v1/a/c/manifest')
resp = controller.GET(req)
self.assertEqual(resp.status_int, 200)
self.assertEqual(resp.body, 'AaBbCcDdEe')
@@ -1249,7 +1312,7 @@ class TestObjectController(unittest.TestCase):
body_iter=response_bodies,
give_connect=capture_requested_paths)
- req = Request.blank('/a/c/manifest')
+ req = Request.blank('/v1/a/c/manifest')
resp = controller.GET(req)
self.assertEqual(resp.status_int, 200)
self.assertEqual(resp.body, 'AaBb')
@@ -1301,7 +1364,7 @@ class TestObjectController(unittest.TestCase):
body_iter=response_bodies,
give_connect=capture_requested_paths)
- req = Request.blank('/a/c/manifest?multipart-manifest=get')
+ req = Request.blank('/v1/a/c/manifest?multipart-manifest=get')
resp = controller.GET(req)
self.assertEqual(resp.status_int, 200)
self.assertEqual(resp.body, json_listing)
@@ -1351,7 +1414,7 @@ class TestObjectController(unittest.TestCase):
body_iter=response_bodies,
give_connect=capture_requested_paths)
- req = Request.blank('/a/c/manifest?multipart-manifest=get',
+ req = Request.blank('/v1/a/c/manifest?multipart-manifest=get',
headers={'x-copy-from': '/a/c/manifest'})
resp = controller.GET(req)
self.assertEqual(resp.status_int, 200)
@@ -1404,7 +1467,7 @@ class TestObjectController(unittest.TestCase):
'content-type': 'text/html; swift_bytes=4'}, {}, {}],
body_iter=response_bodies,
give_connect=capture_requested_paths)
- req = Request.blank('/a/c/manifest')
+ req = Request.blank('/v1/a/c/manifest')
resp = controller.GET(req)
self.assertEqual(resp.status_int, 200)
self.assertEqual(resp.content_length, 4) # content incomplete
@@ -1484,7 +1547,7 @@ class TestObjectController(unittest.TestCase):
headers=[{}, {}, slob_headers, slob_headers, {}, {}, {}, {}],
body_iter=response_bodies,
give_connect=capture_requested_paths)
- req = Request.blank('/a/c/manifest')
+ req = Request.blank('/v1/a/c/manifest')
resp = controller.GET(req)
self.assertEqual(resp.status_int, 200)
self.assertEqual(resp.content_length, 8)
@@ -1587,7 +1650,7 @@ class TestObjectController(unittest.TestCase):
body_iter=response_bodies,
give_connect=capture_requested_paths)
- req = Request.blank('/a/c/manifest')
+ req = Request.blank('/v1/a/c/manifest')
req.range = 'bytes=4-7'
resp = controller.GET(req)
got_called = [False, ]
@@ -1659,7 +1722,7 @@ class TestObjectController(unittest.TestCase):
'content-type': 'text/html; swift_bytes=4'}, {}, {}],
body_iter=response_bodies,
give_connect=capture_requested_paths)
- req = Request.blank('/a/c/manifest')
+ req = Request.blank('/v1/a/c/manifest')
resp = controller.GET(req)
self.assertEqual(resp.status_int, 200)
self.assertEqual(resp.content_length, 6) # content incomplete
@@ -1716,7 +1779,7 @@ class TestObjectController(unittest.TestCase):
body_iter=response_bodies,
give_connect=capture_requested_paths)
- req = Request.blank('/a/c/manifest',
+ req = Request.blank('/v1/a/c/manifest',
environ={'REQUEST_METHOD': 'HEAD'})
resp = controller.HEAD(req)
self.assertEqual(resp.status_int, 200)
@@ -1744,7 +1807,7 @@ class TestObjectController(unittest.TestCase):
expected.next()))
# We need into include a transfer-encoding to get past
# constraints.check_object_creation()
- req = Request.blank('/a/c/%s' % filename, {},
+ req = Request.blank('/v1/a/c/%s' % filename, {},
headers={'transfer-encoding': 'chunked'})
self.app.update_request(req)
self.app.memcache.store = {}
@@ -1783,7 +1846,7 @@ class TestObjectController(unittest.TestCase):
def test_status_map(statuses, expected):
set_http_connect(*statuses)
- req = Request.blank('/a/c/o.jpg', {})
+ req = Request.blank('/v1/a/c/o.jpg', {})
req.content_length = 0
self.app.update_request(req)
self.app.memcache.store = {}
@@ -1803,7 +1866,7 @@ class TestObjectController(unittest.TestCase):
def test_status_map(statuses, expected):
set_http_connect(*statuses)
self.app.memcache.store = {}
- req = Request.blank('/a/c/o.jpg', {})
+ req = Request.blank('/v1/a/c/o.jpg', {})
req.content_length = 0
self.app.update_request(req)
res = controller.PUT(req)
@@ -1823,7 +1886,7 @@ class TestObjectController(unittest.TestCase):
def test_status_map(statuses, expected):
self.app.memcache.store = {}
set_http_connect(*statuses)
- req = Request.blank('/a/c/o.jpg',
+ req = Request.blank('/v1/a/c/o.jpg',
environ={'REQUEST_METHOD': 'PUT'},
body='some data')
self.app.update_request(req)
@@ -1839,7 +1902,7 @@ class TestObjectController(unittest.TestCase):
set_http_connect(201, 201, 201)
controller = proxy_server.ObjectController(self.app, 'account',
'container', 'object')
- req = Request.blank('/a/c/o', {}, headers={
+ req = Request.blank('/v1/a/c/o', {}, headers={
'Content-Length': str(MAX_FILE_SIZE + 1),
'Content-Type': 'foo/bar'})
self.app.update_request(req)
@@ -1851,7 +1914,7 @@ class TestObjectController(unittest.TestCase):
set_http_connect(201, 201, 201)
controller = proxy_server.ObjectController(self.app, 'account',
'container', 'object')
- req = Request.blank('/a/c/o', {}, headers={
+ req = Request.blank('/v1/a/c/o', {}, headers={
'Content-Length': 0, 'Content-Type': 'foo/bar;swift_hey=45'})
self.app.update_request(req)
res = controller.PUT(req)
@@ -1866,7 +1929,7 @@ class TestObjectController(unittest.TestCase):
def test_status_map(statuses, expected):
self.app.memcache.store = {}
set_http_connect(*statuses)
- req = Request.blank('/a/c/o.jpg', {})
+ req = Request.blank('/v1/a/c/o.jpg', {})
req.content_length = 0
self.app.update_request(req)
res = controller.PUT(req)
@@ -2315,18 +2378,6 @@ class TestObjectController(unittest.TestCase):
def test_node_read_timeout_retry(self):
with save_globals():
- self.app.account_ring.get_nodes('account')
- for dev in self.app.account_ring.devs.values():
- dev['ip'] = '127.0.0.1'
- dev['port'] = 1
- self.app.container_ring.get_nodes('account')
- for dev in self.app.container_ring.devs.values():
- dev['ip'] = '127.0.0.1'
- dev['port'] = 1
- self.app.object_ring.get_nodes('account')
- for dev in self.app.object_ring.devs.values():
- dev['ip'] = '127.0.0.1'
- dev['port'] = 1
req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'GET'})
self.app.update_request(req)
@@ -2522,7 +2573,7 @@ class TestObjectController(unittest.TestCase):
def test_best_response_sets_headers(self):
controller = proxy_server.ObjectController(self.app, 'account',
'container', 'object')
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'GET'})
+ req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'GET'})
resp = controller.best_response(req, [200] * 3, ['OK'] * 3, [''] * 3,
'Object', headers=[{'X-Test': '1'},
{'X-Test': '2'},
@@ -2532,7 +2583,7 @@ class TestObjectController(unittest.TestCase):
def test_best_response_sets_etag(self):
controller = proxy_server.ObjectController(self.app, 'account',
'container', 'object')
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'GET'})
+ req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'GET'})
resp = controller.best_response(req, [200] * 3, ['OK'] * 3, [''] * 3,
'Object')
self.assertEquals(resp.etag, None)
@@ -2561,7 +2612,8 @@ class TestObjectController(unittest.TestCase):
def test_proxy_passes_content_length_on_head(self):
with save_globals():
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'HEAD'})
+ req = Request.blank('/v1/a/c/o',
+ environ={'REQUEST_METHOD': 'HEAD'})
self.app.update_request(req)
controller = proxy_server.ObjectController(self.app, 'account',
'container', 'object')
@@ -2618,7 +2670,8 @@ class TestObjectController(unittest.TestCase):
controller = proxy_server.ObjectController(self.app, 'account',
'container', 'object')
set_http_connect(200, 200, 200, 200, 200, 200)
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'DELETE'})
+ req = Request.blank('/v1/a/c/o',
+ environ={'REQUEST_METHOD': 'DELETE'})
self.app.update_request(req)
resp = getattr(controller, 'DELETE')(req)
self.assertEquals(resp.status_int, 200)
@@ -2626,49 +2679,56 @@ class TestObjectController(unittest.TestCase):
set_http_connect(404, 404, 404)
# acct acct acct
# make sure to use a fresh request without cached env
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'DELETE'})
+ req = Request.blank('/v1/a/c/o',
+ environ={'REQUEST_METHOD': 'DELETE'})
resp = getattr(controller, 'DELETE')(req)
self.assertEquals(resp.status_int, 404)
set_http_connect(503, 404, 404)
# acct acct acct
# make sure to use a fresh request without cached env
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'DELETE'})
+ req = Request.blank('/v1/a/c/o',
+ environ={'REQUEST_METHOD': 'DELETE'})
resp = getattr(controller, 'DELETE')(req)
self.assertEquals(resp.status_int, 404)
set_http_connect(503, 503, 404)
# acct acct acct
# make sure to use a fresh request without cached env
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'DELETE'})
+ req = Request.blank('/v1/a/c/o',
+ environ={'REQUEST_METHOD': 'DELETE'})
resp = getattr(controller, 'DELETE')(req)
self.assertEquals(resp.status_int, 404)
set_http_connect(503, 503, 503)
# acct acct acct
# make sure to use a fresh request without cached env
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'DELETE'})
+ req = Request.blank('/v1/a/c/o',
+ environ={'REQUEST_METHOD': 'DELETE'})
resp = getattr(controller, 'DELETE')(req)
self.assertEquals(resp.status_int, 404)
set_http_connect(200, 200, 204, 204, 204)
# acct cont obj obj obj
# make sure to use a fresh request without cached env
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'DELETE'})
+ req = Request.blank('/v1/a/c/o',
+ environ={'REQUEST_METHOD': 'DELETE'})
resp = getattr(controller, 'DELETE')(req)
self.assertEquals(resp.status_int, 204)
set_http_connect(200, 404, 404, 404)
# acct cont cont cont
# make sure to use a fresh request without cached env
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'DELETE'})
+ req = Request.blank('/v1/a/c/o',
+ environ={'REQUEST_METHOD': 'DELETE'})
resp = getattr(controller, 'DELETE')(req)
self.assertEquals(resp.status_int, 404)
set_http_connect(200, 503, 503, 503)
# acct cont cont cont
# make sure to use a fresh request without cached env
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'DELETE'})
+ req = Request.blank('/v1/a/c/o',
+ environ={'REQUEST_METHOD': 'DELETE'})
resp = getattr(controller, 'DELETE')(req)
self.assertEquals(resp.status_int, 404)
@@ -2679,7 +2739,8 @@ class TestObjectController(unittest.TestCase):
# acct [isn't actually called since everything
# is error limited]
# make sure to use a fresh request without cached env
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'DELETE'})
+ req = Request.blank('/v1/a/c/o',
+ environ={'REQUEST_METHOD': 'DELETE'})
resp = getattr(controller, 'DELETE')(req)
self.assertEquals(resp.status_int, 404)
@@ -2692,7 +2753,8 @@ class TestObjectController(unittest.TestCase):
# acct cont [isn't actually called since
# everything is error limited]
# make sure to use a fresh request without cached env
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'DELETE'})
+ req = Request.blank('/v1/a/c/o',
+ environ={'REQUEST_METHOD': 'DELETE'})
resp = getattr(controller, 'DELETE')(req)
self.assertEquals(resp.status_int, 404)
@@ -2704,13 +2766,15 @@ class TestObjectController(unittest.TestCase):
'container', 'object')
set_http_connect(200, 404, 404, 404, 200, 200, 200)
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'})
+ req = Request.blank('/v1/a/c/o',
+ environ={'REQUEST_METHOD': 'PUT'})
self.app.update_request(req)
resp = controller.PUT(req)
self.assertEquals(resp.status_int, 404)
set_http_connect(200, 404, 404, 404, 200, 200)
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'POST'},
+ req = Request.blank('/v1/a/c/o',
+ environ={'REQUEST_METHOD': 'POST'},
headers={'Content-Type': 'text/plain'})
self.app.update_request(req)
resp = controller.POST(req)
@@ -2722,13 +2786,14 @@ class TestObjectController(unittest.TestCase):
controller = proxy_server.ObjectController(self.app, 'account',
'container', 'object')
set_http_connect(200, 404, 404, 404, 200, 200, 200)
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'})
+ req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'PUT'})
self.app.update_request(req)
resp = controller.PUT(req)
self.assertEquals(resp.status_int, 404)
set_http_connect(200, 404, 404, 404, 200, 200, 200, 200, 200, 200)
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'POST'},
+ req = Request.blank('/v1/a/c/o',
+ environ={'REQUEST_METHOD': 'POST'},
headers={'Content-Type': 'text/plain'})
self.app.update_request(req)
resp = controller.POST(req)
@@ -2740,14 +2805,14 @@ class TestObjectController(unittest.TestCase):
'container', 'object')
set_http_connect(200, 200, 201, 201, 201)
# acct cont obj obj obj
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
+ req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
headers={'Content-Length': '0'})
self.app.update_request(req)
resp = controller.PUT(req)
self.assertEquals(resp.status_int, 201)
set_http_connect(201, 201, 201)
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
+ req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
headers={'Content-Length': '0',
'X-Object-Meta-' + ('a' *
MAX_META_NAME_LENGTH): 'v'})
@@ -2755,7 +2820,7 @@ class TestObjectController(unittest.TestCase):
resp = controller.PUT(req)
self.assertEquals(resp.status_int, 201)
set_http_connect(201, 201, 201)
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
+ req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
headers={'Content-Length': '0',
'X-Object-Meta-' + ('a' *
(MAX_META_NAME_LENGTH + 1)): 'v'})
@@ -2764,7 +2829,7 @@ class TestObjectController(unittest.TestCase):
self.assertEquals(resp.status_int, 400)
set_http_connect(201, 201, 201)
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
+ req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
headers={'Content-Length': '0',
'X-Object-Meta-Too-Long': 'a' *
MAX_META_VALUE_LENGTH})
@@ -2772,7 +2837,7 @@ class TestObjectController(unittest.TestCase):
resp = controller.PUT(req)
self.assertEquals(resp.status_int, 201)
set_http_connect(201, 201, 201)
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
+ req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
headers={'Content-Length': '0',
'X-Object-Meta-Too-Long': 'a' *
(MAX_META_VALUE_LENGTH + 1)})
@@ -2784,7 +2849,7 @@ class TestObjectController(unittest.TestCase):
headers = {'Content-Length': '0'}
for x in xrange(MAX_META_COUNT):
headers['X-Object-Meta-%d' % x] = 'v'
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
+ req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
headers=headers)
self.app.update_request(req)
resp = controller.PUT(req)
@@ -2793,7 +2858,7 @@ class TestObjectController(unittest.TestCase):
headers = {'Content-Length': '0'}
for x in xrange(MAX_META_COUNT + 1):
headers['X-Object-Meta-%d' % x] = 'v'
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
+ req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
headers=headers)
self.app.update_request(req)
resp = controller.PUT(req)
@@ -2812,7 +2877,7 @@ class TestObjectController(unittest.TestCase):
if MAX_META_OVERALL_SIZE - size > 1:
headers['X-Object-Meta-a'] = \
'a' * (MAX_META_OVERALL_SIZE - size - 1)
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
+ req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
headers=headers)
self.app.update_request(req)
resp = controller.PUT(req)
@@ -2820,7 +2885,7 @@ class TestObjectController(unittest.TestCase):
set_http_connect(201, 201, 201)
headers['X-Object-Meta-a'] = \
'a' * (MAX_META_OVERALL_SIZE - size)
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
+ req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
headers=headers)
self.app.update_request(req)
resp = controller.PUT(req)
@@ -2831,7 +2896,7 @@ class TestObjectController(unittest.TestCase):
controller = proxy_server.ObjectController(self.app, 'account',
'container', 'object')
# initial source object PUT
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
+ req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
headers={'Content-Length': '0'})
self.app.update_request(req)
set_http_connect(200, 200, 201, 201, 201)
@@ -2840,7 +2905,7 @@ class TestObjectController(unittest.TestCase):
self.assertEquals(resp.status_int, 201)
# basic copy
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
+ req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
headers={'Content-Length': '0',
'X-Copy-From': 'c/o'})
self.app.update_request(req)
@@ -2852,7 +2917,7 @@ class TestObjectController(unittest.TestCase):
self.assertEquals(resp.headers['x-copied-from'], 'c/o')
# non-zero content length
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
+ req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
headers={'Content-Length': '5',
'X-Copy-From': 'c/o'})
self.app.update_request(req)
@@ -2863,7 +2928,7 @@ class TestObjectController(unittest.TestCase):
self.assertEquals(resp.status_int, 400)
# extra source path parsing
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
+ req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
headers={'Content-Length': '0',
'X-Copy-From': 'c/o/o2'})
req.account = 'a'
@@ -2875,7 +2940,7 @@ class TestObjectController(unittest.TestCase):
self.assertEquals(resp.headers['x-copied-from'], 'c/o/o2')
# space in soure path
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
+ req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
headers={'Content-Length': '0',
'X-Copy-From': 'c/o%20o2'})
req.account = 'a'
@@ -2887,7 +2952,7 @@ class TestObjectController(unittest.TestCase):
self.assertEquals(resp.headers['x-copied-from'], 'c/o%20o2')
# repeat tests with leading /
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
+ req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
headers={'Content-Length': '0',
'X-Copy-From': '/c/o'})
self.app.update_request(req)
@@ -2898,7 +2963,7 @@ class TestObjectController(unittest.TestCase):
self.assertEquals(resp.status_int, 201)
self.assertEquals(resp.headers['x-copied-from'], 'c/o')
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
+ req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
headers={'Content-Length': '0',
'X-Copy-From': '/c/o/o2'})
req.account = 'a'
@@ -2912,7 +2977,7 @@ class TestObjectController(unittest.TestCase):
# negative tests
# invalid x-copy-from path
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
+ req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
headers={'Content-Length': '0',
'X-Copy-From': '/c'})
self.app.update_request(req)
@@ -2921,7 +2986,7 @@ class TestObjectController(unittest.TestCase):
self.assertEquals(resp.status_int // 100, 4) # client error
# server error
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
+ req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
headers={'Content-Length': '0',
'X-Copy-From': '/c/o'})
self.app.update_request(req)
@@ -2932,7 +2997,7 @@ class TestObjectController(unittest.TestCase):
self.assertEquals(resp.status_int, 503)
# not found
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
+ req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
headers={'Content-Length': '0',
'X-Copy-From': '/c/o'})
self.app.update_request(req)
@@ -2943,7 +3008,7 @@ class TestObjectController(unittest.TestCase):
self.assertEquals(resp.status_int, 404)
# some missing containers
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
+ req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
headers={'Content-Length': '0',
'X-Copy-From': '/c/o'})
self.app.update_request(req)
@@ -2954,7 +3019,7 @@ class TestObjectController(unittest.TestCase):
self.assertEquals(resp.status_int, 201)
# test object meta data
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
+ req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
headers={'Content-Length': '0',
'X-Copy-From': '/c/o',
'X-Object-Meta-Ours': 'okay'})
@@ -2970,7 +3035,7 @@ class TestObjectController(unittest.TestCase):
self.assertEquals(resp.headers.get('x-delete-at'), '9876543210')
# copy-from object is too large to fit in target object
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
+ req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
headers={'Content-Length': '0',
'X-Copy-From': '/c/o'})
self.app.update_request(req)
@@ -2993,7 +3058,7 @@ class TestObjectController(unittest.TestCase):
def test_COPY(self):
with save_globals():
controller = proxy_server.ObjectController(self.app, 'a', 'c', 'o')
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
+ req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
headers={'Content-Length': '0'})
req.account = 'a'
set_http_connect(200, 200, 201, 201, 201)
@@ -3001,7 +3066,8 @@ class TestObjectController(unittest.TestCase):
resp = controller.PUT(req)
self.assertEquals(resp.status_int, 201)
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'COPY'},
+ req = Request.blank('/v1/a/c/o',
+ environ={'REQUEST_METHOD': 'COPY'},
headers={'Destination': 'c/o'})
req.account = 'a'
set_http_connect(200, 200, 200, 200, 200, 201, 201, 201, 200, 200)
@@ -3011,7 +3077,7 @@ class TestObjectController(unittest.TestCase):
self.assertEquals(resp.status_int, 201)
self.assertEquals(resp.headers['x-copied-from'], 'c/o')
- req = Request.blank('/a/c/o/o2',
+ req = Request.blank('/v1/a/c/o/o2',
environ={'REQUEST_METHOD': 'COPY'},
headers={'Destination': 'c/o'})
req.account = 'a'
@@ -3023,7 +3089,8 @@ class TestObjectController(unittest.TestCase):
self.assertEquals(resp.status_int, 201)
self.assertEquals(resp.headers['x-copied-from'], 'c/o/o2')
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'COPY'},
+ req = Request.blank('/v1/a/c/o',
+ environ={'REQUEST_METHOD': 'COPY'},
headers={'Destination': '/c/o'})
req.account = 'a'
controller.object_name = 'o'
@@ -3034,7 +3101,7 @@ class TestObjectController(unittest.TestCase):
self.assertEquals(resp.status_int, 201)
self.assertEquals(resp.headers['x-copied-from'], 'c/o')
- req = Request.blank('/a/c/o/o2',
+ req = Request.blank('/v1/a/c/o/o2',
environ={'REQUEST_METHOD': 'COPY'},
headers={'Destination': '/c/o'})
req.account = 'a'
@@ -3046,7 +3113,8 @@ class TestObjectController(unittest.TestCase):
self.assertEquals(resp.status_int, 201)
self.assertEquals(resp.headers['x-copied-from'], 'c/o/o2')
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'COPY'},
+ req = Request.blank('/v1/a/c/o',
+ environ={'REQUEST_METHOD': 'COPY'},
headers={'Destination': 'c_o'})
req.account = 'a'
controller.object_name = 'o'
@@ -3056,7 +3124,8 @@ class TestObjectController(unittest.TestCase):
resp = controller.COPY(req)
self.assertEquals(resp.status_int, 412)
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'COPY'},
+ req = Request.blank('/v1/a/c/o',
+ environ={'REQUEST_METHOD': 'COPY'},
headers={'Destination': '/c/o'})
req.account = 'a'
controller.object_name = 'o'
@@ -3066,7 +3135,8 @@ class TestObjectController(unittest.TestCase):
resp = controller.COPY(req)
self.assertEquals(resp.status_int, 503)
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'COPY'},
+ req = Request.blank('/v1/a/c/o',
+ environ={'REQUEST_METHOD': 'COPY'},
headers={'Destination': '/c/o'})
req.account = 'a'
controller.object_name = 'o'
@@ -3076,7 +3146,8 @@ class TestObjectController(unittest.TestCase):
resp = controller.COPY(req)
self.assertEquals(resp.status_int, 404)
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'COPY'},
+ req = Request.blank('/v1/a/c/o',
+ environ={'REQUEST_METHOD': 'COPY'},
headers={'Destination': '/c/o'})
req.account = 'a'
controller.object_name = 'o'
@@ -3086,7 +3157,8 @@ class TestObjectController(unittest.TestCase):
resp = controller.COPY(req)
self.assertEquals(resp.status_int, 201)
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'COPY'},
+ req = Request.blank('/v1/a/c/o',
+ environ={'REQUEST_METHOD': 'COPY'},
headers={'Destination': '/c/o',
'X-Object-Meta-Ours': 'okay'})
req.account = 'a'
@@ -3101,7 +3173,8 @@ class TestObjectController(unittest.TestCase):
self.assertEquals(resp.headers.get('x-object-meta-ours'), 'okay')
self.assertEquals(resp.headers.get('x-delete-at'), '9876543210')
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'COPY'},
+ req = Request.blank('/v1/a/c/o',
+ environ={'REQUEST_METHOD': 'COPY'},
headers={'Destination': '/c/o'})
self.app.update_request(req)
@@ -3123,7 +3196,8 @@ class TestObjectController(unittest.TestCase):
def test_COPY_newest(self):
with save_globals():
controller = proxy_server.ObjectController(self.app, 'a', 'c', 'o')
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'COPY'},
+ req = Request.blank('/v1/a/c/o',
+ environ={'REQUEST_METHOD': 'COPY'},
headers={'Destination': '/c/o'})
req.account = 'a'
controller.object_name = 'o'
@@ -3150,7 +3224,8 @@ class TestObjectController(unittest.TestCase):
controller._connect_put_node = fake_connect_put_node
set_http_connect(200, 200, 200, 200, 200, 201, 201, 201)
self.app.memcache.store = {}
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'COPY'},
+ req = Request.blank('/v1/a/c/o',
+ environ={'REQUEST_METHOD': 'COPY'},
headers={'Destination': '/c/o'})
self.app.update_request(req)
@@ -3186,7 +3261,8 @@ class TestObjectController(unittest.TestCase):
set_http_connect(201, 201, 201, 201)
controller = proxy_server.ObjectController(self.app, 'account',
'container', 'object')
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'COPY'},
+ req = Request.blank('/v1/a/c/o',
+ environ={'REQUEST_METHOD': 'COPY'},
headers={'Transfer-Encoding': 'chunked',
'Content-Type': 'foo/bar'})
@@ -3198,7 +3274,8 @@ class TestObjectController(unittest.TestCase):
# test 413 entity to large
set_http_connect(201, 201, 201, 201)
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'COPY'},
+ req = Request.blank('/v1/a/c/o',
+ environ={'REQUEST_METHOD': 'COPY'},
headers={'Transfer-Encoding': 'chunked',
'Content-Type': 'foo/bar'})
req.body_file = ChunkedFile(11)
@@ -4290,7 +4367,7 @@ class TestObjectController(unittest.TestCase):
# no etag supplied, object servers return success w/ diff values
controller = proxy_server.ObjectController(self.app, 'account',
'container', 'object')
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
+ req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
headers={'Content-Length': '0'})
self.app.update_request(req)
set_http_connect(200, 201, 201, 201,
@@ -4302,7 +4379,7 @@ class TestObjectController(unittest.TestCase):
self.assertEquals(resp.status_int // 100, 5) # server error
# req supplies etag, object servers return 422 - mismatch
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
+ req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
headers={
'Content-Length': '0',
'ETag': '68b329da9893e34099c7d8ad5cb9c940',
@@ -4318,7 +4395,7 @@ class TestObjectController(unittest.TestCase):
def test_response_get_accept_ranges_header(self):
with save_globals():
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'GET'})
+ req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'GET'})
self.app.update_request(req)
controller = proxy_server.ObjectController(self.app, 'account',
'container', 'object')
@@ -4329,7 +4406,8 @@ class TestObjectController(unittest.TestCase):
def test_response_head_accept_ranges_header(self):
with save_globals():
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'HEAD'})
+ req = Request.blank('/v1/a/c/o',
+ environ={'REQUEST_METHOD': 'HEAD'})
self.app.update_request(req)
controller = proxy_server.ObjectController(self.app, 'account',
'container', 'object')
@@ -4348,7 +4426,7 @@ class TestObjectController(unittest.TestCase):
set_http_connect(200, 200, 201, 201, 201)
controller = proxy_server.ObjectController(self.app, 'account',
'container', 'object')
- req = Request.blank('/a/c/o')
+ req = Request.blank('/v1/a/c/o')
req.environ['swift.authorize'] = authorize
self.app.update_request(req)
controller.GET(req)
@@ -4364,7 +4442,7 @@ class TestObjectController(unittest.TestCase):
set_http_connect(200, 200, 201, 201, 201)
controller = proxy_server.ObjectController(self.app, 'account',
'container', 'object')
- req = Request.blank('/a/c/o', {'REQUEST_METHOD': 'HEAD'})
+ req = Request.blank('/v1/a/c/o', {'REQUEST_METHOD': 'HEAD'})
req.environ['swift.authorize'] = authorize
self.app.update_request(req)
controller.HEAD(req)
@@ -4381,7 +4459,8 @@ class TestObjectController(unittest.TestCase):
set_http_connect(200, 200, 201, 201, 201)
controller = proxy_server.ObjectController(self.app, 'account',
'container', 'object')
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'POST'},
+ req = Request.blank('/v1/a/c/o',
+ environ={'REQUEST_METHOD': 'POST'},
headers={'Content-Length': '5'}, body='12345')
req.environ['swift.authorize'] = authorize
self.app.update_request(req)
@@ -4398,7 +4477,8 @@ class TestObjectController(unittest.TestCase):
set_http_connect(200, 200, 200, 200, 200, 201, 201, 201)
controller = proxy_server.ObjectController(self.app, 'account',
'container', 'object')
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'POST'},
+ req = Request.blank('/v1/a/c/o',
+ environ={'REQUEST_METHOD': 'POST'},
headers={'Content-Length': '5'}, body='12345')
req.environ['swift.authorize'] = authorize
self.app.update_request(req)
@@ -4415,7 +4495,7 @@ class TestObjectController(unittest.TestCase):
set_http_connect(200, 200, 201, 201, 201)
controller = proxy_server.ObjectController(self.app, 'account',
'container', 'object')
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
+ req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
headers={'Content-Length': '5'}, body='12345')
req.environ['swift.authorize'] = authorize
self.app.update_request(req)
@@ -4432,7 +4512,8 @@ class TestObjectController(unittest.TestCase):
set_http_connect(200, 200, 200, 200, 200, 201, 201, 201)
controller = proxy_server.ObjectController(self.app, 'account',
'container', 'object')
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'COPY'},
+ req = Request.blank('/v1/a/c/o',
+ environ={'REQUEST_METHOD': 'COPY'},
headers={'Destination': 'c/o'})
req.environ['swift.authorize'] = authorize
self.app.update_request(req)
@@ -4450,7 +4531,7 @@ class TestObjectController(unittest.TestCase):
try:
t = time.time()
time.time = lambda: t
- req = Request.blank('/a/c/o', {},
+ req = Request.blank('/v1/a/c/o', {},
headers={'Content-Type': 'foo/bar',
'X-Delete-After': '60'})
self.app.update_request(req)
@@ -4465,7 +4546,7 @@ class TestObjectController(unittest.TestCase):
'object')
set_http_connect(200, 200, 202, 202, 202)
self.app.memcache.store = {}
- req = Request.blank('/a/c/o', {},
+ req = Request.blank('/v1/a/c/o', {},
headers={'Content-Type': 'foo/bar',
'X-Delete-After': '60'})
self.app.update_request(req)
@@ -4483,7 +4564,7 @@ class TestObjectController(unittest.TestCase):
'container', 'object')
set_http_connect(200, 200, 200, 200, 200, 202, 202, 202)
self.app.memcache.store = {}
- req = Request.blank('/a/c/o', {},
+ req = Request.blank('/v1/a/c/o', {},
headers={'Content-Type': 'foo/bar',
'X-Delete-After': '60.1'})
self.app.update_request(req)
@@ -4498,7 +4579,7 @@ class TestObjectController(unittest.TestCase):
'container', 'object')
set_http_connect(200, 200, 200, 200, 200, 202, 202, 202)
self.app.memcache.store = {}
- req = Request.blank('/a/c/o', {},
+ req = Request.blank('/v1/a/c/o', {},
headers={'Content-Type': 'foo/bar',
'X-Delete-After': '-60'})
self.app.update_request(req)
@@ -4522,7 +4603,7 @@ class TestObjectController(unittest.TestCase):
set_http_connect(200, 200)
self.app.memcache.store = {}
t = str(int(time.time() + 100))
- req = Request.blank('/a/c/o', {},
+ req = Request.blank('/v1/a/c/o', {},
headers={'Content-Type': 'foo/bar',
'X-Delete-At': t})
self.app.update_request(req)
@@ -4534,7 +4615,7 @@ class TestObjectController(unittest.TestCase):
self.assertTrue('X-Delete-At-Container' in given_headers)
t = str(int(time.time() + 100)) + '.1'
- req = Request.blank('/a/c/o', {},
+ req = Request.blank('/v1/a/c/o', {},
headers={'Content-Type': 'foo/bar',
'X-Delete-At': t})
self.app.update_request(req)
@@ -4543,7 +4624,7 @@ class TestObjectController(unittest.TestCase):
self.assertTrue('Non-integer X-Delete-At' in resp.body)
t = str(int(time.time() - 100))
- req = Request.blank('/a/c/o', {},
+ req = Request.blank('/v1/a/c/o', {},
headers={'Content-Type': 'foo/bar',
'X-Delete-At': t})
self.app.update_request(req)
@@ -4562,7 +4643,7 @@ class TestObjectController(unittest.TestCase):
try:
t = time.time()
time.time = lambda: t
- req = Request.blank('/a/c/o', {},
+ req = Request.blank('/v1/a/c/o', {},
headers={'Content-Length': '0',
'Content-Type': 'foo/bar',
'X-Delete-After': '60'})
@@ -4581,7 +4662,7 @@ class TestObjectController(unittest.TestCase):
'container', 'object')
set_http_connect(200, 200, 201, 201, 201)
self.app.memcache.store = {}
- req = Request.blank('/a/c/o', {},
+ req = Request.blank('/v1/a/c/o', {},
headers={'Content-Length': '0',
'Content-Type': 'foo/bar',
'X-Delete-After': '60.1'})
@@ -4597,7 +4678,7 @@ class TestObjectController(unittest.TestCase):
'container', 'object')
set_http_connect(200, 200, 201, 201, 201)
self.app.memcache.store = {}
- req = Request.blank('/a/c/o', {},
+ req = Request.blank('/v1/a/c/o', {},
headers={'Content-Length': '0',
'Content-Type': 'foo/bar',
'X-Delete-After': '-60'})
@@ -4621,7 +4702,7 @@ class TestObjectController(unittest.TestCase):
set_http_connect(200, 200)
self.app.memcache.store = {}
t = str(int(time.time() + 100))
- req = Request.blank('/a/c/o', {},
+ req = Request.blank('/v1/a/c/o', {},
headers={'Content-Length': '0',
'Content-Type': 'foo/bar',
'X-Delete-At': t})
@@ -4634,7 +4715,7 @@ class TestObjectController(unittest.TestCase):
self.assertTrue('X-Delete-At-Container' in given_headers)
t = str(int(time.time() + 100)) + '.1'
- req = Request.blank('/a/c/o', {},
+ req = Request.blank('/v1/a/c/o', {},
headers={'Content-Length': '0',
'Content-Type': 'foo/bar',
'X-Delete-At': t})
@@ -4644,7 +4725,7 @@ class TestObjectController(unittest.TestCase):
self.assertTrue('Non-integer X-Delete-At' in resp.body)
t = str(int(time.time() - 100))
- req = Request.blank('/a/c/o', {},
+ req = Request.blank('/v1/a/c/o', {},
headers={'Content-Length': '0',
'Content-Type': 'foo/bar',
'X-Delete-At': t})
@@ -4674,7 +4755,10 @@ class TestObjectController(unittest.TestCase):
# Remember Request instance count, make sure the GC is run for pythons
# without reference counting.
for i in xrange(4):
+ sleep(0) # let eventlet do its thing
gc.collect()
+ else:
+ sleep(0)
before_request_instances = len(_request_instances)
# GET test file, but disconnect early
sock = connect_tcp(('localhost', prolis.getsockname()[1]))
@@ -4691,10 +4775,12 @@ class TestObjectController(unittest.TestCase):
fd.read(1)
fd.close()
sock.close()
- sleep(0) # let eventlet do it's thing
# Make sure the GC is run again for pythons without reference counting
for i in xrange(4):
+ sleep(0) # let eventlet do its thing
gc.collect()
+ else:
+ sleep(0)
self.assertEquals(before_request_instances, len(_request_instances))
def test_OPTIONS(self):
@@ -4706,7 +4792,7 @@ class TestObjectController(unittest.TestCase):
return {}
controller.container_info = my_empty_container_info
req = Request.blank(
- '/a/c/o.jpg',
+ '/v1/a/c/o.jpg',
{'REQUEST_METHOD': 'OPTIONS'},
headers={'Origin': 'http://foo.com',
'Access-Control-Request-Method': 'GET'})
@@ -4717,7 +4803,7 @@ class TestObjectController(unittest.TestCase):
return {'cors': {'allow_origin': None}}
controller.container_info = my_empty_origin_container_info
req = Request.blank(
- '/a/c/o.jpg',
+ '/v1/a/c/o.jpg',
{'REQUEST_METHOD': 'OPTIONS'},
headers={'Origin': 'http://foo.com',
'Access-Control-Request-Method': 'GET'})
@@ -4733,7 +4819,7 @@ class TestObjectController(unittest.TestCase):
}
controller.container_info = my_container_info
req = Request.blank(
- '/a/c/o.jpg',
+ '/v1/a/c/o.jpg',
{'REQUEST_METHOD': 'OPTIONS'},
headers={'Origin': 'https://foo.bar',
'Access-Control-Request-Method': 'GET'})
@@ -4751,13 +4837,13 @@ class TestObjectController(unittest.TestCase):
7)
self.assertEquals('999', resp.headers['access-control-max-age'])
req = Request.blank(
- '/a/c/o.jpg',
+ '/v1/a/c/o.jpg',
{'REQUEST_METHOD': 'OPTIONS'},
headers={'Origin': 'https://foo.bar'})
req.content_length = 0
resp = controller.OPTIONS(req)
self.assertEquals(401, resp.status_int)
- req = Request.blank('/a/c/o.jpg', {'REQUEST_METHOD': 'OPTIONS'})
+ req = Request.blank('/v1/a/c/o.jpg', {'REQUEST_METHOD': 'OPTIONS'})
req.content_length = 0
resp = controller.OPTIONS(req)
self.assertEquals(200, resp.status_int)
@@ -4766,13 +4852,13 @@ class TestObjectController(unittest.TestCase):
verb in resp.headers['Allow'])
self.assertEquals(len(resp.headers['Allow'].split(', ')), 7)
req = Request.blank(
- '/a/c/o.jpg',
+ '/v1/a/c/o.jpg',
{'REQUEST_METHOD': 'OPTIONS'},
headers={'Origin': 'http://foo.com'})
resp = controller.OPTIONS(req)
self.assertEquals(401, resp.status_int)
req = Request.blank(
- '/a/c/o.jpg',
+ '/v1/a/c/o.jpg',
{'REQUEST_METHOD': 'OPTIONS'},
headers={'Origin': 'http://foo.bar',
'Access-Control-Request-Method': 'GET'})
@@ -4789,7 +4875,7 @@ class TestObjectController(unittest.TestCase):
}
controller.container_info = my_container_info_wildcard
req = Request.blank(
- '/a/c/o.jpg',
+ '/v1/a/c/o.jpg',
{'REQUEST_METHOD': 'OPTIONS'},
headers={'Origin': 'https://bar.baz',
'Access-Control-Request-Method': 'GET'})
@@ -4826,7 +4912,7 @@ class TestObjectController(unittest.TestCase):
})
req = Request.blank(
- '/a/c/o.jpg',
+ '/v1/a/c/o.jpg',
{'REQUEST_METHOD': 'GET'},
headers={'Origin': 'http://foo.bar'})
@@ -4876,7 +4962,7 @@ class TestObjectController(unittest.TestCase):
key=lambda d: d.get(header_list[0]) or 'z')
def test_PUT_x_container_headers_with_equal_replicas(self):
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
+ req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
headers={'Content-Length': '5'}, body='12345')
controller = proxy_server.ObjectController(self.app, 'a', 'c', 'o')
seen_headers = self._gather_x_container_headers(
@@ -4897,7 +4983,7 @@ class TestObjectController(unittest.TestCase):
def test_PUT_x_container_headers_with_fewer_container_replicas(self):
self.app.container_ring.set_replicas(2)
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
+ req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
headers={'Content-Length': '5'}, body='12345')
controller = proxy_server.ObjectController(self.app, 'a', 'c', 'o')
seen_headers = self._gather_x_container_headers(
@@ -4919,7 +5005,7 @@ class TestObjectController(unittest.TestCase):
def test_PUT_x_container_headers_with_more_container_replicas(self):
self.app.container_ring.set_replicas(4)
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
+ req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
headers={'Content-Length': '5'}, body='12345')
controller = proxy_server.ObjectController(self.app, 'a', 'c', 'o')
seen_headers = self._gather_x_container_headers(
@@ -4942,7 +5028,8 @@ class TestObjectController(unittest.TestCase):
self.app.container_ring.set_replicas(4)
self.app.object_post_as_copy = False
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'POST'},
+ req = Request.blank('/v1/a/c/o',
+ environ={'REQUEST_METHOD': 'POST'},
headers={'Content-Type': 'application/stuff'})
controller = proxy_server.ObjectController(self.app, 'a', 'c', 'o')
seen_headers = self._gather_x_container_headers(
@@ -4964,7 +5051,8 @@ class TestObjectController(unittest.TestCase):
def test_DELETE_x_container_headers_with_more_container_replicas(self):
self.app.container_ring.set_replicas(4)
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'DELETE'},
+ req = Request.blank('/v1/a/c/o',
+ environ={'REQUEST_METHOD': 'DELETE'},
headers={'Content-Type': 'application/stuff'})
controller = proxy_server.ObjectController(self.app, 'a', 'c', 'o')
seen_headers = self._gather_x_container_headers(
@@ -4993,7 +5081,7 @@ class TestObjectController(unittest.TestCase):
delete_at_timestamp /
self.app.expiring_objects_container_divisor *
self.app.expiring_objects_container_divisor)
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
+ req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
headers={'Content-Type': 'application/stuff',
'Content-Length': '0',
'X-Delete-At': str(delete_at_timestamp)})
@@ -5031,7 +5119,7 @@ class TestObjectController(unittest.TestCase):
delete_at_timestamp /
self.app.expiring_objects_container_divisor *
self.app.expiring_objects_container_divisor)
- req = Request.blank('/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
+ req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
headers={'Content-Type': 'application/stuff',
'Content-Length': 0,
'X-Delete-At': str(delete_at_timestamp)})
@@ -5086,14 +5174,14 @@ class TestContainerController(unittest.TestCase):
kwargs['missing_container'] = missing_container
set_http_connect(*statuses, **kwargs)
self.app.memcache.store = {}
- req = Request.blank('/a/c', headers={'Content-Length': '0',
+ req = Request.blank('/v1/a/c', headers={'Content-Length': '0',
'Content-Type': 'text/plain'})
self.app.update_request(req)
res = method(req)
self.assertEquals(res.status_int, expected)
set_http_connect(*statuses, **kwargs)
self.app.memcache.store = {}
- req = Request.blank('/a/c/', headers={'Content-Length': '0',
+ req = Request.blank('/v1/a/c/', headers={'Content-Length': '0',
'Content-Type': 'text/plain'})
self.app.update_request(req)
res = method(req)
@@ -5107,7 +5195,7 @@ class TestContainerController(unittest.TestCase):
c_expected=None, a_expected=None, **kwargs):
set_http_connect(*statuses, **kwargs)
self.app.memcache.store = {}
- req = Request.blank('/a/c', {})
+ req = Request.blank('/v1/a/c', {})
self.app.update_request(req)
res = controller.HEAD(req)
self.assertEquals(res.status[:len(str(expected))],
@@ -5131,7 +5219,7 @@ class TestContainerController(unittest.TestCase):
set_http_connect(*statuses, **kwargs)
self.app.memcache.store = {}
- req = Request.blank('/a/c', {})
+ req = Request.blank('/v1/a/c', {})
self.app.update_request(req)
res = controller.GET(req)
self.assertEquals(res.status[:len(str(expected))],
@@ -5181,7 +5269,7 @@ class TestContainerController(unittest.TestCase):
def test_status_map(statuses, expected, **kwargs):
set_http_connect(*statuses, **kwargs)
self.app.memcache.store = {}
- req = Request.blank('/a/c', {})
+ req = Request.blank('/v1/a/c', {})
req.content_length = 0
self.app.update_request(req)
res = controller.PUT(req)
@@ -5239,7 +5327,7 @@ class TestContainerController(unittest.TestCase):
def test_status_map(statuses, expected, **kwargs):
set_http_connect(*statuses, **kwargs)
self.app.memcache.store = {}
- req = Request.blank('/a/c', {})
+ req = Request.blank('/v1/a/c', {})
req.content_length = 0
self.app.update_request(req)
res = controller.POST(req)
@@ -5318,26 +5406,30 @@ class TestContainerController(unittest.TestCase):
else:
set_http_connect(200, 200, 200, 200)
self.app.memcache.store = {}
- req = Request.blank('/a/c', environ={'REQUEST_METHOD': meth})
+ req = Request.blank('/v1/a/c',
+ environ={'REQUEST_METHOD': meth})
self.app.update_request(req)
resp = getattr(controller, meth)(req)
self.assertEquals(resp.status_int, 200)
set_http_connect(404, 404, 404, 200, 200, 200)
# Make sure it is a blank request wthout env caching
- req = Request.blank('/a/c', environ={'REQUEST_METHOD': meth})
+ req = Request.blank('/v1/a/c',
+ environ={'REQUEST_METHOD': meth})
resp = getattr(controller, meth)(req)
self.assertEquals(resp.status_int, 404)
set_http_connect(503, 404, 404)
# Make sure it is a blank request wthout env caching
- req = Request.blank('/a/c', environ={'REQUEST_METHOD': meth})
+ req = Request.blank('/v1/a/c',
+ environ={'REQUEST_METHOD': meth})
resp = getattr(controller, meth)(req)
self.assertEquals(resp.status_int, 404)
set_http_connect(503, 404, raise_exc=True)
# Make sure it is a blank request wthout env caching
- req = Request.blank('/a/c', environ={'REQUEST_METHOD': meth})
+ req = Request.blank('/v1/a/c',
+ environ={'REQUEST_METHOD': meth})
resp = getattr(controller, meth)(req)
self.assertEquals(resp.status_int, 404)
@@ -5346,7 +5438,8 @@ class TestContainerController(unittest.TestCase):
dev['last_error'] = time.time()
set_http_connect(200, 200, 200, 200, 200, 200)
# Make sure it is a blank request wthout env caching
- req = Request.blank('/a/c', environ={'REQUEST_METHOD': meth})
+ req = Request.blank('/v1/a/c',
+ environ={'REQUEST_METHOD': meth})
resp = getattr(controller, meth)(req)
self.assertEquals(resp.status_int, 404)
@@ -5371,7 +5464,7 @@ class TestContainerController(unittest.TestCase):
self.app.memcache = MockMemcache(allow_lock=True)
set_http_connect(200, 201, 201, 201,
missing_container=True)
- req = Request.blank('/a/c', environ={'REQUEST_METHOD': 'PUT'})
+ req = Request.blank('/v1/a/c', environ={'REQUEST_METHOD': 'PUT'})
self.app.update_request(req)
res = controller.PUT(req)
self.assertEquals(res.status_int, 201)
@@ -5429,7 +5522,7 @@ class TestContainerController(unittest.TestCase):
set_http_connect(200, 200, body='{}')
controller = proxy_server.ContainerController(self.app, 'account',
'container')
- req = Request.blank('/a/c?format=json')
+ req = Request.blank('/v1/a/c?format=json')
self.app.update_request(req)
res = controller.GET(req)
self.assert_('accept-ranges' in res.headers)
@@ -5440,7 +5533,7 @@ class TestContainerController(unittest.TestCase):
set_http_connect(200, 200, body='{}')
controller = proxy_server.ContainerController(self.app, 'account',
'container')
- req = Request.blank('/a/c?format=json')
+ req = Request.blank('/v1/a/c?format=json')
self.app.update_request(req)
res = controller.HEAD(req)
self.assert_('accept-ranges' in res.headers)
@@ -5483,7 +5576,8 @@ class TestContainerController(unittest.TestCase):
controller = \
proxy_server.ContainerController(self.app, 'a', 'c')
set_http_connect(200, 201, 201, 201, give_connect=test_connect)
- req = Request.blank('/a/c', environ={'REQUEST_METHOD': method},
+ req = Request.blank('/v1/a/c',
+ environ={'REQUEST_METHOD': method},
headers={test_header: test_value})
self.app.update_request(req)
getattr(controller, method)(req)
@@ -5499,20 +5593,20 @@ class TestContainerController(unittest.TestCase):
with save_globals():
controller = proxy_server.ContainerController(self.app, 'a', 'c')
set_http_connect(200, 201, 201, 201)
- req = Request.blank('/a/c', environ={'REQUEST_METHOD': method})
+ req = Request.blank('/v1/a/c', environ={'REQUEST_METHOD': method})
self.app.update_request(req)
resp = getattr(controller, method)(req)
self.assertEquals(resp.status_int, 201)
set_http_connect(201, 201, 201)
- req = Request.blank('/a/c', environ={'REQUEST_METHOD': method},
+ req = Request.blank('/v1/a/c', environ={'REQUEST_METHOD': method},
headers={'X-Container-Meta-' +
('a' * MAX_META_NAME_LENGTH): 'v'})
self.app.update_request(req)
resp = getattr(controller, method)(req)
self.assertEquals(resp.status_int, 201)
set_http_connect(201, 201, 201)
- req = Request.blank('/a/c', environ={'REQUEST_METHOD': method},
+ req = Request.blank('/v1/a/c', environ={'REQUEST_METHOD': method},
headers={'X-Container-Meta-' +
('a' * (MAX_META_NAME_LENGTH + 1)): 'v'})
self.app.update_request(req)
@@ -5520,14 +5614,14 @@ class TestContainerController(unittest.TestCase):
self.assertEquals(resp.status_int, 400)
set_http_connect(201, 201, 201)
- req = Request.blank('/a/c', environ={'REQUEST_METHOD': method},
+ req = Request.blank('/v1/a/c', environ={'REQUEST_METHOD': method},
headers={'X-Container-Meta-Too-Long':
'a' * MAX_META_VALUE_LENGTH})
self.app.update_request(req)
resp = getattr(controller, method)(req)
self.assertEquals(resp.status_int, 201)
set_http_connect(201, 201, 201)
- req = Request.blank('/a/c', environ={'REQUEST_METHOD': method},
+ req = Request.blank('/v1/a/c', environ={'REQUEST_METHOD': method},
headers={'X-Container-Meta-Too-Long':
'a' * (MAX_META_VALUE_LENGTH + 1)})
self.app.update_request(req)
@@ -5538,7 +5632,7 @@ class TestContainerController(unittest.TestCase):
headers = {}
for x in xrange(MAX_META_COUNT):
headers['X-Container-Meta-%d' % x] = 'v'
- req = Request.blank('/a/c', environ={'REQUEST_METHOD': method},
+ req = Request.blank('/v1/a/c', environ={'REQUEST_METHOD': method},
headers=headers)
self.app.update_request(req)
resp = getattr(controller, method)(req)
@@ -5547,7 +5641,7 @@ class TestContainerController(unittest.TestCase):
headers = {}
for x in xrange(MAX_META_COUNT + 1):
headers['X-Container-Meta-%d' % x] = 'v'
- req = Request.blank('/a/c', environ={'REQUEST_METHOD': method},
+ req = Request.blank('/v1/a/c', environ={'REQUEST_METHOD': method},
headers=headers)
self.app.update_request(req)
resp = getattr(controller, method)(req)
@@ -5565,7 +5659,7 @@ class TestContainerController(unittest.TestCase):
if MAX_META_OVERALL_SIZE - size > 1:
headers['X-Container-Meta-a'] = \
'a' * (MAX_META_OVERALL_SIZE - size - 1)
- req = Request.blank('/a/c', environ={'REQUEST_METHOD': method},
+ req = Request.blank('/v1/a/c', environ={'REQUEST_METHOD': method},
headers=headers)
self.app.update_request(req)
resp = getattr(controller, method)(req)
@@ -5573,7 +5667,7 @@ class TestContainerController(unittest.TestCase):
set_http_connect(201, 201, 201)
headers['X-Container-Meta-a'] = \
'a' * (MAX_META_OVERALL_SIZE - size)
- req = Request.blank('/a/c', environ={'REQUEST_METHOD': method},
+ req = Request.blank('/v1/a/c', environ={'REQUEST_METHOD': method},
headers=headers)
self.app.update_request(req)
resp = getattr(controller, method)(req)
@@ -5589,7 +5683,7 @@ class TestContainerController(unittest.TestCase):
set_http_connect(200, 201, 201, 201)
controller = proxy_server.ContainerController(self.app, 'account',
'container')
- req = Request.blank('/a/c', environ={'REQUEST_METHOD': 'POST'},
+ req = Request.blank('/v1/a/c', environ={'REQUEST_METHOD': 'POST'},
headers={'X-Container-Read': '.r:*'})
req.environ['swift.clean_acl'] = clean_acl
self.app.update_request(req)
@@ -5600,7 +5694,7 @@ class TestContainerController(unittest.TestCase):
set_http_connect(200, 201, 201, 201)
controller = proxy_server.ContainerController(self.app, 'account',
'container')
- req = Request.blank('/a/c', environ={'REQUEST_METHOD': 'POST'},
+ req = Request.blank('/v1/a/c', environ={'REQUEST_METHOD': 'POST'},
headers={'X-Container-Write': '.r:*'})
req.environ['swift.clean_acl'] = clean_acl
self.app.update_request(req)
@@ -5617,7 +5711,7 @@ class TestContainerController(unittest.TestCase):
set_http_connect(200, 201, 201, 201)
controller = proxy_server.ContainerController(self.app, 'account',
'container')
- req = Request.blank('/a/c', environ={'REQUEST_METHOD': 'PUT'},
+ req = Request.blank('/v1/a/c', environ={'REQUEST_METHOD': 'PUT'},
headers={'X-Container-Read': '.r:*'})
req.environ['swift.clean_acl'] = clean_acl
self.app.update_request(req)
@@ -5628,7 +5722,7 @@ class TestContainerController(unittest.TestCase):
set_http_connect(200, 201, 201, 201)
controller = proxy_server.ContainerController(self.app, 'account',
'container')
- req = Request.blank('/a/c', environ={'REQUEST_METHOD': 'PUT'},
+ req = Request.blank('/v1/a/c', environ={'REQUEST_METHOD': 'PUT'},
headers={'X-Container-Write': '.r:*'})
req.environ['swift.clean_acl'] = clean_acl
self.app.update_request(req)
@@ -5640,9 +5734,10 @@ class TestContainerController(unittest.TestCase):
set_http_connect(200, 204, 204, 204)
controller = proxy_server.ContainerController(self.app, 'account',
'container')
- req = Request.blank('/a/c')
+ req = Request.blank('/v1/a/c')
self.app.update_request(req)
res = controller.GET(req)
+ self.assertEquals(res.status_int, 204)
self.assertEquals(
res.environ['swift.container/a/c']['status'], 204)
self.assertEquals(res.content_length, 0)
@@ -5658,7 +5753,7 @@ class TestContainerController(unittest.TestCase):
set_http_connect(200, 201, 201, 201)
controller = proxy_server.ContainerController(self.app, 'account',
'container')
- req = Request.blank('/a/c')
+ req = Request.blank('/v1/a/c')
req.environ['swift.authorize'] = authorize
self.app.update_request(req)
res = controller.GET(req)
@@ -5675,7 +5770,7 @@ class TestContainerController(unittest.TestCase):
set_http_connect(200, 201, 201, 201)
controller = proxy_server.ContainerController(self.app, 'account',
'container')
- req = Request.blank('/a/c', {'REQUEST_METHOD': 'HEAD'})
+ req = Request.blank('/v1/a/c', {'REQUEST_METHOD': 'HEAD'})
req.environ['swift.authorize'] = authorize
self.app.update_request(req)
controller.HEAD(req)
@@ -5689,7 +5784,7 @@ class TestContainerController(unittest.TestCase):
return {}
controller.container_info = my_empty_container_info
req = Request.blank(
- '/a/c',
+ '/v1/a/c',
{'REQUEST_METHOD': 'OPTIONS'},
headers={'Origin': 'http://foo.com',
'Access-Control-Request-Method': 'GET'})
@@ -5700,7 +5795,7 @@ class TestContainerController(unittest.TestCase):
return {'cors': {'allow_origin': None}}
controller.container_info = my_empty_origin_container_info
req = Request.blank(
- '/a/c',
+ '/v1/a/c',
{'REQUEST_METHOD': 'OPTIONS'},
headers={'Origin': 'http://foo.com',
'Access-Control-Request-Method': 'GET'})
@@ -5716,7 +5811,7 @@ class TestContainerController(unittest.TestCase):
}
controller.container_info = my_container_info
req = Request.blank(
- '/a/c',
+ '/v1/a/c',
{'REQUEST_METHOD': 'OPTIONS'},
headers={'Origin': 'https://foo.bar',
'Access-Control-Request-Method': 'GET'})
@@ -5734,13 +5829,13 @@ class TestContainerController(unittest.TestCase):
6)
self.assertEquals('999', resp.headers['access-control-max-age'])
req = Request.blank(
- '/a/c',
+ '/v1/a/c',
{'REQUEST_METHOD': 'OPTIONS'},
headers={'Origin': 'https://foo.bar'})
req.content_length = 0
resp = controller.OPTIONS(req)
self.assertEquals(401, resp.status_int)
- req = Request.blank('/a/c', {'REQUEST_METHOD': 'OPTIONS'})
+ req = Request.blank('/v1/a/c', {'REQUEST_METHOD': 'OPTIONS'})
req.content_length = 0
resp = controller.OPTIONS(req)
self.assertEquals(200, resp.status_int)
@@ -5749,14 +5844,14 @@ class TestContainerController(unittest.TestCase):
verb in resp.headers['Allow'])
self.assertEquals(len(resp.headers['Allow'].split(', ')), 6)
req = Request.blank(
- '/a/c',
+ '/v1/a/c',
{'REQUEST_METHOD': 'OPTIONS'},
headers={'Origin': 'http://foo.bar',
'Access-Control-Request-Method': 'GET'})
resp = controller.OPTIONS(req)
self.assertEquals(401, resp.status_int)
req = Request.blank(
- '/a/c',
+ '/v1/a/c',
{'REQUEST_METHOD': 'OPTIONS'},
headers={'Origin': 'http://foo.bar',
'Access-Control-Request-Method': 'GET'})
@@ -5773,7 +5868,7 @@ class TestContainerController(unittest.TestCase):
}
controller.container_info = my_container_info_wildcard
req = Request.blank(
- '/a/c/o.jpg',
+ '/v1/a/c/o.jpg',
{'REQUEST_METHOD': 'OPTIONS'},
headers={'Origin': 'https://bar.baz',
'Access-Control-Request-Method': 'GET'})
@@ -5792,7 +5887,7 @@ class TestContainerController(unittest.TestCase):
self.assertEquals('999', resp.headers['access-control-max-age'])
req = Request.blank(
- '/a/c/o.jpg',
+ '/v1/a/c/o.jpg',
{'REQUEST_METHOD': 'OPTIONS'},
headers={'Origin': 'https://bar.baz',
'Access-Control-Request-Headers':
@@ -5825,7 +5920,7 @@ class TestContainerController(unittest.TestCase):
})
req = Request.blank(
- '/a/c',
+ '/v1/a/c',
{'REQUEST_METHOD': 'GET'},
headers={'Origin': 'http://foo.bar'})
@@ -5875,7 +5970,7 @@ class TestContainerController(unittest.TestCase):
def test_PUT_x_account_headers_with_fewer_account_replicas(self):
self.app.account_ring.set_replicas(2)
- req = Request.blank('/a/c', headers={'': ''})
+ req = Request.blank('/v1/a/c', headers={'': ''})
controller = proxy_server.ContainerController(self.app, 'a', 'c')
seen_headers = self._gather_x_account_headers(
@@ -5895,7 +5990,7 @@ class TestContainerController(unittest.TestCase):
def test_PUT_x_account_headers_with_more_account_replicas(self):
self.app.account_ring.set_replicas(4)
- req = Request.blank('/a/c', headers={'': ''})
+ req = Request.blank('/v1/a/c', headers={'': ''})
controller = proxy_server.ContainerController(self.app, 'a', 'c')
seen_headers = self._gather_x_account_headers(
@@ -5915,7 +6010,7 @@ class TestContainerController(unittest.TestCase):
def test_DELETE_x_account_headers_with_fewer_account_replicas(self):
self.app.account_ring.set_replicas(2)
- req = Request.blank('/a/c', headers={'': ''})
+ req = Request.blank('/v1/a/c', headers={'': ''})
controller = proxy_server.ContainerController(self.app, 'a', 'c')
seen_headers = self._gather_x_account_headers(
@@ -5935,7 +6030,7 @@ class TestContainerController(unittest.TestCase):
def test_DELETE_x_account_headers_with_more_account_replicas(self):
self.app.account_ring.set_replicas(4)
- req = Request.blank('/a/c', headers={'': ''})
+ req = Request.blank('/v1/a/c', headers={'': ''})
controller = proxy_server.ContainerController(self.app, 'a', 'c')
seen_headers = self._gather_x_account_headers(
@@ -5953,6 +6048,19 @@ class TestContainerController(unittest.TestCase):
'X-Account-Device': 'sdc'}
])
+ def test_node_read_timeout_retry_to_container(self):
+ with save_globals():
+ req = Request.blank('/v1/a/c', environ={'REQUEST_METHOD': 'GET'})
+ self.app.node_timeout = 0.1
+ set_http_connect(200, 200, 200, body='abcdef', slow=[2])
+ resp = req.get_response(self.app)
+ got_exc = False
+ try:
+ resp.body
+ except ChunkReadTimeout:
+ got_exc = True
+ self.assert_(got_exc)
+
class TestAccountController(unittest.TestCase):
@@ -5965,7 +6073,7 @@ class TestAccountController(unittest.TestCase):
def assert_status_map(self, method, statuses, expected, env_expected=None):
with save_globals():
set_http_connect(*statuses)
- req = Request.blank('/a', {})
+ req = Request.blank('/v1/a', {})
self.app.update_request(req)
res = method(req)
self.assertEquals(res.status_int, expected)
@@ -5973,7 +6081,7 @@ class TestAccountController(unittest.TestCase):
self.assertEquals(res.environ['swift.account/a']['status'],
env_expected)
set_http_connect(*statuses)
- req = Request.blank('/a/', {})
+ req = Request.blank('/v1/a/', {})
self.app.update_request(req)
res = method(req)
self.assertEquals(res.status_int, expected)
@@ -5985,7 +6093,7 @@ class TestAccountController(unittest.TestCase):
with save_globals():
self.app.allow_account_management = False
controller = proxy_server.AccountController(self.app, 'account')
- req = Request.blank('/account', {'REQUEST_METHOD': 'OPTIONS'})
+ req = Request.blank('/v1/account', {'REQUEST_METHOD': 'OPTIONS'})
req.content_length = 0
resp = controller.OPTIONS(req)
self.assertEquals(200, resp.status_int)
@@ -5999,7 +6107,7 @@ class TestAccountController(unittest.TestCase):
self.app.allow_account_management = False
controller = proxy_server.AccountController(self.app, 'account')
req = Request.blank(
- '/account', {'REQUEST_METHOD': 'OPTIONS'},
+ '/v1/account', {'REQUEST_METHOD': 'OPTIONS'},
headers={'Origin': 'http://foo.com',
'Access-Control-Request-Method': 'GET'})
req.content_length = 0
@@ -6012,7 +6120,7 @@ class TestAccountController(unittest.TestCase):
self.app.allow_account_management = True
controller = proxy_server.AccountController(self.app, 'account')
- req = Request.blank('/account', {'REQUEST_METHOD': 'OPTIONS'})
+ req = Request.blank('/v1/account', {'REQUEST_METHOD': 'OPTIONS'})
req.content_length = 0
resp = controller.OPTIONS(req)
self.assertEquals(200, resp.status_int)
@@ -6130,7 +6238,7 @@ class TestAccountController(unittest.TestCase):
dev['ip'] = '127.0.0.1'
dev['port'] = 1 # can't connect on this port
controller = proxy_server.AccountController(self.app, 'account')
- req = Request.blank('/account', environ={'REQUEST_METHOD': 'HEAD'})
+ req = Request.blank('/v1/account', environ={'REQUEST_METHOD': 'HEAD'})
self.app.update_request(req)
resp = controller.HEAD(req)
self.assertEquals(resp.status_int, 503)
@@ -6141,7 +6249,7 @@ class TestAccountController(unittest.TestCase):
dev['ip'] = '127.0.0.1'
dev['port'] = -1 # invalid port number
controller = proxy_server.AccountController(self.app, 'account')
- req = Request.blank('/account', environ={'REQUEST_METHOD': 'HEAD'})
+ req = Request.blank('/v1/account', environ={'REQUEST_METHOD': 'HEAD'})
self.app.update_request(req)
resp = controller.HEAD(req)
self.assertEquals(resp.status_int, 503)
@@ -6150,7 +6258,7 @@ class TestAccountController(unittest.TestCase):
with save_globals():
set_http_connect(200, 200, body='{}')
controller = proxy_server.AccountController(self.app, 'account')
- req = Request.blank('/a?format=json')
+ req = Request.blank('/v1/a?format=json')
self.app.update_request(req)
res = controller.GET(req)
self.assert_('accept-ranges' in res.headers)
@@ -6160,7 +6268,7 @@ class TestAccountController(unittest.TestCase):
with save_globals():
set_http_connect(200, 200, body='{}')
controller = proxy_server.AccountController(self.app, 'account')
- req = Request.blank('/a?format=json')
+ req = Request.blank('/v1/a?format=json')
self.app.update_request(req)
res = controller.HEAD(req)
res.body
@@ -6174,7 +6282,7 @@ class TestAccountController(unittest.TestCase):
def test_status_map(statuses, expected, **kwargs):
set_http_connect(*statuses, **kwargs)
self.app.memcache.store = {}
- req = Request.blank('/a', {})
+ req = Request.blank('/v1/a', {})
req.content_length = 0
self.app.update_request(req)
res = controller.PUT(req)
@@ -6239,7 +6347,8 @@ class TestAccountController(unittest.TestCase):
controller = \
proxy_server.AccountController(self.app, 'a')
set_http_connect(201, 201, 201, give_connect=test_connect)
- req = Request.blank('/a/c', environ={'REQUEST_METHOD': method},
+ req = Request.blank('/v1/a/c',
+ environ={'REQUEST_METHOD': method},
headers={test_header: test_value})
self.app.update_request(req)
getattr(controller, method)(req)
@@ -6256,20 +6365,20 @@ class TestAccountController(unittest.TestCase):
self.app.allow_account_management = True
controller = proxy_server.AccountController(self.app, 'a')
set_http_connect(200, 201, 201, 201)
- req = Request.blank('/a/c', environ={'REQUEST_METHOD': method})
+ req = Request.blank('/v1/a/c', environ={'REQUEST_METHOD': method})
self.app.update_request(req)
resp = getattr(controller, method)(req)
self.assertEquals(resp.status_int, 201)
set_http_connect(201, 201, 201)
- req = Request.blank('/a/c', environ={'REQUEST_METHOD': method},
+ req = Request.blank('/v1/a/c', environ={'REQUEST_METHOD': method},
headers={'X-Account-Meta-' +
('a' * MAX_META_NAME_LENGTH): 'v'})
self.app.update_request(req)
resp = getattr(controller, method)(req)
self.assertEquals(resp.status_int, 201)
set_http_connect(201, 201, 201)
- req = Request.blank('/a/c', environ={'REQUEST_METHOD': method},
+ req = Request.blank('/v1/a/c', environ={'REQUEST_METHOD': method},
headers={'X-Account-Meta-' +
('a' * (MAX_META_NAME_LENGTH + 1)): 'v'})
self.app.update_request(req)
@@ -6277,14 +6386,14 @@ class TestAccountController(unittest.TestCase):
self.assertEquals(resp.status_int, 400)
set_http_connect(201, 201, 201)
- req = Request.blank('/a/c', environ={'REQUEST_METHOD': method},
+ req = Request.blank('/v1/a/c', environ={'REQUEST_METHOD': method},
headers={'X-Account-Meta-Too-Long':
'a' * MAX_META_VALUE_LENGTH})
self.app.update_request(req)
resp = getattr(controller, method)(req)
self.assertEquals(resp.status_int, 201)
set_http_connect(201, 201, 201)
- req = Request.blank('/a/c', environ={'REQUEST_METHOD': method},
+ req = Request.blank('/v1/a/c', environ={'REQUEST_METHOD': method},
headers={'X-Account-Meta-Too-Long':
'a' * (MAX_META_VALUE_LENGTH + 1)})
self.app.update_request(req)
@@ -6295,7 +6404,7 @@ class TestAccountController(unittest.TestCase):
headers = {}
for x in xrange(MAX_META_COUNT):
headers['X-Account-Meta-%d' % x] = 'v'
- req = Request.blank('/a/c', environ={'REQUEST_METHOD': method},
+ req = Request.blank('/v1/a/c', environ={'REQUEST_METHOD': method},
headers=headers)
self.app.update_request(req)
resp = getattr(controller, method)(req)
@@ -6304,7 +6413,7 @@ class TestAccountController(unittest.TestCase):
headers = {}
for x in xrange(MAX_META_COUNT + 1):
headers['X-Account-Meta-%d' % x] = 'v'
- req = Request.blank('/a/c', environ={'REQUEST_METHOD': method},
+ req = Request.blank('/v1/a/c', environ={'REQUEST_METHOD': method},
headers=headers)
self.app.update_request(req)
resp = getattr(controller, method)(req)
@@ -6322,7 +6431,7 @@ class TestAccountController(unittest.TestCase):
if MAX_META_OVERALL_SIZE - size > 1:
headers['X-Account-Meta-a'] = \
'a' * (MAX_META_OVERALL_SIZE - size - 1)
- req = Request.blank('/a/c', environ={'REQUEST_METHOD': method},
+ req = Request.blank('/v1/a/c', environ={'REQUEST_METHOD': method},
headers=headers)
self.app.update_request(req)
resp = getattr(controller, method)(req)
@@ -6330,7 +6439,7 @@ class TestAccountController(unittest.TestCase):
set_http_connect(201, 201, 201)
headers['X-Account-Meta-a'] = \
'a' * (MAX_META_OVERALL_SIZE - size)
- req = Request.blank('/a/c', environ={'REQUEST_METHOD': method},
+ req = Request.blank('/v1/a/c', environ={'REQUEST_METHOD': method},
headers=headers)
self.app.update_request(req)
resp = getattr(controller, method)(req)
@@ -6343,7 +6452,7 @@ class TestAccountController(unittest.TestCase):
def test_status_map(statuses, expected, **kwargs):
set_http_connect(*statuses, **kwargs)
self.app.memcache.store = {}
- req = Request.blank('/a', {'REQUEST_METHOD': 'DELETE'})
+ req = Request.blank('/v1/a', {'REQUEST_METHOD': 'DELETE'})
req.content_length = 0
self.app.update_request(req)
res = controller.DELETE(req)
@@ -6366,7 +6475,8 @@ class TestAccountController(unittest.TestCase):
def test_status_map(statuses, expected, **kwargs):
set_http_connect(*statuses, **kwargs)
self.app.memcache.store = {}
- req = Request.blank('/a?whoops', {'REQUEST_METHOD': 'DELETE'})
+ req = Request.blank('/v1/a?whoops',
+ environ={'REQUEST_METHOD': 'DELETE'})
req.content_length = 0
self.app.update_request(req)
res = controller.DELETE(req)
@@ -6856,7 +6966,7 @@ class TestProxyObjectPerformance(unittest.TestCase):
self.obj_len = obj_len
def test_GET_debug_large_file(self):
- for i in range(0, 10):
+ for i in range(10):
start = time.time()
prolis = _test_sockets[0]
@@ -6885,6 +6995,33 @@ class TestProxyObjectPerformance(unittest.TestCase):
print "Run %02d took %07.03f" % (i, end - start)
+class TestSwiftInfo(unittest.TestCase):
+ def setUp(self):
+ utils._swift_info = {}
+ utils._swift_admin_info = {}
+
+ def test_registered_defaults(self):
+ proxy_server.Application({}, FakeMemcache(),
+ account_ring=FakeRing(),
+ container_ring=FakeRing(),
+ object_ring=FakeRing)
+
+ si = utils.get_swift_info()['swift']
+ self.assertTrue('version' in si)
+ self.assertEqual(si['max_file_size'], MAX_FILE_SIZE)
+ self.assertEqual(si['max_meta_name_length'], MAX_META_NAME_LENGTH)
+ self.assertEqual(si['max_meta_value_length'], MAX_META_VALUE_LENGTH)
+ self.assertEqual(si['max_meta_count'], MAX_META_COUNT)
+ self.assertEqual(si['account_listing_limit'], ACCOUNT_LISTING_LIMIT)
+ self.assertEqual(si['container_listing_limit'],
+ CONTAINER_LISTING_LIMIT)
+ self.assertEqual(si['max_account_name_length'],
+ MAX_ACCOUNT_NAME_LENGTH)
+ self.assertEqual(si['max_container_name_length'],
+ MAX_CONTAINER_NAME_LENGTH)
+ self.assertEqual(si['max_object_name_length'], MAX_OBJECT_NAME_LENGTH)
+
+
if __name__ == '__main__':
setup()
try:
diff --git a/tools/requirements.txt b/tools/requirements.txt
new file mode 100644
index 0000000..1139866
--- /dev/null
+++ b/tools/requirements.txt
@@ -0,0 +1,8 @@
+dnspython>=1.9.4
+eventlet>=0.9.15
+greenlet>=0.3.1
+netifaces>=0.5
+pastedeploy>=1.3.3
+simplejson>=2.0.9
+xattr>=0.4
+python-swiftclient
diff --git a/tools/test-requires b/tools/test-requires
index 6bf711e..d2c027f 100644
--- a/tools/test-requires
+++ b/tools/test-requires
@@ -8,7 +8,7 @@ nose
nosexcover
openstack.nose_plugin
nosehtmloutput
-sphinx>=1.1.2
+sphinx>=1.1.2,<1.2
mock>=0.8.0
python-keystoneclient
prettytable
diff --git a/tox.ini b/tox.ini
index acb6065..07f0587 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,7 +1,11 @@
[tox]
envlist = py26,py27,pep8,functest,ksfunctest
+minversion = 1.6
+skipsdist = True
[testenv]
+usedevelop = True
+install_command = pip install --allow-external netifaces --allow-insecure netifaces -U {opts} {packages}
whitelist_externals=bash
setenv = VIRTUAL_ENV={envdir}
NOSE_WITH_OPENSTACK=1
@@ -11,9 +15,10 @@ setenv = VIRTUAL_ENV={envdir}
NOSE_OPENSTACK_SHOW_ELAPSED=1
NOSE_OPENSTACK_STDOUT=1
deps =
- https://launchpad.net/gluster-swift/icehouse/1.10.2/+download/swift-1.10.0.172.g9fe7748.tar.gz
+ https://launchpad.net/gluster-swift/icehouse/1.11.0/+download/swift-1.11.0.71.gf310006.tar.gz
--download-cache={homedir}/.pipcache
-r{toxinidir}/tools/test-requires
+ -r{toxinidir}/tools/requirements.txt
changedir = {toxinidir}/test/unit
commands = nosetests -v --exe --with-xunit --with-coverage --cover-package gluster --cover-erase --cover-xml --cover-html --cover-branches --with-html-output {posargs}