Example #1
0
    def test_rollback(self):

        Reservation.save = Mock()
        QuotaUsage.save = Mock()

        FAKE_QUOTAS = [QuotaUsage(id=1,
                                  tenant_id=FAKE_TENANT1,
                                  resource=Resource.INSTANCES,
                                  in_use=5,
                                  reserved=2),
                       QuotaUsage(id=2,
                                  tenant_id=FAKE_TENANT1,
                                  resource=Resource.VOLUMES,
                                  in_use=1,
                                  reserved=2)]

        FAKE_RESERVATIONS = [Reservation(usage_id=1,
                                         delta=1,
                                         status=Reservation.Statuses.RESERVED),
                             Reservation(usage_id=2,
                                         delta=2,
                                         status=Reservation.Statuses.RESERVED)]

        QuotaUsage.find_by = Mock(side_effect=FAKE_QUOTAS)
        self.driver.rollback(FAKE_RESERVATIONS)

        self.assertEqual(5, FAKE_QUOTAS[0].in_use)
        self.assertEqual(1, FAKE_QUOTAS[0].reserved)
        self.assertEqual(Reservation.Statuses.ROLLEDBACK,
                         FAKE_RESERVATIONS[0].status)

        self.assertEqual(1, FAKE_QUOTAS[1].in_use)
        self.assertEqual(0, FAKE_QUOTAS[1].reserved)
        self.assertEqual(Reservation.Statuses.ROLLEDBACK,
                         FAKE_RESERVATIONS[1].status)
Example #2
0
    def reserve(self, tenant_id, resources, deltas):
        """Check quotas and reserve resources for a tenant.

        This method checks quotas against current usage,
        reserved resources and the desired deltas.

        If any of the proposed values is over the defined quota, an
        QuotaExceeded exception will be raised with the sorted list of the
        resources which are too high.  Otherwise, the method returns a
        list of reservation objects which were created.

        :param tenant_id: The ID of the tenant reserving the resources.
        :param resources: A dictionary of the registered resources.
        :param deltas: A dictionary of the proposed delta changes.
        """

        self.check_quotas(tenant_id, resources, deltas)
        quota_usages = self.get_all_quota_usages_by_tenant(tenant_id,
                                                           deltas.keys())

        reservations = []
        for resource in sorted(deltas):
            reserved = deltas[resource]
            usage = quota_usages[resource]
            usage.reserved += reserved
            usage.save()

            resv = Reservation.create(usage_id=usage.id,
                                      delta=reserved,
                                      status=Reservation.Statuses.RESERVED)
            reservations.append(resv)

        return reservations
Example #3
0
    def test_commit_cannot_be_less_than_zero(self):

        Reservation.save = Mock()
        QuotaUsage.save = Mock()

        FAKE_QUOTAS = [
            QuotaUsage(id=1,
                       tenant_id=FAKE_TENANT1,
                       resource=Resource.INSTANCES,
                       in_use=0,
                       reserved=-1)
        ]

        FAKE_RESERVATIONS = [
            Reservation(usage_id=1,
                        delta=-1,
                        status=Reservation.Statuses.RESERVED)
        ]

        QuotaUsage.find_by = Mock(side_effect=FAKE_QUOTAS)
        self.driver.commit(FAKE_RESERVATIONS)

        self.assertEqual(0, FAKE_QUOTAS[0].in_use)
        self.assertEqual(0, FAKE_QUOTAS[0].reserved)
        self.assertEqual(Reservation.Statuses.COMMITTED,
                         FAKE_RESERVATIONS[0].status)
Example #4
0
    def reserve(self, tenant_id, resources, deltas):
        """Check quotas and reserve resources for a tenant.

        This method checks quotas against current usage,
        reserved resources and the desired deltas.

        If any of the proposed values is over the defined quota, an
        QuotaExceeded exception will be raised with the sorted list of the
        resources which are too high.  Otherwise, the method returns a
        list of reservation objects which were created.

        :param tenant_id: The ID of the tenant reserving the resources.
        :param resources: A dictionary of the registered resources.
        :param deltas: A dictionary of the proposed delta changes.
        """

        unregistered_resources = [
            delta for delta in deltas if delta not in resources
        ]
        if unregistered_resources:
            raise exception.QuotaResourceUnknown(
                unknown=unregistered_resources)

        quotas = self.get_all_quotas_by_tenant(tenant_id, deltas.keys())
        quota_usages = self.get_all_quota_usages_by_tenant(
            tenant_id, deltas.keys())

        overs = [
            resource for resource in deltas
            if (int(deltas[resource]) > 0 and
                (quota_usages[resource].in_use +
                 quota_usages[resource].reserved +
                 int(deltas[resource])) > quotas[resource].hard_limit)
        ]

        if overs:
            raise exception.QuotaExceeded(overs=sorted(overs))

        reservations = []
        for resource in deltas:
            reserved = deltas[resource]
            usage = quota_usages[resource]
            usage.reserved += reserved
            usage.save()

            resv = Reservation.create(usage_id=usage.id,
                                      delta=reserved,
                                      status=Reservation.Statuses.RESERVED)
            reservations.append(resv)

        return reservations
Example #5
0
    def reserve(self, tenant_id, resources, deltas):
        """Check quotas and reserve resources for a tenant.

        This method checks quotas against current usage,
        reserved resources and the desired deltas.

        If any of the proposed values is over the defined quota, an
        QuotaExceeded exception will be raised with the sorted list of the
        resources which are too high.  Otherwise, the method returns a
        list of reservation objects which were created.

        :param tenant_id: The ID of the tenant reserving the resources.
        :param resources: A dictionary of the registered resources.
        :param deltas: A dictionary of the proposed delta changes.
        """

        unregistered_resources = [delta for delta in deltas
                                  if delta not in resources]
        if unregistered_resources:
            raise exception.QuotaResourceUnknown(unknown=
                                                 unregistered_resources)

        quotas = self.get_all_quotas_by_tenant(tenant_id, deltas.keys())
        quota_usages = self.get_all_quota_usages_by_tenant(tenant_id,
                                                           deltas.keys())

        overs = [resource for resource in deltas
                 if (int(deltas[resource]) > 0 and
                    (quota_usages[resource].in_use +
                     quota_usages[resource].reserved +
                     int(deltas[resource])) > quotas[resource].hard_limit)]

        if overs:
            raise exception.QuotaExceeded(overs=sorted(overs))

        reservations = []
        for resource in deltas:
            reserved = deltas[resource]
            usage = quota_usages[resource]
            usage.reserved += reserved
            usage.save()

            resv = Reservation.create(usage_id=usage.id,
                                      delta=reserved,
                                      status=Reservation.Statuses.RESERVED)
            reservations.append(resv)

        return reservations