Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / quotaholder / test / simpletests.py @ 3adbfafa

History | View | Annotate | Download (18.5 kB)

1
# Copyright 2012, 2013 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 printf
37

    
38
from astakos.quotaholder.exception import (
39
                            QuotaholderError,
40
                            InvalidDataError,
41
                            NoQuantityError, NoCapacityError,
42
                            CommissionValueException,
43
                            DuplicateError)
44

    
45
from astakos.quotaholder.api import QH_PRACTICALLY_INFINITE
46
from astakos.quotaholder.utils.rand import random_int, random_nat, random_name
47

    
48
DEFAULT_HOLDING = (0, 0, 0, 0)
49

    
50
class QHAPITest(QHTestCase):
51

    
52
    @classmethod
53
    def setUpClass(self):
54
        QHTestCase.setUpClass()
55
        self.client = self.rand_holder()
56

    
57
    @classmethod
58
    def rand_name(self, exclude=None):
59
        for i in range(1,100):
60
            r = random_name()
61
            if exclude is not None and r not in exclude:
62
                exclude.append(r)
63
                return r
64
        else:
65
            m = 'Could not make a unique random name'
66
            raise Exception(m)
67

    
68
    used_entities = ['system']
69

    
70
    @classmethod
71
    def rand_holder(self):
72
        return self.rand_name(self.used_entities)
73

    
74
    used_policies = []
75

    
76
    @classmethod
77
    def rand_policy(self):
78
        return self.rand_name(self.used_policies)
79

    
80
    used_resources = []
81

    
82
    @classmethod
83
    def rand_resource(self):
84
        return self.rand_name(self.used_resources)
85

    
86
    def rand_limits(self):
87
        q = random_nat()
88
        c = random_nat()
89
        return q, c,
90

    
91
    def rand_policy_limits(self):
92
        p = self.rand_policy()
93
        limits = self.rand_limits()
94
        return p, limits
95

    
96
    def rand_flags(self):
97
        return random_nat()
98

    
99
    def rand_counters(self):
100
        return tuple(random_nat() for i in range(4))
101

    
102
    def new_policy(self):
103
        p, limits = self.rand_policy_limits()
104
        self.qh.set_limits(set_limits=[(p,) + limits])
105
        return p, limits
106

    
107
    @transaction.commit_on_success
108
    def test_006_get_set_limits(self):
109

    
110
        p1, limits1 = self.rand_policy_limits()
111
        limits2 = self.rand_limits()
112
        r = self.qh.set_limits(set_limits=[(p1,) + limits1,
113
                                           (p1,) + limits2])
114

    
115
        p2, _ = self.rand_policy_limits()
116
        r = self.qh.get_limits(get_limits=[p1, p2])
117
        self.assertEqual(r, [(p1,) + limits2])
118

    
119
    @transaction.commit_on_success
120
    def test_007_get_set_holding(self):
121
        e = self.rand_holder()
122
        resource = self.rand_resource()
123

    
124
        p0 = self.rand_policy()
125
        f0 = self.rand_flags()
126
        p1, _ = self.new_policy()
127
        f1 = self.rand_flags()
128
        p2, _ = self.new_policy()
129
        f2 = self.rand_flags()
130

    
131
        with self.assertRaises(QuotaholderError) as cm:
132
            self.qh.set_holding(set_holding=[(e, resource, p0, f0),
133
                                             (e, resource, p1, f1),
134
                                             (e, resource, p2, f2)])
135

    
136
        # Python people consider this a legal use
137
        # It's even in the library docs... whatever
138
        err = cm.exception
139
        self.assertEqual(err.message, [(e, resource, p0)])
140

    
141
        self.qh.get_holding(get_holding=[(e, resource)])
142

    
143
        self.qh.set_holding(set_holding=[(e, resource, p1, f1),
144
                                         (e, resource, p2, f2)])
145

    
146
        resource1 = self.rand_resource()
147
        r = self.qh.get_holding(get_holding=[(e, resource),
148
                                             (e, resource1)])
149
        self.assertEqual(r, [(e, resource, p2) + DEFAULT_HOLDING + (f2,)])
150

    
151
    @transaction.commit_on_success
152
    def test_0080_get_set_quota(self):
153
        e = self.rand_holder()
154
        resource = self.rand_resource()
155
        limits = self.rand_limits()
156
        limits1 = self.rand_limits()
157
        f = self.rand_flags()
158
        self.qh.set_quota(set_quota=[(e, resource) + limits + (f,),
159
                                     (e, resource) + limits1 + (f,)])
160

    
161
        resource2 = self.rand_resource()
162
        r = self.qh.get_quota(get_quota=[(e, resource),
163
                                         (e, resource2)])
164
        self.assertEqual(r, [(e, resource) + limits1 +
165
                             DEFAULT_HOLDING + (f,)])
166

    
167
    def new_quota(self, holder, resource, limits=None):
168
        if limits is None:
169
            limits = self.rand_limits()
170
        f = self.rand_flags()
171
        self.qh.set_quota(
172
            set_quota=[(holder, resource) + limits + (f,)])
173
        return limits
174

    
175
    @transaction.commit_on_success
176
    def test_0081_add_quota(self):
177
        e0 = self.rand_holder()
178
        e1 = self.rand_holder()
179
        resource0 = self.rand_resource()
180
        resource1 = self.rand_resource()
181

    
182
        self.qh.set_quota(
183
            set_quota=[(e0, resource0) + (5, QH_PRACTICALLY_INFINITE) + (0,),
184
                       (e1, resource0) + (5, 5) + (0,)])
185

    
186
        self.qh.add_quota(sub_quota=[(e0, resource0,
187
                                      0, QH_PRACTICALLY_INFINITE)],
188
                          add_quota=[(e0, resource0,
189
                                      0, 3),
190
                                     # new holding
191
                                     (e0, resource1,
192
                                      0, QH_PRACTICALLY_INFINITE)])
193

    
194
        r = self.qh.get_quota(get_quota=[(e0, resource0),
195
                                         (e0, resource1)])
196
        self.assertEqual(r, [(e0, resource0, 5, 3)
197
                             + DEFAULT_HOLDING + (0,),
198
                             (e0, resource1, 0, QH_PRACTICALLY_INFINITE)
199
                             + DEFAULT_HOLDING + (0,)])
200

    
201
        with self.assertRaises(QuotaholderError) as cm:
202
            self.qh.add_quota(add_quota=[(e1, resource0,
203
                                          0, (-10)),
204
                                         (e0, resource1, 1, 0)])
205

    
206
        err = cm.exception
207
        self.assertEqual(err.message, [(e1, resource0)])
208

    
209
        # r = self.qh.get_quota(get_quota=[(e1, resource0),
210
        #                                  (e0, resource1)])
211
        # self.assertEqual(r, [(e1, resource0, 5, 5)
212
        #                      + DEFAULT_HOLDING + (0,),
213
        #                      (e0, resource1, 0, QH_PRACTICALLY_INFINITE)
214
        #                      + DEFAULT_HOLDING + (0,)])
215

    
216
    @transaction.commit_on_success
217
    def test_0082_max_quota(self):
218
        e0 = self.rand_holder()
219
        e1 = self.rand_holder()
220
        resource0 = self.rand_resource()
221
        resource1 = self.rand_resource()
222

    
223
        self.qh.set_quota(
224
            set_quota=[(e0, resource0) +
225
                       (5, QH_PRACTICALLY_INFINITE) + (0,)])
226

    
227
        self.qh.add_quota(add_quota=[(e0, resource0,
228
                                      0, QH_PRACTICALLY_INFINITE)])
229

    
230
        r = self.qh.get_quota(get_quota=[(e0, resource0)])
231
        self.assertEqual(r, [(e0, resource0, 5, 2*QH_PRACTICALLY_INFINITE)
232
                             + DEFAULT_HOLDING + (0,)])
233

    
234
    @transaction.commit_on_success
235
    def test_0090_commissions(self):
236
        e0 = self.rand_holder()
237
        e1 = self.rand_holder()
238
        resource = self.rand_resource()
239
        q0, c0 = self.new_quota(e0, resource)
240
        q1, c1 = self.new_quota(e1, resource)
241

    
242
        most = min(c0, q1)
243
        if most < 0:
244
            raise AssertionError("%s <= 0" % most)
245

    
246
        @transaction.commit_on_success
247
        def f():
248
            return self.qh.issue_commission(clientkey=self.client, target=e0,
249
                                            name='something',
250
                                            provisions=[(e1, resource, most)])
251

    
252
        r = f()
253
        self.assertEqual(r, 1)
254

    
255
        @transaction.commit_on_success
256
        def f():
257
            self.qh.issue_commission(clientkey=self.client, target=e0,
258
                                     name='something',
259
                                     provisions=[(e1, resource, 1)])
260

    
261
        with self.assertRaises(CommissionValueException):
262
            f()
263

    
264
        r = self.qh.get_pending_commissions(clientkey=self.client)
265
        self.assertEqual(list(r), [1])
266
        r = self.qh.resolve_pending_commissions(clientkey=self.client,
267
                                                max_serial=1, accept_set=[1])
268
        r = self.qh.get_pending_commissions(clientkey=self.client)
269
        self.assertEqual(list(r), [])
270

    
271
    @transaction.commit_on_success
272
    def test_0091_commissions_exceptions(self):
273
        es1 = self.rand_holder()
274
        es2 = self.rand_holder()
275
        et1 = self.rand_holder()
276
        et2 = self.rand_holder()
277
        resource = self.rand_resource()
278
        self.new_quota(es1, resource, (10, 5))
279
        self.new_quota(es2, resource, (10, 5))
280
        self.new_quota(et1, resource, (0, 15))
281
        self.new_quota(et2, resource, (0, 15))
282

    
283
        with self.assertRaises(NoQuantityError) as cm:
284
            self.qh.issue_commission(clientkey=self.client, target=et1,
285
                                     name='something',
286
                                     provisions=[(es1, resource, 12)])
287
        e = cm.exception
288
        self.assertEqual(e.source, es1)
289
        self.assertEqual(e.target, et1)
290
        self.assertEqual(e.resource, resource)
291
        self.assertEqual(int(e.limit), 10)
292
        self.assertEqual(int(e.requested), 12)
293
        self.assertEqual(int(e.current), 0)
294

    
295
        r = self.qh.issue_commission(clientkey=self.client, target=et1,
296
                                     name='something',
297
                                     provisions=[(es1, resource, 2)])
298
        self.assertGreater(r, 0)
299

    
300
        # with self.assertRaises(ImportLimitError) as cm:
301
        #     self.qh.issue_commission(clientkey=self.client, target=et1,
302
        #                              name='something',
303
        #                              provisions=[(es1, resource, 2)])
304
        # e = cm.exception
305
        # self.assertEqual(e.source, es1)
306
        # self.assertEqual(e.target, et1)
307
        # self.assertEqual(e.resource, resource)
308
        # self.assertEqual(int(e.limit), 3)
309
        # self.assertEqual(int(e.requested), 2)
310
        # self.assertEqual(int(e.current), 2)
311

    
312
        r = self.qh.issue_commission(clientkey=self.client, target=et2,
313
                                     name='something',
314
                                     provisions=[(es2, resource, 9)])
315
        self.assertGreater(r, 0)
316

    
317
        with self.assertRaises(NoCapacityError) as cm:
318
            self.qh.issue_commission(clientkey=self.client, target=et2,
319
                                     name='something',
320
                                     provisions=[(es2, resource, 1),
321
                                                 (es1, resource, 6)])
322
        e = cm.exception
323
        self.assertEqual(e.source, es1)
324
        self.assertEqual(e.target, et2)
325
        self.assertEqual(e.resource, resource)
326
        self.assertEqual(int(e.limit), 15)
327
        self.assertEqual(int(e.requested), 6)
328
        # 9 actual + 1 from the first provision
329
        self.assertEqual(int(e.current), 10)
330

    
331
    @transaction.commit_on_success
332
    def test_010_list_holdings(self):
333
        e0 = 'list_holdings_one'
334
        e1 = 'list_holdings_two'
335
        resource = 'list_holdings_resource'
336
        sys = 'system'
337

    
338
        self.qh.set_quota(set_quota=[(sys, resource, 10, 0, 0),
339
                                     (e0, resource, 0, 10, 0),
340
                                     (e1, resource, 0, 10, 0)])
341

    
342
        s0 = self.qh.issue_commission(clientkey=self.client, target=e0,
343
                                      name='a commission',
344
                                      provisions=[('system', resource, 3)])
345

    
346
        s1 = self.qh.issue_commission(clientkey=self.client, target=e1,
347
                                      name='a commission',
348
                                      provisions=[('system', resource, 4)])
349

    
350
        self.qh.accept_commission(clientkey=self.client, serials=[s0, s1])
351

    
352
        holdings_list, rejected = self.qh.list_holdings(
353
            list_holdings=[e0, e1, e0+e1])
354

    
355
        self.assertEqual(rejected, [e0+e1])
356
        self.assertEqual(holdings_list, [[(e0, resource, 3, 0, 0, 0)],
357
                                         [(e1, resource, 4, 0, 0, 0)]])
358

    
359

    
360
    @transaction.commit_on_success
361
    def test_0130_release_holding(self):
362
        e = self.rand_holder()
363
        resource = self.rand_resource()
364
        limits = self.new_quota(e, resource, (1, 2))
365

    
366
        with self.assertRaises(QuotaholderError) as cm:
367
            self.qh.release_holding(release_holding=[(e, resource)])
368

    
369
        err = cm.exception
370
        self.assertEqual(err.message, [0])
371

    
372
    @transaction.commit_on_success
373
    def test_0131_release_holding(self):
374
        e = self.rand_holder()
375
        resource = self.rand_resource()
376
        limits = self.new_quota(e, resource, (0, 2))
377

    
378
        self.qh.release_holding(release_holding=[(e, resource)])
379

    
380
    @transaction.commit_on_success
381
    def test_0132_release_holding(self):
382
        resource = self.rand_resource()
383

    
384
        es = self.rand_holder()
385
        limits_s = self.new_quota(es, resource, (3, 3))
386
        e = self.rand_holder()
387
        limits = self.new_quota(e, resource, (0, 2))
388

    
389
        r = self.qh.issue_commission(clientkey=self.client, target=e,
390
                                     name='something',
391
                                     provisions=[(es, resource, 1)])
392
        self.assertGreater(r, 0)
393

    
394
        with self.assertRaises(QuotaholderError) as cm:
395
            self.qh.release_holding(release_holding=[(e, resource)])
396

    
397
        err = cm.exception
398
        self.assertEqual(err.message, [0])
399

    
400
    @transaction.commit_on_success
401
    def test_014_reset_holding(self):
402
        e0 = self.rand_holder()
403
        e1 = self.rand_holder()
404
        resource = self.rand_resource()
405
        p, _ = self.new_policy()
406
        f = self.rand_flags()
407
        r = self.qh.set_holding(set_holding=[(e1, resource, p, f)])
408

    
409
        counters = self.rand_counters()
410

    
411
        with self.assertRaises(QuotaholderError) as cm:
412
            self.qh.reset_holding(
413
                reset_holding=[(e0, resource) + counters,
414
                               (e1, resource) + counters])
415

    
416
        err = cm.exception
417
        self.assertEqual(err.message, [0])
418

    
419
        r = self.qh.get_holding(get_holding=[(e1, resource)])
420
        self.assertEqual(r, [(e1, resource, p) + counters + (f,)])
421

    
422
    @transaction.commit_on_success
423
    def test_015_release_nocapacity(self):
424
        qh = self.qh
425
        owner = "system"
426
        source = "test_015_release_nocapacity_source"
427
        resource = "resource"
428
        target = "test_015_release_nocapacity_target"
429
        flags = 0
430
        source_limits  = [source, 6, 0]
431
        source_holding = [source, resource, source, flags]
432
        target_limits  = [target, 0, 5]
433
        target_holding = [target, resource, target, flags]
434

    
435
        failed = AssertionError("Quotaholder call failed")
436
        if qh.set_limits(set_limits=[source_limits, target_limits]):
437
            raise failed
438
        if qh.set_holding(set_holding=[source_holding, target_holding]):
439
            raise failed
440

    
441
        serial = qh.issue_commission(clientkey=self.client, target=target,
442
                                     name="something",
443
                                     provisions=[(source, resource, 5)])
444
        qh.accept_commission(clientkey=self.client, serials=[serial])
445

    
446
        holding = qh.get_holding(get_holding=[[source, resource]])
447
        self.assertEqual(tuple(holding[0]),
448
                         (source, resource, source, 0, 5, 0, 0, flags))
449
        holding = qh.get_holding(get_holding=[[target, resource]])
450
        self.assertEqual(tuple(holding[0]),
451
                         (target, resource, target, 5, 0, 0, 0, flags))
452

    
453
        if qh.reset_holding(reset_holding=[[target, resource, 10, 0, 0, 0]]):
454
            raise failed
455

    
456
        with self.assertRaises(NoCapacityError):
457
            qh.issue_commission(clientkey=self.client, target=target,
458
                                name="something",
459
                                provisions=[(source, resource, 1)])
460

    
461
        with self.assertRaises(NoQuantityError):
462
            qh.issue_commission(clientkey=self.client, target=target,
463
                                name="something",
464
                                provisions=[(source, resource, -7)])
465

    
466
        source_limits  = [source, 6, 10]
467
        if qh.set_limits(set_limits=[source_limits]):
468
            raise failed
469

    
470
        serial = qh.issue_commission(clientkey=self.client, target=target,
471
                                     name="something",
472
                                     provisions=[(source, resource, -1)])
473
        qh.accept_commission(clientkey=self.client, serials=[serial])
474

    
475
        holding = qh.get_holding(get_holding=[[source, resource]])
476
        self.assertEqual(tuple(holding[0]),
477
                         (source, resource, source, 0, 5, 1, 0, flags))
478
        holding = qh.get_holding(get_holding=[[target, resource]])
479
        self.assertEqual(tuple(holding[0]),
480
                         (target, resource, target, 10, 0, 0, 1, flags))
481

    
482
        with self.assertRaises(NoCapacityError):
483
            qh.issue_commission(clientkey=self.client, target=target,
484
                                name="something",
485
                                provisions=[(source, resource, -10)])
486

    
487

    
488
if __name__ == "__main__":
489
    import sys
490
    printf("Using {0}", sys.executable)
491
    run_test_case(QHAPITest)