
This library can be used in novaclient, keystoneclient, glanceclient, and other client projects. The library contains common code and uses python-requests for HTTP communication. Features: * reissue authentication request for expired tokens; * pluggable authentication; * rich exceptions hierarchy; * utils for building CLI tools. Partially implements: blueprint common-client-library Change-Id: I82df865d52f32ce47dde6a09a84d3d917fd77918
137 lines
4.4 KiB
Python
137 lines
4.4 KiB
Python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
|
|
# Copyright 2012 OpenStack Foundation
|
|
# All Rights Reserved.
|
|
#
|
|
# 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 mock
|
|
import requests
|
|
|
|
from marconiclient.common.apiclient.auth import endpoint
|
|
from marconiclient.common.apiclient import client
|
|
from marconiclient.common.apiclient import exceptions
|
|
|
|
from tests import utils
|
|
|
|
|
|
class TestClient(client.BaseClient):
|
|
service_type = "test"
|
|
|
|
|
|
class FakeAuthPlugin(endpoint.EndpointTokenAuthPlugin):
|
|
auth_system = "fake"
|
|
attempt = 0
|
|
|
|
def authenticate(self, http_client):
|
|
http_client.token = "token-%s" % self.attempt
|
|
http_client.endpoint = "/endpoint-%s" % self.attempt
|
|
self.attempt = self.attempt + 1
|
|
|
|
|
|
class ClientTest(utils.BaseTestCase):
|
|
|
|
def test_client_with_timeout(self):
|
|
http_client = client.HttpClient(None, timeout=2)
|
|
self.assertEqual(http_client.timeout, 2)
|
|
mock_request = mock.Mock()
|
|
mock_request.return_value = requests.Response()
|
|
mock_request.return_value.status_code = 200
|
|
with mock.patch("requests.Session.request", mock_request):
|
|
http_client.request("GET", "/", json={"1": "2"})
|
|
requests.Session.request.assert_called_with(
|
|
"GET",
|
|
"/",
|
|
timeout=2,
|
|
headers=mock.ANY,
|
|
verify=mock.ANY,
|
|
data=mock.ANY)
|
|
|
|
def test_concat_url(self):
|
|
self.assertEqual(client.HttpClient.concat_url("/a", "/b"), "/a/b")
|
|
self.assertEqual(client.HttpClient.concat_url("/a", "b"), "/a/b")
|
|
self.assertEqual(client.HttpClient.concat_url("/a/", "/b"), "/a/b")
|
|
|
|
def test_client_request(self):
|
|
http_client = client.HttpClient(FakeAuthPlugin())
|
|
mock_request = mock.Mock()
|
|
mock_request.return_value = requests.Response()
|
|
mock_request.return_value.status_code = 200
|
|
with mock.patch("requests.Session.request", mock_request):
|
|
http_client.client_request(
|
|
TestClient(http_client), "GET", "/resource", json={"1": "2"})
|
|
requests.Session.request.assert_called_with(
|
|
"GET",
|
|
"/endpoint-0/resource",
|
|
headers={
|
|
"User-Agent": http_client.user_agent,
|
|
"Content-Type": "application/json",
|
|
"X-Auth-Token": "token-0"
|
|
},
|
|
data='{"1": "2"}',
|
|
verify=True)
|
|
|
|
def test_client_request_reissue(self):
|
|
reject_token = None
|
|
|
|
def fake_request(method, url, **kwargs):
|
|
if kwargs["headers"]["X-Auth-Token"] == reject_token:
|
|
raise exceptions.Unauthorized(method=method, url=url)
|
|
return "%s %s" % (method, url)
|
|
|
|
http_client = client.HttpClient(FakeAuthPlugin())
|
|
test_client = TestClient(http_client)
|
|
http_client.request = fake_request
|
|
|
|
self.assertEqual(
|
|
http_client.client_request(
|
|
test_client, "GET", "/resource"),
|
|
"GET /endpoint-0/resource")
|
|
reject_token = "token-0"
|
|
self.assertEqual(
|
|
http_client.client_request(
|
|
test_client, "GET", "/resource"),
|
|
"GET /endpoint-1/resource")
|
|
|
|
|
|
class FakeClient1(object):
|
|
pass
|
|
|
|
|
|
class FakeClient21(object):
|
|
pass
|
|
|
|
|
|
class GetClientClassTestCase(utils.BaseTestCase):
|
|
version_map = {
|
|
"1": "%s.FakeClient1" % __name__,
|
|
"2.1": "%s.FakeClient21" % __name__,
|
|
}
|
|
|
|
def test_get_int(self):
|
|
self.assertEqual(
|
|
client.BaseClient.get_class("fake", 1, self.version_map),
|
|
FakeClient1)
|
|
|
|
def test_get_str(self):
|
|
self.assertEqual(
|
|
client.BaseClient.get_class("fake", "2.1", self.version_map),
|
|
FakeClient21)
|
|
|
|
def test_unsupported_version(self):
|
|
self.assertRaises(
|
|
exceptions.UnsupportedVersion,
|
|
client.BaseClient.get_class,
|
|
"fake", "7", self.version_map)
|