Statistics
| Branch: | Tag: | Revision:

root / snf-quotaholder-app / quotaholder_django / test / simpletests.py @ 39462ae0

History | View | Annotate | Download (19.8 kB)

1
# Copyright 2012 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 config import QHTestCase
35
from config import run_test_case
36
from config import rand_string
37
from config import printf
38

    
39
from synnefo.lib.commissioning import CallError
40
from synnefo.lib.quotaholder.api import (
41
                            InvalidDataError,
42
                            InvalidKeyError, NoEntityError,
43
                            NoQuantityError, NoCapacityError,
44
                            ExportLimitError, ImportLimitError,
45
                            DuplicateError)
46
from synnefo.lib.quotaholder.api.quotaholder import (
47
    Name, Key, Quantity, Capacity, ImportLimit, ExportLimit, Resource, Flags,
48
    Imported, Exported, Returned, Released)
49

    
50
QH_MAX_INT = 10**32
51

    
52
DEFAULT_HOLDING = (0, 0, 0, 0)
53

    
54
class QHAPITest(QHTestCase):
55

    
56
    @classmethod
57
    def setUpClass(self):
58
        QHTestCase.setUpClass()
59
        e = self.rand_entity()
60
        k = Key.random()
61
        r = self.qh.create_entity(create_entity=[(e, 'system', k, '')])
62
        self.e_name = e
63
        self.e_key = k
64
        self.client = self.rand_entity()
65

    
66
    @classmethod
67
    def rand_name(self, exclude=[]):
68
        for i in range(1,100):
69
            r = Name().random()
70
            if r not in exclude:
71
                exclude.append(r)
72
                return r
73
        else:
74
            m = 'Could not make a unique random name'
75
            raise Exception(m)
76

    
77
    used_entities = ['system']
78

    
79
    @classmethod
80
    def rand_entity(self):
81
        return self.rand_name(self.used_entities)
82

    
83
    used_policies = []
84

    
85
    @classmethod
86
    def rand_policy(self):
87
        return self.rand_name(self.used_policies)
88

    
89
    used_resources = []
90

    
91
    @classmethod
92
    def rand_resource(self):
93
        return self.rand_name(self.used_resources)
94

    
95
    def rand_limits(self):
96
        q = Capacity.random() # Nonnegative
97
        c = Capacity.random()
98
        il = ImportLimit.random()
99
        el = ExportLimit.random()
100
        return q, c, il, el
101

    
102
    def rand_policy_limits(self):
103
        p = self.rand_policy()
104
        limits = self.rand_limits()
105
        return p, limits
106

    
107
    def rand_flags(self):
108
        return Flags.random()
109

    
110
    def rand_counters(self):
111
        return (Imported.random(), Exported.random(),
112
                Returned.random(), Released.random())
113

    
114
    def new_entity(self, parent='system', parent_key=''):
115
        e = self.rand_entity()
116
        k = Key.random()
117
        r = self.qh.create_entity(create_entity=[(e, parent, k, parent_key)])
118
        self.assertEqual(r, [])
119
        return e, k
120

    
121
    def new_policy(self):
122
        p, limits = self.rand_policy_limits()
123
        r = self.qh.set_limits(set_limits=[(p,) + limits])
124
        self.assertEqual(r, [])
125
        return p, limits
126

    
127
    def test_001_list_entities(self):
128
        r = self.qh.list_entities(entity='system', key='')
129
        self.assertEqual(sorted(r), sorted(['system', self.e_name]))
130

    
131
        with self.assertRaises(NoEntityError):
132
            self.qh.list_entities(entity='doesnotexist', key='')
133

    
134
        with self.assertRaises(InvalidDataError):
135
            self.qh.list_entities(entity='system; SELECT ALL', key='')
136

    
137
    def test_002_create_entity(self):
138
        e = self.rand_entity()
139
        k = Key.random()
140
        r = self.qh.create_entity(
141
            create_entity=[(self.e_name, 'system', self.e_key, ''),
142
                           (e, self.e_name, k, self.e_key),
143
                           (e, self.e_name, k, self.e_key)])
144
        self.assertEqual(r, [0,2])
145

    
146
    def test_003_release_entity(self):
147
        e, k = self.new_entity()
148
        r = self.qh.release_entity(release_entity=[(e, k)])
149
        self.assertEqual(r, [])
150

    
151
    def test_004_set_entity_key(self):
152
        e, k = self.new_entity()
153
        k1 = Key.random()
154
        k2 = Key.random()
155
        r = self.qh.set_entity_key(set_entity_key=[(e, k1, k2)])
156
        self.assertEqual(r, [e])
157
        r = self.qh.set_entity_key(set_entity_key=[(e, k, k2)])
158
        self.assertEqual(r, [])
159
        r = self.qh.release_entity(release_entity=[(e, k)])
160
        self.assertEqual(r, [e])
161

    
162
    def test_005_get_entity(self):
163
        e = self.rand_entity()
164
        k = Key.random()
165
        r = self.qh.get_entity(get_entity=[(self.e_name, self.e_key), (e, k)])
166
        self.assertEqual(r, [(self.e_name, 'system')])
167

    
168
    def test_006_get_set_limits(self):
169

    
170
        p1, limits1 = self.rand_policy_limits()
171
        limits2 = self.rand_limits()
172
        r = self.qh.set_limits(set_limits=[(p1,) + limits1,
173
                                           (p1,) + limits2])
174
        self.assertEqual(r, [])
175

    
176
        p2, _ = self.rand_policy_limits()
177
        r = self.qh.get_limits(get_limits=[p1, p2])
178
        self.assertEqual(r, [(p1,) + limits2])
179

    
180
    def test_007_get_set_holding(self):
181
        e, k = self.new_entity()
182
        resource = self.rand_resource()
183

    
184
        p0 = self.rand_policy()
185
        f0 = self.rand_flags()
186
        p1, _ = self.new_policy()
187
        f1 = self.rand_flags()
188
        p2, _ = self.new_policy()
189
        f2 = self.rand_flags()
190

    
191
        # none is committed
192
        r = self.qh.set_holding(set_holding=[(e, resource, k, p0, f0),
193
                                             (e, resource, k, p1, f1),
194
                                             (e, resource, k, p2, f2)])
195
        self.assertEqual(r, [(e, resource, p0)])
196

    
197
        r = self.qh.get_holding(get_holding=[(e, resource, k)])
198
        self.assertEqual(r, [])
199

    
200
        r = self.qh.set_holding(set_holding=[(e, resource, k, p1, f1),
201
                                             (e, resource, k, p2, f2)])
202
        self.assertEqual(r, [])
203

    
204
        resource1 = self.rand_resource()
205
        r = self.qh.get_holding(get_holding=[(e, resource, k),
206
                                             (e, resource1, k)])
207
        self.assertEqual(r, [(e, resource, p2) + DEFAULT_HOLDING + (f2,)])
208

    
209
    def test_008_get_set_quota(self):
210
        e, k = self.new_entity()
211
        resource = self.rand_resource()
212
        limits = self.rand_limits()
213
        limits1 = self.rand_limits()
214
        f = self.rand_flags()
215
        r = self.qh.set_quota(set_quota=[(e, resource, k) + limits + (f,),
216
                                         (e, resource, k) + limits1 + (f,)])
217
        self.assertEqual(r, [])
218

    
219
        resource2 = self.rand_resource()
220
        r = self.qh.get_quota(get_quota=[(e, resource, k),
221
                                         (e, resource2, k)])
222
        self.assertEqual(r, [(e, resource) + limits1 +
223
                             DEFAULT_HOLDING + (f,)])
224

    
225
    def new_quota(self, entity, key, resource, limits=None):
226
        if limits is None:
227
            limits = self.rand_limits()
228
        f = self.rand_flags()
229
        r = self.qh.set_quota(
230
            set_quota=[(entity, resource, key) + limits + (f,)])
231
        self.assertEqual(r, [])
232
        return limits
233

    
234
    def test_0081_add_quota(self):
235
        e0, k0 = self.new_entity()
236
        e1, k1 = self.new_entity()
237
        resource0 = self.rand_resource()
238
        resource1 = self.rand_resource()
239

    
240
        r = self.qh.set_quota(
241
            set_quota=[(e0, resource0, k0) + (5, QH_MAX_INT, 5, 6) + (0,),
242
                       (e1, resource0, k1) + (5, 5, 5, 5) + (0,)])
243
        self.assertEqual(r, [])
244

    
245
        r = self.qh.add_quota(clientkey=self.client,
246
                              serial=1,
247
                              sub_quota=[(e0, resource0, k0, 0, QH_MAX_INT, 1, 1)],
248
                              add_quota=[(e0, resource0, k0, 0, 3, QH_MAX_INT, 0),
249
                                         # new holding
250
                                         (e0, resource1, k0, 0, QH_MAX_INT, 5, 5)])
251
        self.assertEqual(r, [])
252

    
253
        r = self.qh.get_quota(get_quota=[(e0, resource0, k0),
254
                                         (e0, resource1, k0)])
255
        self.assertEqual(r, [(e0, resource0, 5, 3, QH_MAX_INT+4, 5)
256
                             + DEFAULT_HOLDING + (0,),
257
                             (e0, resource1, 0, QH_MAX_INT, 5, 5)
258
                             + DEFAULT_HOLDING + (0,)])
259

    
260
        # repeated serial
261
        r = self.qh.add_quota(clientkey=self.client,
262
                              serial=1,
263
                              sub_quota=[(e0, resource1, k0, 0, QH_MAX_INT, (-5), 0)],
264
                              add_quota=[(e0, resource0, k0, 0, 2, QH_MAX_INT, 0)])
265
        self.assertEqual(r, [(e0, resource1), (e0, resource0)])
266

    
267
        r = self.qh.query_serials(clientkey=self.client, serials=[1, 2])
268
        self.assertEqual(r, [1])
269

    
270
        r = self.qh.query_serials(clientkey=self.client, serials=[])
271
        self.assertEqual(r, [1])
272

    
273
        r = self.qh.query_serials(clientkey=self.client, serials=[2])
274
        self.assertEqual(r, [])
275

    
276
        r = self.qh.ack_serials(clientkey=self.client, serials=[1])
277

    
278
        r = self.qh.query_serials(clientkey=self.client, serials=[1, 2])
279
        self.assertEqual(r, [])
280

    
281
        # idempotent
282
        r = self.qh.ack_serials(clientkey=self.client, serials=[1])
283

    
284
        # serial has been deleted
285
        r = self.qh.add_quota(clientkey=self.client,
286
                              serial=1,
287
                              add_quota=[(e0, resource0, k0, 0, 2, QH_MAX_INT, 0)])
288
        self.assertEqual(r, [])
289

    
290
        # none is committed
291
        r = self.qh.add_quota(clientkey=self.client,
292
                              serial=2,
293
                              add_quota=[(e1, resource0, k1, 0, (-10), QH_MAX_INT, 0),
294
                                         (e0, resource1, k0, 1, 0, 0, 0)])
295
        self.assertEqual(r, [(e1, resource0)])
296

    
297
        r = self.qh.get_quota(get_quota=[(e1, resource0, k1),
298
                                         (e0, resource1, k0)])
299
        self.assertEqual(r, [(e1, resource0, 5, 5 , 5, 5)
300
                             + DEFAULT_HOLDING + (0,),
301
                             (e0, resource1, 0, QH_MAX_INT, 5, 5)
302
                             + DEFAULT_HOLDING + (0,)])
303

    
304
    def test_0082_max_quota(self):
305
        e0, k0 = self.new_entity()
306
        e1, k1 = self.new_entity()
307
        resource0 = self.rand_resource()
308
        resource1 = self.rand_resource()
309

    
310
        r = self.qh.set_quota(
311
            set_quota=[(e0, resource0, k0) + (5, QH_MAX_INT, 5, 6) + (0,)])
312
        self.assertEqual(r, [])
313

    
314
        r = self.qh.add_quota(clientkey=self.client,
315
                              serial=3,
316
                              add_quota=[(e0, resource0, k0, 0, QH_MAX_INT, 0, 0)])
317

    
318
        self.assertEqual(r, [])
319

    
320
        r = self.qh.get_quota(get_quota=[(e0, resource0, k0)])
321
        self.assertEqual(r, [(e0, resource0, 5, 2*QH_MAX_INT, 5, 6)
322
                             + DEFAULT_HOLDING + (0,)])
323

    
324

    
325

    
326
    def test_0090_commissions(self):
327
        e0, k0 = self.new_entity()
328
        e1, k1 = self.new_entity()
329
        resource = self.rand_resource()
330
        q0, c0, il0, el0 = self.new_quota(e0, k0, resource)
331
        q1, c1, il1, el1 = self.new_quota(e1, k1, resource)
332

    
333
        most = max(0, min(c0, il0, q1, el1))
334
        r = self.qh.issue_commission(clientkey=self.client, target=e0, key=k0,
335
                                     name='something',
336
                                     provisions=[(e1, resource, most)])
337
        self.assertEqual(r, 1)
338

    
339
        with self.assertRaises(CallError):
340
            self.qh.issue_commission(clientkey=self.client, target=e0, key=k0,
341
                                     name='something',
342
                                     provisions=[(e1, resource, 1)])
343

    
344
        r = self.qh.get_pending_commissions(clientkey=self.client)
345
        self.assertEqual(r, [1])
346
        r = self.qh.resolve_pending_commissions(clientkey=self.client,
347
                                                max_serial=1, accept_set=[1])
348
        r = self.qh.get_pending_commissions(clientkey=self.client)
349
        self.assertEqual(r, [])
350

    
351
    def test_0091_commissions_exceptions(self):
352
        es1, ks1 = self.new_entity()
353
        es2, ks2 = self.new_entity()
354
        et1, kt1 = self.new_entity()
355
        et2, kt2 = self.new_entity()
356
        resource = self.rand_resource()
357
        self.new_quota(es1, ks1, resource, (10, 5, 5, 15))
358
        self.new_quota(es2, ks2, resource, (10, 5, 5, 10))
359
        self.new_quota(et1, kt1, resource, (0, 15, 3, 20))
360
        self.new_quota(et2, kt2, resource, (0, 15, 20, 20))
361

    
362
        try:
363
            self.qh.issue_commission(clientkey=self.client, target=et1, key=kt1,
364
                                     name='something',
365
                                     provisions=[(es1, resource, 12)])
366
        except NoQuantityError, e:
367
            self.assertEqual(e.source, es1)
368
            self.assertEqual(e.target, et1)
369
            self.assertEqual(e.resource, resource)
370
            self.assertEqual(e.limit, 10)
371
            self.assertEqual(e.requested, 12)
372
            self.assertEqual(e.current, 0)
373

    
374
            r = self.qh.issue_commission(clientkey=self.client, target=et1,
375
                                         key=kt1,
376
                                         name='something',
377
                                         provisions=[(es1, resource, 2)])
378
            self.assertGreater(r, 0)
379

    
380
        try:
381
            self.qh.issue_commission(clientkey=self.client, target=et1, key=kt1,
382
                                     name='something',
383
                                     provisions=[(es1, resource, 2)])
384
        except ImportLimitError, e:
385
            self.assertEqual(e.source, es1)
386
            self.assertEqual(e.target, et1)
387
            self.assertEqual(e.resource, resource)
388
            self.assertEqual(e.limit, 3)
389
            self.assertEqual(e.requested, 2)
390
            self.assertEqual(e.current, 2)
391

    
392
            r = self.qh.issue_commission(clientkey=self.client, target=et2,
393
                                         key=kt2,
394
                                         name='something',
395
                                         provisions=[(es2, resource, 9)])
396
            self.assertGreater(r, 0)
397

    
398
        try:
399
            self.qh.issue_commission(clientkey=self.client, target=et2,
400
                                     key=kt2,
401
                                     name='something',
402
                                     provisions=[(es2, resource, 1),
403
                                                 (es1, resource, 2)])
404
        except NoCapacityError, e:
405
            self.assertEqual(e.source, es1)
406
            self.assertEqual(e.target, et2)
407
            self.assertEqual(e.resource, resource)
408
            self.assertEqual(e.limit, 10)
409
            self.assertEqual(e.requested, 2)
410
            # 9 actual + 1 from the first provision
411
            self.assertEqual(e.current, 10)
412

    
413

    
414
    def test_010_list_holdings(self):
415
        e0, k0 = ('list_holdings_one', '1')
416
        e1, k1 = ('list_holdings_two', '1')
417
        resource = 'list_holdings_resource'
418
        sys = 'system'
419

    
420
        r = self.qh.create_entity(create_entity=[(e0, sys, k0, ''),
421
                                                 (e1, sys, k1, '')])
422
        if r:
423
            raise AssertionError("cannot create entities")
424

    
425
        self.qh.set_quota(set_quota=[(sys, resource, '', 10, 0, QH_MAX_INT, QH_MAX_INT, 0),
426
                                     (e0, resource, k0, 0, 10, QH_MAX_INT, QH_MAX_INT, 0),
427
                                     (e1, resource, k1, 0, 10, QH_MAX_INT, QH_MAX_INT, 0)])
428

    
429
        s0 = self.qh.issue_commission(clientkey=self.client, target=e0, key=k0,
430
                                      name='a commission',
431
                                      provisions=[('system', resource, 3)])
432

    
433
        s1 = self.qh.issue_commission(clientkey=self.client, target=e1, key=k1,
434
                                      name='a commission',
435
                                      provisions=[('system', resource, 4)])
436

    
437
        self.qh.accept_commission(clientkey=self.client, serials=[s0, s1])
438

    
439
        holdings_list, rejected = self.qh.list_holdings(list_holdings=[
440
                                                        (e0, k0),
441
                                                        (e1, k1),
442
                                                        (e0+e1, k0+k1)])
443

    
444
        self.assertEqual(rejected, [e0+e1])
445
        self.assertEqual(holdings_list, [[(e0, resource, 3, 0, 0, 0)],
446
                                         [(e1, resource, 4, 0, 0, 0)]])
447

    
448

    
449
    def test_011_release_empty(self):
450
        e, k = self.new_entity()
451
        e0, k0 = self.rand_entity(), Key.random()
452

    
453
        # none is committed
454
        r = self.qh.release_entity(release_entity=[(e, k), (e0, k0)])
455
        self.assertEqual(r, [e0])
456

    
457
        r = self.qh.get_entity(get_entity=[(e, k)])
458
        self.assertEqual(r, [(e, 'system')])
459

    
460
        r = self.qh.release_entity(release_entity=[(e, k)])
461
        self.assertEqual(r, [])
462

    
463
        r = self.qh.get_entity(get_entity=[(e, k)])
464
        self.assertEqual(r, [])
465

    
466
    def test_012_release_nonempty(self):
467
        e, k = self.new_entity()
468
        e1, k1 = self.new_entity(e, k)
469

    
470
        # none is committed
471
        r = self.qh.release_entity(release_entity=[(e, k), (e1, k1)])
472
        self.assertEqual(r, [e])
473

    
474
        r = self.qh.get_entity(get_entity=[(e1, k1)])
475
        self.assertEqual(r, [(e1, e)])
476

    
477
        r = self.qh.release_entity(release_entity=[(e1, k1), (e, k)])
478
        self.assertEqual(r, [])
479

    
480
        r = self.qh.get_entity(get_entity=[(e1, k1)])
481
        self.assertEqual(r, [])
482

    
483
    def test_013_release_nonempty(self):
484
        e, k = self.new_entity()
485
        resource = self.rand_resource()
486
        limits = self.new_quota(e, k, resource)
487
        r = self.qh.release_entity(release_entity=[(e, k)])
488
        self.assertEqual(r, [e])
489
        r = self.qh.release_holding(release_holding=[(e, resource, k)])
490
        self.assertEqual(r, [])
491
        r = self.qh.release_entity(release_entity=[(e, k)])
492
        self.assertEqual(r, [])
493

    
494
    def test_014_reset_holding(self):
495
        e0, k0 = self.new_entity()
496
        e1, k1 = self.new_entity()
497
        resource = self.rand_resource()
498
        p, _ = self.new_policy()
499
        f = self.rand_flags()
500
        r = self.qh.set_holding(set_holding=[(e1, resource, k1, p, f)])
501

    
502
        counters = self.rand_counters()
503

    
504
        # none is committed
505
        r = self.qh.reset_holding(
506
            reset_holding=[(e0, resource, k0) + counters,
507
                           (e1, resource, k1) + counters])
508
        self.assertEqual(r, [0])
509

    
510
        r = self.qh.get_holding(get_holding=[(e1, resource, k1)])
511
        self.assertEqual(r, [(e1, resource, p) + DEFAULT_HOLDING + (f,)])
512

    
513
        r = self.qh.reset_holding(
514
            reset_holding=[(e1, resource, k1) + counters])
515
        self.assertEqual(r, [])
516

    
517
        r = self.qh.get_holding(get_holding=[(e1, resource, k1)])
518
        self.assertEqual(r, [(e1, resource, p) + counters + (f,)])
519

    
520

    
521
if __name__ == "__main__":
522
    import sys
523
    printf("Using {0}", sys.executable)
524
    run_test_case(QHAPITest)