Statistics
| Branch: | Tag: | Revision:

root / kamaki / clients / test.py @ c4aefeaf

History | View | Annotate | Download (20 kB)

1 85898ca4 Stavros Sachtouris
# Copyright 2013 GRNET S.A. All rights reserved.
2 c1004a00 Stavros Sachtouris
#
3 c1004a00 Stavros Sachtouris
# Redistribution and use in source and binary forms, with or
4 c1004a00 Stavros Sachtouris
# without modification, are permitted provided that the following
5 c1004a00 Stavros Sachtouris
# conditions are met:
6 c1004a00 Stavros Sachtouris
#
7 c1004a00 Stavros Sachtouris
#   1. Redistributions of source code must retain the above
8 c1004a00 Stavros Sachtouris
#      copyright notice, this list of conditions and the following
9 c1004a00 Stavros Sachtouris
#      disclaimer.
10 c1004a00 Stavros Sachtouris
#
11 c1004a00 Stavros Sachtouris
#   2. Redistributions in binary form must reproduce the above
12 c1004a00 Stavros Sachtouris
#      copyright notice, this list of conditions and the following
13 c1004a00 Stavros Sachtouris
#      disclaimer in the documentation and/or other materials
14 c1004a00 Stavros Sachtouris
#      provided with the distribution.
15 c1004a00 Stavros Sachtouris
#
16 c1004a00 Stavros Sachtouris
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 c1004a00 Stavros Sachtouris
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 c1004a00 Stavros Sachtouris
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 c1004a00 Stavros Sachtouris
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 c1004a00 Stavros Sachtouris
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 c1004a00 Stavros Sachtouris
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 c1004a00 Stavros Sachtouris
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 c1004a00 Stavros Sachtouris
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 c1004a00 Stavros Sachtouris
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 c1004a00 Stavros Sachtouris
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 c1004a00 Stavros Sachtouris
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 c1004a00 Stavros Sachtouris
# POSSIBILITY OF SUCH DAMAGE.
28 c1004a00 Stavros Sachtouris
#
29 c1004a00 Stavros Sachtouris
# The views and conclusions contained in the software and
30 c1004a00 Stavros Sachtouris
# documentation are those of the authors and should not be
31 c1004a00 Stavros Sachtouris
# interpreted as representing official policies, either expressed
32 c1004a00 Stavros Sachtouris
# or implied, of GRNET S.A.
33 c1004a00 Stavros Sachtouris
34 97baa5c3 Stavros Sachtouris
from mock import patch, call
35 db113224 Stavros Sachtouris
from unittest import makeSuite, TestSuite, TextTestRunner, TestCase
36 db113224 Stavros Sachtouris
from time import sleep
37 85898ca4 Stavros Sachtouris
from inspect import getmembers, isclass
38 97baa5c3 Stavros Sachtouris
from itertools import product
39 9c6c3d69 Stavros Sachtouris
from random import randint
40 c1004a00 Stavros Sachtouris
41 480585cd Stavros Sachtouris
from kamaki.clients.utils.test import Utils
42 3c50df2e Stavros Sachtouris
from kamaki.clients.astakos.test import AstakosClient
43 3c50df2e Stavros Sachtouris
from kamaki.clients.compute.test import ComputeClient, ComputeRestClient
44 3c50df2e Stavros Sachtouris
from kamaki.clients.cyclades.test import CycladesClient
45 3c50df2e Stavros Sachtouris
from kamaki.clients.cyclades.test import CycladesRestClient
46 3c50df2e Stavros Sachtouris
from kamaki.clients.image.test import ImageClient
47 3c50df2e Stavros Sachtouris
from kamaki.clients.storage.test import StorageClient
48 3c50df2e Stavros Sachtouris
from kamaki.clients.pithos.test import PithosClient, PithosRestClient
49 c1004a00 Stavros Sachtouris
50 c1004a00 Stavros Sachtouris
51 f4de4c91 Stavros Sachtouris
class ClientError(TestCase):
52 f4de4c91 Stavros Sachtouris
53 f4de4c91 Stavros Sachtouris
    def test___init__(self):
54 f4de4c91 Stavros Sachtouris
        from kamaki.clients import ClientError
55 f4de4c91 Stavros Sachtouris
        for msg, status, details, exp_msg, exp_status, exp_details in (
56 f4de4c91 Stavros Sachtouris
                ('some msg', 42, 0.28, 0, 0, 0),
57 f4de4c91 Stavros Sachtouris
                ('some msg', 'fail', [], 0, 0, 0),
58 f4de4c91 Stavros Sachtouris
                ('some msg', 42, 'details on error', 0, 0, 0),
59 f4de4c91 Stavros Sachtouris
                (
60 f4de4c91 Stavros Sachtouris
                    '404 {"ExampleError":'
61 f4de4c91 Stavros Sachtouris
                    ' {"message": "a msg", "code": 42, "details": "dets"}}',
62 f4de4c91 Stavros Sachtouris
                    404,
63 f4de4c91 Stavros Sachtouris
                    0,
64 f4de4c91 Stavros Sachtouris
                    '404 ExampleError (a msg)\n',
65 f4de4c91 Stavros Sachtouris
                    42,
66 f4de4c91 Stavros Sachtouris
                    ['dets']),
67 f4de4c91 Stavros Sachtouris
                (
68 f4de4c91 Stavros Sachtouris
                    '404 {"ExampleError":'
69 f4de4c91 Stavros Sachtouris
                    ' {"message": "a msg", "code": 42}}',
70 f4de4c91 Stavros Sachtouris
                    404,
71 f4de4c91 Stavros Sachtouris
                    'details on error',
72 f4de4c91 Stavros Sachtouris
                    '404 ExampleError (a msg)\n',
73 f4de4c91 Stavros Sachtouris
                    42,
74 f4de4c91 Stavros Sachtouris
                    0),
75 f4de4c91 Stavros Sachtouris
                (
76 f4de4c91 Stavros Sachtouris
                    '404 {"ExampleError":'
77 f4de4c91 Stavros Sachtouris
                    ' {"details": "Explain your error"}}',
78 f4de4c91 Stavros Sachtouris
                    404,
79 f4de4c91 Stavros Sachtouris
                    'details on error',
80 f4de4c91 Stavros Sachtouris
                    '404 ExampleError',
81 f4de4c91 Stavros Sachtouris
                    0,
82 f4de4c91 Stavros Sachtouris
                    ['details on error', 'Explain your error']),
83 f4de4c91 Stavros Sachtouris
                ('some msg\n', -10, ['details', 'on', 'error'], 0, 0, 0)):
84 f4de4c91 Stavros Sachtouris
            ce = ClientError(msg, status, details)
85 f4de4c91 Stavros Sachtouris
            exp_msg = exp_msg or (msg if msg.endswith('\n') else msg + '\n')
86 f4de4c91 Stavros Sachtouris
            exp_status = exp_status or status
87 f4de4c91 Stavros Sachtouris
            exp_details = exp_details or details
88 f4de4c91 Stavros Sachtouris
            self.assertEqual('%s' % ce, exp_msg)
89 f4de4c91 Stavros Sachtouris
            self.assertEqual(
90 f4de4c91 Stavros Sachtouris
                exp_status if isinstance(exp_status, int) else 0,
91 f4de4c91 Stavros Sachtouris
                ce.status)
92 f4de4c91 Stavros Sachtouris
            self.assertEqual(exp_details, ce.details)
93 db113224 Stavros Sachtouris
94 f4de4c91 Stavros Sachtouris
95 7fa5c263 Stavros Sachtouris
class RequestManager(TestCase):
96 7fa5c263 Stavros Sachtouris
97 7fa5c263 Stavros Sachtouris
    def setUp(self):
98 7fa5c263 Stavros Sachtouris
        from kamaki.clients import RequestManager
99 7fa5c263 Stavros Sachtouris
        self.RM = RequestManager
100 7fa5c263 Stavros Sachtouris
101 7fa5c263 Stavros Sachtouris
    def test___init__(self):
102 7fa5c263 Stavros Sachtouris
        from kamaki.clients import HTTP_METHODS
103 7fa5c263 Stavros Sachtouris
        method_values = HTTP_METHODS + [v.lower() for v in HTTP_METHODS]
104 7fa5c263 Stavros Sachtouris
        for args in product(
105 7fa5c263 Stavros Sachtouris
                tuple(method_values),
106 7fa5c263 Stavros Sachtouris
                ('http://www.example.com', 'https://example.com', ''),
107 7fa5c263 Stavros Sachtouris
                ('/some/path', '/' ''),
108 7fa5c263 Stavros Sachtouris
                ('Some data', '', None),
109 7fa5c263 Stavros Sachtouris
                (dict(k1='v1', k2='v2'), dict()),
110 7fa5c263 Stavros Sachtouris
                (dict(k='v', k2=None, k3='v3'), dict(k=0), dict(k='v'), {})):
111 7fa5c263 Stavros Sachtouris
            req = self.RM(*args)
112 7fa5c263 Stavros Sachtouris
            method, url, path, data, headers, params = args
113 7fa5c263 Stavros Sachtouris
            self.assertEqual(req.method, method.upper())
114 7fa5c263 Stavros Sachtouris
            for i, (k, v) in enumerate(params.items()):
115 7fa5c263 Stavros Sachtouris
                path += '%s%s%s' % (
116 7fa5c263 Stavros Sachtouris
                    '&' if '?' in path or i else '?',
117 7fa5c263 Stavros Sachtouris
                    k,
118 7fa5c263 Stavros Sachtouris
                    ('=%s' % v) if v else '')
119 7fa5c263 Stavros Sachtouris
            self.assertEqual(req.path, path)
120 7fa5c263 Stavros Sachtouris
            self.assertEqual(req.data, data)
121 7fa5c263 Stavros Sachtouris
            self.assertEqual(req.headers, headers)
122 7fa5c263 Stavros Sachtouris
        self.assertRaises(AssertionError, self.RM, 'GOT', '', '', '', {}, {})
123 7fa5c263 Stavros Sachtouris
124 f8eea8ec Stavros Sachtouris
    @patch('httplib.HTTPConnection.getresponse')
125 f8eea8ec Stavros Sachtouris
    @patch('httplib.HTTPConnection.request')
126 f8eea8ec Stavros Sachtouris
    def test_perform(self, request, getresponse):
127 f8eea8ec Stavros Sachtouris
        from httplib import HTTPConnection
128 f8eea8ec Stavros Sachtouris
        self.RM('GET', 'http://example.com', '/').perform(
129 f8eea8ec Stavros Sachtouris
            HTTPConnection('http', 'example.com'))
130 f8eea8ec Stavros Sachtouris
        expected = dict(body=None, headers={}, url='/', method='GET')
131 f8eea8ec Stavros Sachtouris
        request.assert_called_once_with(**expected)
132 f8eea8ec Stavros Sachtouris
        getresponse.assert_called_once_with()
133 f8eea8ec Stavros Sachtouris
134 f8eea8ec Stavros Sachtouris
135 f8eea8ec Stavros Sachtouris
class FakeResp(object):
136 f8eea8ec Stavros Sachtouris
137 f8eea8ec Stavros Sachtouris
    READ = 'something to read'
138 f8eea8ec Stavros Sachtouris
    HEADERS = dict(k='v', k1='v1', k2='v2')
139 f8eea8ec Stavros Sachtouris
    reason = 'some reason'
140 f8eea8ec Stavros Sachtouris
    status = 42
141 f8eea8ec Stavros Sachtouris
142 f8eea8ec Stavros Sachtouris
    def read(self):
143 f8eea8ec Stavros Sachtouris
        return self.READ
144 f8eea8ec Stavros Sachtouris
145 f8eea8ec Stavros Sachtouris
    def getheaders(self):
146 f8eea8ec Stavros Sachtouris
        return self.HEADERS.items()
147 f8eea8ec Stavros Sachtouris
148 f8eea8ec Stavros Sachtouris
149 f8eea8ec Stavros Sachtouris
class ResponseManager(TestCase):
150 f8eea8ec Stavros Sachtouris
151 f8eea8ec Stavros Sachtouris
    def setUp(self):
152 f8eea8ec Stavros Sachtouris
        from kamaki.clients import ResponseManager, RequestManager
153 f8eea8ec Stavros Sachtouris
        from httplib import HTTPConnection
154 f8eea8ec Stavros Sachtouris
        self.RM = ResponseManager(RequestManager('GET', 'http://ok', '/'))
155 f8eea8ec Stavros Sachtouris
        self.HTTPC = HTTPConnection
156 f8eea8ec Stavros Sachtouris
157 f8eea8ec Stavros Sachtouris
    def tearDown(self):
158 f8eea8ec Stavros Sachtouris
        FakeResp.READ = 'something to read'
159 f8eea8ec Stavros Sachtouris
160 f8eea8ec Stavros Sachtouris
    @patch('kamaki.clients.RequestManager.perform', return_value=FakeResp())
161 f8eea8ec Stavros Sachtouris
    def test_content(self, perform):
162 f8eea8ec Stavros Sachtouris
        self.assertEqual(self.RM.content, FakeResp.READ)
163 f8eea8ec Stavros Sachtouris
        self.assertTrue(isinstance(perform.call_args[0][0], self.HTTPC))
164 f8eea8ec Stavros Sachtouris
165 f8eea8ec Stavros Sachtouris
    @patch('kamaki.clients.RequestManager.perform', return_value=FakeResp())
166 f8eea8ec Stavros Sachtouris
    def test_text(self, perform):
167 f8eea8ec Stavros Sachtouris
        self.assertEqual(self.RM.text, FakeResp.READ)
168 f8eea8ec Stavros Sachtouris
        self.assertTrue(isinstance(perform.call_args[0][0], self.HTTPC))
169 f8eea8ec Stavros Sachtouris
170 f8eea8ec Stavros Sachtouris
    @patch('kamaki.clients.RequestManager.perform', return_value=FakeResp())
171 f8eea8ec Stavros Sachtouris
    def test_status(self, perform):
172 f8eea8ec Stavros Sachtouris
        self.assertEqual(self.RM.status, FakeResp.reason)
173 f8eea8ec Stavros Sachtouris
        self.assertTrue(isinstance(perform.call_args[0][0], self.HTTPC))
174 f8eea8ec Stavros Sachtouris
175 f8eea8ec Stavros Sachtouris
    @patch('kamaki.clients.RequestManager.perform', return_value=FakeResp())
176 f8eea8ec Stavros Sachtouris
    def test_status_code(self, perform):
177 f8eea8ec Stavros Sachtouris
        self.assertEqual(self.RM.status_code, FakeResp.status)
178 f8eea8ec Stavros Sachtouris
        self.assertTrue(isinstance(perform.call_args[0][0], self.HTTPC))
179 f8eea8ec Stavros Sachtouris
180 f8eea8ec Stavros Sachtouris
    @patch('kamaki.clients.RequestManager.perform', return_value=FakeResp())
181 f8eea8ec Stavros Sachtouris
    def test_headers(self, perform):
182 f8eea8ec Stavros Sachtouris
        self.assertEqual(self.RM.headers, FakeResp.HEADERS)
183 f8eea8ec Stavros Sachtouris
        self.assertTrue(isinstance(perform.call_args[0][0], self.HTTPC))
184 f8eea8ec Stavros Sachtouris
185 f8eea8ec Stavros Sachtouris
    @patch('kamaki.clients.RequestManager.perform', return_value=FakeResp())
186 f8eea8ec Stavros Sachtouris
    def test_json(self, perform):
187 f8eea8ec Stavros Sachtouris
        try:
188 f8eea8ec Stavros Sachtouris
            self.RM.json
189 f8eea8ec Stavros Sachtouris
        except Exception as e:
190 f8eea8ec Stavros Sachtouris
            self.assertEqual(
191 f8eea8ec Stavros Sachtouris
                '%s' % e,
192 f8eea8ec Stavros Sachtouris
                'Response not formated in JSON - '
193 f8eea8ec Stavros Sachtouris
                'No JSON object could be decoded\n')
194 f8eea8ec Stavros Sachtouris
195 f8eea8ec Stavros Sachtouris
        from json import dumps
196 f8eea8ec Stavros Sachtouris
        FakeResp.READ = dumps(FakeResp.HEADERS)
197 f8eea8ec Stavros Sachtouris
        self.RM._request_performed = False
198 f8eea8ec Stavros Sachtouris
        self.assertEqual(self.RM.json, FakeResp.HEADERS)
199 f8eea8ec Stavros Sachtouris
        self.assertTrue(isinstance(perform.call_args[0][0], self.HTTPC))
200 f8eea8ec Stavros Sachtouris
201 f8eea8ec Stavros Sachtouris
    @patch('kamaki.clients.RequestManager.perform', return_value=FakeResp())
202 f8eea8ec Stavros Sachtouris
    def test_all(self, perform):
203 f8eea8ec Stavros Sachtouris
        self.assertEqual(self.RM.content, FakeResp.READ)
204 f8eea8ec Stavros Sachtouris
        self.assertEqual(self.RM.text, FakeResp.READ)
205 f8eea8ec Stavros Sachtouris
        self.assertEqual(self.RM.status, FakeResp.reason)
206 f8eea8ec Stavros Sachtouris
        self.assertEqual(self.RM.status_code, FakeResp.status)
207 f8eea8ec Stavros Sachtouris
        self.assertEqual(self.RM.headers, FakeResp.HEADERS)
208 f8eea8ec Stavros Sachtouris
        perform.assert_called_only_once
209 f8eea8ec Stavros Sachtouris
210 7fa5c263 Stavros Sachtouris
211 f4de4c91 Stavros Sachtouris
class SilentEvent(TestCase):
212 db113224 Stavros Sachtouris
213 27abfa9f Stavros Sachtouris
    def thread_content(self, methodid, raiseException=0):
214 db113224 Stavros Sachtouris
        wait = 0.1
215 f4de4c91 Stavros Sachtouris
        self.can_finish = -1
216 db113224 Stavros Sachtouris
        while self.can_finish < methodid and wait < 4:
217 db113224 Stavros Sachtouris
            sleep(wait)
218 db113224 Stavros Sachtouris
            wait = 2 * wait
219 27abfa9f Stavros Sachtouris
        if raiseException and raiseException == methodid:
220 27abfa9f Stavros Sachtouris
            raise Exception('Some exception')
221 03493855 Stavros Sachtouris
        self._value = methodid
222 db113224 Stavros Sachtouris
        self.assertTrue(wait < 4)
223 db113224 Stavros Sachtouris
224 db113224 Stavros Sachtouris
    def setUp(self):
225 db113224 Stavros Sachtouris
        from kamaki.clients import SilentEvent
226 db113224 Stavros Sachtouris
        self.SE = SilentEvent
227 db113224 Stavros Sachtouris
228 27abfa9f Stavros Sachtouris
    def test_run(self):
229 27abfa9f Stavros Sachtouris
        threads = [self.SE(self.thread_content, i) for i in range(4)]
230 db113224 Stavros Sachtouris
        for t in threads:
231 db113224 Stavros Sachtouris
            t.start()
232 db113224 Stavros Sachtouris
233 db113224 Stavros Sachtouris
        for i in range(4):
234 db113224 Stavros Sachtouris
            self.assertTrue(threads[i].is_alive())
235 db113224 Stavros Sachtouris
            self.can_finish = i
236 db113224 Stavros Sachtouris
            threads[i].join()
237 db113224 Stavros Sachtouris
            self.assertFalse(threads[i].is_alive())
238 db113224 Stavros Sachtouris
239 27abfa9f Stavros Sachtouris
    def test_value(self):
240 27abfa9f Stavros Sachtouris
        threads = [self.SE(self.thread_content, i) for i in range(4)]
241 27abfa9f Stavros Sachtouris
        for t in threads:
242 27abfa9f Stavros Sachtouris
            t.start()
243 27abfa9f Stavros Sachtouris
244 27abfa9f Stavros Sachtouris
        for mid, t in enumerate(threads):
245 27abfa9f Stavros Sachtouris
            if t.is_alive():
246 27abfa9f Stavros Sachtouris
                self.can_finish = mid
247 27abfa9f Stavros Sachtouris
                continue
248 27abfa9f Stavros Sachtouris
            self.assertTrue(mid, t.value)
249 27abfa9f Stavros Sachtouris
250 27abfa9f Stavros Sachtouris
    def test_exception(self):
251 27abfa9f Stavros Sachtouris
        threads = [self.SE(self.thread_content, i, (i % 2)) for i in range(4)]
252 27abfa9f Stavros Sachtouris
        for t in threads:
253 27abfa9f Stavros Sachtouris
            t.start()
254 27abfa9f Stavros Sachtouris
255 27abfa9f Stavros Sachtouris
        for i, t in enumerate(threads):
256 27abfa9f Stavros Sachtouris
            if t.is_alive():
257 27abfa9f Stavros Sachtouris
                self.can_finish = i
258 27abfa9f Stavros Sachtouris
                continue
259 27abfa9f Stavros Sachtouris
            if i % 2:
260 27abfa9f Stavros Sachtouris
                self.assertTrue(isinstance(t.exception, Exception))
261 27abfa9f Stavros Sachtouris
            else:
262 27abfa9f Stavros Sachtouris
                self.assertFalse(t.exception)
263 27abfa9f Stavros Sachtouris
264 db113224 Stavros Sachtouris
265 6a6175c0 Stavros Sachtouris
class FR(object):
266 6a6175c0 Stavros Sachtouris
    json = None
267 6a6175c0 Stavros Sachtouris
    text = None
268 6a6175c0 Stavros Sachtouris
    headers = dict()
269 6a6175c0 Stavros Sachtouris
    content = json
270 6a6175c0 Stavros Sachtouris
    status = None
271 6a6175c0 Stavros Sachtouris
    status_code = 200
272 6a6175c0 Stavros Sachtouris
273 6a6175c0 Stavros Sachtouris
274 5a71b3a1 Stavros Sachtouris
class FakeConnection(object):
275 5a71b3a1 Stavros Sachtouris
    """A fake Connection class"""
276 5a71b3a1 Stavros Sachtouris
277 6a6175c0 Stavros Sachtouris
    headers = dict()
278 6a6175c0 Stavros Sachtouris
    params = dict()
279 6a6175c0 Stavros Sachtouris
280 5a71b3a1 Stavros Sachtouris
    def __init__(self):
281 5a71b3a1 Stavros Sachtouris
        pass
282 5a71b3a1 Stavros Sachtouris
283 97baa5c3 Stavros Sachtouris
    def set_header(self, name, value):
284 97baa5c3 Stavros Sachtouris
        pass
285 97baa5c3 Stavros Sachtouris
286 6a6175c0 Stavros Sachtouris
    def reset_headers(self):
287 6a6175c0 Stavros Sachtouris
        self.headers = {}
288 5a71b3a1 Stavros Sachtouris
289 6a6175c0 Stavros Sachtouris
    def set_param(self, name, value):
290 6a6175c0 Stavros Sachtouris
        self.params = {}
291 5dde4c83 Stavros Sachtouris
292 6a6175c0 Stavros Sachtouris
    def reset_params(self):
293 5dde4c83 Stavros Sachtouris
        pass
294 5dde4c83 Stavros Sachtouris
295 6a6175c0 Stavros Sachtouris
    def perform_request(self, *args):
296 6a6175c0 Stavros Sachtouris
        return FR()
297 6a6175c0 Stavros Sachtouris
298 5dde4c83 Stavros Sachtouris
299 5a71b3a1 Stavros Sachtouris
class Client(TestCase):
300 5a71b3a1 Stavros Sachtouris
301 5a71b3a1 Stavros Sachtouris
    def assert_dicts_are_equal(self, d1, d2):
302 5a71b3a1 Stavros Sachtouris
        for k, v in d1.items():
303 5a71b3a1 Stavros Sachtouris
            self.assertTrue(k in d2)
304 5a71b3a1 Stavros Sachtouris
            if isinstance(v, dict):
305 5a71b3a1 Stavros Sachtouris
                self.assert_dicts_are_equal(v, d2[k])
306 5a71b3a1 Stavros Sachtouris
            else:
307 5a71b3a1 Stavros Sachtouris
                self.assertEqual(unicode(v), unicode(d2[k]))
308 5a71b3a1 Stavros Sachtouris
309 5a71b3a1 Stavros Sachtouris
    def setUp(self):
310 5a71b3a1 Stavros Sachtouris
        from kamaki.clients import Client
311 5dde4c83 Stavros Sachtouris
        from kamaki.clients import ClientError as CE
312 5a71b3a1 Stavros Sachtouris
        self.base_url = 'http://example.com'
313 5a71b3a1 Stavros Sachtouris
        self.token = 's0m370k3n=='
314 5a71b3a1 Stavros Sachtouris
        self.client = Client(self.base_url, self.token, FakeConnection())
315 5dde4c83 Stavros Sachtouris
        self.CE = CE
316 5dde4c83 Stavros Sachtouris
317 5dde4c83 Stavros Sachtouris
    def tearDown(self):
318 5dde4c83 Stavros Sachtouris
        FR.text = None
319 5dde4c83 Stavros Sachtouris
        FR.status = None
320 5dde4c83 Stavros Sachtouris
        FR.status_code = 200
321 6a6175c0 Stavros Sachtouris
        FakeConnection.headers = dict()
322 6a6175c0 Stavros Sachtouris
        self.client.token = self.token
323 5a71b3a1 Stavros Sachtouris
324 5a71b3a1 Stavros Sachtouris
    def test___init__(self):
325 5a71b3a1 Stavros Sachtouris
        self.assertEqual(self.client.base_url, self.base_url)
326 5a71b3a1 Stavros Sachtouris
        self.assertEqual(self.client.token, self.token)
327 5a71b3a1 Stavros Sachtouris
        self.assert_dicts_are_equal(self.client.headers, {})
328 5a71b3a1 Stavros Sachtouris
        DATE_FORMATS = [
329 5a71b3a1 Stavros Sachtouris
            '%a %b %d %H:%M:%S %Y',
330 5a71b3a1 Stavros Sachtouris
            '%A, %d-%b-%y %H:%M:%S GMT',
331 5a71b3a1 Stavros Sachtouris
            '%a, %d %b %Y %H:%M:%S GMT']
332 5a71b3a1 Stavros Sachtouris
        self.assertEqual(self.client.DATE_FORMATS, DATE_FORMATS)
333 5a71b3a1 Stavros Sachtouris
        self.assertTrue(isinstance(self.client.http_client, FakeConnection))
334 5a71b3a1 Stavros Sachtouris
335 9c6c3d69 Stavros Sachtouris
    def test__init_thread_limit(self):
336 9c6c3d69 Stavros Sachtouris
        exp = 'Nothing set here'
337 9c6c3d69 Stavros Sachtouris
        for faulty in (-1, 0.5, 'a string', {}):
338 9c6c3d69 Stavros Sachtouris
            self.assertRaises(
339 9c6c3d69 Stavros Sachtouris
                AssertionError,
340 9c6c3d69 Stavros Sachtouris
                self.client._init_thread_limit,
341 9c6c3d69 Stavros Sachtouris
                faulty)
342 9c6c3d69 Stavros Sachtouris
            self.assertEqual(exp, getattr(self.client, '_thread_limit', exp))
343 9c6c3d69 Stavros Sachtouris
            self.assertEqual(exp, getattr(self.client, '_elapsed_old', exp))
344 9c6c3d69 Stavros Sachtouris
            self.assertEqual(exp, getattr(self.client, '_elapsed_new', exp))
345 9c6c3d69 Stavros Sachtouris
        self.client._init_thread_limit(42)
346 9c6c3d69 Stavros Sachtouris
        self.assertEqual(42, self.client._thread_limit)
347 9c6c3d69 Stavros Sachtouris
        self.assertEqual(0.0, self.client._elapsed_old)
348 9c6c3d69 Stavros Sachtouris
        self.assertEqual(0.0, self.client._elapsed_new)
349 9c6c3d69 Stavros Sachtouris
350 9c6c3d69 Stavros Sachtouris
    def test__watch_thread_limit(self):
351 9c6c3d69 Stavros Sachtouris
        waits = (
352 9c6c3d69 Stavros Sachtouris
            dict(args=((0.1, 1), (0.1, 2), (0.2, 1), (0.7, 1), (0.3, 2))),
353 9c6c3d69 Stavros Sachtouris
            dict(args=((1.0 - (i / 10.0), (i + 1)) for i in range(7))),
354 9c6c3d69 Stavros Sachtouris
            dict(max=1, args=tuple([(randint(1, 10) / 3.0, 1), ] * 10)),
355 9c6c3d69 Stavros Sachtouris
            dict(
356 9c6c3d69 Stavros Sachtouris
                limit=5,
357 9c6c3d69 Stavros Sachtouris
                args=tuple([
358 9c6c3d69 Stavros Sachtouris
                    (1.0 + (i / 10.0), (5 - i - 1)) for i in range(4)] + [
359 9c6c3d69 Stavros Sachtouris
                    (2.0, 1), (1.9, 2), (2.0, 1), (2.0, 2)])),
360 9c6c3d69 Stavros Sachtouris
            dict(args=tuple(
361 9c6c3d69 Stavros Sachtouris
                [(1.0 - (i / 10.0), (i + 1)) for i in range(7)] + [
362 9c6c3d69 Stavros Sachtouris
                (0.1, 7), (0.2, 6), (0.4, 5), (0.3, 6), (0.2, 7), (0.1, 7)])),)
363 9c6c3d69 Stavros Sachtouris
        for wait_dict in waits:
364 9c6c3d69 Stavros Sachtouris
            if 'max' in wait_dict:
365 9c6c3d69 Stavros Sachtouris
                self.client.MAX_THREADS = wait_dict['max']
366 9c6c3d69 Stavros Sachtouris
            else:
367 9c6c3d69 Stavros Sachtouris
                self.client.MAX_THREADS = 7
368 9c6c3d69 Stavros Sachtouris
            if 'limit' in wait_dict:
369 9c6c3d69 Stavros Sachtouris
                self.client._init_thread_limit(wait_dict['limit'])
370 9c6c3d69 Stavros Sachtouris
            else:
371 9c6c3d69 Stavros Sachtouris
                self.client._init_thread_limit()
372 9c6c3d69 Stavros Sachtouris
                self.client._watch_thread_limit(list())
373 9c6c3d69 Stavros Sachtouris
                self.assertEqual(1, self.client._thread_limit)
374 9c6c3d69 Stavros Sachtouris
            for wait, exp_limit in wait_dict['args']:
375 9c6c3d69 Stavros Sachtouris
                self.client._elapsed_new = wait
376 9c6c3d69 Stavros Sachtouris
                self.client._watch_thread_limit(list())
377 9c6c3d69 Stavros Sachtouris
                self.assertEqual(exp_limit, self.client._thread_limit)
378 9c6c3d69 Stavros Sachtouris
379 5dde4c83 Stavros Sachtouris
    def test__raise_for_status(self):
380 5dde4c83 Stavros Sachtouris
        r = FR()
381 5dde4c83 Stavros Sachtouris
        for txt, sts_code, sts in (('err msg', 10, None), ('', 42, 'Err St')):
382 5dde4c83 Stavros Sachtouris
            r.text, r.status_code, r.status = txt, sts_code, sts
383 5dde4c83 Stavros Sachtouris
            try:
384 5dde4c83 Stavros Sachtouris
                self.client._raise_for_status(r)
385 5dde4c83 Stavros Sachtouris
            except self.CE as ce:
386 5dde4c83 Stavros Sachtouris
                self.assertEqual('%s' % ce, '%s %s\n' % (sts or '', txt))
387 5dde4c83 Stavros Sachtouris
                self.assertEqual(ce.status, sts_code)
388 5dde4c83 Stavros Sachtouris
389 5dde4c83 Stavros Sachtouris
        for msg, sts_code in (('err msg', 32), ('', 42), ('an err', None)):
390 5dde4c83 Stavros Sachtouris
            err = self.CE(msg, sts_code) if sts_code else Exception(msg)
391 5dde4c83 Stavros Sachtouris
            try:
392 5dde4c83 Stavros Sachtouris
                self.client._raise_for_status(err)
393 5dde4c83 Stavros Sachtouris
            except self.CE as ce:
394 5dde4c83 Stavros Sachtouris
                self.assertEqual('%s' % ce, '%s %s\n' % (sts_code or '', msg))
395 5dde4c83 Stavros Sachtouris
                self.assertEqual(ce.status, sts_code or 0)
396 5dde4c83 Stavros Sachtouris
397 97baa5c3 Stavros Sachtouris
    @patch('%s.FakeConnection.set_header' % __name__)
398 97baa5c3 Stavros Sachtouris
    def test_set_header(self, SH):
399 97baa5c3 Stavros Sachtouris
        num_of_calls = 0
400 97baa5c3 Stavros Sachtouris
        for name, value, condition in product(
401 97baa5c3 Stavros Sachtouris
                ('n4m3', '', None),
402 97baa5c3 Stavros Sachtouris
                ('v41u3', None, 42),
403 97baa5c3 Stavros Sachtouris
                (True, False, None, 1, '')):
404 97baa5c3 Stavros Sachtouris
            self.client.set_header(name, value, iff=condition)
405 97baa5c3 Stavros Sachtouris
            if value is not None and condition:
406 97baa5c3 Stavros Sachtouris
                self.assertEqual(SH.mock_calls[-1], call(name, value))
407 97baa5c3 Stavros Sachtouris
                num_of_calls += 1
408 97baa5c3 Stavros Sachtouris
            else:
409 97baa5c3 Stavros Sachtouris
                self.assertEqual(num_of_calls, len(SH.mock_calls))
410 97baa5c3 Stavros Sachtouris
411 9af3a427 Stavros Sachtouris
    @patch('%s.FakeConnection.set_param' % __name__)
412 9af3a427 Stavros Sachtouris
    def test_set_param(self, SP):
413 9af3a427 Stavros Sachtouris
        num_of_calls = 0
414 9af3a427 Stavros Sachtouris
        for name, value, condition in product(
415 9af3a427 Stavros Sachtouris
                ('n4m3', '', None),
416 9af3a427 Stavros Sachtouris
                ('v41u3', None, 42),
417 9af3a427 Stavros Sachtouris
                (True, False, None, 1, '')):
418 9af3a427 Stavros Sachtouris
            self.client.set_param(name, value, iff=condition)
419 9af3a427 Stavros Sachtouris
            if condition:
420 9af3a427 Stavros Sachtouris
                self.assertEqual(SP.mock_calls[-1], call(name, value))
421 9af3a427 Stavros Sachtouris
                num_of_calls += 1
422 9af3a427 Stavros Sachtouris
            else:
423 9af3a427 Stavros Sachtouris
                self.assertEqual(num_of_calls, len(SP.mock_calls))
424 9af3a427 Stavros Sachtouris
425 6a6175c0 Stavros Sachtouris
    @patch('%s.FakeConnection.perform_request' % __name__, return_value=FR())
426 6a6175c0 Stavros Sachtouris
    def test_request(self, PR):
427 6a6175c0 Stavros Sachtouris
        for args in product(
428 6a6175c0 Stavros Sachtouris
                ('get', '', dict(method='get')),
429 6a6175c0 Stavros Sachtouris
                ('/some/path', None, ['some', 'path']),
430 6a6175c0 Stavros Sachtouris
                (dict(), dict(h1='v1'), dict(h1='v2', h2='v2')),
431 6a6175c0 Stavros Sachtouris
                (dict(), dict(p1='v1'), dict(p1='v2', p2=None, p3='v3')),
432 6a6175c0 Stavros Sachtouris
                (dict(), dict(data='some data'), dict(
433 6a6175c0 Stavros Sachtouris
                    success=400,
434 6a6175c0 Stavros Sachtouris
                    json=dict(k2='v2', k1='v1')))):
435 6a6175c0 Stavros Sachtouris
            method, path, kwargs = args[0], args[1], args[-1]
436 6a6175c0 Stavros Sachtouris
            args = args[:-1]
437 6a6175c0 Stavros Sachtouris
            if not (isinstance(method, str) and method and isinstance(
438 6a6175c0 Stavros Sachtouris
                    path, str) and path):
439 6a6175c0 Stavros Sachtouris
                self.assertRaises(
440 6a6175c0 Stavros Sachtouris
                    AssertionError,
441 6a6175c0 Stavros Sachtouris
                    self.client.request,
442 6a6175c0 Stavros Sachtouris
                    *args, **kwargs)
443 6a6175c0 Stavros Sachtouris
            else:
444 6a6175c0 Stavros Sachtouris
                atoken = 'a70k3n_%s' % randint(1, 30)
445 6a6175c0 Stavros Sachtouris
                self.client.token = atoken
446 6a6175c0 Stavros Sachtouris
                if 'success' in kwargs:
447 6a6175c0 Stavros Sachtouris
                    self.assertRaises(
448 6a6175c0 Stavros Sachtouris
                        self.CE,
449 6a6175c0 Stavros Sachtouris
                        self.client.request,
450 6a6175c0 Stavros Sachtouris
                        *args, **kwargs)
451 6a6175c0 Stavros Sachtouris
                    FR.status_code = kwargs['success']
452 6a6175c0 Stavros Sachtouris
                else:
453 6a6175c0 Stavros Sachtouris
                    FR.status_code = 200
454 6a6175c0 Stavros Sachtouris
                self.client.request(*args, **kwargs)
455 6a6175c0 Stavros Sachtouris
                data = kwargs.get(
456 6a6175c0 Stavros Sachtouris
                    'data',
457 6a6175c0 Stavros Sachtouris
                    '{"k2": "v2", "k1": "v1"}' if 'json' in kwargs else None)
458 6a6175c0 Stavros Sachtouris
                self.assertEqual(self.client.http_client.url, self.base_url)
459 6a6175c0 Stavros Sachtouris
                self.assertEqual(self.client.http_client.path, path)
460 6a6175c0 Stavros Sachtouris
                self.assertEqual(
461 6a6175c0 Stavros Sachtouris
                    PR.mock_calls[-1],
462 6a6175c0 Stavros Sachtouris
                    call(method, data, *args[2:]))
463 6a6175c0 Stavros Sachtouris
                self.assertEqual(self.client.http_client.headers, dict())
464 6a6175c0 Stavros Sachtouris
                self.assertEqual(self.client.http_client.params, dict())
465 6a6175c0 Stavros Sachtouris
466 6a6175c0 Stavros Sachtouris
    @patch('kamaki.clients.Client.request', return_value='lala')
467 6a6175c0 Stavros Sachtouris
    def _test_foo(self, foo, request):
468 6a6175c0 Stavros Sachtouris
        method = getattr(self.client, foo)
469 6a6175c0 Stavros Sachtouris
        r = method('path', k='v')
470 6a6175c0 Stavros Sachtouris
        self.assertEqual(r, 'lala')
471 6a6175c0 Stavros Sachtouris
        request.assert_called_once_with(foo, 'path', k='v')
472 6a6175c0 Stavros Sachtouris
473 6a6175c0 Stavros Sachtouris
    def test_delete(self):
474 6a6175c0 Stavros Sachtouris
        self._test_foo('delete')
475 6a6175c0 Stavros Sachtouris
476 6a6175c0 Stavros Sachtouris
    def test_get(self):
477 6a6175c0 Stavros Sachtouris
        self._test_foo('get')
478 6a6175c0 Stavros Sachtouris
479 6a6175c0 Stavros Sachtouris
    def test_head(self):
480 6a6175c0 Stavros Sachtouris
        self._test_foo('head')
481 6a6175c0 Stavros Sachtouris
482 6a6175c0 Stavros Sachtouris
    def test_post(self):
483 6a6175c0 Stavros Sachtouris
        self._test_foo('post')
484 6a6175c0 Stavros Sachtouris
485 6a6175c0 Stavros Sachtouris
    def test_put(self):
486 6a6175c0 Stavros Sachtouris
        self._test_foo('put')
487 6a6175c0 Stavros Sachtouris
488 6a6175c0 Stavros Sachtouris
    def test_copy(self):
489 6a6175c0 Stavros Sachtouris
        self._test_foo('copy')
490 6a6175c0 Stavros Sachtouris
491 6a6175c0 Stavros Sachtouris
    def test_move(self):
492 6a6175c0 Stavros Sachtouris
        self._test_foo('move')
493 6a6175c0 Stavros Sachtouris
494 5a71b3a1 Stavros Sachtouris
495 85898ca4 Stavros Sachtouris
#  TestCase auxiliary methods
496 85898ca4 Stavros Sachtouris
497 657dc0c8 Stavros Sachtouris
def runTestCase(cls, test_name, args=[], failure_collector=[]):
498 657dc0c8 Stavros Sachtouris
    """
499 657dc0c8 Stavros Sachtouris
    :param cls: (TestCase) a set of Tests
500 657dc0c8 Stavros Sachtouris

501 657dc0c8 Stavros Sachtouris
    :param test_name: (str)
502 657dc0c8 Stavros Sachtouris

503 657dc0c8 Stavros Sachtouris
    :param args: (list) these are prefixed with test_ and used as params when
504 657dc0c8 Stavros Sachtouris
        instantiating cls
505 657dc0c8 Stavros Sachtouris

506 657dc0c8 Stavros Sachtouris
    :param failure_collector: (list) collects info of test failures
507 657dc0c8 Stavros Sachtouris

508 657dc0c8 Stavros Sachtouris
    :returns: (int) total # of run tests
509 657dc0c8 Stavros Sachtouris
    """
510 85898ca4 Stavros Sachtouris
    suite = TestSuite()
511 85898ca4 Stavros Sachtouris
    if args:
512 85898ca4 Stavros Sachtouris
        suite.addTest(cls('_'.join(['test'] + args)))
513 85898ca4 Stavros Sachtouris
    else:
514 85898ca4 Stavros Sachtouris
        suite.addTest(makeSuite(cls))
515 85898ca4 Stavros Sachtouris
    print('* Test * %s *' % test_name)
516 657dc0c8 Stavros Sachtouris
    r = TextTestRunner(verbosity=2).run(suite)
517 657dc0c8 Stavros Sachtouris
    failure_collector += r.failures
518 657dc0c8 Stavros Sachtouris
    return r.testsRun
519 85898ca4 Stavros Sachtouris
520 85898ca4 Stavros Sachtouris
521 85898ca4 Stavros Sachtouris
def _add_value(foo, value):
522 85898ca4 Stavros Sachtouris
    def wrap(self):
523 85898ca4 Stavros Sachtouris
        return foo(self, value)
524 85898ca4 Stavros Sachtouris
    return wrap
525 85898ca4 Stavros Sachtouris
526 85898ca4 Stavros Sachtouris
527 85898ca4 Stavros Sachtouris
def get_test_classes(module=__import__(__name__), name=''):
528 85898ca4 Stavros Sachtouris
    module_stack = [module]
529 85898ca4 Stavros Sachtouris
    while module_stack:
530 85898ca4 Stavros Sachtouris
        module = module_stack[-1]
531 85898ca4 Stavros Sachtouris
        module_stack = module_stack[:-1]
532 85898ca4 Stavros Sachtouris
        for objname, obj in getmembers(module):
533 85898ca4 Stavros Sachtouris
            if (objname == name or not name):
534 85898ca4 Stavros Sachtouris
                if isclass(obj) and objname != 'TestCase' and (
535 85898ca4 Stavros Sachtouris
                        issubclass(obj, TestCase)):
536 85898ca4 Stavros Sachtouris
                    yield (obj, objname)
537 85898ca4 Stavros Sachtouris
538 85898ca4 Stavros Sachtouris
539 c1004a00 Stavros Sachtouris
def main(argv):
540 d86c3c7d Stavros Sachtouris
    found = False
541 657dc0c8 Stavros Sachtouris
    failure_collector = list()
542 657dc0c8 Stavros Sachtouris
    num_of_tests = 0
543 c1004a00 Stavros Sachtouris
    for cls, name in get_test_classes(name=argv[1] if len(argv) > 1 else ''):
544 d86c3c7d Stavros Sachtouris
        found = True
545 657dc0c8 Stavros Sachtouris
        num_of_tests += runTestCase(cls, name, argv[2:], failure_collector)
546 d86c3c7d Stavros Sachtouris
    if not found:
547 d86c3c7d Stavros Sachtouris
        print('Test "%s" not found' % ' '.join(argv[1:]))
548 657dc0c8 Stavros Sachtouris
    else:
549 657dc0c8 Stavros Sachtouris
        for i, failure in enumerate(failure_collector):
550 657dc0c8 Stavros Sachtouris
            print('Failure %s: ' % (i + 1))
551 657dc0c8 Stavros Sachtouris
            for field in failure:
552 657dc0c8 Stavros Sachtouris
                print('\t%s' % field)
553 657dc0c8 Stavros Sachtouris
        print('\nTotal tests run: %s' % num_of_tests)
554 657dc0c8 Stavros Sachtouris
        print('Total failures: %s' % len(failure_collector))
555 c1004a00 Stavros Sachtouris
556 c1004a00 Stavros Sachtouris
557 c1004a00 Stavros Sachtouris
if __name__ == '__main__':
558 c1004a00 Stavros Sachtouris
    from sys import argv
559 c1004a00 Stavros Sachtouris
    main(argv)