Revision 4ec8c043

b/snf-common/synnefo/lib/quotaholder/api/quotaholder.py
76 76
Capacity            =   Nonnegative(classname='Capacity', null=True)
77 77
ImportLimit         =   Nonnegative(classname='ImportLimit', null=True)
78 78
ExportLimit         =   Nonnegative(classname='ExportLimit', null=True)
79
QuantityDelta       =   Integer(classname='QuantityDelta', null=True)
80
CapacityDelta       =   Integer(classname='CapacityDelta', null=True)
81
ImportLimitDelta    =   Integer(classname='ImportLimitDelta', null=True)
82
ExportLimitDelta    =   Integer(classname='ExportLimitDelta', null=True)
79 83
Imported            =   Nonnegative(classname='Imported')
80 84
Exported            =   Nonnegative(classname='Exported')
81 85
Returned            =   Nonnegative(classname='Returned')
......
230 234
        rejected = ListOf(Entity, Resource)
231 235
        return rejected
232 236

  
237
    def add_quota   (
238
                self,
239
                context     =   Context,
240
                add_quota   =   ListOf( Entity, Resource, Key,
241
                                        QuantityDelta, CapacityDelta,
242
                                        ImportLimitDelta, ExportLimitDelta )
243
        ):
244
        rejected = ListOf(Entity, Resource)
245
        return rejected
246

  
233 247
    def issue_commission    (
234 248
                self,
235 249
                context     =   Context,
b/snf-quotaholder-app/quotaholder_django/quotaholder_app/callpoint.py
506 506
            raise ReturnButFail(rejected)
507 507
        return rejected
508 508

  
509
    def add_quota(self, context={}, add_quota=()):
510
        rejected = []
511
        append = rejected.append
512

  
513
        for (   entity, resource, key,
514
                quantity, capacity,
515
                import_limit, export_limit ) in add_quota:
516

  
517
                try:
518
                    e = Entity.objects.get(entity=entity, key=key)
519
                except Entity.DoesNotExist:
520
                    append((entity, resource))
521
                    continue
522

  
523
                try:
524
                    h = db_get_holding(entity=entity, resource=resource,
525
                                       for_update=True)
526
                    p = h.policy
527
                except Holding.DoesNotExist:
528
                    h = Holding(entity=e, resource=resource, flags=0)
529
                    p = None
530

  
531
                policy = newname('policy_')
532
                newp = Policy(policy=policy)
533

  
534
                newp.quantity = _add(p.quantity if p else 0, quantity)
535
                newp.capacity = _add(p.capacity if p else 0, capacity)
536
                newp.import_limit = _add(p.import_limit if p else 0,
537
                                              import_limit)
538
                newp.export_limit = _add(p.export_limit if p else 0,
539
                                              export_limit)
540

  
541
                new_values = [newp.capacity,
542
                              newp.import_limit, newp.export_limit]
543
                if any(map(_isneg, new_values)):
544
                    append((entity, resource))
545
                    continue
546

  
547
                h.policy = newp
548

  
549
                # the order is intentionally reversed so that it
550
                # would break if we are not within a transaction.
551
                # Has helped before.
552
                h.save()
553
                newp.save()
554

  
555
                if p is not None and p.holding_set.count() == 0:
556
                    p.delete()
557

  
558
        if rejected:
559
            raise ReturnButFail(rejected)
560
        return rejected
561

  
509 562
    def issue_commission(self,  context     =   {},
510 563
                                clientkey   =   None,
511 564
                                target      =   None,
......
864 917

  
865 918
        return timeline
866 919

  
920
def _add(x, y):
921
    if x is None or y is None:
922
        return None
923
    return x + y
924

  
925
def _update(dest, source, attr, delta):
926
    dest_attr = getattr(dest, attr)
927
    dest_attr = _add(getattr(source, attr, 0), delta)
928

  
929
def _isneg(x):
930
    if x is None:
931
        return False
932
    return x < 0
867 933

  
868 934
API_Callpoint = QuotaholderDjangoDBCallpoint
869 935

  
b/snf-quotaholder-app/quotaholder_django/test/simpletests.py
223 223
        self.assertEqual(r, [])
224 224
        return limits
225 225

  
226
    def test_0081_add_quota(self):
227
        e0, k0 = self.new_entity()
228
        e1, k1 = self.new_entity()
229
        resource0 = self.rand_resource()
230
        resource1 = self.rand_resource()
231

  
232
        r = self.qh.set_quota(
233
            set_quota=[(e0, resource0, k0) + (5, 5, 5, 5) + (0,),
234
                       (e1, resource0, k1) + (5, 5, 5, 5) + (0,)])
235
        self.assertEqual(r, [])
236

  
237
        r = self.qh.add_quota(add_quota=[(e0, resource0, k0, 0, (-2), None, 0),
238
                                         (e0, resource1, k0, 0, None, 5, 5)])
239
        self.assertEqual(r, [])
240

  
241
        r = self.qh.get_quota(get_quota=[(e0, resource0, k0),
242
                                         (e0, resource1, k0)])
243
        self.assertEqual(r, [(e0, resource0, 5, 5 - 2, None, 5)
244
                             + DEFAULT_HOLDING + (0,),
245
                             (e0, resource1, 0, None, 5, 5)
246
                             + DEFAULT_HOLDING + (0,)])
247

  
248
        # none is committed
249
        r = self.qh.add_quota(add_quota=[(e1, resource0, k1, 0, (-10), None, 0),
250
                                         (e0, resource1, k0, 1, 0, 0, 0)])
251
        self.assertEqual(r, [(e1, resource0)])
252

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

  
226 260
    def test_009_commissions(self):
227 261
        e0, k0 = self.new_entity()
228 262
        e1, k1 = self.new_entity()

Also available in: Unified diff