Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / tests / api.py @ ab7ca50a

History | View | Annotate | Download (18 kB)

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

    
34
from astakos.im.tests.common import *
35
from astakos.im.activation_backends import get_backend
36

    
37
from django.test import TestCase
38

    
39
from urllib import quote
40
from urlparse import urlparse, parse_qs
41
#from xml.dom import minidom
42

    
43
import json
44

    
45
ROOT = '/astakos/api/'
46
u = lambda url: ROOT + url
47

    
48

    
49
class QuotaAPITest(TestCase):
50
    def test_0(self):
51
        client = Client()
52
        # custom service resources
53
        service1 = Service.objects.create(
54
            name="service1", api_url="http://service1.api")
55
        resource11 = {"name": "service1.resource11",
56
                      "desc": "resource11 desc",
57
                      "allow_in_projects": True}
58
        r, _ = resources.add_resource(service1, resource11)
59
        resources.update_resource(r, 100)
60
        resource12 = {"name": "service1.resource12",
61
                      "desc": "resource11 desc",
62
                      "unit": "bytes"}
63
        r, _ = resources.add_resource(service1, resource12)
64
        resources.update_resource(r, 1024)
65

    
66
        # create user
67
        user = get_local_user('test@grnet.gr')
68
        quotas.qh_sync_user(user)
69

    
70
        # create another service
71
        service2 = Service.objects.create(
72
            name="service2", api_url="http://service2.api")
73
        resource21 = {"name": "service2.resource21",
74
                      "desc": "resource11 desc",
75
                      "allow_in_projects": False}
76
        r, _ = resources.add_resource(service2, resource21)
77
        resources.update_resource(r, 3)
78

    
79
        resource_names = [r['name'] for r in
80
                          [resource11, resource12, resource21]]
81

    
82
        # get resources
83
        r = client.get(u('resources'))
84
        self.assertEqual(r.status_code, 200)
85
        body = json.loads(r.content)
86
        for name in resource_names:
87
            assertIn(name, body)
88

    
89
        # get quota
90
        r = client.get(u('quotas'))
91
        self.assertEqual(r.status_code, 401)
92

    
93
        headers = {'HTTP_X_AUTH_TOKEN': user.auth_token}
94
        r = client.get(u('quotas/'), **headers)
95
        self.assertEqual(r.status_code, 200)
96
        body = json.loads(r.content)
97
        system_quota = body['system']
98
        assertIn('system', body)
99
        for name in resource_names:
100
            assertIn(name, system_quota)
101

    
102
        r = client.get(u('service_quotas'))
103
        self.assertEqual(r.status_code, 401)
104

    
105
        s1_headers = {'HTTP_X_AUTH_TOKEN': service1.auth_token}
106
        r = client.get(u('service_quotas'), **s1_headers)
107
        self.assertEqual(r.status_code, 200)
108
        body = json.loads(r.content)
109
        assertIn(user.uuid, body)
110

    
111
        r = client.get(u('commissions'), **s1_headers)
112
        self.assertEqual(r.status_code, 200)
113
        body = json.loads(r.content)
114
        self.assertEqual(body, [])
115

    
116
        # issue some commissions
117
        commission_request = {
118
            "force": False,
119
            "auto_accept": False,
120
            "name": "my commission",
121
            "provisions": [
122
                {
123
                    "holder": user.uuid,
124
                    "source": "system",
125
                    "resource": resource11['name'],
126
                    "quantity": 1
127
                },
128
                {
129
                    "holder": user.uuid,
130
                    "source": "system",
131
                    "resource": resource12['name'],
132
                    "quantity": 30000
133
                }]}
134

    
135
        post_data = json.dumps(commission_request)
136
        r = client.post(u('commissions'), post_data,
137
                        content_type='application/json', **s1_headers)
138
        self.assertEqual(r.status_code, 413)
139

    
140
        commission_request = {
141
            "force": False,
142
            "auto_accept": False,
143
            "name": "my commission",
144
            "provisions": [
145
                {
146
                    "holder": user.uuid,
147
                    "source": "system",
148
                    "resource": resource11['name'],
149
                    "quantity": 1
150
                },
151
                {
152
                    "holder": user.uuid,
153
                    "source": "system",
154
                    "resource": resource12['name'],
155
                    "quantity": 100
156
                }]}
157

    
158
        post_data = json.dumps(commission_request)
159
        r = client.post(u('commissions'), post_data,
160
                        content_type='application/json', **s1_headers)
161
        self.assertEqual(r.status_code, 201)
162
        body = json.loads(r.content)
163
        serial = body['serial']
164
        self.assertEqual(serial, 1)
165

    
166
        post_data = json.dumps(commission_request)
167
        r = client.post(u('commissions'), post_data,
168
                        content_type='application/json', **s1_headers)
169
        self.assertEqual(r.status_code, 201)
170
        body = json.loads(r.content)
171
        self.assertEqual(body['serial'], 2)
172

    
173
        post_data = json.dumps(commission_request)
174
        r = client.post(u('commissions'), post_data,
175
                        content_type='application/json', **s1_headers)
176
        self.assertEqual(r.status_code, 201)
177
        body = json.loads(r.content)
178
        self.assertEqual(body['serial'], 3)
179

    
180
        r = client.get(u('commissions'), **s1_headers)
181
        self.assertEqual(r.status_code, 200)
182
        body = json.loads(r.content)
183
        self.assertEqual(body, [1, 2, 3])
184

    
185
        r = client.get(u('commissions/' + str(serial)), **s1_headers)
186
        self.assertEqual(r.status_code, 200)
187
        body = json.loads(r.content)
188
        self.assertEqual(body['serial'], serial)
189
        assertIn('issue_time', body)
190
        self.assertEqual(body['provisions'], commission_request['provisions'])
191
        self.assertEqual(body['name'], commission_request['name'])
192

    
193
        r = client.get(u('service_quotas?user=' + user.uuid), **s1_headers)
194
        self.assertEqual(r.status_code, 200)
195
        body = json.loads(r.content)
196
        user_quota = body[user.uuid]
197
        system_quota = user_quota['system']
198
        r11 = system_quota[resource11['name']]
199
        self.assertEqual(r11['usage'], 3)
200
        self.assertEqual(r11['pending'], 3)
201

    
202
        # resolve pending commissions
203
        resolve_data = {
204
            "accept": [1, 3],
205
            "reject": [2, 3, 4],
206
        }
207
        post_data = json.dumps(resolve_data)
208

    
209
        r = client.post(u('commissions/action'), post_data,
210
                        content_type='application/json', **s1_headers)
211
        self.assertEqual(r.status_code, 200)
212
        body = json.loads(r.content)
213
        self.assertEqual(body['accepted'], [1])
214
        self.assertEqual(body['rejected'], [2])
215
        failed = body['failed']
216
        self.assertEqual(len(failed), 2)
217

    
218
        r = client.get(u('commissions/' + str(serial)), **s1_headers)
219
        self.assertEqual(r.status_code, 404)
220

    
221
        # auto accept
222
        commission_request = {
223
            "auto_accept": True,
224
            "name": "my commission",
225
            "provisions": [
226
                {
227
                    "holder": user.uuid,
228
                    "source": "system",
229
                    "resource": resource11['name'],
230
                    "quantity": 1
231
                },
232
                {
233
                    "holder": user.uuid,
234
                    "source": "system",
235
                    "resource": resource12['name'],
236
                    "quantity": 100
237
                }]}
238

    
239
        post_data = json.dumps(commission_request)
240
        r = client.post(u('commissions'), post_data,
241
                        content_type='application/json', **s1_headers)
242
        self.assertEqual(r.status_code, 201)
243
        body = json.loads(r.content)
244
        serial = body['serial']
245
        self.assertEqual(serial, 4)
246

    
247
        r = client.get(u('commissions/' + str(serial)), **s1_headers)
248
        self.assertEqual(r.status_code, 404)
249

    
250
        # malformed
251
        commission_request = {
252
            "auto_accept": True,
253
            "name": "my commission",
254
            "provisions": [
255
                {
256
                    "holder": user.uuid,
257
                    "source": "system",
258
                    "resource": resource11['name'],
259
                }
260
            ]}
261

    
262
        post_data = json.dumps(commission_request)
263
        r = client.post(u('commissions'), post_data,
264
                        content_type='application/json', **s1_headers)
265
        self.assertEqual(r.status_code, 400)
266

    
267
        commission_request = {
268
            "auto_accept": True,
269
            "name": "my commission",
270
            "provisions": "dummy"}
271

    
272
        post_data = json.dumps(commission_request)
273
        r = client.post(u('commissions'), post_data,
274
                        content_type='application/json', **s1_headers)
275
        self.assertEqual(r.status_code, 400)
276

    
277
        r = client.post(u('commissions'), commission_request,
278
                        content_type='application/json', **s1_headers)
279
        self.assertEqual(r.status_code, 400)
280

    
281
        # no holding
282
        commission_request = {
283
            "auto_accept": True,
284
            "name": "my commission",
285
            "provisions": [
286
                {
287
                    "holder": user.uuid,
288
                    "source": "system",
289
                    "resource": "non existent",
290
                    "quantity": 1
291
                },
292
                {
293
                    "holder": user.uuid,
294
                    "source": "system",
295
                    "resource": resource12['name'],
296
                    "quantity": 100
297
                }]}
298

    
299
        post_data = json.dumps(commission_request)
300
        r = client.post(u('commissions'), post_data,
301
                        content_type='application/json', **s1_headers)
302
        self.assertEqual(r.status_code, 404)
303

    
304
        # release
305
        commission_request = {
306
            "provisions": [
307
                {
308
                    "holder": user.uuid,
309
                    "source": "system",
310
                    "resource": resource11['name'],
311
                    "quantity": -1
312
                }
313
            ]}
314

    
315
        post_data = json.dumps(commission_request)
316
        r = client.post(u('commissions'), post_data,
317
                        content_type='application/json', **s1_headers)
318
        self.assertEqual(r.status_code, 201)
319
        body = json.loads(r.content)
320
        serial = body['serial']
321

    
322
        accept_data = {'accept': ""}
323
        post_data = json.dumps(accept_data)
324
        r = client.post(u('commissions/' + str(serial) + '/action'), post_data,
325
                        content_type='application/json', **s1_headers)
326
        self.assertEqual(r.status_code, 200)
327

    
328
        reject_data = {'reject': ""}
329
        post_data = json.dumps(accept_data)
330
        r = client.post(u('commissions/' + str(serial) + '/action'), post_data,
331
                        content_type='application/json', **s1_headers)
332
        self.assertEqual(r.status_code, 404)
333

    
334
        # force
335
        commission_request = {
336
            "force": True,
337
            "provisions": [
338
                {
339
                    "holder": user.uuid,
340
                    "source": "system",
341
                    "resource": resource11['name'],
342
                    "quantity": 100
343
                }]}
344

    
345
        post_data = json.dumps(commission_request)
346
        r = client.post(u('commissions'), post_data,
347
                        content_type='application/json', **s1_headers)
348
        self.assertEqual(r.status_code, 201)
349

    
350
        commission_request = {
351
            "force": True,
352
            "provisions": [
353
                {
354
                    "holder": user.uuid,
355
                    "source": "system",
356
                    "resource": resource11['name'],
357
                    "quantity": -200
358
                }]}
359

    
360
        post_data = json.dumps(commission_request)
361
        r = client.post(u('commissions'), post_data,
362
                        content_type='application/json', **s1_headers)
363
        self.assertEqual(r.status_code, 413)
364

    
365
        r = client.get(u('quotas'), **headers)
366
        self.assertEqual(r.status_code, 200)
367
        body = json.loads(r.content)
368
        system_quota = body['system']
369
        r11 = system_quota[resource11['name']]
370
        self.assertEqual(r11['usage'], 102)
371
        self.assertEqual(r11['pending'], 101)
372

    
373

    
374
class TokensApiTest(TestCase):
375
    def setUp(self):
376
        backend = activation_backends.get_backend()
377

    
378
        self.user1 = AstakosUser.objects.create(
379
            email='test1', email_verified=True, moderated=True,
380
            is_rejected=False)
381
        backend.activate_user(self.user1)
382
        assert self.user1.is_active is True
383

    
384
        self.user2 = AstakosUser.objects.create(
385
            email='test2', email_verified=True, moderated=True,
386
            is_rejected=False)
387
        backend.activate_user(self.user2)
388
        assert self.user2.is_active is True
389

    
390
        Service(name='service1', url='http://localhost/service1',
391
                api_url='http://localhost/api/service1').save()
392
        Service(name='service2', url='http://localhost/service2',
393
                api_url='http://localhost/api/service2').save()
394
        Service(name='service3', url='http://localhost/service3',
395
                api_url='http://localhost/api/service3').save()
396

    
397
    def test_get_endpoints(self):
398
        client = Client()
399

    
400
        # Check no token
401
        url = '/astakos/api/tokens/%s/endpoints' % quote(self.user1.auth_token)
402
        r = client.get(url)
403
        self.assertEqual(r.status_code, 401)
404

    
405
        # Check in active user token
406
        inactive_user = AstakosUser.objects.create(email='test3')
407
        url = '/astakos/api/tokens/%s/endpoints' % quote(
408
            inactive_user.auth_token)
409
        r = client.get(url)
410
        self.assertEqual(r.status_code, 401)
411

    
412
        # Check invalid user token in path
413
        url = '/astakos/api/tokens/nouser/endpoints'
414
        r = client.get(url)
415
        self.assertEqual(r.status_code, 401)
416

    
417

    
418
        # Check forbidden
419
        url = '/astakos/api/tokens/%s/endpoints' % quote(self.user1.auth_token)
420
        headers = {'HTTP_X_AUTH_TOKEN': AstakosUser.objects.create(
421
            email='test4').auth_token}
422
        r = client.get(url, **headers)
423
        self.assertEqual(r.status_code, 401)
424

    
425

    
426
        # Check bad request method
427
        url = '/astakos/api/tokens/%s/endpoints' % quote(self.user1.auth_token)
428
        r = client.post(url)
429
        self.assertEqual(r.status_code, 400)
430

    
431
        # Check forbidden
432
        url = '/astakos/api/tokens/%s/endpoints' % quote(self.user1.auth_token)
433
        headers = {'HTTP_X_AUTH_TOKEN': self.user2.auth_token}
434
        r = client.get(url, **headers)
435
        self.assertEqual(r.status_code, 403)
436

    
437
        url = '/astakos/api/tokens/%s/endpoints' % quote(self.user1.auth_token)
438
        headers = {'HTTP_X_AUTH_TOKEN': self.user1.auth_token}
439
        r = client.get(url, **headers)
440
        self.assertEqual(r.status_code, 200)
441
        self.assertEqual(r['Content-Type'], 'application/json; charset=UTF-8')
442
        try:
443
            body = json.loads(r.content)
444
        except:
445
            self.fail('json format expected')
446
        endpoints = body.get('endpoints')
447
        self.assertEqual(len(endpoints), 3)
448

    
449
        # Check belongsTo BadRequest
450
        url = '/astakos/api/tokens/%s/endpoints?belongsTo=%s' % (
451
            quote(self.user1.auth_token), quote(self.user2.uuid))
452
        headers = {'HTTP_X_AUTH_TOKEN': self.user1.auth_token}
453
        r = client.get(url, **headers)
454
        self.assertEqual(r.status_code, 400)
455

    
456
         # Check xml serialization
457
        url = '/astakos/api/tokens/%s/endpoints?format=xml' %\
458
            quote(self.user1.auth_token)
459
        headers = {'HTTP_X_AUTH_TOKEN': self.user1.auth_token}
460
        r = client.get(url, **headers)
461
        self.assertEqual(r.status_code, 200)
462
        self.assertEqual(r['Content-Type'], 'application/xml; charset=UTF-8')
463
#        try:
464
#            body = minidom.parseString(r.content)
465
#        except Exception, e:
466
#            self.fail('xml format expected')
467
        endpoints = body.get('endpoints')
468
        self.assertEqual(len(endpoints), 3)
469

    
470
        # Check limit
471
        url = '/astakos/api/tokens/%s/endpoints?limit=2' %\
472
            quote(self.user1.auth_token)
473
        headers = {'HTTP_X_AUTH_TOKEN': self.user1.auth_token}
474
        r = client.get(url, **headers)
475
        self.assertEqual(r.status_code, 200)
476
        body = json.loads(r.content)
477
        endpoints = body.get('endpoints')
478
        self.assertEqual(len(endpoints), 2)
479

    
480
        endpoint_link = body.get('endpoint_links', [])[0]
481
        next = endpoint_link.get('href')
482
        p = urlparse(next)
483
        params = parse_qs(p.query)
484
        self.assertTrue('limit' in params)
485
        self.assertTrue('marker' in params)
486
        self.assertEqual(params['marker'][0], '2')
487

    
488
        # Check marker
489
        headers = {'HTTP_X_AUTH_TOKEN': self.user1.auth_token}
490
        r = client.get(next, **headers)
491
        self.assertEqual(r.status_code, 200)
492
        body = json.loads(r.content)
493
        endpoints = body.get('endpoints')
494
        self.assertEqual(len(endpoints), 1)