Merge "Decoupled Unit Tests"
This commit is contained in:
commit
f227a24651
@ -16,30 +16,8 @@
|
||||
# single module.
|
||||
|
||||
from marconi.tests.queues.transport.wsgi import base
|
||||
from marconi.tests.queues.transport.wsgi import test_auth
|
||||
from marconi.tests.queues.transport.wsgi import test_claims
|
||||
from marconi.tests.queues.transport.wsgi import test_default_limits
|
||||
from marconi.tests.queues.transport.wsgi import test_home
|
||||
from marconi.tests.queues.transport.wsgi import test_media_type
|
||||
from marconi.tests.queues.transport.wsgi import test_messages
|
||||
from marconi.tests.queues.transport.wsgi import test_queue_lifecycle as lc
|
||||
from marconi.tests.queues.transport.wsgi import test_shards
|
||||
|
||||
TestBase = base.TestBase
|
||||
TestBaseFaulty = base.TestBaseFaulty
|
||||
TestAuth = test_auth.TestAuth
|
||||
TestClaimsFaultyDriver = test_claims.TestClaimsFaultyDriver
|
||||
TestClaimsMongoDB = test_claims.TestClaimsMongoDB
|
||||
TestClaimsSqlalchemy = test_claims.TestClaimsSqlalchemy
|
||||
TestDefaultLimits = test_default_limits.TestDefaultLimits
|
||||
TestHomeDocument = test_home.TestHomeDocument
|
||||
TestMediaType = test_media_type.TestMediaType
|
||||
TestMessagesFaultyDriver = test_messages.TestMessagesFaultyDriver
|
||||
TestMessagesMongoDB = test_messages.TestMessagesMongoDB
|
||||
TestMessagesMongoDBSharded = test_messages.TestMessagesMongoDBSharded
|
||||
TestMessagesSqlalchemy = test_messages.TestMessagesSqlalchemy
|
||||
TestQueueFaultyDriver = lc.TestQueueLifecycleFaultyDriver
|
||||
TestQueueLifecycleMongoDB = lc.TestQueueLifecycleMongoDB
|
||||
TestQueueLifecycleSqlalchemy = lc.TestQueueLifecycleSqlalchemy
|
||||
TestShardsMongoDB = test_shards.TestShardsMongoDB
|
||||
TestShardsSqlalchemy = test_shards.TestShardsSqlalchemy
|
||||
V1Base = base.V1Base
|
||||
V1_1Base = base.V1_1Base
|
||||
|
@ -106,3 +106,43 @@ class TestBase(testing.TestBase):
|
||||
|
||||
class TestBaseFaulty(TestBase):
|
||||
"""This test ensures we aren't letting any exceptions go unhandled."""
|
||||
|
||||
|
||||
class V1Base(TestBase):
|
||||
"""Base class for V1 API Tests.
|
||||
Should contain methods specific to V1 of the API
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class V1BaseFaulty(TestBaseFaulty):
|
||||
"""Base class for V1 API Faulty Tests.
|
||||
Should contain methods specific to V1 exception testing
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class V1_1Base(TestBase):
|
||||
"""Base class for V1 API Tests.
|
||||
Should contain methods specific to V1.1 of the API
|
||||
"""
|
||||
|
||||
def simulate_request(self, path, **kwargs):
|
||||
"""Simulate a request.
|
||||
|
||||
Simulates a WSGI request to the API for testing.
|
||||
|
||||
:param path: Request path for the desired resource
|
||||
:param kwargs: Same as falcon.testing.create_environ()
|
||||
|
||||
:returns: standard WSGI iterable response
|
||||
"""
|
||||
return self.app(ftest.create_environ(path=path, **kwargs),
|
||||
self.srmock)
|
||||
|
||||
|
||||
class V1_1BaseFaulty(TestBaseFaulty):
|
||||
"""Base class for V1.1 API Faulty Tests.
|
||||
Should contain methods specific to V1.1 exception testing
|
||||
"""
|
||||
pass
|
||||
|
39
marconi/tests/queues/transport/wsgi/v1/__init__.py
Normal file
39
marconi/tests/queues/transport/wsgi/v1/__init__.py
Normal file
@ -0,0 +1,39 @@
|
||||
# Copyright (c) 2014 Rackspace, Inc.
|
||||
#
|
||||
# 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.
|
||||
|
||||
from marconi.tests.queues.transport.wsgi.v1 import test_auth
|
||||
from marconi.tests.queues.transport.wsgi.v1 import test_claims
|
||||
from marconi.tests.queues.transport.wsgi.v1 import test_default_limits
|
||||
from marconi.tests.queues.transport.wsgi.v1 import test_home
|
||||
from marconi.tests.queues.transport.wsgi.v1 import test_media_type
|
||||
from marconi.tests.queues.transport.wsgi.v1 import test_messages
|
||||
from marconi.tests.queues.transport.wsgi.v1 import test_queue_lifecycle as lc
|
||||
from marconi.tests.queues.transport.wsgi.v1 import test_shards
|
||||
|
||||
TestAuth = test_auth.TestAuth
|
||||
TestClaimsFaultyDriver = test_claims.TestClaimsFaultyDriver
|
||||
TestClaimsMongoDB = test_claims.TestClaimsMongoDB
|
||||
TestClaimsSqlalchemy = test_claims.TestClaimsSqlalchemy
|
||||
TestDefaultLimits = test_default_limits.TestDefaultLimits
|
||||
TestHomeDocument = test_home.TestHomeDocument
|
||||
TestMediaType = test_media_type.TestMediaType
|
||||
TestMessagesFaultyDriver = test_messages.TestMessagesFaultyDriver
|
||||
TestMessagesMongoDB = test_messages.TestMessagesMongoDB
|
||||
TestMessagesMongoDBSharded = test_messages.TestMessagesMongoDBSharded
|
||||
TestMessagesSqlalchemy = test_messages.TestMessagesSqlalchemy
|
||||
TestQueueFaultyDriver = lc.TestQueueLifecycleFaultyDriver
|
||||
TestQueueLifecycleMongoDB = lc.TestQueueLifecycleMongoDB
|
||||
TestQueueLifecycleSqlalchemy = lc.TestQueueLifecycleSqlalchemy
|
||||
TestShardsMongoDB = test_shards.TestShardsMongoDB
|
||||
TestShardsSqlalchemy = test_shards.TestShardsSqlalchemy
|
@ -20,10 +20,10 @@ import falcon
|
||||
from falcon import testing
|
||||
from keystoneclient.middleware import auth_token
|
||||
|
||||
from . import base # noqa
|
||||
from marconi.tests.queues.transport.wsgi import base
|
||||
|
||||
|
||||
class TestAuth(base.TestBase):
|
||||
class TestAuth(base.V1Base):
|
||||
|
||||
config_file = 'keystone_auth.conf'
|
||||
|
@ -14,7 +14,6 @@
|
||||
# limitations under the License.
|
||||
|
||||
import datetime
|
||||
import json
|
||||
import uuid
|
||||
|
||||
import ddt
|
||||
@ -22,13 +21,14 @@ import falcon
|
||||
import mock
|
||||
from testtools import matchers
|
||||
|
||||
from . import base # noqa
|
||||
from marconi.openstack.common import jsonutils
|
||||
from marconi.openstack.common import timeutils
|
||||
from marconi import tests as testing
|
||||
from marconi.tests.queues.transport.wsgi import base
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class ClaimsBaseTest(base.TestBase):
|
||||
class ClaimsBaseTest(base.V1Base):
|
||||
|
||||
def setUp(self):
|
||||
super(ClaimsBaseTest, self).setUp()
|
||||
@ -43,7 +43,7 @@ class ClaimsBaseTest(base.TestBase):
|
||||
self.simulate_put(self.queue_path, self.project_id, body=doc)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_201)
|
||||
|
||||
doc = json.dumps([{'body': 239, 'ttl': 300}] * 10)
|
||||
doc = jsonutils.dumps([{'body': 239, 'ttl': 300}] * 10)
|
||||
self.simulate_post(self.queue_path + '/messages', self.project_id,
|
||||
body=doc, headers={'Client-ID': str(uuid.uuid4())})
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_201)
|
||||
@ -74,7 +74,7 @@ class ClaimsBaseTest(base.TestBase):
|
||||
def test_unacceptable_ttl_or_grace(self, ttl_grace):
|
||||
ttl, grace = ttl_grace
|
||||
self.simulate_post(self.claims_path, self.project_id,
|
||||
body=json.dumps({'ttl': ttl, 'grace': grace}))
|
||||
body=jsonutils.dumps({'ttl': ttl, 'grace': grace}))
|
||||
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
@ -83,7 +83,7 @@ class ClaimsBaseTest(base.TestBase):
|
||||
href = self._get_a_claim()
|
||||
|
||||
self.simulate_patch(href, self.project_id,
|
||||
body=json.dumps({'ttl': ttl}))
|
||||
body=jsonutils.dumps({'ttl': ttl}))
|
||||
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
@ -99,7 +99,7 @@ class ClaimsBaseTest(base.TestBase):
|
||||
body = self.simulate_post(self.claims_path, self.project_id, body=doc)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_201)
|
||||
|
||||
claimed = json.loads(body[0])
|
||||
claimed = jsonutils.loads(body[0])
|
||||
claim_href = self.srmock.headers_dict['Location']
|
||||
message_href, params = claimed[0]['href'].split('?')
|
||||
|
||||
@ -121,7 +121,7 @@ class ClaimsBaseTest(base.TestBase):
|
||||
body = self.simulate_get(self.messages_path, self.project_id,
|
||||
query_string='include_claimed=true',
|
||||
headers=headers)
|
||||
listed = json.loads(body[0])
|
||||
listed = jsonutils.loads(body[0])
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
self.assertEqual(len(listed['messages']), len(claimed))
|
||||
|
||||
@ -131,7 +131,7 @@ class ClaimsBaseTest(base.TestBase):
|
||||
mock_utcnow.return_value = now
|
||||
body = self.simulate_get(claim_href, self.project_id)
|
||||
|
||||
claim = json.loads(body[0])
|
||||
claim = jsonutils.loads(body[0])
|
||||
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
self.assertEqual(self.srmock.headers_dict['Content-Location'],
|
||||
@ -166,7 +166,7 @@ class ClaimsBaseTest(base.TestBase):
|
||||
# Get the claimed messages (again)
|
||||
body = self.simulate_get(claim_href, self.project_id)
|
||||
query = timeutils.utcnow()
|
||||
claim = json.loads(body[0])
|
||||
claim = jsonutils.loads(body[0])
|
||||
message_href, params = claim['messages'][0]['href'].split('?')
|
||||
|
||||
self.assertEqual(claim['ttl'], 60)
|
||||
@ -218,7 +218,7 @@ class ClaimsBaseTest(base.TestBase):
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
def test_patch_nonexistent_claim_404s(self):
|
||||
patch_data = json.dumps({'ttl': 100})
|
||||
patch_data = jsonutils.dumps({'ttl': 100})
|
||||
self.simulate_patch(self.claims_path + '/a', body=patch_data)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_404)
|
||||
|
||||
@ -248,7 +248,7 @@ class TestClaimsSqlalchemy(ClaimsBaseTest):
|
||||
config_file = 'wsgi_sqlalchemy.conf'
|
||||
|
||||
|
||||
class TestClaimsFaultyDriver(base.TestBaseFaulty):
|
||||
class TestClaimsFaultyDriver(base.V1BaseFaulty):
|
||||
|
||||
config_file = 'wsgi_faulty.conf'
|
||||
|
@ -14,18 +14,16 @@
|
||||
# limitations under the License.
|
||||
|
||||
import contextlib
|
||||
import json
|
||||
import uuid
|
||||
|
||||
import falcon
|
||||
|
||||
from . import base # noqa
|
||||
|
||||
from marconi.openstack.common import jsonutils
|
||||
from marconi.queues import storage
|
||||
from marconi.tests.queues.transport.wsgi import base
|
||||
|
||||
|
||||
class TestDefaultLimits(base.TestBase):
|
||||
class TestDefaultLimits(base.V1Base):
|
||||
|
||||
config_file = 'wsgi_sqlalchemy_default_limits.conf'
|
||||
|
||||
@ -92,7 +90,7 @@ class TestDefaultLimits(base.TestBase):
|
||||
self.simulate_delete(path)
|
||||
|
||||
def _prepare_messages(self, count):
|
||||
doc = json.dumps([{'body': 239, 'ttl': 300}] * count)
|
||||
doc = jsonutils.dumps([{'body': 239, 'ttl': 300}] * count)
|
||||
self.simulate_post(self.messages_path, body=doc,
|
||||
headers={'Client-ID': str(uuid.uuid4())})
|
||||
|
@ -15,11 +15,14 @@
|
||||
import falcon
|
||||
import six.moves.urllib.parse as urlparse
|
||||
|
||||
from . import base # noqa
|
||||
|
||||
from marconi.openstack.common import jsonutils
|
||||
|
||||
|
||||
class TestHomeDocument(base.TestBase):
|
||||
from marconi.tests.queues.transport.wsgi import base
|
||||
|
||||
|
||||
class TestHomeDocument(base.V1Base):
|
||||
|
||||
config_file = 'wsgi_sqlalchemy.conf'
|
||||
|
@ -18,10 +18,11 @@ import uuid
|
||||
import falcon
|
||||
from falcon import testing
|
||||
|
||||
from . import base # noqa
|
||||
|
||||
from marconi.tests.queues.transport.wsgi import base
|
||||
|
||||
|
||||
class TestMediaType(base.TestBase):
|
||||
class TestMediaType(base.V1Base):
|
||||
|
||||
config_file = 'wsgi_sqlalchemy.conf'
|
||||
|
@ -14,7 +14,6 @@
|
||||
# limitations under the License.
|
||||
|
||||
import datetime
|
||||
import json
|
||||
import uuid
|
||||
|
||||
import ddt
|
||||
@ -23,15 +22,16 @@ import mock
|
||||
import six
|
||||
from testtools import matchers
|
||||
|
||||
from . import base # noqa
|
||||
|
||||
from marconi.openstack.common import jsonutils
|
||||
from marconi.openstack.common import timeutils
|
||||
from marconi.queues.transport import validation
|
||||
from marconi import tests as testing
|
||||
from marconi.tests.queues.transport.wsgi import base
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class MessagesBaseTest(base.TestBase):
|
||||
class MessagesBaseTest(base.V1Base):
|
||||
|
||||
def setUp(self):
|
||||
super(MessagesBaseTest, self).setUp()
|
||||
@ -41,7 +41,7 @@ class MessagesBaseTest(base.TestBase):
|
||||
uri = self.conf['drivers:storage:mongodb'].uri
|
||||
doc = {'weight': 100, 'uri': uri}
|
||||
self.simulate_put(self.url_prefix + '/shards/' + str(i),
|
||||
body=json.dumps(doc))
|
||||
body=jsonutils.dumps(doc))
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_201)
|
||||
|
||||
self.project_id = '7e55e1a7e'
|
||||
@ -68,7 +68,7 @@ class MessagesBaseTest(base.TestBase):
|
||||
super(MessagesBaseTest, self).tearDown()
|
||||
|
||||
def _test_post(self, sample_messages):
|
||||
sample_doc = json.dumps(sample_messages)
|
||||
sample_doc = jsonutils.dumps(sample_messages)
|
||||
|
||||
result = self.simulate_post(self.messages_path, self.project_id,
|
||||
body=sample_doc, headers=self.headers)
|
||||
@ -234,7 +234,7 @@ class MessagesBaseTest(base.TestBase):
|
||||
@ddt.data(-1, 59, 1209601)
|
||||
def test_unacceptable_ttl(self, ttl):
|
||||
self.simulate_post(self.queue_path + '/messages',
|
||||
body=json.dumps([{'ttl': ttl,
|
||||
body=jsonutils.dumps([{'ttl': ttl,
|
||||
'body': None}]),
|
||||
headers=self.headers)
|
||||
|
||||
@ -242,7 +242,8 @@ class MessagesBaseTest(base.TestBase):
|
||||
|
||||
def test_exceeded_message_posting(self):
|
||||
# Total (raw request) size
|
||||
doc = json.dumps([{'body': "some body", 'ttl': 100}] * 20, indent=4)
|
||||
doc = jsonutils.dumps([{'body': "some body", 'ttl': 100}] * 20,
|
||||
indent=4)
|
||||
|
||||
max_len = self.transport_cfg.max_message_size
|
||||
long_doc = doc + (' ' * (max_len - len(doc) + 1))
|
||||
@ -444,7 +445,7 @@ class MessagesBaseTest(base.TestBase):
|
||||
messages[0]['href'])
|
||||
|
||||
def _post_messages(self, target, repeat=1):
|
||||
doc = json.dumps([{'body': 239, 'ttl': 300}] * repeat)
|
||||
doc = jsonutils.dumps([{'body': 239, 'ttl': 300}] * repeat)
|
||||
return self.simulate_post(target, self.project_id, body=doc,
|
||||
headers=self.headers)
|
||||
|
||||
@ -489,7 +490,7 @@ class TestMessagesMongoDBSharded(MessagesBaseTest):
|
||||
self.skipTest("Need to implement sharded queue listing.")
|
||||
|
||||
|
||||
class TestMessagesFaultyDriver(base.TestBaseFaulty):
|
||||
class TestMessagesFaultyDriver(base.V1BaseFaulty):
|
||||
|
||||
config_file = 'wsgi_faulty.conf'
|
||||
|
@ -16,13 +16,13 @@ import ddt
|
||||
import falcon
|
||||
import six
|
||||
|
||||
from . import base # noqa
|
||||
from marconi.openstack.common import jsonutils
|
||||
from marconi import tests as testing
|
||||
from marconi.tests.queues.transport.wsgi import base
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class QueueLifecycleBaseTest(base.TestBase):
|
||||
class QueueLifecycleBaseTest(base.V1Base):
|
||||
|
||||
config_file = None
|
||||
|
||||
@ -361,7 +361,7 @@ class TestQueueLifecycleSqlalchemy(QueueLifecycleBaseTest):
|
||||
config_file = 'wsgi_sqlalchemy.conf'
|
||||
|
||||
|
||||
class TestQueueLifecycleFaultyDriver(base.TestBaseFaulty):
|
||||
class TestQueueLifecycleFaultyDriver(base.V1BaseFaulty):
|
||||
|
||||
config_file = 'wsgi_faulty.conf'
|
||||
|
@ -13,15 +13,15 @@
|
||||
# the License.
|
||||
|
||||
import contextlib
|
||||
import json
|
||||
import uuid
|
||||
|
||||
import ddt
|
||||
import falcon
|
||||
|
||||
from . import base # noqa
|
||||
|
||||
from marconi.openstack.common import jsonutils
|
||||
from marconi import tests as testing
|
||||
from marconi.tests.queues.transport.wsgi import base
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
@ -42,7 +42,7 @@ def shard(test, name, weight, uri, options={}):
|
||||
doc = {'weight': weight, 'uri': uri, 'options': options}
|
||||
path = test.url_prefix + '/shards/' + name
|
||||
|
||||
test.simulate_put(path, body=json.dumps(doc))
|
||||
test.simulate_put(path, body=jsonutils.dumps(doc))
|
||||
|
||||
try:
|
||||
yield name, weight, uri, options
|
||||
@ -69,7 +69,7 @@ def shards(test, count, uri):
|
||||
for i in range(count)]
|
||||
for path, weight, option in args:
|
||||
doc = {'weight': weight, 'uri': uri, 'options': option}
|
||||
test.simulate_put(path, body=json.dumps(doc))
|
||||
test.simulate_put(path, body=jsonutils.dumps(doc))
|
||||
|
||||
try:
|
||||
yield args
|
||||
@ -79,13 +79,13 @@ def shards(test, count, uri):
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class ShardsBaseTest(base.TestBase):
|
||||
class ShardsBaseTest(base.V1Base):
|
||||
|
||||
def setUp(self):
|
||||
super(ShardsBaseTest, self).setUp()
|
||||
self.doc = {'weight': 100, 'uri': 'sqlite://:memory:'}
|
||||
self.shard = self.url_prefix + '/shards/' + str(uuid.uuid1())
|
||||
self.simulate_put(self.shard, body=json.dumps(self.doc))
|
||||
self.simulate_put(self.shard, body=jsonutils.dumps(self.doc))
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_201)
|
||||
|
||||
def tearDown(self):
|
||||
@ -101,10 +101,12 @@ class ShardsBaseTest(base.TestBase):
|
||||
|
||||
def test_put_raises_if_missing_fields(self):
|
||||
path = self.url_prefix + '/shards/' + str(uuid.uuid1())
|
||||
self.simulate_put(path, body=json.dumps({'weight': 100}))
|
||||
self.simulate_put(path, body=jsonutils.dumps({'weight': 100}))
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
self.simulate_put(path, body=json.dumps({'uri': 'sqlite://:memory:'}))
|
||||
self.simulate_put(path,
|
||||
body=jsonutils.dumps(
|
||||
{'uri': 'sqlite://:memory:'}))
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
@ddt.data(-1, 2**32+1, 'big')
|
||||
@ -112,28 +114,28 @@ class ShardsBaseTest(base.TestBase):
|
||||
path = self.url_prefix + '/shards/' + str(uuid.uuid1())
|
||||
doc = {'weight': weight, 'uri': 'a'}
|
||||
self.simulate_put(path,
|
||||
body=json.dumps(doc))
|
||||
body=jsonutils.dumps(doc))
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
@ddt.data(-1, 2**32+1, [], 'localhost:27017')
|
||||
def test_put_raises_if_invalid_uri(self, uri):
|
||||
path = self.url_prefix + '/shards/' + str(uuid.uuid1())
|
||||
self.simulate_put(path,
|
||||
body=json.dumps({'weight': 1, 'uri': uri}))
|
||||
body=jsonutils.dumps({'weight': 1, 'uri': uri}))
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
@ddt.data(-1, 'wee', [])
|
||||
def test_put_raises_if_invalid_options(self, options):
|
||||
path = self.url_prefix + '/shards/' + str(uuid.uuid1())
|
||||
doc = {'weight': 1, 'uri': 'a', 'options': options}
|
||||
self.simulate_put(path, body=json.dumps(doc))
|
||||
self.simulate_put(path, body=jsonutils.dumps(doc))
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
def test_put_existing_overwrites(self):
|
||||
# NOTE(cabrera): setUp creates default shard
|
||||
expect = self.doc
|
||||
self.simulate_put(self.shard,
|
||||
body=json.dumps(expect))
|
||||
body=jsonutils.dumps(expect))
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_201)
|
||||
|
||||
result = self.simulate_get(self.shard)
|
||||
@ -180,12 +182,12 @@ class ShardsBaseTest(base.TestBase):
|
||||
|
||||
def test_patch_raises_if_missing_fields(self):
|
||||
self.simulate_patch(self.shard,
|
||||
body=json.dumps({'location': 1}))
|
||||
body=jsonutils.dumps({'location': 1}))
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
def _patch_test(self, doc):
|
||||
self.simulate_patch(self.shard,
|
||||
body=json.dumps(doc))
|
||||
body=jsonutils.dumps(doc))
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
|
||||
result = self.simulate_get(self.shard,
|
||||
@ -208,24 +210,24 @@ class ShardsBaseTest(base.TestBase):
|
||||
@ddt.data(-1, 2**32+1, 'big')
|
||||
def test_patch_raises_400_on_invalid_weight(self, weight):
|
||||
self.simulate_patch(self.shard,
|
||||
body=json.dumps({'weight': weight}))
|
||||
body=jsonutils.dumps({'weight': weight}))
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
@ddt.data(-1, 2**32+1, [], 'localhost:27017')
|
||||
def test_patch_raises_400_on_invalid_uri(self, uri):
|
||||
self.simulate_patch(self.shard,
|
||||
body=json.dumps({'uri': uri}))
|
||||
body=jsonutils.dumps({'uri': uri}))
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
@ddt.data(-1, 'wee', [])
|
||||
def test_patch_raises_400_on_invalid_options(self, options):
|
||||
self.simulate_patch(self.shard,
|
||||
body=json.dumps({'options': options}))
|
||||
body=jsonutils.dumps({'options': options}))
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
def test_patch_raises_404_if_shard_not_found(self):
|
||||
self.simulate_patch(self.url_prefix + '/shards/notexists',
|
||||
body=json.dumps({'weight': 1}))
|
||||
body=jsonutils.dumps({'weight': 1}))
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_404)
|
||||
|
||||
def test_empty_listing_returns_204(self):
|
39
marconi/tests/queues/transport/wsgi/v1_1/__init__.py
Normal file
39
marconi/tests/queues/transport/wsgi/v1_1/__init__.py
Normal file
@ -0,0 +1,39 @@
|
||||
# Copyright (c) 2014 Rackspace, Inc.
|
||||
#
|
||||
# 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.
|
||||
|
||||
from marconi.tests.queues.transport.wsgi.v1_1 import test_auth
|
||||
from marconi.tests.queues.transport.wsgi.v1_1 import test_claims
|
||||
from marconi.tests.queues.transport.wsgi.v1_1 import test_default_limits
|
||||
from marconi.tests.queues.transport.wsgi.v1_1 import test_home
|
||||
from marconi.tests.queues.transport.wsgi.v1_1 import test_media_type
|
||||
from marconi.tests.queues.transport.wsgi.v1_1 import test_messages
|
||||
from marconi.tests.queues.transport.wsgi.v1_1 import test_queue_lifecycle as lc
|
||||
from marconi.tests.queues.transport.wsgi.v1_1 import test_shards
|
||||
|
||||
TestAuth = test_auth.TestAuth
|
||||
TestClaimsFaultyDriver = test_claims.TestClaimsFaultyDriver
|
||||
TestClaimsMongoDB = test_claims.TestClaimsMongoDB
|
||||
TestClaimsSqlalchemy = test_claims.TestClaimsSqlalchemy
|
||||
TestDefaultLimits = test_default_limits.TestDefaultLimits
|
||||
TestHomeDocument = test_home.TestHomeDocument
|
||||
TestMediaType = test_media_type.TestMediaType
|
||||
TestMessagesFaultyDriver = test_messages.TestMessagesFaultyDriver
|
||||
TestMessagesMongoDB = test_messages.TestMessagesMongoDB
|
||||
TestMessagesMongoDBSharded = test_messages.TestMessagesMongoDBSharded
|
||||
TestMessagesSqlalchemy = test_messages.TestMessagesSqlalchemy
|
||||
TestQueueFaultyDriver = lc.TestQueueLifecycleFaultyDriver
|
||||
TestQueueLifecycleMongoDB = lc.TestQueueLifecycleMongoDB
|
||||
TestQueueLifecycleSqlalchemy = lc.TestQueueLifecycleSqlalchemy
|
||||
TestShardsMongoDB = test_shards.TestShardsMongoDB
|
||||
TestShardsSqlalchemy = test_shards.TestShardsSqlalchemy
|
43
marconi/tests/queues/transport/wsgi/v1_1/test_auth.py
Normal file
43
marconi/tests/queues/transport/wsgi/v1_1/test_auth.py
Normal file
@ -0,0 +1,43 @@
|
||||
# Copyright (c) 2013 Red Hat, Inc.
|
||||
#
|
||||
# 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.
|
||||
"""Test Auth."""
|
||||
|
||||
import uuid
|
||||
|
||||
import falcon
|
||||
from falcon import testing
|
||||
from keystoneclient.middleware import auth_token
|
||||
|
||||
from marconi.tests.queues.transport.wsgi import base
|
||||
|
||||
|
||||
class TestAuth(base.V1_1Base):
|
||||
|
||||
config_file = 'keystone_auth.conf'
|
||||
|
||||
def setUp(self):
|
||||
super(TestAuth, self).setUp()
|
||||
self.headers = {'Client-ID': str(uuid.uuid4())}
|
||||
|
||||
def test_auth_install(self):
|
||||
self.assertIsInstance(self.app, auth_token.AuthProtocol)
|
||||
|
||||
def test_non_authenticated(self):
|
||||
env = testing.create_environ(self.url_prefix + '/480924/queues/',
|
||||
method='GET',
|
||||
headers=self.headers)
|
||||
|
||||
self.app(env, self.srmock)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_401)
|
316
marconi/tests/queues/transport/wsgi/v1_1/test_claims.py
Normal file
316
marconi/tests/queues/transport/wsgi/v1_1/test_claims.py
Normal file
@ -0,0 +1,316 @@
|
||||
# Copyright (c) 2013 Rackspace, Inc.
|
||||
#
|
||||
# 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 datetime
|
||||
import json
|
||||
import uuid
|
||||
|
||||
import ddt
|
||||
import falcon
|
||||
from marconi.tests.queues.transport.wsgi import base
|
||||
import mock
|
||||
from testtools import matchers
|
||||
|
||||
|
||||
from marconi.openstack.common import timeutils
|
||||
from marconi import tests as testing
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class ClaimsBaseTest(base.V1_1Base):
|
||||
|
||||
def setUp(self):
|
||||
super(ClaimsBaseTest, self).setUp()
|
||||
|
||||
self.project_id = '737_abc8332832'
|
||||
|
||||
self.headers = {
|
||||
'Client-ID': str(uuid.uuid4()),
|
||||
'X-Project-ID': self.project_id
|
||||
}
|
||||
self.queue_path = self.url_prefix + '/queues/fizbit'
|
||||
self.claims_path = self.queue_path + '/claims'
|
||||
self.messages_path = self.queue_path + '/messages'
|
||||
|
||||
doc = json.dumps({"_ttl": 60})
|
||||
|
||||
self.simulate_put(self.queue_path, body=doc, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_201)
|
||||
|
||||
doc = json.dumps([{'body': 239, 'ttl': 300}] * 10)
|
||||
self.simulate_post(self.queue_path + '/messages',
|
||||
body=doc, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_201)
|
||||
|
||||
def tearDown(self):
|
||||
self.simulate_delete(self.queue_path, headers=self.headers)
|
||||
|
||||
super(ClaimsBaseTest, self).tearDown()
|
||||
|
||||
@ddt.data(None, '[', '[]', '{}', '.', '"fail"')
|
||||
def test_bad_claim(self, doc):
|
||||
self.simulate_post(self.claims_path, body=doc, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
href = self._get_a_claim()
|
||||
|
||||
self.simulate_patch(href, body=doc, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
def test_exceeded_claim(self):
|
||||
self.simulate_post(self.claims_path,
|
||||
body='{"ttl": 100, "grace": 60}',
|
||||
query_string='limit=21', headers=self.headers)
|
||||
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
@ddt.data((-1, -1), (59, 60), (60, 59), (60, 43201), (43201, 60))
|
||||
def test_unacceptable_ttl_or_grace(self, ttl_grace):
|
||||
ttl, grace = ttl_grace
|
||||
self.simulate_post(self.claims_path,
|
||||
body=json.dumps({'ttl': ttl, 'grace': grace}),
|
||||
headers=self.headers)
|
||||
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
@ddt.data(-1, 59, 43201)
|
||||
def test_unacceptable_new_ttl(self, ttl):
|
||||
href = self._get_a_claim()
|
||||
|
||||
self.simulate_patch(href,
|
||||
body=json.dumps({'ttl': ttl}),
|
||||
headers=self.headers)
|
||||
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
def _get_a_claim(self):
|
||||
doc = '{"ttl": 100, "grace": 60}'
|
||||
self.simulate_post(self.claims_path, body=doc, headers=self.headers)
|
||||
return self.srmock.headers_dict['Location']
|
||||
|
||||
def test_lifecycle(self):
|
||||
doc = '{"ttl": 100, "grace": 60}'
|
||||
|
||||
# First, claim some messages
|
||||
body = self.simulate_post(self.claims_path, body=doc,
|
||||
headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_201)
|
||||
|
||||
claimed = json.loads(body[0])
|
||||
claim_href = self.srmock.headers_dict['Location']
|
||||
message_href, params = claimed[0]['href'].split('?')
|
||||
|
||||
# No more messages to claim
|
||||
self.simulate_post(self.claims_path, body=doc,
|
||||
query_string='limit=3', headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
# Listing messages, by default, won't include claimed, will echo
|
||||
body = self.simulate_get(self.messages_path,
|
||||
headers=self.headers,
|
||||
query_string="echo=true")
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
# Listing messages, by default, won't include claimed, won't echo
|
||||
body = self.simulate_get(self.messages_path,
|
||||
headers=self.headers,
|
||||
query_string="echo=false")
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
# List messages, include_claimed, but don't echo
|
||||
body = self.simulate_get(self.messages_path,
|
||||
query_string='include_claimed=true'
|
||||
'&echo=false',
|
||||
headers=self.headers)
|
||||
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
# List messages with a different client-id and echo=false.
|
||||
# Should return some messages
|
||||
headers = self.headers.copy()
|
||||
headers["Client-ID"] = str(uuid.uuid4())
|
||||
body = self.simulate_get(self.messages_path,
|
||||
query_string='include_claimed=true'
|
||||
'&echo=false',
|
||||
headers=headers)
|
||||
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
|
||||
# Include claimed messages this time, and echo
|
||||
body = self.simulate_get(self.messages_path,
|
||||
query_string='include_claimed=true'
|
||||
'&echo=true',
|
||||
headers=self.headers)
|
||||
listed = json.loads(body[0])
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
self.assertEqual(len(listed['messages']), len(claimed))
|
||||
|
||||
now = timeutils.utcnow() + datetime.timedelta(seconds=10)
|
||||
timeutils_utcnow = 'marconi.openstack.common.timeutils.utcnow'
|
||||
with mock.patch(timeutils_utcnow) as mock_utcnow:
|
||||
mock_utcnow.return_value = now
|
||||
body = self.simulate_get(claim_href, headers=self.headers)
|
||||
|
||||
claim = json.loads(body[0])
|
||||
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
self.assertEqual(self.srmock.headers_dict['Content-Location'],
|
||||
claim_href)
|
||||
self.assertEqual(claim['ttl'], 100)
|
||||
## NOTE(cpp-cabrera): verify that claim age is non-negative
|
||||
self.assertThat(claim['age'], matchers.GreaterThan(-1))
|
||||
|
||||
# Try to delete the message without submitting a claim_id
|
||||
self.simulate_delete(message_href, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_403)
|
||||
|
||||
# Delete the message and its associated claim
|
||||
self.simulate_delete(message_href,
|
||||
query_string=params, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
# Try to get it from the wrong project
|
||||
headers = {
|
||||
'Client-ID': str(uuid.uuid4()),
|
||||
'X-Project-ID': 'bogusproject'
|
||||
}
|
||||
self.simulate_get(message_href, query_string=params, headers=headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_404)
|
||||
|
||||
# Get the message
|
||||
self.simulate_get(message_href, query_string=params,
|
||||
headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_404)
|
||||
|
||||
# Update the claim
|
||||
new_claim_ttl = '{"ttl": 60}'
|
||||
creation = timeutils.utcnow()
|
||||
self.simulate_patch(claim_href, body=new_claim_ttl,
|
||||
headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
# Get the claimed messages (again)
|
||||
body = self.simulate_get(claim_href, headers=self.headers)
|
||||
query = timeutils.utcnow()
|
||||
claim = json.loads(body[0])
|
||||
message_href, params = claim['messages'][0]['href'].split('?')
|
||||
|
||||
self.assertEqual(claim['ttl'], 60)
|
||||
estimated_age = timeutils.delta_seconds(creation, query)
|
||||
self.assertTrue(estimated_age > claim['age'])
|
||||
|
||||
# Delete the claim
|
||||
self.simulate_delete(claim['href'], headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
# Try to delete a message with an invalid claim ID
|
||||
self.simulate_delete(message_href,
|
||||
query_string=params, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_403)
|
||||
|
||||
# Make sure it wasn't deleted!
|
||||
self.simulate_get(message_href, query_string=params,
|
||||
headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
|
||||
# Try to get a claim that doesn't exist
|
||||
self.simulate_get(claim['href'], headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_404)
|
||||
|
||||
# Try to update a claim that doesn't exist
|
||||
self.simulate_patch(claim['href'], body=doc,
|
||||
headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_404)
|
||||
|
||||
def test_post_claim_nonexistent_queue(self):
|
||||
path = self.url_prefix + '/queues/nonexistent/claims'
|
||||
self.simulate_post(path,
|
||||
body='{"ttl": 100, "grace": 60}',
|
||||
headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
def test_get_claim_nonexistent_queue(self):
|
||||
path = self.url_prefix + '/queues/nonexistent/claims/aaabbbba'
|
||||
self.simulate_get(path, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_404)
|
||||
|
||||
# NOTE(cpp-cabrera): regression test against bug #1203842
|
||||
def test_get_nonexistent_claim_404s(self):
|
||||
self.simulate_get(self.claims_path + '/a', headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_404)
|
||||
|
||||
def test_delete_nonexistent_claim_204s(self):
|
||||
self.simulate_delete(self.claims_path + '/a',
|
||||
headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
def test_patch_nonexistent_claim_404s(self):
|
||||
patch_data = json.dumps({'ttl': 100})
|
||||
self.simulate_patch(self.claims_path + '/a', body=patch_data,
|
||||
headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_404)
|
||||
|
||||
|
||||
class TestClaimsMongoDB(ClaimsBaseTest):
|
||||
|
||||
config_file = 'wsgi_mongodb.conf'
|
||||
|
||||
@testing.requires_mongodb
|
||||
def setUp(self):
|
||||
super(TestClaimsMongoDB, self).setUp()
|
||||
|
||||
def tearDown(self):
|
||||
storage = self.boot.storage._storage
|
||||
connection = storage.connection
|
||||
|
||||
connection.drop_database(storage.queues_database)
|
||||
|
||||
for db in storage.message_databases:
|
||||
connection.drop_database(db)
|
||||
|
||||
super(TestClaimsMongoDB, self).tearDown()
|
||||
|
||||
|
||||
class TestClaimsSqlalchemy(ClaimsBaseTest):
|
||||
|
||||
config_file = 'wsgi_sqlalchemy.conf'
|
||||
|
||||
|
||||
class TestClaimsFaultyDriver(base.V1_1BaseFaulty):
|
||||
|
||||
config_file = 'wsgi_faulty.conf'
|
||||
|
||||
def test_simple(self):
|
||||
self.project_id = '480924abc_'
|
||||
self.headers = {
|
||||
'Client-ID': str(uuid.uuid4()),
|
||||
'X-Project-ID': self.project_id
|
||||
}
|
||||
|
||||
claims_path = self.url_prefix + '/queues/fizbit/claims'
|
||||
doc = '{"ttl": 100, "grace": 60}'
|
||||
|
||||
self.simulate_post(claims_path, body=doc, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_503)
|
||||
|
||||
self.simulate_get(claims_path + '/nichts', headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_503)
|
||||
|
||||
self.simulate_patch(claims_path + '/nichts', body=doc,
|
||||
headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_503)
|
||||
|
||||
self.simulate_delete(claims_path + '/foo', headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_503)
|
122
marconi/tests/queues/transport/wsgi/v1_1/test_default_limits.py
Normal file
122
marconi/tests/queues/transport/wsgi/v1_1/test_default_limits.py
Normal file
@ -0,0 +1,122 @@
|
||||
# Copyright (c) 2013 Rackspace, Inc.
|
||||
#
|
||||
# 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 contextlib
|
||||
import uuid
|
||||
|
||||
import falcon
|
||||
|
||||
from marconi.openstack.common import jsonutils
|
||||
from marconi.queues import storage
|
||||
from marconi.tests.queues.transport.wsgi import base
|
||||
|
||||
|
||||
class TestDefaultLimits(base.V1_1Base):
|
||||
|
||||
config_file = 'wsgi_sqlalchemy_default_limits.conf'
|
||||
|
||||
def setUp(self):
|
||||
super(TestDefaultLimits, self).setUp()
|
||||
|
||||
self.headers = {
|
||||
'Client-ID': str(uuid.uuid4()),
|
||||
'X-Project-ID': '838383abc_'
|
||||
}
|
||||
self.queue_path = self.url_prefix + '/queues'
|
||||
self.q1_queue_path = self.queue_path + '/q1'
|
||||
self.messages_path = self.q1_queue_path + '/messages'
|
||||
self.claims_path = self.q1_queue_path + '/claims'
|
||||
|
||||
self.simulate_put(self.q1_queue_path, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_201)
|
||||
|
||||
def tearDown(self):
|
||||
self.simulate_delete(self.queue_path, headers=self.headers)
|
||||
super(TestDefaultLimits, self).tearDown()
|
||||
|
||||
def test_queue_listing(self):
|
||||
# 2 queues to list
|
||||
self.simulate_put(self.queue_path + '/q2', headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_201)
|
||||
|
||||
with self._prepare_queues(storage.DEFAULT_QUEUES_PER_PAGE + 1):
|
||||
result = self.simulate_get(self.queue_path, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
|
||||
queues = jsonutils.loads(result[0])['queues']
|
||||
self.assertEqual(len(queues), storage.DEFAULT_QUEUES_PER_PAGE)
|
||||
|
||||
def test_message_listing_different_id(self):
|
||||
self._prepare_messages(storage.DEFAULT_MESSAGES_PER_PAGE + 1)
|
||||
|
||||
headers = self.headers.copy()
|
||||
headers['Client-ID'] = str(uuid.uuid4())
|
||||
result = self.simulate_get(self.messages_path,
|
||||
headers=headers,
|
||||
query_string='echo=false')
|
||||
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
|
||||
messages = jsonutils.loads(result[0])['messages']
|
||||
self.assertEqual(len(messages), storage.DEFAULT_MESSAGES_PER_PAGE)
|
||||
|
||||
def test_message_listing_same_id(self):
|
||||
self._prepare_messages(storage.DEFAULT_MESSAGES_PER_PAGE + 1)
|
||||
result = self.simulate_get(self.messages_path,
|
||||
headers=self.headers,
|
||||
query_string='echo=false')
|
||||
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
self._prepare_messages(storage.DEFAULT_MESSAGES_PER_PAGE + 1)
|
||||
result = self.simulate_get(self.messages_path,
|
||||
headers=self.headers,
|
||||
query_string='echo=true')
|
||||
|
||||
messages = jsonutils.loads(result[0])['messages']
|
||||
self.assertEqual(len(messages), storage.DEFAULT_MESSAGES_PER_PAGE)
|
||||
|
||||
def test_claim_creation(self):
|
||||
self._prepare_messages(storage.DEFAULT_MESSAGES_PER_CLAIM + 1)
|
||||
|
||||
result = self.simulate_post(self.claims_path,
|
||||
body='{"ttl": 60, "grace": 60}',
|
||||
headers=self.headers)
|
||||
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_201)
|
||||
|
||||
messages = jsonutils.loads(result[0])
|
||||
self.assertEqual(len(messages), storage.DEFAULT_MESSAGES_PER_CLAIM)
|
||||
|
||||
@contextlib.contextmanager
|
||||
def _prepare_queues(self, count):
|
||||
queue_paths = [self.queue_path + '/multi-{0}'.format(i)
|
||||
for i in range(count)]
|
||||
|
||||
for path in queue_paths:
|
||||
self.simulate_put(path, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_201)
|
||||
|
||||
yield
|
||||
|
||||
for path in queue_paths:
|
||||
self.simulate_delete(path, headers=self.headers)
|
||||
|
||||
def _prepare_messages(self, count):
|
||||
doc = jsonutils.dumps([{'body': 239, 'ttl': 300}] * count)
|
||||
self.simulate_post(self.messages_path, body=doc,
|
||||
headers=self.headers)
|
||||
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_201)
|
67
marconi/tests/queues/transport/wsgi/v1_1/test_home.py
Normal file
67
marconi/tests/queues/transport/wsgi/v1_1/test_home.py
Normal file
@ -0,0 +1,67 @@
|
||||
# Copyright (c) 2013 Rackspace, Inc.
|
||||
#
|
||||
# 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 uuid
|
||||
|
||||
import falcon
|
||||
import six.moves.urllib.parse as urlparse
|
||||
|
||||
from marconi.openstack.common import jsonutils
|
||||
from marconi.tests.queues.transport.wsgi import base
|
||||
|
||||
|
||||
class TestHomeDocument(base.V1_1Base):
|
||||
|
||||
config_file = 'wsgi_sqlalchemy.conf'
|
||||
|
||||
def test_json_response(self):
|
||||
self.headers = {
|
||||
'Client-ID': str(uuid.uuid4()),
|
||||
'X-Project-ID': '8383830383abc_'
|
||||
}
|
||||
body = self.simulate_get(self.url_prefix, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
|
||||
content_type = self.srmock.headers_dict['Content-Type']
|
||||
self.assertEqual(content_type, 'application/json-home')
|
||||
|
||||
try:
|
||||
jsonutils.loads(body[0])
|
||||
except ValueError:
|
||||
self.fail('Home document is not valid JSON')
|
||||
|
||||
def test_href_template(self):
|
||||
self.headers = {
|
||||
'Client-ID': str(uuid.uuid4()),
|
||||
'X-Project-ID': '8383830383'
|
||||
}
|
||||
body = self.simulate_get(self.url_prefix, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
resp = jsonutils.loads(body[0])
|
||||
queue_href_template = resp['resources']['rel/queue']['href-template']
|
||||
path_1 = 'https://marconi.example.com' + self.url_prefix
|
||||
path_2 = 'https://marconi.example.com' + self.url_prefix + '/'
|
||||
|
||||
# Verify all the href template start with the correct version prefix
|
||||
for resource in list(resp['resources']):
|
||||
self.assertTrue(resp['resources'][resource]['href-template'].
|
||||
startswith(self.url_prefix))
|
||||
|
||||
url = urlparse.urljoin(path_1, queue_href_template)
|
||||
expected = ('https://marconi.example.com' + self.url_prefix +
|
||||
'/queues/foo')
|
||||
self.assertEqual(url.format(queue_name='foo'), expected)
|
||||
|
||||
url = urlparse.urljoin(path_2, queue_href_template)
|
||||
self.assertEqual(url.format(queue_name='foo'), expected)
|
51
marconi/tests/queues/transport/wsgi/v1_1/test_media_type.py
Normal file
51
marconi/tests/queues/transport/wsgi/v1_1/test_media_type.py
Normal file
@ -0,0 +1,51 @@
|
||||
# Copyright (c) 2013 Rackspace, Inc.
|
||||
#
|
||||
# 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 uuid
|
||||
|
||||
import falcon
|
||||
from falcon import testing
|
||||
|
||||
from marconi.tests.queues.transport.wsgi import base
|
||||
|
||||
|
||||
class TestMediaType(base.V1_1Base):
|
||||
|
||||
config_file = 'wsgi_sqlalchemy.conf'
|
||||
|
||||
def test_json_only_endpoints(self):
|
||||
endpoints = (
|
||||
('GET', self.url_prefix + '/queues'),
|
||||
('GET', self.url_prefix + '/queues/nonexistent/metadata'),
|
||||
('GET', self.url_prefix + '/queues/nonexistent/stats'),
|
||||
('POST', self.url_prefix + '/queues/nonexistent/messages'),
|
||||
('GET', self.url_prefix + '/queues/nonexistent/messages/deadbeaf'),
|
||||
('POST', self.url_prefix + '/queues/nonexistent/claims'),
|
||||
('GET', self.url_prefix + '/queues/nonexistent/claims/0ad'),
|
||||
('GET', self.url_prefix + '/health'),
|
||||
)
|
||||
|
||||
for method, endpoint in endpoints:
|
||||
headers = {
|
||||
'Client-ID': str(uuid.uuid4()),
|
||||
'Accept': 'application/xml',
|
||||
}
|
||||
|
||||
env = testing.create_environ(endpoint,
|
||||
method=method,
|
||||
headers=headers)
|
||||
|
||||
self.app(env, self.srmock)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_406)
|
524
marconi/tests/queues/transport/wsgi/v1_1/test_messages.py
Normal file
524
marconi/tests/queues/transport/wsgi/v1_1/test_messages.py
Normal file
@ -0,0 +1,524 @@
|
||||
# Copyright (c) 2013 Rackspace, Inc.
|
||||
#
|
||||
# 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 datetime
|
||||
import uuid
|
||||
|
||||
import ddt
|
||||
import falcon
|
||||
import mock
|
||||
import six
|
||||
from testtools import matchers
|
||||
|
||||
from marconi.openstack.common import jsonutils
|
||||
from marconi.openstack.common import timeutils
|
||||
from marconi.queues.transport import validation
|
||||
from marconi import tests as testing
|
||||
from marconi.tests.queues.transport.wsgi import base
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class MessagesBaseTest(base.V1_1Base):
|
||||
def setUp(self):
|
||||
super(MessagesBaseTest, self).setUp()
|
||||
|
||||
if self.conf.sharding:
|
||||
for i in range(4):
|
||||
uri = self.conf['drivers:storage:mongodb'].uri
|
||||
doc = {'weight': 100, 'uri': uri}
|
||||
self.simulate_put(self.url_prefix + '/shards/' + str(i),
|
||||
body=jsonutils.dumps(doc))
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_201)
|
||||
|
||||
self.project_id = '7e55e1a7e'
|
||||
self.headers = {
|
||||
'Client-ID': str(uuid.uuid4()),
|
||||
'X-Project-ID': self.project_id
|
||||
}
|
||||
|
||||
# TODO(kgriffs): Add support in self.simulate_* for a "base path"
|
||||
# so that we don't have to concatenate against self.url_prefix
|
||||
# all over the place.
|
||||
self.queue_path = self.url_prefix + '/queues/fizbit'
|
||||
self.messages_path = self.queue_path + '/messages'
|
||||
|
||||
doc = '{"_ttl": 60}'
|
||||
self.simulate_put(self.queue_path, body=doc, headers=self.headers)
|
||||
|
||||
def tearDown(self):
|
||||
self.simulate_delete(self.queue_path, headers=self.headers)
|
||||
if self.conf.sharding:
|
||||
for i in range(4):
|
||||
self.simulate_delete(self.url_prefix + '/shards/' + str(i),
|
||||
headers=self.headers)
|
||||
|
||||
super(MessagesBaseTest, self).tearDown()
|
||||
|
||||
def _test_post(self, sample_messages):
|
||||
sample_doc = jsonutils.dumps(sample_messages)
|
||||
|
||||
result = self.simulate_post(self.messages_path,
|
||||
body=sample_doc, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_201)
|
||||
|
||||
result_doc = jsonutils.loads(result[0])
|
||||
|
||||
msg_ids = self._get_msg_ids(self.srmock.headers_dict)
|
||||
self.assertEqual(len(msg_ids), len(sample_messages))
|
||||
|
||||
expected_resources = [six.text_type(self.messages_path + '/' + id)
|
||||
for id in msg_ids]
|
||||
self.assertEqual(expected_resources, result_doc['resources'])
|
||||
self.assertFalse(result_doc['partial'])
|
||||
|
||||
self.assertEqual(len(msg_ids), len(sample_messages))
|
||||
|
||||
lookup = dict([(m['ttl'], m['body']) for m in sample_messages])
|
||||
|
||||
# Test GET on the message resource directly
|
||||
# NOTE(cpp-cabrera): force the passing of time to age a message
|
||||
timeutils_utcnow = 'marconi.openstack.common.timeutils.utcnow'
|
||||
now = timeutils.utcnow() + datetime.timedelta(seconds=10)
|
||||
with mock.patch(timeutils_utcnow) as mock_utcnow:
|
||||
mock_utcnow.return_value = now
|
||||
for msg_id in msg_ids:
|
||||
message_uri = self.messages_path + '/' + msg_id
|
||||
|
||||
headers = self.headers.copy()
|
||||
headers['X-Project-ID'] = '777777'
|
||||
# Wrong project ID
|
||||
self.simulate_get(message_uri, headers=headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_404)
|
||||
|
||||
# Correct project ID
|
||||
result = self.simulate_get(message_uri, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
self.assertEqual(self.srmock.headers_dict['Content-Location'],
|
||||
message_uri)
|
||||
|
||||
# Check message properties
|
||||
message = jsonutils.loads(result[0])
|
||||
self.assertEqual(message['href'], message_uri)
|
||||
self.assertEqual(message['body'], lookup[message['ttl']])
|
||||
|
||||
# no negative age
|
||||
# NOTE(cpp-cabrera): testtools lacks GreaterThanEqual on py26
|
||||
self.assertThat(message['age'],
|
||||
matchers.GreaterThan(-1))
|
||||
|
||||
# Test bulk GET
|
||||
query_string = 'ids=' + ','.join(msg_ids)
|
||||
result = self.simulate_get(self.messages_path,
|
||||
query_string=query_string,
|
||||
headers=self.headers)
|
||||
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
result_doc = jsonutils.loads(result[0])
|
||||
expected_ttls = set(m['ttl'] for m in sample_messages)
|
||||
actual_ttls = set(m['ttl'] for m in result_doc)
|
||||
self.assertFalse(expected_ttls - actual_ttls)
|
||||
|
||||
def test_exceeded_payloads(self):
|
||||
# Get a valid message id
|
||||
self._post_messages(self.messages_path)
|
||||
msg_id = self._get_msg_id(self.srmock.headers_dict)
|
||||
|
||||
# Bulk GET restriction
|
||||
query_string = 'ids=' + ','.join([msg_id] * 21)
|
||||
self.simulate_get(self.messages_path,
|
||||
query_string=query_string, headers=self.headers)
|
||||
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
# Listing restriction
|
||||
self.simulate_get(self.messages_path,
|
||||
query_string='limit=21',
|
||||
headers=self.headers)
|
||||
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
# Bulk deletion restriction
|
||||
query_string = 'ids=' + ','.join([msg_id] * 22)
|
||||
self.simulate_delete(self.messages_path,
|
||||
query_string=query_string, headers=self.headers)
|
||||
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
def test_post_single(self):
|
||||
sample_messages = [
|
||||
{'body': {'key': 'value'}, 'ttl': 200},
|
||||
]
|
||||
|
||||
self._test_post(sample_messages)
|
||||
|
||||
def test_post_multiple(self):
|
||||
sample_messages = [
|
||||
{'body': 239, 'ttl': 100},
|
||||
{'body': {'key': 'value'}, 'ttl': 200},
|
||||
{'body': [1, 3], 'ttl': 300},
|
||||
]
|
||||
|
||||
self._test_post(sample_messages)
|
||||
|
||||
def test_post_to_non_ascii_queue(self):
|
||||
# NOTE(kgriffs): This test verifies that routes with
|
||||
# embedded queue name params go through the validation
|
||||
# hook, regardless of the target resource.
|
||||
|
||||
path = self.url_prefix + u'/queues/non-ascii-n\u0153me/messages'
|
||||
|
||||
if six.PY2:
|
||||
path = path.encode('utf-8')
|
||||
|
||||
self._post_messages(path)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
def test_post_with_long_queue_name(self):
|
||||
# NOTE(kgriffs): This test verifies that routes with
|
||||
# embedded queue name params go through the validation
|
||||
# hook, regardless of the target resource.
|
||||
|
||||
queues_path = self.url_prefix + '/queues/'
|
||||
|
||||
game_title = 'v' * validation.QUEUE_NAME_MAX_LEN
|
||||
self._post_messages(queues_path + game_title + '/messages')
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_404)
|
||||
|
||||
game_title += 'v'
|
||||
self._post_messages(queues_path + game_title + '/messages')
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
def test_post_to_missing_queue(self):
|
||||
self._post_messages(self.url_prefix + '/queues/nonexistent/messages')
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_404)
|
||||
|
||||
def test_get_from_missing_queue(self):
|
||||
self.simulate_get(self.url_prefix + '/queues/nonexistent/messages',
|
||||
headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
@ddt.data('', '0xdeadbeef', '550893e0-2b6e-11e3-835a-5cf9dd72369')
|
||||
def test_bad_client_id(self, text_id):
|
||||
self.simulate_post(self.queue_path + '/messages',
|
||||
body='{"ttl": 60, "body": ""}',
|
||||
headers={'Client-ID': text_id})
|
||||
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
self.simulate_get(self.queue_path + '/messages',
|
||||
query_string='limit=3&echo=true',
|
||||
headers={'Client-ID': text_id})
|
||||
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
@ddt.data(None, '[', '[]', '{}', '.')
|
||||
def test_post_bad_message(self, document):
|
||||
self.simulate_post(self.queue_path + '/messages',
|
||||
body=document,
|
||||
headers=self.headers)
|
||||
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
@ddt.data(-1, 59, 1209601)
|
||||
def test_unacceptable_ttl(self, ttl):
|
||||
self.simulate_post(self.queue_path + '/messages',
|
||||
body=jsonutils.dumps([{'ttl': ttl,
|
||||
'body': None}]),
|
||||
headers=self.headers)
|
||||
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
def test_exceeded_message_posting(self):
|
||||
# Total (raw request) size
|
||||
doc = jsonutils.dumps([{'body': "some body", 'ttl': 100}] * 20,
|
||||
indent=4)
|
||||
|
||||
max_len = self.transport_cfg.max_message_size
|
||||
long_doc = doc + (' ' * (max_len - len(doc) + 1))
|
||||
|
||||
self.simulate_post(self.queue_path + '/messages',
|
||||
body=long_doc,
|
||||
headers=self.headers)
|
||||
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
@ddt.data('{"overflow": 9223372036854775808}',
|
||||
'{"underflow": -9223372036854775809}')
|
||||
def test_unsupported_json(self, document):
|
||||
self.simulate_post(self.queue_path + '/messages',
|
||||
body=document,
|
||||
headers=self.headers)
|
||||
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
def test_delete(self):
|
||||
self._post_messages(self.messages_path)
|
||||
msg_id = self._get_msg_id(self.srmock.headers_dict)
|
||||
target = self.messages_path + '/' + msg_id
|
||||
|
||||
self.simulate_get(target, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
|
||||
self.simulate_delete(target, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
self.simulate_get(target, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_404)
|
||||
|
||||
# Safe to delete non-existing ones
|
||||
self.simulate_delete(target, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
def test_bulk_delete(self):
|
||||
path = self.queue_path + '/messages'
|
||||
self._post_messages(path, repeat=5)
|
||||
[target, params] = self.srmock.headers_dict['location'].split('?')
|
||||
|
||||
# Deleting the whole collection is denied
|
||||
self.simulate_delete(path, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
self.simulate_delete(target, query_string=params, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
self.simulate_get(target, query_string=params, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
# Safe to delete non-existing ones
|
||||
self.simulate_delete(target, query_string=params, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
# Even after the queue is gone
|
||||
self.simulate_delete(self.queue_path, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
self.simulate_delete(target, query_string=params, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
def test_list(self):
|
||||
path = self.queue_path + '/messages'
|
||||
self._post_messages(path, repeat=10)
|
||||
|
||||
query_string = 'limit=3&echo=true'
|
||||
body = self.simulate_get(path,
|
||||
query_string=query_string,
|
||||
headers=self.headers)
|
||||
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
self.assertEqual(self.srmock.headers_dict['Content-Location'],
|
||||
path + '?' + query_string)
|
||||
|
||||
cnt = 0
|
||||
while self.srmock.status == falcon.HTTP_200:
|
||||
contents = jsonutils.loads(body[0])
|
||||
[target, params] = contents['links'][0]['href'].split('?')
|
||||
|
||||
for msg in contents['messages']:
|
||||
self.simulate_get(msg['href'], headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
|
||||
body = self.simulate_get(target,
|
||||
query_string=params,
|
||||
headers=self.headers)
|
||||
cnt += 1
|
||||
|
||||
self.assertEqual(cnt, 4)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
# Stats
|
||||
body = self.simulate_get(self.queue_path + '/stats',
|
||||
headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
|
||||
message_stats = jsonutils.loads(body[0])['messages']
|
||||
self.assertEqual(self.srmock.headers_dict['Content-Location'],
|
||||
self.queue_path + '/stats')
|
||||
|
||||
# NOTE(kgriffs): The other parts of the stats are tested
|
||||
# in tests.storage.base and so are not repeated here.
|
||||
expected_pattern = self.queue_path + '/messages/[^/]+$'
|
||||
for message_stat_name in ('oldest', 'newest'):
|
||||
self.assertThat(message_stats[message_stat_name]['href'],
|
||||
matchers.MatchesRegex(expected_pattern))
|
||||
|
||||
# NOTE(kgriffs): Try to get messages for a missing queue
|
||||
self.simulate_get(self.url_prefix + '/queues/nonexistent/messages',
|
||||
headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
def test_list_with_bad_marker(self):
|
||||
path = self.queue_path + '/messages'
|
||||
self._post_messages(path, repeat=5)
|
||||
|
||||
query_string = 'limit=3&echo=true&marker=sfhlsfdjh2048'
|
||||
self.simulate_get(path,
|
||||
query_string=query_string,
|
||||
headers=self.headers)
|
||||
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
def test_no_uuid(self):
|
||||
headers = {
|
||||
'Client-ID': "textid",
|
||||
'X-Project-ID': '7e7e7e'
|
||||
}
|
||||
path = self.queue_path + '/messages'
|
||||
|
||||
self.simulate_post(path, body='[{"body": 0, "ttl": 100}]',
|
||||
headers=headers)
|
||||
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
self.simulate_get(path, headers=headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
# NOTE(cpp-cabrera): regression test against bug #1210633
|
||||
def test_when_claim_deleted_then_messages_unclaimed(self):
|
||||
path = self.queue_path
|
||||
self._post_messages(path + '/messages', repeat=5)
|
||||
|
||||
# post claim
|
||||
self.simulate_post(path + '/claims',
|
||||
body='{"ttl": 100, "grace": 100}',
|
||||
headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_201)
|
||||
location = self.srmock.headers_dict['location']
|
||||
|
||||
# release claim
|
||||
self.simulate_delete(location, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
# get unclaimed messages
|
||||
self.simulate_get(path + '/messages',
|
||||
query_string='echo=true',
|
||||
headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
|
||||
# NOTE(cpp-cabrera): regression test against bug #1203842
|
||||
def test_get_nonexistent_message_404s(self):
|
||||
path = self.url_prefix + '/queues/notthere/messages/a'
|
||||
self.simulate_get(path, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_404)
|
||||
|
||||
def test_get_multiple_invalid_messages_204s(self):
|
||||
path = self.url_prefix + '/queues/notthere/messages'
|
||||
self.simulate_get(path, query_string='ids=a,b,c',
|
||||
headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
def test_delete_multiple_invalid_messages_204s(self):
|
||||
path = self.url_prefix + '/queues/notthere/messages'
|
||||
self.simulate_delete(path, query_string='ids=a,b,c',
|
||||
headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
def test_delete_message_with_invalid_claim_doesnt_delete_message(self):
|
||||
path = self.queue_path
|
||||
resp = self._post_messages(path + '/messages', 1)
|
||||
location = jsonutils.loads(resp[0])['resources'][0]
|
||||
|
||||
self.simulate_delete(location, query_string='claim_id=invalid',
|
||||
headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
self.simulate_get(location, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
|
||||
def test_no_duplicated_messages_path_in_href(self):
|
||||
"""Fixes bug 1240897
|
||||
"""
|
||||
path = self.queue_path + '/messages'
|
||||
self._post_messages(path, repeat=1)
|
||||
|
||||
msg_id = self._get_msg_id(self.srmock.headers_dict)
|
||||
|
||||
query_string = 'ids=%s' % msg_id
|
||||
body = self.simulate_get(path,
|
||||
query_string=query_string,
|
||||
headers=self.headers)
|
||||
messages = jsonutils.loads(body[0])
|
||||
|
||||
self.assertNotIn(self.queue_path + '/messages/messages',
|
||||
messages[0]['href'])
|
||||
|
||||
def _post_messages(self, target, repeat=1):
|
||||
doc = jsonutils.dumps([{'body': 239, 'ttl': 300}] * repeat)
|
||||
return self.simulate_post(target, body=doc,
|
||||
headers=self.headers)
|
||||
|
||||
def _get_msg_id(self, headers):
|
||||
return self._get_msg_ids(headers)[0]
|
||||
|
||||
def _get_msg_ids(self, headers):
|
||||
return headers['location'].rsplit('=', 1)[-1].split(',')
|
||||
|
||||
|
||||
class TestMessagesSqlalchemy(MessagesBaseTest):
|
||||
config_file = 'wsgi_sqlalchemy.conf'
|
||||
|
||||
|
||||
class TestMessagesMongoDB(MessagesBaseTest):
|
||||
config_file = 'wsgi_mongodb.conf'
|
||||
|
||||
@testing.requires_mongodb
|
||||
def setUp(self):
|
||||
super(TestMessagesMongoDB, self).setUp()
|
||||
|
||||
def tearDown(self):
|
||||
super(TestMessagesMongoDB, self).tearDown()
|
||||
|
||||
|
||||
class TestMessagesMongoDBSharded(MessagesBaseTest):
|
||||
config_file = 'wsgi_mongodb_sharded.conf'
|
||||
|
||||
@testing.requires_mongodb
|
||||
def setUp(self):
|
||||
super(TestMessagesMongoDBSharded, self).setUp()
|
||||
|
||||
def tearDown(self):
|
||||
super(TestMessagesMongoDBSharded, self).tearDown()
|
||||
|
||||
# TODO(cpp-cabrera): remove this skipTest once sharded queue
|
||||
# listing is implemented
|
||||
def test_list(self):
|
||||
self.skipTest("Need to implement sharded queue listing.")
|
||||
|
||||
|
||||
class TestMessagesFaultyDriver(base.V1_1BaseFaulty):
|
||||
config_file = 'wsgi_faulty.conf'
|
||||
|
||||
def test_simple(self):
|
||||
project_id = 'xyz'
|
||||
path = self.url_prefix + '/queues/fizbit/messages'
|
||||
doc = '[{"body": 239, "ttl": 100}]'
|
||||
headers = {
|
||||
'Client-ID': str(uuid.uuid4()),
|
||||
'X-Project-ID': project_id
|
||||
}
|
||||
|
||||
self.simulate_post(path,
|
||||
body=doc,
|
||||
headers=headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_503)
|
||||
|
||||
self.simulate_get(path,
|
||||
headers=headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_503)
|
||||
|
||||
self.simulate_get(path + '/nonexistent', headers=headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_503)
|
||||
|
||||
self.simulate_delete(path + '/nada', headers=headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_503)
|
440
marconi/tests/queues/transport/wsgi/v1_1/test_queue_lifecycle.py
Normal file
440
marconi/tests/queues/transport/wsgi/v1_1/test_queue_lifecycle.py
Normal file
@ -0,0 +1,440 @@
|
||||
# Copyright (c) 2013 Rackspace, Inc.
|
||||
#
|
||||
# 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 uuid
|
||||
|
||||
import ddt
|
||||
import falcon
|
||||
import six
|
||||
|
||||
from marconi.openstack.common import jsonutils
|
||||
from marconi import tests as testing
|
||||
from marconi.tests.queues.transport.wsgi import base
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class QueueLifecycleBaseTest(base.V1_1Base):
|
||||
|
||||
config_file = None
|
||||
|
||||
def setUp(self):
|
||||
super(QueueLifecycleBaseTest, self).setUp()
|
||||
|
||||
self.queue_path = self.url_prefix + '/queues'
|
||||
self.gumshoe_queue_path = self.queue_path + '/gumshoe'
|
||||
self.fizbat_queue_path = self.queue_path + '/fizbat'
|
||||
self.fizbat_queue_path_metadata = self.fizbat_queue_path + '/metadata'
|
||||
|
||||
self.headers = {
|
||||
'Client-ID': str(uuid.uuid4()),
|
||||
'X-Project-ID': '3387309841abc_'
|
||||
}
|
||||
|
||||
def test_empty_project_id(self):
|
||||
headers = {
|
||||
'Client-ID': str(uuid.uuid4()),
|
||||
'X-Project-ID': ''
|
||||
}
|
||||
self.simulate_get(self.gumshoe_queue_path, headers=headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
self.simulate_put(self.gumshoe_queue_path, headers=headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
self.simulate_head(self.gumshoe_queue_path, headers=headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
self.simulate_delete(self.gumshoe_queue_path, headers=headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
@ddt.data('480924', 'foo')
|
||||
def test_basics_thoroughly(self, project_id):
|
||||
headers = {
|
||||
'Client-ID': str(uuid.uuid4()),
|
||||
'X-Project-ID': project_id
|
||||
}
|
||||
gumshoe_queue_path_metadata = self.gumshoe_queue_path + '/metadata'
|
||||
gumshoe_queue_path_stats = self.gumshoe_queue_path + '/stats'
|
||||
|
||||
# Stats not found - queue not created yet
|
||||
self.simulate_get(gumshoe_queue_path_stats, headers=headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_404)
|
||||
|
||||
# Metadata not found - queue not created yet
|
||||
self.simulate_get(gumshoe_queue_path_metadata, headers=headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_404)
|
||||
|
||||
# Create
|
||||
self.simulate_put(self.gumshoe_queue_path, headers=headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_201)
|
||||
|
||||
location = self.srmock.headers_dict['Location']
|
||||
self.assertEqual(location, self.gumshoe_queue_path)
|
||||
|
||||
# Ensure queue existence
|
||||
self.simulate_head(self.gumshoe_queue_path, headers=headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
# Add metadata
|
||||
|
||||
doc = '{"messages": {"ttl": 600}}'
|
||||
self.simulate_put(gumshoe_queue_path_metadata,
|
||||
headers=headers, body=doc)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
# Fetch metadata
|
||||
result = self.simulate_get(gumshoe_queue_path_metadata,
|
||||
headers=headers)
|
||||
result_doc = jsonutils.loads(result[0])
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
self.assertEqual(result_doc, jsonutils.loads(doc))
|
||||
|
||||
# Stats empty queue
|
||||
self.simulate_get(gumshoe_queue_path_stats, headers=headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
|
||||
# Delete
|
||||
self.simulate_delete(self.gumshoe_queue_path, headers=headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
# Get non-existent queue
|
||||
self.simulate_get(self.gumshoe_queue_path, headers=headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_404)
|
||||
|
||||
# Get non-existent stats
|
||||
self.simulate_get(gumshoe_queue_path_stats, headers=headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_404)
|
||||
|
||||
# Get non-existent metadata
|
||||
self.simulate_get(gumshoe_queue_path_metadata, headers=headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_404)
|
||||
|
||||
def test_name_restrictions(self):
|
||||
self.simulate_put(self.queue_path + '/Nice-Boat_2',
|
||||
headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_201)
|
||||
|
||||
self.simulate_put(self.queue_path + '/Nice-Bo@t',
|
||||
headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
self.simulate_put(self.queue_path + '/_' + 'niceboat' * 8,
|
||||
headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
def test_project_id_restriction(self):
|
||||
muvluv_queue_path = self.queue_path + '/Muv-Luv'
|
||||
|
||||
self.simulate_put(muvluv_queue_path,
|
||||
headers={'Client-ID': str(uuid.uuid4()),
|
||||
'X-Project-ID': 'JAM Project' * 24})
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
# no charset restrictions
|
||||
self.simulate_put(muvluv_queue_path,
|
||||
headers={'Client-ID': str(uuid.uuid4()),
|
||||
'X-Project-ID': 'JAM Project'})
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_201)
|
||||
|
||||
def test_non_ascii_name(self):
|
||||
test_params = ((u'/queues/non-ascii-n\u0153me', 'utf-8'),
|
||||
(u'/queues/non-ascii-n\xc4me', 'iso8859-1'))
|
||||
|
||||
for uri, enc in test_params:
|
||||
uri = self.url_prefix + uri
|
||||
|
||||
if six.PY2:
|
||||
uri = uri.encode(enc)
|
||||
|
||||
self.simulate_put(uri, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
self.simulate_get(uri, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
self.simulate_delete(uri, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
def test_no_metadata(self):
|
||||
self.simulate_put(self.fizbat_queue_path, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_201)
|
||||
|
||||
self.simulate_put(self.fizbat_queue_path_metadata,
|
||||
headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
self.simulate_put(self.fizbat_queue_path_metadata, body='',
|
||||
headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
@ddt.data('{', '[]', '.', ' ', '')
|
||||
def test_bad_metadata(self, document):
|
||||
self.simulate_put(self.fizbat_queue_path, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_201)
|
||||
|
||||
self.simulate_put(self.fizbat_queue_path_metadata,
|
||||
headers=self.headers,
|
||||
body=document)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
def test_too_much_metadata(self):
|
||||
self.simulate_put(self.fizbat_queue_path, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_201)
|
||||
doc = '{{"messages": {{"ttl": 600}}, "padding": "{pad}"}}'
|
||||
|
||||
max_size = self.transport_cfg.max_queue_metadata
|
||||
padding_len = max_size - (len(doc) - 10) + 1
|
||||
|
||||
doc = doc.format(pad='x' * padding_len)
|
||||
|
||||
self.simulate_put(self.fizbat_queue_path_metadata,
|
||||
headers=self.headers,
|
||||
body=doc)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
def test_way_too_much_metadata(self):
|
||||
self.simulate_put(self.fizbat_queue_path, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_201)
|
||||
doc = '{{"messages": {{"ttl": 600}}, "padding": "{pad}"}}'
|
||||
|
||||
max_size = self.transport_cfg.max_queue_metadata
|
||||
padding_len = max_size * 100
|
||||
|
||||
doc = doc.format(pad='x' * padding_len)
|
||||
|
||||
self.simulate_put(self.fizbat_queue_path_metadata,
|
||||
headers=self.headers, body=doc)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
def test_custom_metadata(self):
|
||||
self.simulate_put(self.fizbat_queue_path, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_201)
|
||||
|
||||
# Set
|
||||
doc = '{{"messages": {{"ttl": 600}}, "padding": "{pad}"}}'
|
||||
|
||||
max_size = self.transport_cfg.max_queue_metadata
|
||||
padding_len = max_size - (len(doc) - 2)
|
||||
|
||||
doc = doc.format(pad='x' * padding_len)
|
||||
self.simulate_put(self.fizbat_queue_path_metadata,
|
||||
headers=self.headers,
|
||||
body=doc)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
# Get
|
||||
result = self.simulate_get(self.fizbat_queue_path_metadata,
|
||||
headers=self.headers)
|
||||
result_doc = jsonutils.loads(result[0])
|
||||
self.assertEqual(result_doc, jsonutils.loads(doc))
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
|
||||
def test_update_metadata(self):
|
||||
xyz_queue_path = self.url_prefix + '/queues/xyz'
|
||||
xyz_queue_path_metadata = xyz_queue_path + '/metadata'
|
||||
|
||||
# Create
|
||||
self.simulate_put(xyz_queue_path, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_201)
|
||||
|
||||
# Set meta
|
||||
doc1 = '{"messages": {"ttl": 600}}'
|
||||
self.simulate_put(xyz_queue_path_metadata,
|
||||
headers=self.headers,
|
||||
body=doc1)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
# Update
|
||||
doc2 = '{"messages": {"ttl": 100}}'
|
||||
self.simulate_put(xyz_queue_path_metadata,
|
||||
headers=self.headers,
|
||||
body=doc2)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
# Get
|
||||
result = self.simulate_get(xyz_queue_path_metadata,
|
||||
headers=self.headers)
|
||||
result_doc = jsonutils.loads(result[0])
|
||||
|
||||
self.assertEqual(result_doc, jsonutils.loads(doc2))
|
||||
self.assertEqual(self.srmock.headers_dict['Content-Location'],
|
||||
xyz_queue_path_metadata)
|
||||
|
||||
def test_list(self):
|
||||
arbitrary_number = 644079696574693
|
||||
project_id = str(arbitrary_number)
|
||||
header = {
|
||||
'X-Project-ID': project_id
|
||||
}
|
||||
|
||||
# NOTE(kgriffs): It's important that this one sort after the one
|
||||
# above. This is in order to prove that bug/1236605 is fixed, and
|
||||
# stays fixed!
|
||||
alt_project_id = str(arbitrary_number + 1)
|
||||
|
||||
# List empty
|
||||
self.simulate_get(self.queue_path, headers=header)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
# Payload exceeded
|
||||
self.simulate_get(self.queue_path, headers=header,
|
||||
query_string='limit=21')
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
# Create some
|
||||
def create_queue(name, project_id, body):
|
||||
altheader = {}
|
||||
if project_id is not None:
|
||||
altheader['X-Project-ID'] = project_id
|
||||
uri = self.queue_path + '/' + name
|
||||
self.simulate_put(uri, headers=altheader)
|
||||
self.simulate_put(uri + '/metadata', headers=altheader, body=body)
|
||||
|
||||
create_queue('g1', None, '{"answer": 42}')
|
||||
create_queue('g2', None, '{"answer": 42}')
|
||||
|
||||
create_queue('q1', project_id, '{"node": 31}')
|
||||
create_queue('q2', project_id, '{"node": 32}')
|
||||
create_queue('q3', project_id, '{"node": 33}')
|
||||
|
||||
create_queue('q3', alt_project_id, '{"alt": 1}')
|
||||
|
||||
# List (global queues)
|
||||
result = self.simulate_get(self.queue_path,
|
||||
query_string='limit=2&detailed=true')
|
||||
|
||||
result_doc = jsonutils.loads(result[0])
|
||||
queues = result_doc['queues']
|
||||
self.assertEqual(len(queues), 2)
|
||||
|
||||
for queue in queues:
|
||||
self.assertEqual(queue['metadata'], {'answer': 42})
|
||||
|
||||
# List (limit)
|
||||
result = self.simulate_get(self.queue_path, headers=header,
|
||||
query_string='limit=2')
|
||||
|
||||
result_doc = jsonutils.loads(result[0])
|
||||
self.assertEqual(len(result_doc['queues']), 2)
|
||||
|
||||
# List (no metadata, get all)
|
||||
result = self.simulate_get(self.queue_path,
|
||||
headers=header, query_string='limit=5')
|
||||
|
||||
result_doc = jsonutils.loads(result[0])
|
||||
[target, params] = result_doc['links'][0]['href'].split('?')
|
||||
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
self.assertEqual(self.srmock.headers_dict['Content-Location'],
|
||||
self.queue_path + '?limit=5')
|
||||
|
||||
# Ensure we didn't pick up the queue from the alt project.
|
||||
queues = result_doc['queues']
|
||||
self.assertEqual(len(queues), 3)
|
||||
|
||||
for queue in queues:
|
||||
self.simulate_get(queue['href'] + '/metadata', headers=header)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
|
||||
altheader = header.copy()
|
||||
altheader['X-Project-ID'] = 'imnothere'
|
||||
self.simulate_get(queue['href'] + '/metadata', headers=altheader)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_404)
|
||||
|
||||
self.assertNotIn('metadata', queue)
|
||||
|
||||
# List with metadata
|
||||
result = self.simulate_get(self.queue_path, headers=header,
|
||||
query_string='detailed=true')
|
||||
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
result_doc = jsonutils.loads(result[0])
|
||||
[target, params] = result_doc['links'][0]['href'].split('?')
|
||||
|
||||
queue = result_doc['queues'][0]
|
||||
result = self.simulate_get(queue['href'] + '/metadata', headers=header)
|
||||
result_doc = jsonutils.loads(result[0])
|
||||
self.assertEqual(result_doc, queue['metadata'])
|
||||
self.assertEqual(result_doc, {'node': 31})
|
||||
|
||||
# List tail
|
||||
self.simulate_get(target, headers=header, query_string=params)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
# List manually-constructed tail
|
||||
self.simulate_get(target, headers=header, query_string='marker=zzz')
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
|
||||
class TestQueueLifecycleMongoDB(QueueLifecycleBaseTest):
|
||||
|
||||
config_file = 'wsgi_mongodb.conf'
|
||||
|
||||
@testing.requires_mongodb
|
||||
def setUp(self):
|
||||
super(TestQueueLifecycleMongoDB, self).setUp()
|
||||
|
||||
def tearDown(self):
|
||||
storage = self.boot.storage._storage
|
||||
connection = storage.connection
|
||||
|
||||
connection.drop_database(storage.queues_database)
|
||||
|
||||
for db in storage.message_databases:
|
||||
connection.drop_database(db)
|
||||
|
||||
super(TestQueueLifecycleMongoDB, self).tearDown()
|
||||
|
||||
|
||||
class TestQueueLifecycleSqlalchemy(QueueLifecycleBaseTest):
|
||||
|
||||
config_file = 'wsgi_sqlalchemy.conf'
|
||||
|
||||
|
||||
class TestQueueLifecycleFaultyDriver(base.V1_1BaseFaulty):
|
||||
|
||||
config_file = 'wsgi_faulty.conf'
|
||||
|
||||
def test_simple(self):
|
||||
self.headers = {
|
||||
'Client-ID': str(uuid.uuid4()),
|
||||
'X-Project-ID': '338730984abc_1'
|
||||
}
|
||||
|
||||
gumshoe_queue_path = self.url_prefix + '/queues/gumshoe'
|
||||
doc = '{"messages": {"ttl": 600}}'
|
||||
self.simulate_put(gumshoe_queue_path,
|
||||
headers=self.headers,
|
||||
body=doc)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_503)
|
||||
|
||||
location = ('Location', gumshoe_queue_path)
|
||||
self.assertNotIn(location, self.srmock.headers)
|
||||
|
||||
result = self.simulate_get(gumshoe_queue_path + '/metadata',
|
||||
headers=self.headers)
|
||||
result_doc = jsonutils.loads(result[0])
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_503)
|
||||
self.assertNotEqual(result_doc, jsonutils.loads(doc))
|
||||
|
||||
self.simulate_get(gumshoe_queue_path + '/stats',
|
||||
headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_503)
|
||||
|
||||
self.simulate_get(self.url_prefix + '/queues',
|
||||
headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_503)
|
||||
|
||||
self.simulate_delete(gumshoe_queue_path, headers=self.headers)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_503)
|
308
marconi/tests/queues/transport/wsgi/v1_1/test_shards.py
Normal file
308
marconi/tests/queues/transport/wsgi/v1_1/test_shards.py
Normal file
@ -0,0 +1,308 @@
|
||||
# Copyright (c) 2013 Rackspace, Inc.
|
||||
#
|
||||
# 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 contextlib
|
||||
import uuid
|
||||
|
||||
import ddt
|
||||
import falcon
|
||||
|
||||
from marconi.openstack.common import jsonutils
|
||||
from marconi import tests as testing
|
||||
from marconi.tests.queues.transport.wsgi import base
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def shard(test, name, weight, uri, options={}):
|
||||
"""A context manager for constructing a shard for use in testing.
|
||||
|
||||
Deletes the shard after exiting the context.
|
||||
|
||||
:param test: Must expose simulate_* methods
|
||||
:param name: Name for this shard
|
||||
:type name: six.text_type
|
||||
:type weight: int
|
||||
:type uri: six.text_type
|
||||
:type options: dict
|
||||
:returns: (name, weight, uri, options)
|
||||
:rtype: see above
|
||||
"""
|
||||
doc = {'weight': weight, 'uri': uri, 'options': options}
|
||||
path = test.url_prefix + '/shards/' + name
|
||||
|
||||
test.simulate_put(path, body=jsonutils.dumps(doc))
|
||||
|
||||
try:
|
||||
yield name, weight, uri, options
|
||||
|
||||
finally:
|
||||
test.simulate_delete(path)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def shards(test, count, uri):
|
||||
"""A context manager for constructing shards for use in testing.
|
||||
|
||||
Deletes the shards after exiting the context.
|
||||
|
||||
:param test: Must expose simulate_* methods
|
||||
:param count: Number of shards to create
|
||||
:type count: int
|
||||
:returns: (paths, weights, uris, options)
|
||||
:rtype: ([six.text_type], [int], [six.text_type], [dict])
|
||||
"""
|
||||
base = test.url_prefix + '/shards/'
|
||||
args = [(base + str(i), i,
|
||||
{str(i): i})
|
||||
for i in range(count)]
|
||||
for path, weight, option in args:
|
||||
doc = {'weight': weight, 'uri': uri, 'options': option}
|
||||
test.simulate_put(path, body=jsonutils.dumps(doc))
|
||||
|
||||
try:
|
||||
yield args
|
||||
finally:
|
||||
for path, _, _ in args:
|
||||
test.simulate_delete(path)
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class ShardsBaseTest(base.V1_1Base):
|
||||
|
||||
def setUp(self):
|
||||
super(ShardsBaseTest, self).setUp()
|
||||
self.doc = {'weight': 100, 'uri': 'sqlite://:memory:'}
|
||||
self.shard = self.url_prefix + '/shards/' + str(uuid.uuid1())
|
||||
self.simulate_put(self.shard, body=jsonutils.dumps(self.doc))
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_201)
|
||||
|
||||
def tearDown(self):
|
||||
super(ShardsBaseTest, self).tearDown()
|
||||
self.simulate_delete(self.shard)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
def test_put_shard_works(self):
|
||||
name = str(uuid.uuid1())
|
||||
weight, uri = self.doc['weight'], self.doc['uri']
|
||||
with shard(self, name, weight, uri):
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_201)
|
||||
|
||||
def test_put_raises_if_missing_fields(self):
|
||||
path = self.url_prefix + '/shards/' + str(uuid.uuid1())
|
||||
self.simulate_put(path, body=jsonutils.dumps({'weight': 100}))
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
self.simulate_put(path,
|
||||
body=jsonutils.dumps(
|
||||
{'uri': 'sqlite://:memory:'}))
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
@ddt.data(-1, 2**32+1, 'big')
|
||||
def test_put_raises_if_invalid_weight(self, weight):
|
||||
path = self.url_prefix + '/shards/' + str(uuid.uuid1())
|
||||
doc = {'weight': weight, 'uri': 'a'}
|
||||
self.simulate_put(path,
|
||||
body=jsonutils.dumps(doc))
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
@ddt.data(-1, 2**32+1, [], 'localhost:27017')
|
||||
def test_put_raises_if_invalid_uri(self, uri):
|
||||
path = self.url_prefix + '/shards/' + str(uuid.uuid1())
|
||||
self.simulate_put(path,
|
||||
body=jsonutils.dumps({'weight': 1, 'uri': uri}))
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
@ddt.data(-1, 'wee', [])
|
||||
def test_put_raises_if_invalid_options(self, options):
|
||||
path = self.url_prefix + '/shards/' + str(uuid.uuid1())
|
||||
doc = {'weight': 1, 'uri': 'a', 'options': options}
|
||||
self.simulate_put(path, body=jsonutils.dumps(doc))
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
def test_put_existing_overwrites(self):
|
||||
# NOTE(cabrera): setUp creates default shard
|
||||
expect = self.doc
|
||||
self.simulate_put(self.shard,
|
||||
body=jsonutils.dumps(expect))
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_201)
|
||||
|
||||
result = self.simulate_get(self.shard)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
doc = jsonutils.loads(result[0])
|
||||
self.assertEqual(doc['weight'], expect['weight'])
|
||||
self.assertEqual(doc['uri'], expect['uri'])
|
||||
|
||||
def test_delete_works(self):
|
||||
self.simulate_delete(self.shard)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
self.simulate_get(self.shard)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_404)
|
||||
|
||||
def test_get_nonexisting_raises_404(self):
|
||||
self.simulate_get(self.url_prefix + '/shards/nonexisting')
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_404)
|
||||
|
||||
def _shard_expect(self, shard, xhref, xweight, xuri):
|
||||
self.assertIn('href', shard)
|
||||
self.assertEqual(shard['href'], xhref)
|
||||
self.assertIn('weight', shard)
|
||||
self.assertEqual(shard['weight'], xweight)
|
||||
self.assertIn('uri', shard)
|
||||
self.assertEqual(shard['uri'], xuri)
|
||||
|
||||
def test_get_works(self):
|
||||
result = self.simulate_get(self.shard)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
shard = jsonutils.loads(result[0])
|
||||
self._shard_expect(shard, self.shard, self.doc['weight'],
|
||||
self.doc['uri'])
|
||||
|
||||
def test_detailed_get_works(self):
|
||||
result = self.simulate_get(self.shard,
|
||||
query_string='?detailed=True')
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
shard = jsonutils.loads(result[0])
|
||||
self._shard_expect(shard, self.shard, self.doc['weight'],
|
||||
self.doc['uri'])
|
||||
self.assertIn('options', shard)
|
||||
self.assertEqual(shard['options'], {})
|
||||
|
||||
def test_patch_raises_if_missing_fields(self):
|
||||
self.simulate_patch(self.shard,
|
||||
body=jsonutils.dumps({'location': 1}))
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
def _patch_test(self, doc):
|
||||
self.simulate_patch(self.shard,
|
||||
body=jsonutils.dumps(doc))
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
|
||||
result = self.simulate_get(self.shard,
|
||||
query_string='?detailed=True')
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
shard = jsonutils.loads(result[0])
|
||||
self._shard_expect(shard, self.shard, doc['weight'],
|
||||
doc['uri'])
|
||||
self.assertEqual(shard['options'], doc['options'])
|
||||
|
||||
def test_patch_works(self):
|
||||
doc = {'weight': 101, 'uri': 'sqlite://:memory:', 'options': {'a': 1}}
|
||||
self._patch_test(doc)
|
||||
|
||||
def test_patch_works_with_extra_fields(self):
|
||||
doc = {'weight': 101, 'uri': 'sqlite://:memory:', 'options': {'a': 1},
|
||||
'location': 100, 'partition': 'taco'}
|
||||
self._patch_test(doc)
|
||||
|
||||
@ddt.data(-1, 2**32+1, 'big')
|
||||
def test_patch_raises_400_on_invalid_weight(self, weight):
|
||||
self.simulate_patch(self.shard,
|
||||
body=jsonutils.dumps({'weight': weight}))
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
@ddt.data(-1, 2**32+1, [], 'localhost:27017')
|
||||
def test_patch_raises_400_on_invalid_uri(self, uri):
|
||||
self.simulate_patch(self.shard,
|
||||
body=jsonutils.dumps({'uri': uri}))
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
@ddt.data(-1, 'wee', [])
|
||||
def test_patch_raises_400_on_invalid_options(self, options):
|
||||
self.simulate_patch(self.shard,
|
||||
body=jsonutils.dumps({'options': options}))
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_400)
|
||||
|
||||
def test_patch_raises_404_if_shard_not_found(self):
|
||||
self.simulate_patch(self.url_prefix + '/shards/notexists',
|
||||
body=jsonutils.dumps({'weight': 1}))
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_404)
|
||||
|
||||
def test_empty_listing_returns_204(self):
|
||||
self.simulate_delete(self.shard)
|
||||
self.simulate_get(self.url_prefix + '/shards')
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_204)
|
||||
|
||||
def _listing_test(self, count=10, limit=10,
|
||||
marker=None, detailed=False):
|
||||
# NOTE(cpp-cabrera): delete initial shard - it will interfere
|
||||
# with listing tests
|
||||
self.simulate_delete(self.shard)
|
||||
query = '?limit={0}&detailed={1}'.format(limit, detailed)
|
||||
if marker:
|
||||
query += '&marker={2}'.format(marker)
|
||||
|
||||
with shards(self, count, self.doc['uri']) as expected:
|
||||
result = self.simulate_get(self.url_prefix + '/shards',
|
||||
query_string=query)
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
results = jsonutils.loads(result[0])
|
||||
self.assertIsInstance(results, dict)
|
||||
self.assertIn('shards', results)
|
||||
shard_list = results['shards']
|
||||
self.assertEqual(len(shard_list), min(limit, count))
|
||||
for s in shard_list:
|
||||
# NOTE(flwang): It can't assumed that both sqlalchemy and
|
||||
# mongodb can return query result with the same order. Just
|
||||
# like the order they're inserted. Actually, sqlalchemy can't
|
||||
# guarantee that. So we're leveraging the relationship between
|
||||
# shard weight and the index of shards fixture to get the
|
||||
# right shard to verify.
|
||||
expect = expected[s['weight']]
|
||||
path, weight = expect[:2]
|
||||
self._shard_expect(s, path, weight, self.doc['uri'])
|
||||
if detailed:
|
||||
self.assertIn('options', s)
|
||||
self.assertEqual(s['options'], expect[-1])
|
||||
else:
|
||||
self.assertNotIn('options', s)
|
||||
|
||||
def test_listing_works(self):
|
||||
self._listing_test()
|
||||
|
||||
def test_detailed_listing_works(self):
|
||||
self._listing_test(detailed=True)
|
||||
|
||||
@ddt.data(1, 5, 10, 15)
|
||||
def test_listing_works_with_limit(self, limit):
|
||||
self._listing_test(count=15, limit=limit)
|
||||
|
||||
def test_listing_marker_is_respected(self):
|
||||
self.simulate_delete(self.shard)
|
||||
|
||||
with shards(self, 10, self.doc['uri']) as expected:
|
||||
result = self.simulate_get(self.url_prefix + '/shards',
|
||||
query_string='?marker=3')
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_200)
|
||||
shard_list = jsonutils.loads(result[0])['shards']
|
||||
self.assertEqual(len(shard_list), 6)
|
||||
path, weight = expected[4][:2]
|
||||
self._shard_expect(shard_list[0], path, weight, self.doc['uri'])
|
||||
|
||||
|
||||
class TestShardsMongoDB(ShardsBaseTest):
|
||||
|
||||
config_file = 'wsgi_mongodb.conf'
|
||||
|
||||
@testing.requires_mongodb
|
||||
def setUp(self):
|
||||
super(TestShardsMongoDB, self).setUp()
|
||||
|
||||
|
||||
class TestShardsSqlalchemy(ShardsBaseTest):
|
||||
|
||||
config_file = 'wsgi_sqlalchemy.conf'
|
||||
|
||||
def setUp(self):
|
||||
super(TestShardsSqlalchemy, self).setUp()
|
@ -14,7 +14,8 @@
|
||||
|
||||
import falcon
|
||||
|
||||
from marconi.tests.queues.transport import wsgi
|
||||
from marconi.tests.queues.transport.wsgi import base
|
||||
from marconi.tests.queues.transport.wsgi import v1
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
@ -24,67 +25,67 @@ from marconi.tests.queues.transport import wsgi
|
||||
URL_PREFIX = '/v1'
|
||||
|
||||
|
||||
class TestAuth(wsgi.TestAuth):
|
||||
class TestAuth(v1.TestAuth):
|
||||
url_prefix = URL_PREFIX
|
||||
|
||||
|
||||
class TestClaimsFaultyDriver(wsgi.TestClaimsFaultyDriver):
|
||||
class TestClaimsFaultyDriver(v1.TestClaimsFaultyDriver):
|
||||
url_prefix = URL_PREFIX
|
||||
|
||||
|
||||
class TestClaimsMongoDB(wsgi.TestClaimsMongoDB):
|
||||
class TestClaimsMongoDB(v1.TestClaimsMongoDB):
|
||||
url_prefix = URL_PREFIX
|
||||
|
||||
|
||||
class TestClaimsSqlalchemy(wsgi.TestClaimsSqlalchemy):
|
||||
class TestClaimsSqlalchemy(v1.TestClaimsSqlalchemy):
|
||||
url_prefix = URL_PREFIX
|
||||
|
||||
|
||||
class TestDefaultLimits(wsgi.TestDefaultLimits):
|
||||
class TestDefaultLimits(v1.TestDefaultLimits):
|
||||
url_prefix = URL_PREFIX
|
||||
|
||||
|
||||
class TestHomeDocument(wsgi.TestHomeDocument):
|
||||
class TestHomeDocument(v1.TestHomeDocument):
|
||||
url_prefix = URL_PREFIX
|
||||
|
||||
|
||||
class TestMediaType(wsgi.TestMediaType):
|
||||
class TestMediaType(v1.TestMediaType):
|
||||
url_prefix = URL_PREFIX
|
||||
|
||||
|
||||
class TestMessagesFaultyDriver(wsgi.TestMessagesFaultyDriver):
|
||||
class TestMessagesFaultyDriver(v1.TestMessagesFaultyDriver):
|
||||
url_prefix = URL_PREFIX
|
||||
|
||||
|
||||
class TestMessagesMongoDB(wsgi.TestMessagesMongoDB):
|
||||
class TestMessagesMongoDB(v1.TestMessagesMongoDB):
|
||||
url_prefix = URL_PREFIX
|
||||
|
||||
|
||||
class TestMessagesMongoDBSharded(wsgi.TestMessagesMongoDBSharded):
|
||||
class TestMessagesMongoDBSharded(v1.TestMessagesMongoDBSharded):
|
||||
url_prefix = URL_PREFIX
|
||||
|
||||
|
||||
class TestMessagesSqlalchemy(wsgi.TestMessagesSqlalchemy):
|
||||
class TestMessagesSqlalchemy(v1.TestMessagesSqlalchemy):
|
||||
url_prefix = URL_PREFIX
|
||||
|
||||
|
||||
class TestQueueFaultyDriver(wsgi.TestQueueFaultyDriver):
|
||||
class TestQueueFaultyDriver(v1.TestQueueFaultyDriver):
|
||||
url_prefix = URL_PREFIX
|
||||
|
||||
|
||||
class TestQueueLifecycleMongoDB(wsgi.TestQueueLifecycleMongoDB):
|
||||
class TestQueueLifecycleMongoDB(v1.TestQueueLifecycleMongoDB):
|
||||
url_prefix = URL_PREFIX
|
||||
|
||||
|
||||
class TestQueueLifecycleSqlalchemy(wsgi.TestQueueLifecycleSqlalchemy):
|
||||
class TestQueueLifecycleSqlalchemy(v1.TestQueueLifecycleSqlalchemy):
|
||||
url_prefix = URL_PREFIX
|
||||
|
||||
|
||||
class TestShardsMongoDB(wsgi.TestShardsMongoDB):
|
||||
class TestShardsMongoDB(v1.TestShardsMongoDB):
|
||||
url_prefix = URL_PREFIX
|
||||
|
||||
|
||||
class TestShardsSqlalchemy(wsgi.TestShardsSqlalchemy):
|
||||
class TestShardsSqlalchemy(v1.TestShardsSqlalchemy):
|
||||
url_prefix = URL_PREFIX
|
||||
|
||||
|
||||
@ -92,7 +93,7 @@ class TestShardsSqlalchemy(wsgi.TestShardsSqlalchemy):
|
||||
# v1.0 only
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
class TestHealth(wsgi.TestBase):
|
||||
class TestHealth(base.V1Base):
|
||||
|
||||
config_file = 'wsgi_sqlalchemy.conf'
|
||||
|
||||
|
@ -14,8 +14,8 @@
|
||||
|
||||
import falcon
|
||||
|
||||
from marconi.tests.queues.transport import wsgi
|
||||
|
||||
from marconi.tests.queues.transport.wsgi import base
|
||||
from marconi.tests.queues.transport.wsgi import v1_1
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Identical or just minor variations across versions
|
||||
@ -24,69 +24,69 @@ from marconi.tests.queues.transport import wsgi
|
||||
URL_PREFIX = '/v1.1'
|
||||
|
||||
|
||||
class TestAuth(wsgi.TestAuth):
|
||||
class TestAuth(v1_1.TestAuth):
|
||||
url_prefix = URL_PREFIX
|
||||
|
||||
|
||||
class TestClaimsFaultyDriver(wsgi.TestClaimsFaultyDriver):
|
||||
class TestClaimsFaultyDriver(v1_1.TestClaimsFaultyDriver):
|
||||
url_prefix = URL_PREFIX
|
||||
|
||||
|
||||
class TestClaimsMongoDB(wsgi.TestClaimsMongoDB):
|
||||
class TestClaimsMongoDB(v1_1.TestClaimsMongoDB):
|
||||
url_prefix = URL_PREFIX
|
||||
|
||||
|
||||
class TestClaimsSqlalchemy(wsgi.TestClaimsSqlalchemy):
|
||||
class TestClaimsSqlalchemy(v1_1.TestClaimsSqlalchemy):
|
||||
url_prefix = URL_PREFIX
|
||||
|
||||
|
||||
class TestDefaultLimits(wsgi.TestDefaultLimits):
|
||||
class TestDefaultLimits(v1_1.TestDefaultLimits):
|
||||
url_prefix = URL_PREFIX
|
||||
|
||||
|
||||
class TestHomeDocument(wsgi.TestHomeDocument):
|
||||
class TestHomeDocument(v1_1.TestHomeDocument):
|
||||
url_prefix = URL_PREFIX
|
||||
|
||||
|
||||
class TestMediaType(wsgi.TestMediaType):
|
||||
class TestMediaType(v1_1.TestMediaType):
|
||||
url_prefix = URL_PREFIX
|
||||
|
||||
|
||||
class TestMessagesFaultyDriver(wsgi.TestMessagesFaultyDriver):
|
||||
class TestMessagesFaultyDriver(v1_1.TestMessagesFaultyDriver):
|
||||
url_prefix = URL_PREFIX
|
||||
|
||||
|
||||
class TestMessagesMongoDB(wsgi.TestMessagesMongoDB):
|
||||
class TestMessagesMongoDB(v1_1.TestMessagesMongoDB):
|
||||
url_prefix = URL_PREFIX
|
||||
|
||||
|
||||
class TestMessagesMongoDBSharded(wsgi.TestMessagesMongoDBSharded):
|
||||
class TestMessagesMongoDBSharded(v1_1.TestMessagesMongoDBSharded):
|
||||
url_prefix = URL_PREFIX
|
||||
|
||||
|
||||
class TestMessagesSqlalchemy(wsgi.TestMessagesSqlalchemy):
|
||||
class TestMessagesSqlalchemy(v1_1.TestMessagesSqlalchemy):
|
||||
url_prefix = URL_PREFIX
|
||||
|
||||
|
||||
class TestQueueFaultyDriver(wsgi.TestQueueFaultyDriver):
|
||||
class TestQueueFaultyDriver(v1_1.TestQueueFaultyDriver):
|
||||
url_prefix = URL_PREFIX
|
||||
|
||||
|
||||
# TODO(kgriffs): Having to list a separate test for each backend is
|
||||
# sort of a pain; is there a better way?
|
||||
class TestQueueLifecycleMongoDB(wsgi.TestQueueLifecycleMongoDB):
|
||||
class TestQueueLifecycleMongoDB(v1_1.TestQueueLifecycleMongoDB):
|
||||
url_prefix = URL_PREFIX
|
||||
|
||||
|
||||
class TestQueueLifecycleSqlalchemy(wsgi.TestQueueLifecycleSqlalchemy):
|
||||
class TestQueueLifecycleSqlalchemy(v1_1.TestQueueLifecycleSqlalchemy):
|
||||
url_prefix = URL_PREFIX
|
||||
|
||||
|
||||
class TestShardsMongoDB(wsgi.TestShardsMongoDB):
|
||||
class TestShardsMongoDB(v1_1.TestShardsMongoDB):
|
||||
url_prefix = URL_PREFIX
|
||||
|
||||
|
||||
class TestShardsSqlalchemy(wsgi.TestShardsSqlalchemy):
|
||||
class TestShardsSqlalchemy(v1_1.TestShardsSqlalchemy):
|
||||
url_prefix = URL_PREFIX
|
||||
|
||||
|
||||
@ -94,7 +94,7 @@ class TestShardsSqlalchemy(wsgi.TestShardsSqlalchemy):
|
||||
# v1.1 only
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
class TestPing(wsgi.TestBase):
|
||||
class TestPing(base.V1_1Base):
|
||||
|
||||
config_file = 'wsgi_sqlalchemy.conf'
|
||||
|
||||
@ -114,7 +114,7 @@ class TestPing(wsgi.TestBase):
|
||||
self.assertEqual(response, [])
|
||||
|
||||
|
||||
class TestHealth(wsgi.TestBase):
|
||||
class TestHealth(base.V1_1Base):
|
||||
|
||||
config_file = 'wsgi_sqlalchemy.conf'
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user