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

"""Unit Tests for the astakos-client module

Provides unit tests for the code implementing
the astakos client library

"""

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 56 57 58 59 60
try:
    import unittest2 as unittest
except ImportError:
    if sys.version_info < (2, 7):
        raise Exception("The unittest2 package is required for Python < 2.7")
    import unittest
61 62 63 64


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

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

user = {
    'id': "73917abc-abcd-477e-a1f1-1763abcdefab",
    'name': "Example User One",
    'roles': [{u'id': 1, u'name': u'default'},
              {u'id': 5, u'name': u'academic-login-users'}],
    'roles_links': []
    }
92 93 94 95 96 97 98 99 100

resources = {
    "cyclades.ram": {
        "unit": "bytes",
        "description": "Virtual machine memory",
        "service": "cyclades"}}

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

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

127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
quotas = {
    "system": {
        "cyclades.ram": {
            "pending": 0,
            "limit": 1073741824,
            "usage": 536870912},
        "cyclades.vm": {
            "pending": 0,
            "limit": 2,
            "usage": 2}},
    "project:1": {
        "cyclades.ram": {
            "pending": 0,
            "limit": 2147483648,
            "usage": 2147483648},
        "cyclades.vm": {
            "pending": 1,
            "limit": 5,
            "usage": 2}}}

commission_request = {
    "force": False,
    "auto_accept": False,
    "name": "my commission",
    "provisions": [
        {
            "holder": "c02f315b-7d84-45bc-a383-552a3f97d2ad",
            "source": "system",
            "resource": "cyclades.vm",
            "quantity": 1
        },
        {
            "holder": "c02f315b-7d84-45bc-a383-552a3f97d2ad",
            "source": "system",
            "resource": "cyclades.ram",
            "quantity": 30000
        }]}

commission_successful_response = {"serial": 57}

commission_failure_response = {
    "overLimit": {
        "message": "a human-readable error message",
        "code": 413,
        "data": {
            "provision": {
                "holder": "c02f315b-7d84-45bc-a383-552a3f97d2ad",
                "source": "system",
                "resource": "cyclades.ram",
                "quantity": 520000000},
            "name": "NoCapacityError",
            "limit": 600000000,
            "usage": 180000000}}}

pending_commissions = [100, 200]

commission_description = {
    "serial": 57,
    "issue_time": "2013-04-08T10:19:15.0373+00:00",
    "name": "a commission",
    "provisions": [
        {
            "holder": "c02f315b-7d84-45bc-a383-552a3f97d2ad",
            "source": "system",
            "resource": "cyclades.vm",
            "quantity": 1
        },
        {
            "holder": "c02f315b-7d84-45bc-a383-552a3f97d2ad",
            "source": "system",
            "resource": "cyclades.ram",
            "quantity": 536870912
        }]}

resolve_commissions_req = {
    "accept": [56, 57],
    "reject": [56, 58, 59]}

resolve_commissions_rep = {
    "accepted": [57],
    "rejected": [59],
    "failed": [
        [56, {
            "badRequest": {
                "message": "cannot both accept and reject serial 56",
                "code": 400}}],
        [58, {
            "itemNotFound": {
                "message": "serial 58 does not exist",
                "code": 404}}]]}

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 238 239 240 241 242 243 244
def _request_status_403(conn, method, url, **kwargs):
    """This request returns 403"""
    message = "UNAUTHORIZED"
    status = 403
    data = "Forbidden"
    return (message, data, status)


245
def _request_status_401(conn, method, url, **kwargs):
246
    """This request returns 401"""
247
    message = "UNAUTHORIZED"
248 249
    status = 401
    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 257
    status = 400
    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 264
    if api_tokens == url:
        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 278 279
def _req_tokens(conn, method, url, **kwargs):
    """Return endpoints"""
    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 287
    req_token = kwargs['headers'].get('X-Auth-Token')
    if req_token != token['id']:
288
        return _request_status_401(conn, method, url, **kwargs)
289

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

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 308
    req_token = kwargs['headers'].get('X-Auth-Token')
    if req_token != token['id']:
309
        return _request_status_401(conn, method, url, **kwargs)
310 311 312

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


332 333 334 335 336 337 338 339 340 341 342 343 344 345
def _req_resources(conn, method, url, **kwargs):
    """Return quota resources"""
    global resources

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

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


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

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

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


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

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

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

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


421 422 423 424 425 426
# --------------------------------------------------------------------
# The actual tests

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

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 438
            client = AstakosClient(token, auth_url, use_pool=pool)
            client.authenticate()
439
        except Unauthorized:
440 441 442
            pass
        except Exception:
            self.fail("Should have returned 401 (Invalid X-Auth-Token)")
443 444 445
        else:
            self.fail("Should have returned 401 (Invalid X-Auth-Token)")

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

450 451 452
    def test_invalid_token_pool(self):
        """Test _invalid_token using pool"""
        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 460
            client = AstakosClient(token['id'], auth_url, use_pool=pool)
            client._call_astakos("/astakos/api/misspelled")
461
        except NotFound:
462
            pass
463 464
        except Exception, e:
            self.fail("Got \"%s\" instead of 404" % e)
465 466 467
        else:
            self.fail("Should have returned 404 (Not Found)")

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

472 473 474
    def test_invalid_url_pool(self):
        """Test _invalid_url using pool"""
        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 482 483
            client = AstakosClient(
                token['id'], "ftp://example.com", use_pool=pool)
            client.authenticate()
484
        except BadValue:
485 486
            pass
        except Exception:
487
            self.fail("Should have raise BadValue Exception")
488
        else:
489
            self.fail("Should have raise BadValue Exception")
490

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

495 496 497
    def test_unsupported_scheme_pool(self):
        """Test _unsupported_scheme using pool"""
        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 506
            client = AstakosClient(token['id'], http_auth_url, use_pool=pool)
            client.authenticate()
507 508
        except AstakosClientException as err:
            if err.status != 302:
509 510 511 512
                self.fail("Should have returned 302 (Found)")
        else:
            self.fail("Should have returned 302 (Found)")

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

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

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

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

539 540 541
    def test_get_authenticate_pool(self):
        """Test _get_authenticate using pool"""
        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 549
            client = AstakosClient(token['id'], auth_url, use_pool=pool)
            client._call_astakos(api_usercatalogs)
550
        except BadRequest:
551 552 553
            pass
        except Exception:
            self.fail("Should have returned 400 (Method not allowed)")
554 555 556
        else:
            self.fail("Should have returned 400 (Method not allowed)")

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

561 562 563
    def test_get_user_catalogs_pool(self):
        """Test _get_user_catalogs using pool"""
        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 580
            client = AstakosClient(token, auth_url, use_pool=pool)
            client.authenticate()
581
        except Unauthorized:
582 583 584
            pass
        except Exception:
            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 589 590
    def test_invalid_token(self):
        """Test _invalid_token without pool"""
        self._invalid_token(False)
591

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

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

607 608
    def test_auth_user(self):
        """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 617 618
class TestDisplayNames(unittest.TestCase):
    """Test cases for functions getDisplayNames/getDisplayName"""

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

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 631
            client = AstakosClient(token, auth_url)
            client.get_usernames(["12412351"])
632
        except Unauthorized:
633 634 635
            pass
        except Exception:
            self.fail("Should have returned 401 (Invalid X-Auth-Token)")
636 637 638 639
        else:
            self.fail("Should have returned 401 (Invalid X-Auth-Token)")

    # ----------------------------------
640 641 642 643 644 645 646 647 648 649 650
    # Get username
    def test_username(self):
        """Test get_username"""
        global token, user, auth_url
        try:
            client = AstakosClient(token['id'], auth_url,
                                   use_pool=False, retry=2)
            info = client.get_username(user['id'])
        except Exception, e:
            self.fail("Shouldn't raise an Exception: %s" % e)
        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 658
            client = AstakosClient(token['id'], auth_url)
            client.get_username("1234")
659
        except NoUserName:
660 661 662 663 664 665
            pass
        except:
            self.fail("Should have raised NoDisplayName exception")
        else:
            self.fail("Should have raised NoDisplayName exception")

666

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

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

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 682
            client = AstakosClient(token, auth_url)
            client.get_uuids([user['name']])
683
        except Unauthorized:
684 685 686
            pass
        except Exception:
            self.fail("Should have returned 401 (Invalid X-Auth-Token)")
687 688 689 690
        else:
            self.fail("Should have returned 401 (Invalid X-Auth-Token)")

    # ----------------------------------
691 692 693 694
    # Get uuid
    def test_get_uuid(self):
        """Test get_uuid"""
        global token, user, auth_url
695
        try:
696 697
            client = AstakosClient(token['id'], auth_url, retry=1)
            catalog = client.get_uuids([user['name']])
698 699
        except:
            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 708
            client = AstakosClient(token['id'], auth_url)
            client.get_uuid("1234")
709 710 711 712 713 714 715
        except NoUUID:
            pass
        except:
            self.fail("Should have raised NoUUID exception")
        else:
            self.fail("Should have raised NoUUID exception")

716

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

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

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


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

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

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

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


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 776
        astakosclient._do_request = _mock_request

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 784
            client = AstakosClient(token['id'], auth_url)
            response = client.issue_commission(commission_request)
785 786 787 788 789
        except Exception as err:
            self.fail("Shouldn't raise Exception %s" % err)
        self.assertEqual(response, commission_successful_response['serial'])

    # ----------------------------------
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 795 796
        new_request = dict(commission_request)
        new_request['provisions'][1]['quantity'] = 520000000
        try:
797 798
            client = AstakosClient(token['id'], auth_url)
            client.issue_commission(new_request)
799 800 801 802 803 804 805
        except QuotaLimit:
            pass
        except Exception as err:
            self.fail("Shouldn't raise Exception %s" % err)
        else:
            self.fail("Should have raised QuotaLimit Exception")

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

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

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

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

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

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

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

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

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

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

929

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