~ubuntu-branches/ubuntu/trusty/python-keystoneclient/trusty-proposed

« back to all changes in this revision

Viewing changes to tests/test_http.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short, Adam Gandelman, Chuck Short
  • Date: 2013-11-14 10:51:32 UTC
  • mfrom: (1.1.23)
  • Revision ID: package-import@ubuntu.com-20131114105132-p1o428l7fclasv9e
Tags: 1:0.4.1-0ubuntu1
[ Adam Gandelman ]
* debian/patches: Refreshed.
* debian/patches/use-mox-dependency.patch: Use mox instead of mox3
  dependency.

[ Chuck Short ]
* New upstream release.
* debian/control:
  - open icehouse release.
  - Dropped python-d2to1 and python-httplib2 dependency.
* debian/patches/skip-tests-ubuntu.patch: Dropped no longer needed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
 
 
3
 
# Copyright 2013 OpenStack LLC
4
 
#
5
 
# Licensed under the Apache License, Version 2.0 (the "License"); you may
6
 
# not use this file except in compliance with the License. You may obtain
7
 
# a copy of the License at
8
 
#
9
 
#      http://www.apache.org/licenses/LICENSE-2.0
10
 
#
11
 
# Unless required by applicable law or agreed to in writing, software
12
 
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13
 
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14
 
# License for the specific language governing permissions and limitations
15
 
# under the License.
16
 
 
17
 
import json
18
 
import mock
19
 
 
20
 
try:
21
 
    import httpretty
22
 
except ImportError:
23
 
    pass
24
 
import requests
25
 
import testtools
26
 
from testtools import matchers
27
 
 
28
 
from keystoneclient import exceptions
29
 
from keystoneclient import httpclient
30
 
from tests import utils
31
 
 
32
 
 
33
 
FAKE_RESPONSE = utils.TestResponse({
34
 
    "status_code": 200,
35
 
    "text": '{"hi": "there"}',
36
 
})
37
 
MOCK_REQUEST = mock.Mock(return_value=(FAKE_RESPONSE))
38
 
 
39
 
 
40
 
def get_client():
41
 
    cl = httpclient.HTTPClient(username="username", password="password",
42
 
                               tenant_id="tenant", auth_url="auth_test")
43
 
    return cl
44
 
 
45
 
 
46
 
def get_authed_client():
47
 
    cl = get_client()
48
 
    cl.management_url = "http://127.0.0.1:5000"
49
 
    cl.auth_token = "token"
50
 
    return cl
51
 
 
52
 
 
53
 
class FakeLog(object):
54
 
    def __init__(self):
55
 
        self.warn_log = str()
56
 
        self.debug_log = str()
57
 
 
58
 
    def warn(self, msg=None, *args, **kwargs):
59
 
        self.warn_log = "%s\n%s" % (self.warn_log, (msg % args))
60
 
 
61
 
    def debug(self, msg=None, *args, **kwargs):
62
 
        self.debug_log = "%s\n%s" % (self.debug_log, (msg % args))
63
 
 
64
 
 
65
 
class ClientTest(utils.TestCase):
66
 
 
67
 
    def test_unauthorized_client_requests(self):
68
 
        cl = get_client()
69
 
        self.assertRaises(exceptions.AuthorizationFailure, cl.get, '/hi')
70
 
        self.assertRaises(exceptions.AuthorizationFailure, cl.post, '/hi')
71
 
        self.assertRaises(exceptions.AuthorizationFailure, cl.put, '/hi')
72
 
        self.assertRaises(exceptions.AuthorizationFailure, cl.delete, '/hi')
73
 
 
74
 
    def test_get(self):
75
 
        cl = get_authed_client()
76
 
 
77
 
        with mock.patch.object(requests, "request", MOCK_REQUEST):
78
 
            with mock.patch('time.time', mock.Mock(return_value=1234)):
79
 
                resp, body = cl.get("/hi")
80
 
                headers = {"X-Auth-Token": "token",
81
 
                           "User-Agent": httpclient.USER_AGENT}
82
 
                MOCK_REQUEST.assert_called_with(
83
 
                    "GET",
84
 
                    "http://127.0.0.1:5000/hi",
85
 
                    headers=headers,
86
 
                    **self.TEST_REQUEST_BASE)
87
 
                # Automatic JSON parsing
88
 
                self.assertEqual(body, {"hi": "there"})
89
 
 
90
 
    def test_get_error_with_plaintext_resp(self):
91
 
        cl = get_authed_client()
92
 
 
93
 
        fake_err_response = utils.TestResponse({
94
 
            "status_code": 400,
95
 
            "text": 'Some evil plaintext string',
96
 
        })
97
 
        err_MOCK_REQUEST = mock.Mock(return_value=(fake_err_response))
98
 
 
99
 
        with mock.patch.object(requests, "request", err_MOCK_REQUEST):
100
 
            self.assertRaises(exceptions.BadRequest, cl.get, '/hi')
101
 
 
102
 
    def test_get_error_with_json_resp(self):
103
 
        cl = get_authed_client()
104
 
        err_response = {
105
 
            "error": {
106
 
                "code": 400,
107
 
                "title": "Error title",
108
 
                "message": "Error message string"
109
 
            }
110
 
        }
111
 
        fake_err_response = utils.TestResponse({
112
 
            "status_code": 400,
113
 
            "text": json.dumps(err_response)
114
 
        })
115
 
        err_MOCK_REQUEST = mock.Mock(return_value=(fake_err_response))
116
 
 
117
 
        with mock.patch.object(requests, "request", err_MOCK_REQUEST):
118
 
            exc_raised = False
119
 
            try:
120
 
                cl.get('/hi')
121
 
            except exceptions.BadRequest as exc:
122
 
                exc_raised = True
123
 
                self.assertEqual(exc.message, "Error message string")
124
 
            self.assertTrue(exc_raised, 'Exception not raised.')
125
 
 
126
 
    def test_post(self):
127
 
        cl = get_authed_client()
128
 
 
129
 
        with mock.patch.object(requests, "request", MOCK_REQUEST):
130
 
            cl.post("/hi", body=[1, 2, 3])
131
 
            headers = {
132
 
                "X-Auth-Token": "token",
133
 
                "Content-Type": "application/json",
134
 
                "User-Agent": httpclient.USER_AGENT
135
 
            }
136
 
            MOCK_REQUEST.assert_called_with(
137
 
                "POST",
138
 
                "http://127.0.0.1:5000/hi",
139
 
                headers=headers,
140
 
                data='[1, 2, 3]',
141
 
                **self.TEST_REQUEST_BASE)
142
 
 
143
 
    def test_forwarded_for(self):
144
 
        ORIGINAL_IP = "10.100.100.1"
145
 
        cl = httpclient.HTTPClient(username="username", password="password",
146
 
                                   tenant_id="tenant", auth_url="auth_test",
147
 
                                   original_ip=ORIGINAL_IP)
148
 
 
149
 
        with mock.patch.object(requests, "request", MOCK_REQUEST):
150
 
            res = cl.request('/', 'GET')
151
 
 
152
 
            args, kwargs = MOCK_REQUEST.call_args
153
 
            self.assertIn(
154
 
                ('Forwarded', "for=%s;by=%s" % (ORIGINAL_IP,
155
 
                                                httpclient.USER_AGENT)),
156
 
                kwargs['headers'].items())
157
 
 
158
 
    def test_client_deprecated(self):
159
 
        # Can resolve symbols from the keystoneclient.client module.
160
 
        # keystoneclient.client was deprecated and renamed to
161
 
        # keystoneclient.httpclient. This tests that keystoneclient.client
162
 
        # can still be used.
163
 
 
164
 
        from keystoneclient import client
165
 
 
166
 
        # These statements will raise an AttributeError if the symbol isn't
167
 
        # defined in the module.
168
 
 
169
 
        client.HTTPClient
170
 
 
171
 
 
172
 
class BasicRequestTests(testtools.TestCase):
173
 
 
174
 
    url = 'http://keystone.test.com/'
175
 
 
176
 
    def setUp(self):
177
 
        super(BasicRequestTests, self).setUp()
178
 
        self.logger = FakeLog()
179
 
        try:
180
 
            httpretty.enable()
181
 
        except:
182
 
            self.skipTest('httppretty is not installed')
183
 
 
184
 
    def tearDown(self):
185
 
        httpretty.disable()
186
 
        super(BasicRequestTests, self).tearDown()
187
 
 
188
 
    def request(self, method='GET', response='Test Response', status=200,
189
 
                url=None, **kwargs):
190
 
        if not url:
191
 
            url = self.url
192
 
 
193
 
        httpretty.register_uri(method, url, body=response, status=status)
194
 
 
195
 
        return httpclient.request(url, method, debug=True,
196
 
                                  logger=self.logger, **kwargs)
197
 
 
198
 
    @property
199
 
    def last_request(self):
200
 
        return httpretty.httpretty.last_request
201
 
 
202
 
    def test_basic_params(self):
203
 
        method = 'GET'
204
 
        response = 'Test Response'
205
 
        status = 200
206
 
 
207
 
        resp = self.request(method=method, status=status, response=response)
208
 
 
209
 
        self.assertEqual(self.last_request.method, method)
210
 
 
211
 
        self.assertThat(self.logger.debug_log, matchers.Contains('curl'))
212
 
        self.assertThat(self.logger.debug_log, matchers.Contains('-X %s' %
213
 
                                                                 method))
214
 
        self.assertThat(self.logger.debug_log, matchers.Contains(self.url))
215
 
 
216
 
        self.assertThat(self.logger.debug_log, matchers.Contains(str(status)))
217
 
        self.assertThat(self.logger.debug_log, matchers.Contains(response))
218
 
 
219
 
    def test_headers(self):
220
 
        headers = {'key': 'val', 'test': 'other'}
221
 
 
222
 
        self.request(headers=headers)
223
 
 
224
 
        for k, v in headers.iteritems():
225
 
            self.assertEqual(self.last_request.headers[k], v)
226
 
 
227
 
        for header in headers.iteritems():
228
 
            self.assertThat(self.logger.debug_log,
229
 
                            matchers.Contains('-H "%s: %s"' % header))
230
 
 
231
 
    def test_body(self):
232
 
        data = "BODY DATA"
233
 
        resp = self.request(response=data)
234
 
        self.assertThat(self.logger.debug_log, matchers.Contains('BODY:'))
235
 
        self.assertThat(self.logger.debug_log, matchers.Contains(data))