Move request_and_transport to the Client

This patch moves the `_get_transport` and `request_and_transport` method
to the client. Both method are useful for other resources like Message,
for example.

This patch also moves the is_functional logic to the BaseTest class and
splits unittests from functional tests.

Partially-Implements: python-marconiclient-v1
Change-Id: Iaf56c234291b355c98817feee5644a5dd07c0b7f
This commit is contained in:
Flavio Percoco 2013-12-09 23:16:18 +01:00
parent d215aaaa55
commit b153951e57
9 changed files with 79 additions and 69 deletions

View File

@ -17,6 +17,7 @@ import uuid
from marconiclient.queues.v1 import queues
from marconiclient import transport
from marconiclient.transport import request
class Client(object):
@ -44,6 +45,34 @@ class Client(object):
self.client_uuid = self.conf.get('client_uuid',
uuid.uuid4().hex)
def _get_transport(self, request):
"""Gets a transport and caches its instance
This method gets a transport instance based on
the request's endpoint and caches that for later
use. The transport instance is invalidated whenever
a session expires.
:param request: The request to use to load the
transport instance.
:type request: `transport.request.Request`
"""
trans = transport.get_transport_for(request,
options=self.conf)
return (trans or self.transport)
def _request_and_transport(self):
api = 'queues.v' + str(self.api_version)
req = request.prepare_request(self.auth_opts,
endpoint=self.api_url,
api=api)
req.headers['Client-ID'] = self.client_uuid
trans = self._get_transport(req)
return req, trans
def transport(self):
"""Gets a transport based the api url and version."""
return transport.get_transport_for(self.url,

View File

@ -14,8 +14,6 @@
# limitations under the License.
from marconiclient.queues.v1 import core
from marconiclient import transport
from marconiclient.transport import request
class Queue(object):
@ -30,37 +28,9 @@ class Queue(object):
if auto_create:
self.ensure_exists()
def _get_transport(self, request):
"""Gets a transport and caches its instance
This method gets a transport instance based on
the request's endpoint and caches that for later
use. The transport instance is invalidated whenever
a session expires.
:param request: The request to use to load the
transport instance.
:type request: `transport.request.Request`
"""
trans = transport.get_transport_for(request,
options=self.client.conf)
return (trans or self.client.transport)
def _request_and_transport(self):
api = 'queues.v' + str(self.client.api_version)
req = request.prepare_request(self.client.auth_opts,
endpoint=self.client.api_url,
api=api)
req.headers['Client-ID'] = self.client.client_uuid
trans = self._get_transport(req)
return req, trans
def exists(self):
"""Checks if the queue exists."""
req, trans = self._request_and_transport()
req, trans = self.client._request_and_transport()
return core.queue_exists(trans, req, self._id)
def ensure_exists(self):
@ -70,7 +40,7 @@ class Queue(object):
the queue could've been deleted
right after it was called.
"""
req, trans = self._request_and_transport()
req, trans = self.client._request_and_transport()
core.queue_create(trans, req, self._id)
def metadata(self, new_meta=None, force_reload=False):
@ -88,7 +58,7 @@ class Queue(object):
:returns: The queue metadata.
"""
req, trans = self._request_and_transport()
req, trans = self.client._request_and_transport()
if new_meta:
core.queue_set_metadata(trans, req, self._id, new_meta)
@ -102,7 +72,7 @@ class Queue(object):
return self._metadata
def delete(self):
req, trans = self._request_and_transport()
req, trans = self.client._request_and_transport()
core.queue_delete(trans, req, self._id)
# Messages API
@ -119,7 +89,7 @@ class Queue(object):
if not isinstance(messages, list):
messages = [messages]
req, trans = self._request_and_transport()
req, trans = self.client._request_and_transport()
# TODO(flaper87): Return a list of messages
return core.message_post(trans, req,
@ -134,7 +104,7 @@ class Queue(object):
:returns: A message
:rtype: `dict`
"""
req, trans = self._request_and_transport()
req, trans = self.client._request_and_transport()
return core.message_get(trans, req, self._id,
message_id)
@ -158,7 +128,7 @@ class Queue(object):
:returns: List of messages
:rtype: `list`
"""
req, trans = self._request_and_transport()
req, trans = self.client._request_and_transport()
# TODO(flaper87): Return a MessageIterator.
# This iterator should handle limits, pagination

View File

@ -13,12 +13,19 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import fixtures
import testtools
_RUN_FUNCTIONAL = os.environ.get('MARCONICLIENT_TEST_FUNCTIONAL', False)
class TestBase(testtools.TestCase):
transport_cls = None
is_functional = False
def setUp(self):
super(TestBase, self).setUp()
@ -30,6 +37,9 @@ class TestBase(testtools.TestCase):
stderr = self.useFixture(fixtures.StringStream('stderr')).stream
self.useFixture(fixtures.MonkeyPatch('sys.stderr', stderr))
if not _RUN_FUNCTIONAL and self.is_functional:
self.skipTest('Functional tests disabled')
def config(self, group=None, **kw):
"""Override some configuration values.

View File

@ -13,23 +13,16 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import json
import mock
import testtools
from marconiclient.queues.v1 import client
from marconiclient.tests import base
from marconiclient.transport import response
_RUN_FUNCTIONAL = os.environ.get('MARCONICLIENT_TEST_FUNCTIONAL', False)
class QueuesV1QueueTestBase(base.TestBase):
transport_cls = None
# NOTE(flaper87): These class attributes
# are intended for functional tests only
# and will be replaced with something
@ -45,13 +38,16 @@ class QueuesV1QueueTestBase(base.TestBase):
self.client = client.Client(self.url, self.version,
self.conf)
mocked_transport = mock.Mock(return_value=self.transport)
self.client._get_transport = mocked_transport
# NOTE(flaper87): Nasty monkeypatch, lets use
# the dummy transport here.
#setattr(self.client, 'transport', self.transport)
self.queue = self.client.queue(1, auto_create=False)
self.queue._get_transport = mock.Mock(return_value=self.transport)
self.is_functional = _RUN_FUNCTIONAL
class QueuesV1QueueUnitTest(QueuesV1QueueTestBase):
def test_queue_metadata(self):
test_metadata = {'type': 'Bank Accounts'}
@ -199,17 +195,13 @@ class QueuesV1QueueTestBase(base.TestBase):
# doesn't crash.
class QueuesV1QueueFuncMixin(object):
class QueuesV1QueueFunctionalTest(QueuesV1QueueTestBase):
@testtools.skipUnless(_RUN_FUNCTIONAL,
'Functional tests disabled')
def test_queue_create_functional(self):
queue = self.client.queue("nonono")
queue._get_transport = mock.Mock(return_value=self.transport)
self.assertTrue(queue.exists())
@testtools.skipUnless(_RUN_FUNCTIONAL,
'Functional tests disabled')
def test_queue_delete_functional(self):
queue = self.client.queue("nonono")
queue._get_transport = mock.Mock(return_value=self.transport)
@ -217,15 +209,11 @@ class QueuesV1QueueFuncMixin(object):
queue.delete()
self.assertFalse(queue.exists())
@testtools.skipUnless(_RUN_FUNCTIONAL,
'Functional tests disabled')
def test_queue_exists_functional(self):
queue = self.client.queue("404", auto_create=False)
queue._get_transport = mock.Mock(return_value=self.transport)
self.assertFalse(queue.exists())
@testtools.skipUnless(_RUN_FUNCTIONAL,
'Functional tests disabled')
def test_queue_metadata_functional(self):
test_metadata = {'type': 'Bank Accounts'}
queue = self.client.queue("meta-test")
@ -236,8 +224,6 @@ class QueuesV1QueueFuncMixin(object):
metadata = queue.metadata()
self.assertEqual(metadata, test_metadata)
@testtools.skipUnless(_RUN_FUNCTIONAL,
'Functional tests disabled')
def test_queue_metadata_reload_functional(self):
test_metadata = {'type': 'Bank Accounts'}
queue = self.client.queue("meta-test")
@ -249,8 +235,6 @@ class QueuesV1QueueFuncMixin(object):
metadata = queue.metadata(force_reload=True)
self.assertEqual(metadata, test_metadata)
@testtools.skipUnless(_RUN_FUNCTIONAL,
'Functional tests disabled')
def test_message_post_functional(self):
messages = [
{'ttl': 60, 'body': 'Post It!'},
@ -264,8 +248,6 @@ class QueuesV1QueueFuncMixin(object):
self.assertIn('resources', result)
self.assertEqual(len(result['resources']), 3)
@testtools.skipUnless(_RUN_FUNCTIONAL,
'Functional tests disabled')
def test_message_list_functional(self):
queue = self.client.queue("test_queue")
queue._get_transport = mock.Mock(return_value=self.transport)
@ -277,8 +259,6 @@ class QueuesV1QueueFuncMixin(object):
self.assertTrue(isinstance(messages, list))
self.assertGreaterEqual(len(messages), 0)
@testtools.skipUnless(_RUN_FUNCTIONAL,
'Functional tests disabled')
def test_message_list_echo_functional(self):
queue = self.client.queue("test_queue")
queue._get_transport = mock.Mock(return_value=self.transport)
@ -293,8 +273,6 @@ class QueuesV1QueueFuncMixin(object):
self.assertTrue(isinstance(messages, list))
self.assertGreaterEqual(len(messages), 3)
@testtools.skipUnless(_RUN_FUNCTIONAL,
'Functional tests disabled')
def test_message_get_functional(self):
queue = self.client.queue("test_queue")
queue._get_transport = mock.Mock(return_value=self.transport)
@ -311,8 +289,6 @@ class QueuesV1QueueFuncMixin(object):
self.assertTrue(isinstance(message, dict))
self.assertEqual(message['href'], res[0])
@testtools.skipUnless(_RUN_FUNCTIONAL,
'Functional tests disabled')
def test_message_get_many_functional(self):
queue = self.client.queue("test_queue")
queue._get_transport = mock.Mock(return_value=self.transport)

View File

View File

View File

View File

@ -0,0 +1,26 @@
# 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.
from marconiclient.tests.queues import queues
from marconiclient.transport import http
class QueuesV1QueueHttpFunctionalTest(queues.QueuesV1QueueFunctionalTest):
is_functional = True
transport_cls = http.HttpTransport
url = 'http://127.0.0.1:8888/v1'
version = 1

View File

@ -24,8 +24,7 @@ class QueuesV1QueueDummyTransportTest(queues.QueuesV1QueueTestBase):
transport_cls = dummy.DummyTransport
class QueuesV1QueueHttpTransportTest(queues.QueuesV1QueueTestBase,
queues.QueuesV1QueueFuncMixin):
class QueuesV1QueueHttpUnitTest(queues.QueuesV1QueueUnitTest):
transport_cls = http.HttpTransport
url = 'http://127.0.0.1:8888/v1'