Implement ProjectClaim objects

When calculating usage of a resource against a project, there is some
common information that we need to know as an enforcement library.
This can be referred to as a "claim", which consists of the name of
the resource being claimed, the project claiming the resources in the
request, and the quantity being claimed.

This commit adds some basic plumbing and tests that introduce this
object. Subsequent patches will introduce a context manager that
performs usage calculation using ProjecClaim objects.

Change-Id: Iacfa39535c58a7c6b49ba01c5ebf6bbb5f3fe8d1
This commit is contained in:
Lance Bragstad 2018-07-02 19:51:10 +00:00
parent e5d6b14534
commit 9f7fd57753
2 changed files with 114 additions and 3 deletions

46
oslo_limit/limit.py Normal file
View File

@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import six
class ProjectClaim(object):
def __init__(self, resource_name, project_id, quantity=None):
"""An object representing a claim of resources against a project.
:param resource_name: A string representing the resource to claim.
:type resource_name: string
:param project_id: The ID of the project claiming the resources.
:type project_id: string
:param quantity: The number of resources being claimed.
:type quantity: integer
"""
if not isinstance(resource_name, six.string_types):
msg = 'resource_name must be a string type.'
raise ValueError(msg)
if not isinstance(project_id, six.string_types):
msg = 'project_id must be a string type.'
raise ValueError(msg)
if quantity and not isinstance(quantity, int):
msg = 'quantity must be an integer.'
raise ValueError(msg)
self.resource_name = resource_name
self.project_id = project_id
self.quantity = quantity

View File

@ -19,10 +19,75 @@ test_limit
Tests for `limit` module.
"""
import uuid
from oslo_limit import limit
from oslotest import base
class TestLimit(base.BaseTestCase):
class TestProjectClaim(base.BaseTestCase):
def test_something(self):
pass
def test_required_parameters(self):
resource_name = uuid.uuid4().hex
project_id = uuid.uuid4().hex
claim = limit.ProjectClaim(resource_name, project_id)
self.assertEqual(resource_name, claim.resource_name)
self.assertEqual(project_id, claim.project_id)
self.assertIsNone(claim.quantity)
def test_optional_parameters(self):
resource_name = uuid.uuid4().hex
project_id = uuid.uuid4().hex
quantity = 10
claim = limit.ProjectClaim(
resource_name, project_id, quantity=quantity
)
self.assertEqual(resource_name, claim.resource_name)
self.assertEqual(project_id, claim.project_id)
self.assertEqual(quantity, claim.quantity)
def test_resource_name_must_be_a_string(self):
project_id = uuid.uuid4().hex
invalid_resource_name_types = [
True, False, [uuid.uuid4().hex], {'key': 'value'}, 1, 1.2
]
for invalid_resource_name in invalid_resource_name_types:
self.assertRaises(
ValueError,
limit.ProjectClaim,
invalid_resource_name,
project_id
)
def test_project_id_must_be_a_string(self):
resource_name = uuid.uuid4().hex
invalid_project_id_types = [
True, False, [uuid.uuid4().hex], {'key': 'value'}, 1, 1.2
]
for invalid_project_id in invalid_project_id_types:
self.assertRaises(
ValueError,
limit.ProjectClaim,
resource_name,
invalid_project_id
)
def test_quantity_must_be_an_integer(self):
resource_name = uuid.uuid4().hex
project_id = uuid.uuid4().hex
invalid_quantity_types = ['five', 5.5, [5], {5: 5}]
for invalid_quantity in invalid_quantity_types:
self.assertRaises(
ValueError,
limit.ProjectClaim,
resource_name,
invalid_quantity,
quantity=invalid_quantity
)