Statistics
| Branch: | Tag: | Revision:

root / astakosclient / astakosclient / tests.py @ 8204cb4c

History | View | Annotate | Download (31.8 kB)

1
#!/usr/bin/env python
2
#
3
# Copyright (C) 2012, 2013 GRNET S.A. All rights reserved.
4
#
5
# Redistribution and use in source and binary forms, with or
6
# without modification, are permitted provided that the following
7
# conditions are met:
8
#
9
#   1. Redistributions of source code must retain the above
10
#      copyright notice, this list of conditions and the following
11
#      disclaimer.
12
#
13
#   2. Redistributions in binary form must reproduce the above
14
#      copyright notice, this list of conditions and the following
15
#      disclaimer in the documentation and/or other materials
16
#      provided with the distribution.
17
#
18
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
19
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
22
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
25
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
# POSSIBILITY OF SUCH DAMAGE.
30
#
31
# The views and conclusions contained in the software and
32
# documentation are those of the authors and should not be
33
# interpreted as representing official policies, either expressed
34
# or implied, of GRNET S.A.
35

    
36
"""Unit Tests for the astakos-client module
37

38
Provides unit tests for the code implementing
39
the astakos client library
40

41
"""
42

    
43
import re
44
import sys
45
import simplejson
46

    
47
import astakosclient
48
from astakosclient import AstakosClient
49
from astakosclient.utils import join_urls
50
from astakosclient.errors import \
51
    AstakosClientException, Unauthorized, BadRequest, NotFound, \
52
    NoUserName, NoUUID, BadValue, QuotaLimit
53

    
54
# Use backported unittest functionality if Python < 2.7
55
try:
56
    import unittest2 as unittest
57
except ImportError:
58
    if sys.version_info < (2, 7):
59
        raise Exception("The unittest2 package is required for Python < 2.7")
60
    import unittest
61

    
62

    
63
# --------------------------------------------------------------------
64
# Helper functions
65
auth_url = "https://example.org/identity/v2.0"
66
account_prefix = "/account_prefix"
67
ui_prefix = "/ui_prefix"
68
oauth2_prefix = "/oauth2"
69
api_tokens = "/identity/v2.0/tokens"
70
api_usercatalogs = join_urls(account_prefix, "user_catalogs")
71
api_resources = join_urls(account_prefix, "resources")
72
api_quotas = join_urls(account_prefix, "quotas")
73
api_commissions = join_urls(account_prefix, "commissions")
74

    
75
# --------------------------------------
76
# Local users
77
token = {
78
    'id': "skzleaFlBl+fasFdaf24sx",
79
    'tenant': {
80
        'id': "73917abc-abcd-477e-a1f1-1763abcdefab",
81
        'name': "Example User One",
82
        },
83
    }
84

    
85
user = {
86
    'id': "73917abc-abcd-477e-a1f1-1763abcdefab",
87
    'name': "Example User One",
88
    'roles': [{u'id': 1, u'name': u'default'},
89
              {u'id': 5, u'name': u'academic-login-users'}],
90
    'roles_links': []
91
    }
92

    
93
resources = {
94
    "cyclades.ram": {
95
        "unit": "bytes",
96
        "description": "Virtual machine memory",
97
        "service": "cyclades"}}
98

    
99
endpoints = {
100
    "access": {
101
        "serviceCatalog": [
102
            {"endpoints": [{"SNF:uiURL": join_urls("https://example.org/",
103
                                                   ui_prefix),
104
                            "publicURL": join_urls("https://example.org/",
105
                                                   account_prefix),
106
                            "region": "default",
107
                            "versionId": "v1.0"}],
108
             "name": "astakos_account",
109
             "type": "account"
110
             },
111
            {"endpoints": [{"SNF:uiURL": join_urls("https://example.org/",
112
                                                   ui_prefix),
113
                            "publicURL": join_urls("https://example.org/",
114
                                                   oauth2_prefix),
115
                            "region": "default",
116
                            "versionId": "v1.0"}],
117
             "name": "astakos_oauth2",
118
             "type": "astakos_auth"
119
             }]
120
        }
121
    }
122

    
123
endpoints_with_info = dict(endpoints)
124
endpoints_with_info['access']['token'] = dict(token)
125
endpoints_with_info['access']['user'] = dict(user)
126

    
127
quotas = {
128
    "system": {
129
        "cyclades.ram": {
130
            "pending": 0,
131
            "limit": 1073741824,
132
            "usage": 536870912},
133
        "cyclades.vm": {
134
            "pending": 0,
135
            "limit": 2,
136
            "usage": 2}},
137
    "project:1": {
138
        "cyclades.ram": {
139
            "pending": 0,
140
            "limit": 2147483648,
141
            "usage": 2147483648},
142
        "cyclades.vm": {
143
            "pending": 1,
144
            "limit": 5,
145
            "usage": 2}}}
146

    
147
commission_request = {
148
    "force": False,
149
    "auto_accept": False,
150
    "name": "my commission",
151
    "provisions": [
152
        {
153
            "holder": "c02f315b-7d84-45bc-a383-552a3f97d2ad",
154
            "source": "system",
155
            "resource": "cyclades.vm",
156
            "quantity": 1
157
        },
158
        {
159
            "holder": "c02f315b-7d84-45bc-a383-552a3f97d2ad",
160
            "source": "system",
161
            "resource": "cyclades.ram",
162
            "quantity": 30000
163
        }]}
164

    
165
commission_successful_response = {"serial": 57}
166

    
167
commission_failure_response = {
168
    "overLimit": {
169
        "message": "a human-readable error message",
170
        "code": 413,
171
        "data": {
172
            "provision": {
173
                "holder": "c02f315b-7d84-45bc-a383-552a3f97d2ad",
174
                "source": "system",
175
                "resource": "cyclades.ram",
176
                "quantity": 520000000},
177
            "name": "NoCapacityError",
178
            "limit": 600000000,
179
            "usage": 180000000}}}
180

    
181
pending_commissions = [100, 200]
182

    
183
commission_description = {
184
    "serial": 57,
185
    "issue_time": "2013-04-08T10:19:15.0373+00:00",
186
    "name": "a commission",
187
    "provisions": [
188
        {
189
            "holder": "c02f315b-7d84-45bc-a383-552a3f97d2ad",
190
            "source": "system",
191
            "resource": "cyclades.vm",
192
            "quantity": 1
193
        },
194
        {
195
            "holder": "c02f315b-7d84-45bc-a383-552a3f97d2ad",
196
            "source": "system",
197
            "resource": "cyclades.ram",
198
            "quantity": 536870912
199
        }]}
200

    
201
resolve_commissions_req = {
202
    "accept": [56, 57],
203
    "reject": [56, 58, 59]}
204

    
205
resolve_commissions_rep = {
206
    "accepted": [57],
207
    "rejected": [59],
208
    "failed": [
209
        [56, {
210
            "badRequest": {
211
                "message": "cannot both accept and reject serial 56",
212
                "code": 400}}],
213
        [58, {
214
            "itemNotFound": {
215
                "message": "serial 58 does not exist",
216
                "code": 404}}]]}
217

    
218

    
219
# ----------------------------
220
# These functions will be used as mocked requests
221
def _request_status_302(conn, method, url, **kwargs):
222
    """This request returns 302"""
223
    message = "FOUND"
224
    status = 302
225
    data = "302 Found"
226
    return (message, data, status)
227

    
228

    
229
def _request_status_404(conn, method, url, **kwargs):
230
    """This request returns 404"""
231
    message = "Not Found"
232
    status = 404
233
    data = "404 Not Found"
234
    return (message, data, status)
235

    
236

    
237
def _request_status_403(conn, method, url, **kwargs):
238
    """This request returns 403"""
239
    message = "UNAUTHORIZED"
240
    status = 403
241
    data = "Forbidden"
242
    return (message, data, status)
243

    
244

    
245
def _request_status_401(conn, method, url, **kwargs):
246
    """This request returns 401"""
247
    message = "UNAUTHORIZED"
248
    status = 401
249
    data = "Invalid X-Auth-Token\n"
250
    return (message, data, status)
251

    
252

    
253
def _request_status_400(conn, method, url, **kwargs):
254
    """This request returns 400"""
255
    message = "BAD REQUEST"
256
    status = 400
257
    data = "Method not allowed.\n"
258
    return (message, data, status)
259

    
260

    
261
def _mock_request(conn, method, url, **kwargs):
262
    """This request behaves like original Astakos does"""
263
    if api_tokens == url:
264
        return _req_tokens(conn, method, url, **kwargs)
265
    elif api_usercatalogs == url:
266
        return _req_catalogs(conn, method, url, **kwargs)
267
    elif api_resources == url:
268
        return _req_resources(conn, method, url, **kwargs)
269
    elif api_quotas == url:
270
        return _req_quotas(conn, method, url, **kwargs)
271
    elif url.startswith(api_commissions):
272
        return _req_commission(conn, method, url, **kwargs)
273
    else:
274
        return _request_status_404(conn, method, url, **kwargs)
275

    
276

    
277
def _req_tokens(conn, method, url, **kwargs):
278
    """Return endpoints"""
279
    global token, user, endpoints
280

    
281
    # Check input
282
    if conn.__class__.__name__ != "HTTPSConnection":
283
        return _request_status_302(conn, method, url, **kwargs)
284
    if method != "POST":
285
        return _request_status_400(conn, method, url, **kwargs)
286
    req_token = kwargs['headers'].get('X-Auth-Token')
287
    if req_token != token['id']:
288
        return _request_status_401(conn, method, url, **kwargs)
289

    
290
    if 'body' in kwargs:
291
        # Return endpoints with authenticate info
292
        return ("", simplejson.dumps(endpoints_with_info), 200)
293
    else:
294
        # Return endpoints without authenticate info
295
        return ("", simplejson.dumps(endpoints), 200)
296

    
297

    
298
def _req_catalogs(conn, method, url, **kwargs):
299
    """Return user catalogs"""
300
    global token, user
301

    
302
    # Check input
303
    if conn.__class__.__name__ != "HTTPSConnection":
304
        return _request_status_302(conn, method, url, **kwargs)
305
    if method != "POST":
306
        return _request_status_400(conn, method, url, **kwargs)
307
    req_token = kwargs['headers'].get('X-Auth-Token')
308
    if req_token != token['id']:
309
        return _request_status_401(conn, method, url, **kwargs)
310

    
311
    # Return
312
    body = simplejson.loads(kwargs['body'])
313
    if 'uuids' in body:
314
        # Return uuid_catalog
315
        uuids = body['uuids']
316
        catalogs = {}
317
        if user['id'] in uuids:
318
            catalogs[user['id']] = user['name']
319
        return_catalog = {"displayname_catalog": {}, "uuid_catalog": catalogs}
320
    elif 'displaynames' in body:
321
        # Return displayname_catalog
322
        names = body['displaynames']
323
        catalogs = {}
324
        if user['name'] in names:
325
            catalogs[user['name']] = user['id']
326
        return_catalog = {"displayname_catalog": catalogs, "uuid_catalog": {}}
327
    else:
328
        return_catalog = {"displayname_catalog": {}, "uuid_catalog": {}}
329
    return ("", simplejson.dumps(return_catalog), 200)
330

    
331

    
332
def _req_resources(conn, method, url, **kwargs):
333
    """Return quota resources"""
334
    global resources
335

    
336
    # Check input
337
    if conn.__class__.__name__ != "HTTPSConnection":
338
        return _request_status_302(conn, method, url, **kwargs)
339
    if method != "GET":
340
        return _request_status_400(conn, method, url, **kwargs)
341

    
342
    # Return
343
    return ("", simplejson.dumps(resources), 200)
344

    
345

    
346
def _req_quotas(conn, method, url, **kwargs):
347
    """Return quotas for user_1"""
348
    global token, quotas
349

    
350
    # Check input
351
    if conn.__class__.__name__ != "HTTPSConnection":
352
        return _request_status_302(conn, method, url, **kwargs)
353
    if method != "GET":
354
        return _request_status_400(conn, method, url, **kwargs)
355
    req_token = kwargs['headers'].get('X-Auth-Token')
356
    if req_token != token['id']:
357
        return _request_status_401(conn, method, url, **kwargs)
358

    
359
    # Return
360
    return ("", simplejson.dumps(quotas), 200)
361

    
362

    
363
def _req_commission(conn, method, url, **kwargs):
364
    """Perform a commission for user_1"""
365
    global token, pending_commissions, \
366
        commission_successful_response, commission_failure_response
367

    
368
    # Check input
369
    if conn.__class__.__name__ != "HTTPSConnection":
370
        return _request_status_302(conn, method, url, **kwargs)
371
    req_token = kwargs['headers'].get('X-Auth-Token')
372
    if req_token != token['id']:
373
        return _request_status_401(conn, method, url, **kwargs)
374

    
375
    if method == "POST":
376
        if 'body' not in kwargs:
377
            return _request_status_400(conn, method, url, **kwargs)
378
        body = simplejson.loads(unicode(kwargs['body']))
379
        if re.match('/?'+api_commissions+'$', url) is not None:
380
            # Issue Commission
381
            # Check if we have enough resources to give
382
            if body['provisions'][1]['quantity'] > 420000000:
383
                return ("", simplejson.dumps(commission_failure_response), 413)
384
            else:
385
                return \
386
                    ("", simplejson.dumps(commission_successful_response), 200)
387
        else:
388
            # Issue commission action
389
            serial = url.split('/')[3]
390
            if serial == "action":
391
                # Resolve multiple actions
392
                if body == resolve_commissions_req:
393
                    return ("", simplejson.dumps(resolve_commissions_rep), 200)
394
                else:
395
                    return _request_status_400(conn, method, url, **kwargs)
396
            else:
397
                # Issue action for one commission
398
                if serial != str(57):
399
                    return _request_status_404(conn, method, url, **kwargs)
400
                if len(body) != 1:
401
                    return _request_status_400(conn, method, url, **kwargs)
402
                if "accept" not in body.keys() and "reject" not in body.keys():
403
                    return _request_status_400(conn, method, url, **kwargs)
404
                return ("", "", 200)
405

    
406
    elif method == "GET":
407
        if re.match('/?'+api_commissions+'$', url) is not None:
408
            # Return pending commission
409
            return ("", simplejson.dumps(pending_commissions), 200)
410
        else:
411
            # Return commissions's description
412
            serial = re.sub('/?' + api_commissions, '', url)[1:]
413
            if serial == str(57):
414
                return ("", simplejson.dumps(commission_description), 200)
415
            else:
416
                return _request_status_404(conn, method, url, **kwargs)
417
    else:
418
        return _request_status_400(conn, method, url, **kwargs)
419

    
420

    
421
# --------------------------------------------------------------------
422
# The actual tests
423

    
424
class TestCallAstakos(unittest.TestCase):
425
    """Test cases for function _callAstakos"""
426

    
427
    # Patch astakosclient's _do_request function
428
    def setUp(self):  # noqa
429
        astakosclient._do_request = _mock_request
430

    
431
    # ----------------------------------
432
    # Test the response we get if we send invalid token
433
    def _invalid_token(self, pool):
434
        global auth_url
435
        token = "skaksaFlBl+fasFdaf24sx"
436
        try:
437
            client = AstakosClient(token, auth_url, use_pool=pool)
438
            client.authenticate()
439
        except Unauthorized:
440
            pass
441
        except Exception:
442
            self.fail("Should have returned 401 (Invalid X-Auth-Token)")
443
        else:
444
            self.fail("Should have returned 401 (Invalid X-Auth-Token)")
445

    
446
    def test_invalid_token(self):
447
        """Test _invalid_token without pool"""
448
        self._invalid_token(False)
449

    
450
    def test_invalid_token_pool(self):
451
        """Test _invalid_token using pool"""
452
        self._invalid_token(True)
453

    
454
    # ----------------------------------
455
    # Test the response we get if we send invalid url
456
    def _invalid_url(self, pool):
457
        global token, auth_url
458
        try:
459
            client = AstakosClient(token['id'], auth_url, use_pool=pool)
460
            client._call_astakos("/astakos/api/misspelled")
461
        except NotFound:
462
            pass
463
        except Exception, e:
464
            self.fail("Got \"%s\" instead of 404" % e)
465
        else:
466
            self.fail("Should have returned 404 (Not Found)")
467

    
468
    def test_invalid_url(self):
469
        """Test _invalid_url without pool"""
470
        self._invalid_url(False)
471

    
472
    def test_invalid_url_pool(self):
473
        """Test _invalid_url using pool"""
474
        self._invalid_url(True)
475

    
476
    # ----------------------------------
477
    # Test the response we get if we use an unsupported scheme
478
    def _unsupported_scheme(self, pool):
479
        global token, auth_url
480
        try:
481
            client = AstakosClient(
482
                token['id'], "ftp://example.com", use_pool=pool)
483
            client.authenticate()
484
        except BadValue:
485
            pass
486
        except Exception:
487
            self.fail("Should have raise BadValue Exception")
488
        else:
489
            self.fail("Should have raise BadValue Exception")
490

    
491
    def test_unsupported_scheme(self):
492
        """Test _unsupported_scheme without pool"""
493
        self._unsupported_scheme(False)
494

    
495
    def test_unsupported_scheme_pool(self):
496
        """Test _unsupported_scheme using pool"""
497
        self._unsupported_scheme(True)
498

    
499
    # ----------------------------------
500
    # Test the response we get if we use http instead of https
501
    def _http_scheme(self, pool):
502
        global token
503
        http_auth_url = "http://example.org/identity/v2.0"
504
        try:
505
            client = AstakosClient(token['id'], http_auth_url, use_pool=pool)
506
            client.authenticate()
507
        except AstakosClientException as err:
508
            if err.status != 302:
509
                self.fail("Should have returned 302 (Found)")
510
        else:
511
            self.fail("Should have returned 302 (Found)")
512

    
513
    def test_http_scheme(self):
514
        """Test _http_scheme without pool"""
515
        self._http_scheme(False)
516

    
517
    def test_http_scheme_pool(self):
518
        """Test _http_scheme using pool"""
519
        self._http_scheme(True)
520

    
521
    # ----------------------------------
522
    # Test the response we get if we use authenticate with GET
523
    def _get_authenticate(self, pool):
524
        global token, auth_url
525
        try:
526
            client = AstakosClient(token['id'], auth_url, use_pool=pool)
527
            client._call_astakos(api_tokens, method="GET")
528
        except BadRequest:
529
            pass
530
        except Exception:
531
            self.fail("Should have returned 400 (Method not allowed)")
532
        else:
533
            self.fail("Should have returned 400 (Method not allowed)")
534

    
535
    def test_get_authenticate(self):
536
        """Test _get_authenticate without pool"""
537
        self._get_authenticate(False)
538

    
539
    def test_get_authenticate_pool(self):
540
        """Test _get_authenticate using pool"""
541
        self._get_authenticate(True)
542

    
543
    # ----------------------------------
544
    # Test the response if we request user_catalogs with GET
545
    def _get_user_catalogs(self, pool):
546
        global token, auth_url, api_usercatalogs
547
        try:
548
            client = AstakosClient(token['id'], auth_url, use_pool=pool)
549
            client._call_astakos(api_usercatalogs)
550
        except BadRequest:
551
            pass
552
        except Exception:
553
            self.fail("Should have returned 400 (Method not allowed)")
554
        else:
555
            self.fail("Should have returned 400 (Method not allowed)")
556

    
557
    def test_get_user_catalogs(self):
558
        """Test _get_user_catalogs without pool"""
559
        self._get_user_catalogs(False)
560

    
561
    def test_get_user_catalogs_pool(self):
562
        """Test _get_user_catalogs using pool"""
563
        self._get_user_catalogs(True)
564

    
565

    
566
class TestAuthenticate(unittest.TestCase):
567
    """Test cases for function getUserInfo"""
568

    
569
    # Patch astakosclient's _do_request function
570
    def setUp(self):  # noqa
571
        astakosclient._do_request = _mock_request
572

    
573
    # ----------------------------------
574
    # Test the response we get for invalid token
575
    def _invalid_token(self, pool):
576
        global auth_url
577
        token = "skaksaFlBl+fasFdaf24sx"
578
        try:
579
            client = AstakosClient(token, auth_url, use_pool=pool)
580
            client.authenticate()
581
        except Unauthorized:
582
            pass
583
        except Exception:
584
            self.fail("Should have returned 401 (Invalid X-Auth-Token)")
585
        else:
586
            self.fail("Should have returned 401 (Invalid X-Auth-Token)")
587

    
588
    def test_invalid_token(self):
589
        """Test _invalid_token without pool"""
590
        self._invalid_token(False)
591

    
592
    def test_invalid_token_pool(self):
593
        """Test _invalid_token using pool"""
594
        self._invalid_token(True)
595

    
596
    # ----------------------------------
597
    # Test response for user
598
    def _auth_user(self, pool):
599
        global token, endpoints_with_info, auth_url
600
        try:
601
            client = AstakosClient(token['id'], auth_url, use_pool=pool)
602
            auth_info = client.authenticate()
603
        except Exception as err:
604
            self.fail("Shouldn't raise an Exception: %s" % err)
605
        self.assertEqual(endpoints_with_info, auth_info)
606

    
607
    def test_auth_user(self):
608
        """Test _auth_user without pool"""
609
        self._auth_user(False)
610

    
611
    def test_auth_user_pool(self):
612
        """Test _auth_user for User 1 using pool, with usage"""
613
        self._auth_user(True)
614

    
615

    
616
class TestDisplayNames(unittest.TestCase):
617
    """Test cases for functions getDisplayNames/getDisplayName"""
618

    
619
    # Patch astakosclient's _do_request function
620
    def setUp(self):  # noqa
621
        astakosclient._do_request = _mock_request
622

    
623
    # ----------------------------------
624
    # Test the response we get for invalid token
625
    def test_invalid_token(self):
626
        """Test the response we get for invalid token (without pool)"""
627
        global auth_url
628
        token = "skaksaFlBl+fasFdaf24sx"
629
        try:
630
            client = AstakosClient(token, auth_url)
631
            client.get_usernames(["12412351"])
632
        except Unauthorized:
633
            pass
634
        except Exception:
635
            self.fail("Should have returned 401 (Invalid X-Auth-Token)")
636
        else:
637
            self.fail("Should have returned 401 (Invalid X-Auth-Token)")
638

    
639
    # ----------------------------------
640
    # Get username
641
    def test_username(self):
642
        """Test get_username"""
643
        global token, user, auth_url
644
        try:
645
            client = AstakosClient(token['id'], auth_url,
646
                                   use_pool=False, retry=2)
647
            info = client.get_username(user['id'])
648
        except Exception, e:
649
            self.fail("Shouldn't raise an Exception: %s" % e)
650
        self.assertEqual(info, user['name'])
651

    
652
    # ----------------------------------
653
    # Get info with wrong uuid
654
    def test_no_username(self):
655
        global token, auth_url
656
        try:
657
            client = AstakosClient(token['id'], auth_url)
658
            client.get_username("1234")
659
        except NoUserName:
660
            pass
661
        except:
662
            self.fail("Should have raised NoDisplayName exception")
663
        else:
664
            self.fail("Should have raised NoDisplayName exception")
665

    
666

    
667
class TestGetUUIDs(unittest.TestCase):
668
    """Test cases for functions getUUIDs/getUUID"""
669

    
670
    # Patch astakosclient's _do_request function
671
    def setUp(self):  # noqa
672
        astakosclient._do_request = _mock_request
673

    
674
    # ----------------------------------
675
    # Test the response we get for invalid token
676
    def test_invalid_token(self):
677
        """Test the response we get for invalid token (using pool)"""
678
        global user, auth_url
679
        token = "skaksaFlBl+fasFdaf24sx"
680
        try:
681
            client = AstakosClient(token, auth_url)
682
            client.get_uuids([user['name']])
683
        except Unauthorized:
684
            pass
685
        except Exception:
686
            self.fail("Should have returned 401 (Invalid X-Auth-Token)")
687
        else:
688
            self.fail("Should have returned 401 (Invalid X-Auth-Token)")
689

    
690
    # ----------------------------------
691
    # Get uuid
692
    def test_get_uuid(self):
693
        """Test get_uuid"""
694
        global token, user, auth_url
695
        try:
696
            client = AstakosClient(token['id'], auth_url, retry=1)
697
            catalog = client.get_uuids([user['name']])
698
        except:
699
            self.fail("Shouldn't raise an Exception")
700
        self.assertEqual(catalog[user['name']], user['id'])
701

    
702
    # ----------------------------------
703
    # Get uuid with wrong username
704
    def test_no_uuid(self):
705
        global token, auth_url
706
        try:
707
            client = AstakosClient(token['id'], auth_url)
708
            client.get_uuid("1234")
709
        except NoUUID:
710
            pass
711
        except:
712
            self.fail("Should have raised NoUUID exception")
713
        else:
714
            self.fail("Should have raised NoUUID exception")
715

    
716

    
717
class TestResources(unittest.TestCase):
718
    """Test cases for function get_resources"""
719

    
720
    # Patch astakosclient's _do_request function
721
    def setUp(self):  # noqa
722
        astakosclient._do_request = _mock_request
723

    
724
    # ----------------------------------
725
    def test_get_resources(self):
726
        """Test function call of get_resources"""
727
        global resources, auth_url, token
728
        try:
729
            client = AstakosClient(token['id'], auth_url, retry=1)
730
            result = client.get_resources()
731
        except Exception as err:
732
            self.fail("Shouldn't raise Exception %s" % err)
733
        self.assertEqual(resources, result)
734

    
735

    
736
class TestQuotas(unittest.TestCase):
737
    """Test cases for function get_quotas"""
738

    
739
    # Patch astakosclient's _do_request function
740
    def setUp(self):  # noqa
741
        astakosclient._do_request = _mock_request
742

    
743
    # ----------------------------------
744
    def test_get_quotas(self):
745
        """Test function call of get_quotas"""
746
        global quotas, token, auth_url
747
        try:
748
            client = AstakosClient(token['id'], auth_url)
749
            result = client.get_quotas()
750
        except Exception as err:
751
            self.fail("Shouldn't raise Exception %s" % err)
752
        self.assertEqual(quotas, result)
753

    
754
    # -----------------------------------
755
    def test_get_quotas_unauthorized(self):
756
        """Test function call of get_quotas with wrong token"""
757
        global auth_url
758
        token = "buahfhsda"
759
        try:
760
            client = AstakosClient(token, auth_url)
761
            client.get_quotas()
762
        except Unauthorized:
763
            pass
764
        except Exception as err:
765
            self.fail("Shouldn't raise Exception %s" % err)
766
        else:
767
            self.fail("Should have raised Unauthorized Exception")
768

    
769

    
770
class TestCommissions(unittest.TestCase):
771
    """Test cases for quota commissions"""
772

    
773
    # Patch astakosclient's _do_request function
774
    def setUp(self):  # noqa
775
        astakosclient._do_request = _mock_request
776

    
777
    # ----------------------------------
778
    def test_issue_commission(self):
779
        """Test function call of issue_commission"""
780
        global token, commission_request, commission_successful_reqsponse
781
        global auth_url
782
        try:
783
            client = AstakosClient(token['id'], auth_url)
784
            response = client.issue_commission(commission_request)
785
        except Exception as err:
786
            self.fail("Shouldn't raise Exception %s" % err)
787
        self.assertEqual(response, commission_successful_response['serial'])
788

    
789
    # ----------------------------------
790
    def test_issue_commission_quota_limit(self):
791
        """Test function call of issue_commission with limit exceeded"""
792
        global token, commission_request, commission_failure_response
793
        global auth_url
794
        new_request = dict(commission_request)
795
        new_request['provisions'][1]['quantity'] = 520000000
796
        try:
797
            client = AstakosClient(token['id'], auth_url)
798
            client.issue_commission(new_request)
799
        except QuotaLimit:
800
            pass
801
        except Exception as err:
802
            self.fail("Shouldn't raise Exception %s" % err)
803
        else:
804
            self.fail("Should have raised QuotaLimit Exception")
805

    
806
    # ----------------------------------
807
    def test_issue_one_commission(self):
808
        """Test function call of issue_one_commission"""
809
        global token, commission_successful_response, auth_url
810
        try:
811
            client = AstakosClient(token['id'], auth_url)
812
            response = client.issue_one_commission(
813
                "c02f315b-7d84-45bc-a383-552a3f97d2ad",
814
                "system", {"cyclades.vm": 1, "cyclades.ram": 30000})
815
        except Exception as err:
816
            self.fail("Shouldn't have raised Exception %s" % err)
817
        self.assertEqual(response, commission_successful_response['serial'])
818

    
819
    # ----------------------------------
820
    def test_get_pending_commissions(self):
821
        """Test function call of get_pending_commissions"""
822
        global token, pending_commissions, auth_url
823
        try:
824
            client = AstakosClient(token['id'], auth_url)
825
            response = client.get_pending_commissions()
826
        except Exception as err:
827
            self.fail("Shouldn't raise Exception %s" % err)
828
        self.assertEqual(response, pending_commissions)
829

    
830
    # ----------------------------------
831
    def test_get_commission_info(self):
832
        """Test function call of get_commission_info"""
833
        global token, commission_description, auth_url
834
        try:
835
            client = AstakosClient(token['id'], auth_url,
836
                                   use_pool=True, pool_size=2)
837
            response = client.get_commission_info(57)
838
        except Exception as err:
839
            self.fail("Shouldn't raise Exception %s" % err)
840
        self.assertEqual(response, commission_description)
841

    
842
    # ----------------------------------
843
    def test_get_commission_info_not_found(self):
844
        """Test function call of get_commission_info with invalid serial"""
845
        global token, auth_url
846
        try:
847
            client = AstakosClient(token['id'], auth_url)
848
            client.get_commission_info("57lala")
849
        except NotFound:
850
            pass
851
        except Exception as err:
852
            self.fail("Shouldn't raise Exception %s" % err)
853
        else:
854
            self.fail("Should have raised NotFound")
855

    
856
    # ----------------------------------
857
    def test_get_commission_info_without_serial(self):
858
        """Test function call of get_commission_info without serial"""
859
        global token, auth_url
860
        try:
861
            client = AstakosClient(token['id'], auth_url)
862
            client.get_commission_info(None)
863
        except BadValue:
864
            pass
865
        except Exception as err:
866
            self.fail("Shouldn't raise Exception %s" % err)
867
        else:
868
            self.fail("Should have raise BadValue")
869

    
870
    # ----------------------------------
871
    def test_commision_action(self):
872
        """Test function call of commision_action with wrong action"""
873
        global token, auth_url
874
        try:
875
            client = AstakosClient(token['id'], auth_url)
876
            client.commission_action(57, "lala")
877
        except BadRequest:
878
            pass
879
        except Exception as err:
880
            self.fail("Shouldn't raise Exception %s" % err)
881
        else:
882
            self.fail("Should have raised BadRequest")
883

    
884
    # ----------------------------------
885
    def test_accept_commission(self):
886
        """Test function call of accept_commission"""
887
        global token, auth_url
888
        try:
889
            client = AstakosClient(token['id'], auth_url)
890
            client.accept_commission(57)
891
        except Exception as err:
892
            self.fail("Shouldn't raise Exception %s" % err)
893

    
894
    # ----------------------------------
895
    def test_reject_commission(self):
896
        """Test function call of reject_commission"""
897
        global token, auth_url
898
        try:
899
            client = AstakosClient(token['id'], auth_url)
900
            client.reject_commission(57)
901
        except Exception as err:
902
            self.fail("Shouldn't raise Exception %s" % err)
903

    
904
    # ----------------------------------
905
    def test_accept_commission_not_found(self):
906
        """Test function call of accept_commission with wrong serial"""
907
        global token, auth_url
908
        try:
909
            client = AstakosClient(token['id'], auth_url)
910
            client.reject_commission(20)
911
        except NotFound:
912
            pass
913
        except Exception as err:
914
            self.fail("Shouldn't raise Exception %s" % err)
915
        else:
916
            self.fail("Should have raised NotFound")
917

    
918
    # ----------------------------------
919
    def test_resolve_commissions(self):
920
        """Test function call of resolve_commissions"""
921
        global token, auth_url
922
        try:
923
            client = AstakosClient(token['id'], auth_url)
924
            result = client.resolve_commissions([56, 57], [56, 58, 59])
925
        except Exception as err:
926
            self.fail("Shouldn't raise Exception %s" % err)
927
        self.assertEqual(result, resolve_commissions_rep)
928

    
929

    
930
# ----------------------------
931
# Run tests
932
if __name__ == "__main__":
933
    unittest.main()