chore: cleanup the unit tests with ddt

ddt stands for data-driven-tests, and it's also a Python module.
It adds the test data as a decorator to the test methods, so that
the test code can focus on each type of behaviors instead of using
`for` loops internally (on the other hand, you have to split big
tests which testing different types of behaviors into small tests).

Change-Id: I1cba67c15e9bb6e5e73e26a11e08fb1390a0504a
This commit is contained in:
Zhihao Yuan 2013-08-16 15:55:00 -04:00
parent 8e43a9adcb
commit 0464668be4
5 changed files with 136 additions and 133 deletions

View File

@ -18,6 +18,7 @@ import os
import pymongo
import ddt
import falcon
from marconi.common import config
@ -25,6 +26,7 @@ from marconi.openstack.common import timeutils
from marconi.tests.transport.wsgi import base
@ddt.ddt
class ClaimsBaseTest(base.TestBase):
def setUp(self):
@ -53,40 +55,43 @@ class ClaimsBaseTest(base.TestBase):
super(ClaimsBaseTest, self).tearDown()
def test_bad_claim(self):
for doc in (None, '[', '[]', '{}', '.', '"fail"'):
self.simulate_post(self.claims_path, self.project_id,
body=doc)
self.assertEquals(self.srmock.status, falcon.HTTP_400)
@ddt.data(None, '[', '[]', '{}', '.', '"fail"')
def test_bad_claim(self, doc):
self.simulate_post(self.claims_path, self.project_id, body=doc)
self.assertEquals(self.srmock.status, falcon.HTTP_400)
# Payload exceeded
href = self._get_a_claim()
self.simulate_patch(href, self.project_id, body=doc)
self.assertEquals(self.srmock.status, falcon.HTTP_400)
def test_exceeded_claim(self):
self.simulate_post(self.claims_path, self.project_id,
body='{"ttl": 100, "grace": 60}',
query_string='limit=21')
self.assertEquals(self.srmock.status, falcon.HTTP_400)
# Unacceptable TTL or grace
for ttl, grace in ((-1, -1), (59, 60), (60, 59),
(60, 43201), (43201, 60)):
self.simulate_post(self.claims_path, self.project_id,
body=json.dumps({'ttl': ttl, 'grace': grace}))
self.assertEquals(self.srmock.status, falcon.HTTP_400)
def test_bad_patch(self):
@ddt.data((-1, -1), (59, 60), (60, 59), (60, 43201), (43201, 60))
def test_unacceptable_ttl_or_grace(self, (ttl, grace)):
self.simulate_post(self.claims_path, self.project_id,
body='{"ttl": 100, "grace": 60}')
href = self.srmock.headers_dict['Location']
body=json.dumps({'ttl': ttl, 'grace': grace}))
for doc in (None, '[', '"crunchy"'):
self.simulate_patch(href, self.project_id, body=doc)
self.assertEquals(self.srmock.status, falcon.HTTP_400)
self.assertEquals(self.srmock.status, falcon.HTTP_400)
# Unacceptable new TTL
for ttl in (-1, 59, 43201):
self.simulate_post(self.claims_path, self.project_id,
body=json.dumps({'ttl': ttl}))
self.assertEquals(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, self.project_id,
body=json.dumps({'ttl': ttl}))
self.assertEquals(self.srmock.status, falcon.HTTP_400)
def _get_a_claim(self):
doc = '{"ttl": 100, "grace": 60}'
self.simulate_post(self.claims_path, self.project_id, body=doc)
return self.srmock.headers_dict['Location']
def test_too_much_metadata(self):
doc = '{"ttl": 100, "grace": 60}'
@ -200,22 +205,16 @@ class ClaimsBaseTest(base.TestBase):
# NOTE(cpp-cabrera): regression test against bug #1203842
def test_get_nonexistent_claim_404s(self):
path = '/v1/queues/notthere'
self.simulate_get(path + '/claims/a')
self.simulate_get(self.claims_path + '/a')
self.assertEquals(self.srmock.status, falcon.HTTP_404)
def test_delete_nonexistent_claim_204s(self):
path = '/v1/queues/notthere'
self.simulate_delete(path + '/claims/a')
self.simulate_delete(self.claims_path + '/a')
self.assertEquals(self.srmock.status, falcon.HTTP_204)
def test_patch_nonexistent_claim_404s(self):
path = '/v1/queues/notthere'
patch_data = json.dumps({'ttl': 100})
self.simulate_patch(path + '/claims/a', body=patch_data)
self.simulate_patch(self.claims_path + '/a', body=patch_data)
self.assertEquals(self.srmock.status, falcon.HTTP_404)

View File

@ -13,35 +13,35 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import ddt
import falcon
from falcon import testing
from marconi.tests.transport.wsgi import base
@ddt.ddt
class TestWSGIMediaType(base.TestBase):
config_filename = 'wsgi_sqlite.conf'
def test_json_only_endpoints(self):
@ddt.data(
('GET', '/v1/queues'),
('GET', '/v1/queues/nonexistent/metadata'),
('GET', '/v1/queues/nonexistent/stats'),
('POST', '/v1/queues/nonexistent/messages'),
('GET', '/v1/queues/nonexistent/messages/deadbeaf'),
('POST', '/v1/queues/nonexistent/claims'),
('GET', '/v1/queues/nonexistent/claims/0ad'),
('GET', '/v1/health'),
)
def test_json_only_endpoints(self, (method, endpoint)):
headers = {'Client-ID': '30387f00',
'Accept': 'application/xml'}
endpoints = [
('GET', '/v1/queues'),
('GET', '/v1/queues/nonexistent/metadata'),
('GET', '/v1/queues/nonexistent/stats'),
('POST', '/v1/queues/nonexistent/messages'),
('GET', '/v1/queues/nonexistent/messages/deadbeaf'),
('POST', '/v1/queues/nonexistent/claims'),
('GET', '/v1/queues/nonexistent/claims/0ad'),
('GET', '/v1/health'),
]
env = testing.create_environ(endpoint,
method=method,
headers=headers)
for method, endpoint in endpoints:
env = testing.create_environ(endpoint,
method=method,
headers=headers)
self.app(env, self.srmock)
self.assertEquals(self.srmock.status, falcon.HTTP_406)
self.app(env, self.srmock)
self.assertEquals(self.srmock.status, falcon.HTTP_406)

View File

@ -16,6 +16,7 @@
import json
import os
import ddt
import falcon
from testtools import matchers
@ -23,6 +24,7 @@ from marconi.common import config
from marconi.tests.transport.wsgi import base
@ddt.ddt
class MessagesBaseTest(base.TestBase):
def setUp(self):
@ -33,6 +35,7 @@ class MessagesBaseTest(base.TestBase):
self.project_id = '7e55e1a7e'
self.queue_path = '/v1/queues/fizbit'
self.messages_path = self.queue_path + '/messages'
doc = '{"_ttl": 60}'
self.simulate_put(self.queue_path, self.project_id, body=doc)
@ -48,8 +51,7 @@ class MessagesBaseTest(base.TestBase):
def _test_post(self, sample_messages):
sample_doc = json.dumps(sample_messages)
messages_path = self.queue_path + '/messages'
result = self.simulate_post(messages_path, self.project_id,
result = self.simulate_post(self.messages_path, self.project_id,
body=sample_doc, headers=self.headers)
self.assertEquals(self.srmock.status, falcon.HTTP_201)
@ -58,7 +60,7 @@ class MessagesBaseTest(base.TestBase):
msg_ids = self._get_msg_ids(self.srmock.headers_dict)
self.assertEquals(len(msg_ids), len(sample_messages))
expected_resources = [unicode(messages_path + '/' + id)
expected_resources = [unicode(self.messages_path + '/' + id)
for id in msg_ids]
self.assertEquals(expected_resources, result_doc['resources'])
self.assertFalse(result_doc['partial'])
@ -69,7 +71,7 @@ class MessagesBaseTest(base.TestBase):
# Test GET on the message resource directly
for msg_id in msg_ids:
message_uri = messages_path + '/' + msg_id
message_uri = self.messages_path + '/' + msg_id
# Wrong project ID
self.simulate_get(message_uri, '777777')
@ -87,7 +89,7 @@ class MessagesBaseTest(base.TestBase):
# Test bulk GET
query_string = 'ids=' + ','.join(msg_ids)
result = self.simulate_get(messages_path, self.project_id,
result = self.simulate_get(self.messages_path, self.project_id,
query_string=query_string)
self.assertEquals(self.srmock.status, falcon.HTTP_200)
@ -98,23 +100,22 @@ class MessagesBaseTest(base.TestBase):
def test_exceeded_payloads(self):
# Get a valid message id
path = self.queue_path + '/messages'
self._post_messages(path)
self._post_messages(self.messages_path)
msg_id = self._get_msg_id(self.srmock.headers_dict)
# Posting restriction
self._post_messages(path, repeat=23)
self._post_messages(self.messages_path, repeat=23)
self.assertEquals(self.srmock.status, falcon.HTTP_400)
# Bulk GET restriction
query_string = 'ids=' + ','.join([msg_id] * 21)
self.simulate_get(path, self.project_id, query_string=query_string)
self.simulate_get(self.messages_path, self.project_id,
query_string=query_string)
self.assertEquals(self.srmock.status, falcon.HTTP_400)
# Listing restriction
self.simulate_get(path, self.project_id,
self.simulate_get(self.messages_path, self.project_id,
query_string='limit=21',
headers=self.headers)
@ -122,7 +123,8 @@ class MessagesBaseTest(base.TestBase):
# Bulk deletion restriction
query_string = 'ids=' + ','.join([msg_id] * 22)
self.simulate_delete(path, self.project_id, query_string=query_string)
self.simulate_delete(self.messages_path, self.project_id,
query_string=query_string)
self.assertEquals(self.srmock.status, falcon.HTTP_400)
@ -146,23 +148,22 @@ class MessagesBaseTest(base.TestBase):
self._post_messages('/v1/queues/nonexistent/messages')
self.assertEquals(self.srmock.status, falcon.HTTP_404)
def test_post_bad_message(self):
messages_path = self.queue_path + '/messages'
@ddt.data(None, '[', '[]', '{}', '.')
def test_post_bad_message(self, document):
self.simulate_post(self.queue_path + '/messages',
body=document,
headers=self.headers)
for document in (None, '[', '[]', '{}', '.'):
self.simulate_post(messages_path,
body=document,
headers=self.headers)
self.assertEquals(self.srmock.status, falcon.HTTP_400)
self.assertEquals(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=json.dumps([{'ttl': ttl,
'body': None}]),
headers=self.headers)
# Unacceptable TTL
for ttl in (-1, 59, 1209601):
self.simulate_post(messages_path,
body=json.dumps([{'ttl': ttl,
'body': None}]),
headers=self.headers)
self.assertEquals(self.srmock.status, falcon.HTTP_400)
self.assertEquals(self.srmock.status, falcon.HTTP_400)
def test_exceeded_message_posting(self):
# Total (raw request) size
@ -176,32 +177,31 @@ class MessagesBaseTest(base.TestBase):
self.assertEquals(self.srmock.status, falcon.HTTP_400)
def test_unsupported_json(self):
for document in ('{"overflow": 9223372036854775808}',
'{"underflow": -9223372036854775809}'):
self.simulate_post(self.queue_path + '/messages',
body=document,
headers=self.headers)
@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.assertEquals(self.srmock.status, falcon.HTTP_400)
self.assertEquals(self.srmock.status, falcon.HTTP_400)
def test_delete(self):
path = self.queue_path + '/messages'
self._post_messages(path)
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(path + '/' + msg_id, self.project_id)
self.simulate_get(target, self.project_id)
self.assertEquals(self.srmock.status, falcon.HTTP_200)
self.simulate_delete(path + '/' + msg_id, self.project_id)
self.simulate_delete(target, self.project_id)
self.assertEquals(self.srmock.status, falcon.HTTP_204)
self.simulate_get(path + '/' + msg_id, self.project_id)
self.simulate_get(target, self.project_id)
self.assertEquals(self.srmock.status, falcon.HTTP_404)
# Safe to delete non-existing ones
self.simulate_delete(path + '/' + msg_id, self.project_id)
self.simulate_delete(target, self.project_id)
self.assertEquals(self.srmock.status, falcon.HTTP_204)
def test_bulk_delete(self):

View File

@ -17,6 +17,7 @@
import json
import os
import ddt
import falcon
import pymongo
@ -24,6 +25,7 @@ from marconi.common import config
from marconi.tests.transport.wsgi import base
@ddt.ddt
class QueueLifecycleBaseTest(base.TestBase):
config_filename = None
@ -34,55 +36,55 @@ class QueueLifecycleBaseTest(base.TestBase):
self.wsgi_cfg = config.namespace(
'drivers:transport:wsgi').from_options()
def test_basics_thoroughly(self):
@ddt.data('480924', 'foo', '', None)
def test_basics_thoroughly(self, project_id):
path = '/v1/queues/gumshoe'
for project_id in ('480924', 'foo', '', None):
# Stats not found - queue not created yet
self.simulate_get(path + '/stats', project_id)
self.assertEquals(self.srmock.status, falcon.HTTP_404)
# Stats not found - queue not created yet
self.simulate_get(path + '/stats', project_id)
self.assertEquals(self.srmock.status, falcon.HTTP_404)
# Metadata not found - queue not created yet
self.simulate_get(path + '/metadata', project_id)
self.assertEquals(self.srmock.status, falcon.HTTP_404)
# Metadata not found - queue not created yet
self.simulate_get(path + '/metadata', project_id)
self.assertEquals(self.srmock.status, falcon.HTTP_404)
# Create
self.simulate_put(path, project_id)
self.assertEquals(self.srmock.status, falcon.HTTP_201)
# Create
self.simulate_put(path, project_id)
self.assertEquals(self.srmock.status, falcon.HTTP_201)
location = ('Location', '/v1/queues/gumshoe')
self.assertIn(location, self.srmock.headers)
location = ('Location', '/v1/queues/gumshoe')
self.assertIn(location, self.srmock.headers)
# Ensure queue existence
self.simulate_head(path, project_id)
self.assertEquals(self.srmock.status, falcon.HTTP_204)
# Ensure queue existence
self.simulate_head(path, project_id)
self.assertEquals(self.srmock.status, falcon.HTTP_204)
# Add metadata
doc = '{"messages": {"ttl": 600}}'
self.simulate_put(path + '/metadata', project_id, body=doc)
self.assertEquals(self.srmock.status, falcon.HTTP_204)
# Add metadata
doc = '{"messages": {"ttl": 600}}'
self.simulate_put(path + '/metadata', project_id, body=doc)
self.assertEquals(self.srmock.status, falcon.HTTP_204)
# Fetch metadata
result = self.simulate_get(path + '/metadata', project_id)
result_doc = json.loads(result[0])
self.assertEquals(self.srmock.status, falcon.HTTP_200)
self.assertEquals(result_doc, json.loads(doc))
# Fetch metadata
result = self.simulate_get(path + '/metadata', project_id)
result_doc = json.loads(result[0])
self.assertEquals(self.srmock.status, falcon.HTTP_200)
self.assertEquals(result_doc, json.loads(doc))
# Delete
self.simulate_delete(path, project_id)
self.assertEquals(self.srmock.status, falcon.HTTP_204)
# Delete
self.simulate_delete(path, project_id)
self.assertEquals(self.srmock.status, falcon.HTTP_204)
# Get non-existent queue
self.simulate_get(path, project_id)
self.assertEquals(self.srmock.status, falcon.HTTP_404)
# Get non-existent queue
self.simulate_get(path, project_id)
self.assertEquals(self.srmock.status, falcon.HTTP_404)
# Get non-existent stats
self.simulate_get(path + '/stats', project_id)
self.assertEquals(self.srmock.status, falcon.HTTP_404)
# Get non-existent stats
self.simulate_get(path + '/stats', project_id)
self.assertEquals(self.srmock.status, falcon.HTTP_404)
# Get non-existent metadata
self.simulate_get(path + '/metadata', project_id)
self.assertEquals(self.srmock.status, falcon.HTTP_404)
# Get non-existent metadata
self.simulate_get(path + '/metadata', project_id)
self.assertEquals(self.srmock.status, falcon.HTTP_404)
def test_name_restrictions(self):
self.simulate_put('/v1/queues/Nice-Boat_2')
@ -104,13 +106,14 @@ class QueueLifecycleBaseTest(base.TestBase):
self.simulate_put('/v1/queues/fizbat/metadata', body='')
self.assertEquals(self.srmock.status, falcon.HTTP_400)
def test_bad_metadata(self):
@ddt.data('{', '[]', '.', ' ', '')
def test_bad_metadata(self, document):
self.simulate_put('/v1/queues/fizbat', '7e55e1a7e')
self.assertEquals(self.srmock.status, falcon.HTTP_201)
for document in ('{', '[]', '.', ' ', ''):
self.simulate_put('/v1/queues/fizbat/metadata', '7e55e1a7e',
body=document)
self.assertEquals(self.srmock.status, falcon.HTTP_400)
self.simulate_put('/v1/queues/fizbat/metadata', '7e55e1a7e',
body=document)
self.assertEquals(self.srmock.status, falcon.HTTP_400)
def test_too_much_metadata(self):
self.simulate_put('/v1/queues/fizbat', '7e55e1a7e')

View File

@ -3,6 +3,7 @@ mock
distribute>=0.6.24
# Unit testing
ddt
discover
fixtures
python-subunit