Replace mox in tests with requests-mock
requests-mock is a tool specifically designed for mocking responses from the requests library. Use that instead of handling mox and mock ourselves. Change-Id: Ifd855b8d6c1b401e29ac210593c48d2da87a571b
This commit is contained in:
parent
b3d2c636ec
commit
02b1a05226
@ -5,9 +5,10 @@ hacking>=0.8.0,<0.9
|
|||||||
|
|
||||||
coverage>=3.6
|
coverage>=3.6
|
||||||
discover
|
discover
|
||||||
mox3>=0.7.0
|
|
||||||
mock>=1.0
|
mock>=1.0
|
||||||
oslosphinx>=2.2.0 # Apache-2.0
|
oslosphinx>=2.2.0 # Apache-2.0
|
||||||
sphinx>=1.1.2,!=1.2.0,!=1.3b1,<1.3
|
sphinx>=1.1.2,!=1.2.0,!=1.3b1,<1.3
|
||||||
testrepository>=0.0.18
|
testrepository>=0.0.18
|
||||||
testtools>=0.9.36,!=1.2.0
|
testtools>=0.9.36,!=1.2.0
|
||||||
|
fixtures>=0.3.14
|
||||||
|
requests-mock>=0.6.0 # Apache-2.0
|
||||||
|
@ -14,9 +14,8 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
import json
|
import json
|
||||||
|
|
||||||
import mock
|
|
||||||
from mox3 import mox
|
|
||||||
import requests
|
import requests
|
||||||
|
from requests_mock.contrib import fixture
|
||||||
import six
|
import six
|
||||||
from six.moves.urllib import parse
|
from six.moves.urllib import parse
|
||||||
import testtools
|
import testtools
|
||||||
@ -33,16 +32,11 @@ class TestClient(testtools.TestCase):
|
|||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestClient, self).setUp()
|
super(TestClient, self).setUp()
|
||||||
self.mock = mox.Mox()
|
self.mock = self.useFixture(fixture.Fixture())
|
||||||
self.mock.StubOutWithMock(requests.Session, 'request')
|
|
||||||
|
|
||||||
self.endpoint = 'http://example.com:9292'
|
self.endpoint = 'http://example.com:9292'
|
||||||
self.client = http.HTTPClient(self.endpoint, token=u'abc123')
|
self.client = http.HTTPClient(self.endpoint, token=u'abc123')
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
super(TestClient, self).tearDown()
|
|
||||||
self.mock.UnsetStubs()
|
|
||||||
|
|
||||||
def test_identity_headers_and_token(self):
|
def test_identity_headers_and_token(self):
|
||||||
identity_headers = {
|
identity_headers = {
|
||||||
'X-Auth-Token': 'auth_token',
|
'X-Auth-Token': 'auth_token',
|
||||||
@ -97,25 +91,22 @@ class TestClient(testtools.TestCase):
|
|||||||
# when creating the http client, the session headers don't contain
|
# when creating the http client, the session headers don't contain
|
||||||
# the X-Auth-Token key.
|
# the X-Auth-Token key.
|
||||||
identity_headers = {
|
identity_headers = {
|
||||||
b'X-User-Id': b'user',
|
'X-User-Id': b'user',
|
||||||
b'X-Tenant-Id': b'tenant',
|
'X-Tenant-Id': b'tenant',
|
||||||
b'X-Roles': b'roles',
|
'X-Roles': b'roles',
|
||||||
b'X-Identity-Status': b'Confirmed',
|
'X-Identity-Status': b'Confirmed',
|
||||||
b'X-Service-Catalog': b'service_catalog',
|
'X-Service-Catalog': b'service_catalog',
|
||||||
}
|
}
|
||||||
kwargs = {'identity_headers': identity_headers}
|
kwargs = {'identity_headers': identity_headers}
|
||||||
http_client = http.HTTPClient(self.endpoint, **kwargs)
|
http_client = http.HTTPClient(self.endpoint, **kwargs)
|
||||||
|
|
||||||
def check_headers(*args, **kwargs):
|
path = '/v1/images/my-image'
|
||||||
headers = kwargs.get('headers')
|
self.mock.get(self.endpoint + path)
|
||||||
for k, v in six.iteritems(identity_headers):
|
http_client.get(path)
|
||||||
self.assertEqual(v, headers[k])
|
|
||||||
|
|
||||||
return utils.FakeResponse({}, six.StringIO('{}'))
|
headers = self.mock.last_request.headers
|
||||||
|
for k, v in six.iteritems(identity_headers):
|
||||||
with mock.patch.object(http_client.session, 'request') as mreq:
|
self.assertEqual(v, headers[k])
|
||||||
mreq.side_effect = check_headers
|
|
||||||
http_client.get('http://example.com:9292/v1/images/my-image')
|
|
||||||
|
|
||||||
def test_connection_refused(self):
|
def test_connection_refused(self):
|
||||||
"""
|
"""
|
||||||
@ -123,43 +114,27 @@ class TestClient(testtools.TestCase):
|
|||||||
And the error should list the host and port that refused the
|
And the error should list the host and port that refused the
|
||||||
connection
|
connection
|
||||||
"""
|
"""
|
||||||
requests.Session.request(
|
def cb(request, context):
|
||||||
mox.IgnoreArg(),
|
raise requests.exceptions.ConnectionError()
|
||||||
mox.IgnoreArg(),
|
|
||||||
data=mox.IgnoreArg(),
|
path = '/v1/images/detail?limit=20'
|
||||||
headers=mox.IgnoreArg(),
|
self.mock.get(self.endpoint + path, text=cb)
|
||||||
stream=mox.IgnoreArg(),
|
|
||||||
).AndRaise(requests.exceptions.ConnectionError())
|
comm_err = self.assertRaises(glanceclient.exc.CommunicationError,
|
||||||
self.mock.ReplayAll()
|
self.client.get,
|
||||||
try:
|
'/v1/images/detail?limit=20')
|
||||||
self.client.get('/v1/images/detail?limit=20')
|
|
||||||
#NOTE(alaski) We expect exc.CommunicationError to be raised
|
self.assertIn(self.endpoint, comm_err.message)
|
||||||
# so we should never reach this point. try/except is used here
|
|
||||||
# rather than assertRaises() so that we can check the body of
|
|
||||||
# the exception.
|
|
||||||
self.fail('An exception should have bypassed this line.')
|
|
||||||
except glanceclient.exc.CommunicationError as comm_err:
|
|
||||||
fail_msg = ("Exception message '%s' should contain '%s'" %
|
|
||||||
(comm_err.message, self.endpoint))
|
|
||||||
self.assertTrue(self.endpoint in comm_err.message, fail_msg)
|
|
||||||
|
|
||||||
def test_http_encoding(self):
|
def test_http_encoding(self):
|
||||||
# Lets fake the response
|
path = '/v1/images/detail'
|
||||||
# returned by requests
|
text = 'Ok'
|
||||||
response = 'Ok'
|
self.mock.get(self.endpoint + path, text=text,
|
||||||
headers = {"Content-Type": "text/plain"}
|
headers={"Content-Type": "text/plain"})
|
||||||
fake = utils.FakeResponse(headers, six.StringIO(response))
|
|
||||||
requests.Session.request(
|
|
||||||
mox.IgnoreArg(),
|
|
||||||
mox.IgnoreArg(),
|
|
||||||
data=mox.IgnoreArg(),
|
|
||||||
stream=mox.IgnoreArg(),
|
|
||||||
headers=mox.IgnoreArg()).AndReturn(fake)
|
|
||||||
self.mock.ReplayAll()
|
|
||||||
|
|
||||||
headers = {"test": u'ni\xf1o'}
|
headers = {"test": u'ni\xf1o'}
|
||||||
resp, body = self.client.get('/v1/images/detail', headers=headers)
|
resp, body = self.client.get(path, headers=headers)
|
||||||
self.assertEqual(fake, resp)
|
self.assertEqual(text, resp.text)
|
||||||
|
|
||||||
def test_headers_encoding(self):
|
def test_headers_encoding(self):
|
||||||
value = u'ni\xf1o'
|
value = u'ni\xf1o'
|
||||||
@ -171,18 +146,14 @@ class TestClient(testtools.TestCase):
|
|||||||
def test_raw_request(self):
|
def test_raw_request(self):
|
||||||
" Verify the path being used for HTTP requests reflects accurately. "
|
" Verify the path being used for HTTP requests reflects accurately. "
|
||||||
headers = {"Content-Type": "text/plain"}
|
headers = {"Content-Type": "text/plain"}
|
||||||
response = 'Ok'
|
text = 'Ok'
|
||||||
fake = utils.FakeResponse({}, six.StringIO(response))
|
path = '/v1/images/detail'
|
||||||
requests.Session.request(
|
|
||||||
mox.IgnoreArg(),
|
self.mock.get(self.endpoint + path, text=text, headers=headers)
|
||||||
mox.IgnoreArg(),
|
|
||||||
data=mox.IgnoreArg(),
|
|
||||||
stream=mox.IgnoreArg(),
|
|
||||||
headers=mox.IgnoreArg()).AndReturn(fake)
|
|
||||||
self.mock.ReplayAll()
|
|
||||||
|
|
||||||
resp, body = self.client.get('/v1/images/detail', headers=headers)
|
resp, body = self.client.get('/v1/images/detail', headers=headers)
|
||||||
self.assertEqual(fake, resp)
|
self.assertEqual(headers, resp.headers)
|
||||||
|
self.assertEqual(text, resp.text)
|
||||||
|
|
||||||
def test_parse_endpoint(self):
|
def test_parse_endpoint(self):
|
||||||
endpoint = 'http://example.com:9292'
|
endpoint = 'http://example.com:9292'
|
||||||
@ -199,76 +170,36 @@ class TestClient(testtools.TestCase):
|
|||||||
self.assertEqual(test_client.timeout, 600.0)
|
self.assertEqual(test_client.timeout, 600.0)
|
||||||
|
|
||||||
def test_http_chunked_request(self):
|
def test_http_chunked_request(self):
|
||||||
# Lets fake the response
|
text = "Ok"
|
||||||
# returned by requests
|
data = six.StringIO(text)
|
||||||
response = "Ok"
|
path = '/v1/images/'
|
||||||
data = six.StringIO(response)
|
self.mock.post(self.endpoint + path, text=text)
|
||||||
fake = utils.FakeResponse({}, data)
|
|
||||||
requests.Session.request(
|
|
||||||
mox.IgnoreArg(),
|
|
||||||
mox.IgnoreArg(),
|
|
||||||
stream=mox.IgnoreArg(),
|
|
||||||
data=mox.IsA(types.GeneratorType),
|
|
||||||
headers=mox.IgnoreArg()).AndReturn(fake)
|
|
||||||
self.mock.ReplayAll()
|
|
||||||
|
|
||||||
headers = {"test": u'chunked_request'}
|
headers = {"test": u'chunked_request'}
|
||||||
resp, body = self.client.post('/v1/images/',
|
resp, body = self.client.post(path, headers=headers, data=data)
|
||||||
headers=headers, data=data)
|
self.assertIsInstance(self.mock.last_request.body, types.GeneratorType)
|
||||||
self.assertEqual(fake, resp)
|
self.assertEqual(text, resp.text)
|
||||||
|
|
||||||
def test_http_json(self):
|
def test_http_json(self):
|
||||||
data = {"test": "json_request"}
|
data = {"test": "json_request"}
|
||||||
fake = utils.FakeResponse({}, b"OK")
|
path = '/v1/images'
|
||||||
|
text = 'OK'
|
||||||
def test_json(passed_data):
|
self.mock.post(self.endpoint + path, text=text)
|
||||||
"""
|
|
||||||
This function tests whether the data
|
|
||||||
being passed to request's method is
|
|
||||||
a valid json or not.
|
|
||||||
|
|
||||||
This function will be called by pymox
|
|
||||||
|
|
||||||
:params passed_data: The data being
|
|
||||||
passed to requests.Session.request.
|
|
||||||
"""
|
|
||||||
if not isinstance(passed_data, six.string_types):
|
|
||||||
return False
|
|
||||||
|
|
||||||
try:
|
|
||||||
passed_data = json.loads(passed_data)
|
|
||||||
return data == passed_data
|
|
||||||
except (TypeError, ValueError):
|
|
||||||
return False
|
|
||||||
|
|
||||||
requests.Session.request(
|
|
||||||
mox.IgnoreArg(),
|
|
||||||
mox.IgnoreArg(),
|
|
||||||
stream=mox.IgnoreArg(),
|
|
||||||
data=mox.Func(test_json),
|
|
||||||
headers=mox.IgnoreArg()).AndReturn(fake)
|
|
||||||
self.mock.ReplayAll()
|
|
||||||
|
|
||||||
headers = {"test": u'chunked_request'}
|
headers = {"test": u'chunked_request'}
|
||||||
resp, body = self.client.post('/v1/images/',
|
resp, body = self.client.post(path, headers=headers, data=data)
|
||||||
headers=headers,
|
|
||||||
data=data)
|
self.assertEqual(text, resp.text)
|
||||||
self.assertEqual(fake, resp)
|
self.assertIsInstance(self.mock.last_request.body, six.string_types)
|
||||||
|
self.assertEqual(data, json.loads(self.mock.last_request.body))
|
||||||
|
|
||||||
def test_http_chunked_response(self):
|
def test_http_chunked_response(self):
|
||||||
headers = {"Content-Type": "application/octet-stream"}
|
|
||||||
data = "TEST"
|
data = "TEST"
|
||||||
fake = utils.FakeResponse(headers, six.StringIO(data))
|
path = '/v1/images/'
|
||||||
|
self.mock.get(self.endpoint + path, body=six.StringIO(data),
|
||||||
|
headers={"Content-Type": "application/octet-stream"})
|
||||||
|
|
||||||
requests.Session.request(
|
resp, body = self.client.get(path)
|
||||||
mox.IgnoreArg(),
|
|
||||||
mox.IgnoreArg(),
|
|
||||||
stream=mox.IgnoreArg(),
|
|
||||||
data=mox.IgnoreArg(),
|
|
||||||
headers=mox.IgnoreArg()).AndReturn(fake)
|
|
||||||
self.mock.ReplayAll()
|
|
||||||
headers = {"test": u'chunked_request'}
|
|
||||||
resp, body = self.client.get('/v1/images/')
|
|
||||||
self.assertTrue(isinstance(body, types.GeneratorType))
|
self.assertTrue(isinstance(body, types.GeneratorType))
|
||||||
self.assertEqual([data], list(body))
|
self.assertEqual([data], list(body))
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user