diff --git a/.github/workflows/precommit.yaml b/.github/workflows/precommit.yaml new file mode 100644 index 00000000..bb6c6e5b --- /dev/null +++ b/.github/workflows/precommit.yaml @@ -0,0 +1,31 @@ +name: Run pre-commit checks + +on: + pull_request: + push: + +jobs: + run-linters: + runs-on: ubuntu-latest + steps: + - name: Check out code + uses: actions/checkout@v4 + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: "3.x" + + - name: Configure caching + uses: actions/cache@v4 + with: + path: ~/.cache/pre-commit + key: precommit-${{ runner.os }}-${{ hashFiles('.pre-commit-config.yaml') }} + + - name: Install pre-commit + run: | + pip install pre-commit + + - name: Run linters + run: | + pre-commit run --all-files diff --git a/.github/workflows/tests.yml b/.github/workflows/unit-tests.yaml similarity index 92% rename from .github/workflows/tests.yml rename to .github/workflows/unit-tests.yaml index 397f7c15..366d3513 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/unit-tests.yaml @@ -20,7 +20,5 @@ jobs: run: | python -m pip install --upgrade pip pip install tox - - name: Lint - run: tox -epep8 - name: Unit Tests run: tox -epy3 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000..212018fc --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,24 @@ +repos: + - repo: https://github.com/Lucas-C/pre-commit-hooks + rev: v1.5.5 + hooks: + - id: remove-tabs + + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.6.0 + hooks: + - id: trailing-whitespace + - id: check-merge-conflict + - id: end-of-file-fixer + - id: check-added-large-files + - id: check-case-conflict + - id: detect-private-key + - id: check-yaml + args: [--allow-multiple-documents] + + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.5.2 + hooks: + - id: ruff + args: [ --fix ] + - id: ruff-format diff --git a/LICENSE b/LICENSE index 68c771a0..67db8588 100644 --- a/LICENSE +++ b/LICENSE @@ -173,4 +173,3 @@ defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. - diff --git a/README.md b/README.md index b46096b6..63b90f82 100644 --- a/README.md +++ b/README.md @@ -167,3 +167,23 @@ EOF ``` `1718` is the dummy node UUID; replace it with whatever you'd like. When creating an offer for this dummy node, simply specify `resource_type` as `dummy_node` and `resource_uuid` as `1718`. + +## Contributing + +### Pull requests + +When you submit a pull request, your changes will be validated by running a number of automatic tests. + +First, we run a series of [linters] and an automatic formatter on the code to check for a variety of minor issues and ensure consistent formatting. As a developer you will want to integrate these same checks into your local development environment: + +1. Install the [pre-commit] tool using your favorite package manager. +2. Run `pre-commit install` from inside this repository. + +This will enable a git [`pre-commit` hook][hooks] that will run the linters and formatter whenever you commit changes locally. We are using [`ruff`][ruff] for linting and formatting; this can be integrated into many editors to provide live checks as you are writing code. + +Next, we run all unit tests across all the Python versions supported by the `esi-leap` code. We expect that any changes introducing new functionality will also include appropriate unit tests to exercise those changes. + +[linters]: https://en.wikipedia.org/wiki/Lint_(software) +[pre-commit]: https://pre-commit.com/ +[hooks]: https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks +[ruff]: https://github.com/astral-sh/ruff diff --git a/babel.cfg b/babel.cfg index 15cd6cb7..efceab81 100644 --- a/babel.cfg +++ b/babel.cfg @@ -1,2 +1 @@ [python: **.py] - diff --git a/docs/esi-leap-api-ref.md b/docs/esi-leap-api-ref.md index 0d35b171..5b76b633 100644 --- a/docs/esi-leap-api-ref.md +++ b/docs/esi-leap-api-ref.md @@ -6,12 +6,12 @@ The Offer API endpoint can be reached at /v1/offers. * The /v1/offers/\ endpoint is used to retrieve the offer with the given uuid. The response type is 'application/json'. * The /v1/offers endpoint is used to retrieve a list of offers. This URL supports several URL variables for retrieving offers filtered by given values. The response type is 'application/json'. * project_id: Returns all offers with given project_id. - * status: Returns all offers with given status. + * status: Returns all offers with given status. * This value will default to returning offers with status 'available'. * This value can be set to 'any' to return offers without filtering by status. * resource_uuid: Returns all offers with given resource_uuid. * resource_type: Returns all offers with given resource_type - * start_time and end_time: Passing in values for the start_time and end_time variables will return all offers with a start_time and end_time which completely span the given values. These two URL variables must be used together. Passing in only one will throw an error. + * start_time and end_time: Passing in values for the start_time and end_time variables will return all offers with a start_time and end_time which completely span the given values. These two URL variables must be used together. Passing in only one will throw an error. * available_start_time and available_end_time: Passing in values for the available_start_time and available_end_time variables will return all offers with availabilities which completely span the given values. These two URL variables must be used together. Passing in only one will throw an error. @@ -32,9 +32,9 @@ The Offer API endpoint can be reached at /v1/offers. * properties: * a json object * This field is optional. Not setting it will default to {}. -* 'status', 'uuid', and 'availabilities' are read only. +* 'status', 'uuid', and 'availabilities' are read only. * The response to a POST request will be the newly created offer. The response type is 'application/json'. - + An example curl request is shown below. ``` curl -X POST -sH "X-Auth-Token: $token" http://localhost:7777/v1/offers -H 'Content-Type: application/json' -d '{ @@ -54,13 +54,13 @@ curl -X POST -sH "X-Auth-Token: $token" http://localhost:7777/v1/offers -H 'Con "size_gb": 500, "model": "YOYODYNE 1234" }, - { + { "size_gb": 1024, "model": "evo840 ssd" } ] } -}' +}' ``` ##### DELETE @@ -80,10 +80,10 @@ The lease api endpoint can be reached at /v1/leases * The /v1/leases endpoint is used to retrieve a list of leases. This URL supports several URL variables for retrieving offers filtered by given values. The response type is 'application/json'. * project_id: Returns all leases with given project_id. * This value will default to the project_id of the request. - * status: Returns all offers with given status. + * status: Returns all offers with given status. * This value will default to returning leases with status 'open'. * This value can be set to 'any' to return leases without filtering by status. - * start_time and end_time: Passing in values for the start_time and end_time variables will return all leases with a start_time and end_time which completely span the given values. These two URL variables must be used together. Passing in only one will throw an error. + * start_time and end_time: Passing in values for the start_time and end_time variables will return all leases with a start_time and end_time which completely span the given values. These two URL variables must be used together. Passing in only one will throw an error. * owner: Returns all leases which are related to offers with project_id 'owner'. * view: Setting view to 'all' will return all leases in the database. This value can be used in combination with other filters. @@ -101,7 +101,7 @@ The lease api endpoint can be reached at /v1/leases * offer_uuid_or_name: * A string. * This field is required. -* 'status' and 'uuid' are read only. +* 'status' and 'uuid' are read only. * The response to a POST request will be the newly created lease. The response type is 'application/json'. An example curl request is shown below. diff --git a/docs/esi-leap-reporting.md b/docs/esi-leap-reporting.md index 6558f56b..aa76f324 100644 --- a/docs/esi-leap-reporting.md +++ b/docs/esi-leap-reporting.md @@ -8,7 +8,7 @@ To generate a csv file with data on all lessees' usage on different nodes: openstack esi lease list --all --long -f csv > report.csv ``` -The ESI-Leap API allows users to retrieve data based on certain parameters. +The ESI-Leap API allows users to retrieve data based on certain parameters. For example, it is possible to generate a report based on a lessee's OpenStack project_id. To get a list of all projects type ``openstack project list`` and from there grab the desired project id and run the command: diff --git a/docs/esi-leap-requirements.md b/docs/esi-leap-requirements.md index 9db9d398..8a6e67b0 100644 --- a/docs/esi-leap-requirements.md +++ b/docs/esi-leap-requirements.md @@ -89,7 +89,7 @@ An offer response has the following fields: * deleted: an offer is no longer available for leasing. An offer is set to deleted when it is manually revoked by a user before its end_time has passed. * "properties" is the baremetal properties of an offer. * "availabilities" is a list of [start, end] datetime pairings representing a continuous time range in which an offer is available for leasing. - * "availabilities" is not kept in the schema and is computed when retrieving an offer. + * "availabilities" is not kept in the schema and is computed when retrieving an offer. * "created_at", "updated_at", and "id" are only used in the schema and cannot be read or set. @@ -164,11 +164,11 @@ A lease response has the following fields: ### Manager Service -An ESI-Leap manager has periodic jobs to manage offers and leases. +An ESI-Leap manager has periodic jobs to manage offers and leases. * expire offers: out-of-date offers, i.e, the current timestamp > offer's end_time, will be updated with an 'EXPIRED' status. -* fulfill leases: if a lease's start_time <= the current timestamp and is not expired, the manager service will fulfill the resources in the leases and update the status of the leases to 'active'. +* fulfill leases: if a lease's start_time <= the current timestamp and is not expired, the manager service will fulfill the resources in the leases and update the status of the leases to 'active'. * expire leases: same as 'expire offers', ESI-Leap will expire leases based on timestamp. -* update offers: after the manager fulfills and expires leases, it will update the relevant offers' status. The offers in a fulfilled lease should be unavailable to others. Likewise, when a lease expires, offers in the lease should be updated and be available again. +* update offers: after the manager fulfills and expires leases, it will update the relevant offers' status. The offers in a fulfilled lease should be unavailable to others. Likewise, when a lease expires, offers in the lease should be updated and be available again. ## Reporting API ESI-Leap admin queries this API to learn about the usage of nodes given a period. The admin enters a date range to get all leases' information within that range. The results could be like this: diff --git a/esi_leap/api/app.py b/esi_leap/api/app.py index 7cfd8a08..373e0ac8 100644 --- a/esi_leap/api/app.py +++ b/esi_leap/api/app.py @@ -32,11 +32,11 @@ def after(self, state): def get_pecan_config(): cfg_dict = { - 'app': { - 'root': CONF.pecan.root, - 'modules': CONF.pecan.modules, - 'debug': CONF.pecan.debug, - 'auth_enable': CONF.pecan.auth_enable + "app": { + "root": CONF.pecan.root, + "modules": CONF.pecan.modules, + "debug": CONF.pecan.debug, + "auth_enable": CONF.pecan.auth_enable, } } @@ -54,7 +54,7 @@ def setup_app(config=None): hooks=lambda: [ContextHook()], debug=CONF.pecan.debug, static_root=config.app.static_root if CONF.pecan.debug else None, - force_canonical=getattr(config.app, 'force_canonical', True), + force_canonical=getattr(config.app, "force_canonical", True), ) if CONF.pecan.auth_enable: diff --git a/esi_leap/api/controllers/base.py b/esi_leap/api/controllers/base.py index 59541acc..e34e1c3b 100644 --- a/esi_leap/api/controllers/base.py +++ b/esi_leap/api/controllers/base.py @@ -15,7 +15,6 @@ class ESILEAPBase(wtypes.Base): - def to_dict(self): esi_leap_dict = {} if self.fields: diff --git a/esi_leap/api/controllers/root.py b/esi_leap/api/controllers/root.py index 37e169bb..6d0b1fc9 100644 --- a/esi_leap/api/controllers/root.py +++ b/esi_leap/api/controllers/root.py @@ -17,29 +17,27 @@ from esi_leap.api.controllers.v1 import root -API_VERSION = 'v1' +API_VERSION = "v1" class RootController(rest.RestController): - _versions = [API_VERSION] _default_version = API_VERSION v1 = root.Controller() - @pecan.expose(content_type='application/json') + @pecan.expose(content_type="application/json") def index(self): pecan.response.status_code = 300 - pecan.response.content_type = 'application/json' + pecan.response.content_type = "application/json" versions = { - 'versions': [ + "versions": [ { - 'id': 'v1.0', - 'status': 'CURRENT', - 'links': [{ - 'href': '{0}/v1'.format(pecan.request.host_url), - 'rel': 'self' - }] + "id": "v1.0", + "status": "CURRENT", + "links": [ + {"href": "{0}/v1".format(pecan.request.host_url), "rel": "self"} + ], } ] } diff --git a/esi_leap/api/controllers/types.py b/esi_leap/api/controllers/types.py index 86f189af..0bca0dcd 100644 --- a/esi_leap/api/controllers/types.py +++ b/esi_leap/api/controllers/types.py @@ -20,12 +20,11 @@ class JsonType(wtypes.UserType): """A simple JSON type.""" basetype = wtypes.text - name = 'json' + name = "json" def __str__(self): # These are the json serializable native types - return ' | '.join(map(str, (wtypes.text, int, float, - bool, list, dict, None))) + return " | ".join(map(str, (wtypes.text, int, float, bool, list, dict, None))) @staticmethod def validate(value): @@ -38,7 +37,6 @@ def frombasetype(value): class Collection(wtypes.Base): - @property def collection(self): return getattr(self, self._type) @@ -52,15 +50,17 @@ def get_next(self, limit, url=None, **kwargs): return wtypes.Unset url = url or self._type - q_args = ''.join(['%s=%s&' % item for item in kwargs.items()]) - next_args = '?%(args)slimit=%(limit)d&marker=%(marker)s' % { - 'args': q_args, 'limit': limit, - 'marker': getattr(self.collection[-1], 'uuid')} - - next_link = '%(url)s/v1/%(resource)s%(args)s' % { - 'url': url, - 'resource': self._type, - 'args': next_args + q_args = "".join(["%s=%s&" % item for item in kwargs.items()]) + next_args = "?%(args)slimit=%(limit)d&marker=%(marker)s" % { + "args": q_args, + "limit": limit, + "marker": getattr(self.collection[-1], "uuid"), + } + + next_link = "%(url)s/v1/%(resource)s%(args)s" % { + "url": url, + "resource": self._type, + "args": next_args, } return next_link diff --git a/esi_leap/api/controllers/v1/event.py b/esi_leap/api/controllers/v1/event.py index 7473f4f0..d8aa5ae4 100644 --- a/esi_leap/api/controllers/v1/event.py +++ b/esi_leap/api/controllers/v1/event.py @@ -30,7 +30,6 @@ class Event(base.ESILEAPBase): - id = wsme.wsattr(int, readonly=True) event_type = wsme.wsattr(wtypes.text, readonly=True) event_time = wsme.wsattr(datetime.datetime, readonly=True) @@ -42,7 +41,6 @@ class Event(base.ESILEAPBase): owner_id = wsme.wsattr(wtypes.text, readonly=True) def __init__(self, **kwargs): - self.fields = event_obj.Event.fields for field in self.fields: setattr(self, field, kwargs.get(field, wtypes.Unset)) @@ -52,28 +50,41 @@ class EventCollection(types.Collection): events = [Event] def __init__(self, **kwargs): - self._type = 'events' + self._type = "events" class EventsController(rest.RestController): - - @wsme_pecan.wsexpose(EventCollection, int, wtypes.text, - datetime.datetime, wtypes.text, wtypes.text, - wtypes.text, wtypes.text) - def get_all(self, last_event_id=None, lessee_or_owner_id=None, - last_event_time=None, event_type=None, - resource_type=None, resource_uuid=None): + @wsme_pecan.wsexpose( + EventCollection, + int, + wtypes.text, + datetime.datetime, + wtypes.text, + wtypes.text, + wtypes.text, + wtypes.text, + ) + def get_all( + self, + last_event_id=None, + lessee_or_owner_id=None, + last_event_time=None, + event_type=None, + resource_type=None, + resource_uuid=None, + ): request = pecan.request.context cdict = request.to_policy_values() try: - utils.policy_authorize('esi_leap:offer:offer_admin', cdict, cdict) + utils.policy_authorize("esi_leap:offer:offer_admin", cdict, cdict) except exception.HTTPForbidden: - lessee_or_owner_id = cdict['project_id'] + lessee_or_owner_id = cdict["project_id"] if lessee_or_owner_id is not None: lessee_or_owner_id = keystone.get_project_uuid_from_ident( - lessee_or_owner_id) + lessee_or_owner_id + ) if resource_uuid is not None: if resource_type is None: @@ -82,12 +93,12 @@ def get_all(self, last_event_id=None, lessee_or_owner_id=None, resource_uuid = resource.get_uuid() filters = { - 'last_event_id': last_event_id, - 'last_event_time': last_event_time, - 'lessee_or_owner_id': lessee_or_owner_id, - 'event_type': event_type, - 'resource_type': resource_type, - 'resource_uuid': resource_uuid, + "last_event_id": last_event_id, + "last_event_time": last_event_time, + "lessee_or_owner_id": lessee_or_owner_id, + "event_type": event_type, + "resource_type": resource_type, + "resource_uuid": resource_uuid, } # unpack iterator to tuple so we can use 'del' @@ -99,15 +110,17 @@ def get_all(self, last_event_id=None, lessee_or_owner_id=None, event_collection = EventCollection() event_collection.events = [] for event in events: - e = Event(id=event.id, - event_type=event.event_type, - event_time=event.event_time, - object_type=event.object_type, - object_uuid=event.object_uuid, - resource_type=event.resource_type, - resource_uuid=event.resource_uuid, - lessee_id=event.lessee_id, - owner_id=event.owner_id) + e = Event( + id=event.id, + event_type=event.event_type, + event_time=event.event_time, + object_type=event.object_type, + object_uuid=event.object_uuid, + resource_type=event.resource_type, + resource_uuid=event.resource_uuid, + lessee_id=event.lessee_id, + owner_id=event.owner_id, + ) event_collection.events.append(e) return event_collection diff --git a/esi_leap/api/controllers/v1/lease.py b/esi_leap/api/controllers/v1/lease.py index 4fc7101f..1898396b 100644 --- a/esi_leap/api/controllers/v1/lease.py +++ b/esi_leap/api/controllers/v1/lease.py @@ -36,7 +36,6 @@ class Lease(base.ESILEAPBase): - name = wsme.wsattr(wtypes.text) uuid = wsme.wsattr(wtypes.text, readonly=True) project_id = wsme.wsattr(wtypes.text) @@ -63,8 +62,13 @@ def __init__(self, **kwargs): for field in self.fields: setattr(self, field, kwargs.get(field, wtypes.Unset)) - for attr in ('project', 'owner', 'resource', 'resource_class', - 'resource_properties'): + for attr in ( + "project", + "owner", + "resource", + "resource_class", + "resource_properties", + ): setattr(self, attr, kwargs.get(attr, wtypes.Unset)) @@ -72,27 +76,46 @@ class LeaseCollection(types.Collection): leases = [Lease] def __init__(self, **kwargs): - self._type = 'leases' + self._type = "leases" class LeasesController(rest.RestController): - @wsme_pecan.wsexpose(Lease, wtypes.text) def get_one(self, lease_id): request = pecan.request.context lease = utils.check_lease_policy_and_retrieve( - request, 'esi_leap:lease:get', lease_id) + request, "esi_leap:lease:get", lease_id + ) return Lease(**utils.lease_get_dict_with_added_info(lease)) - @wsme_pecan.wsexpose(LeaseCollection, wtypes.text, - datetime.datetime, datetime.datetime, wtypes.text, - wtypes.text, wtypes.text, wtypes.text, - wtypes.text, wtypes.text, wtypes.text) - def get_all(self, project_id=None, start_time=None, end_time=None, - status=None, offer_uuid=None, view=None, owner_id=None, - resource_type=None, resource_uuid=None, resource_class=None): + @wsme_pecan.wsexpose( + LeaseCollection, + wtypes.text, + datetime.datetime, + datetime.datetime, + wtypes.text, + wtypes.text, + wtypes.text, + wtypes.text, + wtypes.text, + wtypes.text, + wtypes.text, + ) + def get_all( + self, + project_id=None, + start_time=None, + end_time=None, + status=None, + offer_uuid=None, + view=None, + owner_id=None, + resource_type=None, + resource_uuid=None, + resource_class=None, + ): request = pecan.request.context cdict = request.to_policy_values() @@ -110,10 +133,17 @@ def get_all(self, project_id=None, start_time=None, end_time=None, resource_uuid = resource.get_uuid() filters = LeasesController._lease_get_all_authorize_filters( - cdict, project_id=project_id, owner_id=owner_id, - start_time=start_time, end_time=end_time, - status=status, offer_uuid=offer_uuid, view=view, - resource_type=resource_type, resource_uuid=resource_uuid) + cdict, + project_id=project_id, + owner_id=owner_id, + start_time=start_time, + end_time=end_time, + status=status, + offer_uuid=offer_uuid, + view=view, + resource_type=resource_type, + resource_uuid=resource_uuid, + ) lease_collection = LeaseCollection() leases = lease_obj.Lease.get_all(filters, request) @@ -131,13 +161,19 @@ def get_all(self, project_id=None, start_time=None, end_time=None, project_list = f2.result() leases_with_added_info = [ - Lease(**utils.lease_get_dict_with_added_info(l, project_list, - node_list)) - for l in leases] + Lease( + **utils.lease_get_dict_with_added_info( + lease, project_list, node_list + ) + ) + for lease in leases + ] if resource_class: lease_collection.leases = [ - l for l in leases_with_added_info - if l.resource_class == resource_class] + lease + for lease in leases_with_added_info + if lease.resource_class == resource_class + ] else: lease_collection.leases = leases_with_added_info @@ -147,32 +183,37 @@ def get_all(self, project_id=None, start_time=None, end_time=None, def post(self, new_lease): request = pecan.request.context cdict = request.to_policy_values() - utils.policy_authorize('esi_leap:lease:create', cdict, cdict) + utils.policy_authorize("esi_leap:lease:create", cdict, cdict) lease_dict = new_lease.to_dict() - lease_dict['owner_id'] = request.project_id - lease_dict['uuid'] = uuidutils.generate_uuid() - if 'resource_type' not in lease_dict: - lease_dict['resource_type'] = CONF.api.default_resource_type - resource = get_resource_object(lease_dict['resource_type'], - lease_dict['resource_uuid']) - lease_dict['resource_uuid'] = resource.get_uuid() - - if 'project_id' in lease_dict: - lease_dict['project_id'] = keystone.get_project_uuid_from_ident( - lease_dict['project_id']) - - if 'start_time' not in lease_dict: - lease_dict['start_time'] = datetime.datetime.now() - - if 'end_time' not in lease_dict: - lease_dict['end_time'] = lease_dict['start_time'] + \ - datetime.timedelta(days=CONF.api.default_lease_time) + lease_dict["owner_id"] = request.project_id + lease_dict["uuid"] = uuidutils.generate_uuid() + if "resource_type" not in lease_dict: + lease_dict["resource_type"] = CONF.api.default_resource_type + resource = get_resource_object( + lease_dict["resource_type"], lease_dict["resource_uuid"] + ) + lease_dict["resource_uuid"] = resource.get_uuid() + + if "project_id" in lease_dict: + lease_dict["project_id"] = keystone.get_project_uuid_from_ident( + lease_dict["project_id"] + ) + + if "start_time" not in lease_dict: + lease_dict["start_time"] = datetime.datetime.now() + + if "end_time" not in lease_dict: + lease_dict["end_time"] = lease_dict["start_time"] + datetime.timedelta( + days=CONF.api.default_lease_time + ) else: - utils.check_lease_length(cdict, - lease_dict['start_time'], - lease_dict['end_time'], - CONF.api.max_lease_time) + utils.check_lease_length( + cdict, + lease_dict["start_time"], + lease_dict["end_time"], + CONF.api.max_lease_time, + ) try: utils.check_resource_admin(cdict, resource, request.project_id) @@ -181,11 +222,12 @@ def post(self, new_lease): cdict, resource, request.project_id, - lease_dict.get('start_time'), - lease_dict.get('end_time')) + lease_dict.get("start_time"), + lease_dict.get("end_time"), + ) if parent_lease_uuid is None: raise - lease_dict['parent_lease_uuid'] = parent_lease_uuid + lease_dict["parent_lease_uuid"] = parent_lease_uuid lease = lease_obj.Lease(**lease_dict) lease.create(request) @@ -196,16 +238,18 @@ def patch(self, lease_uuid, patch=None): request = pecan.request.context lease = utils.check_lease_policy_and_retrieve( - request, 'esi_leap:lease:update', lease_uuid) + request, "esi_leap:lease:update", lease_uuid + ) # check that patch has acceptable fields; only end_time for now patch_keys = patch.keys() - if not('end_time' in patch_keys and len(patch_keys) == 1): + if not ("end_time" in patch_keys and len(patch_keys) == 1): raise exception.LeaseInvalidPatch() new_end_time = datetime.datetime.strptime( - patch['end_time'], '%Y-%m-%dT%H:%M:%S') - updates = {'end_time': new_end_time} + patch["end_time"], "%Y-%m-%dT%H:%M:%S" + ) + updates = {"end_time": new_end_time} lease.update(updates, request) return Lease(**utils.lease_get_dict_with_added_info(lease)) @@ -215,69 +259,79 @@ def delete(self, lease_id): request = pecan.request.context lease = utils.check_lease_policy_and_retrieve( - request, 'esi_leap:lease:get', lease_id, - statuses.LEASE_CAN_DELETE) + request, "esi_leap:lease:get", lease_id, statuses.LEASE_CAN_DELETE + ) lease.cancel(request) @staticmethod - def _lease_get_all_authorize_filters(cdict, - start_time=None, end_time=None, - status=None, offer_uuid=None, - project_id=None, view=None, - owner_id=None, resource_type=None, - resource_uuid=None): - + def _lease_get_all_authorize_filters( + cdict, + start_time=None, + end_time=None, + status=None, + offer_uuid=None, + project_id=None, + view=None, + owner_id=None, + resource_type=None, + resource_uuid=None, + ): if status is not None: - status = [status] if status != 'any' else None + status = [status] if status != "any" else None else: - status = [statuses.CREATED, statuses.ACTIVE, statuses.ERROR, - statuses.WAIT_CANCEL, statuses.WAIT_EXPIRE, - statuses.WAIT_FULFILL] + status = [ + statuses.CREATED, + statuses.ACTIVE, + statuses.ERROR, + statuses.WAIT_CANCEL, + statuses.WAIT_EXPIRE, + statuses.WAIT_FULFILL, + ] filters = { - 'status': status, - 'offer_uuid': offer_uuid, - 'start_time': start_time, - 'end_time': end_time, - 'resource_type': resource_type, - 'resource_uuid': resource_uuid, - 'time_filter_type': constants.WITHIN_TIME_FILTER, + "status": status, + "offer_uuid": offer_uuid, + "start_time": start_time, + "end_time": end_time, + "resource_type": resource_type, + "resource_uuid": resource_uuid, + "time_filter_type": constants.WITHIN_TIME_FILTER, } - if view == 'all': - utils.policy_authorize('esi_leap:lease:lease_admin', cdict, cdict) - filters['owner_id'] = owner_id - filters['project_id'] = project_id + if view == "all": + utils.policy_authorize("esi_leap:lease:lease_admin", cdict, cdict) + filters["owner_id"] = owner_id + filters["project_id"] = project_id else: - utils.policy_authorize('esi_leap:lease:get_all', cdict, cdict) + utils.policy_authorize("esi_leap:lease:get_all", cdict, cdict) if owner_id: - if cdict['project_id'] != owner_id: - utils.policy_authorize('esi_leap:lease:lease_admin', cdict, - cdict) + if cdict["project_id"] != owner_id: + utils.policy_authorize("esi_leap:lease:lease_admin", cdict, cdict) - filters['owner_id'] = owner_id - filters['project_id'] = project_id + filters["owner_id"] = owner_id + filters["project_id"] = project_id else: if project_id is None: - project_id = cdict['project_id'] - filters['project_or_owner_id'] = project_id + project_id = cdict["project_id"] + filters["project_or_owner_id"] = project_id else: - if project_id != cdict['project_id']: - utils.policy_authorize('esi_leap:lease:lease_admin', - cdict, cdict) - filters['project_id'] = project_id + if project_id != cdict["project_id"]: + utils.policy_authorize( + "esi_leap:lease:lease_admin", cdict, cdict + ) + filters["project_id"] = project_id # either both are defined or both are None if bool(start_time) != bool(end_time): - raise exception.InvalidTimeAPICommand(resource='a lease', - start_time=str(start_time), - end_time=str(end_time)) + raise exception.InvalidTimeAPICommand( + resource="a lease", start_time=str(start_time), end_time=str(end_time) + ) if (start_time or end_time) and (end_time <= start_time): - raise exception.InvalidTimeAPICommand(resource='a lease', - start_time=str(start_time), - end_time=str(end_time)) + raise exception.InvalidTimeAPICommand( + resource="a lease", start_time=str(start_time), end_time=str(end_time) + ) # unpack iterator to tuple so we can use 'del' for k, v in tuple(filters.items()): diff --git a/esi_leap/api/controllers/v1/node.py b/esi_leap/api/controllers/v1/node.py index 7c67fd62..c780a55f 100644 --- a/esi_leap/api/controllers/v1/node.py +++ b/esi_leap/api/controllers/v1/node.py @@ -31,7 +31,6 @@ class Node(base.ESILEAPBase): - name = wsme.wsattr(wtypes.text) owner = wsme.wsattr(wtypes.text) maintenance = wsme.wsattr(wtypes.text) @@ -49,11 +48,23 @@ class Node(base.ESILEAPBase): future_leases = wsme.wsattr(wtypes.text) def __init__(self, **kwargs): - self.fields = ('name', 'owner', 'uuid', 'offer_uuid', 'lease_uuid', - 'lessee', 'future_offers', 'future_leases', - 'resource_class', 'provision_state', 'maintenance', - 'properties', 'target_provision_state', 'power_state', - 'target_power_state') + self.fields = ( + "name", + "owner", + "uuid", + "offer_uuid", + "lease_uuid", + "lessee", + "future_offers", + "future_leases", + "resource_class", + "provision_state", + "maintenance", + "properties", + "target_provision_state", + "power_state", + "target_power_state", + ) for field in self.fields: setattr(self, field, kwargs.get(field, wtypes.Unset)) @@ -62,16 +73,13 @@ class NodeCollection(types.Collection): nodes = [Node] def __init__(self, **kwargs): - self._type = 'nodes' - self.nodes = kwargs.get('nodes', []) + self._type = "nodes" + self.nodes = kwargs.get("nodes", []) class NodesController(rest.RestController): - - @wsme_pecan.wsexpose(NodeCollection, wtypes.text, - wtypes.text, wtypes.text) - def get_all(self, resource_class=None, owner=None, - lessee=None): + @wsme_pecan.wsexpose(NodeCollection, wtypes.text, wtypes.text, wtypes.text) + def get_all(self, resource_class=None, owner=None, lessee=None): context = pecan.request.context if owner is not None: @@ -80,18 +88,16 @@ def get_all(self, resource_class=None, owner=None, lessee = keystone.get_project_uuid_from_ident(lessee) filter_args = { - 'resource_class': resource_class, - 'owner': owner, - 'lessee': lessee + "resource_class": resource_class, + "owner": owner, + "lessee": lessee, } nodes = None project_list = None with concurrent.futures.ThreadPoolExecutor() as executor: - filter_args = { - k: v for k, v in filter_args.items() if v is not None - } + filter_args = {k: v for k, v in filter_args.items() if v is not None} f1 = executor.submit(ironic.get_node_list, context, **filter_args) f2 = executor.submit(keystone.get_project_list) nodes = f1.result() @@ -101,48 +107,49 @@ def get_all(self, resource_class=None, owner=None, now = datetime.now() - offers = offer_obj.Offer.get_all({'status': [statuses.AVAILABLE]}, - context) + offers = offer_obj.Offer.get_all({"status": [statuses.AVAILABLE]}, context) - leases = lease_obj.Lease.get_all({'status': [statuses.CREATED]}, - context) + leases = lease_obj.Lease.get_all({"status": [statuses.CREATED]}, context) for node in nodes: future_offers = [] current_offer = None - node_offers = [offer for offer in offers - if offer.resource_uuid == node.uuid] + node_offers = [ + offer for offer in offers if offer.resource_uuid == node.uuid + ] for offer in node_offers: if offer.start_time > now: future_offers.append(offer.uuid) elif offer.end_time >= now: current_offer = offer - future_offers = ' '.join(future_offers) - - f_lease_uuids = ''.join([lease.uuid for lease in leases - if lease.resource_uuid == node.uuid]) - - n = Node(name=node.name, uuid=node.uuid, - provision_state=node.provision_state, - target_provision_state=node.target_provision_state, - power_state=node.power_state, - target_power_state=node.target_power_state, - resource_class=node.resource_class, - properties=ironic.get_condensed_properties( - node.properties), - maintenance=str(node.maintenance), - owner=keystone.get_project_name(node.owner, project_list), - lessee=keystone.get_project_name(node.lessee, - project_list), - future_offers=future_offers, - future_leases=f_lease_uuids) + future_offers = " ".join(future_offers) + + f_lease_uuids = "".join( + [lease.uuid for lease in leases if lease.resource_uuid == node.uuid] + ) + + n = Node( + name=node.name, + uuid=node.uuid, + provision_state=node.provision_state, + target_provision_state=node.target_provision_state, + power_state=node.power_state, + target_power_state=node.target_power_state, + resource_class=node.resource_class, + properties=ironic.get_condensed_properties(node.properties), + maintenance=str(node.maintenance), + owner=keystone.get_project_name(node.owner, project_list), + lessee=keystone.get_project_name(node.lessee, project_list), + future_offers=future_offers, + future_leases=f_lease_uuids, + ) if current_offer: n.offer_uuid = current_offer.uuid - if 'lease_uuid' in node.properties: - n.lease_uuid = node.properties['lease_uuid'] + if "lease_uuid" in node.properties: + n.lease_uuid = node.properties["lease_uuid"] node_collection.nodes.append(n) diff --git a/esi_leap/api/controllers/v1/offer.py b/esi_leap/api/controllers/v1/offer.py index d9f387b8..b22dcabb 100644 --- a/esi_leap/api/controllers/v1/offer.py +++ b/esi_leap/api/controllers/v1/offer.py @@ -37,7 +37,6 @@ class Offer(base.ESILEAPBase): - name = wsme.wsattr(wtypes.text) uuid = wsme.wsattr(wtypes.text, readonly=True) project_id = wsme.wsattr(wtypes.text, readonly=True) @@ -57,14 +56,18 @@ class Offer(base.ESILEAPBase): parent_lease_uuid = wsme.wsattr(wtypes.text, readonly=True) def __init__(self, **kwargs): - self.fields = offer_obj.Offer.fields for field in self.fields: setattr(self, field, kwargs.get(field, wtypes.Unset)) - for attr in ('availabilities', 'project', 'lessee', - 'resource', 'resource_class', - 'resource_properties'): + for attr in ( + "availabilities", + "project", + "lessee", + "resource", + "resource_class", + "resource_properties", + ): setattr(self, attr, kwargs.get(attr, wtypes.Unset)) @@ -72,14 +75,11 @@ class OfferCollection(types.Collection): offers = [Offer] def __init__(self, **kwargs): - self._type = 'offers' + self._type = "offers" class OffersController(rest.RestController): - - _custom_actions = { - 'claim': ['POST'] - } + _custom_actions = {"claim": ["POST"]} @wsme_pecan.wsexpose(Offer, wtypes.text) def get_one(self, offer_id): @@ -87,25 +87,41 @@ def get_one(self, offer_id): cdict = request.to_policy_values() offer = utils.check_offer_policy_and_retrieve( - request, 'esi_leap:offer:get', offer_id) + request, "esi_leap:offer:get", offer_id + ) utils.check_offer_lessee(cdict, offer) o = utils.offer_get_dict_with_added_info(offer) return Offer(**o) - @wsme_pecan.wsexpose(OfferCollection, wtypes.text, wtypes.text, - wtypes.text, wtypes.text, datetime.datetime, - datetime.datetime, datetime.datetime, - datetime.datetime, wtypes.text) - def get_all(self, project_id=None, resource_type=None, - resource_class=None, resource_uuid=None, - start_time=None, end_time=None, - available_start_time=None, available_end_time=None, - status=None): + @wsme_pecan.wsexpose( + OfferCollection, + wtypes.text, + wtypes.text, + wtypes.text, + wtypes.text, + datetime.datetime, + datetime.datetime, + datetime.datetime, + datetime.datetime, + wtypes.text, + ) + def get_all( + self, + project_id=None, + resource_type=None, + resource_class=None, + resource_uuid=None, + start_time=None, + end_time=None, + available_start_time=None, + available_end_time=None, + status=None, + ): request = pecan.request.context cdict = request.to_policy_values() - utils.policy_authorize('esi_leap:offer:get_all', cdict, cdict) + utils.policy_authorize("esi_leap:offer:get_all", cdict, cdict) if project_id is not None: project_id = keystone.get_project_uuid_from_ident(project_id) @@ -118,47 +134,48 @@ def get_all(self, project_id=None, resource_type=None, # either both are defined or both are None if bool(start_time) != bool(end_time): - raise exception.InvalidTimeAPICommand(resource='an offer', - start_time=str(start_time), - end_time=str(end_time)) + raise exception.InvalidTimeAPICommand( + resource="an offer", start_time=str(start_time), end_time=str(end_time) + ) if (start_time or end_time) and (end_time <= start_time): - raise exception.InvalidTimeAPICommand(resource='an offer', - start_time=str(start_time), - end_time=str(end_time)) + raise exception.InvalidTimeAPICommand( + resource="an offer", start_time=str(start_time), end_time=str(end_time) + ) if bool(available_start_time) != bool(available_end_time): raise exception.InvalidAvailabilityAPICommand( - a_start=str(available_start_time), - a_end=str(available_end_time)) - if ((available_start_time or available_end_time) and - (available_end_time <= available_start_time)): + a_start=str(available_start_time), a_end=str(available_end_time) + ) + if (available_start_time or available_end_time) and ( + available_end_time <= available_start_time + ): raise exception.InvalidAvailabilityAPICommand( - a_start=str(available_start_time), - a_end=str(available_end_time)) + a_start=str(available_start_time), a_end=str(available_end_time) + ) if status is None: status = statuses.OFFER_CAN_DELETE - elif status == 'any': + elif status == "any": status = None else: status = [status] try: - utils.policy_authorize('esi_leap:offer:offer_admin', cdict, cdict) + utils.policy_authorize("esi_leap:offer:offer_admin", cdict, cdict) lessee_id = None except exception.HTTPForbidden: - lessee_id = cdict['project_id'] + lessee_id = cdict["project_id"] filters = { - 'project_id': project_id, - 'lessee_id': lessee_id, - 'resource_type': resource_type, - 'resource_uuid': resource_uuid, - 'status': status, - 'start_time': start_time, - 'end_time': end_time, - 'available_start_time': available_start_time, - 'available_end_time': available_end_time, + "project_id": project_id, + "lessee_id": lessee_id, + "resource_type": resource_type, + "resource_uuid": resource_uuid, + "status": status, + "start_time": start_time, + "end_time": end_time, + "available_start_time": available_start_time, + "available_end_time": available_end_time, } # unpack iterator to tuple so we can use 'del' @@ -181,13 +198,17 @@ def get_all(self, project_id=None, resource_type=None, project_list = f2.result() offers_with_added_info = [ - Offer(**utils.offer_get_dict_with_added_info(o, project_list, - node_list)) - for o in offers] + Offer( + **utils.offer_get_dict_with_added_info(o, project_list, node_list) + ) + for o in offers + ] if resource_class: offer_collection.offers = [ - o for o in offers_with_added_info - if o.resource_class == resource_class] + o + for o in offers_with_added_info + if o.resource_class == resource_class + ] else: offer_collection.offers = offers_with_added_info @@ -197,31 +218,34 @@ def get_all(self, project_id=None, resource_type=None, def post(self, new_offer): request = pecan.request.context cdict = request.to_policy_values() - utils.policy_authorize('esi_leap:offer:create', cdict, cdict) + utils.policy_authorize("esi_leap:offer:create", cdict, cdict) offer_dict = new_offer.to_dict() - offer_dict['project_id'] = request.project_id - offer_dict['uuid'] = uuidutils.generate_uuid() - if 'resource_type' not in offer_dict: - offer_dict['resource_type'] = CONF.api.default_resource_type - resource = get_resource_object(offer_dict['resource_type'], - offer_dict['resource_uuid']) - offer_dict['resource_uuid'] = resource.get_uuid() - - if 'lessee_id' in offer_dict: - offer_dict['lessee_id'] = keystone.get_project_uuid_from_ident( - offer_dict['lessee_id']) - - if 'start_time' not in offer_dict: - offer_dict['start_time'] = datetime.datetime.now() - if 'end_time' not in offer_dict: - offer_dict['end_time'] = datetime.datetime.max - - if offer_dict['start_time'] >= offer_dict['end_time']: + offer_dict["project_id"] = request.project_id + offer_dict["uuid"] = uuidutils.generate_uuid() + if "resource_type" not in offer_dict: + offer_dict["resource_type"] = CONF.api.default_resource_type + resource = get_resource_object( + offer_dict["resource_type"], offer_dict["resource_uuid"] + ) + offer_dict["resource_uuid"] = resource.get_uuid() + + if "lessee_id" in offer_dict: + offer_dict["lessee_id"] = keystone.get_project_uuid_from_ident( + offer_dict["lessee_id"] + ) + + if "start_time" not in offer_dict: + offer_dict["start_time"] = datetime.datetime.now() + if "end_time" not in offer_dict: + offer_dict["end_time"] = datetime.datetime.max + + if offer_dict["start_time"] >= offer_dict["end_time"]: raise exception.InvalidTimeRange( - resource='an offer', - start_time=str(offer_dict['start_time']), - end_time=str(offer_dict['end_time'])) + resource="an offer", + start_time=str(offer_dict["start_time"]), + end_time=str(offer_dict["end_time"]), + ) try: utils.check_resource_admin(cdict, resource, request.project_id) @@ -230,11 +254,12 @@ def post(self, new_offer): cdict, resource, request.project_id, - offer_dict.get('start_time'), - offer_dict.get('end_time')) + offer_dict.get("start_time"), + offer_dict.get("end_time"), + ) if parent_lease_uuid is None: raise - offer_dict['parent_lease_uuid'] = parent_lease_uuid + offer_dict["parent_lease_uuid"] = parent_lease_uuid o = offer_obj.Offer(**offer_dict) o.create() @@ -245,41 +270,42 @@ def delete(self, offer_id): request = pecan.request.context offer = utils.check_offer_policy_and_retrieve( - request, 'esi_leap:offer:delete', offer_id, - statuses.OFFER_CAN_DELETE) + request, "esi_leap:offer:delete", offer_id, statuses.OFFER_CAN_DELETE + ) offer.cancel() - @wsme_pecan.wsexpose(lease.Lease, wtypes.text, body=lease.Lease, - status_code=http_client.CREATED) + @wsme_pecan.wsexpose( + lease.Lease, wtypes.text, body=lease.Lease, status_code=http_client.CREATED + ) def claim(self, offer_uuid, new_lease): request = pecan.request.context cdict = request.to_policy_values() offer = utils.check_offer_policy_and_retrieve( - request, 'esi_leap:offer:claim', offer_uuid, [statuses.AVAILABLE]) + request, "esi_leap:offer:claim", offer_uuid, [statuses.AVAILABLE] + ) utils.check_offer_lessee(cdict, offer) lease_dict = new_lease.to_dict() - lease_dict['project_id'] = request.project_id - lease_dict['uuid'] = uuidutils.generate_uuid() - lease_dict['offer_uuid'] = offer_uuid - lease_dict['resource_type'] = offer.resource_type - lease_dict['resource_uuid'] = offer.resource_uuid - lease_dict['owner_id'] = offer.project_id + lease_dict["project_id"] = request.project_id + lease_dict["uuid"] = uuidutils.generate_uuid() + lease_dict["offer_uuid"] = offer_uuid + lease_dict["resource_type"] = offer.resource_type + lease_dict["resource_uuid"] = offer.resource_uuid + lease_dict["owner_id"] = offer.project_id if offer.parent_lease_uuid is not None: - lease_dict['parent_lease_uuid'] = offer.parent_lease_uuid + lease_dict["parent_lease_uuid"] = offer.parent_lease_uuid - if 'start_time' not in lease_dict: - lease_dict['start_time'] = datetime.datetime.now() + if "start_time" not in lease_dict: + lease_dict["start_time"] = datetime.datetime.now() - if 'end_time' not in lease_dict: - q = offer.get_next_lease_start_time( - lease_dict['start_time']) + if "end_time" not in lease_dict: + q = offer.get_next_lease_start_time(lease_dict["start_time"]) if q is None: - lease_dict['end_time'] = offer.end_time + lease_dict["end_time"] = offer.end_time else: - lease_dict['end_time'] = q.start_time + lease_dict["end_time"] = q.start_time new_lease = lease_obj.Lease(**lease_dict) new_lease.create(request) diff --git a/esi_leap/api/controllers/v1/root.py b/esi_leap/api/controllers/v1/root.py index 62c9eaba..00fd4fde 100644 --- a/esi_leap/api/controllers/v1/root.py +++ b/esi_leap/api/controllers/v1/root.py @@ -21,25 +21,23 @@ class Controller(rest.RestController): - leases = lease.LeasesController() offers = offer.OffersController() nodes = node.NodesController() events = event.EventsController() - @pecan.expose(content_type='application/json') + @pecan.expose(content_type="application/json") def index(self): pecan.response.status_code = 300 - pecan.response.content_type = 'application/json' + pecan.response.content_type = "application/json" versions = { - 'versions': [ + "versions": [ { - 'id': 'v1.0', - 'status': 'CURRENT', - 'links': [{ - 'href': '{0}/v1'.format(pecan.request.host_url), - 'rel': 'self' - }] + "id": "v1.0", + "status": "CURRENT", + "links": [ + {"href": "{0}/v1".format(pecan.request.host_url), "rel": "self"} + ], } ] } diff --git a/esi_leap/api/controllers/v1/utils.py b/esi_leap/api/controllers/v1/utils.py index f4335d65..25d3e892 100644 --- a/esi_leap/api/controllers/v1/utils.py +++ b/esi_leap/api/controllers/v1/utils.py @@ -24,14 +24,16 @@ def check_resource_admin(cdict, resource, project_id): if project_id != resource.get_owner_project_id(): - resource_policy_authorize('esi_leap:offer:offer_admin', - cdict, cdict, - resource.resource_type, - resource.get_uuid()) + resource_policy_authorize( + "esi_leap:offer:offer_admin", + cdict, + cdict, + resource.resource_type, + resource.get_uuid(), + ) -def check_resource_lease_admin(cdict, resource, project_id, - start_time, end_time): +def check_resource_lease_admin(cdict, resource, project_id, start_time, end_time): # check to see if project is current lessee if project_id == resource.get_lessee_project_id(): parent_lease_uuid = resource.get_lease_uuid() @@ -41,15 +43,17 @@ def check_resource_lease_admin(cdict, resource, project_id, # don't allow sub-sub-leases if parent_lease.parent_lease_uuid is None: # check if offer is within start and end time bounds - if ((start_time >= parent_lease.start_time) and - (end_time <= parent_lease.end_time)): + if (start_time >= parent_lease.start_time) and ( + end_time <= parent_lease.end_time + ): return parent_lease_uuid else: raise exception.ResourceNoPermissionTime( resource_type=resource.resource_type, resource_uuid=resource.get_uuid(), start_time=start_time, - end_time=end_time) + end_time=end_time, + ) def get_offer(uuid_or_name, status_filters=[]): @@ -60,8 +64,9 @@ def get_offer(uuid_or_name, status_filters=[]): else: raise exception.OfferNotFound(offer_uuid=uuid_or_name) else: - offers = offer_obj.Offer.get_all({'name': uuid_or_name, - 'status': status_filters}) + offers = offer_obj.Offer.get_all( + {"name": uuid_or_name, "status": status_filters} + ) if len(offers) != 1: if len(offers) == 0: @@ -80,8 +85,9 @@ def get_lease(uuid_or_name, status_filters=[]): else: raise exception.LeaseNotFound(lease_id=uuid_or_name) else: - leases = lease_obj.Lease.get_all({'name': uuid_or_name, - 'status': status_filters}) + leases = lease_obj.Lease.get_all( + {"name": uuid_or_name, "status": status_filters} + ) if len(leases) != 1: if len(leases) == 0: @@ -99,42 +105,44 @@ def policy_authorize(policy_name, target, creds): raise exception.HTTPForbidden(rule=policy_name) -def resource_policy_authorize(policy_name, target, creds, - resource_type, resource): +def resource_policy_authorize(policy_name, target, creds, resource_type, resource): try: policy_authorize(policy_name, target, creds) except exception.HTTPForbidden: - raise exception.HTTPResourceForbidden(resource_type=resource_type, - resource=resource) + raise exception.HTTPResourceForbidden( + resource_type=resource_type, resource=resource + ) -def check_lease_policy_and_retrieve(request, policy_name, lease_ident, - status_filters=[]): +def check_lease_policy_and_retrieve( + request, policy_name, lease_ident, status_filters=[] +): lease = get_lease(lease_ident, status_filters) cdict = request.to_policy_values() target = dict(cdict) - target['lease.owner_id'] = lease.owner_id - target['lease.project_id'] = lease.project_id + target["lease.owner_id"] = lease.owner_id + target["lease.project_id"] = lease.project_id - resource_policy_authorize(policy_name, target, cdict, 'lease', lease.uuid) + resource_policy_authorize(policy_name, target, cdict, "lease", lease.uuid) return lease -def check_offer_policy_and_retrieve(request, policy_name, offer_ident, - status_filters=[]): +def check_offer_policy_and_retrieve( + request, policy_name, offer_ident, status_filters=[] +): offer = get_offer(offer_ident, status_filters) cdict = request.to_policy_values() target = dict(cdict) - target['offer.project_id'] = offer.project_id + target["offer.project_id"] = offer.project_id - resource_policy_authorize(policy_name, target, cdict, 'offer', offer.uuid) + resource_policy_authorize(policy_name, target, cdict, "offer", offer.uuid) return offer def check_offer_lessee(cdict, offer): - project_id = cdict['project_id'] + project_id = cdict["project_id"] # pass if offer has no lessee limitation or project_id created the offer if offer.lessee_id is None or offer.project_id == project_id: @@ -142,20 +150,20 @@ def check_offer_lessee(cdict, offer): if offer.lessee_id not in keystone.get_parent_project_id_tree(project_id): resource_policy_authorize( - 'esi_leap:offer:offer_admin', - cdict, cdict, 'offer', offer.uuid) + "esi_leap:offer:offer_admin", cdict, cdict, "offer", offer.uuid + ) def offer_get_dict_with_added_info(offer, project_list=None, node_list=None): resource = offer.resource_object() o = offer.to_dict() - o['availabilities'] = offer.get_availabilities() - o['project'] = keystone.get_project_name(offer.project_id, project_list) - o['lessee'] = keystone.get_project_name(offer.lessee_id, project_list) - o['resource'] = resource.get_name(node_list) - o['resource_class'] = resource.get_resource_class(node_list) - o['resource_properties'] = resource.get_properties(node_list) + o["availabilities"] = offer.get_availabilities() + o["project"] = keystone.get_project_name(offer.project_id, project_list) + o["lessee"] = keystone.get_project_name(offer.lessee_id, project_list) + o["resource"] = resource.get_name(node_list) + o["resource_class"] = resource.get_resource_class(node_list) + o["resource_properties"] = resource.get_properties(node_list) return o @@ -163,13 +171,11 @@ def lease_get_dict_with_added_info(lease, project_list=None, node_list=None): resource = lease.resource_object() lease_dict = lease.to_dict() - lease_dict['project'] = keystone.get_project_name(lease.project_id, - project_list) - lease_dict['owner'] = keystone.get_project_name(lease.owner_id, - project_list) - lease_dict['resource'] = resource.get_name(node_list) - lease_dict['resource_class'] = resource.get_resource_class(node_list) - lease_dict['resource_properties'] = resource.get_properties(node_list) + lease_dict["project"] = keystone.get_project_name(lease.project_id, project_list) + lease_dict["owner"] = keystone.get_project_name(lease.owner_id, project_list) + lease_dict["resource"] = resource.get_name(node_list) + lease_dict["resource_class"] = resource.get_resource_class(node_list) + lease_dict["resource_properties"] = resource.get_properties(node_list) return lease_dict @@ -178,6 +184,6 @@ def check_lease_length(cdict, start_time, end_time, max_time): # Check if the current project is admin # Only admin project can set a lease beyond the max length try: - policy_authorize('esi_leap:lease:lease_admin', cdict, cdict) + policy_authorize("esi_leap:lease:lease_admin", cdict, cdict) except exception.HTTPForbidden: raise exception.LeaseExceedMaxTimeRange(max_time=max_time) diff --git a/esi_leap/api/service.py b/esi_leap/api/service.py index d50182f2..fac34903 100644 --- a/esi_leap/api/service.py +++ b/esi_leap/api/service.py @@ -22,19 +22,18 @@ class WSGIService(service.ServiceBase): - def __init__(self, name): self.name = name self.app = app.setup_app() - self.workers = ( - CONF.api.api_workers or processutils.get_worker_count() - ) + self.workers = CONF.api.api_workers or processutils.get_worker_count() self.server = wsgi.Server( - CONF, name, self.app, + CONF, + name, + self.app, host=CONF.api.host_ip, port=CONF.api.port, - use_ssl=CONF.api.enable_ssl_api + use_ssl=CONF.api.enable_ssl_api, ) def start(self): diff --git a/esi_leap/api/wsgi.py b/esi_leap/api/wsgi.py index 8f00a623..6cfb794d 100644 --- a/esi_leap/api/wsgi.py +++ b/esi_leap/api/wsgi.py @@ -25,11 +25,11 @@ def initialize_wsgi_app(argv=sys.argv): - i18n.install('esi_leap') + i18n.install("esi_leap") service.prepare_service(argv) - LOG.debug('Configuration:') + LOG.debug("Configuration:") CONF.log_opt_values(LOG, logging.DEBUG) return WSGIApplication() diff --git a/esi_leap/cmd/api.py b/esi_leap/cmd/api.py index 841eb441..458939ab 100644 --- a/esi_leap/cmd/api.py +++ b/esi_leap/cmd/api.py @@ -25,7 +25,7 @@ def main(): esi_leap_service.prepare_service(sys.argv) # Build and start the WSGI app - launcher = service.ProcessLauncher(CONF, restart_method='mutate') - server = wsgi_service.WSGIService('esi_leap_api') + launcher = service.ProcessLauncher(CONF, restart_method="mutate") + server = wsgi_service.WSGIService("esi_leap_api") launcher.launch_service(server, workers=server.workers) launcher.wait() diff --git a/esi_leap/cmd/dbsync.py b/esi_leap/cmd/dbsync.py index c55ef561..7dbe97c4 100644 --- a/esi_leap/cmd/dbsync.py +++ b/esi_leap/cmd/dbsync.py @@ -26,7 +26,6 @@ class DBCommand(object): - def create_schema(self): migration.create_schema() @@ -50,46 +49,42 @@ def add_command_parsers(subparsers): command_object = DBCommand() parser = subparsers.add_parser( - 'create_schema', - help=_('Create the database schema.')) + "create_schema", help=_("Create the database schema.") + ) parser.set_defaults(func=command_object.create_schema) - parser = subparsers.add_parser( - 'upgrade', - help=_('Upgrade the database.')) + parser = subparsers.add_parser("upgrade", help=_("Upgrade the database.")) parser.set_defaults(func=command_object.upgrade) - parser.add_argument('--revision', nargs='?') + parser.add_argument("--revision", nargs="?") - parser = subparsers.add_parser( - 'downgrade', - help=_('Downgrade the database.')) + parser = subparsers.add_parser("downgrade", help=_("Downgrade the database.")) parser.set_defaults(func=command_object.downgrade) - parser.add_argument('--revision', nargs='?') + parser.add_argument("--revision", nargs="?") parser = subparsers.add_parser( - 'stamp', - help=_('Stamp the database with provided revision.')) + "stamp", help=_("Stamp the database with provided revision.") + ) parser.set_defaults(func=command_object.stamp) - parser.add_argument('--revision', nargs='?') + parser.add_argument("--revision", nargs="?") - parser = subparsers.add_parser( - 'revision', - help=_('Creates template for migration')) + parser = subparsers.add_parser("revision", help=_("Creates template for migration")) parser.set_defaults(func=command_object.revision) - parser.add_argument('-m', '--message') - parser.add_argument('--autogenerate', action='store_true') + parser.add_argument("-m", "--message") + parser.add_argument("--autogenerate", action="store_true") parser = subparsers.add_parser( - 'version', - help=_('Print the current version information and exit.')) + "version", help=_("Print the current version information and exit.") + ) parser.set_defaults(func=command_object.version) def main(): - command_opt = cfg.SubCommandOpt('command', - title='Command', - help=_('Available commands'), - handler=add_command_parsers) + command_opt = cfg.SubCommandOpt( + "command", + title="Command", + help=_("Available commands"), + handler=add_command_parsers, + ) CONF.register_cli_opt(command_opt) diff --git a/esi_leap/cmd/manager.py b/esi_leap/cmd/manager.py index 8194dd9c..87a5cc37 100644 --- a/esi_leap/cmd/manager.py +++ b/esi_leap/cmd/manager.py @@ -25,7 +25,5 @@ def main(): esi_leap_service.prepare_service(sys.argv) service.launch( - CONF, - manager_service.ManagerService(), - restart_method='mutate' + CONF, manager_service.ManagerService(), restart_method="mutate" ).wait() diff --git a/esi_leap/common/constants.py b/esi_leap/common/constants.py index 963bd837..0ee1f7c4 100644 --- a/esi_leap/common/constants.py +++ b/esi_leap/common/constants.py @@ -10,4 +10,4 @@ # License for the specific language governing permissions and limitations # under the License. -WITHIN_TIME_FILTER = 'within' +WITHIN_TIME_FILTER = "within" diff --git a/esi_leap/common/exception.py b/esi_leap/common/exception.py index 4dca37f1..61894651 100644 --- a/esi_leap/common/exception.py +++ b/esi_leap/common/exception.py @@ -16,16 +16,16 @@ class ESILeapException(Exception): - msg_fmt = _('An unknown exception occurred.') + msg_fmt = _("An unknown exception occurred.") code = http_client.INTERNAL_SERVER_ERROR safe = False def __init__(self, message=None, **kwargs): self.kwargs = kwargs - if 'code' not in self.kwargs: + if "code" not in self.kwargs: try: - self.kwargs['code'] = self.code + self.kwargs["code"] = self.code except AttributeError: pass @@ -41,140 +41,162 @@ def __init__(self, message=None, **kwargs): class LeaseExceedMaxTimeRange(ESILeapException): code = http_client.FORBIDDEN - msg_fmt = _('Attempted to create lease with an invalid ' - 'time range. The max time range is %(max_time)s days.') + msg_fmt = _( + "Attempted to create lease with an invalid " + "time range. The max time range is %(max_time)s days." + ) class LeaseInvalidPatch(ESILeapException): - msg_fmt = _('Only the end_time field may be updated') + msg_fmt = _("Only the end_time field may be updated") class HTTPForbidden(ESILeapException): code = http_client.FORBIDDEN - msg_fmt = _('Access was denied to %(rule)s.') + msg_fmt = _("Access was denied to %(rule)s.") class HTTPResourceForbidden(ESILeapException): code = http_client.FORBIDDEN - msg_fmt = _('Access was denied to %(resource_type)s %(resource)s.') + msg_fmt = _("Access was denied to %(resource_type)s %(resource)s.") class LeaseNoPermission(ESILeapException): - msg_fmt = _('You do not have permissions on ' - 'lease %(lease_uuid)s.') + msg_fmt = _("You do not have permissions on " "lease %(lease_uuid)s.") class LeaseDuplicateName(ESILeapException): - msg_fmt = _('Duplicate leases with name %(name)s.') + msg_fmt = _("Duplicate leases with name %(name)s.") class LeaseNotActive(ESILeapException): - msg_fmt = _('Lease with name or uuid %(lease_id)s not active.') + msg_fmt = _("Lease with name or uuid %(lease_id)s not active.") class LeaseNotFound(ESILeapException): code = http_client.NOT_FOUND - msg_fmt = _('Lease with name or uuid %(lease_id)s not found.') + msg_fmt = _("Lease with name or uuid %(lease_id)s not found.") class LeaseNoOfferUUID(ESILeapException): - msg_fmt = _('Cannot create lease without parameter offer_uuid.') + msg_fmt = _("Cannot create lease without parameter offer_uuid.") class LeaseNoTimeAvailabilities(ESILeapException): - msg_fmt = _('Lease %(lease_uuid)s has no availabilities at given ' - 'time range %(start_time)s, %(end_time)s.') + msg_fmt = _( + "Lease %(lease_uuid)s has no availabilities at given " + "time range %(start_time)s, %(end_time)s." + ) class OfferNoPermission(ESILeapException): - msg_fmt = _('You do not have permissions on ' - 'offer %(offer_uuid)s.') + msg_fmt = _("You do not have permissions on " "offer %(offer_uuid)s.") class OfferDuplicateName(ESILeapException): - msg_fmt = _('Duplicate offers with name %(name)s.') + msg_fmt = _("Duplicate offers with name %(name)s.") class OfferNotFound(ESILeapException): code = http_client.NOT_FOUND - msg_fmt = _('Offer with name or uuid %(offer_uuid)s not found.') + msg_fmt = _("Offer with name or uuid %(offer_uuid)s not found.") class OfferNoTimeAvailabilities(ESILeapException): - msg_fmt = _('Offer %(offer_uuid)s has no availabilities at given ' - 'time range %(start_time)s, %(end_time)s.') + msg_fmt = _( + "Offer %(offer_uuid)s has no availabilities at given " + "time range %(start_time)s, %(end_time)s." + ) class OfferNotAvailable(ESILeapException): - msg_fmt = _('Offer %(offer_uuid)s does not have status ' - '"available". Got offer status "%(status)s".') + msg_fmt = _( + "Offer %(offer_uuid)s does not have status " + '"available". Got offer status "%(status)s".' + ) class ProjectNoPermission(ESILeapException): - msg_fmt = _('You do not have permissions on project %(project_id)s.') + msg_fmt = _("You do not have permissions on project %(project_id)s.") class ProjectNoSuchName(ESILeapException): - msg_fmt = _('No project named %(name)s.') + msg_fmt = _("No project named %(name)s.") class ResourceTimeConflict(ESILeapException): - msg_fmt = ('Time conflict for %(resource_type)s %(resource_uuid)s.') + msg_fmt = "Time conflict for %(resource_type)s %(resource_uuid)s." class ResourceNoPermission(ESILeapException): - msg_fmt = _('You do not have permissions on ' - '%(resource_type)s %(resource_uuid)s.') + msg_fmt = _( + "You do not have permissions on " "%(resource_type)s %(resource_uuid)s." + ) class ResourceNoPermissionTime(ESILeapException): - msg_fmt = _('You do not have permissions on ' - '%(resource_type)s %(resource_uuid)s for the time range ' - '%(start_time)s - %(end_time)s.') + msg_fmt = _( + "You do not have permissions on " + "%(resource_type)s %(resource_uuid)s for the time range " + "%(start_time)s - %(end_time)s." + ) class ResourceTypeUnknown(ESILeapException): - msg_fmt = _('%(resource_type)s resource type unknown.') + msg_fmt = _("%(resource_type)s resource type unknown.") class InvalidTimeAPICommand(ESILeapException): - msg_fmt = _('Attempted to get %(resource)s resource without providing ' - 'both a valid Start Time and End Time. ' - 'Start Time must be strictly less than End Time. ' - 'Got %(start_time)s, %(end_time)s.') + msg_fmt = _( + "Attempted to get %(resource)s resource without providing " + "both a valid Start Time and End Time. " + "Start Time must be strictly less than End Time. " + "Got %(start_time)s, %(end_time)s." + ) class InvalidAvailabilityAPICommand(ESILeapException): - msg_fmt = _('Attempted to get an offer resource without providing ' - 'both a valid Availability Start Time and Availability ' - 'End Time. Availability Start Time must be strictly ' - 'less than Availability End Time. ' - 'Got %(a_start)s, %(a_end)s.') + msg_fmt = _( + "Attempted to get an offer resource without providing " + "both a valid Availability Start Time and Availability " + "End Time. Availability Start Time must be strictly " + "less than Availability End Time. " + "Got %(a_start)s, %(a_end)s." + ) class InvalidTimeRange(ESILeapException): - msg_fmt = _('Attempted to create %(resource)s resource with an invalid ' - 'Start Time and End Time. Start Time must be strictly less ' - 'than End Time. Got %(start_time)s, %(end_time)s.') + msg_fmt = _( + "Attempted to create %(resource)s resource with an invalid " + "Start Time and End Time. Start Time must be strictly less " + "than End Time. Got %(start_time)s, %(end_time)s." + ) class NodeNotFound(ESILeapException): code = http_client.NOT_FOUND - msg_fmt = _('Encountered an error fetching info for node %(uuid)s ' - '(%(resource_type)s): %(err)s') + msg_fmt = _( + "Encountered an error fetching info for node %(uuid)s " + "(%(resource_type)s): %(err)s" + ) class NotificationPayloadError(ESILeapException): - _msg_fmt = _("Payload not populated when trying to send notification " - "\"%(class_name)s\"") + _msg_fmt = _( + "Payload not populated when trying to send notification " '"%(class_name)s"' + ) class NotificationSchemaObjectError(ESILeapException): - _msg_fmt = _("Expected object %(obj)s when populating notification payload" - " but got object %(source)s") + _msg_fmt = _( + "Expected object %(obj)s when populating notification payload" + " but got object %(source)s" + ) class NotificationSchemaKeyError(ESILeapException): - _msg_fmt = _("Object %(obj)s doesn't have the field \"%(field)s\" " - "required for populating notification schema key " - "\"%(key)s\"") + _msg_fmt = _( + 'Object %(obj)s doesn\'t have the field "%(field)s" ' + "required for populating notification schema key " + '"%(key)s"' + ) diff --git a/esi_leap/common/i18n.py b/esi_leap/common/i18n.py index c033abb7..58df944d 100644 --- a/esi_leap/common/i18n.py +++ b/esi_leap/common/i18n.py @@ -12,7 +12,7 @@ import oslo_i18n as i18n -_translators = i18n.TranslatorFactory(domain='esi-leap') +_translators = i18n.TranslatorFactory(domain="esi-leap") # The primary translation function using the well-known name "_" _ = _translators.primary diff --git a/esi_leap/common/ironic.py b/esi_leap/common/ironic.py index 89f026b2..39d61ba6 100644 --- a/esi_leap/common/ironic.py +++ b/esi_leap/common/ironic.py @@ -24,21 +24,24 @@ def get_ironic_client(context=None): - session = ks_loading.load_session_from_conf_options(CONF, 'ironic') - service_auth = ks_loading.load_auth_from_conf_options(CONF, 'ironic') + session = ks_loading.load_session_from_conf_options(CONF, "ironic") + service_auth = ks_loading.load_auth_from_conf_options(CONF, "ironic") # use user context if provided user_auth = None if context: endpoint = ks_loading.load_adapter_from_conf_options( - CONF, 'ironic', session=session, auth=service_auth).get_endpoint() + CONF, "ironic", session=session, auth=service_auth + ).get_endpoint() user_auth = service_token.ServiceTokenAuthWrapper( user_auth=token_endpoint.Token(endpoint, context.auth_token), - service_auth=service_auth) + service_auth=service_auth, + ) sess = ks_loading.load_session_from_conf_options( - CONF, 'ironic', auth=user_auth or service_auth) + CONF, "ironic", auth=user_auth or service_auth + ) - kwargs = {'os_ironic_api_version': '1.65'} + kwargs = {"os_ironic_api_version": "1.65"} cli = ironic_client.get_client(1, session=sess, **kwargs) return cli @@ -58,6 +61,6 @@ def get_node(node_uuid, node_list=None): def get_condensed_properties(properties): cp = properties.copy() - cp.pop('lease_uuid', None) - cp.pop('capabilities', None) + cp.pop("lease_uuid", None) + cp.pop("capabilities", None) return cp diff --git a/esi_leap/common/keystone.py b/esi_leap/common/keystone.py index 223b80ca..464b95c4 100644 --- a/esi_leap/common/keystone.py +++ b/esi_leap/common/keystone.py @@ -28,9 +28,8 @@ def get_keystone_client(): if _cached_keystone_client is not None: return _cached_keystone_client - auth_plugin = ks_loading.load_auth_from_conf_options(CONF, 'keystone') - sess = ks_loading.load_session_from_conf_options(CONF, 'keystone', - auth=auth_plugin) + auth_plugin = ks_loading.load_auth_from_conf_options(CONF, "keystone") + sess = ks_loading.load_session_from_conf_options(CONF, "keystone", auth=auth_plugin) cli = keystone_client.Client(session=sess) _cached_keystone_client = cli @@ -67,9 +66,9 @@ def get_project_name(project_id, project_list=None): if project_list is None: project = get_keystone_client().projects.get(project_id) else: - project = next((p for p in project_list - if getattr(p, 'id') == project_id), - None) - return project.name if project else '' + project = next( + (p for p in project_list if getattr(p, "id") == project_id), None + ) + return project.name if project else "" else: - return '' + return "" diff --git a/esi_leap/common/notification_utils.py b/esi_leap/common/notification_utils.py index 3806abf8..31daabe5 100644 --- a/esi_leap/common/notification_utils.py +++ b/esi_leap/common/notification_utils.py @@ -27,8 +27,7 @@ CONF = cfg.CONF -def _emit_notification(context, obj, action, level, status, - crud_notify_obj, **kwargs): +def _emit_notification(context, obj, action, level, status, crud_notify_obj, **kwargs): """Helper for emitting notifications. :param context: request context. @@ -56,45 +55,58 @@ def _emit_notification(context, obj, action, level, status, payload_name = payload_method.__name__ finally: # Prepare our exception message just in case - exception_values = {"resource": resource, - "uuid": obj.uuid, - "action": action, - "status": status, - "level": level, - "notification_method": notification_name, - "payload_method": payload_name} - exception_message = (_("Failed to send esi_leap.%(resource)s." - "%(action)s.%(status)s notification for " - "%(resource)s %(uuid)s with level " - "%(level)s, notification method " - "%(notification_method)s, payload method " - "%(payload_method)s, error %(error)s")) + exception_values = { + "resource": resource, + "uuid": obj.uuid, + "action": action, + "status": status, + "level": level, + "notification_method": notification_name, + "payload_method": payload_name, + } + exception_message = _( + "Failed to send esi_leap.%(resource)s." + "%(action)s.%(status)s notification for " + "%(resource)s %(uuid)s with level " + "%(level)s, notification method " + "%(notification_method)s, payload method " + "%(payload_method)s, error %(error)s" + ) payload = payload_method(obj, **extra_args) event_type = "esi_leap.%s.%s.%s" % (resource, action, status) notification_method( publisher=notification.NotificationPublisher( - service='esi-leap-manager', host=CONF.host), + service="esi-leap-manager", host=CONF.host + ), event_type=notification.EventType( - object=resource, action=action, status=status), + object=resource, action=action, status=status + ), level=level, - payload=payload).emit(context) - LOG.info("Emit esi_leap notification: host is %s " - "event is %s ," - "level is %s ," - "notification method is %s", - CONF.host, event_type, - level, notification_method) - except (exception.NotificationSchemaObjectError, - exception.NotificationSchemaKeyError, - exception.NotificationPayloadError, - oslo_msg_exc.MessageDeliveryFailure, - oslo_vo_exc.VersionedObjectsException) as e: - exception_values['error'] = e + payload=payload, + ).emit(context) + LOG.info( + "Emit esi_leap notification: host is %s " + "event is %s ," + "level is %s ," + "notification method is %s", + CONF.host, + event_type, + level, + notification_method, + ) + except ( + exception.NotificationSchemaObjectError, + exception.NotificationSchemaKeyError, + exception.NotificationPayloadError, + oslo_msg_exc.MessageDeliveryFailure, + oslo_vo_exc.VersionedObjectsException, + ) as e: + exception_values["error"] = e LOG.warning(exception_message, exception_values) LOG.exception(e.msg_fmt) except Exception as e: - exception_values['error'] = e + exception_values["error"] = e LOG.exception(exception_message, exception_values) @@ -106,11 +118,15 @@ def emit_start_notification(context, obj, action, crud_notify_obj, **kwargs): :param action: Action string to go in the EventType. :param kwargs: kwargs to use when creating the notification payload. """ - _emit_notification(context, obj, action, - fields.NotificationLevel.INFO, - fields.NotificationStatus.START, - crud_notify_obj, - **kwargs) + _emit_notification( + context, + obj, + action, + fields.NotificationLevel.INFO, + fields.NotificationStatus.START, + crud_notify_obj, + **kwargs, + ) @contextlib.contextmanager @@ -126,11 +142,15 @@ def handle_error_notification(context, obj, action, crud_notify_obj, **kwargs): yield except Exception: with excutils.save_and_reraise_exception(): - _emit_notification(context, obj, action, - fields.NotificationLevel.ERROR, - fields.NotificationStatus.ERROR, - crud_notify_obj, - **kwargs) + _emit_notification( + context, + obj, + action, + fields.NotificationLevel.ERROR, + fields.NotificationStatus.ERROR, + crud_notify_obj, + **kwargs, + ) def emit_end_notification(context, obj, action, crud_notify_obj, **kwargs): @@ -141,8 +161,12 @@ def emit_end_notification(context, obj, action, crud_notify_obj, **kwargs): :param action: Action string to go in the EventType. :param kwargs: kwargs to use when creating the notification payload. """ - _emit_notification(context, obj, action, - fields.NotificationLevel.INFO, - fields.NotificationStatus.END, - crud_notify_obj, - **kwargs) + _emit_notification( + context, + obj, + action, + fields.NotificationLevel.INFO, + fields.NotificationStatus.END, + crud_notify_obj, + **kwargs, + ) diff --git a/esi_leap/common/policy.py b/esi_leap/common/policy.py index 47a5a84a..a2f6b978 100644 --- a/esi_leap/common/policy.py +++ b/esi_leap/common/policy.py @@ -20,96 +20,120 @@ _ENFORCER = None default_policies = [ - policy.RuleDefault('is_admin', - 'role:admin or role:esi_leap_admin', - description='Full read/write API access'), - policy.RuleDefault('is_owner', - 'role:owner or role:esi_leap_owner', - description='Owner API access'), - policy.RuleDefault('is_lessee', - 'role:lessee or role:esi_leap_lessee', - description='Lessee API access'), - policy.RuleDefault('is_offer_owner', - 'project_id:%(offer.project_id)s', - description='Owner of offer'), - policy.RuleDefault('is_lease_owner', - 'project_id:%(lease.owner_id)s', - description='Owner of lease'), - policy.RuleDefault('is_lease_lessee', - 'project_id:%(lease.project_id)s', - description='Lessee of lease'), + policy.RuleDefault( + "is_admin", + "role:admin or role:esi_leap_admin", + description="Full read/write API access", + ), + policy.RuleDefault( + "is_owner", "role:owner or role:esi_leap_owner", description="Owner API access" + ), + policy.RuleDefault( + "is_lessee", + "role:lessee or role:esi_leap_lessee", + description="Lessee API access", + ), + policy.RuleDefault( + "is_offer_owner", + "project_id:%(offer.project_id)s", + description="Owner of offer", + ), + policy.RuleDefault( + "is_lease_owner", "project_id:%(lease.owner_id)s", description="Owner of lease" + ), + policy.RuleDefault( + "is_lease_lessee", + "project_id:%(lease.project_id)s", + description="Lessee of lease", + ), ] lease_policies = [ policy.DocumentedRuleDefault( - 'esi_leap:lease:lease_admin', - 'rule:is_admin', - 'Complete permissions over leases', - [{'path': '/leases', 'method': 'POST'}, - {'path': '/leases', 'method': 'GET'}, - {'path': '/leases/{lease_ident}', 'method': 'GET'}, - {'path': '/leases/{lease_ident}', 'method': 'DELETE'}]), + "esi_leap:lease:lease_admin", + "rule:is_admin", + "Complete permissions over leases", + [ + {"path": "/leases", "method": "POST"}, + {"path": "/leases", "method": "GET"}, + {"path": "/leases/{lease_ident}", "method": "GET"}, + {"path": "/leases/{lease_ident}", "method": "DELETE"}, + ], + ), policy.DocumentedRuleDefault( - 'esi_leap:lease:create', - 'rule:is_admin or rule:is_owner', - 'Create lease', - [{'path': '/leases', 'method': 'POST'}]), + "esi_leap:lease:create", + "rule:is_admin or rule:is_owner", + "Create lease", + [{"path": "/leases", "method": "POST"}], + ), policy.DocumentedRuleDefault( - 'esi_leap:lease:update', - 'rule:is_admin', - 'Update lease', - [{'path': '/leases/{lease_ident}', 'method': 'PATCH'}]), + "esi_leap:lease:update", + "rule:is_admin", + "Update lease", + [{"path": "/leases/{lease_ident}", "method": "PATCH"}], + ), policy.DocumentedRuleDefault( - 'esi_leap:lease:get', - 'rule:is_admin or rule:is_lease_owner or rule:is_lease_lessee', - 'Retrieve a single lease', - [{'path': '/leases/{lease_ident}', 'method': 'GET'}]), + "esi_leap:lease:get", + "rule:is_admin or rule:is_lease_owner or rule:is_lease_lessee", + "Retrieve a single lease", + [{"path": "/leases/{lease_ident}", "method": "GET"}], + ), policy.DocumentedRuleDefault( - 'esi_leap:lease:get_all', - 'rule:is_admin or rule:is_owner or rule:is_lessee', - 'Retrieve all leases owned by project_id', - [{'path': '/leases', 'method': 'GET'}]), + "esi_leap:lease:get_all", + "rule:is_admin or rule:is_owner or rule:is_lessee", + "Retrieve all leases owned by project_id", + [{"path": "/leases", "method": "GET"}], + ), policy.DocumentedRuleDefault( - 'esi_leap:lease:delete', - 'rule:is_admin or rule:is_lease_owner or rule:is_lease_lessee', - 'Delete lease', - [{'path': '/leases/{lease_ident}', 'method': 'DELETE'}]), + "esi_leap:lease:delete", + "rule:is_admin or rule:is_lease_owner or rule:is_lease_lessee", + "Delete lease", + [{"path": "/leases/{lease_ident}", "method": "DELETE"}], + ), ] offer_policies = [ policy.DocumentedRuleDefault( - 'esi_leap:offer:offer_admin', - 'rule:is_admin', - 'Complete permissions over offers', - [{'path': '/offers', 'method': 'POST'}, - {'path': '/offers', 'method': 'GET'}, - {'path': '/offers/{offer_ident}', 'method': 'GET'}, - {'path': '/offers/{offer_ident}', 'method': 'DELETE'}]), + "esi_leap:offer:offer_admin", + "rule:is_admin", + "Complete permissions over offers", + [ + {"path": "/offers", "method": "POST"}, + {"path": "/offers", "method": "GET"}, + {"path": "/offers/{offer_ident}", "method": "GET"}, + {"path": "/offers/{offer_ident}", "method": "DELETE"}, + ], + ), policy.DocumentedRuleDefault( - 'esi_leap:offer:create', - 'rule:is_admin or rule:is_owner', - 'Create offer', - [{'path': '/offers', 'method': 'POST'}]), + "esi_leap:offer:create", + "rule:is_admin or rule:is_owner", + "Create offer", + [{"path": "/offers", "method": "POST"}], + ), policy.DocumentedRuleDefault( - 'esi_leap:offer:get', - 'rule:is_admin or rule:is_owner or rule:is_lessee', - 'Retrieve a single offer', - [{'path': '/offers/{offer_ident}', 'method': 'GET'}]), + "esi_leap:offer:get", + "rule:is_admin or rule:is_owner or rule:is_lessee", + "Retrieve a single offer", + [{"path": "/offers/{offer_ident}", "method": "GET"}], + ), policy.DocumentedRuleDefault( - 'esi_leap:offer:get_all', - 'rule:is_admin or rule:is_owner or rule:is_lessee', - 'Retrieve multiple offers', - [{'path': '/offers', 'method': 'GET'}]), + "esi_leap:offer:get_all", + "rule:is_admin or rule:is_owner or rule:is_lessee", + "Retrieve multiple offers", + [{"path": "/offers", "method": "GET"}], + ), policy.DocumentedRuleDefault( - 'esi_leap:offer:delete', - 'rule:is_admin or rule:is_offer_owner', - 'Delete offer', - [{'path': '/offers/{offer_ident}', 'method': 'DELETE'}]), + "esi_leap:offer:delete", + "rule:is_admin or rule:is_offer_owner", + "Delete offer", + [{"path": "/offers/{offer_ident}", "method": "DELETE"}], + ), policy.DocumentedRuleDefault( - 'esi_leap:offer:claim', - 'rule:is_admin or rule:is_owner or rule:is_lessee', - 'Claim an offer', - [{'path': '/offers/{offer_ident}/claim', 'method': 'POST'}]), + "esi_leap:offer:claim", + "rule:is_admin or rule:is_owner or rule:is_lessee", + "Claim an offer", + [{"path": "/offers/{offer_ident}/claim", "method": "POST"}], + ), ] @@ -123,7 +147,7 @@ def list_rules(): def get_enforcer(): - CONF([], project='esi-leap') + CONF([], project="esi-leap") global _ENFORCER if not _ENFORCER: _ENFORCER = policy.Enforcer(CONF) @@ -135,5 +159,4 @@ def authorize(rule, target, creds, *args, **kwargs): if not CONF.pecan.auth_enable: return True - return get_enforcer().authorize( - rule, target, creds, do_raise=True, *args, **kwargs) + return get_enforcer().authorize(rule, target, creds, do_raise=True, *args, **kwargs) diff --git a/esi_leap/common/rpc.py b/esi_leap/common/rpc.py index 422c3f6a..ddd41be3 100644 --- a/esi_leap/common/rpc.py +++ b/esi_leap/common/rpc.py @@ -29,21 +29,21 @@ def init(conf): global NOTIFICATION_TRANSPORT global VERSIONED_NOTIFIER NOTIFICATION_TRANSPORT = messaging.get_notification_transport( - conf, - allowed_remote_exmods=ALLOWED_EXMODS) + conf, allowed_remote_exmods=ALLOWED_EXMODS + ) serializer = RequestContextSerializer(messaging.JsonPayloadSerializer()) if conf.notification.notification_level is None: - - VERSIONED_NOTIFIER = messaging.Notifier(NOTIFICATION_TRANSPORT, - serializer=serializer, - driver='noop') + VERSIONED_NOTIFIER = messaging.Notifier( + NOTIFICATION_TRANSPORT, serializer=serializer, driver="noop" + ) else: VERSIONED_NOTIFIER = messaging.Notifier( NOTIFICATION_TRANSPORT, serializer=serializer, - topics=CONF.notification.versioned_notifications_topics) + topics=CONF.notification.versioned_notifications_topics, + ) def cleanup(): @@ -58,7 +58,6 @@ def cleanup(): # RequestContextSerializer borrowed from Ironic class RequestContextSerializer(messaging.Serializer): - def __init__(self, base): self._base = base @@ -79,7 +78,7 @@ def serialize_context(self, context): trace_info = { "hmac_key": prof.hmac_key, "base_id": prof.get_base_id(), - "parent_id": prof.get_id() + "parent_id": prof.get_id(), } _context.update({"trace_info": trace_info}) return _context diff --git a/esi_leap/common/service.py b/esi_leap/common/service.py index c5eaf44e..19b227be 100644 --- a/esi_leap/common/service.py +++ b/esi_leap/common/service.py @@ -25,15 +25,17 @@ def prepare_service(argv=None, default_config_files=None): argv = [] if argv is None else argv log.register_options(CONF) - CONF(argv[1:], - project='esi-leap', - version=version.version_info.release_string(), - default_config_files=default_config_files) + CONF( + argv[1:], + project="esi-leap", + version=version.version_info.release_string(), + default_config_files=default_config_files, + ) db_options.set_defaults(CONF) - log.setup(CONF, 'esi-leap') + log.setup(CONF, "esi-leap") rpc.init(CONF) objects.register_all() def process_launcher(): - return service.ProcessLauncher(CONF, restart_method='mutate') + return service.ProcessLauncher(CONF, restart_method="mutate") diff --git a/esi_leap/common/statuses.py b/esi_leap/common/statuses.py index 4d346372..0608d037 100644 --- a/esi_leap/common/statuses.py +++ b/esi_leap/common/statuses.py @@ -10,15 +10,15 @@ # License for the specific language governing permissions and limitations # under the License. -ACTIVE = 'active' -AVAILABLE = 'available' -CREATED = 'created' -DELETED = 'deleted' -ERROR = 'error' -EXPIRED = 'expired' -WAIT_CANCEL = 'wait cancel' -WAIT_EXPIRE = 'wait expire' -WAIT_FULFILL = 'wait fulfill' +ACTIVE = "active" +AVAILABLE = "available" +CREATED = "created" +DELETED = "deleted" +ERROR = "error" +EXPIRED = "expired" +WAIT_CANCEL = "wait cancel" +WAIT_EXPIRE = "wait expire" +WAIT_FULFILL = "wait fulfill" OFFER_CAN_DELETE = [AVAILABLE, ERROR] LEASE_CAN_DELETE = [ACTIVE, CREATED, ERROR, WAIT_FULFILL] diff --git a/esi_leap/common/utils.py b/esi_leap/common/utils.py index 14557351..d733735e 100644 --- a/esi_leap/common/utils.py +++ b/esi_leap/common/utils.py @@ -12,9 +12,9 @@ from oslo_concurrency import lockutils -_prefix = 'esileap' +_prefix = "esileap" lock = lockutils.lock_with_prefix(_prefix) def get_resource_lock_name(resource_type, resource_uuid): - return resource_type + '-' + resource_uuid + return resource_type + "-" + resource_uuid diff --git a/esi_leap/conf/__init__.py b/esi_leap/conf/__init__.py index e4e32405..d1a8660e 100644 --- a/esi_leap/conf/__init__.py +++ b/esi_leap/conf/__init__.py @@ -23,7 +23,7 @@ CONF = cfg.CONF -CONF.register_group(cfg.OptGroup(name='database')) +CONF.register_group(cfg.OptGroup(name="database")) api.register_opts(CONF) dummy_node.register_opts(CONF) ironic.register_opts(CONF) diff --git a/esi_leap/conf/api.py b/esi_leap/conf/api.py index 067af300..2cfe080f 100644 --- a/esi_leap/conf/api.py +++ b/esi_leap/conf/api.py @@ -14,19 +14,19 @@ opts = [ - cfg.HostAddressOpt('host_ip', default='0.0.0.0'), - cfg.PortOpt('port', default=7777), - cfg.IntOpt('max_limit', default=1000), - cfg.StrOpt('public_endpoint'), - cfg.IntOpt('api_workers'), - cfg.BoolOpt('enable_ssl_api', default=False), - cfg.StrOpt('default_resource_type', default='ironic_node'), - cfg.IntOpt('max_lease_time', default=21), - cfg.IntOpt('default_lease_time', default=7), + cfg.HostAddressOpt("host_ip", default="0.0.0.0"), + cfg.PortOpt("port", default=7777), + cfg.IntOpt("max_limit", default=1000), + cfg.StrOpt("public_endpoint"), + cfg.IntOpt("api_workers"), + cfg.BoolOpt("enable_ssl_api", default=False), + cfg.StrOpt("default_resource_type", default="ironic_node"), + cfg.IntOpt("max_lease_time", default=21), + cfg.IntOpt("default_lease_time", default=7), ] -api_group = cfg.OptGroup('api', title='API Options') +api_group = cfg.OptGroup("api", title="API Options") def register_opts(conf): diff --git a/esi_leap/conf/dummy_node.py b/esi_leap/conf/dummy_node.py index 690ad79a..f624bcdd 100644 --- a/esi_leap/conf/dummy_node.py +++ b/esi_leap/conf/dummy_node.py @@ -13,10 +13,10 @@ from oslo_config import cfg -opts = [cfg.StrOpt('dummy_node_dir', default='/tmp/nodes')] +opts = [cfg.StrOpt("dummy_node_dir", default="/tmp/nodes")] -dummy_node_group = cfg.OptGroup('dummy_node', title='Dummy Node Options') +dummy_node_group = cfg.OptGroup("dummy_node", title="Dummy Node Options") def register_opts(conf): diff --git a/esi_leap/conf/ironic.py b/esi_leap/conf/ironic.py index 44ee6d06..1b1e2afa 100644 --- a/esi_leap/conf/ironic.py +++ b/esi_leap/conf/ironic.py @@ -17,7 +17,7 @@ opts = [] -ironic_group = cfg.OptGroup('ironic', title='Ironic Options') +ironic_group = cfg.OptGroup("ironic", title="Ironic Options") def register_opts(conf): @@ -25,9 +25,8 @@ def register_opts(conf): loading.register_session_conf_options(conf, ironic_group) loading.register_auth_conf_options(conf, ironic_group) loading.register_adapter_conf_options(conf, ironic_group) - conf.set_default('valid_interfaces', ['internal', 'public'], - group=ironic_group) - conf.set_default('service_type', 'baremetal', group=ironic_group) + conf.set_default("valid_interfaces", ["internal", "public"], group=ironic_group) + conf.set_default("service_type", "baremetal", group=ironic_group) def list_opts(): @@ -42,17 +41,17 @@ def add_options(opts, opts_to_add): opts_copy = copy.deepcopy(opts) opts_copy.insert(0, loading.get_auth_common_conf_options()[0]) - plugins = ['password', 'v2password', 'v3password'] + plugins = ["password", "v2password", "v3password"] for name in plugins: plugin = loading.get_plugin_loader(name) add_options(opts_copy, loading.get_auth_plugin_conf_options(plugin)) add_options(opts_copy, loading.get_session_conf_options()) - adapter_opts = loading.get_adapter_conf_options( - include_deprecated=False) + adapter_opts = loading.get_adapter_conf_options(include_deprecated=False) # adding defaults for valid interfaces - cfg.set_defaults(adapter_opts, service_type='baremetal', - valid_interfaces=['internal', 'public']) + cfg.set_defaults( + adapter_opts, service_type="baremetal", valid_interfaces=["internal", "public"] + ) add_options(opts_copy, adapter_opts) opts_copy.sort(key=lambda x: x.name) return opts_copy diff --git a/esi_leap/conf/keystone.py b/esi_leap/conf/keystone.py index 110c40fd..5f599d91 100644 --- a/esi_leap/conf/keystone.py +++ b/esi_leap/conf/keystone.py @@ -17,7 +17,7 @@ opts = [] -keystone_group = cfg.OptGroup('keystone', title='Keystone Options') +keystone_group = cfg.OptGroup("keystone", title="Keystone Options") def register_opts(conf): @@ -25,9 +25,8 @@ def register_opts(conf): loading.register_session_conf_options(conf, keystone_group) loading.register_auth_conf_options(conf, keystone_group) loading.register_adapter_conf_options(conf, keystone_group) - conf.set_default('valid_interfaces', ['internal', 'public'], - group=keystone_group) - conf.set_default('service_type', 'identity', group=keystone_group) + conf.set_default("valid_interfaces", ["internal", "public"], group=keystone_group) + conf.set_default("service_type", "identity", group=keystone_group) def list_opts(): @@ -42,17 +41,17 @@ def add_options(opts, opts_to_add): opts_copy = copy.deepcopy(opts) opts_copy.insert(0, loading.get_auth_common_conf_options()[0]) - plugins = ['password', 'v2password', 'v3password'] + plugins = ["password", "v2password", "v3password"] for name in plugins: plugin = loading.get_plugin_loader(name) add_options(opts_copy, loading.get_auth_plugin_conf_options(plugin)) add_options(opts_copy, loading.get_session_conf_options()) - adapter_opts = loading.get_adapter_conf_options( - include_deprecated=False) + adapter_opts = loading.get_adapter_conf_options(include_deprecated=False) # adding defaults for valid interfaces - cfg.set_defaults(adapter_opts, service_type='identity', - valid_interfaces=['internal', 'public']) + cfg.set_defaults( + adapter_opts, service_type="identity", valid_interfaces=["internal", "public"] + ) add_options(opts_copy, adapter_opts) opts_copy.sort(key=lambda x: x.name) return opts_copy diff --git a/esi_leap/conf/netconf.py b/esi_leap/conf/netconf.py index 5b70951f..76596756 100644 --- a/esi_leap/conf/netconf.py +++ b/esi_leap/conf/netconf.py @@ -15,7 +15,7 @@ from oslo_config import cfg -opts = [cfg.StrOpt('host', default=socket.gethostname())] +opts = [cfg.StrOpt("host", default=socket.gethostname())] def register_opts(conf): diff --git a/esi_leap/conf/notification.py b/esi_leap/conf/notification.py index ce1481e4..cda1d4d7 100644 --- a/esi_leap/conf/notification.py +++ b/esi_leap/conf/notification.py @@ -15,26 +15,35 @@ # borrowed from Ironic opts = [ - cfg.StrOpt('notification_level', - choices=[('debug', _('"debug" level')), - ('info', _('"info" level')), - ('warning', _('"warning" level')), - ('error', _('"error" level')), - ('critical', _('"critical" level'))], - help=_('Specifies the minimum level for which to send ' - 'notifications. If not set, no notifications will ' - 'be sent.')), + cfg.StrOpt( + "notification_level", + choices=[ + ("debug", _('"debug" level')), + ("info", _('"info" level')), + ("warning", _('"warning" level')), + ("error", _('"error" level')), + ("critical", _('"critical" level')), + ], + help=_( + "Specifies the minimum level for which to send " + "notifications. If not set, no notifications will " + "be sent." + ), + ), cfg.ListOpt( - 'versioned_notifications_topics', - default=['esi_leap_versioned_notifications'], - help=_('Specifies the topics for ' - 'the versioned notifications issued by esi-leap.')), + "versioned_notifications_topics", + default=["esi_leap_versioned_notifications"], + help=_( + "Specifies the topics for " + "the versioned notifications issued by esi-leap." + ), + ), ] -notification_group = cfg.OptGroup('notification', title='Notification Options') +notification_group = cfg.OptGroup("notification", title="Notification Options") def register_opts(conf): conf.register_opts(opts, group=notification_group) - conf.set_default('notification_level', 'info', group=notification_group) + conf.set_default("notification_level", "info", group=notification_group) diff --git a/esi_leap/conf/opts.py b/esi_leap/conf/opts.py index 4c109c7f..cc5a715b 100644 --- a/esi_leap/conf/opts.py +++ b/esi_leap/conf/opts.py @@ -13,13 +13,13 @@ import esi_leap.conf _opts = [ - ('DEFAULT', esi_leap.conf.netconf.opts), - ('api', esi_leap.conf.api.opts), - ('dummy_node', esi_leap.conf.dummy_node.opts), - ('ironic', esi_leap.conf.ironic.list_opts()), - ('keystone', esi_leap.conf.keystone.list_opts()), - ('pecan', esi_leap.conf.pecan.opts), - ('notification', esi_leap.conf.notification.opts), + ("DEFAULT", esi_leap.conf.netconf.opts), + ("api", esi_leap.conf.api.opts), + ("dummy_node", esi_leap.conf.dummy_node.opts), + ("ironic", esi_leap.conf.ironic.list_opts()), + ("keystone", esi_leap.conf.keystone.list_opts()), + ("pecan", esi_leap.conf.pecan.opts), + ("notification", esi_leap.conf.notification.opts), ] diff --git a/esi_leap/conf/pecan.py b/esi_leap/conf/pecan.py index d4e87615..2ed6dbda 100644 --- a/esi_leap/conf/pecan.py +++ b/esi_leap/conf/pecan.py @@ -14,14 +14,13 @@ opts = [ - cfg.StrOpt('root', - default='esi_leap.api.controllers.root.RootController'), - cfg.ListOpt('modules', default=['esi_leap.api']), - cfg.BoolOpt('debug', default=False), - cfg.BoolOpt('auth_enable', default=True) + cfg.StrOpt("root", default="esi_leap.api.controllers.root.RootController"), + cfg.ListOpt("modules", default=["esi_leap.api"]), + cfg.BoolOpt("debug", default=False), + cfg.BoolOpt("auth_enable", default=True), ] -pecan_group = cfg.OptGroup('pecan', title='Pecan Options') +pecan_group = cfg.OptGroup("pecan", title="Pecan Options") def register_opts(conf): diff --git a/esi_leap/db/api.py b/esi_leap/db/api.py index d0734476..d988ccea 100644 --- a/esi_leap/db/api.py +++ b/esi_leap/db/api.py @@ -16,12 +16,10 @@ _BACKEND_MAPPING = { - 'sqlalchemy': 'esi_leap.db.sqlalchemy.api', + "sqlalchemy": "esi_leap.db.sqlalchemy.api", } -IMPL = db_api.DBAPI.from_config(cfg.CONF, - backend_mapping=_BACKEND_MAPPING, - lazy=True) +IMPL = db_api.DBAPI.from_config(cfg.CONF, backend_mapping=_BACKEND_MAPPING, lazy=True) LOG = logging.getLogger(__name__) @@ -93,13 +91,11 @@ def offer_get_conflict_times(offer_ref): def offer_get_next_lease_start_time(offer_uuid, start): - return IMPL.offer_get_next_lease_start_time( - offer_uuid, start) + return IMPL.offer_get_next_lease_start_time(offer_uuid, start) def offer_verify_availability(offer_ref, start, end): - return IMPL.offer_verify_availability( - offer_ref, start, end) + return IMPL.offer_verify_availability(offer_ref, start, end) def offer_create(values): @@ -143,22 +139,30 @@ def lease_destroy(lease_uuid): def lease_verify_child_availability(lease_ref, start, end): - return IMPL.lease_verify_child_availability( - lease_ref, start, end) + return IMPL.lease_verify_child_availability(lease_ref, start, end) # Resource object def resource_verify_availability(r_type, r_uuid, start, end): - return IMPL.resource_verify_availability( - r_type, r_uuid, start, end) + return IMPL.resource_verify_availability(r_type, r_uuid, start, end) -def resource_check_admin(resource_type, resource_uuid, - start_time, end_time, - default_admin_project_id, project_id): +def resource_check_admin( + resource_type, + resource_uuid, + start_time, + end_time, + default_admin_project_id, + project_id, +): return IMPL.resource_check_admin( - resource_type, resource_uuid, start_time, end_time, - default_admin_project_id, project_id) + resource_type, + resource_uuid, + start_time, + end_time, + default_admin_project_id, + project_id, + ) # Event diff --git a/esi_leap/db/migration.py b/esi_leap/db/migration.py index e0cf0dfd..ae5621c0 100644 --- a/esi_leap/db/migration.py +++ b/esi_leap/db/migration.py @@ -22,9 +22,10 @@ def get_backend(): global _IMPL if not _IMPL: - cfg.CONF.import_opt('backend', 'oslo_db.options', group='database') - _IMPL = driver.DriverManager('esi_leap.database.migration_backend', - cfg.CONF.database.backend).driver + cfg.CONF.import_opt("backend", "oslo_db.options", group="database") + _IMPL = driver.DriverManager( + "esi_leap.database.migration_backend", cfg.CONF.database.backend + ).driver return _IMPL diff --git a/esi_leap/db/sqlalchemy/alembic/env.py b/esi_leap/db/sqlalchemy/alembic/env.py index 7b9b5f89..0ee86c21 100644 --- a/esi_leap/db/sqlalchemy/alembic/env.py +++ b/esi_leap/db/sqlalchemy/alembic/env.py @@ -51,9 +51,7 @@ def run_migrations_online(): """ engine = enginefacade.writer.get_engine() with engine.connect() as connection: - context.configure( - connection=connection, target_metadata=target_metadata - ) + context.configure(connection=connection, target_metadata=target_metadata) with context.begin_transaction(): context.run_migrations() diff --git a/esi_leap/db/sqlalchemy/alembic/versions/a1ea63fec697_create_events_table.py b/esi_leap/db/sqlalchemy/alembic/versions/a1ea63fec697_create_events_table.py index 7cd62278..ff9b748f 100644 --- a/esi_leap/db/sqlalchemy/alembic/versions/a1ea63fec697_create_events_table.py +++ b/esi_leap/db/sqlalchemy/alembic/versions/a1ea63fec697_create_events_table.py @@ -17,12 +17,13 @@ Create Date: 2023-06-26 14:22:34.822066 """ + from alembic import op import sqlalchemy as sa # revision identifiers, used by Alembic. -revision = 'a1ea63fec697' +revision = "a1ea63fec697" down_revision = None branch_labels = None depends_on = None @@ -30,30 +31,27 @@ def upgrade(): op.create_table( - 'events', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('event_type', sa.String(length=255), nullable=False), - sa.Column('event_time', sa.DateTime(), nullable=False), - sa.Column('object_type', sa.String(length=255), nullable=True), - sa.Column('object_uuid', sa.String(length=36), nullable=True), - sa.Column('resource_type', sa.String(length=255), nullable=True), - sa.Column('resource_uuid', sa.String(length=36), nullable=True), - sa.Column('lessee_id', sa.String(length=36), nullable=True), - sa.Column('owner_id', sa.String(length=36), nullable=True), - sa.Column('created_at', sa.DateTime(), nullable=True), - sa.Column('updated_at', sa.DateTime(), nullable=True), - sa.PrimaryKeyConstraint('id'), + "events", + sa.Column("id", sa.Integer(), nullable=False), + sa.Column("event_type", sa.String(length=255), nullable=False), + sa.Column("event_time", sa.DateTime(), nullable=False), + sa.Column("object_type", sa.String(length=255), nullable=True), + sa.Column("object_uuid", sa.String(length=36), nullable=True), + sa.Column("resource_type", sa.String(length=255), nullable=True), + sa.Column("resource_uuid", sa.String(length=36), nullable=True), + sa.Column("lessee_id", sa.String(length=36), nullable=True), + sa.Column("owner_id", sa.String(length=36), nullable=True), + sa.Column("created_at", sa.DateTime(), nullable=True), + sa.Column("updated_at", sa.DateTime(), nullable=True), + sa.PrimaryKeyConstraint("id"), ) - op.create_index('event_type_idx', 'events', ['event_type'], - unique=False) - op.create_index('event_lessee_id_idx', 'events', ['lessee_id'], - unique=False) - op.create_index('event_owner_id_idx', 'events', ['owner_id'], - unique=False) - op.create_index('event_resource_idx', 'events', - ['resource_type', 'resource_uuid'], - unique=False) + op.create_index("event_type_idx", "events", ["event_type"], unique=False) + op.create_index("event_lessee_id_idx", "events", ["lessee_id"], unique=False) + op.create_index("event_owner_id_idx", "events", ["owner_id"], unique=False) + op.create_index( + "event_resource_idx", "events", ["resource_type", "resource_uuid"], unique=False + ) def downgrade(): diff --git a/esi_leap/db/sqlalchemy/api.py b/esi_leap/db/sqlalchemy/api.py index dca88c90..dbf57504 100644 --- a/esi_leap/db/sqlalchemy/api.py +++ b/esi_leap/db/sqlalchemy/api.py @@ -112,16 +112,15 @@ def offer_get_by_name(name): def offer_get_all(filters): - query = model_query(models.Offer) - lessee_id = filters.pop('lessee_id', None) - start = filters.pop('start_time', None) - end = filters.pop('end_time', None) - time_filter_type = filters.pop('time_filter_type', None) - a_start = filters.pop('available_start_time', None) - status = filters.pop('status', None) - a_end = filters.pop('available_end_time', None) + lessee_id = filters.pop("lessee_id", None) + start = filters.pop("start_time", None) + end = filters.pop("end_time", None) + time_filter_type = filters.pop("time_filter_type", None) + a_start = filters.pop("available_start_time", None) + status = filters.pop("status", None) + a_end = filters.pop("available_end_time", None) query = query.filter_by(**filters) @@ -130,20 +129,24 @@ def offer_get_all(filters): if lessee_id: lessee_id_list = keystone.get_parent_project_id_tree(lessee_id) - query = query.filter(or_(models.Offer.project_id == lessee_id, - models.Offer.lessee_id.__eq__(None), - models.Offer.lessee_id.in_(lessee_id_list))) + query = query.filter( + or_( + models.Offer.project_id == lessee_id, + models.Offer.lessee_id.__eq__(None), + models.Offer.lessee_id.in_(lessee_id_list), + ) + ) if start and end: if time_filter_type == constants.WITHIN_TIME_FILTER: - query = query.filter(((start <= models.Offer.start_time) & - (end >= models.Offer.start_time)) | - - ((start <= models.Offer.end_time) & - (end >= models.Offer.end_time))) + query = query.filter( + ((start <= models.Offer.start_time) & (end >= models.Offer.start_time)) + | ((start <= models.Offer.end_time) & (end >= models.Offer.end_time)) + ) else: - query = query.filter((start >= models.Offer.start_time) & - (end <= models.Offer.end_time)) + query = query.filter( + (start >= models.Offer.start_time) & (end <= models.Offer.end_time) + ) if a_start and a_end: for o in query: @@ -156,55 +159,59 @@ def offer_get_all(filters): def offer_get_conflict_times(offer_ref): - l_query = model_query(models.Lease) - return l_query.with_entities( - models.Lease.start_time, models.Lease.end_time).\ - join(models.Offer, models.Offer.uuid == models.Lease.offer_uuid).\ - order_by(models.Lease.start_time).\ - filter(models.Lease.offer_uuid == offer_ref.uuid, - (models.Lease.status != statuses.EXPIRED) & - (models.Lease.status != statuses.DELETED) - ).all() + return ( + l_query.with_entities(models.Lease.start_time, models.Lease.end_time) + .join(models.Offer, models.Offer.uuid == models.Lease.offer_uuid) + .order_by(models.Lease.start_time) + .filter( + models.Lease.offer_uuid == offer_ref.uuid, + (models.Lease.status != statuses.EXPIRED) + & (models.Lease.status != statuses.DELETED), + ) + .all() + ) def offer_get_next_lease_start_time(offer_uuid, start): l_query = model_query(models.Lease) - return l_query.with_entities( - models.Lease.start_time).\ - filter(models.Lease.offer_uuid == offer_uuid, - (models.Lease.status == statuses.CREATED) | - (models.Lease.status == statuses.ACTIVE) - ).\ - order_by(models.Lease.start_time).\ - filter((models.Lease.end_time >= start) & - (models.Lease.start_time >= start)).first() + return ( + l_query.with_entities(models.Lease.start_time) + .filter( + models.Lease.offer_uuid == offer_uuid, + (models.Lease.status == statuses.CREATED) + | (models.Lease.status == statuses.ACTIVE), + ) + .order_by(models.Lease.start_time) + .filter((models.Lease.end_time >= start) & (models.Lease.start_time >= start)) + .first() + ) def offer_verify_availability(offer_ref, start, end): - if start < offer_ref.start_time or end > offer_ref.end_time: - raise exception.OfferNoTimeAvailabilities(offer_uuid=offer_ref.uuid, - start_time=start, - end_time=end) + raise exception.OfferNoTimeAvailabilities( + offer_uuid=offer_ref.uuid, start_time=start, end_time=end + ) l_query = model_query(models.Lease) leases = l_query.with_entities( - models.Lease.start_time, models.Lease.end_time).\ - filter((models.Lease.offer_uuid == offer_ref.uuid), - (models.Lease.status == statuses.CREATED) | - (models.Lease.status == statuses.ACTIVE) - ) + models.Lease.start_time, models.Lease.end_time + ).filter( + (models.Lease.offer_uuid == offer_ref.uuid), + (models.Lease.status == statuses.CREATED) + | (models.Lease.status == statuses.ACTIVE), + ) leases = add_lease_conflict_filter(leases, start, end) conflict = leases.first() if conflict: - raise exception.OfferNoTimeAvailabilities(offer_uuid=offer_ref.uuid, - start_time=start, - end_time=end) + raise exception.OfferNoTimeAvailabilities( + offer_uuid=offer_ref.uuid, start_time=start, end_time=end + ) def offer_create(values): @@ -218,25 +225,23 @@ def offer_create(values): def offer_update(offer_uuid, values): - with _session_for_write() as session: - query = model_query(models.Offer) offer_ref = query.filter_by(uuid=offer_uuid).one_or_none() - values.pop('uuid', None) - values.pop('project_id', None) + values.pop("uuid", None) + values.pop("project_id", None) - start = values.get('start_time', None) - end = values.get('end_time', None) + start = values.get("start_time", None) + end = values.get("end_time", None) if start is None: start = offer_ref.start_time if end is None: end = offer_ref.end_time if start >= end: - raise exception.InvalidTimeRange(resource='an offer', - start_time=str(start), - end_time=str(end)) + raise exception.InvalidTimeRange( + resource="an offer", start_time=str(start), end_time=str(end) + ) offer_ref.update(values) session.flush() @@ -256,16 +261,13 @@ def offer_destroy(offer_uuid): def add_offer_conflict_filter(query, start, end): - return query.filter(( - ((start >= models.Offer.start_time) & - (start < models.Offer.end_time)) | - - ((end > models.Offer.start_time) & - (end <= models.Offer.end_time)) | - - ((start <= models.Offer.start_time) & - (end >= models.Offer.end_time)) - )) + return query.filter( + ( + ((start >= models.Offer.start_time) & (start < models.Offer.end_time)) + | ((end > models.Offer.start_time) & (end <= models.Offer.end_time)) + | ((start <= models.Offer.start_time) & (end >= models.Offer.end_time)) + ) + ) # Leases @@ -284,11 +286,11 @@ def lease_get_by_name(name): def lease_get_all(filters): query = model_query(models.Lease) - start = filters.pop('start_time', None) - end = filters.pop('end_time', None) - time_filter_type = filters.pop('time_filter_type', None) - status = filters.pop('status', None) - project_or_owner_id = filters.pop('project_or_owner_id', None) + start = filters.pop("start_time", None) + end = filters.pop("end_time", None) + time_filter_type = filters.pop("time_filter_type", None) + status = filters.pop("status", None) + project_or_owner_id = filters.pop("project_or_owner_id", None) query = query.filter_by(**filters) @@ -297,23 +299,22 @@ def lease_get_all(filters): if start and end: if time_filter_type == constants.WITHIN_TIME_FILTER: - query = query.filter(((start <= models.Lease.start_time) & - (end >= models.Lease.start_time)) | - - ((start <= models.Lease.end_time) & - (end >= models.Lease.end_time)) | - - ((start >= models.Lease.start_time) & - (end <= models.Lease.end_time))) + query = query.filter( + ((start <= models.Lease.start_time) & (end >= models.Lease.start_time)) + | ((start <= models.Lease.end_time) & (end >= models.Lease.end_time)) + | ((start >= models.Lease.start_time) & (end <= models.Lease.end_time)) + ) else: - query = query.filter((start >= models.Lease.start_time) & - (end <= models.Lease.end_time)) + query = query.filter( + (start >= models.Lease.start_time) & (end <= models.Lease.end_time) + ) if project_or_owner_id: query = query.filter( - (project_or_owner_id == models.Lease.project_id) | - (project_or_owner_id == models.Lease.owner_id)) + (project_or_owner_id == models.Lease.project_id) + | (project_or_owner_id == models.Lease.owner_id) + ) return query @@ -333,19 +334,19 @@ def lease_update(lease_uuid, values): query = model_query(models.Lease) lease_ref = query.filter_by(uuid=lease_uuid).one_or_none() - values.pop('uuid', None) - values.pop('project_id', None) + values.pop("uuid", None) + values.pop("project_id", None) - start = values.get('start_time', None) - end = values.get('end_time', None) + start = values.get("start_time", None) + end = values.get("end_time", None) if start is None: start = lease_ref.start_time if end is None: end = lease_ref.end_time if start >= end: - raise exception.InvalidTimeRange(resource='a lease', - start_time=str(start), - end_time=str(end)) + raise exception.InvalidTimeRange( + resource="a lease", start_time=str(start), end_time=str(end) + ) lease_ref.update(values) session.flush() @@ -354,7 +355,6 @@ def lease_update(lease_uuid, values): def lease_destroy(lease_uuid): with _session_for_write() as session: - query = model_query(models.Lease) lease_ref = query.filter_by(uuid=lease_uuid).one_or_none() @@ -366,52 +366,52 @@ def lease_destroy(lease_uuid): def lease_verify_child_availability(lease_ref, start, end): if start < lease_ref.start_time or end > lease_ref.end_time: - raise exception.LeaseNoTimeAvailabilities(lease_uuid=lease_ref.uuid, - start_time=start, - end_time=end) + raise exception.LeaseNoTimeAvailabilities( + lease_uuid=lease_ref.uuid, start_time=start, end_time=end + ) # check lease conflicts l_query = model_query(models.Lease) leases = l_query.with_entities( - models.Lease.start_time, models.Lease.end_time).\ - filter((models.Lease.parent_lease_uuid == lease_ref.uuid), - (models.Lease.status == statuses.CREATED) | - (models.Lease.status == statuses.ACTIVE) - ) + models.Lease.start_time, models.Lease.end_time + ).filter( + (models.Lease.parent_lease_uuid == lease_ref.uuid), + (models.Lease.status == statuses.CREATED) + | (models.Lease.status == statuses.ACTIVE), + ) leases = add_lease_conflict_filter(leases, start, end) lease_conflict = leases.first() if lease_conflict: - raise exception.LeaseNoTimeAvailabilities(lease_uuid=lease_ref.uuid, - start_time=start, - end_time=end) + raise exception.LeaseNoTimeAvailabilities( + lease_uuid=lease_ref.uuid, start_time=start, end_time=end + ) # check offer conflicts o_query = model_query(models.Offer) offers = o_query.with_entities( - models.Offer.start_time, models.Offer.end_time).\ - filter((models.Offer.parent_lease_uuid == lease_ref.uuid), - (models.Offer.status == statuses.AVAILABLE)) + models.Offer.start_time, models.Offer.end_time + ).filter( + (models.Offer.parent_lease_uuid == lease_ref.uuid), + (models.Offer.status == statuses.AVAILABLE), + ) offers = add_offer_conflict_filter(offers, start, end) offer_conflict = offers.first() if offer_conflict: - raise exception.LeaseNoTimeAvailabilities(lease_uuid=lease_ref.uuid, - start_time=start, - end_time=end) + raise exception.LeaseNoTimeAvailabilities( + lease_uuid=lease_ref.uuid, start_time=start, end_time=end + ) def add_lease_conflict_filter(query, start, end): - return query.filter(( - ((start >= models.Lease.start_time) & - (start < models.Lease.end_time)) | - - ((end > models.Lease.start_time) & - (end <= models.Lease.end_time)) | - - ((start <= models.Lease.start_time) & - (end >= models.Lease.end_time)) - )) + return query.filter( + ( + ((start >= models.Lease.start_time) & (start < models.Lease.end_time)) + | ((end > models.Lease.start_time) & (end <= models.Lease.end_time)) + | ((start <= models.Lease.start_time) & (end >= models.Lease.end_time)) + ) + ) # Resources @@ -420,55 +420,56 @@ def resource_verify_availability(r_type, r_uuid, start, end): o_query = model_query(models.Offer) offers = o_query.with_entities( - models.Offer.start_time, models.Offer.end_time).\ - filter((models.Offer.resource_uuid == r_uuid), - (models.Offer.resource_type == r_type), - (models.Offer.status == statuses.AVAILABLE)) + models.Offer.start_time, models.Offer.end_time + ).filter( + (models.Offer.resource_uuid == r_uuid), + (models.Offer.resource_type == r_type), + (models.Offer.status == statuses.AVAILABLE), + ) offers = add_offer_conflict_filter(offers, start, end) offer_conflict = offers.first() if offer_conflict: - raise exception.ResourceTimeConflict( - resource_uuid=r_uuid, - resource_type=r_type) + raise exception.ResourceTimeConflict(resource_uuid=r_uuid, resource_type=r_type) # check conflict with leases l_query = model_query(models.Lease) leases = l_query.with_entities( - models.Lease.start_time, models.Lease.end_time).\ - filter((models.Lease.resource_uuid == r_uuid), - (models.Lease.resource_type == r_type), - (models.Lease.status.in_([statuses.CREATED, statuses.ACTIVE]))) + models.Lease.start_time, models.Lease.end_time + ).filter( + (models.Lease.resource_uuid == r_uuid), + (models.Lease.resource_type == r_type), + (models.Lease.status.in_([statuses.CREATED, statuses.ACTIVE])), + ) leases = add_lease_conflict_filter(leases, start, end) lease_conflict = leases.first() if lease_conflict: - raise exception.ResourceTimeConflict( - resource_uuid=r_uuid, - resource_type=r_type) + raise exception.ResourceTimeConflict(resource_uuid=r_uuid, resource_type=r_type) # Events + def event_get_all(filters): query = model_query(models.Event) - last_event_time = filters.pop('last_event_time', None) - last_event_id = filters.pop('last_event_id', None) - lessee_or_owner_id = filters.pop('lessee_or_owner_id', None) + last_event_time = filters.pop("last_event_time", None) + last_event_id = filters.pop("last_event_id", None) + lessee_or_owner_id = filters.pop("lessee_or_owner_id", None) query = query.filter_by(**filters) if last_event_time: - query = query.filter( - last_event_time < models.Event.event_time) + query = query.filter(last_event_time < models.Event.event_time) if last_event_id: query = query.filter(last_event_id < models.Event.id) if lessee_or_owner_id: query = query.filter( - (lessee_or_owner_id == models.Event.lessee_id) | - (lessee_or_owner_id == models.Event.owner_id)) + (lessee_or_owner_id == models.Event.lessee_id) + | (lessee_or_owner_id == models.Event.owner_id) + ) return query diff --git a/esi_leap/db/sqlalchemy/migration.py b/esi_leap/db/sqlalchemy/migration.py index 7997fc0a..5539cbcd 100644 --- a/esi_leap/db/sqlalchemy/migration.py +++ b/esi_leap/db/sqlalchemy/migration.py @@ -25,7 +25,7 @@ def _alembic_config(): - path = os.path.join(os.path.dirname(__file__), 'alembic.ini') + path = os.path.join(os.path.dirname(__file__), "alembic.ini") config = alembic_config.Config(path) return config @@ -49,10 +49,10 @@ def upgrade(revision, config=None): :param version: Desired database version :type version: string """ - revision = revision or 'head' + revision = revision or "head" config = config or _alembic_config() - alembic.command.upgrade(config, revision or 'head') + alembic.command.upgrade(config, revision or "head") def downgrade(revision, config=None): @@ -61,7 +61,7 @@ def downgrade(revision, config=None): :param version: Desired database version :type version: string """ - revision = revision or 'base' + revision = revision or "base" config = config or _alembic_config() return alembic.command.downgrade(config, revision) @@ -89,8 +89,7 @@ def revision(message=None, autogenerate=False, config=None): :type autogenerate: bool """ config = config or _alembic_config() - return alembic.command.revision(config, message=message, - autogenerate=autogenerate) + return alembic.command.revision(config, message=message, autogenerate=autogenerate) def create_schema(config=None, engine=None): @@ -101,4 +100,4 @@ def create_schema(config=None, engine=None): if engine is None: engine = enginefacade.writer.get_engine() models.Base.metadata.create_all(engine) - stamp('head', config=config) + stamp("head", config=config) diff --git a/esi_leap/db/sqlalchemy/models.py b/esi_leap/db/sqlalchemy/models.py index ef559525..04595a55 100644 --- a/esi_leap/db/sqlalchemy/models.py +++ b/esi_leap/db/sqlalchemy/models.py @@ -22,13 +22,12 @@ from esi_leap.common import statuses -@compiles(DateTime, 'mysql') +@compiles(DateTime, "mysql") def compile_datetime_mysql(type_, compiler, **kw): - return 'DATETIME(6)' + return "DATETIME(6)" class ESILEAPBase(models.TimestampMixin, models.ModelBase): - metadata = None def to_dict(self): @@ -44,12 +43,12 @@ def to_dict(self): class Offer(Base): """Represents a resource that is offered.""" - __tablename__ = 'offers' + __tablename__ = "offers" __table_args__ = ( - Index('offer_uuid_idx', 'uuid'), - Index('offer_project_id_idx', 'project_id'), - Index('offer_resource_idx', 'resource_type', 'resource_uuid'), - Index('offer_status_idx', 'status'), + Index("offer_uuid_idx", "uuid"), + Index("offer_project_id_idx", "project_id"), + Index("offer_resource_idx", "resource_type", "resource_uuid"), + Index("offer_status_idx", "status"), ) id = Column(Integer, primary_key=True, nullable=False, autoincrement=True) @@ -63,11 +62,9 @@ class Offer(Base): end_time = Column(DateTime) status = Column(String(15), nullable=False, default=statuses.AVAILABLE) properties = Column(db_types.JsonEncodedDict, nullable=True) - parent_lease_uuid = Column(String(36), - ForeignKey('leases.uuid'), - nullable=True) + parent_lease_uuid = Column(String(36), ForeignKey("leases.uuid"), nullable=True) parent_lease = orm.relationship( - 'Lease', + "Lease", foreign_keys=[parent_lease_uuid], ) @@ -75,12 +72,12 @@ class Offer(Base): class Lease(Base): """Represents a lease.""" - __tablename__ = 'leases' + __tablename__ = "leases" __table_args__ = ( - Index('lease_uuid_idx', 'uuid'), - Index('lease_project_id_idx', 'project_id'), - Index('lease_owner_id_idx', 'owner_id'), - Index('lease_status_idx', 'status'), + Index("lease_uuid_idx", "uuid"), + Index("lease_project_id_idx", "project_id"), + Index("lease_owner_id_idx", "owner_id"), + Index("lease_status_idx", "status"), ) id = Column(Integer, primary_key=True, nullable=False, autoincrement=True) @@ -97,33 +94,30 @@ class Lease(Base): expire_time = Column(DateTime) status = Column(String(15), nullable=False, default=statuses.CREATED) properties = Column(db_types.JsonEncodedDict, nullable=True) - offer_uuid = Column(String(36), - ForeignKey('offers.uuid'), - nullable=True) - parent_lease_uuid = Column(String(36), - ForeignKey('leases.uuid'), - nullable=True) + offer_uuid = Column(String(36), ForeignKey("offers.uuid"), nullable=True) + parent_lease_uuid = Column(String(36), ForeignKey("leases.uuid"), nullable=True) offer = orm.relationship( Offer, - backref=orm.backref('offers'), + backref=orm.backref("offers"), foreign_keys=offer_uuid, - primaryjoin=offer_uuid == Offer.uuid) + primaryjoin=offer_uuid == Offer.uuid, + ) parent_lease = orm.relationship( - 'Lease', - backref=orm.backref('child_leases', remote_side=uuid), + "Lease", + backref=orm.backref("child_leases", remote_side=uuid), ) class Event(Base): """Represents an event.""" - __tablename__ = 'events' + __tablename__ = "events" __table_args__ = ( - Index('event_type_idx', 'event_type'), - Index('event_lessee_id_idx', 'lessee_id'), - Index('event_owner_id_idx', 'owner_id'), - Index('event_resource_idx', 'resource_type', 'resource_uuid'), - Index('event_time_idx', 'event_time'), + Index("event_type_idx", "event_type"), + Index("event_lessee_id_idx", "lessee_id"), + Index("event_owner_id_idx", "owner_id"), + Index("event_resource_idx", "resource_type", "resource_uuid"), + Index("event_time_idx", "event_time"), ) id = Column(Integer, primary_key=True, nullable=False, autoincrement=True) diff --git a/esi_leap/manager/rpcapi.py b/esi_leap/manager/rpcapi.py index 2425dbd4..f80000aa 100644 --- a/esi_leap/manager/rpcapi.py +++ b/esi_leap/manager/rpcapi.py @@ -28,5 +28,5 @@ class ManagerRPCAPI(object): def __init__(self): self._client = messaging.RPCClient( - target=utils.get_target(), - transport=messaging.get_rpc_transport(CONF)) + target=utils.get_target(), transport=messaging.get_rpc_transport(CONF) + ) diff --git a/esi_leap/manager/service.py b/esi_leap/manager/service.py index 4302621a..b9db538a 100644 --- a/esi_leap/manager/service.py +++ b/esi_leap/manager/service.py @@ -30,103 +30,110 @@ class ManagerService(service.Service): def __init__(self): super(ManagerService, self).__init__() - LOG.info('Creating esi-leap manager RPC server') + LOG.info("Creating esi-leap manager RPC server") self._server = messaging.get_rpc_server( target=utils.get_target(), transport=messaging.get_rpc_transport(CONF), endpoints=[ManagerEndpoint()], - executor='eventlet', + executor="eventlet", ) self._context = ctx.RequestContext( - auth_token=None, - project_id=None, - overwrite=False) + auth_token=None, project_id=None, overwrite=False + ) def start(self): super(ManagerService, self).start() - LOG.info('Starting esi-leap manager RPC server') + LOG.info("Starting esi-leap manager RPC server") self.tg.add_thread(self._server.start) - LOG.info('Starting _fulfill_leases periodic job') + LOG.info("Starting _fulfill_leases periodic job") self.tg.add_timer(EVENT_INTERVAL, self._fulfill_leases) - LOG.info('Starting _expire_leases periodic job') + LOG.info("Starting _expire_leases periodic job") self.tg.add_timer(EVENT_INTERVAL, self._expire_leases) - LOG.info('Starting _cancel_leases periodic job') + LOG.info("Starting _cancel_leases periodic job") self.tg.add_timer(EVENT_INTERVAL, self._cancel_leases) - LOG.info('Starting _expire_offers periodic job') + LOG.info("Starting _expire_offers periodic job") self.tg.add_timer(EVENT_INTERVAL, self._expire_offers) def stop(self): super(ManagerService, self).stop() - LOG.info('Shutting down esi-leap manager RPC server') + LOG.info("Shutting down esi-leap manager RPC server") self._server.stop() def _fulfill_leases(self): - LOG.info('Checking for leases to fulfill') + LOG.info("Checking for leases to fulfill") leases = lease_obj.Lease.get_all( - {'status': [statuses.CREATED, statuses.WAIT_FULFILL]}, - self._context) + {"status": [statuses.CREATED, statuses.WAIT_FULFILL]}, self._context + ) now = timeutils.utcnow() for lease in leases: if lease.start_time <= now and now <= lease.end_time: try: - LOG.info('Fulfilling lease %s', lease.uuid) + LOG.info("Fulfilling lease %s", lease.uuid) lease.fulfill(self._context) except Exception as e: - LOG.info('Error fulfilling lease: %s: %s' % - (type(e).__name__, e)) - LOG.info('Setting lease status to ERROR') + LOG.info("Error fulfilling lease: %s: %s" % (type(e).__name__, e)) + LOG.info("Setting lease status to ERROR") lease.status = statuses.ERROR lease.save() def _expire_leases(self): - LOG.info('Checking for expiring leases') + LOG.info("Checking for expiring leases") leases = lease_obj.Lease.get_all( - {'status': [statuses.ACTIVE, statuses.CREATED, - statuses.WAIT_EXPIRE, statuses.WAIT_FULFILL]}, - self._context) + { + "status": [ + statuses.ACTIVE, + statuses.CREATED, + statuses.WAIT_EXPIRE, + statuses.WAIT_FULFILL, + ] + }, + self._context, + ) now = timeutils.utcnow() for lease in leases: if lease.end_time <= now: try: - LOG.info('Expiring lease %s', lease.uuid) + LOG.info("Expiring lease %s", lease.uuid) lease.expire(self._context) except Exception as e: - LOG.info('Error expiring lease: %s: %s' % - (type(e).__name__, e)) - LOG.info('Setting lease status to ERROR') + LOG.info("Error expiring lease: %s: %s" % (type(e).__name__, e)) + LOG.info("Setting lease status to ERROR") lease.status = statuses.ERROR lease.save() def _cancel_leases(self): - LOG.info('Checking for leases to cancel') + LOG.info("Checking for leases to cancel") leases = lease_obj.Lease.get_all( - {'status': [statuses.WAIT_CANCEL]}, self._context) + {"status": [statuses.WAIT_CANCEL]}, self._context + ) for lease in leases: try: - LOG.info('Cancelling lease %s', lease.uuid) + LOG.info("Cancelling lease %s", lease.uuid) lease.cancel() except Exception as e: - LOG.info('Error cancelling lease: %s: %s' % - (type(e).__name__, e)) - LOG.info('Setting lease status to ERROR') + LOG.info("Error cancelling lease: %s: %s" % (type(e).__name__, e)) + LOG.info("Setting lease status to ERROR") lease.status = statuses.ERROR lease.save() def _expire_offers(self): - LOG.info('Checking for expiring offers') - offers = offer_obj.Offer.get_all({'status': statuses.OFFER_CAN_DELETE}, - self._context) + LOG.info("Checking for expiring offers") + offers = offer_obj.Offer.get_all( + {"status": statuses.OFFER_CAN_DELETE}, self._context + ) for offer in offers: if offer.end_time and offer.end_time <= timeutils.utcnow(): try: - LOG.info('Expiring offer %s for %s %s', - offer.uuid, offer.resource_type, - offer.resource_uuid) + LOG.info( + "Expiring offer %s for %s %s", + offer.uuid, + offer.resource_type, + offer.resource_uuid, + ) offer.expire(self._context) except Exception as e: - LOG.info('Error expiring offer: %s: %s' % - (type(e).__name__, e)) + LOG.info("Error expiring offer: %s: %s" % (type(e).__name__, e)) offer.status = statuses.ERROR offer.save() diff --git a/esi_leap/manager/utils.py b/esi_leap/manager/utils.py index ddc4d440..7716b825 100644 --- a/esi_leap/manager/utils.py +++ b/esi_leap/manager/utils.py @@ -16,13 +16,12 @@ CONF = esi_leap.conf.CONF -NAMESPACE = 'manager.api' -RPC_API_VERSION = '1.0' -TOPIC = 'esi_leap.manager' +NAMESPACE = "manager.api" +RPC_API_VERSION = "1.0" +TOPIC = "esi_leap.manager" def get_target(): - return messaging.Target(topic=TOPIC, - server=CONF.host, - version=RPC_API_VERSION, - namespace=NAMESPACE) + return messaging.Target( + topic=TOPIC, server=CONF.host, version=RPC_API_VERSION, namespace=NAMESPACE + ) diff --git a/esi_leap/objects/__init__.py b/esi_leap/objects/__init__.py index 911963c6..bb85ba0f 100644 --- a/esi_leap/objects/__init__.py +++ b/esi_leap/objects/__init__.py @@ -1,4 +1,4 @@ def register_all(): - __import__('esi_leap.objects.event') - __import__('esi_leap.objects.lease') - __import__('esi_leap.objects.offer') + __import__("esi_leap.objects.event") + __import__("esi_leap.objects.lease") + __import__("esi_leap.objects.offer") diff --git a/esi_leap/objects/base.py b/esi_leap/objects/base.py index 8ed31e00..421465f8 100644 --- a/esi_leap/objects/base.py +++ b/esi_leap/objects/base.py @@ -19,12 +19,12 @@ class ESILEAPObject(object_base.VersionedObject): - OBJ_SERIAL_NAMESPACE = 'esi_leap_object' - OBJ_PROJECT_NAMESPACE = 'esi_leap' + OBJ_SERIAL_NAMESPACE = "esi_leap_object" + OBJ_PROJECT_NAMESPACE = "esi_leap" fields = { - 'created_at': object_fields.DateTimeField(nullable=True), - 'updated_at': object_fields.DateTimeField(nullable=True), + "created_at": object_fields.DateTimeField(nullable=True), + "updated_at": object_fields.DateTimeField(nullable=True), } @staticmethod @@ -37,10 +37,9 @@ def _from_db_object(context, obj, db_obj): @classmethod def _from_db_object_list(cls, context, db_objs): - return [cls._from_db_object(context, cls(), db_obj) - for db_obj in db_objs] + return [cls._from_db_object(context, cls(), db_obj) for db_obj in db_objs] def to_dict(self): - return dict((k, getattr(self, k)) - for k in self.fields - if self.obj_attr_is_set(k)) + return dict( + (k, getattr(self, k)) for k in self.fields if self.obj_attr_is_set(k) + ) diff --git a/esi_leap/objects/event.py b/esi_leap/objects/event.py index 7d0798ed..ea496596 100644 --- a/esi_leap/objects/event.py +++ b/esi_leap/objects/event.py @@ -27,15 +27,15 @@ class Event(base.ESILEAPObject): dbapi = dbapi.get_instance() fields = { - 'id': fields.IntegerField(), - 'event_type': fields.StringField(), - 'event_time': fields.DateTimeField(), - 'object_type': fields.StringField(nullable=True), - 'object_uuid': fields.StringField(nullable=True), - 'resource_type': fields.StringField(nullable=True), - 'resource_uuid': fields.StringField(nullable=True), - 'lessee_id': fields.StringField(nullable=True), - 'owner_id': fields.StringField(nullable=True), + "id": fields.IntegerField(), + "event_type": fields.StringField(), + "event_time": fields.DateTimeField(), + "object_type": fields.StringField(nullable=True), + "object_uuid": fields.StringField(nullable=True), + "resource_type": fields.StringField(nullable=True), + "resource_uuid": fields.StringField(nullable=True), + "lessee_id": fields.StringField(nullable=True), + "owner_id": fields.StringField(nullable=True), } @classmethod @@ -46,6 +46,6 @@ def get_all(cls, filters, context=None): def create(self, context=None): updates = self.obj_get_changes() - LOG.info('Creating event') + LOG.info("Creating event") db_event = self.dbapi.event_create(updates) self._from_db_object(context, self, db_event) diff --git a/esi_leap/objects/fields.py b/esi_leap/objects/fields.py index 7e715b82..819b5a8e 100644 --- a/esi_leap/objects/fields.py +++ b/esi_leap/objects/fields.py @@ -60,17 +60,16 @@ class UUIDField(object_fields.UUIDField): class NotificationLevel(object_fields.Enum): - DEBUG = 'debug' - INFO = 'info' - WARNING = 'warning' - ERROR = 'error' - CRITICAL = 'critical' + DEBUG = "debug" + INFO = "info" + WARNING = "warning" + ERROR = "error" + CRITICAL = "critical" ALL = (DEBUG, INFO, WARNING, ERROR, CRITICAL) def __init__(self): - super(NotificationLevel, self).__init__( - valid_values=NotificationLevel.ALL) + super(NotificationLevel, self).__init__(valid_values=NotificationLevel.ALL) class NotificationLevelField(object_fields.BaseEnumField): @@ -78,16 +77,15 @@ class NotificationLevelField(object_fields.BaseEnumField): class NotificationStatus(object_fields.Enum): - START = 'start' - END = 'end' - ERROR = 'error' - SUCCESS = 'success' + START = "start" + END = "end" + ERROR = "error" + SUCCESS = "success" ALL = (START, END, ERROR, SUCCESS) def __init__(self): - super(NotificationStatus, self).__init__( - valid_values=NotificationStatus.ALL) + super(NotificationStatus, self).__init__(valid_values=NotificationStatus.ALL) class NotificationStatusField(object_fields.BaseEnumField): diff --git a/esi_leap/objects/lease.py b/esi_leap/objects/lease.py index 98d43cff..8f64172f 100644 --- a/esi_leap/objects/lease.py +++ b/esi_leap/objects/lease.py @@ -35,92 +35,93 @@ class LeaseCRUDNotification(notification.NotificationBase): """Notification emitted when a lease is created or deleted.""" - fields = { - 'payload': fields.ObjectField('LeaseCRUDPayload') - } + fields = {"payload": fields.ObjectField("LeaseCRUDPayload")} @versioned_objects_base.VersionedObjectRegistry.register class LeaseCRUDPayload(notification.NotificationPayloadBase): """Payload schema for when a lease is created or deleted.""" + # Version 1.0: Initial version - VERSION = '1.0' + VERSION = "1.0" SCHEMA = { - 'id': ('lease', 'id'), - 'name': ('lease', 'name'), - 'uuid': ('lease', 'uuid'), - 'project_id': ('lease', 'project_id'), - 'owner_id': ('lease', 'owner_id'), - 'resource_type': ('lease', 'resource_type'), - 'resource_uuid': ('lease', 'resource_uuid'), - 'start_time': ('lease', 'start_time'), - 'end_time': ('lease', 'end_time'), - 'fulfill_time': ('lease', 'fulfill_time'), - 'expire_time': ('lease', 'expire_time'), - 'status': ('lease', 'status'), - 'properties': ('lease', 'properties'), - 'purpose': ('lease', 'purpose'), - 'offer_uuid': ('lease', 'offer_uuid'), - 'parent_lease_uuid': ('lease', 'parent_lease_uuid'), - 'node_name': ('node', 'node_name'), - 'node_uuid': ('node', '_uuid'), - 'node_provision_state': ('node', 'node_provision_state'), - 'node_power_state': ('node', 'node_power_state'), - 'node_properties': ('node', 'node_properties'), + "id": ("lease", "id"), + "name": ("lease", "name"), + "uuid": ("lease", "uuid"), + "project_id": ("lease", "project_id"), + "owner_id": ("lease", "owner_id"), + "resource_type": ("lease", "resource_type"), + "resource_uuid": ("lease", "resource_uuid"), + "start_time": ("lease", "start_time"), + "end_time": ("lease", "end_time"), + "fulfill_time": ("lease", "fulfill_time"), + "expire_time": ("lease", "expire_time"), + "status": ("lease", "status"), + "properties": ("lease", "properties"), + "purpose": ("lease", "purpose"), + "offer_uuid": ("lease", "offer_uuid"), + "parent_lease_uuid": ("lease", "parent_lease_uuid"), + "node_name": ("node", "node_name"), + "node_uuid": ("node", "_uuid"), + "node_provision_state": ("node", "node_provision_state"), + "node_power_state": ("node", "node_power_state"), + "node_properties": ("node", "node_properties"), } fields = { - 'id': fields.IntegerField(), - 'name': fields.StringField(nullable=True), - 'uuid': fields.UUIDField(), - 'project_id': fields.StringField(), - 'owner_id': fields.StringField(), - 'purpose': fields.StringField(nullable=True), - 'resource_type': fields.StringField(), - 'resource_uuid': fields.StringField(), - 'start_time': fields.DateTimeField(nullable=True), - 'end_time': fields.DateTimeField(nullable=True), - 'fulfill_time': fields.DateTimeField(nullable=True), - 'expire_time': fields.DateTimeField(nullable=True), - 'status': fields.StringField(), - 'properties': fields.FlexibleDictField(nullable=True), - 'offer_uuid': fields.UUIDField(nullable=True), - 'parent_lease_uuid': fields.UUIDField(nullable=True), - 'node_name': fields.StringField(nullable=True), - 'node_uuid': fields.UUIDField(), - 'node_provision_state': fields.StringField(), - 'node_power_state': fields.StringField(), - 'node_properties': fields.FlexibleDictField(nullable=True), + "id": fields.IntegerField(), + "name": fields.StringField(nullable=True), + "uuid": fields.UUIDField(), + "project_id": fields.StringField(), + "owner_id": fields.StringField(), + "purpose": fields.StringField(nullable=True), + "resource_type": fields.StringField(), + "resource_uuid": fields.StringField(), + "start_time": fields.DateTimeField(nullable=True), + "end_time": fields.DateTimeField(nullable=True), + "fulfill_time": fields.DateTimeField(nullable=True), + "expire_time": fields.DateTimeField(nullable=True), + "status": fields.StringField(), + "properties": fields.FlexibleDictField(nullable=True), + "offer_uuid": fields.UUIDField(nullable=True), + "parent_lease_uuid": fields.UUIDField(nullable=True), + "node_name": fields.StringField(nullable=True), + "node_uuid": fields.UUIDField(), + "node_provision_state": fields.StringField(), + "node_power_state": fields.StringField(), + "node_properties": fields.FlexibleDictField(nullable=True), } def __init__(self, lease, node): super(LeaseCRUDPayload, self).__init__() - setattr(node, 'node_name', node.get_name()) - setattr(node, 'node_provision_state', node.get_node_provision_state()) - setattr(node, 'node_power_state', node.get_node_power_state()) + setattr(node, "node_name", node.get_name()) + setattr(node, "node_provision_state", node.get_node_provision_state()) + setattr(node, "node_power_state", node.get_node_power_state()) node_properties = node.get_properties().copy() - node_properties.pop('lease_uuid', None) - setattr(node, 'node_properties', node_properties) + node_properties.pop("lease_uuid", None) + setattr(node, "node_properties", node_properties) self.populate_schema(lease=lease, node=node) def get_event_dict(self, event_type): event_dict = super().get_event_dict(event_type) - event_dict.update({ - 'object_type': 'lease', - 'object_uuid': self.uuid, - 'resource_type': self.resource_type, - 'resource_uuid': self.resource_uuid, - 'lessee_id': self.project_id, - 'owner_id': self.owner_id, - }) + event_dict.update( + { + "object_type": "lease", + "object_uuid": self.uuid, + "resource_type": self.resource_type, + "resource_uuid": self.resource_uuid, + "lessee_id": self.project_id, + "owner_id": self.owner_id, + } + ) return event_dict CRUD_NOTIFY_OBJ = { - 'lease': (LeaseCRUDNotification, LeaseCRUDPayload), + "lease": (LeaseCRUDNotification, LeaseCRUDPayload), } @@ -129,22 +130,22 @@ class Lease(base.ESILEAPObject): dbapi = dbapi.get_instance() fields = { - 'id': fields.IntegerField(), - 'name': fields.StringField(nullable=True), - 'uuid': fields.UUIDField(), - 'project_id': fields.StringField(), - 'owner_id': fields.StringField(), - 'purpose': fields.StringField(nullable=True), - 'resource_type': fields.StringField(), - 'resource_uuid': fields.StringField(), - 'start_time': fields.DateTimeField(nullable=True), - 'end_time': fields.DateTimeField(nullable=True), - 'fulfill_time': fields.DateTimeField(nullable=True), - 'expire_time': fields.DateTimeField(nullable=True), - 'status': fields.StringField(), - 'properties': fields.FlexibleDictField(nullable=True), - 'offer_uuid': fields.UUIDField(nullable=True), - 'parent_lease_uuid': fields.UUIDField(nullable=True), + "id": fields.IntegerField(), + "name": fields.StringField(nullable=True), + "uuid": fields.UUIDField(), + "project_id": fields.StringField(), + "owner_id": fields.StringField(), + "purpose": fields.StringField(nullable=True), + "resource_type": fields.StringField(), + "resource_uuid": fields.StringField(), + "start_time": fields.DateTimeField(nullable=True), + "end_time": fields.DateTimeField(nullable=True), + "fulfill_time": fields.DateTimeField(nullable=True), + "expire_time": fields.DateTimeField(nullable=True), + "status": fields.StringField(), + "properties": fields.FlexibleDictField(nullable=True), + "offer_uuid": fields.UUIDField(nullable=True), + "parent_lease_uuid": fields.UUIDField(nullable=True), } @classmethod @@ -160,44 +161,52 @@ def get_all(cls, filters, context=None): def create(self, context=None): updates = self.obj_get_changes() - resource_type = updates['resource_type'] - resource_uuid = updates['resource_uuid'] - start_time = updates['start_time'] - end_time = updates['end_time'] - with utils.lock(utils.get_resource_lock_name(resource_type, - resource_uuid), - external=True): + resource_type = updates["resource_type"] + resource_uuid = updates["resource_uuid"] + start_time = updates["start_time"] + end_time = updates["end_time"] + with utils.lock( + utils.get_resource_lock_name(resource_type, resource_uuid), external=True + ): self.verify_time_range( - start_time, end_time, - updates.get('offer_uuid', None), - updates.get('parent_lease_uuid', None), - resource_type, resource_uuid) + start_time, + end_time, + updates.get("offer_uuid", None), + updates.get("parent_lease_uuid", None), + resource_type, + resource_uuid, + ) db_lease = self.dbapi.lease_create(updates) self._from_db_object(context, self, db_lease) def update(self, updates, context=None): # only allow updates to end_time right now - if 'end_time' not in updates: + if "end_time" not in updates: return - new_end_time = updates['end_time'] - with utils.lock(utils.get_resource_lock_name(self.resource_type, - self.resource_uuid), - external=True): + new_end_time = updates["end_time"] + with utils.lock( + utils.get_resource_lock_name(self.resource_type, self.resource_uuid), + external=True, + ): if self.start_time >= new_end_time: raise exception.InvalidTimeRange( - resource='lease', + resource="lease", start_time=str(self.start_time), - end_time=str(new_end_time) - ) + end_time=str(new_end_time), + ) # only need to check availabilities if new end time is greater # than previous end time if new_end_time > self.end_time: self.verify_time_range( - self.end_time, new_end_time, - self.offer_uuid, self.parent_lease_uuid, - self.resource_type, self.resource_uuid) + self.end_time, + new_end_time, + self.offer_uuid, + self.parent_lease_uuid, + self.resource_type, + self.resource_uuid, + ) # lease is available in new range; set and save self.end_time = new_end_time @@ -205,22 +214,21 @@ def update(self, updates, context=None): def cancel(self, context=None): leases = Lease.get_all( - {'parent_lease_uuid': self.uuid, - 'status': statuses.LEASE_CAN_DELETE}, - None) + {"parent_lease_uuid": self.uuid, "status": statuses.LEASE_CAN_DELETE}, None + ) for lease in leases: lease.cancel() offers = offer_obj.Offer.get_all( - {'parent_lease_uuid': self.uuid, - 'status': statuses.OFFER_CAN_DELETE}, - None) + {"parent_lease_uuid": self.uuid, "status": statuses.OFFER_CAN_DELETE}, None + ) for offer in offers: offer.cancel() - with utils.lock(utils.get_resource_lock_name(self.resource_type, - self.resource_uuid), - external=True): - LOG.info('Deleting lease %s', self.uuid) + with utils.lock( + utils.get_resource_lock_name(self.resource_type, self.resource_uuid), + external=True, + ): + LOG.info("Deleting lease %s", self.uuid) try: resource = self.resource_object() self.deactivate(context, resource) @@ -228,9 +236,8 @@ def cancel(self, context=None): self.expire_time = datetime.datetime.now() except Exception as e: - LOG.info('Error canceling lease: %s: %s' % - (type(e).__name__, e)) - LOG.info('Setting lease status to WAIT') + LOG.info("Error canceling lease: %s: %s" % (type(e).__name__, e)) + LOG.info("Setting lease status to WAIT") self.status = statuses.WAIT_CANCEL self.save(context) @@ -240,61 +247,55 @@ def destroy(self): def save(self, context=None): updates = self.obj_get_changes() - db_lease = self.dbapi.lease_update( - self.uuid, updates) + db_lease = self.dbapi.lease_update(self.uuid, updates) self._from_db_object(context, self, db_lease) def fulfill(self, context=None): - with utils.lock(utils.get_resource_lock_name(self.resource_type, - self.resource_uuid), - external=True): - LOG.info('Fulfilling lease %s', self.uuid) + with utils.lock( + utils.get_resource_lock_name(self.resource_type, self.resource_uuid), + external=True, + ): + LOG.info("Fulfilling lease %s", self.uuid) try: resource = self.resource_object() - notify.emit_start_notification(context, self, - 'fulfill', - CRUD_NOTIFY_OBJ, - node=resource) - with notify.handle_error_notification(context, - self, - 'fulfill', - CRUD_NOTIFY_OBJ, - node=resource): + notify.emit_start_notification( + context, self, "fulfill", CRUD_NOTIFY_OBJ, node=resource + ) + with notify.handle_error_notification( + context, self, "fulfill", CRUD_NOTIFY_OBJ, node=resource + ): resource.set_lease(self) - notify.emit_end_notification(context, self, - 'fulfill', - CRUD_NOTIFY_OBJ, - node=resource) + notify.emit_end_notification( + context, self, "fulfill", CRUD_NOTIFY_OBJ, node=resource + ) self.status = statuses.ACTIVE self.fulfill_time = datetime.datetime.now() except Exception as e: - LOG.info('Error fulfilling lease: %s: %s' % - (type(e).__name__, e)) - LOG.info('Setting lease status to WAIT') + LOG.info("Error fulfilling lease: %s: %s" % (type(e).__name__, e)) + LOG.info("Setting lease status to WAIT") self.status = statuses.WAIT_FULFILL self.save(context) def expire(self, context=None): leases = Lease.get_all( - {'parent_lease_uuid': self.uuid, - 'status': statuses.LEASE_CAN_DELETE}, - None) + {"parent_lease_uuid": self.uuid, "status": statuses.LEASE_CAN_DELETE}, None + ) for lease in leases: lease.expire(context) offers = offer_obj.Offer.get_all( - {'parent_lease_uuid': self.uuid, - 'status': statuses.OFFER_CAN_DELETE}, - None) + {"parent_lease_uuid": self.uuid, "status": statuses.OFFER_CAN_DELETE}, None + ) for offer in offers: offer.expire(context) - with utils.lock(utils.get_resource_lock_name(self.resource_type, - self.resource_uuid), - external=True): - LOG.info('Expiring lease %s', self.uuid) + with utils.lock( + utils.get_resource_lock_name(self.resource_type, self.resource_uuid), + external=True, + ): + LOG.info("Expiring lease %s", self.uuid) try: # expire lease resource = self.resource_object() @@ -303,9 +304,8 @@ def expire(self, context=None): self.expire_time = datetime.datetime.now() except Exception as e: - LOG.info('Error expiring lease: %s: %s' % - (type(e).__name__, e)) - LOG.info('Setting lease status to WAIT') + LOG.info("Error expiring lease: %s: %s" % (type(e).__name__, e)) + LOG.info("Setting lease status to WAIT") self.status = statuses.WAIT_EXPIRE self.save(context) @@ -313,19 +313,16 @@ def resource_object(self): return get_resource_object(self.resource_type, self.resource_uuid) def verify_child_availability(self, start_time, end_time): - return self.dbapi.lease_verify_child_availability( - self, start_time, end_time) + return self.dbapi.lease_verify_child_availability(self, start_time, end_time) def deactivate(self, context, resource): - notify.emit_start_notification(context, self, - 'delete', CRUD_NOTIFY_OBJ, - node=resource) - - with notify.handle_error_notification(context, - self, - 'delete', - CRUD_NOTIFY_OBJ, - node=resource): + notify.emit_start_notification( + context, self, "delete", CRUD_NOTIFY_OBJ, node=resource + ) + + with notify.handle_error_notification( + context, self, "delete", CRUD_NOTIFY_OBJ, node=resource + ): if resource.get_lease_uuid() == self.uuid: resource.remove_lease(self) @@ -333,19 +330,22 @@ def deactivate(self, context, resource): parent_lease = Lease.get(self.parent_lease_uuid) resource.set_lease(parent_lease) - notify.emit_end_notification(context, self, - 'delete', CRUD_NOTIFY_OBJ, - node=resource) + notify.emit_end_notification( + context, self, "delete", CRUD_NOTIFY_OBJ, node=resource + ) @staticmethod - def verify_time_range(start_time, end_time, - offer_uuid, parent_lease_uuid, - resource_type, resource_uuid): + def verify_time_range( + start_time, + end_time, + offer_uuid, + parent_lease_uuid, + resource_type, + resource_uuid, + ): if start_time >= end_time: raise exception.InvalidTimeRange( - resource='lease', - start_time=str(start_time), - end_time=str(end_time) + resource="lease", start_time=str(start_time), end_time=str(end_time) ) # check availability @@ -354,20 +354,16 @@ def verify_time_range(start_time, end_time, related_offer = offer_obj.Offer.get(offer_uuid) if related_offer.status != statuses.AVAILABLE: raise exception.OfferNotAvailable( - offer_uuid=related_offer.uuid, - status=related_offer.status) - related_offer.verify_availability(start_time, - end_time) + offer_uuid=related_offer.uuid, status=related_offer.status + ) + related_offer.verify_availability(start_time, end_time) elif parent_lease_uuid: # lease is a child of an existing lease parent_lease = Lease.get(parent_lease_uuid) if parent_lease.status != statuses.ACTIVE: - raise exception.LeaseNotActive( - parent_lease_uuid) - parent_lease.verify_child_availability(start_time, - end_time) + raise exception.LeaseNotActive(parent_lease_uuid) + parent_lease.verify_child_availability(start_time, end_time) else: - ro = get_resource_object(resource_type, - resource_uuid) + ro = get_resource_object(resource_type, resource_uuid) ro.verify_availability(start_time, end_time) return diff --git a/esi_leap/objects/notification.py b/esi_leap/objects/notification.py index da9b9a44..6ad2e201 100644 --- a/esi_leap/objects/notification.py +++ b/esi_leap/objects/notification.py @@ -35,7 +35,7 @@ fields.NotificationLevel.INFO: 1, fields.NotificationLevel.WARNING: 2, fields.NotificationLevel.ERROR: 3, - fields.NotificationLevel.CRITICAL: 4 + fields.NotificationLevel.CRITICAL: 4, } @@ -46,26 +46,27 @@ class EventType(base.ESILEAPObject): An EventType must specify the object being acted on, a string describing the action being taken on the notification, and the status of the action. """ + # Version 1.0: Initial version - VERSION = '1.0' + VERSION = "1.0" fields = { - 'object': fields.StringField(nullable=False), - 'action': fields.StringField(nullable=False), - 'status': fields.NotificationStatusField() + "object": fields.StringField(nullable=False), + "action": fields.StringField(nullable=False), + "status": fields.NotificationStatusField(), } def to_event_type_field(self): """Constructs string for event_type to be sent on the wire. - The string is in the format: esi_leap... + The string is in the format: esi_leap... - :raises: ValueError if self.status is not one of - :class:`fields.NotificationStatusField` - :returns: event_type string + :raises: ValueError if self.status is not one of + :class:`fields.NotificationStatusField` + :returns: event_type string """ - parts = ['esi_leap', self.object, self.action, self.status] - return '.'.join(parts) + parts = ["esi_leap", self.object, self.action, self.status] + return ".".join(parts) class NotificationBase(base.ESILEAPObject): @@ -74,13 +75,14 @@ class NotificationBase(base.ESILEAPObject): Subclasses must define the "payload" field, which must be a subclass of NotificationPayloadBase. """ + # Version 1.0: Initial version - VERSION = '1.0' + VERSION = "1.0" fields = { - 'level': fields.NotificationLevelField(), - 'event_type': fields.ObjectField('EventType'), - 'publisher': fields.ObjectField('NotificationPublisher') + "level": fields.NotificationLevelField(), + "event_type": fields.ObjectField("EventType"), + "publisher": fields.ObjectField("NotificationPublisher"), } def _should_notify(self): @@ -95,24 +97,25 @@ def _should_notify(self): """ if CONF.notification.notification_level is None: return False - return (NOTIFY_LEVELS[self.level] >= - NOTIFY_LEVELS[CONF.notification.notification_level]) + return ( + NOTIFY_LEVELS[self.level] + >= NOTIFY_LEVELS[CONF.notification.notification_level] + ) def emit(self, context): """Send the notification. - :raises: NotificationPayloadError - :raises: oslo_versionedobjects.exceptions.MessageDeliveryFailure + :raises: NotificationPayloadError + :raises: oslo_versionedobjects.exceptions.MessageDeliveryFailure """ if not self._should_notify(): return if not self.payload.populated: - raise exception.NotificationPayloadError( - class_name=self.__class__.__name__) + raise exception.NotificationPayloadError(class_name=self.__class__.__name__) self.payload.obj_reset_changes() event_type = self.event_type.to_event_type_field() - publisher_id = '%s.%s' % (self.publisher.service, self.publisher.host) + publisher_id = "%s.%s" % (self.publisher.service, self.publisher.host) payload = self.payload.obj_to_primitive() notifier = rpc.get_versioned_notifier(publisher_id) @@ -129,7 +132,7 @@ class NotificationPayloadBase(base.ESILEAPObject): SCHEMA = {} # Version 1.0: Initial version - VERSION = '1.0' + VERSION = "1.0" def __init__(self, *args, **kwargs): super(NotificationPayloadBase, self).__init__(*args, **kwargs) @@ -148,8 +151,7 @@ def populate_schema(self, **kwargs): try: source = kwargs[obj] except KeyError: - raise exception.NotificationSchemaObjectError(obj=obj, - source=kwargs) + raise exception.NotificationSchemaObjectError(obj=obj, source=kwargs) try: setattr(self, key, getattr(source, field)) except NotImplementedError: @@ -158,32 +160,31 @@ def populate_schema(self, **kwargs): # If this field is nullable in this payload, set its payload # value to None. field_obj = self.fields.get(key) - if field_obj is not None and getattr(field_obj, 'nullable', - False): + if field_obj is not None and getattr(field_obj, "nullable", False): setattr(self, key, None) continue - raise exception.NotificationSchemaKeyError(obj=obj, - field=field, - key=key) + raise exception.NotificationSchemaKeyError( + obj=obj, field=field, key=key + ) except Exception: - raise exception.NotificationSchemaKeyError(obj=obj, - field=field, - key=key) + raise exception.NotificationSchemaKeyError( + obj=obj, field=field, key=key + ) self.populated = True def get_event_dict(self, event_type): return { - 'event_type': event_type, - 'event_time': datetime.now(), + "event_type": event_type, + "event_time": datetime.now(), } @versioned_objects_base.VersionedObjectRegistry.register class NotificationPublisher(base.ESILEAPObject): # Version 1.0: Initial version - VERSION = '1.0' + VERSION = "1.0" fields = { - 'service': fields.StringField(nullable=False), - 'host': fields.StringField(nullable=False) + "service": fields.StringField(nullable=False), + "host": fields.StringField(nullable=False), } diff --git a/esi_leap/objects/offer.py b/esi_leap/objects/offer.py index ce4c4880..a6d9b8a5 100644 --- a/esi_leap/objects/offer.py +++ b/esi_leap/objects/offer.py @@ -34,18 +34,18 @@ class Offer(base.ESILEAPObject): dbapi = dbapi.get_instance() fields = { - 'id': fields.IntegerField(), - 'name': fields.StringField(nullable=True), - 'uuid': fields.UUIDField(), - 'project_id': fields.StringField(), - 'lessee_id': fields.StringField(nullable=True), - 'resource_type': fields.StringField(), - 'resource_uuid': fields.StringField(), - 'start_time': fields.DateTimeField(nullable=True), - 'end_time': fields.DateTimeField(nullable=True), - 'status': fields.StringField(), - 'properties': fields.FlexibleDictField(nullable=True), - 'parent_lease_uuid': fields.UUIDField(nullable=True), + "id": fields.IntegerField(), + "name": fields.StringField(nullable=True), + "uuid": fields.UUIDField(), + "project_id": fields.StringField(), + "lessee_id": fields.StringField(nullable=True), + "resource_type": fields.StringField(), + "resource_uuid": fields.StringField(), + "start_time": fields.DateTimeField(nullable=True), + "end_time": fields.DateTimeField(nullable=True), + "status": fields.StringField(), + "properties": fields.FlexibleDictField(nullable=True), + "parent_lease_uuid": fields.UUIDField(nullable=True), } @classmethod @@ -60,7 +60,6 @@ def get_all(cls, filters, context=None): return cls._from_db_object_list(context, db_offers) def get_availabilities(self): - if self.status != statuses.AVAILABLE: return [] @@ -88,9 +87,10 @@ def get_availabilities(self): # Find the conflict timeframe that started # in the past and will end in the future. # add all times after this - if (conflicts[i][0] <= start_time and - conflicts[i][1] > start_time) \ - or conflicts[i][0] > start_time: + if ( + conflicts[i][0] <= start_time + and conflicts[i][1] > start_time + ) or conflicts[i][0] > start_time: times.append(conflicts[i][1]) times.append(conflicts[i + 1][0]) @@ -105,8 +105,7 @@ def get_availabilities(self): else: i += 1 - avails = [[times[j], times[j + 1]] - for j in range(0, len(times) - 1, 2)] + avails = [[times[j], times[j + 1]] for j in range(0, len(times) - 1, 2)] else: avails = [[start_time, self.end_time]] @@ -114,76 +113,76 @@ def get_availabilities(self): return avails def get_next_lease_start_time(self, start): - return self.dbapi.offer_get_next_lease_start_time( - self.uuid, start) + return self.dbapi.offer_get_next_lease_start_time(self.uuid, start) def create(self, context=None): updates = self.obj_get_changes() - with utils.lock(utils.get_resource_lock_name(updates['resource_type'], - updates['resource_uuid']), - external=True): - LOG.info('Creating offer') - if updates['start_time'] >= updates['end_time']: + with utils.lock( + utils.get_resource_lock_name( + updates["resource_type"], updates["resource_uuid"] + ), + external=True, + ): + LOG.info("Creating offer") + if updates["start_time"] >= updates["end_time"]: raise exception.InvalidTimeRange( - resource='offer', - start_time=str(updates['start_time']), - end_time=str(updates['end_time']) + resource="offer", + start_time=str(updates["start_time"]), + end_time=str(updates["end_time"]), ) - if updates.get('parent_lease_uuid'): + if updates.get("parent_lease_uuid"): # offer is a child of an existing lease - parent_lease = lease_obj.Lease.get( - updates['parent_lease_uuid']) + parent_lease = lease_obj.Lease.get(updates["parent_lease_uuid"]) if parent_lease.status != statuses.ACTIVE: - raise exception.LeaseNotActive( - updates['parent_lease_uuid']) + raise exception.LeaseNotActive(updates["parent_lease_uuid"]) - parent_lease.verify_child_availability(updates['start_time'], - updates['end_time']) + parent_lease.verify_child_availability( + updates["start_time"], updates["end_time"] + ) else: - ro = get_resource_object(updates['resource_type'], - updates['resource_uuid']) - ro.verify_availability(updates['start_time'], - updates['end_time']) + ro = get_resource_object( + updates["resource_type"], updates["resource_uuid"] + ) + ro.verify_availability(updates["start_time"], updates["end_time"]) db_offer = self.dbapi.offer_create(updates) self._from_db_object(context, self, db_offer) def cancel(self): - LOG.info('Deleting offer %s', self.uuid) + LOG.info("Deleting offer %s", self.uuid) leases = lease_obj.Lease.get_all( - {'offer_uuid': self.uuid, - 'status': statuses.LEASE_CAN_DELETE}, - None) + {"offer_uuid": self.uuid, "status": statuses.LEASE_CAN_DELETE}, None + ) for lease in leases: lease.cancel() - with utils.lock(utils.get_resource_lock_name(self.resource_type, - self.resource_uuid), - external=True): + with utils.lock( + utils.get_resource_lock_name(self.resource_type, self.resource_uuid), + external=True, + ): self.status = statuses.DELETED self.save(None) def expire(self, context=None): - LOG.info('Expiring offer %s', self.uuid) + LOG.info("Expiring offer %s", self.uuid) leases = lease_obj.Lease.get_all( - {'offer_uuid': self.uuid, - 'status': statuses.LEASE_CAN_DELETE}, - None) + {"offer_uuid": self.uuid, "status": statuses.LEASE_CAN_DELETE}, None + ) for lease in leases: lease.expire(context) - with utils.lock(utils.get_resource_lock_name(self.resource_type, - self.resource_uuid), - external=True): + with utils.lock( + utils.get_resource_lock_name(self.resource_type, self.resource_uuid), + external=True, + ): self.status = statuses.EXPIRED self.save(context) def verify_availability(self, start_time, end_time): - return self.dbapi.offer_verify_availability( - self, start_time, end_time) + return self.dbapi.offer_verify_availability(self, start_time, end_time) def destroy(self): self.dbapi.offer_destroy(self.uuid) @@ -191,8 +190,7 @@ def destroy(self): def save(self, context=None): updates = self.obj_get_changes() - db_offer = self.dbapi.offer_update( - self.uuid, updates) + db_offer = self.dbapi.offer_update(self.uuid, updates) self._from_db_object(context, self, db_offer) def resource_object(self): diff --git a/esi_leap/resource_objects/__init__.py b/esi_leap/resource_objects/__init__.py index a21ce533..aaa60380 100644 --- a/esi_leap/resource_objects/__init__.py +++ b/esi_leap/resource_objects/__init__.py @@ -11,6 +11,7 @@ # under the License. from esi_leap.common.exception import ResourceTypeUnknown from esi_leap.resource_objects import base + # types derived from base won't show as subclasses unless imported somewhere from esi_leap.resource_objects import dummy_node # noqa: F401 from esi_leap.resource_objects import ironic_node # noqa: F401 @@ -18,8 +19,8 @@ _RESOURCE_TYPE_MAP = { - typ.resource_type: typ for typ in - base.ResourceObjectInterface.__subclasses__()} + typ.resource_type: typ for typ in base.ResourceObjectInterface.__subclasses__() +} RESOURCE_TYPES = tuple(_RESOURCE_TYPE_MAP.keys()) diff --git a/esi_leap/resource_objects/base.py b/esi_leap/resource_objects/base.py index a015eace..a80eb964 100644 --- a/esi_leap/resource_objects/base.py +++ b/esi_leap/resource_objects/base.py @@ -18,7 +18,7 @@ class ResourceObjectInterface(object, metaclass=abc.ABCMeta): dbapi = dbapi.get_instance() - resource_type = 'base' + resource_type = "base" @abc.abstractmethod def get_uuid(self): diff --git a/esi_leap/resource_objects/dummy_node.py b/esi_leap/resource_objects/dummy_node.py index 55046dd2..29f20494 100644 --- a/esi_leap/resource_objects/dummy_node.py +++ b/esi_leap/resource_objects/dummy_node.py @@ -28,8 +28,7 @@ class DummyNode(base.ResourceObjectInterface): - - resource_type = 'dummy_node' + resource_type = "dummy_node" def __init__(self, uuid): self._uuid = uuid @@ -39,57 +38,77 @@ def get_uuid(self): return self._uuid def get_name(self, resource_list=None): - return 'dummy-node-%s' % self._uuid + return "dummy-node-%s" % self._uuid def get_resource_class(self, resource_list=None): - return self._get_node_attr('resource_class', '', - resource_list=resource_list, - err_msg='Error getting resource class', - err_val=error.UNKNOWN['resource_class']) + return self._get_node_attr( + "resource_class", + "", + resource_list=resource_list, + err_msg="Error getting resource class", + err_val=error.UNKNOWN["resource_class"], + ) def get_properties(self, resource_list=None): - return self._get_node_attr('properties', {}, - err_msg='Error getting resource properties', - err_val=error.UNKNOWN['properties']) + return self._get_node_attr( + "properties", + {}, + err_msg="Error getting resource properties", + err_val=error.UNKNOWN["properties"], + ) def get_owner_project_id(self): - return self._get_node_attr('project_owner_id', None, - err_msg='Error getting owner project id', - err_val=error.UNKNOWN['owner_project_id']) + return self._get_node_attr( + "project_owner_id", + None, + err_msg="Error getting owner project id", + err_val=error.UNKNOWN["owner_project_id"], + ) def get_lease_uuid(self): - return self._get_node_attr('lease_uuid', '', - err_msg='Error getting lease UUID', - err_val=error.UNKNOWN['lease_uuid']) + return self._get_node_attr( + "lease_uuid", + "", + err_msg="Error getting lease UUID", + err_val=error.UNKNOWN["lease_uuid"], + ) def get_lessee_project_id(self): - return self._get_node_attr('project_id', '', - err_msg='Error getting lessee project id', - err_val=error.UNKNOWN['lessee_project_id']) + return self._get_node_attr( + "project_id", + "", + err_msg="Error getting lessee project id", + err_val=error.UNKNOWN["lessee_project_id"], + ) def get_node_power_state(self): - return self._get_node_attr('power_state', '', - err_msg='Error getting node power state', - err_val=error.UNKNOWN['power_state']) + return self._get_node_attr( + "power_state", + "", + err_msg="Error getting node power state", + err_val=error.UNKNOWN["power_state"], + ) def get_node_provision_state(self): - return self._get_node_attr('provision_state', '', - err_msg='Error getting' - 'node provision state', - err_val=error.UNKNOWN['provision_state']) + return self._get_node_attr( + "provision_state", + "", + err_msg="Error getting" "node provision state", + err_val=error.UNKNOWN["provision_state"], + ) def set_lease(self, lease): node_dict = self._get_node() - node_dict['lease_uuid'] = lease.uuid - node_dict['project_id'] = lease.project_id - with open(self._path, 'w') as node_file: + node_dict["lease_uuid"] = lease.uuid + node_dict["project_id"] = lease.project_id + with open(self._path, "w") as node_file: json.dump(node_dict, node_file) def remove_lease(self, lease): node_dict = self._get_node() - node_dict.pop('lease_uuid', None) - node_dict.pop('project_id', None) - with open(self._path, 'w') as node_file: + node_dict.pop("lease_uuid", None) + node_dict.pop("project_id", None) + with open(self._path, "w") as node_file: json.dump(node_dict, node_file) def _get_node(self): @@ -97,12 +116,13 @@ def _get_node(self): with open(self._path) as node_file: return json.load(node_file) except FileNotFoundError as e: - raise exception.NodeNotFound(uuid=self._uuid, - resource_type=self.resource_type, - err=str(e)) + raise exception.NodeNotFound( + uuid=self._uuid, resource_type=self.resource_type, err=str(e) + ) - def _get_node_attr(self, attr, default=None, resource_list=None, - err_val=None, err_msg=None): + def _get_node_attr( + self, attr, default=None, resource_list=None, err_val=None, err_msg=None + ): try: return self._get_node().get(attr, default) except exception.NodeNotFound: diff --git a/esi_leap/resource_objects/error.py b/esi_leap/resource_objects/error.py index 454d6441..2b531c94 100644 --- a/esi_leap/resource_objects/error.py +++ b/esi_leap/resource_objects/error.py @@ -11,13 +11,13 @@ # under the License. UNKNOWN = { - 'uuid': 'unknown-uuid', - 'name': 'unknown-name', - 'resource_class': 'unknown-class', - 'properties': {}, - 'owner_project_id': 'unknown-owner', - 'lease_uuid': 'unknown-lease', - 'lessee_project_id': 'unknown-lessee', - 'provision_state': 'unknown-provision-state', - 'power_state': 'unknown-power-state' + "uuid": "unknown-uuid", + "name": "unknown-name", + "resource_class": "unknown-class", + "properties": {}, + "owner_project_id": "unknown-owner", + "lease_uuid": "unknown-lease", + "lessee_project_id": "unknown-lessee", + "provision_state": "unknown-provision-state", + "power_state": "unknown-power-state", } diff --git a/esi_leap/resource_objects/ironic_node.py b/esi_leap/resource_objects/ironic_node.py index fa8e02ea..7eeb8464 100644 --- a/esi_leap/resource_objects/ironic_node.py +++ b/esi_leap/resource_objects/ironic_node.py @@ -35,8 +35,7 @@ def get_ironic_client(): class IronicNode(base.ResourceObjectInterface): - - resource_type = 'ironic_node' + resource_type = "ironic_node" def __init__(self, ident): if not is_uuid_like(ident): @@ -50,62 +49,90 @@ def get_uuid(self): return self._uuid def get_name(self, resource_list=None): - return self._get_node_attr('name', '', - resource_list=resource_list, - err_msg='Error getting resource name', - err_val=error.UNKNOWN['name']) + return self._get_node_attr( + "name", + "", + resource_list=resource_list, + err_msg="Error getting resource name", + err_val=error.UNKNOWN["name"], + ) def get_resource_class(self, resource_list=None): - return self._get_node_attr('resource_class', '', - resource_list=resource_list, - err_msg='Error getting resource class', - err_val=error.UNKNOWN['resource_class']) + return self._get_node_attr( + "resource_class", + "", + resource_list=resource_list, + err_msg="Error getting resource class", + err_val=error.UNKNOWN["resource_class"], + ) def get_properties(self, resource_list=None): properties = self._get_node_attr( - 'properties', {}, resource_list=resource_list, - err_msg='Error getting resource properties', - err_val=error.UNKNOWN['properties']) + "properties", + {}, + resource_list=resource_list, + err_msg="Error getting resource properties", + err_val=error.UNKNOWN["properties"], + ) return ironic.get_condensed_properties(properties) def get_owner_project_id(self): - return self._get_node_attr('owner', '', - err_msg='Error getting owner project id', - err_val=error.UNKNOWN['owner_project_id']) + return self._get_node_attr( + "owner", + "", + err_msg="Error getting owner project id", + err_val=error.UNKNOWN["owner_project_id"], + ) def get_lease_uuid(self): - props = self._get_node_attr('properties', None, - err_msg='Error getting lease UUID', - err_val=error.UNKNOWN['lease_uuid']) - return None if props is None else props.get('lease_uuid', None) + props = self._get_node_attr( + "properties", + None, + err_msg="Error getting lease UUID", + err_val=error.UNKNOWN["lease_uuid"], + ) + return None if props is None else props.get("lease_uuid", None) def get_lessee_project_id(self): - return self._get_node_attr('lessee', '', - err_msg='Error getting lessee project id', - err_val=error.UNKNOWN['lessee_project_id']) + return self._get_node_attr( + "lessee", + "", + err_msg="Error getting lessee project id", + err_val=error.UNKNOWN["lessee_project_id"], + ) def get_node_provision_state(self): - return self._get_node_attr('provision_state', '', - err_msg='Error getting provision state', - err_val=error.UNKNOWN['provision_state']) + return self._get_node_attr( + "provision_state", + "", + err_msg="Error getting provision state", + err_val=error.UNKNOWN["provision_state"], + ) def get_node_power_state(self): - return self._get_node_attr('power_state', '', - err_msg='Error getting power state', - err_val=error.UNKNOWN['power_state']) + return self._get_node_attr( + "power_state", + "", + err_msg="Error getting power state", + err_val=error.UNKNOWN["power_state"], + ) def set_lease(self, lease): patches = [] - patches.append({ - 'op': 'add', - 'path': '/properties/lease_uuid', - 'value': lease.uuid, - }) - patches.append({ - 'op': 'add', - 'path': '/lessee', - 'value': lease.project_id, - }) + patches.append( + { + "op": "add", + "path": "/properties/lease_uuid", + "value": lease.uuid, + } + ) + patches.append( + { + "op": "add", + "path": "/lessee", + "value": lease.project_id, + } + ) get_ironic_client().node.update(self._uuid, patches) def remove_lease(self, lease): @@ -114,33 +141,38 @@ def remove_lease(self, lease): if uuid != lease.uuid: return if uuid: - patches.append({ - 'op': 'remove', - 'path': '/properties/lease_uuid', - }) + patches.append( + { + "op": "remove", + "path": "/properties/lease_uuid", + } + ) if self.get_lessee_project_id(): - patches.append({ - 'op': 'remove', - 'path': '/lessee', - }) + patches.append( + { + "op": "remove", + "path": "/lessee", + } + ) if len(patches) > 0: get_ironic_client().node.update(self._uuid, patches) state = self._get_node().provision_state - if state == 'active': - get_ironic_client().node.set_provision_state(self._uuid, 'deleted') + if state == "active": + get_ironic_client().node.set_provision_state(self._uuid, "deleted") def _get_node(self, resource_list=None): try: if not self._node: self._node = ironic.get_node(self._uuid, resource_list) except ir_exception.NotFound as e: - raise exception.NodeNotFound(uuid=self._uuid, - resource_type=self.resource_type, - err=str(e)) + raise exception.NodeNotFound( + uuid=self._uuid, resource_type=self.resource_type, err=str(e) + ) return self._node - def _get_node_attr(self, attr, default=None, resource_list=None, - err_val=None, err_msg=None): + def _get_node_attr( + self, attr, default=None, resource_list=None, err_val=None, err_msg=None + ): try: return getattr(self._get_node(resource_list), attr, default) except exception.NodeNotFound: diff --git a/esi_leap/resource_objects/test_node.py b/esi_leap/resource_objects/test_node.py index b01ed3ff..1e07a721 100644 --- a/esi_leap/resource_objects/test_node.py +++ b/esi_leap/resource_objects/test_node.py @@ -14,10 +14,9 @@ class TestNode(base.ResourceObjectInterface): + resource_type = "test_node" - resource_type = 'test_node' - - def __init__(self, uuid, project_id='12345'): + def __init__(self, uuid, project_id="12345"): self._uuid = uuid self._project_id = project_id @@ -25,10 +24,10 @@ def get_uuid(self): return self._uuid def get_name(self, resource_list=None): - return 'test-node-%s' % self._uuid + return "test-node-%s" % self._uuid def get_resource_class(self, resource_list=None): - return 'fake' + return "fake" def get_properties(self, resource_list=None): return {} @@ -37,16 +36,16 @@ def get_owner_project_id(self): return self._project_id def get_lease_uuid(self): - return '12345' + return "12345" def get_lessee_project_id(self): return self._project_id def get_node_power_state(self): - return 'Off' + return "Off" def get_node_provision_state(self): - return 'available' + return "available" def set_lease(self, lease): return diff --git a/esi_leap/send_email_notification.py b/esi_leap/send_email_notification.py index c0d2aed9..c289d26f 100755 --- a/esi_leap/send_email_notification.py +++ b/esi_leap/send_email_notification.py @@ -51,12 +51,12 @@ import importlib_resources -base_package = __name__.split('.')[0] +base_package = __name__.split(".")[0] -enable_email = os.getenv('ENABLE_EMAIL', 'false').lower() == 'true' -smtp_server = os.getenv('SMTP_SERVER', 'localhost') -email_sender = os.getenv('EMAIL_SENDER') -lease_warning_days = int(os.getenv('LEASE_WARNING_DAYS', 1)) +enable_email = os.getenv("ENABLE_EMAIL", "false").lower() == "true" +smtp_server = os.getenv("SMTP_SERVER", "localhost") +email_sender = os.getenv("EMAIL_SENDER") +lease_warning_days = int(os.getenv("LEASE_WARNING_DAYS", 1)) def get_template_path(default_template_path, env_var): @@ -64,16 +64,15 @@ def get_template_path(default_template_path, env_var): if custom_path: return custom_path else: - return importlib_resources.files(base_package).\ - joinpath(default_template_path) + return importlib_resources.files(base_package).joinpath(default_template_path) def run_openstack_command(cmd): - output_json = subprocess.check_output('%s --format json' % cmd, shell=True) + output_json = subprocess.check_output("%s --format json" % cmd, shell=True) return json.loads(output_json) -def get_last_event_id(default_last_event_id=0, file_name='.esi-last-event-id'): +def get_last_event_id(default_last_event_id=0, file_name=".esi-last-event-id"): try: with open(file_name, "r") as f: last_event_id = int(f.read()) @@ -84,38 +83,37 @@ def get_last_event_id(default_last_event_id=0, file_name='.esi-last-event-id'): return last_event_id -def write_last_event_id(last_event_id, file_name='.esi-last-event-id'): +def write_last_event_id(last_event_id, file_name=".esi-last-event-id"): with open(file_name, "w") as f: f.write(str(last_event_id)) def notify_lease(project_name, email_body): try: - project = run_openstack_command('openstack project show %s' - % project_name) - to_email = project.get('email') + project = run_openstack_command("openstack project show %s" % project_name) + to_email = project.get("email") if not to_email: - print('No email linked to project %s. ' - 'Not sending email notification' % project) + print( + "No email linked to project %s. " + "Not sending email notification" % project + ) else: msg = MIMEMultipart() - msg['From'] = email_sender - msg['To'] = to_email - msg['Subject'] = '[ESI]Lease notification' - msg.attach(MIMEText(email_body, 'plain')) + msg["From"] = email_sender + msg["To"] = to_email + msg["Subject"] = "[ESI]Lease notification" + msg.attach(MIMEText(email_body, "plain")) server = smtplib.SMTP(smtp_server) - server.sendmail(email_sender, to_email, - msg.as_string()) + server.sendmail(email_sender, to_email, msg.as_string()) server.quit() print("Email sent successfully to %s" % to_email) except Exception as e: - print('Email not sent: %s: %s' % - (type(e).__name__, e)) + print("Email not sent: %s: %s" % (type(e).__name__, e)) def fill_email_template(template_path, **kwargs): try: - with open(template_path, 'r') as f: + with open(template_path, "r") as f: content = f.read() return content.format(**kwargs) except FileNotFoundError: @@ -125,52 +123,58 @@ def fill_email_template(template_path, **kwargs): def main(): last_event_id = get_last_event_id() events = run_openstack_command( - 'openstack esi event list --last-event-id %s' % last_event_id) + "openstack esi event list --last-event-id %s" % last_event_id + ) new_last_event_id = last_event_id # checking for leases fulfillment for event in events: - new_last_event_id = event['ID'] - if event['Event Type'] == 'esi_leap.lease.fulfill.end': - node_uuid = event['Resource UUID'] - lease_uuid = event['Object UUID'] - lease = run_openstack_command('openstack esi lease show %s' - % lease_uuid) - print("Lease %s with purpose %s on node %s started" - % (lease_uuid, lease['purpose'], node_uuid)) + new_last_event_id = event["ID"] + if event["Event Type"] == "esi_leap.lease.fulfill.end": + node_uuid = event["Resource UUID"] + lease_uuid = event["Object UUID"] + lease = run_openstack_command("openstack esi lease show %s" % lease_uuid) + print( + "Lease %s with purpose %s on node %s started" + % (lease_uuid, lease["purpose"], node_uuid) + ) if enable_email: lease_create_template_path = get_template_path( - 'templates/lease_create_email.txt', - 'LEASE_CREATE_TEMPLATE') + "templates/lease_create_email.txt", "LEASE_CREATE_TEMPLATE" + ) email_body_lease_start = fill_email_template( lease_create_template_path, - project=lease['project'], - lease_uuid=lease['uuid'], - start_time=lease['start_time'], - end_time=lease['end_time'], - node_name=lease['resource'], - node_uuid=lease['resource_uuid']) - notify_lease(lease['project'], email_body_lease_start) + project=lease["project"], + lease_uuid=lease["uuid"], + start_time=lease["start_time"], + end_time=lease["end_time"], + node_name=lease["resource"], + node_uuid=lease["resource_uuid"], + ) + notify_lease(lease["project"], email_body_lease_start) write_last_event_id(new_last_event_id) # Checking for leases expire soon - leases = run_openstack_command('openstack esi lease list --all') + leases = run_openstack_command("openstack esi lease list --all") now = datetime.datetime.utcnow() for lease in leases: lease_end = parser.parse(lease["End Time"]) if lease_end - now <= datetime.timedelta(lease_warning_days): - print('Lease %s is expiring in %s day(s)' - % (lease["UUID"], lease_warning_days)) + print( + "Lease %s is expiring in %s day(s)" + % (lease["UUID"], lease_warning_days) + ) if enable_email: lease_expire_template_path = get_template_path( - 'templates/lease_expire_email.txt', - 'LEASE_EXPIRE_TEMPLATE') + "templates/lease_expire_email.txt", "LEASE_EXPIRE_TEMPLATE" + ) email_body_lease_expire = fill_email_template( lease_expire_template_path, - project=lease['Project'], - lease_uuid=lease['UUID'], - end_time=lease['End Time'], - node_name=lease['Resource']) - notify_lease(lease['Project'], email_body_lease_expire) + project=lease["Project"], + lease_uuid=lease["UUID"], + end_time=lease["End Time"], + node_name=lease["Resource"], + ) + notify_lease(lease["Project"], email_body_lease_expire) if __name__ == "__main__": diff --git a/esi_leap/templates/lease_create_email.txt b/esi_leap/templates/lease_create_email.txt index 5e455b71..f4d53bf3 100644 --- a/esi_leap/templates/lease_create_email.txt +++ b/esi_leap/templates/lease_create_email.txt @@ -9,4 +9,4 @@ We would like to inform you that your lease: {lease_uuid} has started. Below are Best Regards, -ESI Admin Team \ No newline at end of file +ESI Admin Team diff --git a/esi_leap/templates/lease_expire_email.txt b/esi_leap/templates/lease_expire_email.txt index 98264ab3..b14c29a8 100644 --- a/esi_leap/templates/lease_expire_email.txt +++ b/esi_leap/templates/lease_expire_email.txt @@ -11,4 +11,4 @@ To ensure the continuity of your data, please take the following steps: Thank you! -ESI Admin Team \ No newline at end of file +ESI Admin Team diff --git a/esi_leap/tests/api/base.py b/esi_leap/tests/api/base.py index 1380a8eb..50ec4244 100644 --- a/esi_leap/tests/api/base.py +++ b/esi_leap/tests/api/base.py @@ -21,30 +21,37 @@ CONF = esi_leap.conf.CONF -PATH_PREFIX = '/v1' +PATH_PREFIX = "/v1" class APITestCase(base.DBTestCase): - def setUp(self): super(APITestCase, self).setUp() - CONF.set_override('auth_enable', False, group='pecan') + CONF.set_override("auth_enable", False, group="pecan") self.app = pecan.testing.load_test_app(dict(app.get_pecan_config())) self.patch_context = mock.patch( - 'oslo_context.context.RequestContext.from_environ') + "oslo_context.context.RequestContext.from_environ" + ) self.mock_context = self.patch_context.start() self.addCleanup(self.patch_context.stop) self.mock_context.return_value = self.context - self.config(lock_path=tempfile.mkdtemp(), group='oslo_concurrency') + self.config(lock_path=tempfile.mkdtemp(), group="oslo_concurrency") # borrowed from Ironic - def get_json(self, path, expect_errors=False, headers=None, - extra_environ=None, q=None, path_prefix=PATH_PREFIX, - **params): + def get_json( + self, + path, + expect_errors=False, + headers=None, + extra_environ=None, + q=None, + path_prefix=PATH_PREFIX, + **params, + ): """Sends simulated HTTP GET request to Pecan test app. :param path: url path of target service @@ -60,28 +67,35 @@ def get_json(self, path, expect_errors=False, headers=None, """ q = q if q is not None else [] full_path = path_prefix + path - query_params = {'q.field': [], - 'q.value': [], - 'q.op': []} + query_params = {"q.field": [], "q.value": [], "q.op": []} for query in q: - for name in ['field', 'op', 'value']: - query_params['q.%s' % name].append(query.get(name, '')) + for name in ["field", "op", "value"]: + query_params["q.%s" % name].append(query.get(name, "")) all_params = {} all_params.update(params) if q: all_params.update(query_params) - response = self.app.get(full_path, - params=all_params, - headers=headers, - extra_environ=extra_environ, - expect_errors=expect_errors) + response = self.app.get( + full_path, + params=all_params, + headers=headers, + extra_environ=extra_environ, + expect_errors=expect_errors, + ) if not expect_errors: response = response.json return response # borrowed from Ironic - def post_json(self, path, params, expect_errors=False, headers=None, - extra_environ=None, status=None): + def post_json( + self, + path, + params, + expect_errors=False, + headers=None, + extra_environ=None, + status=None, + ): """Sends simulated HTTP POST request to Pecan test app. :param path: url path of target service @@ -93,14 +107,26 @@ def post_json(self, path, params, expect_errors=False, headers=None, with the request :param status: expected status code of response """ - return self._request_json(path=path, params=params, - expect_errors=expect_errors, - headers=headers, extra_environ=extra_environ, - status=status, method='post') + return self._request_json( + path=path, + params=params, + expect_errors=expect_errors, + headers=headers, + extra_environ=extra_environ, + status=status, + method="post", + ) # borrowed from Ironic - def patch_json(self, path, params, expect_errors=False, headers=None, - extra_environ=None, status=None): + def patch_json( + self, + path, + params, + expect_errors=False, + headers=None, + extra_environ=None, + status=None, + ): """Sends simulated HTTP PATCH request to Pecan test app. :param path: url path of target service @@ -112,14 +138,20 @@ def patch_json(self, path, params, expect_errors=False, headers=None, with the request :param status: expected status code of response """ - return self._request_json(path=path, params=params, - expect_errors=expect_errors, - headers=headers, extra_environ=extra_environ, - status=status, method='patch') + return self._request_json( + path=path, + params=params, + expect_errors=expect_errors, + headers=headers, + extra_environ=extra_environ, + status=status, + method="patch", + ) # borrowed from Ironic - def delete_json(self, path, expect_errors=False, headers=None, - extra_environ=None, status=None): + def delete_json( + self, path, expect_errors=False, headers=None, extra_environ=None, status=None + ): """Sends simulated HTTP POST request to Pecan test app. :param path: url path of target service @@ -130,15 +162,28 @@ def delete_json(self, path, expect_errors=False, headers=None, with the request :param status: expected status code of response """ - return self._request_json(path=path, params={}, - expect_errors=expect_errors, - headers=headers, extra_environ=extra_environ, - status=status, method='delete') + return self._request_json( + path=path, + params={}, + expect_errors=expect_errors, + headers=headers, + extra_environ=extra_environ, + status=status, + method="delete", + ) # borrowed from Ironic - def _request_json(self, path, params, expect_errors=False, headers=None, - method='post', extra_environ=None, status=None, - path_prefix=PATH_PREFIX): + def _request_json( + self, + path, + params, + expect_errors=False, + headers=None, + method="post", + extra_environ=None, + status=None, + path_prefix=PATH_PREFIX, + ): """Sends simulated HTTP request to Pecan test app. :param path: url path of target service @@ -155,12 +200,12 @@ def _request_json(self, path, params, expect_errors=False, headers=None, """ full_path = path_prefix + path - response = getattr(self.app, '%s_json' % method)( + response = getattr(self.app, "%s_json" % method)( str(full_path), params=params, headers=headers, status=status, extra_environ=extra_environ, - expect_errors=expect_errors + expect_errors=expect_errors, ) return response diff --git a/esi_leap/tests/api/controllers/test_types.py b/esi_leap/tests/api/controllers/test_types.py index 0b6b05ae..48f6bcec 100644 --- a/esi_leap/tests/api/controllers/test_types.py +++ b/esi_leap/tests/api/controllers/test_types.py @@ -17,24 +17,24 @@ class TestCollection(unittest.TestCase): - def setUp(self): self.test_collection = types.Collection() - self.test_collection._type = 'stuff' - self.obj1 = mock.Mock(uuid='aaaaa') - self.obj2 = mock.Mock(uuid='bbbbb') - self.obj3 = mock.Mock(uuid='ccccc') + self.test_collection._type = "stuff" + self.obj1 = mock.Mock(uuid="aaaaa") + self.obj2 = mock.Mock(uuid="bbbbb") + self.obj3 = mock.Mock(uuid="ccccc") self.test_collection.stuff = [self.obj1, self.obj2, self.obj3] - self._type = 'url' + self._type = "url" def test_has_next(self): self.assertEqual(self.test_collection.has_next(3), True) self.assertEqual(self.test_collection.has_next(0), False) def test_get_next(self): - kwargs = {'key1': 'Things', 'key2': 'Stuff'} - link = ("{{'key1': 'Things', 'key2': 'Stuff'}}" - "/v1/stuff?limit=3&marker={0}".format(self.obj3.uuid)) - self.assertEqual(self.test_collection.get_next(2, kwargs), - wtypes.Unset) + kwargs = {"key1": "Things", "key2": "Stuff"} + link = ( + "{{'key1': 'Things', 'key2': 'Stuff'}}" + "/v1/stuff?limit=3&marker={0}".format(self.obj3.uuid) + ) + self.assertEqual(self.test_collection.get_next(2, kwargs), wtypes.Unset) self.assertEqual(self.test_collection.get_next(3, kwargs), link) diff --git a/esi_leap/tests/api/controllers/v1/test_event.py b/esi_leap/tests/api/controllers/v1/test_event.py index 5c88bb75..1dc7adba 100644 --- a/esi_leap/tests/api/controllers/v1/test_event.py +++ b/esi_leap/tests/api/controllers/v1/test_event.py @@ -21,80 +21,75 @@ class FakeEvent(object): def __init__(self): self.id = 1 - self.event_type = 'fake:event' + self.event_type = "fake:event" self.event_time = datetime.now() - self.object_type = 'lease' - self.object_uuid = 'fake-lease-uuid' - self.resource_type = 'fake_node' - self.resource_uuid = 'fake-node-uuid' - self.lessee_id = 'fake-lessee-id' - self.owner_id = 'fake-owner-id' + self.object_type = "lease" + self.object_uuid = "fake-lease-uuid" + self.resource_type = "fake_node" + self.resource_uuid = "fake-node-uuid" + self.lessee_id = "fake-lessee-id" + self.owner_id = "fake-owner-id" class TestEventsController(test_api_base.APITestCase): - def setUp(self): super(TestEventsController, self).setUp() - @mock.patch('esi_leap.api.controllers.v1.utils.policy_authorize') - @mock.patch('esi_leap.common.keystone.get_project_uuid_from_ident') - @mock.patch('esi_leap.api.controllers.v1.event.get_resource_object') - @mock.patch('esi_leap.objects.event.Event.get_all') + @mock.patch("esi_leap.api.controllers.v1.utils.policy_authorize") + @mock.patch("esi_leap.common.keystone.get_project_uuid_from_ident") + @mock.patch("esi_leap.api.controllers.v1.event.get_resource_object") + @mock.patch("esi_leap.objects.event.Event.get_all") def test_get_all(self, mock_ega, mock_gro, mock_gpufi, mock_pa): fake_event = FakeEvent() expected_filters = {} mock_pa.side_effect = None mock_ega.return_value = [fake_event] - data = self.get_json('/events') + data = self.get_json("/events") mock_pa.assert_called_once() mock_gpufi.assert_not_called() mock_gro.assert_not_called() mock_ega.assert_called_once_with(expected_filters, self.context) - self.assertEqual(data['events'][0]['id'], 1) + self.assertEqual(data["events"][0]["id"], 1) - @mock.patch('esi_leap.api.controllers.v1.utils.policy_authorize') - @mock.patch('esi_leap.common.keystone.get_project_uuid_from_ident') - @mock.patch('esi_leap.api.controllers.v1.event.get_resource_object') - @mock.patch('esi_leap.objects.event.Event.get_all') + @mock.patch("esi_leap.api.controllers.v1.utils.policy_authorize") + @mock.patch("esi_leap.common.keystone.get_project_uuid_from_ident") + @mock.patch("esi_leap.api.controllers.v1.event.get_resource_object") + @mock.patch("esi_leap.objects.event.Event.get_all") def test_get_all_not_admin(self, mock_ega, mock_gro, mock_gpufi, mock_pa): fake_event = FakeEvent() - expected_filters = {'lessee_or_owner_id': 'fake-lessee-id'} - mock_pa.side_effect = exception.HTTPForbidden( - rule='esi_leap:offer:offer_admin') - mock_gpufi.return_value = 'fake-lessee-id' + expected_filters = {"lessee_or_owner_id": "fake-lessee-id"} + mock_pa.side_effect = exception.HTTPForbidden(rule="esi_leap:offer:offer_admin") + mock_gpufi.return_value = "fake-lessee-id" mock_ega.return_value = [fake_event] - data = self.get_json('/events') + data = self.get_json("/events") mock_pa.assert_called_once() mock_gpufi.assert_called_once() mock_gro.assert_not_called() mock_ega.assert_called_once_with(expected_filters, self.context) - self.assertEqual(data['events'][0]['id'], 1) + self.assertEqual(data["events"][0]["id"], 1) - @mock.patch('esi_leap.api.controllers.v1.utils.policy_authorize') - @mock.patch('esi_leap.common.keystone.get_project_uuid_from_ident') - @mock.patch('esi_leap.api.controllers.v1.event.get_resource_object') - @mock.patch('esi_leap.objects.event.Event.get_all') - def test_get_all_resource_filter(self, mock_ega, mock_gro, mock_gpufi, - mock_pa): + @mock.patch("esi_leap.api.controllers.v1.utils.policy_authorize") + @mock.patch("esi_leap.common.keystone.get_project_uuid_from_ident") + @mock.patch("esi_leap.api.controllers.v1.event.get_resource_object") + @mock.patch("esi_leap.objects.event.Event.get_all") + def test_get_all_resource_filter(self, mock_ega, mock_gro, mock_gpufi, mock_pa): fake_event = FakeEvent() - expected_filters = {'resource_type': 'test_node', - 'resource_uuid': '1111'} + expected_filters = {"resource_type": "test_node", "resource_uuid": "1111"} mock_pa.side_effect = None - mock_gro.return_value = TestNode('1111') + mock_gro.return_value = TestNode("1111") mock_ega.return_value = [fake_event] - data = self.get_json( - '/events?resource_uuid=1111&resource_type=test_node') + data = self.get_json("/events?resource_uuid=1111&resource_type=test_node") mock_pa.assert_called_once() mock_gpufi.assert_not_called() - mock_gro.assert_called_with('test_node', '1111') + mock_gro.assert_called_with("test_node", "1111") mock_ega.assert_called_once_with(expected_filters, self.context) - self.assertEqual(data['events'][0]['id'], 1) + self.assertEqual(data["events"][0]["id"], 1) diff --git a/esi_leap/tests/api/controllers/v1/test_lease.py b/esi_leap/tests/api/controllers/v1/test_lease.py index 4cbf373d..f4c8f4ac 100644 --- a/esi_leap/tests/api/controllers/v1/test_lease.py +++ b/esi_leap/tests/api/controllers/v1/test_lease.py @@ -28,7 +28,6 @@ class TestLeasesController(test_api_base.APITestCase): - def setUp(self): super(TestLeasesController, self).setUp() @@ -36,500 +35,509 @@ def setUp(self): start_time=datetime.datetime(2016, 7, 16, 19, 20, 30), end_time=datetime.datetime(2016, 8, 16, 19, 20, 30), uuid=uuidutils.generate_uuid(), - resource_type='test_node', - resource_uuid='111', - project_id='lesseeid', - owner_id='ownerid', - parent_lease_uuid=None + resource_type="test_node", + resource_uuid="111", + project_id="lesseeid", + owner_id="ownerid", + parent_lease_uuid=None, ) self.test_lease_1 = lease_obj.Lease( start_time=datetime.datetime(2016, 7, 16, 19, 20, 30), end_time=datetime.datetime(2016, 8, 16, 19, 20, 30), uuid=uuidutils.generate_uuid(), - resource_type='ironic_node', - resource_uuid='222', - project_id='lesseeid', - owner_id='ownerid', - parent_lease_uuid=None + resource_type="ironic_node", + resource_uuid="222", + project_id="lesseeid", + owner_id="ownerid", + parent_lease_uuid=None, ) self.test_lease_with_parent = lease_obj.Lease( start_time=datetime.datetime(2016, 7, 16, 19, 20, 30), end_time=datetime.datetime(2016, 8, 16, 19, 20, 30), uuid=uuidutils.generate_uuid(), - resource_type='test_node', - resource_uuid='111', - project_id='lesseeid', - owner_id='ownerid', - parent_lease_uuid='parent-lease-uuid' + resource_type="test_node", + resource_uuid="111", + project_id="lesseeid", + owner_id="ownerid", + parent_lease_uuid="parent-lease-uuid", ) def test_empty(self): - data = self.get_json('/leases') - self.assertEqual([], data['leases']) - - @mock.patch('esi_leap.common.ironic.get_node_list') - @mock.patch('esi_leap.common.keystone.get_project_list') - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'lease_get_dict_with_added_info') - @mock.patch('esi_leap.objects.lease.Lease.get_all') + data = self.get_json("/leases") + self.assertEqual([], data["leases"]) + + @mock.patch("esi_leap.common.ironic.get_node_list") + @mock.patch("esi_leap.common.keystone.get_project_list") + @mock.patch("esi_leap.api.controllers.v1.utils." "lease_get_dict_with_added_info") + @mock.patch("esi_leap.objects.lease.Lease.get_all") def test_one(self, mock_ga, mock_lgdwai, mock_gpl, mock_gnl): mock_ga.return_value = [self.test_lease] mock_lgdwai.return_value = self.test_lease.to_dict() mock_gpl.return_value = [] mock_gnl.return_value = [] - data = self.get_json('/leases') + data = self.get_json("/leases") - self.assertEqual(self.test_lease.uuid, - data['leases'][0]['uuid']) + self.assertEqual(self.test_lease.uuid, data["leases"][0]["uuid"]) mock_gpl.assert_called_once() mock_gnl.assert_called_once() mock_lgdwai.assert_called_once() - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'lease_get_dict_with_added_info') - @mock.patch('esi_leap.api.controllers.v1.lease.get_resource_object') - @mock.patch('esi_leap.common.keystone.get_project_uuid_from_ident') - @mock.patch('oslo_utils.uuidutils.generate_uuid') - @mock.patch('esi_leap.api.controllers.v1.utils.check_resource_admin') - @mock.patch('esi_leap.objects.lease.Lease.create') - def test_post(self, mock_create, mock_cra, mock_generate_uuid, - mock_gpufi, mock_gro, mock_lgdwai): - resource = TestNode('1234567890') + @mock.patch("esi_leap.api.controllers.v1.utils." "lease_get_dict_with_added_info") + @mock.patch("esi_leap.api.controllers.v1.lease.get_resource_object") + @mock.patch("esi_leap.common.keystone.get_project_uuid_from_ident") + @mock.patch("oslo_utils.uuidutils.generate_uuid") + @mock.patch("esi_leap.api.controllers.v1.utils.check_resource_admin") + @mock.patch("esi_leap.objects.lease.Lease.create") + def test_post( + self, + mock_create, + mock_cra, + mock_generate_uuid, + mock_gpufi, + mock_gro, + mock_lgdwai, + ): + resource = TestNode("1234567890") data = { - 'project_id': 'lesseeid', - 'resource_type': 'test_node', - 'resource_uuid': '1234567890', - 'start_time': '2016-07-16T19:20:30', - 'end_time': '2016-08-16T19:20:30', - 'purpose': 'test_purpose' + "project_id": "lesseeid", + "resource_type": "test_node", + "resource_uuid": "1234567890", + "start_time": "2016-07-16T19:20:30", + "end_time": "2016-08-16T19:20:30", + "purpose": "test_purpose", } return_data = data.copy() - return_data['owner_id'] = self.context.project_id - return_data['uuid'] = self.test_lease.uuid + return_data["owner_id"] = self.context.project_id + return_data["uuid"] = self.test_lease.uuid lgdwai_return_data = return_data.copy() - lgdwai_return_data['start_time'] = datetime.datetime( - 2016, 7, 16, 19, 20, 30) - lgdwai_return_data['end_time'] = datetime.datetime( - 2016, 8, 16, 19, 20, 30) + lgdwai_return_data["start_time"] = datetime.datetime(2016, 7, 16, 19, 20, 30) + lgdwai_return_data["end_time"] = datetime.datetime(2016, 8, 16, 19, 20, 30) mock_gro.return_value = resource - mock_gpufi.return_value = 'lesseeid' + mock_gpufi.return_value = "lesseeid" mock_generate_uuid.return_value = self.test_lease.uuid mock_lgdwai.return_value = lgdwai_return_data - request = self.post_json('/leases', data) + request = self.post_json("/leases", data) - mock_gro.assert_called_once_with('test_node', '1234567890') + mock_gro.assert_called_once_with("test_node", "1234567890") mock_generate_uuid.assert_called_once() mock_cra.assert_called_once_with( - self.context.to_policy_values(), - resource, - self.context.project_id) + self.context.to_policy_values(), resource, self.context.project_id + ) mock_create.assert_called_once() mock_lgdwai.assert_called_once() self.assertEqual(return_data, request.json) self.assertEqual(http_client.CREATED, request.status_int) - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'lease_get_dict_with_added_info') - @mock.patch('esi_leap.api.controllers.v1.lease.get_resource_object') - @mock.patch('esi_leap.common.keystone.get_project_uuid_from_ident') - @mock.patch('oslo_utils.uuidutils.generate_uuid') - @mock.patch('esi_leap.api.controllers.v1.utils.check_resource_admin') - @mock.patch('esi_leap.objects.lease.Lease.create') - def test_post_default_resource_type(self, mock_create, mock_cra, - mock_generate_uuid, mock_gpufi, - mock_gro, mock_lgdwai): - resource = IronicNode('13921c8d-ce11-4b6d-99ed-10e19d184e5f') + @mock.patch("esi_leap.api.controllers.v1.utils." "lease_get_dict_with_added_info") + @mock.patch("esi_leap.api.controllers.v1.lease.get_resource_object") + @mock.patch("esi_leap.common.keystone.get_project_uuid_from_ident") + @mock.patch("oslo_utils.uuidutils.generate_uuid") + @mock.patch("esi_leap.api.controllers.v1.utils.check_resource_admin") + @mock.patch("esi_leap.objects.lease.Lease.create") + def test_post_default_resource_type( + self, + mock_create, + mock_cra, + mock_generate_uuid, + mock_gpufi, + mock_gro, + mock_lgdwai, + ): + resource = IronicNode("13921c8d-ce11-4b6d-99ed-10e19d184e5f") data = { - 'project_id': 'lesseeid', - 'resource_uuid': '1234567890', - 'start_time': '2016-07-16T19:20:30', - 'end_time': '2016-08-16T19:20:30' + "project_id": "lesseeid", + "resource_uuid": "1234567890", + "start_time": "2016-07-16T19:20:30", + "end_time": "2016-08-16T19:20:30", } return_data = data.copy() - return_data['resource_type'] = 'ironic_node' - return_data['owner_id'] = self.context.project_id - return_data['uuid'] = self.test_lease.uuid + return_data["resource_type"] = "ironic_node" + return_data["owner_id"] = self.context.project_id + return_data["uuid"] = self.test_lease.uuid lgdwai_return_data = return_data.copy() - lgdwai_return_data['start_time'] = datetime.datetime( - 2016, 7, 16, 19, 20, 30) - lgdwai_return_data['end_time'] = datetime.datetime( - 2016, 8, 16, 19, 20, 30) + lgdwai_return_data["start_time"] = datetime.datetime(2016, 7, 16, 19, 20, 30) + lgdwai_return_data["end_time"] = datetime.datetime(2016, 8, 16, 19, 20, 30) mock_gro.return_value = resource - mock_gpufi.return_value = 'lesseeid' + mock_gpufi.return_value = "lesseeid" mock_generate_uuid.return_value = self.test_lease.uuid mock_lgdwai.return_value = lgdwai_return_data - request = self.post_json('/leases', data) + request = self.post_json("/leases", data) - mock_gro.assert_called_once_with('ironic_node', '1234567890') + mock_gro.assert_called_once_with("ironic_node", "1234567890") mock_generate_uuid.assert_called_once() mock_cra.assert_called_once_with( - self.context.to_policy_values(), - resource, - self.context.project_id) + self.context.to_policy_values(), resource, self.context.project_id + ) mock_create.assert_called_once() mock_lgdwai.assert_called_once() self.assertEqual(return_data, request.json) self.assertEqual(http_client.CREATED, request.status_int) - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'lease_get_dict_with_added_info') - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'check_resource_lease_admin') - @mock.patch('esi_leap.api.controllers.v1.lease.get_resource_object') - @mock.patch('esi_leap.common.keystone.get_project_uuid_from_ident') - @mock.patch('oslo_utils.uuidutils.generate_uuid') - @mock.patch('esi_leap.api.controllers.v1.utils.check_resource_admin') - @mock.patch('esi_leap.objects.lease.Lease.create') - def test_post_non_admin_parent_lease(self, mock_create, mock_cra, - mock_generate_uuid, mock_gpufi, - mock_gro, mock_crla, mock_lgdwai): - resource = IronicNode('13921c8d-ce11-4b6d-99ed-10e19d184e5f') + @mock.patch("esi_leap.api.controllers.v1.utils." "lease_get_dict_with_added_info") + @mock.patch("esi_leap.api.controllers.v1.utils." "check_resource_lease_admin") + @mock.patch("esi_leap.api.controllers.v1.lease.get_resource_object") + @mock.patch("esi_leap.common.keystone.get_project_uuid_from_ident") + @mock.patch("oslo_utils.uuidutils.generate_uuid") + @mock.patch("esi_leap.api.controllers.v1.utils.check_resource_admin") + @mock.patch("esi_leap.objects.lease.Lease.create") + def test_post_non_admin_parent_lease( + self, + mock_create, + mock_cra, + mock_generate_uuid, + mock_gpufi, + mock_gro, + mock_crla, + mock_lgdwai, + ): + resource = IronicNode("13921c8d-ce11-4b6d-99ed-10e19d184e5f") data = { - 'project_id': 'lesseeid', - 'resource_uuid': '1234567890', - 'start_time': '2016-07-17T19:20:30', - 'end_time': '2016-08-14T19:20:30' + "project_id": "lesseeid", + "resource_uuid": "1234567890", + "start_time": "2016-07-17T19:20:30", + "end_time": "2016-08-14T19:20:30", } return_data = data.copy() - return_data['owner_id'] = self.context.project_id - return_data['uuid'] = self.test_lease_with_parent.uuid - return_data['resource_type'] = 'ironic_node' - return_data['parent_lease_uuid'] = ( - self.test_lease_with_parent.parent_lease_uuid) + return_data["owner_id"] = self.context.project_id + return_data["uuid"] = self.test_lease_with_parent.uuid + return_data["resource_type"] = "ironic_node" + return_data["parent_lease_uuid"] = self.test_lease_with_parent.parent_lease_uuid lgdwai_return_data = return_data.copy() - lgdwai_return_data['start_time'] = datetime.datetime( - 2016, 7, 17, 19, 20, 30) - lgdwai_return_data['end_time'] = datetime.datetime( - 2016, 8, 14, 19, 20, 30) + lgdwai_return_data["start_time"] = datetime.datetime(2016, 7, 17, 19, 20, 30) + lgdwai_return_data["end_time"] = datetime.datetime(2016, 8, 14, 19, 20, 30) mock_gro.return_value = resource - mock_gpufi.return_value = 'lesseeid' + mock_gpufi.return_value = "lesseeid" mock_generate_uuid.return_value = self.test_lease_with_parent.uuid mock_cra.side_effect = exception.HTTPResourceForbidden( - resource_type='ironic_node', resource='1234567890') + resource_type="ironic_node", resource="1234567890" + ) mock_crla.return_value = self.test_lease_with_parent.parent_lease_uuid mock_lgdwai.return_value = lgdwai_return_data - request = self.post_json('/leases', data) + request = self.post_json("/leases", data) - mock_gro.assert_called_once_with('ironic_node', '1234567890') + mock_gro.assert_called_once_with("ironic_node", "1234567890") mock_generate_uuid.assert_called_once() mock_cra.assert_called_once_with( - self.context.to_policy_values(), - resource, - self.context.project_id) + self.context.to_policy_values(), resource, self.context.project_id + ) mock_crla.assert_called_once_with( self.context.to_policy_values(), resource, self.context.project_id, datetime.datetime(2016, 7, 17, 19, 20, 30), - datetime.datetime(2016, 8, 14, 19, 20, 30)) + datetime.datetime(2016, 8, 14, 19, 20, 30), + ) mock_create.assert_called_once() mock_lgdwai.assert_called_once() self.assertEqual(return_data, request.json) self.assertEqual(http_client.CREATED, request.status_int) - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'check_resource_lease_admin') - @mock.patch('esi_leap.api.controllers.v1.lease.get_resource_object') - @mock.patch('esi_leap.common.keystone.get_project_uuid_from_ident') - @mock.patch('oslo_utils.uuidutils.generate_uuid') - @mock.patch('esi_leap.api.controllers.v1.utils.check_resource_admin') - @mock.patch('esi_leap.objects.lease.Lease.create') - def test_post_non_admin_no_parent_lease(self, mock_create, mock_cra, - mock_generate_uuid, mock_gpufi, - mock_gro, mock_crla): - fake_uuid = '13921c8d-ce11-4b6d-99ed-10e19d184e5f' + @mock.patch("esi_leap.api.controllers.v1.utils." "check_resource_lease_admin") + @mock.patch("esi_leap.api.controllers.v1.lease.get_resource_object") + @mock.patch("esi_leap.common.keystone.get_project_uuid_from_ident") + @mock.patch("oslo_utils.uuidutils.generate_uuid") + @mock.patch("esi_leap.api.controllers.v1.utils.check_resource_admin") + @mock.patch("esi_leap.objects.lease.Lease.create") + def test_post_non_admin_no_parent_lease( + self, mock_create, mock_cra, mock_generate_uuid, mock_gpufi, mock_gro, mock_crla + ): + fake_uuid = "13921c8d-ce11-4b6d-99ed-10e19d184e5f" resource = IronicNode(fake_uuid) mock_gro.return_value = resource - mock_gpufi.return_value = 'lesseeid' + mock_gpufi.return_value = "lesseeid" mock_generate_uuid.return_value = self.test_lease.uuid mock_cra.side_effect = exception.HTTPResourceForbidden( - resource_type='ironic_node', resource=fake_uuid) + resource_type="ironic_node", resource=fake_uuid + ) mock_crla.return_value = None data = { - 'project_id': 'lesseeid', - 'resource_uuid': fake_uuid, - 'start_time': '2016-07-17T19:20:30', - 'end_time': '2016-08-14T19:20:30' + "project_id": "lesseeid", + "resource_uuid": fake_uuid, + "start_time": "2016-07-17T19:20:30", + "end_time": "2016-08-14T19:20:30", } - request = self.post_json('/leases', data, expect_errors=True) + request = self.post_json("/leases", data, expect_errors=True) - mock_gro.assert_called_once_with('ironic_node', fake_uuid) + mock_gro.assert_called_once_with("ironic_node", fake_uuid) mock_generate_uuid.assert_called_once() mock_cra.assert_called_once_with( - self.context.to_policy_values(), - resource, - self.context.project_id) + self.context.to_policy_values(), resource, self.context.project_id + ) mock_crla.assert_called_once_with( self.context.to_policy_values(), resource, self.context.project_id, datetime.datetime(2016, 7, 17, 19, 20, 30), - datetime.datetime(2016, 8, 14, 19, 20, 30)) + datetime.datetime(2016, 8, 14, 19, 20, 30), + ) mock_create.assert_not_called() self.assertEqual(http_client.FORBIDDEN, request.status_int) - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'lease_get_dict_with_added_info') - @mock.patch('esi_leap.objects.lease.Lease.update') - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'check_lease_policy_and_retrieve') + @mock.patch("esi_leap.api.controllers.v1.utils." "lease_get_dict_with_added_info") + @mock.patch("esi_leap.objects.lease.Lease.update") + @mock.patch("esi_leap.api.controllers.v1.utils." "check_lease_policy_and_retrieve") def test_patch(self, mock_clpar, mock_lease_update, mock_lgdwai): mock_clpar.return_value = self.test_lease - data = { - 'end_time': '2016-09-16T19:20:30' - } - request = self.patch_json( - "/leases/%s" % self.test_lease.uuid, data) + data = {"end_time": "2016-09-16T19:20:30"} + request = self.patch_json("/leases/%s" % self.test_lease.uuid, data) - mock_clpar.assert_called_once_with(self.context, - 'esi_leap:lease:update', - self.test_lease.uuid) + mock_clpar.assert_called_once_with( + self.context, "esi_leap:lease:update", self.test_lease.uuid + ) mock_lease_update.assert_called_once() mock_lgdwai.assert_called_once() self.assertEqual(http_client.OK, request.status_int) - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'lease_get_dict_with_added_info') - @mock.patch('esi_leap.objects.lease.Lease.update') - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'check_lease_policy_and_retrieve') - def test_patch_no_end_time(self, mock_clpar, mock_lease_update, - mock_lgdwai): + @mock.patch("esi_leap.api.controllers.v1.utils." "lease_get_dict_with_added_info") + @mock.patch("esi_leap.objects.lease.Lease.update") + @mock.patch("esi_leap.api.controllers.v1.utils." "check_lease_policy_and_retrieve") + def test_patch_no_end_time(self, mock_clpar, mock_lease_update, mock_lgdwai): mock_clpar.return_value = self.test_lease - data = { - 'name': 'foo' - } + data = {"name": "foo"} request = self.patch_json( - "/leases/%s" % self.test_lease.uuid, data, expect_errors=True) + "/leases/%s" % self.test_lease.uuid, data, expect_errors=True + ) - mock_clpar.assert_called_once_with(self.context, - 'esi_leap:lease:update', - self.test_lease.uuid) + mock_clpar.assert_called_once_with( + self.context, "esi_leap:lease:update", self.test_lease.uuid + ) mock_lease_update.assert_not_called() mock_lgdwai.assert_not_called() self.assertEqual(http_client.INTERNAL_SERVER_ERROR, request.status_int) - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'lease_get_dict_with_added_info') - @mock.patch('esi_leap.objects.lease.Lease.update') - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'check_lease_policy_and_retrieve') - def test_patch_end_time_and_more(self, mock_clpar, mock_lease_update, - mock_lgdwai): + @mock.patch("esi_leap.api.controllers.v1.utils." "lease_get_dict_with_added_info") + @mock.patch("esi_leap.objects.lease.Lease.update") + @mock.patch("esi_leap.api.controllers.v1.utils." "check_lease_policy_and_retrieve") + def test_patch_end_time_and_more(self, mock_clpar, mock_lease_update, mock_lgdwai): mock_clpar.return_value = self.test_lease - data = { - 'end_time': '2016-09-16T19:20:30', - 'name': 'foo' - } + data = {"end_time": "2016-09-16T19:20:30", "name": "foo"} request = self.patch_json( - "/leases/%s" % self.test_lease.uuid, data, expect_errors=True) + "/leases/%s" % self.test_lease.uuid, data, expect_errors=True + ) - mock_clpar.assert_called_once_with(self.context, - 'esi_leap:lease:update', - self.test_lease.uuid) + mock_clpar.assert_called_once_with( + self.context, "esi_leap:lease:update", self.test_lease.uuid + ) mock_lease_update.assert_not_called() mock_lgdwai.assert_not_called() self.assertEqual(http_client.INTERNAL_SERVER_ERROR, request.status_int) - @mock.patch('esi_leap.common.ironic.get_node_list') - @mock.patch('esi_leap.common.keystone.get_project_list') - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'lease_get_dict_with_added_info') - @mock.patch('esi_leap.api.controllers.v1.lease.LeasesController.' - '_lease_get_all_authorize_filters') - @mock.patch('esi_leap.objects.lease.Lease.get_all') - def test_get_nofilters(self, mock_get_all, mock_lgaaf, mock_lgdwai, - mock_gpl, mock_gnl): + @mock.patch("esi_leap.common.ironic.get_node_list") + @mock.patch("esi_leap.common.keystone.get_project_list") + @mock.patch("esi_leap.api.controllers.v1.utils." "lease_get_dict_with_added_info") + @mock.patch( + "esi_leap.api.controllers.v1.lease.LeasesController." + "_lease_get_all_authorize_filters" + ) + @mock.patch("esi_leap.objects.lease.Lease.get_all") + def test_get_nofilters( + self, mock_get_all, mock_lgaaf, mock_lgdwai, mock_gpl, mock_gnl + ): mock_get_all.return_value = [self.test_lease, self.test_lease] mock_gpl.return_value = [] mock_gnl.return_value = [] - self.get_json('/leases') - - mock_lgaaf.assert_called_once_with(self.context.to_policy_values(), - project_id=None, - start_time=None, - end_time=None, - status=None, - offer_uuid=None, - view=None, - owner_id=None, - resource_type=None, - resource_uuid=None) + self.get_json("/leases") + + mock_lgaaf.assert_called_once_with( + self.context.to_policy_values(), + project_id=None, + start_time=None, + end_time=None, + status=None, + offer_uuid=None, + view=None, + owner_id=None, + resource_type=None, + resource_uuid=None, + ) mock_get_all.assert_called_once() mock_gpl.assert_called_once() mock_gnl.assert_called_once() self.assertEqual(2, mock_lgdwai.call_count) - @mock.patch('esi_leap.common.ironic.get_node_list') - @mock.patch('esi_leap.common.keystone.get_project_list') - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'lease_get_dict_with_added_info') - @mock.patch('esi_leap.common.keystone.get_project_uuid_from_ident') - @mock.patch('esi_leap.api.controllers.v1.lease.LeasesController.' - '_lease_get_all_authorize_filters') - @mock.patch('esi_leap.objects.lease.Lease.get_all') - def test_get_project_filter(self, mock_get_all, mock_lgaaf, - mock_gpufi, mock_lgdwai, mock_gpl, - mock_gnl): - mock_gpufi.return_value = '12345' + @mock.patch("esi_leap.common.ironic.get_node_list") + @mock.patch("esi_leap.common.keystone.get_project_list") + @mock.patch("esi_leap.api.controllers.v1.utils." "lease_get_dict_with_added_info") + @mock.patch("esi_leap.common.keystone.get_project_uuid_from_ident") + @mock.patch( + "esi_leap.api.controllers.v1.lease.LeasesController." + "_lease_get_all_authorize_filters" + ) + @mock.patch("esi_leap.objects.lease.Lease.get_all") + def test_get_project_filter( + self, mock_get_all, mock_lgaaf, mock_gpufi, mock_lgdwai, mock_gpl, mock_gnl + ): + mock_gpufi.return_value = "12345" mock_get_all.return_value = [self.test_lease, self.test_lease] mock_gpl.return_value = [] mock_gnl.return_value = [] - self.get_json('/leases?project_id=12345') - - mock_gpufi.assert_called_once_with('12345') - mock_lgaaf.assert_called_once_with(self.context.to_policy_values(), - project_id='12345', - start_time=None, - end_time=None, - status=None, - offer_uuid=None, - view=None, - owner_id=None, - resource_type=None, - resource_uuid=None) + self.get_json("/leases?project_id=12345") + + mock_gpufi.assert_called_once_with("12345") + mock_lgaaf.assert_called_once_with( + self.context.to_policy_values(), + project_id="12345", + start_time=None, + end_time=None, + status=None, + offer_uuid=None, + view=None, + owner_id=None, + resource_type=None, + resource_uuid=None, + ) mock_get_all.assert_called_once() mock_gpl.assert_called_once() mock_gnl.assert_called_once() self.assertEqual(2, mock_lgdwai.call_count) - @mock.patch('esi_leap.common.ironic.get_node_list') - @mock.patch('esi_leap.common.keystone.get_project_list') - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'lease_get_dict_with_added_info') - @mock.patch('esi_leap.common.keystone.get_project_uuid_from_ident') - @mock.patch('esi_leap.api.controllers.v1.lease.LeasesController.' - '_lease_get_all_authorize_filters') - @mock.patch('esi_leap.objects.lease.Lease.get_all') - def test_get_owner_filter(self, mock_get_all, mock_lgaaf, - mock_gpufi, mock_lgdwai, mock_gpl, - mock_gnl): - mock_gpufi.return_value = '54321' + @mock.patch("esi_leap.common.ironic.get_node_list") + @mock.patch("esi_leap.common.keystone.get_project_list") + @mock.patch("esi_leap.api.controllers.v1.utils." "lease_get_dict_with_added_info") + @mock.patch("esi_leap.common.keystone.get_project_uuid_from_ident") + @mock.patch( + "esi_leap.api.controllers.v1.lease.LeasesController." + "_lease_get_all_authorize_filters" + ) + @mock.patch("esi_leap.objects.lease.Lease.get_all") + def test_get_owner_filter( + self, mock_get_all, mock_lgaaf, mock_gpufi, mock_lgdwai, mock_gpl, mock_gnl + ): + mock_gpufi.return_value = "54321" mock_get_all.return_value = [self.test_lease, self.test_lease] mock_gpl.return_value = [] mock_gnl.return_value = [] - self.get_json('/leases?owner_id=54321') + self.get_json("/leases?owner_id=54321") - mock_gpufi.assert_called_once_with('54321') - mock_lgaaf.assert_called_once_with(self.context.to_policy_values(), - project_id=None, - start_time=None, - end_time=None, - status=None, - offer_uuid=None, - view=None, - owner_id='54321', - resource_type=None, - resource_uuid=None) + mock_gpufi.assert_called_once_with("54321") + mock_lgaaf.assert_called_once_with( + self.context.to_policy_values(), + project_id=None, + start_time=None, + end_time=None, + status=None, + offer_uuid=None, + view=None, + owner_id="54321", + resource_type=None, + resource_uuid=None, + ) mock_get_all.assert_called_once() mock_gpl.assert_called_once() mock_gnl.assert_called_once() self.assertEqual(2, mock_lgdwai.call_count) - @mock.patch('esi_leap.common.ironic.get_node_list') - @mock.patch('esi_leap.common.keystone.get_project_list') - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'lease_get_dict_with_added_info') - @mock.patch('esi_leap.api.controllers.v1.lease.get_resource_object') - @mock.patch('esi_leap.api.controllers.v1.lease.LeasesController.' - '_lease_get_all_authorize_filters') - @mock.patch('esi_leap.objects.lease.Lease.get_all') - def test_get_resource_filter(self, mock_get_all, mock_lgaaf, - mock_gro, mock_lgdwai, mock_gpl, - mock_gnl): - mock_gro.return_value = TestNode('54321') + @mock.patch("esi_leap.common.ironic.get_node_list") + @mock.patch("esi_leap.common.keystone.get_project_list") + @mock.patch("esi_leap.api.controllers.v1.utils." "lease_get_dict_with_added_info") + @mock.patch("esi_leap.api.controllers.v1.lease.get_resource_object") + @mock.patch( + "esi_leap.api.controllers.v1.lease.LeasesController." + "_lease_get_all_authorize_filters" + ) + @mock.patch("esi_leap.objects.lease.Lease.get_all") + def test_get_resource_filter( + self, mock_get_all, mock_lgaaf, mock_gro, mock_lgdwai, mock_gpl, mock_gnl + ): + mock_gro.return_value = TestNode("54321") mock_get_all.return_value = [self.test_lease, self.test_lease] mock_gpl.return_value = [] mock_gnl.return_value = [] - self.get_json('/leases?resource_uuid=54321&resource_type=test_node') + self.get_json("/leases?resource_uuid=54321&resource_type=test_node") - mock_gro.assert_called_once_with('test_node', '54321') - mock_lgaaf.assert_called_once_with(self.context.to_policy_values(), - project_id=None, - start_time=None, - end_time=None, - status=None, - offer_uuid=None, - view=None, - owner_id=None, - resource_type='test_node', - resource_uuid='54321') + mock_gro.assert_called_once_with("test_node", "54321") + mock_lgaaf.assert_called_once_with( + self.context.to_policy_values(), + project_id=None, + start_time=None, + end_time=None, + status=None, + offer_uuid=None, + view=None, + owner_id=None, + resource_type="test_node", + resource_uuid="54321", + ) mock_get_all.assert_called_once() mock_gpl.assert_called_once() mock_gnl.assert_called_once() self.assertEqual(2, mock_lgdwai.call_count) - @mock.patch('esi_leap.common.ironic.get_node_list') - @mock.patch('esi_leap.common.keystone.get_project_list') - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'lease_get_dict_with_added_info') - @mock.patch('esi_leap.api.controllers.v1.lease.LeasesController.' - '_lease_get_all_authorize_filters') - @mock.patch('esi_leap.objects.lease.Lease.get_all') - def test_get_resource_class_filter(self, mock_get_all, mock_lgaaf, - mock_lgdwai, mock_gpl, mock_gnl): - def _get_lease_response(l, use_datetime=False): + @mock.patch("esi_leap.common.ironic.get_node_list") + @mock.patch("esi_leap.common.keystone.get_project_list") + @mock.patch("esi_leap.api.controllers.v1.utils." "lease_get_dict_with_added_info") + @mock.patch( + "esi_leap.api.controllers.v1.lease.LeasesController." + "_lease_get_all_authorize_filters" + ) + @mock.patch("esi_leap.objects.lease.Lease.get_all") + def test_get_resource_class_filter( + self, mock_get_all, mock_lgaaf, mock_lgdwai, mock_gpl, mock_gnl + ): + def _get_lease_response(lease, use_datetime=False): if use_datetime: start = datetime.datetime(2016, 7, 16, 19, 20, 30) end = datetime.datetime(2016, 8, 16, 19, 20, 30) else: - start = '2016-07-16T19:20:30' - end = '2016-08-16T19:20:30' + start = "2016-07-16T19:20:30" + end = "2016-08-16T19:20:30" - if l.resource_type in ['test_node', 'dummy_node']: - resource_class = 'fake' - elif l.resource_type == 'ironic_node': - resource_class = 'baremetal' + if lease.resource_type in ["test_node", "dummy_node"]: + resource_class = "fake" + elif lease.resource_type == "ironic_node": + resource_class = "baremetal" return { - 'resource_type': l.resource_type, - 'resource_uuid': l.resource_uuid, - 'resource_class': resource_class, - 'project_id': l.project_id, - 'start_time': start, - 'end_time': end, - 'uuid': l.uuid, - 'owner_id': l.owner_id, - 'parent_lease_uuid': None + "resource_type": lease.resource_type, + "resource_uuid": lease.resource_uuid, + "resource_class": resource_class, + "project_id": lease.project_id, + "start_time": start, + "end_time": end, + "uuid": lease.uuid, + "owner_id": lease.owner_id, + "parent_lease_uuid": None, } mock_get_all.return_value = [self.test_lease, self.test_lease] mock_gpl.return_value = [] mock_gnl.return_value = [] - mock_lgdwai.side_effect = [_get_lease_response(self.test_lease, - use_datetime=True), - _get_lease_response(self.test_lease_1, - use_datetime=True)] - response = self.get_json('/leases?resource_class=fake') - - expected_resp = {'leases': [_get_lease_response(self.test_lease)]} - - mock_lgaaf.assert_called_once_with(self.context.to_policy_values(), - project_id=None, - start_time=None, - end_time=None, - status=None, - offer_uuid=None, - view=None, - owner_id=None, - resource_type=None, - resource_uuid=None) + mock_lgdwai.side_effect = [ + _get_lease_response(self.test_lease, use_datetime=True), + _get_lease_response(self.test_lease_1, use_datetime=True), + ] + response = self.get_json("/leases?resource_class=fake") + + expected_resp = {"leases": [_get_lease_response(self.test_lease)]} + + mock_lgaaf.assert_called_once_with( + self.context.to_policy_values(), + project_id=None, + start_time=None, + end_time=None, + status=None, + offer_uuid=None, + view=None, + owner_id=None, + resource_type=None, + resource_uuid=None, + ) mock_get_all.assert_called_once() mock_gpl.assert_called_once() @@ -537,294 +545,320 @@ def _get_lease_response(l, use_datetime=False): self.assertEqual(2, mock_lgdwai.call_count) self.assertEqual(response, expected_resp) - @mock.patch('esi_leap.common.ironic.get_node_list') - @mock.patch('esi_leap.common.keystone.get_project_list') - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'lease_get_dict_with_added_info') - @mock.patch('esi_leap.api.controllers.v1.lease.get_resource_object') - @mock.patch('esi_leap.api.controllers.v1.lease.LeasesController.' - '_lease_get_all_authorize_filters') - @mock.patch('esi_leap.objects.lease.Lease.get_all') - def test_get_resource_filter_default_resource_type(self, mock_get_all, - mock_lgaaf, mock_gro, - mock_lgdwai, mock_gpl, - mock_gnl): + @mock.patch("esi_leap.common.ironic.get_node_list") + @mock.patch("esi_leap.common.keystone.get_project_list") + @mock.patch("esi_leap.api.controllers.v1.utils." "lease_get_dict_with_added_info") + @mock.patch("esi_leap.api.controllers.v1.lease.get_resource_object") + @mock.patch( + "esi_leap.api.controllers.v1.lease.LeasesController." + "_lease_get_all_authorize_filters" + ) + @mock.patch("esi_leap.objects.lease.Lease.get_all") + def test_get_resource_filter_default_resource_type( + self, mock_get_all, mock_lgaaf, mock_gro, mock_lgdwai, mock_gpl, mock_gnl + ): fake_uuid = uuidutils.generate_uuid() mock_gro.return_value = IronicNode(fake_uuid) mock_get_all.return_value = [self.test_lease, self.test_lease] mock_gpl.return_value = [] mock_gnl.return_value = [] - self.get_json('/leases?resource_uuid=%s' % fake_uuid) + self.get_json("/leases?resource_uuid=%s" % fake_uuid) - mock_gro.assert_called_once_with('ironic_node', fake_uuid) - mock_lgaaf.assert_called_once_with(self.context.to_policy_values(), - project_id=None, - start_time=None, - end_time=None, - status=None, - offer_uuid=None, - view=None, - owner_id=None, - resource_type='ironic_node', - resource_uuid=fake_uuid) + mock_gro.assert_called_once_with("ironic_node", fake_uuid) + mock_lgaaf.assert_called_once_with( + self.context.to_policy_values(), + project_id=None, + start_time=None, + end_time=None, + status=None, + offer_uuid=None, + view=None, + owner_id=None, + resource_type="ironic_node", + resource_uuid=fake_uuid, + ) mock_get_all.assert_called_once() mock_gpl.assert_called_once() mock_gnl.assert_called_once() self.assertEqual(2, mock_lgdwai.call_count) - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'check_lease_policy_and_retrieve') - @mock.patch('esi_leap.objects.lease.Lease.cancel') + @mock.patch("esi_leap.api.controllers.v1.utils." "check_lease_policy_and_retrieve") + @mock.patch("esi_leap.objects.lease.Lease.cancel") def test_lease_delete(self, mock_cancel, mock_clpar): mock_clpar.return_value = self.test_lease - self.delete_json('/leases/' + self.test_lease.uuid) + self.delete_json("/leases/" + self.test_lease.uuid) - mock_clpar.assert_called_once_with(self.context, - 'esi_leap:lease:get', - self.test_lease.uuid, - statuses.LEASE_CAN_DELETE) + mock_clpar.assert_called_once_with( + self.context, + "esi_leap:lease:get", + self.test_lease.uuid, + statuses.LEASE_CAN_DELETE, + ) mock_cancel.assert_called_once() class TestLeaseControllersGetAllFilters(testtools.TestCase): - def setUp(self): super(TestLeaseControllersGetAllFilters, self).setUp() - self.admin_ctx = ctx.RequestContext(project_id='adminid', - roles=['admin']) - self.owner_ctx = ctx.RequestContext(project_id='ownerid', - roles=['owner']) - self.lessee_ctx = ctx.RequestContext(project_id='lesseeid', - roles=['lessee']) - self.random_ctx = ctx.RequestContext(project_id='randomid', - roles=['randomrole']) + self.admin_ctx = ctx.RequestContext(project_id="adminid", roles=["admin"]) + self.owner_ctx = ctx.RequestContext(project_id="ownerid", roles=["owner"]) + self.lessee_ctx = ctx.RequestContext(project_id="lesseeid", roles=["lessee"]) + self.random_ctx = ctx.RequestContext( + project_id="randomid", roles=["randomrole"] + ) def test_lease_get_all_no_view_no_projectid_no_owner(self): - expected_filters = { - 'status': ['random'], - 'offer_uuid': 'offeruuid', - 'time_filter_type': constants.WITHIN_TIME_FILTER + "status": ["random"], + "offer_uuid": "offeruuid", + "time_filter_type": constants.WITHIN_TIME_FILTER, } # admin - expected_filters['project_or_owner_id'] = self.admin_ctx.project_id + expected_filters["project_or_owner_id"] = self.admin_ctx.project_id filters = LeasesController._lease_get_all_authorize_filters( - self.admin_ctx.to_policy_values(), - status='random', offer_uuid='offeruuid') + self.admin_ctx.to_policy_values(), status="random", offer_uuid="offeruuid" + ) self.assertEqual(expected_filters, filters) # owner - expected_filters['project_or_owner_id'] = self.owner_ctx.project_id + expected_filters["project_or_owner_id"] = self.owner_ctx.project_id filters = LeasesController._lease_get_all_authorize_filters( - self.owner_ctx.to_policy_values(), - status='random', offer_uuid='offeruuid') + self.owner_ctx.to_policy_values(), status="random", offer_uuid="offeruuid" + ) self.assertEqual(expected_filters, filters) # lessee - expected_filters['project_or_owner_id'] = self.lessee_ctx.project_id + expected_filters["project_or_owner_id"] = self.lessee_ctx.project_id filters = LeasesController._lease_get_all_authorize_filters( - self.lessee_ctx.to_policy_values(), - status='random', offer_uuid='offeruuid') + self.lessee_ctx.to_policy_values(), status="random", offer_uuid="offeruuid" + ) self.assertEqual(expected_filters, filters) # random - self.assertRaises(exception.HTTPForbidden, - LeasesController. - _lease_get_all_authorize_filters, - self.random_ctx.to_policy_values(), - status='random', offer_uuid='offeruuid') + self.assertRaises( + exception.HTTPForbidden, + LeasesController._lease_get_all_authorize_filters, + self.random_ctx.to_policy_values(), + status="random", + offer_uuid="offeruuid", + ) def test_lease_get_all_no_view_project_no_owner(self): - expected_filters = { - 'status': ['random'], - 'time_filter_type': constants.WITHIN_TIME_FILTER + "status": ["random"], + "time_filter_type": constants.WITHIN_TIME_FILTER, } # admin - expected_filters['project_id'] = self.admin_ctx.project_id + expected_filters["project_id"] = self.admin_ctx.project_id filters = LeasesController._lease_get_all_authorize_filters( self.admin_ctx.to_policy_values(), project_id=self.admin_ctx.project_id, - status='random') + status="random", + ) self.assertEqual(expected_filters, filters) # lessee - expected_filters['project_id'] = self.lessee_ctx.project_id + expected_filters["project_id"] = self.lessee_ctx.project_id filters = LeasesController._lease_get_all_authorize_filters( self.lessee_ctx.to_policy_values(), project_id=self.lessee_ctx.project_id, - status='random') + status="random", + ) self.assertEqual(expected_filters, filters) - self.assertRaises(exception.HTTPForbidden, - LeasesController. - _lease_get_all_authorize_filters, - self.random_ctx.to_policy_values(), - project_id=self.random_ctx.project_id, - status='random') + self.assertRaises( + exception.HTTPForbidden, + LeasesController._lease_get_all_authorize_filters, + self.random_ctx.to_policy_values(), + project_id=self.random_ctx.project_id, + status="random", + ) # owner - expected_filters['project_id'] = self.owner_ctx.project_id + expected_filters["project_id"] = self.owner_ctx.project_id filters = LeasesController._lease_get_all_authorize_filters( self.owner_ctx.to_policy_values(), project_id=self.owner_ctx.project_id, - status='random') + status="random", + ) self.assertEqual(expected_filters, filters) # random - self.assertRaises(exception.HTTPForbidden, - LeasesController. - _lease_get_all_authorize_filters, - self.random_ctx.to_policy_values(), - project_id=self.random_ctx.project_id, - status='random') + self.assertRaises( + exception.HTTPForbidden, + LeasesController._lease_get_all_authorize_filters, + self.random_ctx.to_policy_values(), + project_id=self.random_ctx.project_id, + status="random", + ) def test_lease_get_all_no_view_any_projectid_owner(self): - expected_filters = { - 'status': ['random'], - 'time_filter_type': constants.WITHIN_TIME_FILTER + "status": ["random"], + "time_filter_type": constants.WITHIN_TIME_FILTER, } # admin - expected_filters['owner_id'] = self.admin_ctx.project_id + expected_filters["owner_id"] = self.admin_ctx.project_id filters = LeasesController._lease_get_all_authorize_filters( self.admin_ctx.to_policy_values(), owner_id=self.admin_ctx.project_id, - status='random') + status="random", + ) self.assertEqual(expected_filters, filters) # lessee - expected_filters['owner_id'] = self.lessee_ctx.project_id + expected_filters["owner_id"] = self.lessee_ctx.project_id filters = LeasesController._lease_get_all_authorize_filters( self.lessee_ctx.to_policy_values(), owner_id=self.lessee_ctx.project_id, - status='random') + status="random", + ) self.assertEqual(expected_filters, filters) - expected_filters['owner_id'] = self.lessee_ctx.project_id - expected_filters['project_id'] = self.random_ctx.project_id + expected_filters["owner_id"] = self.lessee_ctx.project_id + expected_filters["project_id"] = self.random_ctx.project_id filters = LeasesController._lease_get_all_authorize_filters( self.lessee_ctx.to_policy_values(), owner_id=self.lessee_ctx.project_id, project_id=self.random_ctx.project_id, - status='random') + status="random", + ) self.assertEqual(expected_filters, filters) - del expected_filters['project_id'] + del expected_filters["project_id"] # owner - expected_filters['owner_id'] = self.owner_ctx.project_id + expected_filters["owner_id"] = self.owner_ctx.project_id filters = LeasesController._lease_get_all_authorize_filters( self.owner_ctx.to_policy_values(), owner_id=self.owner_ctx.project_id, - status='random') + status="random", + ) self.assertEqual(expected_filters, filters) - expected_filters['owner_id'] = self.owner_ctx.project_id - expected_filters['project_id'] = self.random_ctx.project_id + expected_filters["owner_id"] = self.owner_ctx.project_id + expected_filters["project_id"] = self.random_ctx.project_id filters = LeasesController._lease_get_all_authorize_filters( self.owner_ctx.to_policy_values(), owner_id=self.owner_ctx.project_id, project_id=self.random_ctx.project_id, - status='random') + status="random", + ) self.assertEqual(expected_filters, filters) # random - self.assertRaises(exception.HTTPForbidden, - LeasesController. - _lease_get_all_authorize_filters, - self.random_ctx.to_policy_values(), - owner_id=self.random_ctx.project_id, - status='random') + self.assertRaises( + exception.HTTPForbidden, + LeasesController._lease_get_all_authorize_filters, + self.random_ctx.to_policy_values(), + owner_id=self.random_ctx.project_id, + status="random", + ) def test_lease_get_all_all_view(self): - expected_filters = { - 'status': ['random'], - 'time_filter_type': constants.WITHIN_TIME_FILTER + "status": ["random"], + "time_filter_type": constants.WITHIN_TIME_FILTER, } # admin filters = LeasesController._lease_get_all_authorize_filters( - self.admin_ctx.to_policy_values(), - view='all', - status='random') + self.admin_ctx.to_policy_values(), view="all", status="random" + ) self.assertEqual(expected_filters, filters) # not admin - self.assertRaises(exception.HTTPForbidden, - LeasesController. - _lease_get_all_authorize_filters, - self.lessee_ctx.to_policy_values(), - view='all', - status='random') - - self.assertRaises(exception.HTTPForbidden, - LeasesController. - _lease_get_all_authorize_filters, - self.owner_ctx.to_policy_values(), - view='all', - status='random') - - self.assertRaises(exception.HTTPForbidden, - LeasesController. - _lease_get_all_authorize_filters, - self.random_ctx.to_policy_values(), - view='all', - status='random') + self.assertRaises( + exception.HTTPForbidden, + LeasesController._lease_get_all_authorize_filters, + self.lessee_ctx.to_policy_values(), + view="all", + status="random", + ) - def test_lease_get_all_all_view_times(self): + self.assertRaises( + exception.HTTPForbidden, + LeasesController._lease_get_all_authorize_filters, + self.owner_ctx.to_policy_values(), + view="all", + status="random", + ) + self.assertRaises( + exception.HTTPForbidden, + LeasesController._lease_get_all_authorize_filters, + self.random_ctx.to_policy_values(), + view="all", + status="random", + ) + + def test_lease_get_all_all_view_times(self): start = datetime.datetime(2016, 7, 16, 19, 20, 30) end = datetime.datetime(2020, 7, 16, 19, 20, 30) expected_filters = { - 'status': ['random'], - 'start_time': start, - 'end_time': end, - 'time_filter_type': constants.WITHIN_TIME_FILTER + "status": ["random"], + "start_time": start, + "end_time": end, + "time_filter_type": constants.WITHIN_TIME_FILTER, } # admin filters = LeasesController._lease_get_all_authorize_filters( self.admin_ctx.to_policy_values(), - view='all', start_time=start, end_time=end, status='random') + view="all", + start_time=start, + end_time=end, + status="random", + ) self.assertEqual(expected_filters, filters) - self.assertRaises(exception.InvalidTimeAPICommand, - LeasesController. - _lease_get_all_authorize_filters, - self.admin_ctx.to_policy_values(), - view='all', start_time=start, status='random') + self.assertRaises( + exception.InvalidTimeAPICommand, + LeasesController._lease_get_all_authorize_filters, + self.admin_ctx.to_policy_values(), + view="all", + start_time=start, + status="random", + ) - self.assertRaises(exception.InvalidTimeAPICommand, - LeasesController. - _lease_get_all_authorize_filters, - self.admin_ctx.to_policy_values(), - view='all', end_time=end, status='random') + self.assertRaises( + exception.InvalidTimeAPICommand, + LeasesController._lease_get_all_authorize_filters, + self.admin_ctx.to_policy_values(), + view="all", + end_time=end, + status="random", + ) def test_lease_get_all_status(self): - expected_filters = { - 'project_or_owner_id': 'adminid', - 'status': [statuses.CREATED, statuses.ACTIVE, statuses.ERROR, - statuses.WAIT_CANCEL, statuses.WAIT_EXPIRE, - statuses.WAIT_FULFILL], - 'time_filter_type': constants.WITHIN_TIME_FILTER + "project_or_owner_id": "adminid", + "status": [ + statuses.CREATED, + statuses.ACTIVE, + statuses.ERROR, + statuses.WAIT_CANCEL, + statuses.WAIT_EXPIRE, + statuses.WAIT_FULFILL, + ], + "time_filter_type": constants.WITHIN_TIME_FILTER, } # admin filters = LeasesController._lease_get_all_authorize_filters( - self.admin_ctx.to_policy_values()) + self.admin_ctx.to_policy_values() + ) self.assertEqual(expected_filters, filters) - del(expected_filters['status']) + del expected_filters["status"] filters = LeasesController._lease_get_all_authorize_filters( - self.admin_ctx.to_policy_values(), status='any') + self.admin_ctx.to_policy_values(), status="any" + ) self.assertEqual(expected_filters, filters) diff --git a/esi_leap/tests/api/controllers/v1/test_node.py b/esi_leap/tests/api/controllers/v1/test_node.py index badef0a9..03e35dcf 100644 --- a/esi_leap/tests/api/controllers/v1/test_node.py +++ b/esi_leap/tests/api/controllers/v1/test_node.py @@ -17,34 +17,33 @@ class FakeIronicNode(object): def __init__(self): - self.name = 'fake-node' - self.owner = 'fake-project-uuid' - self.uuid = 'fake-uuid' - self.properties = {'lease_uuid': 'fake-lease-uuid', 'cpu': '40'} - self.lessee = 'fake-project-uuid' + self.name = "fake-node" + self.owner = "fake-project-uuid" + self.uuid = "fake-uuid" + self.properties = {"lease_uuid": "fake-lease-uuid", "cpu": "40"} + self.lessee = "fake-project-uuid" self.maintenance = False - self.provision_state = 'active' - self.target_provision_state = 'target_state' - self.power_state = 'power off' - self.target_power_state = 'power on' - self.resource_class = 'baremetal' + self.provision_state = "active" + self.target_provision_state = "target_state" + self.power_state = "power off" + self.target_power_state = "power on" + self.resource_class = "baremetal" class FakeProject(object): def __init__(self): - self.name = 'fake-project' - self.id = 'fake-project-uuid' + self.name = "fake-project" + self.id = "fake-project-uuid" class TestNodesController(test_api_base.APITestCase): - def setUp(self): super(TestNodesController, self).setUp() - @mock.patch('esi_leap.common.ironic.get_node_list') - @mock.patch('esi_leap.objects.offer.Offer.get_all') - @mock.patch('esi_leap.objects.lease.Lease.get_all') - @mock.patch('esi_leap.common.keystone.get_project_list') + @mock.patch("esi_leap.common.ironic.get_node_list") + @mock.patch("esi_leap.objects.offer.Offer.get_all") + @mock.patch("esi_leap.objects.lease.Lease.get_all") + @mock.patch("esi_leap.common.keystone.get_project_list") def test_get_all(self, mock_gpl, mock_lga, mock_oga, mock_gnl): fake_node = FakeIronicNode() fake_project = FakeProject() @@ -53,43 +52,39 @@ def test_get_all(self, mock_gpl, mock_lga, mock_oga, mock_gnl): mock_lga.return_value = [] mock_gpl.return_value = [fake_project] - data = self.get_json('/nodes') + data = self.get_json("/nodes") mock_gnl.assert_called_once_with(self.context) mock_oga.assert_called_once() mock_lga.assert_called_once() mock_gpl.assert_called_once() - self.assertEqual(data['nodes'][0]['name'], 'fake-node') - self.assertEqual(data['nodes'][0]['uuid'], 'fake-uuid') - self.assertEqual(data['nodes'][0]['owner'], 'fake-project') - self.assertEqual(data['nodes'][0]['lease_uuid'], 'fake-lease-uuid') - self.assertEqual(data['nodes'][0]['lessee'], 'fake-project') - self.assertEqual(data['nodes'][0]['properties'], { - 'cpu': '40'}) + self.assertEqual(data["nodes"][0]["name"], "fake-node") + self.assertEqual(data["nodes"][0]["uuid"], "fake-uuid") + self.assertEqual(data["nodes"][0]["owner"], "fake-project") + self.assertEqual(data["nodes"][0]["lease_uuid"], "fake-lease-uuid") + self.assertEqual(data["nodes"][0]["lessee"], "fake-project") + self.assertEqual(data["nodes"][0]["properties"], {"cpu": "40"}) - @mock.patch('esi_leap.common.ironic.get_node_list') - @mock.patch('esi_leap.common.keystone.get_project_list') + @mock.patch("esi_leap.common.ironic.get_node_list") + @mock.patch("esi_leap.common.keystone.get_project_list") def test_get_all_resource_class_filter(self, mock_gpl, mock_gnl): fake_node = FakeIronicNode() fake_project = FakeProject() mock_gnl.return_value = [fake_node] mock_gpl.return_value = [fake_project] - data = self.get_json('/nodes?resource_class=baremetal') + data = self.get_json("/nodes?resource_class=baremetal") - mock_gnl.assert_called_once_with( - self.context, resource_class='baremetal') + mock_gnl.assert_called_once_with(self.context, resource_class="baremetal") mock_gpl.assert_called_once() - self.assertEqual(data['nodes'][0]['resource_class'], 'baremetal') - - @mock.patch('esi_leap.common.ironic.get_node_list') - @mock.patch('esi_leap.common.keystone.get_project_list') - @mock.patch('esi_leap.common.keystone.get_project_uuid_from_ident') - def test_get_all_owner_filter( - self, mock_get_project_uuid, mock_gpl, mock_gnl): + self.assertEqual(data["nodes"][0]["resource_class"], "baremetal") + @mock.patch("esi_leap.common.ironic.get_node_list") + @mock.patch("esi_leap.common.keystone.get_project_list") + @mock.patch("esi_leap.common.keystone.get_project_uuid_from_ident") + def test_get_all_owner_filter(self, mock_get_project_uuid, mock_gpl, mock_gnl): fake_node = FakeIronicNode() fake_project = FakeProject() mock_gnl.return_value = [fake_node] @@ -97,19 +92,17 @@ def test_get_all_owner_filter( mock_get_project_uuid.return_value = fake_project.id - data = self.get_json('/nodes?owner=fake-project') + data = self.get_json("/nodes?owner=fake-project") mock_gnl.assert_called_once_with(self.context, owner=fake_project.id) - mock_get_project_uuid.assert_called_once_with('fake-project') - - self.assertEqual(data['nodes'][0]['owner'], fake_project.name) + mock_get_project_uuid.assert_called_once_with("fake-project") - @mock.patch('esi_leap.common.ironic.get_node_list') - @mock.patch('esi_leap.common.keystone.get_project_list') - @mock.patch('esi_leap.common.keystone.get_project_uuid_from_ident') - def test_get_all_lesse_filter( - self, mock_get_project_uuid, mock_gpl, mock_gnl): + self.assertEqual(data["nodes"][0]["owner"], fake_project.name) + @mock.patch("esi_leap.common.ironic.get_node_list") + @mock.patch("esi_leap.common.keystone.get_project_list") + @mock.patch("esi_leap.common.keystone.get_project_uuid_from_ident") + def test_get_all_lesse_filter(self, mock_get_project_uuid, mock_gpl, mock_gnl): fake_node = FakeIronicNode() fake_project = FakeProject() mock_gnl.return_value = [fake_node] @@ -117,9 +110,9 @@ def test_get_all_lesse_filter( mock_get_project_uuid.return_value = fake_project.id - data = self.get_json('/nodes?lessee=fake-project') + data = self.get_json("/nodes?lessee=fake-project") mock_gnl.assert_called_once_with(self.context, lessee=fake_project.id) - mock_get_project_uuid.assert_called_once_with('fake-project') + mock_get_project_uuid.assert_called_once_with("fake-project") - self.assertEqual(data['nodes'][0]['lessee'], 'fake-project') + self.assertEqual(data["nodes"][0]["lessee"], "fake-project") diff --git a/esi_leap/tests/api/controllers/v1/test_offer.py b/esi_leap/tests/api/controllers/v1/test_offer.py index 83684ae3..91ec8ce2 100644 --- a/esi_leap/tests/api/controllers/v1/test_offer.py +++ b/esi_leap/tests/api/controllers/v1/test_offer.py @@ -28,103 +28,102 @@ def _get_offer_response(o, use_datetime=False): start = datetime.datetime(2016, 7, 16) end = datetime.datetime(2016, 10, 24) else: - start = '2016-07-16T00:00:00' - end = '2016-10-24T00:00:00' - if o.resource_type in ['test_node', 'dummy_node']: - resource_class = 'fake' - elif o.resource_type == 'ironic_node': - resource_class = 'baremetal' + start = "2016-07-16T00:00:00" + end = "2016-10-24T00:00:00" + if o.resource_type in ["test_node", "dummy_node"]: + resource_class = "fake" + elif o.resource_type == "ironic_node": + resource_class = "baremetal" return { - 'resource_type': o.resource_type, - 'resource_uuid': o.resource_uuid, - 'resource_class': resource_class, - 'name': o.name, - 'project_id': o.project_id, - 'start_time': start, - 'end_time': end, - 'status': o.status, - 'availabilities': [], - 'uuid': o.uuid, - 'parent_lease_uuid': None + "resource_type": o.resource_type, + "resource_uuid": o.resource_uuid, + "resource_class": resource_class, + "name": o.name, + "project_id": o.project_id, + "start_time": start, + "end_time": end, + "status": o.status, + "availabilities": [], + "uuid": o.uuid, + "parent_lease_uuid": None, } class TestOffersController(test_api_base.APITestCase): - def setUp(self): super(TestOffersController, self).setUp() start = datetime.datetime(2016, 7, 16) self.test_offer = offer.Offer( - resource_type='test_node', + resource_type="test_node", resource_uuid=uuidutils.generate_uuid(), - name='test_offer', + name="test_offer", uuid=uuidutils.generate_uuid(), status=statuses.AVAILABLE, start_time=start, end_time=start + datetime.timedelta(days=100), project_id=self.context.project_id, - parent_lease_uuid=None + parent_lease_uuid=None, ) self.test_offer_drt = offer.Offer( - resource_type='ironic_node', + resource_type="ironic_node", resource_uuid=uuidutils.generate_uuid(), - name='test_offer', + name="test_offer", uuid=uuidutils.generate_uuid(), status=statuses.AVAILABLE, start_time=start, end_time=start + datetime.timedelta(days=100), project_id=self.context.project_id, - parent_lease_uuid=None + parent_lease_uuid=None, ) self.test_offer_lessee = offer.Offer( - resource_type='test_node', + resource_type="test_node", resource_uuid=uuidutils.generate_uuid(), - name='test_offer', + name="test_offer", uuid=uuidutils.generate_uuid(), - lessee_id='lessee-uuid', + lessee_id="lessee-uuid", status=statuses.AVAILABLE, start_time=start, end_time=start + datetime.timedelta(days=100), project_id=self.context.project_id, - parent_lease_uuid=None + parent_lease_uuid=None, ) self.test_offer_2 = offer.Offer( - resource_type='test_node', + resource_type="test_node", resource_uuid=uuidutils.generate_uuid(), - name='test_offer2', + name="test_offer2", uuid=uuidutils.generate_uuid(), status=statuses.DELETED, start_time=start, end_time=start + datetime.timedelta(days=100), project_id=self.context.project_id, - parent_lease_uuid=None + parent_lease_uuid=None, ) self.test_offer_with_parent = offer.Offer( - resource_type='test_node', + resource_type="test_node", resource_uuid=uuidutils.generate_uuid(), - name='test_offer', + name="test_offer", uuid=uuidutils.generate_uuid(), status=statuses.AVAILABLE, start_time=start, end_time=start + datetime.timedelta(days=100), project_id=self.context.project_id, - parent_lease_uuid='parent-lease-uuid' + parent_lease_uuid="parent-lease-uuid", ) def test_empty(self): - data = self.get_json('/offers') - self.assertEqual([], data['offers']) - - @mock.patch('esi_leap.api.controllers.v1.offer.get_resource_object') - @mock.patch('oslo_utils.uuidutils.generate_uuid') - @mock.patch('esi_leap.api.controllers.v1.utils.check_resource_admin') - @mock.patch('esi_leap.objects.offer.Offer.create') - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'offer_get_dict_with_added_info') - def test_post(self, mock_ogdwai, mock_create, mock_cra, - mock_generate_uuid, mock_gro): + data = self.get_json("/offers") + self.assertEqual([], data["offers"]) + + @mock.patch("esi_leap.api.controllers.v1.offer.get_resource_object") + @mock.patch("oslo_utils.uuidutils.generate_uuid") + @mock.patch("esi_leap.api.controllers.v1.utils.check_resource_admin") + @mock.patch("esi_leap.objects.offer.Offer.create") + @mock.patch("esi_leap.api.controllers.v1.utils." "offer_get_dict_with_added_info") + def test_post( + self, mock_ogdwai, mock_create, mock_cra, mock_generate_uuid, mock_gro + ): resource = TestNode(self.test_offer.resource_uuid) mock_gro.return_value = resource mock_generate_uuid.return_value = self.test_offer.uuid @@ -132,237 +131,256 @@ def test_post(self, mock_ogdwai, mock_create, mock_cra, mock_ogdwai.return_value = self.test_offer.to_dict() data = { - 'resource_type': self.test_offer.resource_type, - 'resource_uuid': self.test_offer.resource_uuid, - 'name': self.test_offer.name, - 'start_time': '2016-07-16T00:00:00', - 'end_time': '2016-10-24T00:00:00' + "resource_type": self.test_offer.resource_type, + "resource_uuid": self.test_offer.resource_uuid, + "name": self.test_offer.name, + "start_time": "2016-07-16T00:00:00", + "end_time": "2016-10-24T00:00:00", } - request = self.post_json('/offers', data) + request = self.post_json("/offers", data) - data['project_id'] = self.context.project_id - data['uuid'] = self.test_offer.uuid - data['status'] = statuses.AVAILABLE - data['parent_lease_uuid'] = None + data["project_id"] = self.context.project_id + data["uuid"] = self.test_offer.uuid + data["status"] = statuses.AVAILABLE + data["parent_lease_uuid"] = None - mock_gro.assert_called_once_with(self.test_offer.resource_type, - self.test_offer.resource_uuid) + mock_gro.assert_called_once_with( + self.test_offer.resource_type, self.test_offer.resource_uuid + ) mock_cra.assert_called_once_with( - self.context.to_policy_values(), - resource, - self.context.project_id) + self.context.to_policy_values(), resource, self.context.project_id + ) mock_create.assert_called_once() mock_ogdwai.assert_called_once() self.assertEqual(data, request.json) self.assertEqual(http_client.CREATED, request.status_int) - @mock.patch('esi_leap.api.controllers.v1.offer.get_resource_object') - @mock.patch('oslo_utils.uuidutils.generate_uuid') - @mock.patch('esi_leap.api.controllers.v1.utils.check_resource_admin') - @mock.patch('esi_leap.objects.offer.Offer.create') - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'offer_get_dict_with_added_info') - def test_post_default_resource_type(self, mock_ogdwai, mock_create, - mock_cra, mock_generate_uuid, - mock_gro): + @mock.patch("esi_leap.api.controllers.v1.offer.get_resource_object") + @mock.patch("oslo_utils.uuidutils.generate_uuid") + @mock.patch("esi_leap.api.controllers.v1.utils.check_resource_admin") + @mock.patch("esi_leap.objects.offer.Offer.create") + @mock.patch("esi_leap.api.controllers.v1.utils." "offer_get_dict_with_added_info") + def test_post_default_resource_type( + self, mock_ogdwai, mock_create, mock_cra, mock_generate_uuid, mock_gro + ): resource = IronicNode(self.test_offer_drt.resource_uuid) mock_gro.return_value = resource mock_generate_uuid.return_value = self.test_offer_drt.uuid mock_ogdwai.return_value = self.test_offer_drt.to_dict() data = { - 'resource_uuid': self.test_offer_drt.resource_uuid, - 'name': self.test_offer_drt.name, - 'start_time': '2016-07-16T00:00:00', - 'end_time': '2016-10-24T00:00:00' + "resource_uuid": self.test_offer_drt.resource_uuid, + "name": self.test_offer_drt.name, + "start_time": "2016-07-16T00:00:00", + "end_time": "2016-10-24T00:00:00", } - request = self.post_json('/offers', data) + request = self.post_json("/offers", data) - data['project_id'] = self.context.project_id - data['uuid'] = self.test_offer_drt.uuid - data['status'] = statuses.AVAILABLE - data['resource_type'] = 'ironic_node' - data['parent_lease_uuid'] = None + data["project_id"] = self.context.project_id + data["uuid"] = self.test_offer_drt.uuid + data["status"] = statuses.AVAILABLE + data["resource_type"] = "ironic_node" + data["parent_lease_uuid"] = None - mock_gro.assert_called_once_with(self.test_offer_drt.resource_type, - self.test_offer_drt.resource_uuid) + mock_gro.assert_called_once_with( + self.test_offer_drt.resource_type, self.test_offer_drt.resource_uuid + ) mock_cra.assert_called_once_with( - self.context.to_policy_values(), - resource, - self.context.project_id) + self.context.to_policy_values(), resource, self.context.project_id + ) mock_create.assert_called_once() mock_ogdwai.assert_called_once() self.assertEqual(data, request.json) self.assertEqual(http_client.CREATED, request.status_int) - @mock.patch('esi_leap.api.controllers.v1.offer.get_resource_object') - @mock.patch('esi_leap.common.keystone.get_project_uuid_from_ident') - @mock.patch('oslo_utils.uuidutils.generate_uuid') - @mock.patch('esi_leap.api.controllers.v1.utils.check_resource_admin') - @mock.patch('esi_leap.objects.offer.Offer.create') - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'offer_get_dict_with_added_info') - def test_post_lessee(self, mock_ogdwai, mock_create, mock_cra, - mock_generate_uuid, mock_gpufi, mock_gro): + @mock.patch("esi_leap.api.controllers.v1.offer.get_resource_object") + @mock.patch("esi_leap.common.keystone.get_project_uuid_from_ident") + @mock.patch("oslo_utils.uuidutils.generate_uuid") + @mock.patch("esi_leap.api.controllers.v1.utils.check_resource_admin") + @mock.patch("esi_leap.objects.offer.Offer.create") + @mock.patch("esi_leap.api.controllers.v1.utils." "offer_get_dict_with_added_info") + def test_post_lessee( + self, + mock_ogdwai, + mock_create, + mock_cra, + mock_generate_uuid, + mock_gpufi, + mock_gro, + ): resource = TestNode(self.test_offer_lessee.resource_uuid) mock_gro.return_value = resource - mock_gpufi.return_value = 'lessee_uuid' + mock_gpufi.return_value = "lessee_uuid" mock_generate_uuid.return_value = self.test_offer_lessee.uuid mock_create.return_value = self.test_offer_lessee mock_ogdwai.return_value = self.test_offer_lessee.to_dict() data = { - 'resource_type': self.test_offer_lessee.resource_type, - 'resource_uuid': self.test_offer_lessee.resource_uuid, - 'name': self.test_offer_lessee.name, - 'start_time': '2016-07-16T00:00:00', - 'end_time': '2016-10-24T00:00:00', - 'lessee_id': 'lessee-uuid' + "resource_type": self.test_offer_lessee.resource_type, + "resource_uuid": self.test_offer_lessee.resource_uuid, + "name": self.test_offer_lessee.name, + "start_time": "2016-07-16T00:00:00", + "end_time": "2016-10-24T00:00:00", + "lessee_id": "lessee-uuid", } - request = self.post_json('/offers', data) + request = self.post_json("/offers", data) - data['project_id'] = self.context.project_id - data['uuid'] = self.test_offer_lessee.uuid - data['status'] = statuses.AVAILABLE - data['parent_lease_uuid'] = None + data["project_id"] = self.context.project_id + data["uuid"] = self.test_offer_lessee.uuid + data["status"] = statuses.AVAILABLE + data["parent_lease_uuid"] = None - mock_gro.assert_called_once_with(self.test_offer_lessee.resource_type, - self.test_offer_lessee.resource_uuid) - mock_gpufi.assert_called_once_with('lessee-uuid') + mock_gro.assert_called_once_with( + self.test_offer_lessee.resource_type, self.test_offer_lessee.resource_uuid + ) + mock_gpufi.assert_called_once_with("lessee-uuid") mock_cra.assert_called_once_with( - self.context.to_policy_values(), - resource, - self.context.project_id) + self.context.to_policy_values(), resource, self.context.project_id + ) mock_create.assert_called_once() mock_ogdwai.assert_called_once() self.assertEqual(data, request.json) self.assertEqual(http_client.CREATED, request.status_int) - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'check_resource_lease_admin') - @mock.patch('esi_leap.api.controllers.v1.offer.get_resource_object') - @mock.patch('oslo_utils.uuidutils.generate_uuid') - @mock.patch('esi_leap.api.controllers.v1.utils.check_resource_admin') - @mock.patch('esi_leap.objects.offer.Offer.create') - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'offer_get_dict_with_added_info') - def test_post_non_admin_parent_lease(self, mock_ogdwai, mock_create, - mock_cra, mock_generate_uuid, - mock_gro, mock_crla): + @mock.patch("esi_leap.api.controllers.v1.utils." "check_resource_lease_admin") + @mock.patch("esi_leap.api.controllers.v1.offer.get_resource_object") + @mock.patch("oslo_utils.uuidutils.generate_uuid") + @mock.patch("esi_leap.api.controllers.v1.utils.check_resource_admin") + @mock.patch("esi_leap.objects.offer.Offer.create") + @mock.patch("esi_leap.api.controllers.v1.utils." "offer_get_dict_with_added_info") + def test_post_non_admin_parent_lease( + self, + mock_ogdwai, + mock_create, + mock_cra, + mock_generate_uuid, + mock_gro, + mock_crla, + ): resource = TestNode(self.test_offer_with_parent.resource_uuid) mock_gro.return_value = resource mock_generate_uuid.return_value = self.test_offer_with_parent.uuid mock_create.return_value = self.test_offer_with_parent mock_ogdwai.return_value = self.test_offer_with_parent.to_dict() mock_cra.side_effect = exception.HTTPResourceForbidden( - resource_type='test_node', - resource=self.test_offer_with_parent.resource_uuid) + resource_type="test_node", + resource=self.test_offer_with_parent.resource_uuid, + ) mock_crla.return_value = self.test_offer_with_parent.parent_lease_uuid data = { - 'resource_type': self.test_offer_with_parent.resource_type, - 'resource_uuid': self.test_offer_with_parent.resource_uuid, - 'name': self.test_offer_with_parent.name, - 'start_time': '2016-07-16T00:00:00', - 'end_time': '2016-10-24T00:00:00' + "resource_type": self.test_offer_with_parent.resource_type, + "resource_uuid": self.test_offer_with_parent.resource_uuid, + "name": self.test_offer_with_parent.name, + "start_time": "2016-07-16T00:00:00", + "end_time": "2016-10-24T00:00:00", } - request = self.post_json('/offers', data) + request = self.post_json("/offers", data) - data['project_id'] = self.context.project_id - data['uuid'] = self.test_offer_with_parent.uuid - data['status'] = statuses.AVAILABLE - data['parent_lease_uuid'] = ( - self.test_offer_with_parent.parent_lease_uuid) + data["project_id"] = self.context.project_id + data["uuid"] = self.test_offer_with_parent.uuid + data["status"] = statuses.AVAILABLE + data["parent_lease_uuid"] = self.test_offer_with_parent.parent_lease_uuid mock_gro.assert_called_once_with( self.test_offer_with_parent.resource_type, - self.test_offer_with_parent.resource_uuid) + self.test_offer_with_parent.resource_uuid, + ) mock_cra.assert_called_once_with( - self.context.to_policy_values(), - resource, - self.context.project_id) + self.context.to_policy_values(), resource, self.context.project_id + ) mock_crla.assert_called_once_with( self.context.to_policy_values(), resource, self.context.project_id, datetime.datetime(2016, 7, 16, 0, 0, 0), - datetime.datetime(2016, 10, 24, 0, 0, 0)) + datetime.datetime(2016, 10, 24, 0, 0, 0), + ) mock_create.assert_called_once() mock_ogdwai.assert_called_once() self.assertEqual(data, request.json) self.assertEqual(http_client.CREATED, request.status_int) - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'check_resource_lease_admin') - @mock.patch('esi_leap.api.controllers.v1.offer.get_resource_object') - @mock.patch('oslo_utils.uuidutils.generate_uuid') - @mock.patch('esi_leap.api.controllers.v1.utils.check_resource_admin') - @mock.patch('esi_leap.objects.offer.Offer.create') - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'offer_get_dict_with_added_info') - def test_post_non_admin_no_parent_lease(self, mock_ogdwai, mock_create, - mock_cra, mock_generate_uuid, - mock_gro, mock_crla): + @mock.patch("esi_leap.api.controllers.v1.utils." "check_resource_lease_admin") + @mock.patch("esi_leap.api.controllers.v1.offer.get_resource_object") + @mock.patch("oslo_utils.uuidutils.generate_uuid") + @mock.patch("esi_leap.api.controllers.v1.utils.check_resource_admin") + @mock.patch("esi_leap.objects.offer.Offer.create") + @mock.patch("esi_leap.api.controllers.v1.utils." "offer_get_dict_with_added_info") + def test_post_non_admin_no_parent_lease( + self, + mock_ogdwai, + mock_create, + mock_cra, + mock_generate_uuid, + mock_gro, + mock_crla, + ): resource = TestNode(self.test_offer_with_parent.resource_uuid) mock_gro.return_value = resource mock_generate_uuid.return_value = self.test_offer_with_parent.uuid mock_create.return_value = self.test_offer_with_parent mock_ogdwai.return_value = self.test_offer_with_parent.to_dict() mock_cra.side_effect = exception.HTTPResourceForbidden( - resource_type='test_node', - resource=self.test_offer_with_parent.resource_uuid) + resource_type="test_node", + resource=self.test_offer_with_parent.resource_uuid, + ) mock_crla.return_value = None data = { - 'resource_type': self.test_offer_with_parent.resource_type, - 'resource_uuid': self.test_offer_with_parent.resource_uuid, - 'name': self.test_offer_with_parent.name, - 'start_time': '2016-07-16T00:00:00', - 'end_time': '2016-10-24T00:00:00' + "resource_type": self.test_offer_with_parent.resource_type, + "resource_uuid": self.test_offer_with_parent.resource_uuid, + "name": self.test_offer_with_parent.name, + "start_time": "2016-07-16T00:00:00", + "end_time": "2016-10-24T00:00:00", } - request = self.post_json('/offers', data, expect_errors=True) + request = self.post_json("/offers", data, expect_errors=True) mock_gro.assert_called_once_with( self.test_offer_with_parent.resource_type, - self.test_offer_with_parent.resource_uuid) + self.test_offer_with_parent.resource_uuid, + ) mock_cra.assert_called_once_with( - self.context.to_policy_values(), - resource, - self.context.project_id) + self.context.to_policy_values(), resource, self.context.project_id + ) mock_crla.assert_called_once_with( self.context.to_policy_values(), resource, self.context.project_id, datetime.datetime(2016, 7, 16, 0, 0, 0), - datetime.datetime(2016, 10, 24, 0, 0, 0)) + datetime.datetime(2016, 10, 24, 0, 0, 0), + ) mock_create.assert_not_called() mock_ogdwai.assert_not_called() self.assertEqual(http_client.FORBIDDEN, request.status_int) - @mock.patch('esi_leap.common.ironic.get_node_list') - @mock.patch('esi_leap.common.keystone.get_project_list') - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'offer_get_dict_with_added_info') - @mock.patch('esi_leap.objects.offer.Offer.get_all') - def test_get_nofilters(self, mock_get_all, mock_ogdwai, mock_gpl, - mock_gnl): + @mock.patch("esi_leap.common.ironic.get_node_list") + @mock.patch("esi_leap.common.keystone.get_project_list") + @mock.patch("esi_leap.api.controllers.v1.utils." "offer_get_dict_with_added_info") + @mock.patch("esi_leap.objects.offer.Offer.get_all") + def test_get_nofilters(self, mock_get_all, mock_ogdwai, mock_gpl, mock_gnl): mock_get_all.return_value = [self.test_offer, self.test_offer_2] mock_ogdwai.side_effect = [ _get_offer_response(self.test_offer, use_datetime=True), - _get_offer_response(self.test_offer_2, use_datetime=True)] + _get_offer_response(self.test_offer_2, use_datetime=True), + ] mock_gpl.return_value = [] mock_gnl.return_value = [] - expected_filters = {'status': statuses.OFFER_CAN_DELETE} - expected_resp = {'offers': [_get_offer_response(self.test_offer), - _get_offer_response(self.test_offer_2)]} + expected_filters = {"status": statuses.OFFER_CAN_DELETE} + expected_resp = { + "offers": [ + _get_offer_response(self.test_offer), + _get_offer_response(self.test_offer_2), + ] + } - request = self.get_json('/offers') + request = self.get_json("/offers") mock_get_all.assert_called_once_with(expected_filters, self.context) mock_gpl.assert_called_once() @@ -370,25 +388,28 @@ def test_get_nofilters(self, mock_get_all, mock_ogdwai, mock_gpl, assert mock_ogdwai.call_count == 2 self.assertEqual(request, expected_resp) - @mock.patch('esi_leap.common.ironic.get_node_list') - @mock.patch('esi_leap.common.keystone.get_project_list') - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'offer_get_dict_with_added_info') - @mock.patch('esi_leap.objects.offer.Offer.get_all') - def test_get_any_status(self, mock_get_all, mock_ogdwai, mock_gpl, - mock_gnl): + @mock.patch("esi_leap.common.ironic.get_node_list") + @mock.patch("esi_leap.common.keystone.get_project_list") + @mock.patch("esi_leap.api.controllers.v1.utils." "offer_get_dict_with_added_info") + @mock.patch("esi_leap.objects.offer.Offer.get_all") + def test_get_any_status(self, mock_get_all, mock_ogdwai, mock_gpl, mock_gnl): mock_get_all.return_value = [self.test_offer, self.test_offer_2] mock_ogdwai.side_effect = [ _get_offer_response(self.test_offer, use_datetime=True), - _get_offer_response(self.test_offer_2, use_datetime=True)] + _get_offer_response(self.test_offer_2, use_datetime=True), + ] mock_gpl.return_value = [] mock_gnl.return_value = [] expected_filters = {} - expected_resp = {'offers': [_get_offer_response(self.test_offer), - _get_offer_response(self.test_offer_2)]} + expected_resp = { + "offers": [ + _get_offer_response(self.test_offer), + _get_offer_response(self.test_offer_2), + ] + } - request = self.get_json('/offers/?status=any') + request = self.get_json("/offers/?status=any") mock_get_all.assert_called_once_with(expected_filters, self.context) mock_gpl.assert_called_once() @@ -396,26 +417,28 @@ def test_get_any_status(self, mock_get_all, mock_ogdwai, mock_gpl, assert mock_ogdwai.call_count == 2 self.assertEqual(request, expected_resp) - @mock.patch('esi_leap.common.ironic.get_node_list') - @mock.patch('esi_leap.common.keystone.get_project_list') - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'offer_get_dict_with_added_info') - @mock.patch('esi_leap.objects.offer.Offer.get_all') - def test_get_status_filter(self, mock_get_all, mock_ogdwai, - mock_gpl, mock_gnl): + @mock.patch("esi_leap.common.ironic.get_node_list") + @mock.patch("esi_leap.common.keystone.get_project_list") + @mock.patch("esi_leap.api.controllers.v1.utils." "offer_get_dict_with_added_info") + @mock.patch("esi_leap.objects.offer.Offer.get_all") + def test_get_status_filter(self, mock_get_all, mock_ogdwai, mock_gpl, mock_gnl): mock_get_all.return_value = [self.test_offer, self.test_offer_2] mock_ogdwai.side_effect = [ _get_offer_response(self.test_offer, use_datetime=True), - _get_offer_response(self.test_offer_2, use_datetime=True)] + _get_offer_response(self.test_offer_2, use_datetime=True), + ] mock_gpl.return_value = [] mock_gnl.return_value = [] - expected_filters = {'status': [statuses.AVAILABLE]} - expected_resp = {'offers': [_get_offer_response(self.test_offer), - _get_offer_response(self.test_offer_2)]} + expected_filters = {"status": [statuses.AVAILABLE]} + expected_resp = { + "offers": [ + _get_offer_response(self.test_offer), + _get_offer_response(self.test_offer_2), + ] + } - request = self.get_json( - '/offers/?status=available') + request = self.get_json("/offers/?status=available") mock_get_all.assert_called_once_with(expected_filters, self.context) mock_gpl.assert_called_once() @@ -423,29 +446,35 @@ def test_get_status_filter(self, mock_get_all, mock_ogdwai, assert mock_ogdwai.call_count == 2 self.assertEqual(request, expected_resp) - @mock.patch('esi_leap.common.ironic.get_node_list') - @mock.patch('esi_leap.common.keystone.get_project_list') - @mock.patch('esi_leap.common.keystone.get_project_uuid_from_ident') - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'offer_get_dict_with_added_info') - @mock.patch('esi_leap.objects.offer.Offer.get_all') - def test_get_project_filter(self, mock_get_all, mock_ogdwai, - mock_gpufi, mock_gpl, mock_gnl): + @mock.patch("esi_leap.common.ironic.get_node_list") + @mock.patch("esi_leap.common.keystone.get_project_list") + @mock.patch("esi_leap.common.keystone.get_project_uuid_from_ident") + @mock.patch("esi_leap.api.controllers.v1.utils." "offer_get_dict_with_added_info") + @mock.patch("esi_leap.objects.offer.Offer.get_all") + def test_get_project_filter( + self, mock_get_all, mock_ogdwai, mock_gpufi, mock_gpl, mock_gnl + ): mock_get_all.return_value = [self.test_offer, self.test_offer_2] mock_ogdwai.side_effect = [ _get_offer_response(self.test_offer, use_datetime=True), - _get_offer_response(self.test_offer_2, use_datetime=True)] + _get_offer_response(self.test_offer_2, use_datetime=True), + ] mock_gpufi.return_value = self.context.project_id mock_gpl.return_value = [] mock_gnl.return_value = [] - expected_filters = {'project_id': self.context.project_id, - 'status': statuses.OFFER_CAN_DELETE} - expected_resp = {'offers': [_get_offer_response(self.test_offer), - _get_offer_response(self.test_offer_2)]} + expected_filters = { + "project_id": self.context.project_id, + "status": statuses.OFFER_CAN_DELETE, + } + expected_resp = { + "offers": [ + _get_offer_response(self.test_offer), + _get_offer_response(self.test_offer_2), + ] + } - request = self.get_json( - '/offers/?project_id=' + self.context.project_id) + request = self.get_json("/offers/?project_id=" + self.context.project_id) mock_gpufi.assert_called_once_with(self.context.project_id) mock_get_all.assert_called_once_with(expected_filters, self.context) @@ -454,57 +483,73 @@ def test_get_project_filter(self, mock_get_all, mock_ogdwai, assert mock_ogdwai.call_count == 2 self.assertEqual(request, expected_resp) - @mock.patch('esi_leap.common.ironic.get_node_list') - @mock.patch('esi_leap.common.keystone.get_project_list') - @mock.patch('esi_leap.api.controllers.v1.offer.get_resource_object') - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'offer_get_dict_with_added_info') - @mock.patch('esi_leap.objects.offer.Offer.get_all') - def test_get_resource_filter(self, mock_get_all, mock_ogdwai, mock_gro, - mock_gpl, mock_gnl): + @mock.patch("esi_leap.common.ironic.get_node_list") + @mock.patch("esi_leap.common.keystone.get_project_list") + @mock.patch("esi_leap.api.controllers.v1.offer.get_resource_object") + @mock.patch("esi_leap.api.controllers.v1.utils." "offer_get_dict_with_added_info") + @mock.patch("esi_leap.objects.offer.Offer.get_all") + def test_get_resource_filter( + self, mock_get_all, mock_ogdwai, mock_gro, mock_gpl, mock_gnl + ): mock_get_all.return_value = [self.test_offer, self.test_offer_2] mock_ogdwai.side_effect = [ _get_offer_response(self.test_offer, use_datetime=True), - _get_offer_response(self.test_offer_2, use_datetime=True)] - mock_gro.return_value = TestNode('54321') + _get_offer_response(self.test_offer_2, use_datetime=True), + ] + mock_gro.return_value = TestNode("54321") mock_gpl.return_value = [] mock_gnl.return_value = [] - expected_filters = {'status': statuses.OFFER_CAN_DELETE, - 'resource_uuid': '54321', - 'resource_type': 'test_node'} - expected_resp = {'offers': [_get_offer_response(self.test_offer), - _get_offer_response(self.test_offer_2)]} + expected_filters = { + "status": statuses.OFFER_CAN_DELETE, + "resource_uuid": "54321", + "resource_type": "test_node", + } + expected_resp = { + "offers": [ + _get_offer_response(self.test_offer), + _get_offer_response(self.test_offer_2), + ] + } - request = self.get_json('/offers/?resource_uuid=54321&' - 'resource_type=test_node') + request = self.get_json( + "/offers/?resource_uuid=54321&" "resource_type=test_node" + ) - mock_gro.assert_called_once_with('test_node', '54321') + mock_gro.assert_called_once_with("test_node", "54321") mock_get_all.assert_called_once_with(expected_filters, self.context) mock_gpl.assert_called_once() mock_gnl.assert_called_once() assert mock_ogdwai.call_count == 2 self.assertEqual(request, expected_resp) - @mock.patch('esi_leap.common.ironic.get_node_list') - @mock.patch('esi_leap.common.keystone.get_project_list') - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'offer_get_dict_with_added_info') - @mock.patch('esi_leap.objects.offer.Offer.get_all') - def test_get_resource_class_filter(self, mock_get_all, mock_ogdwai, - mock_gpl, mock_gnl): - mock_get_all.return_value = [self.test_offer, - self.test_offer_2, self.test_offer_drt] + @mock.patch("esi_leap.common.ironic.get_node_list") + @mock.patch("esi_leap.common.keystone.get_project_list") + @mock.patch("esi_leap.api.controllers.v1.utils." "offer_get_dict_with_added_info") + @mock.patch("esi_leap.objects.offer.Offer.get_all") + def test_get_resource_class_filter( + self, mock_get_all, mock_ogdwai, mock_gpl, mock_gnl + ): + mock_get_all.return_value = [ + self.test_offer, + self.test_offer_2, + self.test_offer_drt, + ] mock_ogdwai.side_effect = [ _get_offer_response(self.test_offer, use_datetime=True), _get_offer_response(self.test_offer_2, use_datetime=True), - _get_offer_response(self.test_offer_drt, use_datetime=True)] + _get_offer_response(self.test_offer_drt, use_datetime=True), + ] mock_gpl.return_value = [] mock_gnl.return_value = [] - expected_filters = {'status': statuses.OFFER_CAN_DELETE} - expected_resp = {'offers': [_get_offer_response(self.test_offer), - _get_offer_response(self.test_offer_2)]} - request = self.get_json('/offers/?resource_class=fake') + expected_filters = {"status": statuses.OFFER_CAN_DELETE} + expected_resp = { + "offers": [ + _get_offer_response(self.test_offer), + _get_offer_response(self.test_offer_2), + ] + } + request = self.get_json("/offers/?resource_class=fake") mock_get_all.assert_called_once_with(expected_filters, self.context) mock_gpl.assert_called_once() @@ -512,65 +557,76 @@ def test_get_resource_class_filter(self, mock_get_all, mock_ogdwai, assert mock_ogdwai.call_count == 3 self.assertEqual(request, expected_resp) - @mock.patch('esi_leap.common.ironic.get_node_list') - @mock.patch('esi_leap.common.keystone.get_project_list') - @mock.patch('esi_leap.api.controllers.v1.offer.get_resource_object') - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'offer_get_dict_with_added_info') - @mock.patch('esi_leap.objects.offer.Offer.get_all') - def test_get_resource_filter_default_resource_type(self, mock_get_all, - mock_ogdwai, - mock_gro, - mock_gpl, - mock_gnl): + @mock.patch("esi_leap.common.ironic.get_node_list") + @mock.patch("esi_leap.common.keystone.get_project_list") + @mock.patch("esi_leap.api.controllers.v1.offer.get_resource_object") + @mock.patch("esi_leap.api.controllers.v1.utils." "offer_get_dict_with_added_info") + @mock.patch("esi_leap.objects.offer.Offer.get_all") + def test_get_resource_filter_default_resource_type( + self, mock_get_all, mock_ogdwai, mock_gro, mock_gpl, mock_gnl + ): fake_uuid = uuidutils.generate_uuid() mock_get_all.return_value = [self.test_offer, self.test_offer_2] mock_ogdwai.side_effect = [ _get_offer_response(self.test_offer, use_datetime=True), - _get_offer_response(self.test_offer_2, use_datetime=True)] + _get_offer_response(self.test_offer_2, use_datetime=True), + ] mock_gro.return_value = IronicNode(fake_uuid) mock_gpl.return_value = [] mock_gnl.return_value = [] - expected_filters = {'status': statuses.OFFER_CAN_DELETE, - 'resource_uuid': fake_uuid, - 'resource_type': 'ironic_node'} - expected_resp = {'offers': [_get_offer_response(self.test_offer), - _get_offer_response(self.test_offer_2)]} + expected_filters = { + "status": statuses.OFFER_CAN_DELETE, + "resource_uuid": fake_uuid, + "resource_type": "ironic_node", + } + expected_resp = { + "offers": [ + _get_offer_response(self.test_offer), + _get_offer_response(self.test_offer_2), + ] + } - request = self.get_json('/offers/?resource_uuid=%s' % fake_uuid) - mock_gro.assert_called_once_with('ironic_node', fake_uuid) + request = self.get_json("/offers/?resource_uuid=%s" % fake_uuid) + mock_gro.assert_called_once_with("ironic_node", fake_uuid) mock_get_all.assert_called_once_with(expected_filters, self.context) mock_gpl.assert_called_once() mock_gnl.assert_called_once() assert mock_ogdwai.call_count == 2 self.assertEqual(request, expected_resp) - @mock.patch('esi_leap.common.ironic.get_node_list') - @mock.patch('esi_leap.common.keystone.get_project_list') - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'offer_get_dict_with_added_info') - @mock.patch('esi_leap.objects.offer.Offer.get_all') - @mock.patch('esi_leap.api.controllers.v1.utils.policy_authorize') - def test_get_lessee_filter(self, mock_authorize, mock_get_all, - mock_ogdwai, mock_gpl, mock_gnl): + @mock.patch("esi_leap.common.ironic.get_node_list") + @mock.patch("esi_leap.common.keystone.get_project_list") + @mock.patch("esi_leap.api.controllers.v1.utils." "offer_get_dict_with_added_info") + @mock.patch("esi_leap.objects.offer.Offer.get_all") + @mock.patch("esi_leap.api.controllers.v1.utils.policy_authorize") + def test_get_lessee_filter( + self, mock_authorize, mock_get_all, mock_ogdwai, mock_gpl, mock_gnl + ): mock_get_all.return_value = [self.test_offer, self.test_offer_2] mock_ogdwai.side_effect = [ _get_offer_response(self.test_offer, use_datetime=True), - _get_offer_response(self.test_offer_2, use_datetime=True)] + _get_offer_response(self.test_offer_2, use_datetime=True), + ] mock_authorize.side_effect = [ None, - exception.HTTPForbidden(rule='esi_leap:offer:get') + exception.HTTPForbidden(rule="esi_leap:offer:get"), ] mock_gpl.return_value = [] mock_gnl.return_value = [] - expected_filters = {'status': statuses.OFFER_CAN_DELETE, - 'lessee_id': self.context.project_id} - expected_resp = {'offers': [_get_offer_response(self.test_offer), - _get_offer_response(self.test_offer_2)]} + expected_filters = { + "status": statuses.OFFER_CAN_DELETE, + "lessee_id": self.context.project_id, + } + expected_resp = { + "offers": [ + _get_offer_response(self.test_offer), + _get_offer_response(self.test_offer_2), + ] + } - request = self.get_json('/offers') + request = self.get_json("/offers") mock_get_all.assert_called_once_with(expected_filters, self.context) mock_gpl.assert_called_once() @@ -578,97 +634,100 @@ def test_get_lessee_filter(self, mock_authorize, mock_get_all, assert mock_ogdwai.call_count == 2 self.assertEqual(request, expected_resp) - @mock.patch('esi_leap.api.controllers.v1.utils.check_offer_lessee') - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'check_offer_policy_and_retrieve') - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'offer_get_dict_with_added_info') + @mock.patch("esi_leap.api.controllers.v1.utils.check_offer_lessee") + @mock.patch("esi_leap.api.controllers.v1.utils." "check_offer_policy_and_retrieve") + @mock.patch("esi_leap.api.controllers.v1.utils." "offer_get_dict_with_added_info") def test_get_one(self, mock_ogdwai, mock_copar, mock_col): mock_copar.return_value = self.test_offer mock_ogdwai.return_value = self.test_offer.to_dict() - self.get_json('/offers/' + self.test_offer.uuid) + self.get_json("/offers/" + self.test_offer.uuid) - mock_copar.assert_called_once_with(self.context, - 'esi_leap:offer:get', - self.test_offer.uuid) - mock_col.assert_called_once_with(self.context.to_policy_values(), - self.test_offer) + mock_copar.assert_called_once_with( + self.context, "esi_leap:offer:get", self.test_offer.uuid + ) + mock_col.assert_called_once_with( + self.context.to_policy_values(), self.test_offer + ) mock_ogdwai.assert_called_once_with(self.test_offer) - @mock.patch('oslo_utils.uuidutils.generate_uuid') - @mock.patch('esi_leap.objects.lease.Lease.create') - @mock.patch('esi_leap.api.controllers.v1.utils.check_offer_lessee') - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'check_offer_policy_and_retrieve') - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'lease_get_dict_with_added_info') - def test_claim(self, mock_lgdwai, mock_copar, mock_col, mock_lease_create, - mock_generate_uuid): - lease_uuid = '12345' + @mock.patch("oslo_utils.uuidutils.generate_uuid") + @mock.patch("esi_leap.objects.lease.Lease.create") + @mock.patch("esi_leap.api.controllers.v1.utils.check_offer_lessee") + @mock.patch("esi_leap.api.controllers.v1.utils." "check_offer_policy_and_retrieve") + @mock.patch("esi_leap.api.controllers.v1.utils." "lease_get_dict_with_added_info") + def test_claim( + self, mock_lgdwai, mock_copar, mock_col, mock_lease_create, mock_generate_uuid + ): + lease_uuid = "12345" mock_generate_uuid.return_value = lease_uuid mock_copar.return_value = self.test_offer data = { - 'name': 'lease_claim', - 'start_time': '2016-07-16T19:20:30', - 'end_time': '2016-08-16T19:20:30' + "name": "lease_claim", + "start_time": "2016-07-16T19:20:30", + "end_time": "2016-08-16T19:20:30", } - request = self.post_json('/offers/' + self.test_offer.uuid + '/claim', - data) + request = self.post_json("/offers/" + self.test_offer.uuid + "/claim", data) - mock_copar.assert_called_once_with(self.context, - 'esi_leap:offer:claim', - self.test_offer.uuid, - [statuses.AVAILABLE]) - mock_col.assert_called_once_with(self.context.to_policy_values(), - self.test_offer) + mock_copar.assert_called_once_with( + self.context, + "esi_leap:offer:claim", + self.test_offer.uuid, + [statuses.AVAILABLE], + ) + mock_col.assert_called_once_with( + self.context.to_policy_values(), self.test_offer + ) mock_lease_create.assert_called_once() mock_lgdwai.assert_called_once() self.assertEqual(http_client.CREATED, request.status_int) - @mock.patch('oslo_utils.uuidutils.generate_uuid') - @mock.patch('esi_leap.objects.lease.Lease.create') - @mock.patch('esi_leap.api.controllers.v1.utils.check_offer_lessee') - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'check_offer_policy_and_retrieve') - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'lease_get_dict_with_added_info') - def test_claim_parent_lease(self, mock_lgdwai, mock_copar, mock_col, - mock_lease_create, mock_generate_uuid): - lease_uuid = '12345' + @mock.patch("oslo_utils.uuidutils.generate_uuid") + @mock.patch("esi_leap.objects.lease.Lease.create") + @mock.patch("esi_leap.api.controllers.v1.utils.check_offer_lessee") + @mock.patch("esi_leap.api.controllers.v1.utils." "check_offer_policy_and_retrieve") + @mock.patch("esi_leap.api.controllers.v1.utils." "lease_get_dict_with_added_info") + def test_claim_parent_lease( + self, mock_lgdwai, mock_copar, mock_col, mock_lease_create, mock_generate_uuid + ): + lease_uuid = "12345" mock_generate_uuid.return_value = lease_uuid mock_copar.return_value = self.test_offer_with_parent data = { - 'name': 'lease_claim', - 'start_time': '2016-07-16T19:20:30', - 'end_time': '2016-08-16T19:20:30' + "name": "lease_claim", + "start_time": "2016-07-16T19:20:30", + "end_time": "2016-08-16T19:20:30", } request = self.post_json( - '/offers/' + self.test_offer_with_parent.uuid + '/claim', - data) - - mock_copar.assert_called_once_with(self.context, - 'esi_leap:offer:claim', - self.test_offer_with_parent.uuid, - [statuses.AVAILABLE]) - mock_col.assert_called_once_with(self.context.to_policy_values(), - self.test_offer_with_parent) + "/offers/" + self.test_offer_with_parent.uuid + "/claim", data + ) + + mock_copar.assert_called_once_with( + self.context, + "esi_leap:offer:claim", + self.test_offer_with_parent.uuid, + [statuses.AVAILABLE], + ) + mock_col.assert_called_once_with( + self.context.to_policy_values(), self.test_offer_with_parent + ) mock_lease_create.assert_called_once() mock_lgdwai.assert_called_once() self.assertEqual(http_client.CREATED, request.status_int) - @mock.patch('esi_leap.api.controllers.v1.utils.' - 'check_offer_policy_and_retrieve') - @mock.patch('esi_leap.objects.offer.Offer.cancel') + @mock.patch("esi_leap.api.controllers.v1.utils." "check_offer_policy_and_retrieve") + @mock.patch("esi_leap.objects.offer.Offer.cancel") def test_delete(self, mock_cancel, mock_copar): mock_copar.return_value = self.test_offer - self.delete_json('/offers/' + self.test_offer.uuid) + self.delete_json("/offers/" + self.test_offer.uuid) - mock_copar.assert_called_once_with(self.context, - 'esi_leap:offer:delete', - self.test_offer.uuid, - statuses.OFFER_CAN_DELETE) + mock_copar.assert_called_once_with( + self.context, + "esi_leap:offer:delete", + self.test_offer.uuid, + statuses.OFFER_CAN_DELETE, + ) mock_cancel.assert_called_once() diff --git a/esi_leap/tests/api/controllers/v1/test_utils.py b/esi_leap/tests/api/controllers/v1/test_utils.py index edfbd41e..b43083c2 100644 --- a/esi_leap/tests/api/controllers/v1/test_utils.py +++ b/esi_leap/tests/api/controllers/v1/test_utils.py @@ -27,121 +27,119 @@ from esi_leap.resource_objects.test_node import TestNode -admin_ctx = ctx.RequestContext(project_id='adminid', roles=['admin']) +admin_ctx = ctx.RequestContext(project_id="adminid", roles=["admin"]) -owner_ctx = ctx.RequestContext(project_id='ownerid', roles=['owner']) +owner_ctx = ctx.RequestContext(project_id="ownerid", roles=["owner"]) owner_ctx_dict = owner_ctx.to_policy_values() -lessee_ctx = ctx.RequestContext(project_id='lesseeid', roles=['lessee']) +lessee_ctx = ctx.RequestContext(project_id="lesseeid", roles=["lessee"]) lessee_ctx_dict = lessee_ctx.to_policy_values() -owner_ctx_2 = ctx.RequestContext(project_id='ownerid2', roles=['owner']) -lessee_ctx_2 = ctx.RequestContext(project_id='lesseeid2', roles=['lessee']) +owner_ctx_2 = ctx.RequestContext(project_id="ownerid2", roles=["owner"]) +lessee_ctx_2 = ctx.RequestContext(project_id="lesseeid2", roles=["lessee"]) start = datetime.datetime(2016, 7, 16) -start_iso = '2016-07-16T00:00:00' +start_iso = "2016-07-16T00:00:00" end = start + datetime.timedelta(days=100) -end_iso = '2016-10-24T00:00:00' +end_iso = "2016-10-24T00:00:00" -test_node_1 = TestNode('111', owner_ctx.project_id) -test_node_2 = TestNode('bbb', owner_ctx_2.project_id) +test_node_1 = TestNode("111", owner_ctx.project_id) +test_node_2 = TestNode("bbb", owner_ctx_2.project_id) o_uuid = uuidutils.generate_uuid() test_offer = offer.Offer( - resource_type='test_node', + resource_type="test_node", resource_uuid=test_node_1._uuid, - name='o', + name="o", uuid=o_uuid, lessee_id=None, status=statuses.AVAILABLE, start_time=start, end_time=end, - project_id=owner_ctx.project_id + project_id=owner_ctx.project_id, ) test_offer_2 = offer.Offer( - resource_type='test_node', + resource_type="test_node", resource_uuid=test_node_1._uuid, - name='o', + name="o", uuid=uuidutils.generate_uuid(), lessee_id=None, status=statuses.EXPIRED, start_time=start, end_time=end, - project_id=owner_ctx.project_id + project_id=owner_ctx.project_id, ) test_offer_lessee_match = offer.Offer( - resource_type='test_node', + resource_type="test_node", resource_uuid=test_node_1._uuid, - name='o', + name="o", uuid=uuidutils.generate_uuid(), - lessee_id='lesseeid', + lessee_id="lesseeid", status=statuses.EXPIRED, start_time=start, end_time=end, - project_id=owner_ctx.project_id + project_id=owner_ctx.project_id, ) test_offer_lessee_no_match = offer.Offer( - resource_type='test_node', + resource_type="test_node", resource_uuid=test_node_1._uuid, - name='o', + name="o", uuid=uuidutils.generate_uuid(), - lessee_id='otherlesseeid', + lessee_id="otherlesseeid", status=statuses.EXPIRED, start_time=start, end_time=end, - project_id=owner_ctx.project_id + project_id=owner_ctx.project_id, ) test_lease = lease.Lease( offer_uuid=o_uuid, - name='c', + name="c", uuid=uuidutils.generate_uuid(), project_id=lessee_ctx.project_id, owner_id=owner_ctx.project_id, - status=statuses.CREATED + status=statuses.CREATED, ) test_lease_2 = lease.Lease( offer_uuid=o_uuid, - name='c', + name="c", uuid=uuidutils.generate_uuid(), project_id=lessee_ctx.project_id, owner_id=owner_ctx.project_id, - status=statuses.CREATED + status=statuses.CREATED, ) test_lease_3 = lease.Lease( offer_uuid=o_uuid, - name='c', + name="c", uuid=uuidutils.generate_uuid(), project_id=lessee_ctx_2.project_id, owner_id=owner_ctx.project_id, - status=statuses.CREATED + status=statuses.CREATED, ) test_lease_4 = lease.Lease( offer_uuid=o_uuid, - name='c2', + name="c2", uuid=uuidutils.generate_uuid(), project_id=lessee_ctx_2.project_id, owner_id=owner_ctx.project_id, - status=statuses.CREATED + status=statuses.CREATED, ) class TestGetObjectUtils(testtools.TestCase): - - @mock.patch('oslo_utils.uuidutils.is_uuid_like') - @mock.patch('esi_leap.objects.offer.Offer.get') + @mock.patch("oslo_utils.uuidutils.is_uuid_like") + @mock.patch("esi_leap.objects.offer.Offer.get") def test_get_offer_uuid(self, mock_offer_get, mock_is_uuid_like): - mock_is_uuid_like.return_value = True mock_offer_get.return_value = test_offer @@ -152,10 +150,9 @@ def test_get_offer_uuid(self, mock_offer_get, mock_is_uuid_like): mock_is_uuid_like.assert_called_once_with(test_offer.uuid) mock_offer_get.assert_called_once_with(test_offer.uuid) - @mock.patch('oslo_utils.uuidutils.is_uuid_like') - @mock.patch('esi_leap.objects.offer.Offer.get') + @mock.patch("oslo_utils.uuidutils.is_uuid_like") + @mock.patch("esi_leap.objects.offer.Offer.get") def test_get_offer_uuid_available(self, mock_offer_get, mock_is_uuid_like): - mock_is_uuid_like.return_value = True mock_offer_get.return_value = test_offer @@ -166,26 +163,22 @@ def test_get_offer_uuid_available(self, mock_offer_get, mock_is_uuid_like): mock_is_uuid_like.assert_called_once_with(test_offer.uuid) mock_offer_get.assert_called_once_with(test_offer.uuid) - @mock.patch('oslo_utils.uuidutils.is_uuid_like') - @mock.patch('esi_leap.objects.offer.Offer.get') - def test_get_offer_uuid_bad_status(self, mock_offer_get, - mock_is_uuid_like): - + @mock.patch("oslo_utils.uuidutils.is_uuid_like") + @mock.patch("esi_leap.objects.offer.Offer.get") + def test_get_offer_uuid_bad_status(self, mock_offer_get, mock_is_uuid_like): mock_is_uuid_like.return_value = True mock_offer_get.return_value = test_offer - self.assertRaises(exception.OfferNotFound, - utils.get_offer, - test_offer.uuid, statuses.DELETED) + self.assertRaises( + exception.OfferNotFound, utils.get_offer, test_offer.uuid, statuses.DELETED + ) mock_is_uuid_like.assert_called_once_with(test_offer.uuid) mock_offer_get.assert_called_once_with(test_offer.uuid) - @mock.patch('oslo_utils.uuidutils.is_uuid_like') - @mock.patch('esi_leap.objects.offer.Offer.get_all') - def test_get_offer_name_available(self, mock_offer_get_all, - mock_is_uuid_like): - + @mock.patch("oslo_utils.uuidutils.is_uuid_like") + @mock.patch("esi_leap.objects.offer.Offer.get_all") + def test_get_offer_name_available(self, mock_offer_get_all, mock_is_uuid_like): mock_is_uuid_like.return_value = False mock_offer_get_all.return_value = [test_offer] @@ -195,13 +188,12 @@ def test_get_offer_name_available(self, mock_offer_get_all, mock_is_uuid_like.assert_called_once_with(test_offer.name) mock_offer_get_all.assert_called_once_with( - {'name': test_offer.name, - 'status': statuses.AVAILABLE}) + {"name": test_offer.name, "status": statuses.AVAILABLE} + ) - @mock.patch('oslo_utils.uuidutils.is_uuid_like') - @mock.patch('esi_leap.objects.lease.Lease.get') + @mock.patch("oslo_utils.uuidutils.is_uuid_like") + @mock.patch("esi_leap.objects.lease.Lease.get") def test_get_lease_uuid(self, mock_lease_get, mock_is_uuid_like): - mock_is_uuid_like.return_value = True mock_lease_get.return_value = test_lease @@ -212,10 +204,9 @@ def test_get_lease_uuid(self, mock_lease_get, mock_is_uuid_like): mock_is_uuid_like.assert_called_once_with(test_lease.uuid) mock_lease_get.assert_called_once_with(test_lease.uuid) - @mock.patch('oslo_utils.uuidutils.is_uuid_like') - @mock.patch('esi_leap.objects.lease.Lease.get') + @mock.patch("oslo_utils.uuidutils.is_uuid_like") + @mock.patch("esi_leap.objects.lease.Lease.get") def test_get_lease_uuid_available(self, mock_lease_get, mock_is_uuid_like): - mock_is_uuid_like.return_value = True mock_lease_get.return_value = test_lease @@ -226,26 +217,22 @@ def test_get_lease_uuid_available(self, mock_lease_get, mock_is_uuid_like): mock_is_uuid_like.assert_called_once_with(test_lease.uuid) mock_lease_get.assert_called_once_with(test_lease.uuid) - @mock.patch('oslo_utils.uuidutils.is_uuid_like') - @mock.patch('esi_leap.objects.lease.Lease.get') - def test_get_lease_uuid_bad_status(self, mock_lease_get, - mock_is_uuid_like): - + @mock.patch("oslo_utils.uuidutils.is_uuid_like") + @mock.patch("esi_leap.objects.lease.Lease.get") + def test_get_lease_uuid_bad_status(self, mock_lease_get, mock_is_uuid_like): mock_is_uuid_like.return_value = True mock_lease_get.return_value = test_lease - self.assertRaises(exception.LeaseNotFound, - utils.get_lease, - test_lease.uuid, statuses.DELETED) + self.assertRaises( + exception.LeaseNotFound, utils.get_lease, test_lease.uuid, statuses.DELETED + ) mock_is_uuid_like.assert_called_once_with(test_lease.uuid) mock_lease_get.assert_called_once_with(test_lease.uuid) - @mock.patch('oslo_utils.uuidutils.is_uuid_like') - @mock.patch('esi_leap.objects.lease.Lease.get_all') - def test_get_lease_name_active(self, mock_lease_get_all, - mock_is_uuid_like): - + @mock.patch("oslo_utils.uuidutils.is_uuid_like") + @mock.patch("esi_leap.objects.lease.Lease.get_all") + def test_get_lease_name_active(self, mock_lease_get_all, mock_is_uuid_like): mock_is_uuid_like.return_value = False mock_lease_get_all.return_value = [test_lease] @@ -255,73 +242,79 @@ def test_get_lease_name_active(self, mock_lease_get_all, mock_is_uuid_like.assert_called_once_with(test_lease.name) mock_lease_get_all.assert_called_once_with( - {'name': test_lease.name, - 'status': statuses.ACTIVE}) + {"name": test_lease.name, "status": statuses.ACTIVE} + ) class TestCheckResourceAdminUtils(testtools.TestCase): - - @mock.patch.object(test_node_1, 'get_owner_project_id') - @mock.patch('esi_leap.api.controllers.v1.utils.resource_policy_authorize') + @mock.patch.object(test_node_1, "get_owner_project_id") + @mock.patch("esi_leap.api.controllers.v1.utils.resource_policy_authorize") def test_check_resource_admin_owner(self, mock_authorize, mock_gopi): mock_gopi.return_value = owner_ctx.project_id - utils.check_resource_admin(owner_ctx.to_policy_values(), - test_node_1, - test_offer.project_id) + utils.check_resource_admin( + owner_ctx.to_policy_values(), test_node_1, test_offer.project_id + ) mock_gopi.assert_called_once() mock_authorize.assert_not_called() - @mock.patch.object(test_node_2, 'get_owner_project_id') - @mock.patch('esi_leap.api.controllers.v1.utils.resource_policy_authorize') + @mock.patch.object(test_node_2, "get_owner_project_id") + @mock.patch("esi_leap.api.controllers.v1.utils.resource_policy_authorize") def test_check_resource_admin_admin(self, mock_authorize, mock_gopi): mock_gopi.return_value = owner_ctx_2.project_id bad_test_offer = offer.Offer( - resource_type='test_node', + resource_type="test_node", resource_uuid=test_node_2._uuid, - project_id=owner_ctx.project_id + project_id=owner_ctx.project_id, ) - utils.check_resource_admin(admin_ctx.to_policy_values(), - test_node_2, - bad_test_offer.project_id) + utils.check_resource_admin( + admin_ctx.to_policy_values(), test_node_2, bad_test_offer.project_id + ) mock_gopi.assert_called_once() - mock_authorize.assert_called_once_with('esi_leap:offer:offer_admin', - admin_ctx.to_policy_values(), - admin_ctx.to_policy_values(), - 'test_node', test_node_2._uuid) - - @mock.patch.object(test_node_2, 'get_owner_project_id') - @mock.patch('esi_leap.api.controllers.v1.utils.resource_policy_authorize') - def test_check_resource_admin_invalid_owner(self, mock_authorize, - mock_gopi): + mock_authorize.assert_called_once_with( + "esi_leap:offer:offer_admin", + admin_ctx.to_policy_values(), + admin_ctx.to_policy_values(), + "test_node", + test_node_2._uuid, + ) + + @mock.patch.object(test_node_2, "get_owner_project_id") + @mock.patch("esi_leap.api.controllers.v1.utils.resource_policy_authorize") + def test_check_resource_admin_invalid_owner(self, mock_authorize, mock_gopi): mock_gopi.return_value = owner_ctx_2.project_id mock_authorize.side_effect = exception.HTTPResourceForbidden( - resource_type='test_node', resource=test_node_2._uuid) + resource_type="test_node", resource=test_node_2._uuid + ) bad_test_offer = offer.Offer( - resource_type='test_node', + resource_type="test_node", resource_uuid=test_node_2._uuid, - project_id=owner_ctx.project_id + project_id=owner_ctx.project_id, ) - self.assertRaises(exception.HTTPResourceForbidden, - utils.check_resource_admin, - owner_ctx_2.to_policy_values(), - test_node_2, - bad_test_offer.project_id) + self.assertRaises( + exception.HTTPResourceForbidden, + utils.check_resource_admin, + owner_ctx_2.to_policy_values(), + test_node_2, + bad_test_offer.project_id, + ) mock_gopi.assert_called_once() - mock_authorize.assert_called_once_with('esi_leap:offer:offer_admin', - owner_ctx_2.to_policy_values(), - owner_ctx_2.to_policy_values(), - 'test_node', test_node_2._uuid) + mock_authorize.assert_called_once_with( + "esi_leap:offer:offer_admin", + owner_ctx_2.to_policy_values(), + owner_ctx_2.to_policy_values(), + "test_node", + test_node_2._uuid, + ) class TestCheckResourceLeaseAdminUtils(testtools.TestCase): - def setUp(self): super(TestCheckResourceLeaseAdminUtils, self).setUp() @@ -329,330 +322,347 @@ def setUp(self): uuid=uuidutils.generate_uuid(), start_time=datetime.datetime(2016, 7, 16, 19, 20, 30), end_time=datetime.datetime(2016, 8, 16, 19, 20, 30), - parent_lease_uuid=None + parent_lease_uuid=None, ) self.test_lease_with_parent = lease.Lease( uuid=uuidutils.generate_uuid(), start_time=datetime.datetime(2016, 7, 16, 19, 20, 30), end_time=datetime.datetime(2016, 8, 16, 19, 20, 30), - parent_lease_uuid='parent-lease-uuid' + parent_lease_uuid="parent-lease-uuid", ) - @mock.patch('esi_leap.objects.lease.Lease.get') - @mock.patch.object(test_node_1, 'get_lease_uuid', - return_value='a-lease-uuid') - @mock.patch.object(test_node_1, 'get_lessee_project_id', - return_value=test_offer.project_id) - def test_check_resource_lease_admin_okay(self, mock_glpi, mock_glu, - mock_lease_get): + @mock.patch("esi_leap.objects.lease.Lease.get") + @mock.patch.object(test_node_1, "get_lease_uuid", return_value="a-lease-uuid") + @mock.patch.object( + test_node_1, "get_lessee_project_id", return_value=test_offer.project_id + ) + def test_check_resource_lease_admin_okay(self, mock_glpi, mock_glu, mock_lease_get): mock_lease_get.return_value = self.test_lease parent_lease_uuid = utils.check_resource_lease_admin( owner_ctx.to_policy_values(), test_node_1, test_offer.project_id, datetime.datetime(2016, 7, 16, 19, 20, 30), - datetime.datetime(2016, 8, 16, 19, 20, 30)) + datetime.datetime(2016, 8, 16, 19, 20, 30), + ) mock_glpi.assert_called_once() mock_glu.assert_called_once() - mock_lease_get.assert_called_once_with('a-lease-uuid') - self.assertEqual('a-lease-uuid', parent_lease_uuid) - - @mock.patch('esi_leap.objects.lease.Lease.get') - @mock.patch.object(test_node_1, 'get_lease_uuid', - return_value='a-lease-uuid') - @mock.patch.object(test_node_1, 'get_lessee_project_id', - return_value='other-lessee') - def test_check_resource_lease_admin_not_lessee(self, mock_glpi, mock_glu, - mock_lease_get): + mock_lease_get.assert_called_once_with("a-lease-uuid") + self.assertEqual("a-lease-uuid", parent_lease_uuid) + + @mock.patch("esi_leap.objects.lease.Lease.get") + @mock.patch.object(test_node_1, "get_lease_uuid", return_value="a-lease-uuid") + @mock.patch.object( + test_node_1, "get_lessee_project_id", return_value="other-lessee" + ) + def test_check_resource_lease_admin_not_lessee( + self, mock_glpi, mock_glu, mock_lease_get + ): mock_lease_get.return_value = self.test_lease parent_lease_uuid = utils.check_resource_lease_admin( owner_ctx.to_policy_values(), test_node_1, test_offer.project_id, datetime.datetime(2016, 7, 16, 19, 20, 30), - datetime.datetime(2016, 8, 16, 19, 20, 30)) + datetime.datetime(2016, 8, 16, 19, 20, 30), + ) mock_glpi.assert_called_once() mock_glu.assert_not_called() mock_lease_get.assert_not_called() self.assertIsNone(parent_lease_uuid) - @mock.patch('esi_leap.objects.lease.Lease.get') - @mock.patch.object(test_node_1, 'get_lease_uuid', - return_value=None) - @mock.patch.object(test_node_1, 'get_lessee_project_id', - return_value=test_offer.project_id) - def test_check_resource_lease_admin_not_lease(self, - mock_glpi, - mock_glu, - mock_lease_get): + @mock.patch("esi_leap.objects.lease.Lease.get") + @mock.patch.object(test_node_1, "get_lease_uuid", return_value=None) + @mock.patch.object( + test_node_1, "get_lessee_project_id", return_value=test_offer.project_id + ) + def test_check_resource_lease_admin_not_lease( + self, mock_glpi, mock_glu, mock_lease_get + ): mock_lease_get.return_value = self.test_lease parent_lease_uuid = utils.check_resource_lease_admin( owner_ctx.to_policy_values(), test_node_1, test_offer.project_id, datetime.datetime(2016, 7, 16, 19, 20, 30), - datetime.datetime(2016, 8, 16, 19, 20, 30)) + datetime.datetime(2016, 8, 16, 19, 20, 30), + ) mock_glpi.assert_called_once() mock_glu.assert_called_once() mock_lease_get.assert_not_called() self.assertIsNone(parent_lease_uuid) - @mock.patch('esi_leap.objects.lease.Lease.get') - @mock.patch.object(test_node_1, 'get_lease_uuid', - return_value='a-lease-uuid') - @mock.patch.object(test_node_1, 'get_lessee_project_id', - return_value=test_offer.project_id) - def test_check_resource_lease_admin_parent_lease(self, - mock_glpi, - mock_glu, - mock_lease_get): + @mock.patch("esi_leap.objects.lease.Lease.get") + @mock.patch.object(test_node_1, "get_lease_uuid", return_value="a-lease-uuid") + @mock.patch.object( + test_node_1, "get_lessee_project_id", return_value=test_offer.project_id + ) + def test_check_resource_lease_admin_parent_lease( + self, mock_glpi, mock_glu, mock_lease_get + ): mock_lease_get.return_value = self.test_lease_with_parent parent_lease_uuid = utils.check_resource_lease_admin( owner_ctx.to_policy_values(), test_node_1, test_offer.project_id, datetime.datetime(2016, 7, 16, 19, 20, 30), - datetime.datetime(2016, 8, 16, 19, 20, 30)) + datetime.datetime(2016, 8, 16, 19, 20, 30), + ) mock_glpi.assert_called_once() mock_glu.assert_called_once() - mock_lease_get.assert_called_once_with('a-lease-uuid') + mock_lease_get.assert_called_once_with("a-lease-uuid") self.assertIsNone(parent_lease_uuid) - @mock.patch('esi_leap.objects.lease.Lease.get') - @mock.patch.object(test_node_1, 'get_lease_uuid', - return_value='a-lease-uuid') - @mock.patch.object(test_node_1, 'get_lessee_project_id', - return_value=test_offer.project_id) - def test_check_resource_lease_admin_bad_time(self, mock_glpi, mock_glu, - mock_lease_get): + @mock.patch("esi_leap.objects.lease.Lease.get") + @mock.patch.object(test_node_1, "get_lease_uuid", return_value="a-lease-uuid") + @mock.patch.object( + test_node_1, "get_lessee_project_id", return_value=test_offer.project_id + ) + def test_check_resource_lease_admin_bad_time( + self, mock_glpi, mock_glu, mock_lease_get + ): mock_lease_get.return_value = self.test_lease - self.assertRaises(exception.ResourceNoPermissionTime, - utils.check_resource_lease_admin, - owner_ctx.to_policy_values(), - test_node_1, - test_offer.project_id, - datetime.datetime(2016, 7, 15, 19, 20, 30), - datetime.datetime(2016, 8, 16, 19, 20, 30)) + self.assertRaises( + exception.ResourceNoPermissionTime, + utils.check_resource_lease_admin, + owner_ctx.to_policy_values(), + test_node_1, + test_offer.project_id, + datetime.datetime(2016, 7, 15, 19, 20, 30), + datetime.datetime(2016, 8, 16, 19, 20, 30), + ) mock_glpi.assert_called_once() mock_glu.assert_called_once() - mock_lease_get.assert_called_once_with('a-lease-uuid') + mock_lease_get.assert_called_once_with("a-lease-uuid") class TestOfferPolicyAndRetrieveUtils(testtools.TestCase): - - @mock.patch('esi_leap.api.controllers.v1.utils.resource_policy_authorize') - @mock.patch('esi_leap.api.controllers.v1.utils.get_offer') + @mock.patch("esi_leap.api.controllers.v1.utils.resource_policy_authorize") + @mock.patch("esi_leap.api.controllers.v1.utils.get_offer") def test_check_offer_policy(self, mock_get_offer, mock_authorize): mock_get_offer.return_value = test_offer target = dict(admin_ctx.to_policy_values()) - target['offer.project_id'] = test_offer.project_id + target["offer.project_id"] = test_offer.project_id offer = utils.check_offer_policy_and_retrieve( - admin_ctx, 'test_policy:test', '12345', []) - - mock_authorize.assert_called_with('test_policy:test', - target, - admin_ctx.to_policy_values(), - 'offer', - test_offer.uuid) - mock_get_offer.assert_called_with('12345', []) + admin_ctx, "test_policy:test", "12345", [] + ) + + mock_authorize.assert_called_with( + "test_policy:test", + target, + admin_ctx.to_policy_values(), + "offer", + test_offer.uuid, + ) + mock_get_offer.assert_called_with("12345", []) self.assertEqual(test_offer, offer) class TestLeasePolicyAndRetrieveUtils(testtools.TestCase): - - @mock.patch('esi_leap.api.controllers.v1.utils.resource_policy_authorize') - @mock.patch('esi_leap.api.controllers.v1.utils.get_lease') + @mock.patch("esi_leap.api.controllers.v1.utils.resource_policy_authorize") + @mock.patch("esi_leap.api.controllers.v1.utils.get_lease") def test_check_lease_policy(self, mock_get_lease, mock_authorize): mock_get_lease.return_value = test_lease target = dict(admin_ctx.to_policy_values()) - target['lease.owner_id'] = test_lease.owner_id - target['lease.project_id'] = test_lease.project_id + target["lease.owner_id"] = test_lease.owner_id + target["lease.project_id"] = test_lease.project_id lease = utils.check_lease_policy_and_retrieve( - admin_ctx, 'test_policy:test', '12345', []) - - mock_authorize.assert_called_with('test_policy:test', - target, - admin_ctx.to_policy_values(), - 'lease', - test_lease.uuid) - mock_get_lease.assert_called_with('12345', []) + admin_ctx, "test_policy:test", "12345", [] + ) + + mock_authorize.assert_called_with( + "test_policy:test", + target, + admin_ctx.to_policy_values(), + "lease", + test_lease.uuid, + ) + mock_get_lease.assert_called_with("12345", []) self.assertEqual(test_lease, lease) class TestOfferLesseeUtils(testtools.TestCase): - - @mock.patch('esi_leap.api.controllers.v1.utils.policy_authorize') - @mock.patch('esi_leap.common.keystone.get_parent_project_id_tree') - def test_check_offer_lessee_no_lessee_id(self, - mock_gppit, - mock_authorize): - utils.check_offer_lessee(lessee_ctx.to_policy_values(), - test_offer) + @mock.patch("esi_leap.api.controllers.v1.utils.policy_authorize") + @mock.patch("esi_leap.common.keystone.get_parent_project_id_tree") + def test_check_offer_lessee_no_lessee_id(self, mock_gppit, mock_authorize): + utils.check_offer_lessee(lessee_ctx.to_policy_values(), test_offer) assert not mock_authorize.called assert not mock_gppit.called - @mock.patch.object(policy, 'authorize', spec=True) - @mock.patch('esi_leap.common.keystone.get_parent_project_id_tree') - def test_check_offer_lessee_owner_match(self, - mock_gppit, - mock_authorize): - utils.check_offer_lessee(owner_ctx.to_policy_values(), - test_offer_lessee_no_match) + @mock.patch.object(policy, "authorize", spec=True) + @mock.patch("esi_leap.common.keystone.get_parent_project_id_tree") + def test_check_offer_lessee_owner_match(self, mock_gppit, mock_authorize): + utils.check_offer_lessee( + owner_ctx.to_policy_values(), test_offer_lessee_no_match + ) assert not mock_authorize.called assert not mock_gppit.called - @mock.patch('esi_leap.api.controllers.v1.utils.policy_authorize') - @mock.patch('esi_leap.common.keystone.get_parent_project_id_tree') - def test_check_offer_lessee_admin(self, - mock_gppit, - mock_authorize): + @mock.patch("esi_leap.api.controllers.v1.utils.policy_authorize") + @mock.patch("esi_leap.common.keystone.get_parent_project_id_tree") + def test_check_offer_lessee_admin(self, mock_gppit, mock_authorize): mock_authorize.return_value = True mock_gppit.return_value = [admin_ctx.project_id] - utils.check_offer_lessee(admin_ctx.to_policy_values(), - test_offer_lessee_no_match) + utils.check_offer_lessee( + admin_ctx.to_policy_values(), test_offer_lessee_no_match + ) - mock_authorize.assert_called_once_with('esi_leap:offer:offer_admin', - admin_ctx.to_policy_values(), - admin_ctx.to_policy_values()) + mock_authorize.assert_called_once_with( + "esi_leap:offer:offer_admin", + admin_ctx.to_policy_values(), + admin_ctx.to_policy_values(), + ) mock_gppit.assert_called_once_with(admin_ctx.project_id) - @mock.patch('esi_leap.api.controllers.v1.utils.policy_authorize') - @mock.patch('esi_leap.common.keystone.get_parent_project_id_tree') - def test_check_offer_lessee_non_admin_match(self, - mock_gppit, - mock_authorize): - mock_gppit.return_value = [lessee_ctx.project_id, 'lesseeidparent'] + @mock.patch("esi_leap.api.controllers.v1.utils.policy_authorize") + @mock.patch("esi_leap.common.keystone.get_parent_project_id_tree") + def test_check_offer_lessee_non_admin_match(self, mock_gppit, mock_authorize): + mock_gppit.return_value = [lessee_ctx.project_id, "lesseeidparent"] - utils.check_offer_lessee(lessee_ctx.to_policy_values(), - test_offer_lessee_match) + utils.check_offer_lessee(lessee_ctx.to_policy_values(), test_offer_lessee_match) assert not mock_authorize.called mock_gppit.assert_called_once_with(lessee_ctx.project_id) - @mock.patch('esi_leap.api.controllers.v1.utils.policy_authorize') - @mock.patch('esi_leap.common.keystone.get_parent_project_id_tree') - def test_check_offer_lessee_non_admin_no_match(self, - mock_gppit, - mock_authorize): + @mock.patch("esi_leap.api.controllers.v1.utils.policy_authorize") + @mock.patch("esi_leap.common.keystone.get_parent_project_id_tree") + def test_check_offer_lessee_non_admin_no_match(self, mock_gppit, mock_authorize): mock_authorize.side_effect = exception.HTTPResourceForbidden( - resource_type='offer', resource=test_offer_lessee_no_match.uuid) - mock_gppit.return_value = [lessee_ctx.project_id, 'lesseeidparent'] + resource_type="offer", resource=test_offer_lessee_no_match.uuid + ) + mock_gppit.return_value = [lessee_ctx.project_id, "lesseeidparent"] - self.assertRaises(exception.HTTPResourceForbidden, - utils.check_offer_lessee, - lessee_ctx.to_policy_values(), - test_offer_lessee_no_match) + self.assertRaises( + exception.HTTPResourceForbidden, + utils.check_offer_lessee, + lessee_ctx.to_policy_values(), + test_offer_lessee_no_match, + ) - mock_authorize.assert_called_once_with('esi_leap:offer:offer_admin', - lessee_ctx.to_policy_values(), - lessee_ctx.to_policy_values()) + mock_authorize.assert_called_once_with( + "esi_leap:offer:offer_admin", + lessee_ctx.to_policy_values(), + lessee_ctx.to_policy_values(), + ) mock_gppit.assert_called_once_with(lessee_ctx.project_id) class TestPolicyAuthorizeUtils(testtools.TestCase): - - @mock.patch.object(policy, 'authorize', spec=True) + @mock.patch.object(policy, "authorize", spec=True) def test_policy_authorize(self, mock_authorize): - utils.policy_authorize('test_policy:test', - lessee_ctx.to_policy_values(), - lessee_ctx.to_policy_values()) + utils.policy_authorize( + "test_policy:test", + lessee_ctx.to_policy_values(), + lessee_ctx.to_policy_values(), + ) - mock_authorize.assert_called_once_with('test_policy:test', - lessee_ctx.to_policy_values(), - lessee_ctx.to_policy_values()) + mock_authorize.assert_called_once_with( + "test_policy:test", + lessee_ctx.to_policy_values(), + lessee_ctx.to_policy_values(), + ) - @mock.patch.object(policy, 'authorize', spec=True) + @mock.patch.object(policy, "authorize", spec=True) def test_policy_authorize_exception(self, mock_authorize): mock_authorize.side_effect = oslo_policy.PolicyNotAuthorized( - 'esi_leap:offer:offer_admin', - lessee_ctx.to_dict(), lessee_ctx.to_dict()) + "esi_leap:offer:offer_admin", lessee_ctx.to_dict(), lessee_ctx.to_dict() + ) - self.assertRaises(exception.HTTPForbidden, - utils.policy_authorize, - 'test_policy:test', - lessee_ctx.to_policy_values(), - lessee_ctx.to_policy_values()) + self.assertRaises( + exception.HTTPForbidden, + utils.policy_authorize, + "test_policy:test", + lessee_ctx.to_policy_values(), + lessee_ctx.to_policy_values(), + ) - mock_authorize.assert_called_once_with('test_policy:test', - lessee_ctx.to_policy_values(), - lessee_ctx.to_policy_values()) + mock_authorize.assert_called_once_with( + "test_policy:test", + lessee_ctx.to_policy_values(), + lessee_ctx.to_policy_values(), + ) - @mock.patch('esi_leap.api.controllers.v1.utils.policy_authorize') + @mock.patch("esi_leap.api.controllers.v1.utils.policy_authorize") def test_resource_policy_authorize(self, mock_authorize): - utils.resource_policy_authorize('test_policy:test', - lessee_ctx.to_policy_values(), - lessee_ctx.to_policy_values(), - 'test_node', - '12345') + utils.resource_policy_authorize( + "test_policy:test", + lessee_ctx.to_policy_values(), + lessee_ctx.to_policy_values(), + "test_node", + "12345", + ) - mock_authorize.assert_called_once_with('test_policy:test', - lessee_ctx.to_policy_values(), - lessee_ctx.to_policy_values()) + mock_authorize.assert_called_once_with( + "test_policy:test", + lessee_ctx.to_policy_values(), + lessee_ctx.to_policy_values(), + ) - @mock.patch('esi_leap.api.controllers.v1.utils.policy_authorize') + @mock.patch("esi_leap.api.controllers.v1.utils.policy_authorize") def test_resource_policy_authorize_exception(self, mock_authorize): - mock_authorize.side_effect = exception.HTTPForbidden( - 'test_policy:test') - - self.assertRaises(exception.HTTPResourceForbidden, - utils.resource_policy_authorize, - 'test_policy:test', - lessee_ctx.to_policy_values(), - lessee_ctx.to_policy_values(), - 'test_node', '12345') - mock_authorize.assert_called_once_with('test_policy:test', - lessee_ctx.to_policy_values(), - lessee_ctx.to_policy_values()) + mock_authorize.side_effect = exception.HTTPForbidden("test_policy:test") + + self.assertRaises( + exception.HTTPResourceForbidden, + utils.resource_policy_authorize, + "test_policy:test", + lessee_ctx.to_policy_values(), + lessee_ctx.to_policy_values(), + "test_node", + "12345", + ) + mock_authorize.assert_called_once_with( + "test_policy:test", + lessee_ctx.to_policy_values(), + lessee_ctx.to_policy_values(), + ) class TestOfferGetDictWithAddedInfoUtils(testtools.TestCase): - - @mock.patch('esi_leap.common.keystone.get_project_name') - @mock.patch('esi_leap.objects.offer.Offer.get_availabilities') - def test_offer_get_dict_with_added_info(self, - mock_get_availabilities, - mock_gpn): + @mock.patch("esi_leap.common.keystone.get_project_name") + @mock.patch("esi_leap.objects.offer.Offer.get_availabilities") + def test_offer_get_dict_with_added_info(self, mock_get_availabilities, mock_gpn): mock_get_availabilities.return_value = [] - mock_gpn.return_value = 'project-name' + mock_gpn.return_value = "project-name" start = datetime.datetime(2016, 7, 16) o = offer.Offer( - resource_type='test_node', - resource_uuid='1234567890', - name='o', + resource_type="test_node", + resource_uuid="1234567890", + name="o", status=statuses.AVAILABLE, start_time=start, end_time=start + datetime.timedelta(days=100), project_id=uuidutils.generate_uuid(), - lessee_id=None + lessee_id=None, ) o_dict = utils.offer_get_dict_with_added_info(o) expected_offer_dict = { - 'resource_type': o.resource_type, - 'resource_uuid': o.resource_uuid, - 'resource_class': 'fake', - 'resource_properties': {}, - 'resource': 'test-node-1234567890', - 'name': o.name, - 'project_id': o.project_id, - 'project': 'project-name', - 'lessee_id': None, - 'lessee': 'project-name', - 'start_time': o.start_time, - 'end_time': o.end_time, - 'status': o.status, - 'availabilities': [], + "resource_type": o.resource_type, + "resource_uuid": o.resource_uuid, + "resource_class": "fake", + "resource_properties": {}, + "resource": "test-node-1234567890", + "name": o.name, + "project_id": o.project_id, + "project": "project-name", + "lessee_id": None, + "lessee": "project-name", + "start_time": o.start_time, + "end_time": o.end_time, + "status": o.status, + "availabilities": [], } self.assertEqual(expected_offer_dict, o_dict) @@ -660,7 +670,6 @@ def test_offer_get_dict_with_added_info(self, class TestLeaseGetDictWithAddedInfoUtils(testtools.TestCase): - def setUp(self): super(TestLeaseGetDictWithAddedInfoUtils, self).setUp() @@ -668,29 +677,29 @@ def setUp(self): start_time=datetime.datetime(2016, 7, 16, 19, 20, 30), end_time=datetime.datetime(2016, 8, 16, 19, 20, 30), uuid=uuidutils.generate_uuid(), - resource_type='test_node', - resource_uuid='111', - project_id='lesseeid', - owner_id='ownerid', - parent_lease_uuid=None + resource_type="test_node", + resource_uuid="111", + project_id="lesseeid", + owner_id="ownerid", + parent_lease_uuid=None, ) - @mock.patch('esi_leap.resource_objects.test_node.TestNode.get_name') - @mock.patch('esi_leap.common.keystone.get_project_name') - @mock.patch('esi_leap.objects.lease.get_resource_object') + @mock.patch("esi_leap.resource_objects.test_node.TestNode.get_name") + @mock.patch("esi_leap.common.keystone.get_project_name") + @mock.patch("esi_leap.objects.lease.get_resource_object") def test_lease_get_dict_with_added_info(self, mock_gro, mock_gpn, mock_gn): - mock_gro.return_value = TestNode('111') - mock_gpn.return_value = 'project-name' - mock_gn.return_value = 'resource-name' + mock_gro.return_value = TestNode("111") + mock_gpn.return_value = "project-name" + mock_gn.return_value = "resource-name" output_dict = utils.lease_get_dict_with_added_info(self.test_lease) expected_output_dict = self.test_lease.to_dict() - expected_output_dict['resource'] = 'resource-name' - expected_output_dict['project'] = 'project-name' - expected_output_dict['owner'] = 'project-name' - expected_output_dict['resource_class'] = 'fake' - expected_output_dict['resource_properties'] = {} + expected_output_dict["resource"] = "resource-name" + expected_output_dict["project"] = "project-name" + expected_output_dict["owner"] = "project-name" + expected_output_dict["resource_class"] = "fake" + expected_output_dict["resource_properties"] = {} mock_gro.assert_called_once() self.assertEqual(2, mock_gpn.call_count) @@ -706,38 +715,46 @@ def setUp(self): self.end_time = datetime.datetime(2016, 8, 16, 19, 20, 30) self.end_time_1 = datetime.datetime(2016, 7, 20, 19, 20, 30) - @mock.patch('esi_leap.api.controllers.v1.utils.policy_authorize') + @mock.patch("esi_leap.api.controllers.v1.utils.policy_authorize") def test_check_lease_length_admin_exceed_max(self, mock_authorize): - utils.check_lease_length(admin_ctx.to_policy_values(), - self.start_time, - self.end_time, - self.max_time) + utils.check_lease_length( + admin_ctx.to_policy_values(), self.start_time, self.end_time, self.max_time + ) - mock_authorize.assert_called_once_with('esi_leap:lease:lease_admin', - admin_ctx.to_policy_values(), - admin_ctx.to_policy_values()) + mock_authorize.assert_called_once_with( + "esi_leap:lease:lease_admin", + admin_ctx.to_policy_values(), + admin_ctx.to_policy_values(), + ) - @mock.patch('esi_leap.api.controllers.v1.utils.policy_authorize') + @mock.patch("esi_leap.api.controllers.v1.utils.policy_authorize") def test_check_lease_length_exception(self, mock_authorize): mock_authorize.side_effect = exception.HTTPForbidden( - 'esi_leap:lease:lease_admin') + "esi_leap:lease:lease_admin" + ) - self.assertRaises(exception.LeaseExceedMaxTimeRange, - utils.check_lease_length, - lessee_ctx.to_policy_values(), - self.start_time, - self.end_time, - self.max_time) + self.assertRaises( + exception.LeaseExceedMaxTimeRange, + utils.check_lease_length, + lessee_ctx.to_policy_values(), + self.start_time, + self.end_time, + self.max_time, + ) - mock_authorize.assert_called_once_with('esi_leap:lease:lease_admin', - lessee_ctx.to_policy_values(), - lessee_ctx.to_policy_values()) + mock_authorize.assert_called_once_with( + "esi_leap:lease:lease_admin", + lessee_ctx.to_policy_values(), + lessee_ctx.to_policy_values(), + ) - @mock.patch('esi_leap.api.controllers.v1.utils.policy_authorize') + @mock.patch("esi_leap.api.controllers.v1.utils.policy_authorize") def test_check_lease_length_non_admin_valid(self, mock_authorize): - utils.check_lease_length(lessee_ctx.to_policy_values(), - self.start_time, - self.end_time_1, - self.max_time) + utils.check_lease_length( + lessee_ctx.to_policy_values(), + self.start_time, + self.end_time_1, + self.max_time, + ) assert not mock_authorize.called diff --git a/esi_leap/tests/base.py b/esi_leap/tests/base.py index 21c7b2d3..dba0c738 100644 --- a/esi_leap/tests/base.py +++ b/esi_leap/tests/base.py @@ -28,7 +28,6 @@ class Database(fixtures.Fixture): - def __init__(self, engine, sql_connection, sqlite_clean_db): self.sql_connection = sql_connection self.sqlite_clean_db = sqlite_clean_db @@ -39,44 +38,42 @@ def __init__(self, engine, sql_connection, sqlite_clean_db): models.Base.metadata.create_all(self.engine) conn = self.engine.connect() - self._DB = ''.join(line for line in conn.connection.iterdump()) + self._DB = "".join(line for line in conn.connection.iterdump()) self.engine.dispose() def setUp(self): super(Database, self).setUp() - if self.sql_connection == 'sqlite://': + if self.sql_connection == "sqlite://": conn = self.engine.connect() conn.connection.executescript(self._DB) self.addCleanup(self.engine.dispose) class TestCase(base.BaseTestCase): - def setUp(self): self.config = self.useFixture(config.Config(lockutils.CONF)).config super(TestCase, self).setUp() - if not hasattr(self, 'context'): + if not hasattr(self, "context"): self.context = ctx.RequestContext( - auth_token=None, - project_id='12345', - is_admin=True, - overwrite=False) + auth_token=None, project_id="12345", is_admin=True, overwrite=False + ) class DBTestCase(TestCase): - def setUp(self): super(DBTestCase, self).setUp() - CONF.set_override('connection', 'sqlite://', group='database') + CONF.set_override("connection", "sqlite://", group="database") self.db_api = db_api.get_instance() global _DB_CACHE if not _DB_CACHE: engine = enginefacade.get_legacy_facade().get_engine() - _DB_CACHE = Database(engine, - sql_connection=CONF.database.connection, - sqlite_clean_db='clean.sqlite') + _DB_CACHE = Database( + engine, + sql_connection=CONF.database.connection, + sqlite_clean_db="clean.sqlite", + ) self.useFixture(_DB_CACHE) diff --git a/esi_leap/tests/common/test_ironic.py b/esi_leap/tests/common/test_ironic.py index 07ef5cea..6de5f5c4 100644 --- a/esi_leap/tests/common/test_ironic.py +++ b/esi_leap/tests/common/test_ironic.py @@ -18,48 +18,43 @@ class FakeNode(object): def __init__(self): - self.uuid = 'uuid' - self.name = 'name' - self.resource_class = 'baremetal' + self.uuid = "uuid" + self.name = "name" + self.resource_class = "baremetal" class IronicTestCase(base.TestCase): - - @mock.patch.object(ironic, 'get_ironic_client', autospec=True) + @mock.patch.object(ironic, "get_ironic_client", autospec=True) def test_get_node(self, mock_ironic): fake_node = FakeNode() mock_ironic.return_value.node.get.return_value = fake_node - node = ironic.get_node('12345') + node = ironic.get_node("12345") self.assertEqual(fake_node, node) - @mock.patch.object(ironic, 'get_ironic_client', autospec=True) + @mock.patch.object(ironic, "get_ironic_client", autospec=True) def test_get_node_list(self, mock_ironic): fake_node = FakeNode() node_list = [fake_node] - node = ironic.get_node('uuid', node_list) + node = ironic.get_node("uuid", node_list) self.assertEqual(fake_node, node) - @mock.patch.object(ironic, 'get_ironic_client', autospec=True) + @mock.patch.object(ironic, "get_ironic_client", autospec=True) def test_get_node_list_no_match(self, mock_ironic): fake_node = FakeNode() node_list = [fake_node] - node = ironic.get_node('uuid2', node_list) + node = ironic.get_node("uuid2", node_list) self.assertEqual(None, node) def test_get_condensed_properties(self): properties = { - 'lease_uuid': '12345', - 'capabilities': 'magic', - 'cpu': '40', - 'local_gb': '1000' + "lease_uuid": "12345", + "capabilities": "magic", + "cpu": "40", + "local_gb": "1000", } - cp = ironic.get_condensed_properties( - properties) + cp = ironic.get_condensed_properties(properties) - self.assertEqual(cp, { - 'cpu': '40', - 'local_gb': '1000' - }) + self.assertEqual(cp, {"cpu": "40", "local_gb": "1000"}) diff --git a/esi_leap/tests/common/test_keystone.py b/esi_leap/tests/common/test_keystone.py index 0bf61944..ae4ada15 100644 --- a/esi_leap/tests/common/test_keystone.py +++ b/esi_leap/tests/common/test_keystone.py @@ -19,74 +19,70 @@ class FakeProject(object): def __init__(self): - self.id = 'uuid' - self.name = 'name' + self.id = "uuid" + self.name = "name" class KeystoneTestCase(base.TestCase): - - @mock.patch('oslo_utils.uuidutils.is_uuid_like') + @mock.patch("oslo_utils.uuidutils.is_uuid_like") def test_get_project_uuid_from_ident_uuid(self, mock_iul): mock_iul.return_value = True - project_uuid = keystone.get_project_uuid_from_ident('uuid') + project_uuid = keystone.get_project_uuid_from_ident("uuid") - mock_iul.assert_called_once_with('uuid') - self.assertEqual('uuid', project_uuid) + mock_iul.assert_called_once_with("uuid") + self.assertEqual("uuid", project_uuid) - @mock.patch.object(keystone, 'get_keystone_client', autospec=True) - @mock.patch('oslo_utils.uuidutils.is_uuid_like') + @mock.patch.object(keystone, "get_keystone_client", autospec=True) + @mock.patch("oslo_utils.uuidutils.is_uuid_like") def test_get_project_uuid_from_ident_name(self, mock_iul, mock_keystone): mock_iul.return_value = False mock_keystone.return_value.projects.list.return_value = [FakeProject()] - project_uuid = keystone.get_project_uuid_from_ident('name') + project_uuid = keystone.get_project_uuid_from_ident("name") - mock_iul.assert_called_once_with('name') - self.assertEqual('uuid', project_uuid) - mock_keystone.return_value.projects.list.assert_called_once_with( - name='name') + mock_iul.assert_called_once_with("name") + self.assertEqual("uuid", project_uuid) + mock_keystone.return_value.projects.list.assert_called_once_with(name="name") - @mock.patch.object(keystone, 'get_keystone_client', autospec=True) - @mock.patch('oslo_utils.uuidutils.is_uuid_like') - def test_get_project_uuid_from_ident_name_no_match(self, mock_iul, - mock_keystone): + @mock.patch.object(keystone, "get_keystone_client", autospec=True) + @mock.patch("oslo_utils.uuidutils.is_uuid_like") + def test_get_project_uuid_from_ident_name_no_match(self, mock_iul, mock_keystone): mock_iul.return_value = False mock_keystone.return_value.projects.list.return_value = [] - self.assertRaises(e.ProjectNoSuchName, - keystone.get_project_uuid_from_ident, - 'name') + self.assertRaises( + e.ProjectNoSuchName, keystone.get_project_uuid_from_ident, "name" + ) - mock_iul.assert_called_once_with('name') - mock_keystone.return_value.projects.list.assert_called_once_with( - name='name') + mock_iul.assert_called_once_with("name") + mock_keystone.return_value.projects.list.assert_called_once_with(name="name") - @mock.patch.object(keystone, 'get_keystone_client', autospec=True) + @mock.patch.object(keystone, "get_keystone_client", autospec=True) def test_get_project_name_no_list(self, mock_keystone): mock_keystone.return_value.projects.get.return_value = FakeProject() - project_name = keystone.get_project_name('12345') + project_name = keystone.get_project_name("12345") - self.assertEqual('name', project_name) + self.assertEqual("name", project_name) - @mock.patch.object(keystone, 'get_keystone_client', autospec=True) + @mock.patch.object(keystone, "get_keystone_client", autospec=True) def test_get_project_name_list(self, mock_keystone): project_list = [FakeProject()] - project_name = keystone.get_project_name('uuid', project_list) + project_name = keystone.get_project_name("uuid", project_list) - self.assertEqual('name', project_name) + self.assertEqual("name", project_name) - @mock.patch.object(keystone, 'get_keystone_client', autospec=True) + @mock.patch.object(keystone, "get_keystone_client", autospec=True) def test_get_project_name_list_no_match(self, mock_keystone): project_list = [FakeProject()] - project_name = keystone.get_project_name('uuid2', project_list) + project_name = keystone.get_project_name("uuid2", project_list) - self.assertEqual('', project_name) + self.assertEqual("", project_name) - @mock.patch.object(keystone, 'get_keystone_client', autospec=True) + @mock.patch.object(keystone, "get_keystone_client", autospec=True) def test_get_project_name_none(self, mock_keystone): project_list = [FakeProject()] project_name = keystone.get_project_name(None, project_list) - self.assertEqual('', project_name) + self.assertEqual("", project_name) diff --git a/esi_leap/tests/common/test_notification_utils.py b/esi_leap/tests/common/test_notification_utils.py index 67bef274..e1db6f5f 100644 --- a/esi_leap/tests/common/test_notification_utils.py +++ b/esi_leap/tests/common/test_notification_utils.py @@ -22,54 +22,55 @@ class NotifyTestCase(tests_base.TestCase): - def setUp(self): super(NotifyTestCase, self).setUp() self.lease_notify_mock = mock.Mock() - self.lease_notify_mock.__name__ = 'LeaseCRUDNotification' + self.lease_notify_mock.__name__ = "LeaseCRUDNotification" self.crud_notify_obj = { - 'lease': (self.lease_notify_mock, - lease_obj.LeaseCRUDPayload), + "lease": (self.lease_notify_mock, lease_obj.LeaseCRUDPayload), } self.lease = lease_obj.Lease( - id='12345', - name='test_lease', + id="12345", + name="test_lease", start_time=datetime.datetime(2016, 7, 16, 19, 20, 30), end_time=datetime.datetime(2016, 8, 16, 19, 20, 30), fulfill_time=datetime.datetime(2016, 7, 16, 19, 21, 30), expire_time=datetime.datetime(2016, 8, 16, 19, 21, 30), - uuid='13921c8d-ce11-4b6d-99ed-10e19d184e5f', - resource_type='test_node', - resource_uuid='111', - project_id='lesseeid', - owner_id='ownerid', + uuid="13921c8d-ce11-4b6d-99ed-10e19d184e5f", + resource_type="test_node", + resource_uuid="111", + project_id="lesseeid", + owner_id="ownerid", parent_lease_uuid=None, offer_uuid=None, properties=None, - status='created', + status="created", purpose=None, ) - self.node = TestNode('test-node', '12345') + self.node = TestNode("test-node", "12345") def test_emit_notification(self): - self.config(host='fake-host') + self.config(host="fake-host") test_level = fields.NotificationLevel.INFO test_status = fields.NotificationStatus.SUCCESS - notif_utils._emit_notification(self.context, - self.lease, - 'fulfill', test_level, - test_status, - self.crud_notify_obj, - node=self.node) + notif_utils._emit_notification( + self.context, + self.lease, + "fulfill", + test_level, + test_status, + self.crud_notify_obj, + node=self.node, + ) init_kwargs = self.lease_notify_mock.call_args[1] - publisher = init_kwargs['publisher'] - event_type = init_kwargs['event_type'] - payload = init_kwargs['payload'] - level = init_kwargs['level'] - self.assertEqual('fake-host', publisher.host) - self.assertEqual('esi-leap-manager', publisher.service) - self.assertEqual('fulfill', event_type.action) - self.assertEqual('lease', event_type.object) + publisher = init_kwargs["publisher"] + event_type = init_kwargs["event_type"] + payload = init_kwargs["payload"] + level = init_kwargs["level"] + self.assertEqual("fake-host", publisher.host) + self.assertEqual("esi-leap-manager", publisher.service) + self.assertEqual("fulfill", event_type.action) + self.assertEqual("lease", event_type.object) self.assertEqual(test_status, event_type.status) self.assertEqual(test_level, level) self.assertEqual(self.lease.name, payload.name) diff --git a/esi_leap/tests/common/test_policy.py b/esi_leap/tests/common/test_policy.py index 7bd2eea1..c1c18e5a 100644 --- a/esi_leap/tests/common/test_policy.py +++ b/esi_leap/tests/common/test_policy.py @@ -21,26 +21,31 @@ class PolicyTestCase(base.TestCase): - def setUp(self): super(PolicyTestCase, self).setUp() - CONF.set_override('auth_enable', True, - group='pecan') + CONF.set_override("auth_enable", True, group="pecan") def test_authorized(self): - creds = {'roles': ['esi_leap_owner']} - self.assertTrue(policy.authorize('esi_leap:offer:get', - creds, creds)) + creds = {"roles": ["esi_leap_owner"]} + self.assertTrue(policy.authorize("esi_leap:offer:get", creds, creds)) def test_unauthorized(self): - creds = {'roles': ['generic_user']} + creds = {"roles": ["generic_user"]} self.assertRaises( oslo_policy.PolicyNotAuthorized, - policy.authorize, 'esi_leap:offer:get', creds, creds) + policy.authorize, + "esi_leap:offer:get", + creds, + creds, + ) def test_authorize_policy_not_registered(self): - creds = {'roles': ['generic_user']} + creds = {"roles": ["generic_user"]} self.assertRaises( oslo_policy.PolicyNotRegistered, - policy.authorize, 'esi_leap:foo:bar', creds, creds) + policy.authorize, + "esi_leap:foo:bar", + creds, + creds, + ) diff --git a/esi_leap/tests/common/test_rpc.py b/esi_leap/tests/common/test_rpc.py index d995efc3..b897a0ac 100644 --- a/esi_leap/tests/common/test_rpc.py +++ b/esi_leap/tests/common/test_rpc.py @@ -24,37 +24,35 @@ # TestUtils borrowed from Ironic class TestUtils(base.TestCase): - - @mock.patch.object(messaging, 'Notifier', autospec=True) - @mock.patch.object(messaging, 'JsonPayloadSerializer', autospec=True) - @mock.patch.object(messaging, 'get_notification_transport', autospec=True) - def test_init_globals_notifications_disabled(self, - mock_get_notification, - mock_json_serializer, - mock_notifier): - self._test_init_globals(False, - mock_get_notification, mock_json_serializer, - mock_notifier) - - @mock.patch.object(messaging, 'Notifier', autospec=True) - @mock.patch.object(messaging, 'JsonPayloadSerializer', autospec=True) - @mock.patch.object(messaging, 'get_notification_transport', autospec=True) - def test_init_globals_notifications_enabled(self, - mock_get_notification, - mock_json_serializer, - mock_notifier): - self.config(notification_level='debug', group='notification') - self._test_init_globals(True, - mock_get_notification, mock_json_serializer, - mock_notifier) + @mock.patch.object(messaging, "Notifier", autospec=True) + @mock.patch.object(messaging, "JsonPayloadSerializer", autospec=True) + @mock.patch.object(messaging, "get_notification_transport", autospec=True) + def test_init_globals_notifications_disabled( + self, mock_get_notification, mock_json_serializer, mock_notifier + ): + self._test_init_globals( + False, mock_get_notification, mock_json_serializer, mock_notifier + ) + + @mock.patch.object(messaging, "Notifier", autospec=True) + @mock.patch.object(messaging, "JsonPayloadSerializer", autospec=True) + @mock.patch.object(messaging, "get_notification_transport", autospec=True) + def test_init_globals_notifications_enabled( + self, mock_get_notification, mock_json_serializer, mock_notifier + ): + self.config(notification_level="debug", group="notification") + self._test_init_globals( + True, mock_get_notification, mock_json_serializer, mock_notifier + ) def _test_init_globals( - self, notifications_enabled, - mock_get_notification, mock_json_serializer, + self, + notifications_enabled, + mock_get_notification, + mock_json_serializer, mock_notifier, - versioned_notifications_topics=( - ['esi_leap_versioned_notifications'])): - + versioned_notifications_topics=(["esi_leap_versioned_notifications"]), + ): rpc.NOTIFICATION_TRANSPORT = None rpc.VERSIONED_NOTIFIER = None mock_request_serializer = mock.Mock() @@ -65,60 +63,63 @@ def _test_init_globals( rpc.init(CONF) - self.assertEqual(mock_get_notification.return_value, - rpc.NOTIFICATION_TRANSPORT) + self.assertEqual(mock_get_notification.return_value, rpc.NOTIFICATION_TRANSPORT) self.assertTrue(mock_json_serializer.called) if not notifications_enabled: mock_notifier.assert_any_call( rpc.NOTIFICATION_TRANSPORT, serializer=mock_request_serializer.return_value, - driver='noop') + driver="noop", + ) else: mock_notifier.assert_any_call( rpc.NOTIFICATION_TRANSPORT, serializer=mock_request_serializer.return_value, - topics=versioned_notifications_topics) + topics=versioned_notifications_topics, + ) self.assertEqual(mock_notifier.return_value, rpc.VERSIONED_NOTIFIER) def test_get_versioned_notifier(self): rpc.VERSIONED_NOTIFIER = mock.Mock(autospec=True) - rpc.get_versioned_notifier(publisher_id='a_great_publisher') + rpc.get_versioned_notifier(publisher_id="a_great_publisher") rpc.VERSIONED_NOTIFIER.prepare.assert_called_once_with( - publisher_id='a_great_publisher') + publisher_id="a_great_publisher" + ) def test_get_versioned_notifier_no_publisher_id(self): rpc.VERSIONED_NOTIFIER = mock.Mock() - self.assertRaises(AssertionError, - rpc.get_versioned_notifier, publisher_id=None) + self.assertRaises(AssertionError, rpc.get_versioned_notifier, publisher_id=None) def test_get_versioned_notifier_no_notifier(self): rpc.VERSIONED_NOTIFIER = None self.assertRaises( - AssertionError, - rpc.get_versioned_notifier, publisher_id='a_great_publisher') + AssertionError, rpc.get_versioned_notifier, publisher_id="a_great_publisher" + ) class TestRequestContextSerializer(base.TestCase): - def setUp(self): super(TestRequestContextSerializer, self).setUp() self.mock_serializer = mock.MagicMock() self.serializer = rpc.RequestContextSerializer(self.mock_serializer) self.context = ctx.RequestContext() - self.entity = {'foo': 'bar'} + self.entity = {"foo": "bar"} def test_serialize_entity(self): self.serializer.serialize_entity(self.context, self.entity) self.mock_serializer.serialize_entity.assert_called_with( - self.context, self.entity) + self.context, self.entity + ) def test_serialize_entity_empty_base(self): # NOTE(viktors): Return False for check `if self.serializer._base:` - bool_args = {'__bool__': lambda *args: False, - '__nonzero__': lambda *args: False} + bool_args = { + "__bool__": lambda *args: False, + "__nonzero__": lambda *args: False, + } self.mock_serializer.configure_mock(**bool_args) entity = self.serializer.serialize_entity(self.context, self.entity) @@ -129,12 +130,15 @@ def test_serialize_entity_empty_base(self): def test_deserialize_entity(self): self.serializer.deserialize_entity(self.context, self.entity) self.mock_serializer.deserialize_entity.assert_called_with( - self.context, self.entity) + self.context, self.entity + ) def test_deserialize_entity_empty_base(self): # NOTE(viktors): Return False for check `if self.serializer._base:` - bool_args = {'__bool__': lambda *args: False, - '__nonzero__': lambda *args: False} + bool_args = { + "__bool__": lambda *args: False, + "__nonzero__": lambda *args: False, + } self.mock_serializer.configure_mock(**bool_args) entity = self.serializer.deserialize_entity(self.context, self.entity) diff --git a/esi_leap/tests/common/test_utils.py b/esi_leap/tests/common/test_utils.py index 6349f50e..2c26bcd2 100644 --- a/esi_leap/tests/common/test_utils.py +++ b/esi_leap/tests/common/test_utils.py @@ -15,11 +15,11 @@ class LockTestCase(base.TestCase): - def test_get_resource_lock_name(self): - resource_type = 'ironic_node' - resource_uuid = '12345' + resource_type = "ironic_node" + resource_uuid = "12345" - self.assertEqual(resource_type + '-' + resource_uuid, - utils.get_resource_lock_name( - resource_type, resource_uuid)) + self.assertEqual( + resource_type + "-" + resource_uuid, + utils.get_resource_lock_name(resource_type, resource_uuid), + ) diff --git a/esi_leap/tests/db/sqlalchemy/test_api.py b/esi_leap/tests/db/sqlalchemy/test_api.py index f80b3063..4c3ace14 100644 --- a/esi_leap/tests/db/sqlalchemy/test_api.py +++ b/esi_leap/tests/db/sqlalchemy/test_api.py @@ -22,77 +22,77 @@ now = datetime.datetime(2016, 7, 16, 19, 20, 30) test_offer_1 = dict( - uuid='11111', - project_id='0wn3r', - name='o1', - resource_uuid='1111', - resource_type='dummy_node', + uuid="11111", + project_id="0wn3r", + name="o1", + resource_uuid="1111", + resource_type="dummy_node", start_time=now, end_time=now + datetime.timedelta(days=100), - properties={'foo': 'bar'}, + properties={"foo": "bar"}, status=statuses.AVAILABLE, ) test_offer_2 = dict( - uuid='22222', - project_id='0wn3r', - lessee_id='12345', - name='o1', - resource_uuid='1111', - resource_type='dummy_node', + uuid="22222", + project_id="0wn3r", + lessee_id="12345", + name="o1", + resource_uuid="1111", + resource_type="dummy_node", start_time=now + datetime.timedelta(days=25), end_time=now + datetime.timedelta(days=100), - properties={'foo': 'bar'}, + properties={"foo": "bar"}, status=statuses.AVAILABLE, ) test_offer_3 = dict( - uuid='33333', - project_id='0wn3r_2', - lessee_id='67890', - name='o1', - resource_uuid='1111', - resource_type='dummy_node', + uuid="33333", + project_id="0wn3r_2", + lessee_id="67890", + name="o1", + resource_uuid="1111", + resource_type="dummy_node", start_time=now + datetime.timedelta(days=50), end_time=now + datetime.timedelta(days=100), - properties={'foo': 'bar'}, + properties={"foo": "bar"}, status=statuses.AVAILABLE, ) test_offer_4 = dict( - uuid='44444', - project_id='0wn3r_2', - lessee_id='ABCDE', - name='o2', - resource_uuid='1111', - resource_type='dummy_node', + uuid="44444", + project_id="0wn3r_2", + lessee_id="ABCDE", + name="o2", + resource_uuid="1111", + resource_type="dummy_node", start_time=now + datetime.timedelta(days=75), end_time=now + datetime.timedelta(days=100), - properties={'foo': 'bar'}, + properties={"foo": "bar"}, status=statuses.AVAILABLE, ) test_offer_5 = dict( - uuid='55555', - project_id='12345', - lessee_id='ABCDE', - name='o2', - resource_uuid='1111', - resource_type='dummy_node', + uuid="55555", + project_id="12345", + lessee_id="ABCDE", + name="o2", + resource_uuid="1111", + resource_type="dummy_node", start_time=now + datetime.timedelta(days=105), end_time=now + datetime.timedelta(days=150), - properties={'foo': 'bar'}, + properties={"foo": "bar"}, status=statuses.AVAILABLE, ) test_lease_1 = dict( - uuid='11111', - project_id='1e5533', - owner_id='0wn3r', - name='l1', - resource_uuid='1111', - resource_type='dummy_node', - purpose='test_purpose', + uuid="11111", + project_id="1e5533", + owner_id="0wn3r", + name="l1", + resource_uuid="1111", + resource_type="dummy_node", + purpose="test_purpose", start_time=now + datetime.timedelta(days=10), end_time=now + datetime.timedelta(days=20), properties={}, @@ -100,13 +100,13 @@ ) test_lease_2 = dict( - uuid='22222', - project_id='1e5533', - owner_id='0wn3r', - name='l1', - resource_uuid='1111', - resource_type='dummy_node', - purpose='test_purpose', + uuid="22222", + project_id="1e5533", + owner_id="0wn3r", + name="l1", + resource_uuid="1111", + resource_type="dummy_node", + purpose="test_purpose", start_time=now + datetime.timedelta(days=20), end_time=now + datetime.timedelta(days=30), properties={}, @@ -114,13 +114,13 @@ ) test_lease_3 = dict( - uuid='33333', - project_id='1e5533_2', - owner_id='0wn3r_2', - name='l1', - resource_uuid='1111', - resource_type='dummy_node', - purpose='test_purpose', + uuid="33333", + project_id="1e5533_2", + owner_id="0wn3r_2", + name="l1", + resource_uuid="1111", + resource_type="dummy_node", + purpose="test_purpose", start_time=now + datetime.timedelta(days=50), end_time=now + datetime.timedelta(days=60), properties={}, @@ -128,13 +128,13 @@ ) test_lease_4 = dict( - uuid='44444', - project_id='1e5533_2', - owner_id='0wn3r_2', - name='l4', - resource_uuid='1111', - resource_type='dummy_node', - purpose='test_purpose', + uuid="44444", + project_id="1e5533_2", + owner_id="0wn3r_2", + name="l4", + resource_uuid="1111", + resource_type="dummy_node", + purpose="test_purpose", start_time=now + datetime.timedelta(days=85), end_time=now + datetime.timedelta(days=90), properties={}, @@ -142,41 +142,41 @@ ) test_lease_5 = dict( - project_id='0wn3r', - owner_id='0wn3r_2', - name='l5', - resource_uuid='1111', - resource_type='dummy_node', - purpose='test_purpose', + project_id="0wn3r", + owner_id="0wn3r_2", + name="l5", + resource_uuid="1111", + resource_type="dummy_node", + purpose="test_purpose", start_time=now + datetime.timedelta(days=90), end_time=now + datetime.timedelta(days=100), - uuid='55555', + uuid="55555", properties={}, status=statuses.EXPIRED, ) test_lease_6 = dict( - project_id='0wn3r', - owner_id='0wn3r_2', - name='l6', - resource_uuid='2222', - resource_type='dummy_node', - purpose='test_purpose', + project_id="0wn3r", + owner_id="0wn3r_2", + name="l6", + resource_uuid="2222", + resource_type="dummy_node", + purpose="test_purpose", start_time=now + datetime.timedelta(days=5), end_time=now + datetime.timedelta(days=30), - uuid='6666', + uuid="6666", properties={}, status=statuses.EXPIRED, ) test_lease_7 = dict( - uuid='77777', - project_id='1e5533_2', - owner_id='0wn3r_2', - name='l1', - resource_uuid='1111', - resource_type='dummy_node', - purpose='test_purpose', + uuid="77777", + project_id="1e5533_2", + owner_id="0wn3r_2", + name="l1", + resource_uuid="1111", + resource_type="dummy_node", + purpose="test_purpose", start_time=now - datetime.timedelta(days=10), end_time=now + datetime.timedelta(days=10), properties={}, @@ -185,43 +185,42 @@ test_event_1 = dict( id=1, - event_type='fake:event:start', + event_type="fake:event:start", event_time=now - datetime.timedelta(days=20), - object_type='lease', - object_uuid='11111', - resource_type='dummy_node', - resource_uuid='1111', - lessee_id='1e5533', - owner_id='0wn3r', + object_type="lease", + object_uuid="11111", + resource_type="dummy_node", + resource_uuid="1111", + lessee_id="1e5533", + owner_id="0wn3r", ) test_event_2 = dict( id=2, - event_type='fake:event:end', + event_type="fake:event:end", event_time=now - datetime.timedelta(days=10), - object_type='lease', - object_uuid='11111', - resource_type='dummy_node', - resource_uuid='1111', - lessee_id='1e5533', - owner_id='0wn3r', + object_type="lease", + object_uuid="11111", + resource_type="dummy_node", + resource_uuid="1111", + lessee_id="1e5533", + owner_id="0wn3r", ) test_event_3 = dict( id=3, - event_type='fake:event:start', + event_type="fake:event:start", event_time=now - datetime.timedelta(days=20), - object_type='lease', - object_uuid='22222', - resource_type='dummy_node', - resource_uuid='2222', - lessee_id='1e5533', - owner_id='0wn3r2', + object_type="lease", + object_uuid="22222", + resource_type="dummy_node", + resource_uuid="2222", + lessee_id="1e5533", + owner_id="0wn3r2", ) class TestOfferAPI(base.DBTestCase): - def test_offer_create(self): offer = api.offer_create(test_offer_1) o = api.offer_get_all({}).all() @@ -231,9 +230,9 @@ def test_offer_create(self): def test_offer_verify_availability(self): offer = api.offer_create(test_offer_1) - test_lease_1['offer_uuid'] = offer.uuid - test_lease_2['offer_uuid'] = offer.uuid - test_lease_3['offer_uuid'] = offer.uuid + test_lease_1["offer_uuid"] = offer.uuid + test_lease_2["offer_uuid"] = offer.uuid + test_lease_3["offer_uuid"] = offer.uuid api.lease_create(test_lease_1) api.lease_create(test_lease_2) @@ -265,77 +264,125 @@ def test_offer_verify_availability(self): start = now + datetime.timedelta(days=15) end = now + datetime.timedelta(days=16) - self.assertRaises(e.OfferNoTimeAvailabilities, - api.offer_verify_availability, - offer, start, end) + self.assertRaises( + e.OfferNoTimeAvailabilities, + api.offer_verify_availability, + offer, + start, + end, + ) start = now + datetime.timedelta(days=45) end = now + datetime.timedelta(days=55) - self.assertRaises(e.OfferNoTimeAvailabilities, - api.offer_verify_availability, - offer, start, end) + self.assertRaises( + e.OfferNoTimeAvailabilities, + api.offer_verify_availability, + offer, + start, + end, + ) start = now + datetime.timedelta(days=55) end = now + datetime.timedelta(days=65) - self.assertRaises(e.OfferNoTimeAvailabilities, - api.offer_verify_availability, - offer, start, end) + self.assertRaises( + e.OfferNoTimeAvailabilities, + api.offer_verify_availability, + offer, + start, + end, + ) start = now + datetime.timedelta(days=50) end = now + datetime.timedelta(days=65) - self.assertRaises(e.OfferNoTimeAvailabilities, - api.offer_verify_availability, - offer, start, end) + self.assertRaises( + e.OfferNoTimeAvailabilities, + api.offer_verify_availability, + offer, + start, + end, + ) start = now + datetime.timedelta(days=45) end = now + datetime.timedelta(days=60) - self.assertRaises(e.OfferNoTimeAvailabilities, - api.offer_verify_availability, - offer, start, end) + self.assertRaises( + e.OfferNoTimeAvailabilities, + api.offer_verify_availability, + offer, + start, + end, + ) start = now + datetime.timedelta(days=90) end = now + datetime.timedelta(days=105) - self.assertRaises(e.OfferNoTimeAvailabilities, - api.offer_verify_availability, - offer, start, end) + self.assertRaises( + e.OfferNoTimeAvailabilities, + api.offer_verify_availability, + offer, + start, + end, + ) start = now + datetime.timedelta(days=100) end = now + datetime.timedelta(days=105) - self.assertRaises(e.OfferNoTimeAvailabilities, - api.offer_verify_availability, - offer, start, end) + self.assertRaises( + e.OfferNoTimeAvailabilities, + api.offer_verify_availability, + offer, + start, + end, + ) start = now + datetime.timedelta(days=105) end = now + datetime.timedelta(days=110) - self.assertRaises(e.OfferNoTimeAvailabilities, - api.offer_verify_availability, - offer, start, end) + self.assertRaises( + e.OfferNoTimeAvailabilities, + api.offer_verify_availability, + offer, + start, + end, + ) start = now - datetime.timedelta(days=1) end = now + datetime.timedelta(days=5) - self.assertRaises(e.OfferNoTimeAvailabilities, - api.offer_verify_availability, - offer, start, end) + self.assertRaises( + e.OfferNoTimeAvailabilities, + api.offer_verify_availability, + offer, + start, + end, + ) start = now - datetime.timedelta(days=1) end = now - self.assertRaises(e.OfferNoTimeAvailabilities, - api.offer_verify_availability, - offer, start, end) + self.assertRaises( + e.OfferNoTimeAvailabilities, + api.offer_verify_availability, + offer, + start, + end, + ) start = now - datetime.timedelta(days=10) end = now - datetime.timedelta(days=5) - self.assertRaises(e.OfferNoTimeAvailabilities, - api.offer_verify_availability, - offer, start, end) + self.assertRaises( + e.OfferNoTimeAvailabilities, + api.offer_verify_availability, + offer, + start, + end, + ) start = now + datetime.timedelta(days=45) end = now + datetime.timedelta(days=55) - self.assertRaises(e.OfferNoTimeAvailabilities, - api.offer_verify_availability, - offer, start, end) + self.assertRaises( + e.OfferNoTimeAvailabilities, + api.offer_verify_availability, + offer, + start, + end, + ) - test_lease_4['offer_uuid'] = offer.uuid + test_lease_4["offer_uuid"] = offer.uuid api.lease_create(test_lease_4) start = now + datetime.timedelta(days=86) end = now + datetime.timedelta(days=87) @@ -344,28 +391,34 @@ def test_offer_verify_availability(self): def test_offer_get_conflict_times(self): o1 = api.offer_create(test_offer_1) self.assertEqual(api.offer_get_conflict_times(o1), []) - test_lease_3['offer_uuid'] = o1.uuid - test_lease_4['offer_uuid'] = o1.uuid - test_lease_5['offer_uuid'] = o1.uuid + test_lease_3["offer_uuid"] = o1.uuid + test_lease_4["offer_uuid"] = o1.uuid + test_lease_5["offer_uuid"] = o1.uuid api.lease_create(test_lease_3) api.lease_create(test_lease_4) api.lease_create(test_lease_5) - self.assertEqual(api.offer_get_conflict_times(o1), - [(now + datetime.timedelta(days=50), - now + datetime.timedelta(days=60))]) + self.assertEqual( + api.offer_get_conflict_times(o1), + [(now + datetime.timedelta(days=50), now + datetime.timedelta(days=60))], + ) def test_offer_get_next_lease_start_time(self): o1 = api.offer_create(test_offer_1) - self.assertEqual(api.offer_get_next_lease_start_time - (o1.uuid, o1.start_time,), None) - test_lease_3['offer_uuid'] = o1.uuid + self.assertEqual( + api.offer_get_next_lease_start_time( + o1.uuid, + o1.start_time, + ), + None, + ) + test_lease_3["offer_uuid"] = o1.uuid api.lease_create(test_lease_3) - test_lease_7['offer_uuid'] = o1.uuid + test_lease_7["offer_uuid"] = o1.uuid api.lease_create(test_lease_7) self.assertEqual( - api.offer_get_next_lease_start_time( - o1.uuid, o1.start_time), - (now + datetime.timedelta(days=50),)) + api.offer_get_next_lease_start_time(o1.uuid, o1.start_time), + (now + datetime.timedelta(days=50),), + ) def test_offer_get_by_uuid(self): o1 = api.offer_create(test_offer_1) @@ -375,7 +428,7 @@ def test_offer_get_by_uuid(self): self.assertEqual(o1.properties, res.properties) def test_offer_get_by_uuid_not_found(self): - assert api.offer_get_by_uuid('some_uuid') is None + assert api.offer_get_by_uuid("some_uuid") is None def test_offer_get_by_name(self): o1 = api.offer_create(test_offer_1) @@ -383,7 +436,7 @@ def test_offer_get_by_name(self): o3 = api.offer_create(test_offer_3) api.offer_create(test_offer_4) - res = api.offer_get_by_name('o1') + res = api.offer_get_by_name("o1") assert len(res) == 3 self.assertEqual(o1.uuid, res[0].uuid) self.assertEqual(o1.project_id, res[0].project_id) @@ -395,32 +448,32 @@ def test_offer_get_by_name(self): self.assertEqual(o3.project_id, res[2].project_id) def test_offer_get_by_name_not_found(self): - self.assertEqual(api.offer_get_by_name('some_name'), []) + self.assertEqual(api.offer_get_by_name("some_name"), []) def test_offer_destroy(self): o1 = api.offer_create(test_offer_2) api.offer_destroy(o1.uuid) - self.assertEqual(api.offer_get_by_uuid('offer_2'), None) + self.assertEqual(api.offer_get_by_uuid("offer_2"), None) def test_offer_destroy_not_found(self): - self.assertEqual(api.offer_get_by_uuid('offer_4'), None) + self.assertEqual(api.offer_get_by_uuid("offer_4"), None) def test_offer_update(self): o1 = api.offer_create(test_offer_3) - values = {'start_time': test_offer_2['start_time'], - 'end_time': test_offer_2['end_time']} + values = { + "start_time": test_offer_2["start_time"], + "end_time": test_offer_2["end_time"], + } api.offer_update(o1.uuid, values) o1 = api.offer_get_by_uuid(o1.uuid) - self.assertEqual(test_offer_2['start_time'], o1.start_time) - self.assertEqual(test_offer_2['end_time'], o1.end_time) + self.assertEqual(test_offer_2["start_time"], o1.start_time) + self.assertEqual(test_offer_2["end_time"], o1.end_time) def test_offer_update_invalid_time(self): o1 = api.offer_create(test_offer_3) - values = {'start_time': now + datetime.timedelta(days=101), - 'end_time': now} - self.assertRaises(e.InvalidTimeRange, api.offer_update, - o1.uuid, values) + values = {"start_time": now + datetime.timedelta(days=101), "end_time": now} + self.assertRaises(e.InvalidTimeRange, api.offer_update, o1.uuid, values) def test_offer_get_all(self): o1 = api.offer_create(test_offer_2) @@ -428,26 +481,27 @@ def test_offer_get_all(self): res = api.offer_get_all({}) self.assertEqual(2, res.count()) - self.assertEqual((o1.to_dict(), o2.to_dict()), - (res[0].to_dict(), res[1].to_dict())) + self.assertEqual( + (o1.to_dict(), o2.to_dict()), (res[0].to_dict(), res[1].to_dict()) + ) - @mock.patch('esi_leap.common.keystone.get_parent_project_id_tree') + @mock.patch("esi_leap.common.keystone.get_parent_project_id_tree") def test_offer_get_all_lessee_filter(self, mock_gppit): - mock_gppit.return_value = ['12345', '67890'] + mock_gppit.return_value = ["12345", "67890"] o1 = api.offer_create(test_offer_1) o2 = api.offer_create(test_offer_2) o3 = api.offer_create(test_offer_3) api.offer_create(test_offer_4) o5 = api.offer_create(test_offer_5) - res = api.offer_get_all({'lessee_id': '12345'}) + res = api.offer_get_all({"lessee_id": "12345"}) - mock_gppit.assert_called_once_with('12345') + mock_gppit.assert_called_once_with("12345") self.assertEqual(4, res.count()) - self.assertEqual((o1.to_dict(), o2.to_dict(), o3.to_dict(), - o5.to_dict()), - (res[0].to_dict(), res[1].to_dict(), - res[2].to_dict(), res[3].to_dict())) + self.assertEqual( + (o1.to_dict(), o2.to_dict(), o3.to_dict(), o5.to_dict()), + (res[0].to_dict(), res[1].to_dict(), res[2].to_dict(), res[3].to_dict()), + ) def test_offer_get_all_time_filter(self): o1 = api.offer_create(test_offer_1) @@ -455,14 +509,17 @@ def test_offer_get_all_time_filter(self): api.offer_create(test_offer_3) api.offer_create(test_offer_4) api.offer_create(test_offer_5) - res = api.offer_get_all({ - 'start_time': o1.start_time + datetime.timedelta(days=26), - 'end_time': o1.end_time + datetime.timedelta(days=-1), - }) + res = api.offer_get_all( + { + "start_time": o1.start_time + datetime.timedelta(days=26), + "end_time": o1.end_time + datetime.timedelta(days=-1), + } + ) self.assertEqual(2, res.count()) - self.assertEqual((o1.to_dict(), o2.to_dict()), - (res[0].to_dict(), res[1].to_dict())) + self.assertEqual( + (o1.to_dict(), o2.to_dict()), (res[0].to_dict(), res[1].to_dict()) + ) def test_offer_get_all_time_filter_within(self): o1 = api.offer_create(test_offer_1) @@ -470,45 +527,46 @@ def test_offer_get_all_time_filter_within(self): o3 = api.offer_create(test_offer_3) o4 = api.offer_create(test_offer_4) api.offer_create(test_offer_5) - res = api.offer_get_all({ - 'start_time': o1.end_time + datetime.timedelta(days=-2), - 'end_time': o2.end_time + datetime.timedelta(days=1), - 'time_filter_type': 'within' - }) + res = api.offer_get_all( + { + "start_time": o1.end_time + datetime.timedelta(days=-2), + "end_time": o2.end_time + datetime.timedelta(days=1), + "time_filter_type": "within", + } + ) self.assertEqual(4, res.count()) - self.assertEqual((o1.to_dict(), o2.to_dict(), o3.to_dict(), - o4.to_dict()), - (res[0].to_dict(), res[1].to_dict(), - res[2].to_dict(), res[3].to_dict())) + self.assertEqual( + (o1.to_dict(), o2.to_dict(), o3.to_dict(), o4.to_dict()), + (res[0].to_dict(), res[1].to_dict(), res[2].to_dict(), res[3].to_dict()), + ) class TestLeaseAPI(base.DBTestCase): - def test_lease_get_by_uuid(self): o1 = api.offer_create(test_offer_2) - test_lease_4['offer_uuid'] = o1.uuid + test_lease_4["offer_uuid"] = o1.uuid l1 = api.lease_create(test_lease_4) res = api.lease_get_by_uuid(l1.uuid) self.assertEqual(l1.uuid, res.uuid) def test_lease_get_by_uuid_not_found(self): - assert api.lease_get_by_uuid('some_uuid') is None + assert api.lease_get_by_uuid("some_uuid") is None def test_lease_get_by_name(self): o1 = api.offer_create(test_offer_1) o2 = api.offer_create(test_offer_2) o3 = api.offer_create(test_offer_3) o4 = api.offer_create(test_offer_4) - test_lease_1['offer_uuid'] = o1.uuid - test_lease_2['offer_uuid'] = o2.uuid - test_lease_3['offer_uuid'] = o3.uuid - test_lease_4['offer_uuid'] = o4.uuid + test_lease_1["offer_uuid"] = o1.uuid + test_lease_2["offer_uuid"] = o2.uuid + test_lease_3["offer_uuid"] = o3.uuid + test_lease_4["offer_uuid"] = o4.uuid l1 = api.lease_create(test_lease_1) l2 = api.lease_create(test_lease_2) l3 = api.lease_create(test_lease_3) api.lease_create(test_lease_4) - res = api.lease_get_by_name('l1') + res = api.lease_get_by_name("l1") assert len(res) == 3 self.assertEqual(l1.uuid, res[0].uuid) self.assertEqual(l1.project_id, res[0].project_id) @@ -520,18 +578,18 @@ def test_lease_get_by_name(self): self.assertEqual(l3.project_id, res[2].project_id) def test_lease_get_by_name_not_found(self): - self.assertEqual(api.lease_get_by_name('some_name'), []) + self.assertEqual(api.lease_get_by_name("some_name"), []) def test_lease_get_all(self): api.lease_create(test_lease_1) api.lease_create(test_lease_2) res = api.lease_get_all({}) - res_uuids = [res_lease.to_dict()['uuid'] for res_lease in res] + res_uuids = [res_lease.to_dict()["uuid"] for res_lease in res] self.assertEqual(2, res.count()) - self.assertIn(test_lease_1['uuid'], res_uuids) - self.assertIn(test_lease_2['uuid'], res_uuids) + self.assertIn(test_lease_1["uuid"], res_uuids) + self.assertIn(test_lease_2["uuid"], res_uuids) def test_lease_get_all_filter_by_status(self): api.lease_create(test_lease_1) @@ -540,29 +598,27 @@ def test_lease_get_all_filter_by_status(self): api.lease_create(test_lease_4) api.lease_create(test_lease_5) - res = api.lease_get_all({'status': [statuses.CREATED, - statuses.ACTIVE]}) - res_uuids = [res_lease.to_dict()['uuid'] for res_lease in res] + res = api.lease_get_all({"status": [statuses.CREATED, statuses.ACTIVE]}) + res_uuids = [res_lease.to_dict()["uuid"] for res_lease in res] self.assertEqual(3, res.count()) - self.assertIn(test_lease_1['uuid'], res_uuids) - self.assertIn(test_lease_2['uuid'], res_uuids) - self.assertIn(test_lease_3['uuid'], res_uuids) + self.assertIn(test_lease_1["uuid"], res_uuids) + self.assertIn(test_lease_2["uuid"], res_uuids) + self.assertIn(test_lease_3["uuid"], res_uuids) def test_lease_get_all_filter_by_time(self): api.lease_create(test_lease_1) api.lease_create(test_lease_2) api.lease_create(test_lease_3) - start_time = test_lease_2['start_time'] + datetime.timedelta(days=1) - end_time = test_lease_2['end_time'] + datetime.timedelta(days=-1) + start_time = test_lease_2["start_time"] + datetime.timedelta(days=1) + end_time = test_lease_2["end_time"] + datetime.timedelta(days=-1) - res = api.lease_get_all({'start_time': start_time, - 'end_time': end_time}) - res_uuids = [res_lease.to_dict()['uuid'] for res_lease in res] + res = api.lease_get_all({"start_time": start_time, "end_time": end_time}) + res_uuids = [res_lease.to_dict()["uuid"] for res_lease in res] self.assertEqual(1, res.count()) - self.assertIn(test_lease_2['uuid'], res_uuids) + self.assertIn(test_lease_2["uuid"], res_uuids) def test_lease_get_all_filter_by_time_within(self): api.lease_create(test_lease_1) @@ -570,18 +626,22 @@ def test_lease_get_all_filter_by_time_within(self): api.lease_create(test_lease_3) api.lease_create(test_lease_6) - start_time = test_lease_1['end_time'] + datetime.timedelta(days=-1) - end_time = test_lease_2['start_time'] + datetime.timedelta(days=1) + start_time = test_lease_1["end_time"] + datetime.timedelta(days=-1) + end_time = test_lease_2["start_time"] + datetime.timedelta(days=1) - res = api.lease_get_all({'start_time': start_time, - 'end_time': end_time, - 'time_filter_type': 'within'}) - res_uuids = [res_lease.to_dict()['uuid'] for res_lease in res] + res = api.lease_get_all( + { + "start_time": start_time, + "end_time": end_time, + "time_filter_type": "within", + } + ) + res_uuids = [res_lease.to_dict()["uuid"] for res_lease in res] self.assertEqual(3, res.count()) - self.assertIn(test_lease_1['uuid'], res_uuids) - self.assertIn(test_lease_2['uuid'], res_uuids) - self.assertIn(test_lease_6['uuid'], res_uuids) + self.assertIn(test_lease_1["uuid"], res_uuids) + self.assertIn(test_lease_2["uuid"], res_uuids) + self.assertIn(test_lease_6["uuid"], res_uuids) def test_lease_get_all_filter_by_project_or_owner_id(self): api.lease_create(test_lease_1) @@ -590,17 +650,17 @@ def test_lease_get_all_filter_by_project_or_owner_id(self): api.lease_create(test_lease_4) api.lease_create(test_lease_5) - res = api.lease_get_all({'project_or_owner_id': '0wn3r'}) - res_uuids = [res_lease.to_dict()['uuid'] for res_lease in res] + res = api.lease_get_all({"project_or_owner_id": "0wn3r"}) + res_uuids = [res_lease.to_dict()["uuid"] for res_lease in res] self.assertEqual(3, res.count()) - self.assertIn(test_lease_1['uuid'], res_uuids) - self.assertIn(test_lease_2['uuid'], res_uuids) - self.assertIn(test_lease_5['uuid'], res_uuids) + self.assertIn(test_lease_1["uuid"], res_uuids) + self.assertIn(test_lease_2["uuid"], res_uuids) + self.assertIn(test_lease_5["uuid"], res_uuids) def test_lease_create(self): o1 = api.offer_create(test_offer_2) - test_lease_4['offer_uuid'] = o1.uuid + test_lease_4["offer_uuid"] = o1.uuid l1 = api.lease_create(test_lease_4) l2 = api.lease_get_all({}).all() assert len(l2) == 1 @@ -608,37 +668,36 @@ def test_lease_create(self): def test_lease_update(self): o1 = api.offer_create(test_offer_2) - test_lease_4['offer_uuid'] = o1.uuid + test_lease_4["offer_uuid"] = o1.uuid l1 = api.lease_create(test_lease_4) - values = {'start_time': test_lease_5['start_time'], - 'end_time': test_lease_5['end_time']} + values = { + "start_time": test_lease_5["start_time"], + "end_time": test_lease_5["end_time"], + } api.lease_update(l1.uuid, values) l1 = api.lease_get_by_uuid(l1.uuid) - self.assertEqual(test_lease_5['start_time'], l1.start_time) - self.assertEqual(test_lease_5['end_time'], l1.end_time) + self.assertEqual(test_lease_5["start_time"], l1.start_time) + self.assertEqual(test_lease_5["end_time"], l1.end_time) def test_lease_update_invalid_time(self): o1 = api.offer_create(test_offer_3) - test_lease_4['offer_uuid'] = o1.uuid + test_lease_4["offer_uuid"] = o1.uuid l1 = api.lease_create(test_lease_4) - values = {'start_time': now + datetime.timedelta(days=101), - 'end_time': now} - self.assertRaises(e.InvalidTimeRange, api.lease_update, - l1.uuid, values) + values = {"start_time": now + datetime.timedelta(days=101), "end_time": now} + self.assertRaises(e.InvalidTimeRange, api.lease_update, l1.uuid, values) def test_lease_destroy(self): o1 = api.offer_create(test_offer_2) - test_lease_4['offer_uuid'] = o1.uuid + test_lease_4["offer_uuid"] = o1.uuid l1 = api.lease_create(test_lease_4) api.lease_destroy(l1.uuid) - self.assertEqual(api.lease_get_by_uuid('lease_4'), None) + self.assertEqual(api.lease_get_by_uuid("lease_4"), None) def test_lease_destroy_not_found(self): - self.assertEqual(api.lease_get_by_uuid('lease_4'), None) + self.assertEqual(api.lease_get_by_uuid("lease_4"), None) class TestLeaseVerifyChildAvailability(base.DBTestCase): - def setUp(self): super(TestLeaseVerifyChildAvailability, self).setUp() @@ -646,9 +705,9 @@ def setUp(self): uuid=uuidutils.generate_uuid(), project_id=uuidutils.generate_uuid(), owner_id=uuidutils.generate_uuid(), - resource_uuid='1111', - resource_type='dummy_node', - purpose='test_purpose', + resource_uuid="1111", + resource_type="dummy_node", + purpose="test_purpose", start_time=now + datetime.timedelta(days=50), end_time=now + datetime.timedelta(days=100), status=statuses.ACTIVE, @@ -657,10 +716,10 @@ def setUp(self): uuid=uuidutils.generate_uuid(), project_id=uuidutils.generate_uuid(), owner_id=uuidutils.generate_uuid(), - parent_lease_uuid=self.parent_lease_data['uuid'], - resource_uuid='1111', - resource_type='dummy_node', - purpose='test_purpose', + parent_lease_uuid=self.parent_lease_data["uuid"], + resource_uuid="1111", + resource_type="dummy_node", + purpose="test_purpose", start_time=now + datetime.timedelta(days=60), end_time=now + datetime.timedelta(days=70), status=statuses.ACTIVE, @@ -668,9 +727,9 @@ def setUp(self): self.child_offer_data = dict( uuid=uuidutils.generate_uuid(), project_id=uuidutils.generate_uuid(), - parent_lease_uuid=self.parent_lease_data['uuid'], - resource_uuid='1111', - resource_type='dummy_node', + parent_lease_uuid=self.parent_lease_data["uuid"], + resource_uuid="1111", + resource_type="dummy_node", start_time=now + datetime.timedelta(days=70), end_time=now + datetime.timedelta(days=80), status=statuses.AVAILABLE, @@ -679,204 +738,259 @@ def setUp(self): def test_lease_verify_child_availability(self): parent_lease = api.lease_create(self.parent_lease_data) - start = (self.parent_lease_data['start_time'] + - datetime.timedelta(days=1)) - end = self.parent_lease_data['end_time'] + datetime.timedelta(days=-1) + start = self.parent_lease_data["start_time"] + datetime.timedelta(days=1) + end = self.parent_lease_data["end_time"] + datetime.timedelta(days=-1) api.lease_verify_child_availability(parent_lease, start, end) - start = (self.parent_lease_data['start_time'] + - datetime.timedelta(days=-1)) - end = self.parent_lease_data['end_time'] + datetime.timedelta(days=-1) - self.assertRaises(e.LeaseNoTimeAvailabilities, - api.lease_verify_child_availability, - parent_lease, start, end,) - - start = (self.parent_lease_data['start_time'] + - datetime.timedelta(days=1)) - end = self.parent_lease_data['end_time'] + datetime.timedelta(days=1) - self.assertRaises(e.LeaseNoTimeAvailabilities, - api.lease_verify_child_availability, - parent_lease, start, end,) - - start = (self.parent_lease_data['start_time'] + - datetime.timedelta(days=-1)) - end = self.parent_lease_data['end_time'] + datetime.timedelta(days=1) - self.assertRaises(e.LeaseNoTimeAvailabilities, - api.lease_verify_child_availability, - parent_lease, start, end,) + start = self.parent_lease_data["start_time"] + datetime.timedelta(days=-1) + end = self.parent_lease_data["end_time"] + datetime.timedelta(days=-1) + self.assertRaises( + e.LeaseNoTimeAvailabilities, + api.lease_verify_child_availability, + parent_lease, + start, + end, + ) + + start = self.parent_lease_data["start_time"] + datetime.timedelta(days=1) + end = self.parent_lease_data["end_time"] + datetime.timedelta(days=1) + self.assertRaises( + e.LeaseNoTimeAvailabilities, + api.lease_verify_child_availability, + parent_lease, + start, + end, + ) + + start = self.parent_lease_data["start_time"] + datetime.timedelta(days=-1) + end = self.parent_lease_data["end_time"] + datetime.timedelta(days=1) + self.assertRaises( + e.LeaseNoTimeAvailabilities, + api.lease_verify_child_availability, + parent_lease, + start, + end, + ) def test_lease_verify_child_availability_lease_conflict(self): parent_lease = api.lease_create(self.parent_lease_data) api.lease_create(self.child_lease_data) - start = (self.child_lease_data['start_time'] + - datetime.timedelta(days=-5)) - end = self.child_lease_data['start_time'] + datetime.timedelta(days=-1) + start = self.child_lease_data["start_time"] + datetime.timedelta(days=-5) + end = self.child_lease_data["start_time"] + datetime.timedelta(days=-1) api.lease_verify_child_availability(parent_lease, start, end) - start = self.child_lease_data['end_time'] + datetime.timedelta(days=1) - end = self.child_lease_data['end_time'] + datetime.timedelta(days=5) + start = self.child_lease_data["end_time"] + datetime.timedelta(days=1) + end = self.child_lease_data["end_time"] + datetime.timedelta(days=5) api.lease_verify_child_availability(parent_lease, start, end) - start = (self.child_lease_data['start_time'] + - datetime.timedelta(days=1)) - end = self.child_lease_data['end_time'] + datetime.timedelta(days=5) - self.assertRaises(e.LeaseNoTimeAvailabilities, - api.lease_verify_child_availability, - parent_lease, start, end,) + start = self.child_lease_data["start_time"] + datetime.timedelta(days=1) + end = self.child_lease_data["end_time"] + datetime.timedelta(days=5) + self.assertRaises( + e.LeaseNoTimeAvailabilities, + api.lease_verify_child_availability, + parent_lease, + start, + end, + ) - start = (self.child_lease_data['start_time'] + - datetime.timedelta(days=-1)) - end = self.child_lease_data['end_time'] + datetime.timedelta(days=-1) - self.assertRaises(e.LeaseNoTimeAvailabilities, - api.lease_verify_child_availability, - parent_lease, start, end,) + start = self.child_lease_data["start_time"] + datetime.timedelta(days=-1) + end = self.child_lease_data["end_time"] + datetime.timedelta(days=-1) + self.assertRaises( + e.LeaseNoTimeAvailabilities, + api.lease_verify_child_availability, + parent_lease, + start, + end, + ) def test_lease_verify_child_availability_offer_conflict(self): parent_lease = api.lease_create(self.parent_lease_data) api.offer_create(self.child_offer_data) - start = (self.child_offer_data['start_time'] + - datetime.timedelta(days=-5)) - end = self.child_offer_data['start_time'] + datetime.timedelta(days=-1) + start = self.child_offer_data["start_time"] + datetime.timedelta(days=-5) + end = self.child_offer_data["start_time"] + datetime.timedelta(days=-1) api.lease_verify_child_availability(parent_lease, start, end) - start = self.child_offer_data['end_time'] + datetime.timedelta(days=1) - end = self.child_offer_data['end_time'] + datetime.timedelta(days=5) + start = self.child_offer_data["end_time"] + datetime.timedelta(days=1) + end = self.child_offer_data["end_time"] + datetime.timedelta(days=5) api.lease_verify_child_availability(parent_lease, start, end) - start = (self.child_offer_data['start_time'] + - datetime.timedelta(days=1)) - end = self.child_offer_data['end_time'] + datetime.timedelta(days=5) - self.assertRaises(e.LeaseNoTimeAvailabilities, - api.lease_verify_child_availability, - parent_lease, start, end,) + start = self.child_offer_data["start_time"] + datetime.timedelta(days=1) + end = self.child_offer_data["end_time"] + datetime.timedelta(days=5) + self.assertRaises( + e.LeaseNoTimeAvailabilities, + api.lease_verify_child_availability, + parent_lease, + start, + end, + ) - start = (self.child_offer_data['start_time'] + - datetime.timedelta(days=-1)) - end = self.child_offer_data['end_time'] + datetime.timedelta(days=-1) - self.assertRaises(e.LeaseNoTimeAvailabilities, - api.lease_verify_child_availability, - parent_lease, start, end,) + start = self.child_offer_data["start_time"] + datetime.timedelta(days=-1) + end = self.child_offer_data["end_time"] + datetime.timedelta(days=-1) + self.assertRaises( + e.LeaseNoTimeAvailabilities, + api.lease_verify_child_availability, + parent_lease, + start, + end, + ) class TestResourceVerifyAvailabilityAPI(base.DBTestCase): - def test_resource_verify_availability_offer_conflict(self): o1 = api.offer_create(test_offer_4) r_type = o1.resource_type r_uuid = o1.resource_uuid - start = test_offer_4['end_time'] + datetime.timedelta(days=1) - end = test_offer_4['end_time'] + datetime.timedelta(days=5) + start = test_offer_4["end_time"] + datetime.timedelta(days=1) + end = test_offer_4["end_time"] + datetime.timedelta(days=5) api.resource_verify_availability(r_type, r_uuid, start, end) - start = test_offer_4['start_time'] + datetime.timedelta(days=1) - end = test_offer_4['end_time'] + datetime.timedelta(days=-1) - self.assertRaises(e.ResourceTimeConflict, - api.resource_verify_availability, - r_type, r_uuid, start, end) - - start = test_offer_4['start_time'] + datetime.timedelta(days=-1) - end = test_offer_4['end_time'] + datetime.timedelta(days=1) - self.assertRaises(e.ResourceTimeConflict, - api.resource_verify_availability, - r_type, r_uuid, start, end) - - start = test_offer_4['start_time'] + datetime.timedelta(days=-1) - end = test_offer_4['start_time'] + datetime.timedelta(days=1) - self.assertRaises(e.ResourceTimeConflict, - api.resource_verify_availability, - r_type, r_uuid, start, end) - - start = test_offer_4['end_time'] + datetime.timedelta(days=-1) - end = test_offer_4['end_time'] + datetime.timedelta(days=1) - self.assertRaises(e.ResourceTimeConflict, - api.resource_verify_availability, - r_type, r_uuid, start, end) + start = test_offer_4["start_time"] + datetime.timedelta(days=1) + end = test_offer_4["end_time"] + datetime.timedelta(days=-1) + self.assertRaises( + e.ResourceTimeConflict, + api.resource_verify_availability, + r_type, + r_uuid, + start, + end, + ) + + start = test_offer_4["start_time"] + datetime.timedelta(days=-1) + end = test_offer_4["end_time"] + datetime.timedelta(days=1) + self.assertRaises( + e.ResourceTimeConflict, + api.resource_verify_availability, + r_type, + r_uuid, + start, + end, + ) + + start = test_offer_4["start_time"] + datetime.timedelta(days=-1) + end = test_offer_4["start_time"] + datetime.timedelta(days=1) + self.assertRaises( + e.ResourceTimeConflict, + api.resource_verify_availability, + r_type, + r_uuid, + start, + end, + ) + + start = test_offer_4["end_time"] + datetime.timedelta(days=-1) + end = test_offer_4["end_time"] + datetime.timedelta(days=1) + self.assertRaises( + e.ResourceTimeConflict, + api.resource_verify_availability, + r_type, + r_uuid, + start, + end, + ) def test_resource_verify_availability_lease_conflict(self): test_lease = api.lease_create(test_lease_1) r_type = test_lease.resource_type r_uuid = test_lease.resource_uuid - start = test_lease_1['end_time'] + datetime.timedelta(days=1) - end = test_lease_1['end_time'] + datetime.timedelta(days=5) + start = test_lease_1["end_time"] + datetime.timedelta(days=1) + end = test_lease_1["end_time"] + datetime.timedelta(days=5) api.resource_verify_availability(r_type, r_uuid, start, end) - start = test_lease_1['start_time'] + datetime.timedelta(days=1) - end = test_lease_1['end_time'] + datetime.timedelta(days=-1) - self.assertRaises(e.ResourceTimeConflict, - api.resource_verify_availability, - r_type, r_uuid, start, end) + start = test_lease_1["start_time"] + datetime.timedelta(days=1) + end = test_lease_1["end_time"] + datetime.timedelta(days=-1) + self.assertRaises( + e.ResourceTimeConflict, + api.resource_verify_availability, + r_type, + r_uuid, + start, + end, + ) - start = test_lease_1['start_time'] + datetime.timedelta(days=-1) - end = test_lease_1['end_time'] + datetime.timedelta(days=1) - self.assertRaises(e.ResourceTimeConflict, - api.resource_verify_availability, - r_type, r_uuid, start, end) + start = test_lease_1["start_time"] + datetime.timedelta(days=-1) + end = test_lease_1["end_time"] + datetime.timedelta(days=1) + self.assertRaises( + e.ResourceTimeConflict, + api.resource_verify_availability, + r_type, + r_uuid, + start, + end, + ) - start = test_lease_1['start_time'] + datetime.timedelta(days=-1) - end = test_lease_1['start_time'] + datetime.timedelta(days=1) - self.assertRaises(e.ResourceTimeConflict, - api.resource_verify_availability, - r_type, r_uuid, start, end) + start = test_lease_1["start_time"] + datetime.timedelta(days=-1) + end = test_lease_1["start_time"] + datetime.timedelta(days=1) + self.assertRaises( + e.ResourceTimeConflict, + api.resource_verify_availability, + r_type, + r_uuid, + start, + end, + ) - start = test_lease_1['end_time'] + datetime.timedelta(days=-1) - end = test_lease_1['end_time'] + datetime.timedelta(days=1) - self.assertRaises(e.ResourceTimeConflict, - api.resource_verify_availability, - r_type, r_uuid, start, end) + start = test_lease_1["end_time"] + datetime.timedelta(days=-1) + end = test_lease_1["end_time"] + datetime.timedelta(days=1) + self.assertRaises( + e.ResourceTimeConflict, + api.resource_verify_availability, + r_type, + r_uuid, + start, + end, + ) class TestEventAPI(base.DBTestCase): - def test_event_get_all(self): api.event_create(test_event_1) api.event_create(test_event_2) events = api.event_get_all({}) - event_ids = [event.to_dict()['id'] for event in events] + event_ids = [event.to_dict()["id"] for event in events] self.assertEqual(2, events.count()) - self.assertIn(test_event_1['id'], event_ids) - self.assertIn(test_event_2['id'], event_ids) + self.assertIn(test_event_1["id"], event_ids) + self.assertIn(test_event_2["id"], event_ids) def test_event_get_all_filter_by_last_event_time(self): api.event_create(test_event_1) api.event_create(test_event_2) api.event_create(test_event_3) - events = api.event_get_all({'last_event_time': - test_event_1['event_time']}) - event_ids = [event.to_dict()['id'] for event in events] + events = api.event_get_all({"last_event_time": test_event_1["event_time"]}) + event_ids = [event.to_dict()["id"] for event in events] self.assertEqual(1, events.count()) - self.assertIn(test_event_2['id'], event_ids) + self.assertIn(test_event_2["id"], event_ids) def test_event_get_all_filter_by_last_event_id(self): api.event_create(test_event_1) api.event_create(test_event_2) api.event_create(test_event_3) - events = api.event_get_all({'last_event_id': 1}) - event_ids = [event.to_dict()['id'] for event in events] + events = api.event_get_all({"last_event_id": 1}) + event_ids = [event.to_dict()["id"] for event in events] self.assertEqual(2, events.count()) - self.assertIn(test_event_2['id'], event_ids) - self.assertIn(test_event_3['id'], event_ids) + self.assertIn(test_event_2["id"], event_ids) + self.assertIn(test_event_3["id"], event_ids) def test_event_get_all_filter_by_lessee_or_owner_id(self): api.event_create(test_event_1) api.event_create(test_event_2) api.event_create(test_event_3) - events = api.event_get_all({'lessee_or_owner_id': '0wn3r'}) - event_ids = [event.to_dict()['id'] for event in events] + events = api.event_get_all({"lessee_or_owner_id": "0wn3r"}) + event_ids = [event.to_dict()["id"] for event in events] self.assertEqual(2, events.count()) - self.assertIn(test_event_1['id'], event_ids) - self.assertIn(test_event_2['id'], event_ids) + self.assertIn(test_event_1["id"], event_ids) + self.assertIn(test_event_2["id"], event_ids) def test_lease_create(self): event = api.event_create(test_event_1) diff --git a/esi_leap/tests/manager/test_service.py b/esi_leap/tests/manager/test_service.py index 4f5a85bc..03bb93f6 100644 --- a/esi_leap/tests/manager/test_service.py +++ b/esi_leap/tests/manager/test_service.py @@ -22,34 +22,33 @@ class TestService(base.TestCase): - def setUp(self): super(TestService, self).setUp() self.test_offer = offer.Offer( - resource_type='test_node', - resource_uuid='abc', - name='o', + resource_type="test_node", + resource_uuid="abc", + name="o", uuid=uuidutils.generate_uuid(), status=statuses.AVAILABLE, start_time=datetime.datetime(3000, 7, 16), end_time=datetime.datetime(4000, 7, 16), - project_id='ownerid' + project_id="ownerid", ) self.test_lease = lease.Lease( offer_uuid=self.test_offer.uuid, - name='c', + name="c", uuid=uuidutils.generate_uuid(), - project_id='lesseeid', + project_id="lesseeid", status=statuses.CREATED, start_time=datetime.datetime(3000, 7, 16), end_time=datetime.datetime(4000, 7, 16), ) - @mock.patch('esi_leap.objects.lease.Lease.fulfill') - @mock.patch('oslo_utils.timeutils.utcnow') - @mock.patch('esi_leap.objects.lease.Lease.get_all') + @mock.patch("esi_leap.objects.lease.Lease.fulfill") + @mock.patch("oslo_utils.timeutils.utcnow") + @mock.patch("esi_leap.objects.lease.Lease.get_all") def test__fulfill_leases(self, mock_ga, mock_utcnow, mock_fulfill): mock_ga.return_value = [self.test_lease, self.test_lease] mock_utcnow.return_value = datetime.datetime(3500, 7, 16) @@ -58,42 +57,41 @@ def test__fulfill_leases(self, mock_ga, mock_utcnow, mock_fulfill): s._fulfill_leases() assert mock_fulfill.call_count == 2 - mock_ga.assert_called_once_with({ - 'status': [statuses.CREATED, statuses.WAIT_FULFILL] - }, s._context) - - @mock.patch('esi_leap.objects.lease.Lease.save') - @mock.patch('esi_leap.objects.lease.Lease.fulfill') - @mock.patch('oslo_utils.timeutils.utcnow') - @mock.patch('esi_leap.objects.lease.Lease.get_all') - def test__fulfill_leases_error(self, mock_ga, mock_utcnow, mock_fulfill, - mock_save): + mock_ga.assert_called_once_with( + {"status": [statuses.CREATED, statuses.WAIT_FULFILL]}, s._context + ) + + @mock.patch("esi_leap.objects.lease.Lease.save") + @mock.patch("esi_leap.objects.lease.Lease.fulfill") + @mock.patch("oslo_utils.timeutils.utcnow") + @mock.patch("esi_leap.objects.lease.Lease.get_all") + def test__fulfill_leases_error(self, mock_ga, mock_utcnow, mock_fulfill, mock_save): error_lease = lease.Lease( offer_uuid=self.test_offer.uuid, - name='c', + name="c", uuid=uuidutils.generate_uuid(), - project_id='lesseeid', + project_id="lesseeid", status=statuses.CREATED, start_time=datetime.datetime(3000, 7, 16), end_time=datetime.datetime(4000, 7, 16), ) mock_ga.return_value = [error_lease] mock_utcnow.return_value = datetime.datetime(3500, 7, 16) - mock_fulfill.side_effect = Exception('whoops') + mock_fulfill.side_effect = Exception("whoops") s = ManagerService() s._fulfill_leases() mock_fulfill.assert_called_once() - mock_ga.assert_called_once_with({ - 'status': [statuses.CREATED, statuses.WAIT_FULFILL] - }, s._context) + mock_ga.assert_called_once_with( + {"status": [statuses.CREATED, statuses.WAIT_FULFILL]}, s._context + ) self.assertEqual(statuses.ERROR, error_lease.status) mock_save.assert_called_once() - @mock.patch('esi_leap.objects.lease.Lease.expire') - @mock.patch('oslo_utils.timeutils.utcnow') - @mock.patch('esi_leap.objects.lease.Lease.get_all') + @mock.patch("esi_leap.objects.lease.Lease.expire") + @mock.patch("oslo_utils.timeutils.utcnow") + @mock.patch("esi_leap.objects.lease.Lease.get_all") def test__expire_leases(self, mock_ga, mock_utcnow, mock_expire): mock_ga.return_value = [self.test_lease, self.test_lease] mock_utcnow.return_value = datetime.datetime(5000, 7, 16) @@ -102,44 +100,57 @@ def test__expire_leases(self, mock_ga, mock_utcnow, mock_expire): s._expire_leases() assert mock_expire.call_count == 2 - mock_ga.assert_called_once_with({ - 'status': [statuses.ACTIVE, statuses.CREATED, - statuses.WAIT_EXPIRE, statuses.WAIT_FULFILL] - }, s._context) - - @mock.patch('esi_leap.objects.lease.Lease.save') - @mock.patch('esi_leap.objects.lease.Lease.expire') - @mock.patch('oslo_utils.timeutils.utcnow') - @mock.patch('esi_leap.objects.lease.Lease.get_all') - def test__expire_leases_error(self, mock_ga, mock_utcnow, mock_expire, - mock_save): + mock_ga.assert_called_once_with( + { + "status": [ + statuses.ACTIVE, + statuses.CREATED, + statuses.WAIT_EXPIRE, + statuses.WAIT_FULFILL, + ] + }, + s._context, + ) + + @mock.patch("esi_leap.objects.lease.Lease.save") + @mock.patch("esi_leap.objects.lease.Lease.expire") + @mock.patch("oslo_utils.timeutils.utcnow") + @mock.patch("esi_leap.objects.lease.Lease.get_all") + def test__expire_leases_error(self, mock_ga, mock_utcnow, mock_expire, mock_save): error_lease = lease.Lease( offer_uuid=self.test_offer.uuid, - name='c', + name="c", uuid=uuidutils.generate_uuid(), - project_id='lesseeid', + project_id="lesseeid", status=statuses.CREATED, start_time=datetime.datetime(3000, 7, 16), end_time=datetime.datetime(4000, 7, 16), ) mock_ga.return_value = [error_lease] mock_utcnow.return_value = datetime.datetime(5000, 7, 16) - mock_expire.side_effect = Exception('whoops') + mock_expire.side_effect = Exception("whoops") s = ManagerService() s._expire_leases() mock_expire.assert_called_once() - mock_ga.assert_called_once_with({ - 'status': [statuses.ACTIVE, statuses.CREATED, - statuses.WAIT_EXPIRE, statuses.WAIT_FULFILL] - }, s._context) + mock_ga.assert_called_once_with( + { + "status": [ + statuses.ACTIVE, + statuses.CREATED, + statuses.WAIT_EXPIRE, + statuses.WAIT_FULFILL, + ] + }, + s._context, + ) self.assertEqual(statuses.ERROR, error_lease.status) mock_save.assert_called_once() - @mock.patch('esi_leap.objects.lease.Lease.cancel') - @mock.patch('oslo_utils.timeutils.utcnow') - @mock.patch('esi_leap.objects.lease.Lease.get_all') + @mock.patch("esi_leap.objects.lease.Lease.cancel") + @mock.patch("oslo_utils.timeutils.utcnow") + @mock.patch("esi_leap.objects.lease.Lease.get_all") def test__cancel_leases(self, mock_ga, mock_utcnow, mock_cancel): mock_ga.return_value = [self.test_lease, self.test_lease] @@ -147,42 +158,37 @@ def test__cancel_leases(self, mock_ga, mock_utcnow, mock_cancel): s._cancel_leases() assert mock_cancel.call_count == 2 - mock_ga.assert_called_once_with({ - 'status': [statuses.WAIT_CANCEL] - }, s._context) - - @mock.patch('esi_leap.objects.lease.Lease.save') - @mock.patch('esi_leap.objects.lease.Lease.cancel') - @mock.patch('oslo_utils.timeutils.utcnow') - @mock.patch('esi_leap.objects.lease.Lease.get_all') - def test__cancel_leases_error(self, mock_ga, mock_utcnow, mock_cancel, - mock_save): + mock_ga.assert_called_once_with({"status": [statuses.WAIT_CANCEL]}, s._context) + + @mock.patch("esi_leap.objects.lease.Lease.save") + @mock.patch("esi_leap.objects.lease.Lease.cancel") + @mock.patch("oslo_utils.timeutils.utcnow") + @mock.patch("esi_leap.objects.lease.Lease.get_all") + def test__cancel_leases_error(self, mock_ga, mock_utcnow, mock_cancel, mock_save): error_lease = lease.Lease( offer_uuid=self.test_offer.uuid, - name='c', + name="c", uuid=uuidutils.generate_uuid(), - project_id='lesseeid', + project_id="lesseeid", status=statuses.WAIT_CANCEL, start_time=datetime.datetime(3000, 7, 16), end_time=datetime.datetime(4000, 7, 16), ) mock_ga.return_value = [error_lease] mock_utcnow.return_value = datetime.datetime(5000, 7, 16) - mock_cancel.side_effect = Exception('whoops') + mock_cancel.side_effect = Exception("whoops") s = ManagerService() s._cancel_leases() mock_cancel.assert_called_once() - mock_ga.assert_called_once_with({ - 'status': [statuses.WAIT_CANCEL] - }, s._context) + mock_ga.assert_called_once_with({"status": [statuses.WAIT_CANCEL]}, s._context) self.assertEqual(statuses.ERROR, error_lease.status) mock_save.assert_called_once() - @mock.patch('esi_leap.objects.offer.Offer.expire') - @mock.patch('oslo_utils.timeutils.utcnow') - @mock.patch('esi_leap.objects.offer.Offer.get_all') + @mock.patch("esi_leap.objects.offer.Offer.expire") + @mock.patch("oslo_utils.timeutils.utcnow") + @mock.patch("esi_leap.objects.offer.Offer.get_all") def test__expire_offers(self, mock_ga, mock_utcnow, mock_expire): mock_ga.return_value = [self.test_offer, self.test_offer] mock_utcnow.return_value = datetime.datetime(5000, 7, 16) @@ -191,36 +197,35 @@ def test__expire_offers(self, mock_ga, mock_utcnow, mock_expire): s._expire_offers() assert mock_expire.call_count == 2 - mock_ga.assert_called_once_with({ - 'status': statuses.OFFER_CAN_DELETE - }, s._context) - - @mock.patch('esi_leap.objects.offer.Offer.save') - @mock.patch('esi_leap.objects.offer.Offer.expire') - @mock.patch('oslo_utils.timeutils.utcnow') - @mock.patch('esi_leap.objects.offer.Offer.get_all') - def test__expire_offers_error(self, mock_ga, mock_utcnow, mock_expire, - mock_save): + mock_ga.assert_called_once_with( + {"status": statuses.OFFER_CAN_DELETE}, s._context + ) + + @mock.patch("esi_leap.objects.offer.Offer.save") + @mock.patch("esi_leap.objects.offer.Offer.expire") + @mock.patch("oslo_utils.timeutils.utcnow") + @mock.patch("esi_leap.objects.offer.Offer.get_all") + def test__expire_offers_error(self, mock_ga, mock_utcnow, mock_expire, mock_save): error_offer = offer.Offer( - resource_type='test_node', - resource_uuid='abc', - name='o', + resource_type="test_node", + resource_uuid="abc", + name="o", uuid=uuidutils.generate_uuid(), status=statuses.AVAILABLE, start_time=datetime.datetime(3000, 7, 16), end_time=datetime.datetime(4000, 7, 16), - project_id='ownerid' + project_id="ownerid", ) mock_ga.return_value = [error_offer] mock_utcnow.return_value = datetime.datetime(5000, 7, 16) - mock_expire.side_effect = Exception('whoops') + mock_expire.side_effect = Exception("whoops") s = ManagerService() s._expire_offers() mock_expire.assert_called_once() - mock_ga.assert_called_once_with({ - 'status': statuses.OFFER_CAN_DELETE - }, s._context) + mock_ga.assert_called_once_with( + {"status": statuses.OFFER_CAN_DELETE}, s._context + ) self.assertEqual(statuses.ERROR, error_offer.status) mock_save.assert_called_once() diff --git a/esi_leap/tests/objects/test_event.py b/esi_leap/tests/objects/test_event.py index 02b8568f..1ba56135 100644 --- a/esi_leap/tests/objects/test_event.py +++ b/esi_leap/tests/objects/test_event.py @@ -18,44 +18,42 @@ class TestEventObject(base.DBTestCase): - def setUp(self): super(TestEventObject, self).setUp() event_time = datetime.now() self.test_event_create_dict = { - 'event_type': 'fake:event', - 'event_time': event_time, - 'object_type': 'lease', - 'object_uuid': '11111', - 'resource_type': 'dummy_node', - 'resource_uuid': '22222', - 'lessee_id': '33333', - 'owner_id': '44444', + "event_type": "fake:event", + "event_time": event_time, + "object_type": "lease", + "object_uuid": "11111", + "resource_type": "dummy_node", + "resource_uuid": "22222", + "lessee_id": "33333", + "owner_id": "44444", } self.test_event_dict = { - 'id': 1, - 'event_type': 'fake:event', - 'event_time': event_time, - 'object_type': 'lease', - 'object_uuid': '11111', - 'resource_type': 'dummy_node', - 'resource_uuid': '22222', - 'lessee_id': '33333', - 'owner_id': '44444', - 'created_at': event_time, - 'updated_at': None, + "id": 1, + "event_type": "fake:event", + "event_time": event_time, + "object_type": "lease", + "object_uuid": "11111", + "resource_type": "dummy_node", + "resource_uuid": "22222", + "lessee_id": "33333", + "owner_id": "44444", + "created_at": event_time, + "updated_at": None, } - @mock.patch('esi_leap.db.sqlalchemy.api.event_get_all') + @mock.patch("esi_leap.db.sqlalchemy.api.event_get_all") def test_get_all(self, mock_ega): event_obj.Event.get_all({}, self.context) mock_ega.assert_called_once_with({}) - @mock.patch('esi_leap.db.sqlalchemy.api.event_create') + @mock.patch("esi_leap.db.sqlalchemy.api.event_create") def test_create(self, mock_ec): mock_ec.return_value = self.test_event_dict - event = event_obj.Event(self.context, - **self.test_event_create_dict) + event = event_obj.Event(self.context, **self.test_event_create_dict) event.create() mock_ec.assert_called_once_with(self.test_event_create_dict) diff --git a/esi_leap/tests/objects/test_fields.py b/esi_leap/tests/objects/test_fields.py index 77b3b8a0..c8938108 100644 --- a/esi_leap/tests/objects/test_fields.py +++ b/esi_leap/tests/objects/test_fields.py @@ -16,57 +16,60 @@ # FlexibleDict borrowed from Ironic class TestFlexibleDictField(base.TestCase): - def setUp(self): super(TestFlexibleDictField, self).setUp() self.field = fields.FlexibleDictField() def test_coerce(self): - d = {'foo_1': 'bar', 'foo_2': 2, 'foo_3': [], 'foo_4': {}} - self.assertEqual(d, self.field.coerce('obj', 'attr', d)) - self.assertEqual({'foo': 'bar'}, - self.field.coerce('obj', 'attr', '{"foo": "bar"}')) + d = {"foo_1": "bar", "foo_2": 2, "foo_3": [], "foo_4": {}} + self.assertEqual(d, self.field.coerce("obj", "attr", d)) + self.assertEqual( + {"foo": "bar"}, self.field.coerce("obj", "attr", '{"foo": "bar"}') + ) def test_coerce_bad_values(self): - self.assertRaises(TypeError, self.field.coerce, 'obj', 'attr', 123) - self.assertRaises(TypeError, self.field.coerce, 'obj', 'attr', True) + self.assertRaises(TypeError, self.field.coerce, "obj", "attr", 123) + self.assertRaises(TypeError, self.field.coerce, "obj", "attr", True) def test_coerce_nullable_translation(self): # non-nullable - self.assertRaises(ValueError, self.field.coerce, 'obj', 'attr', None) + self.assertRaises(ValueError, self.field.coerce, "obj", "attr", None) # nullable self.field = fields.FlexibleDictField(nullable=True) - self.assertEqual({}, self.field.coerce('obj', 'attr', None)) + self.assertEqual({}, self.field.coerce("obj", "attr", None)) # NotificationLevelField borrowed from Ironic class TestNotificationLevelField(base.TestCase): - def setUp(self): super(TestNotificationLevelField, self).setUp() self.field = fields.NotificationLevelField() def test_coerce_good_value(self): - self.assertEqual(fields.NotificationLevel.WARNING, - self.field.coerce('obj', 'attr', 'warning')) + self.assertEqual( + fields.NotificationLevel.WARNING, + self.field.coerce("obj", "attr", "warning"), + ) def test_coerce_bad_value(self): - self.assertRaises(ValueError, self.field.coerce, 'obj', 'attr', - 'not_a_priority') + self.assertRaises( + ValueError, self.field.coerce, "obj", "attr", "not_a_priority" + ) # NotificationStatusField borrowed from Ironic class TestNotificationStatusField(base.TestCase): - def setUp(self): super(TestNotificationStatusField, self).setUp() self.field = fields.NotificationStatusField() def test_coerce_good_value(self): - self.assertEqual(fields.NotificationStatus.START, - self.field.coerce('obj', 'attr', 'start')) + self.assertEqual( + fields.NotificationStatus.START, self.field.coerce("obj", "attr", "start") + ) def test_coerce_bad_value(self): - self.assertRaises(ValueError, self.field.coerce, 'obj', 'attr', - 'not_a_priority') + self.assertRaises( + ValueError, self.field.coerce, "obj", "attr", "not_a_priority" + ) diff --git a/esi_leap/tests/objects/test_lease.py b/esi_leap/tests/objects/test_lease.py index 400d7c8e..59b2faf6 100644 --- a/esi_leap/tests/objects/test_lease.py +++ b/esi_leap/tests/objects/test_lease.py @@ -26,7 +26,6 @@ class TestLeaseObject(base.DBTestCase): - def setUp(self): super(TestLeaseObject, self).setUp() @@ -34,13 +33,13 @@ def setUp(self): self.test_offer = offer_obj.Offer( id=27, uuid=uuidutils.generate_uuid(), - project_id='01d4e6a72f5c408813e02f664cc8c83e', - resource_type='dummy_node', - resource_uuid='1718', + project_id="01d4e6a72f5c408813e02f664cc8c83e", + resource_type="dummy_node", + resource_uuid="1718", start_time=self.start_time, end_time=self.start_time + datetime.timedelta(days=100), status=statuses.AVAILABLE, - properties={'floor_price': 3}, + properties={"floor_price": 3}, ) self.test_parent_lease = lease_obj.Lease( uuid=uuidutils.generate_uuid(), @@ -51,53 +50,53 @@ def setUp(self): status=statuses.EXPIRED, ) self.test_lease_dict = { - 'id': 28, - 'name': 'lease', - 'uuid': uuidutils.generate_uuid(), - 'project_id': 'le55ee', - 'owner_id': '0wn3r', - 'start_time': self.start_time + datetime.timedelta(days=5), - 'end_time': self.start_time + datetime.timedelta(days=10), - 'fulfill_time': self.start_time + datetime.timedelta(days=5), - 'expire_time': self.start_time + datetime.timedelta(days=10), - 'status': statuses.CREATED, - 'properties': {}, - 'resource_type': 'dummy_node', - 'resource_uuid': '1718', - 'purpose': 'test_purpose', - 'offer_uuid': None, - 'parent_lease_uuid': None, - 'created_at': None, - 'updated_at': None + "id": 28, + "name": "lease", + "uuid": uuidutils.generate_uuid(), + "project_id": "le55ee", + "owner_id": "0wn3r", + "start_time": self.start_time + datetime.timedelta(days=5), + "end_time": self.start_time + datetime.timedelta(days=10), + "fulfill_time": self.start_time + datetime.timedelta(days=5), + "expire_time": self.start_time + datetime.timedelta(days=10), + "status": statuses.CREATED, + "properties": {}, + "resource_type": "dummy_node", + "resource_uuid": "1718", + "purpose": "test_purpose", + "offer_uuid": None, + "parent_lease_uuid": None, + "created_at": None, + "updated_at": None, } self.test_lease_offer_dict = self.test_lease_dict.copy() - self.test_lease_offer_dict['offer_uuid'] = self.test_offer.uuid + self.test_lease_offer_dict["offer_uuid"] = self.test_offer.uuid self.test_lease_parent_lease_dict = self.test_lease_dict.copy() - self.test_lease_parent_lease_dict['parent_lease_uuid'] = ( - 'parent-lease-uuid') + self.test_lease_parent_lease_dict["parent_lease_uuid"] = "parent-lease-uuid" self.test_lease_create_dict = { - 'name': 'lease_create', - 'project_id': 'le55ee', - 'owner_id': '0wn3r', - 'start_time': self.start_time + datetime.timedelta(days=5), - 'end_time': self.start_time + datetime.timedelta(days=10), - 'resource_type': 'dummy_node', - 'resource_uuid': '1718', - 'purpose': 'test_purpose', + "name": "lease_create", + "project_id": "le55ee", + "owner_id": "0wn3r", + "start_time": self.start_time + datetime.timedelta(days=5), + "end_time": self.start_time + datetime.timedelta(days=10), + "resource_type": "dummy_node", + "resource_uuid": "1718", + "purpose": "test_purpose", } self.test_lease_create_offer_dict = self.test_lease_create_dict.copy() - self.test_lease_create_offer_dict['offer_uuid'] = self.test_offer.uuid - self.test_lease_create_parent_lease_dict = ( - self.test_lease_create_dict.copy()) - self.test_lease_create_parent_lease_dict['parent_lease_uuid'] = ( - 'parent-lease-uuid') + self.test_lease_create_offer_dict["offer_uuid"] = self.test_offer.uuid + self.test_lease_create_parent_lease_dict = self.test_lease_create_dict.copy() + self.test_lease_create_parent_lease_dict["parent_lease_uuid"] = ( + "parent-lease-uuid" + ) - self.config(lock_path=tempfile.mkdtemp(), group='oslo_concurrency') + self.config(lock_path=tempfile.mkdtemp(), group="oslo_concurrency") def test_get(self): - lease_uuid = self.test_lease_dict['uuid'] - with mock.patch.object(self.db_api, 'lease_get_by_uuid', - autospec=True) as mock_lease_get_by_uuid: + lease_uuid = self.test_lease_dict["uuid"] + with mock.patch.object( + self.db_api, "lease_get_by_uuid", autospec=True + ) as mock_lease_get_by_uuid: mock_lease_get_by_uuid.return_value = self.test_lease_dict lease = lease_obj.Lease.get(lease_uuid, self.context) @@ -107,10 +106,12 @@ def test_get(self): def test_get_all(self): with mock.patch.object( - self.db_api, 'lease_get_all', autospec=True + self.db_api, "lease_get_all", autospec=True ) as mock_lease_get_all: - mock_lease_get_all.return_value = [self.test_lease_dict, - self.test_lease_offer_dict] + mock_lease_get_all.return_value = [ + self.test_lease_dict, + self.test_lease_offer_dict, + ] leases = lease_obj.Lease.get_all({}, self.context) @@ -119,8 +120,8 @@ def test_get_all(self): self.assertIsInstance(leases[0], lease_obj.Lease) self.assertEqual(self.context, leases[0]._context) - @mock.patch('esi_leap.objects.lease.Lease.verify_time_range') - @mock.patch('esi_leap.db.sqlalchemy.api.lease_create') + @mock.patch("esi_leap.objects.lease.Lease.verify_time_range") + @mock.patch("esi_leap.db.sqlalchemy.api.lease_create") def test_create(self, mock_lc, mock_vtr): lease = lease_obj.Lease(self.context, **self.test_lease_create_dict) mock_lc.return_value = self.test_lease_dict @@ -129,23 +130,28 @@ def test_create(self, mock_lc, mock_vtr): mock_lc.assert_called_once_with(self.test_lease_create_dict) mock_vtr.assert_called_once_with( - lease.start_time, lease.end_time, - None, None, - lease.resource_type, lease.resource_uuid) + lease.start_time, + lease.end_time, + None, + None, + lease.resource_type, + lease.resource_uuid, + ) def test_create_conflict(self): - lease = lease_obj.Lease(self.context, - **self.test_lease_create_offer_dict) - lease2 = lease_obj.Lease(self.context, - **self.test_lease_create_offer_dict) + lease = lease_obj.Lease(self.context, **self.test_lease_create_offer_dict) + lease2 = lease_obj.Lease(self.context, **self.test_lease_create_offer_dict) lease2.id = 28 - with mock.patch.object(self.db_api, 'lease_create', - autospec=True) as mock_lease_create: - with mock.patch.object(lease_obj.Lease, 'verify_time_range', - autospec=True) as mock_vtr: + with mock.patch.object( + self.db_api, "lease_create", autospec=True + ) as mock_lease_create: + with mock.patch.object( + lease_obj.Lease, "verify_time_range", autospec=True + ) as mock_vtr: + def update_mock(context): - mock_vtr.side_effect = Exception('bad') + mock_vtr.side_effect = Exception("bad") mock_lease_create.side_effect = update_mock @@ -161,73 +167,65 @@ def update_mock(context): assert mock_vtr.call_count == 2 mock_lease_create.assert_called_once() - @mock.patch('esi_leap.objects.lease.Lease.save') - @mock.patch('esi_leap.objects.lease.Lease.verify_time_range') + @mock.patch("esi_leap.objects.lease.Lease.save") + @mock.patch("esi_leap.objects.lease.Lease.verify_time_range") def test_update(self, mock_vtr, mock_save): lease = lease_obj.Lease(self.context, **self.test_lease_dict) end_time = lease.end_time new_end_time = end_time + datetime.timedelta(days=10) - updates = { - 'end_time': new_end_time - } + updates = {"end_time": new_end_time} lease.update(updates) mock_vtr.assert_called_once_with( - end_time, new_end_time, - lease.offer_uuid, lease.parent_lease_uuid, - lease.resource_type, lease.resource_uuid) + end_time, + new_end_time, + lease.offer_uuid, + lease.parent_lease_uuid, + lease.resource_type, + lease.resource_uuid, + ) mock_save.assert_called_once - @mock.patch('esi_leap.objects.lease.Lease.save') - @mock.patch('esi_leap.objects.lease.Lease.verify_time_range') + @mock.patch("esi_leap.objects.lease.Lease.save") + @mock.patch("esi_leap.objects.lease.Lease.verify_time_range") def test_update_no_end_time(self, mock_vtr, mock_save): lease = lease_obj.Lease(self.context, **self.test_lease_dict) - updates = { - 'name': 'foo' - } + updates = {"name": "foo"} lease.update(updates) mock_vtr.assert_not_called mock_save.assert_not_called - @mock.patch('esi_leap.objects.lease.Lease.save') - @mock.patch('esi_leap.objects.lease.Lease.verify_time_range') + @mock.patch("esi_leap.objects.lease.Lease.save") + @mock.patch("esi_leap.objects.lease.Lease.verify_time_range") def test_update_invalid_end_time(self, mock_vtr, mock_save): lease = lease_obj.Lease(self.context, **self.test_lease_dict) end_time = lease.end_time new_end_time = end_time - datetime.timedelta(days=10) - updates = { - 'end_time': new_end_time - } + updates = {"end_time": new_end_time} - self.assertRaises(exception.InvalidTimeRange, - lease.update, updates) + self.assertRaises(exception.InvalidTimeRange, lease.update, updates) mock_vtr.assert_not_called mock_save.assert_not_called def test_update_conflict(self): - lease = lease_obj.Lease(self.context, - **self.test_lease_dict) - lease2 = lease_obj.Lease(self.context, - **self.test_lease_dict) + lease = lease_obj.Lease(self.context, **self.test_lease_dict) + lease2 = lease_obj.Lease(self.context, **self.test_lease_dict) lease2.id = 28 - lease_updates = { - 'end_time': lease.end_time + datetime.timedelta(days=10) - } + lease_updates = {"end_time": lease.end_time + datetime.timedelta(days=10)} + + with mock.patch.object(lease_obj.Lease, "save", autospec=True) as mock_save: + with mock.patch.object( + lease_obj.Lease, "verify_time_range", autospec=True + ) as mock_vtr: - with mock.patch.object(lease_obj.Lease, 'save', - autospec=True) as mock_save: - with mock.patch.object(lease_obj.Lease, 'verify_time_range', - autospec=True) as mock_vtr: def update_mock(updates, context): - mock_vtr.side_effect = Exception('bad') + mock_vtr.side_effect = Exception("bad") mock_save.side_effect = update_mock - thread = threading.Thread( - target=lease.update, args=[lease_updates]) - thread2 = threading.Thread( - target=lease2.update, args=[lease_updates]) + thread = threading.Thread(target=lease.update, args=[lease_updates]) + thread2 = threading.Thread(target=lease2.update, args=[lease_updates]) thread.start() thread2.start() @@ -238,87 +236,124 @@ def update_mock(updates, context): assert mock_vtr.call_count == 2 mock_save.assert_called_once() - @mock.patch('esi_leap.objects.lease.Lease.resource_object') - @mock.patch('esi_leap.resource_objects.test_node.TestNode.set_lease') - @mock.patch('esi_leap.objects.lease.Lease.save') - @mock.patch('esi_leap.common.notification_utils' - '._emit_notification') - def test_fulfill(self, mock_notify, - mock_save, mock_set_lease, mock_ro): + @mock.patch("esi_leap.objects.lease.Lease.resource_object") + @mock.patch("esi_leap.resource_objects.test_node.TestNode.set_lease") + @mock.patch("esi_leap.objects.lease.Lease.save") + @mock.patch("esi_leap.common.notification_utils" "._emit_notification") + def test_fulfill(self, mock_notify, mock_save, mock_set_lease, mock_ro): lease = lease_obj.Lease(self.context, **self.test_lease_dict) - test_node = TestNode('test-node', '12345') + test_node = TestNode("test-node", "12345") mock_ro.return_value = test_node lease.fulfill() - mock_notify.assert_has_calls([mock.call(mock.ANY, mock.ANY, 'fulfill', - obj_fields.NotificationLevel.INFO, - obj_fields.NotificationStatus.START, - mock.ANY, node=mock.ANY), - mock.call(mock.ANY, mock.ANY, 'fulfill', - obj_fields.NotificationLevel.INFO, - obj_fields.NotificationStatus.END, - mock.ANY, node=mock.ANY)]) + mock_notify.assert_has_calls( + [ + mock.call( + mock.ANY, + mock.ANY, + "fulfill", + obj_fields.NotificationLevel.INFO, + obj_fields.NotificationStatus.START, + mock.ANY, + node=mock.ANY, + ), + mock.call( + mock.ANY, + mock.ANY, + "fulfill", + obj_fields.NotificationLevel.INFO, + obj_fields.NotificationStatus.END, + mock.ANY, + node=mock.ANY, + ), + ] + ) mock_ro.assert_called_once() mock_set_lease.assert_called_once() mock_save.assert_called_once() self.assertEqual(lease.status, statuses.ACTIVE) - @mock.patch('esi_leap.objects.lease.Lease.resource_object') - @mock.patch('esi_leap.resource_objects.test_node.TestNode.set_lease') - @mock.patch('esi_leap.objects.lease.Lease.save') - @mock.patch('esi_leap.common.notification_utils' - '._emit_notification') - def test_fulfill_error(self, mock_notify, mock_save, - mock_set_lease, mock_ro): + @mock.patch("esi_leap.objects.lease.Lease.resource_object") + @mock.patch("esi_leap.resource_objects.test_node.TestNode.set_lease") + @mock.patch("esi_leap.objects.lease.Lease.save") + @mock.patch("esi_leap.common.notification_utils" "._emit_notification") + def test_fulfill_error(self, mock_notify, mock_save, mock_set_lease, mock_ro): lease = lease_obj.Lease(self.context, **self.test_lease_dict) - test_node = TestNode('test-node', '12345') + test_node = TestNode("test-node", "12345") mock_ro.return_value = test_node - mock_set_lease.side_effect = Exception('bad') + mock_set_lease.side_effect = Exception("bad") lease.fulfill() - mock_notify.assert_has_calls([mock.call(mock.ANY, mock.ANY, 'fulfill', - obj_fields.NotificationLevel.INFO, - obj_fields.NotificationStatus.START, - mock.ANY, node=mock.ANY), - mock.call(mock.ANY, mock.ANY, 'fulfill', - obj_fields.NotificationLevel.ERROR, - obj_fields.NotificationStatus.ERROR, - mock.ANY, node=mock.ANY)]) + mock_notify.assert_has_calls( + [ + mock.call( + mock.ANY, + mock.ANY, + "fulfill", + obj_fields.NotificationLevel.INFO, + obj_fields.NotificationStatus.START, + mock.ANY, + node=mock.ANY, + ), + mock.call( + mock.ANY, + mock.ANY, + "fulfill", + obj_fields.NotificationLevel.ERROR, + obj_fields.NotificationStatus.ERROR, + mock.ANY, + node=mock.ANY, + ), + ] + ) mock_ro.assert_called_once() mock_set_lease.assert_called_once() mock_save.assert_called_once() self.assertEqual(lease.status, statuses.WAIT_FULFILL) - @mock.patch('esi_leap.resource_objects.test_node.TestNode.set_lease') - @mock.patch('esi_leap.objects.lease.Lease.get') - @mock.patch('esi_leap.objects.lease.Lease.resource_object') - @mock.patch('esi_leap.resource_objects.test_node.TestNode.get_lease_uuid') - @mock.patch('esi_leap.resource_objects.test_node.TestNode.remove_lease') - @mock.patch('esi_leap.objects.lease.Lease.save') - @mock.patch('esi_leap.common.notification_utils' - '._emit_notification') - def test_cancel(self, mock_notify, mock_save, - mock_rl, mock_glu, mock_ro, - mock_lg, mock_sl): + @mock.patch("esi_leap.resource_objects.test_node.TestNode.set_lease") + @mock.patch("esi_leap.objects.lease.Lease.get") + @mock.patch("esi_leap.objects.lease.Lease.resource_object") + @mock.patch("esi_leap.resource_objects.test_node.TestNode.get_lease_uuid") + @mock.patch("esi_leap.resource_objects.test_node.TestNode.remove_lease") + @mock.patch("esi_leap.objects.lease.Lease.save") + @mock.patch("esi_leap.common.notification_utils" "._emit_notification") + def test_cancel( + self, mock_notify, mock_save, mock_rl, mock_glu, mock_ro, mock_lg, mock_sl + ): lease = lease_obj.Lease(self.context, **self.test_lease_dict) - test_node = TestNode('test-node', '12345') + test_node = TestNode("test-node", "12345") mock_ro.return_value = test_node mock_glu.return_value = lease.uuid lease.cancel() - mock_notify.assert_has_calls([mock.call(mock.ANY, mock.ANY, 'delete', - obj_fields.NotificationLevel.INFO, - obj_fields.NotificationStatus.START, - mock.ANY, node=mock.ANY), - mock.call(mock.ANY, mock.ANY, 'delete', - obj_fields.NotificationLevel.INFO, - obj_fields.NotificationStatus.END, - mock.ANY, node=mock.ANY)]) + mock_notify.assert_has_calls( + [ + mock.call( + mock.ANY, + mock.ANY, + "delete", + obj_fields.NotificationLevel.INFO, + obj_fields.NotificationStatus.START, + mock.ANY, + node=mock.ANY, + ), + mock.call( + mock.ANY, + mock.ANY, + "delete", + obj_fields.NotificationLevel.INFO, + obj_fields.NotificationStatus.END, + mock.ANY, + node=mock.ANY, + ), + ] + ) mock_sl.assert_not_called() mock_lg.assert_not_called() mock_ro.assert_called_once() @@ -327,34 +362,47 @@ def test_cancel(self, mock_notify, mock_save, mock_save.assert_called_once() self.assertEqual(lease.status, statuses.DELETED) - @mock.patch('esi_leap.resource_objects.test_node.TestNode.set_lease') - @mock.patch('esi_leap.objects.lease.Lease.get') - @mock.patch('esi_leap.objects.lease.Lease.resource_object') - @mock.patch('esi_leap.resource_objects.test_node.TestNode.get_lease_uuid') - @mock.patch('esi_leap.resource_objects.test_node.TestNode.remove_lease') - @mock.patch('esi_leap.objects.lease.Lease.save') - @mock.patch('esi_leap.common.notification_utils' - '._emit_notification') - def test_cancel_error(self, mock_notify, mock_save, - mock_rl, mock_glu, - mock_ro, mock_lg, mock_sl): + @mock.patch("esi_leap.resource_objects.test_node.TestNode.set_lease") + @mock.patch("esi_leap.objects.lease.Lease.get") + @mock.patch("esi_leap.objects.lease.Lease.resource_object") + @mock.patch("esi_leap.resource_objects.test_node.TestNode.get_lease_uuid") + @mock.patch("esi_leap.resource_objects.test_node.TestNode.remove_lease") + @mock.patch("esi_leap.objects.lease.Lease.save") + @mock.patch("esi_leap.common.notification_utils" "._emit_notification") + def test_cancel_error( + self, mock_notify, mock_save, mock_rl, mock_glu, mock_ro, mock_lg, mock_sl + ): lease = lease_obj.Lease(self.context, **self.test_lease_dict) - test_node = TestNode('test-node', '12345') + test_node = TestNode("test-node", "12345") mock_ro.return_value = test_node mock_glu.return_value = lease.uuid - mock_rl.side_effect = Exception('bad') + mock_rl.side_effect = Exception("bad") lease.cancel() - mock_notify.assert_has_calls([mock.call(mock.ANY, mock.ANY, 'delete', - obj_fields.NotificationLevel.INFO, - obj_fields.NotificationStatus.START, - mock.ANY, node=mock.ANY), - mock.call(mock.ANY, mock.ANY, 'delete', - obj_fields.NotificationLevel.ERROR, - obj_fields.NotificationStatus.ERROR, - mock.ANY, node=mock.ANY)]) + mock_notify.assert_has_calls( + [ + mock.call( + mock.ANY, + mock.ANY, + "delete", + obj_fields.NotificationLevel.INFO, + obj_fields.NotificationStatus.START, + mock.ANY, + node=mock.ANY, + ), + mock.call( + mock.ANY, + mock.ANY, + "delete", + obj_fields.NotificationLevel.ERROR, + obj_fields.NotificationStatus.ERROR, + mock.ANY, + node=mock.ANY, + ), + ] + ) mock_sl.assert_not_called() mock_lg.assert_not_called() mock_ro.assert_called_once() @@ -363,34 +411,46 @@ def test_cancel_error(self, mock_notify, mock_save, mock_save.assert_called_once() self.assertEqual(lease.status, statuses.WAIT_CANCEL) - @mock.patch('esi_leap.resource_objects.test_node.TestNode.set_lease') - @mock.patch('esi_leap.objects.lease.Lease.get') - @mock.patch('esi_leap.objects.lease.Lease.resource_object') - @mock.patch('esi_leap.resource_objects.test_node.TestNode.get_lease_uuid') - @mock.patch('esi_leap.resource_objects.test_node.TestNode.remove_lease') - @mock.patch('esi_leap.objects.lease.Lease.save') - @mock.patch('esi_leap.common.notification_utils' - '._emit_notification') - def test_cancel_with_parent(self, mock_notify, mock_save, - mock_rl, mock_glu, - mock_ro, mock_lg, mock_sl): - lease = lease_obj.Lease(self.context, - **self.test_lease_parent_lease_dict) - test_node = TestNode('test-node', '12345') + @mock.patch("esi_leap.resource_objects.test_node.TestNode.set_lease") + @mock.patch("esi_leap.objects.lease.Lease.get") + @mock.patch("esi_leap.objects.lease.Lease.resource_object") + @mock.patch("esi_leap.resource_objects.test_node.TestNode.get_lease_uuid") + @mock.patch("esi_leap.resource_objects.test_node.TestNode.remove_lease") + @mock.patch("esi_leap.objects.lease.Lease.save") + @mock.patch("esi_leap.common.notification_utils" "._emit_notification") + def test_cancel_with_parent( + self, mock_notify, mock_save, mock_rl, mock_glu, mock_ro, mock_lg, mock_sl + ): + lease = lease_obj.Lease(self.context, **self.test_lease_parent_lease_dict) + test_node = TestNode("test-node", "12345") mock_ro.return_value = test_node mock_glu.return_value = lease.uuid lease.cancel() - mock_notify.assert_has_calls([mock.call(mock.ANY, mock.ANY, 'delete', - obj_fields.NotificationLevel.INFO, - obj_fields.NotificationStatus.START, - mock.ANY, node=mock.ANY), - mock.call(mock.ANY, mock.ANY, 'delete', - obj_fields.NotificationLevel.INFO, - obj_fields.NotificationStatus.END, - mock.ANY, node=mock.ANY)]) + mock_notify.assert_has_calls( + [ + mock.call( + mock.ANY, + mock.ANY, + "delete", + obj_fields.NotificationLevel.INFO, + obj_fields.NotificationStatus.START, + mock.ANY, + node=mock.ANY, + ), + mock.call( + mock.ANY, + mock.ANY, + "delete", + obj_fields.NotificationLevel.INFO, + obj_fields.NotificationStatus.END, + mock.ANY, + node=mock.ANY, + ), + ] + ) mock_sl.assert_called_once() mock_lg.assert_called_once() mock_ro.assert_called_once() @@ -399,63 +459,88 @@ def test_cancel_with_parent(self, mock_notify, mock_save, mock_save.assert_called_once() self.assertEqual(lease.status, statuses.DELETED) - @mock.patch('esi_leap.objects.lease.Lease.resource_object') - @mock.patch('esi_leap.resource_objects.test_node.TestNode.get_lease_uuid') - @mock.patch('esi_leap.resource_objects.test_node.TestNode.remove_lease') - @mock.patch('esi_leap.objects.lease.Lease.save') - @mock.patch('esi_leap.common.notification_utils' - '._emit_notification') - def test_cancel_no_expire(self, mock_notify, mock_save, - mock_rl, mock_glu, - mock_ro): + @mock.patch("esi_leap.objects.lease.Lease.resource_object") + @mock.patch("esi_leap.resource_objects.test_node.TestNode.get_lease_uuid") + @mock.patch("esi_leap.resource_objects.test_node.TestNode.remove_lease") + @mock.patch("esi_leap.objects.lease.Lease.save") + @mock.patch("esi_leap.common.notification_utils" "._emit_notification") + def test_cancel_no_expire(self, mock_notify, mock_save, mock_rl, mock_glu, mock_ro): lease = lease_obj.Lease(self.context, **self.test_lease_dict) - test_node = TestNode('test-node', '12345') + test_node = TestNode("test-node", "12345") mock_ro.return_value = test_node - mock_glu.return_value = 'some-other-lease-uuid' + mock_glu.return_value = "some-other-lease-uuid" lease.cancel() - mock_notify.assert_has_calls([mock.call(mock.ANY, mock.ANY, 'delete', - obj_fields.NotificationLevel.INFO, - obj_fields.NotificationStatus.START, - mock.ANY, node=mock.ANY), - mock.call(mock.ANY, mock.ANY, 'delete', - obj_fields.NotificationLevel.INFO, - obj_fields.NotificationStatus.END, - mock.ANY, node=mock.ANY)]) + mock_notify.assert_has_calls( + [ + mock.call( + mock.ANY, + mock.ANY, + "delete", + obj_fields.NotificationLevel.INFO, + obj_fields.NotificationStatus.START, + mock.ANY, + node=mock.ANY, + ), + mock.call( + mock.ANY, + mock.ANY, + "delete", + obj_fields.NotificationLevel.INFO, + obj_fields.NotificationStatus.END, + mock.ANY, + node=mock.ANY, + ), + ] + ) mock_ro.assert_called_once() mock_glu.assert_called_once() mock_rl.assert_not_called() mock_save.assert_called_once() self.assertEqual(lease.status, statuses.DELETED) - @mock.patch('esi_leap.resource_objects.test_node.TestNode.set_lease') - @mock.patch('esi_leap.objects.lease.Lease.get') - @mock.patch('esi_leap.objects.lease.Lease.resource_object') - @mock.patch('esi_leap.resource_objects.test_node.TestNode.get_lease_uuid') - @mock.patch('esi_leap.resource_objects.test_node.TestNode.remove_lease') - @mock.patch('esi_leap.objects.lease.Lease.save') - @mock.patch('esi_leap.common.notification_utils' - '._emit_notification') - def test_expire(self, mock_notify, mock_save, mock_rl, mock_glu, mock_ro, - mock_lg, mock_sl): + @mock.patch("esi_leap.resource_objects.test_node.TestNode.set_lease") + @mock.patch("esi_leap.objects.lease.Lease.get") + @mock.patch("esi_leap.objects.lease.Lease.resource_object") + @mock.patch("esi_leap.resource_objects.test_node.TestNode.get_lease_uuid") + @mock.patch("esi_leap.resource_objects.test_node.TestNode.remove_lease") + @mock.patch("esi_leap.objects.lease.Lease.save") + @mock.patch("esi_leap.common.notification_utils" "._emit_notification") + def test_expire( + self, mock_notify, mock_save, mock_rl, mock_glu, mock_ro, mock_lg, mock_sl + ): lease = lease_obj.Lease(self.context, **self.test_lease_dict) - test_node = TestNode('test-node', '12345') + test_node = TestNode("test-node", "12345") mock_ro.return_value = test_node mock_glu.return_value = lease.uuid lease.expire() - mock_notify.assert_has_calls([mock.call(mock.ANY, mock.ANY, 'delete', - obj_fields.NotificationLevel.INFO, - obj_fields.NotificationStatus.START, - mock.ANY, node=mock.ANY), - mock.call(mock.ANY, mock.ANY, 'delete', - obj_fields.NotificationLevel.INFO, - obj_fields.NotificationStatus.END, - mock.ANY, node=mock.ANY)]) + mock_notify.assert_has_calls( + [ + mock.call( + mock.ANY, + mock.ANY, + "delete", + obj_fields.NotificationLevel.INFO, + obj_fields.NotificationStatus.START, + mock.ANY, + node=mock.ANY, + ), + mock.call( + mock.ANY, + mock.ANY, + "delete", + obj_fields.NotificationLevel.INFO, + obj_fields.NotificationStatus.END, + mock.ANY, + node=mock.ANY, + ), + ] + ) mock_sl.assert_not_called() mock_lg.assert_not_called() mock_ro.assert_called_once() @@ -464,33 +549,47 @@ def test_expire(self, mock_notify, mock_save, mock_rl, mock_glu, mock_ro, mock_save.assert_called_once() self.assertEqual(lease.status, statuses.EXPIRED) - @mock.patch('esi_leap.resource_objects.test_node.TestNode.set_lease') - @mock.patch('esi_leap.objects.lease.Lease.get') - @mock.patch('esi_leap.objects.lease.Lease.resource_object') - @mock.patch('esi_leap.resource_objects.test_node.TestNode.get_lease_uuid') - @mock.patch('esi_leap.resource_objects.test_node.TestNode.remove_lease') - @mock.patch('esi_leap.objects.lease.Lease.save') - @mock.patch('esi_leap.common.notification_utils' - '._emit_notification') - def test_expire_error(self, mock_notify, mock_save, mock_rl, mock_glu, - mock_ro, mock_lg, mock_sl): + @mock.patch("esi_leap.resource_objects.test_node.TestNode.set_lease") + @mock.patch("esi_leap.objects.lease.Lease.get") + @mock.patch("esi_leap.objects.lease.Lease.resource_object") + @mock.patch("esi_leap.resource_objects.test_node.TestNode.get_lease_uuid") + @mock.patch("esi_leap.resource_objects.test_node.TestNode.remove_lease") + @mock.patch("esi_leap.objects.lease.Lease.save") + @mock.patch("esi_leap.common.notification_utils" "._emit_notification") + def test_expire_error( + self, mock_notify, mock_save, mock_rl, mock_glu, mock_ro, mock_lg, mock_sl + ): lease = lease_obj.Lease(self.context, **self.test_lease_dict) - test_node = TestNode('test-node', '12345') + test_node = TestNode("test-node", "12345") mock_ro.return_value = test_node mock_glu.return_value = lease.uuid - mock_rl.side_effect = Exception('bad') + mock_rl.side_effect = Exception("bad") lease.expire() - mock_notify.assert_has_calls([mock.call(mock.ANY, mock.ANY, 'delete', - obj_fields.NotificationLevel.INFO, - obj_fields.NotificationStatus.START, - mock.ANY, node=mock.ANY), - mock.call(mock.ANY, mock.ANY, 'delete', - obj_fields.NotificationLevel.ERROR, - obj_fields.NotificationStatus.ERROR, - mock.ANY, node=mock.ANY)]) + mock_notify.assert_has_calls( + [ + mock.call( + mock.ANY, + mock.ANY, + "delete", + obj_fields.NotificationLevel.INFO, + obj_fields.NotificationStatus.START, + mock.ANY, + node=mock.ANY, + ), + mock.call( + mock.ANY, + mock.ANY, + "delete", + obj_fields.NotificationLevel.ERROR, + obj_fields.NotificationStatus.ERROR, + mock.ANY, + node=mock.ANY, + ), + ] + ) mock_sl.assert_not_called() mock_lg.assert_not_called() mock_ro.assert_called_once() @@ -499,33 +598,46 @@ def test_expire_error(self, mock_notify, mock_save, mock_rl, mock_glu, mock_save.assert_called_once() self.assertEqual(lease.status, statuses.WAIT_EXPIRE) - @mock.patch('esi_leap.resource_objects.test_node.TestNode.set_lease') - @mock.patch('esi_leap.objects.lease.Lease.get') - @mock.patch('esi_leap.objects.lease.Lease.resource_object') - @mock.patch('esi_leap.resource_objects.test_node.TestNode.get_lease_uuid') - @mock.patch('esi_leap.resource_objects.test_node.TestNode.remove_lease') - @mock.patch('esi_leap.objects.lease.Lease.save') - @mock.patch('esi_leap.common.notification_utils' - '._emit_notification') - def test_expire_with_parent(self, mock_notify, mock_save, mock_rl, - mock_glu, mock_ro, mock_lg, mock_sl): - lease = lease_obj.Lease(self.context, - **self.test_lease_parent_lease_dict) - test_node = TestNode('test-node', '12345') + @mock.patch("esi_leap.resource_objects.test_node.TestNode.set_lease") + @mock.patch("esi_leap.objects.lease.Lease.get") + @mock.patch("esi_leap.objects.lease.Lease.resource_object") + @mock.patch("esi_leap.resource_objects.test_node.TestNode.get_lease_uuid") + @mock.patch("esi_leap.resource_objects.test_node.TestNode.remove_lease") + @mock.patch("esi_leap.objects.lease.Lease.save") + @mock.patch("esi_leap.common.notification_utils" "._emit_notification") + def test_expire_with_parent( + self, mock_notify, mock_save, mock_rl, mock_glu, mock_ro, mock_lg, mock_sl + ): + lease = lease_obj.Lease(self.context, **self.test_lease_parent_lease_dict) + test_node = TestNode("test-node", "12345") mock_ro.return_value = test_node mock_glu.return_value = lease.uuid lease.expire() - mock_notify.assert_has_calls([mock.call(mock.ANY, mock.ANY, 'delete', - obj_fields.NotificationLevel.INFO, - obj_fields.NotificationStatus.START, - mock.ANY, node=mock.ANY), - mock.call(mock.ANY, mock.ANY, 'delete', - obj_fields.NotificationLevel.INFO, - obj_fields.NotificationStatus.END, - mock.ANY, node=mock.ANY)]) + mock_notify.assert_has_calls( + [ + mock.call( + mock.ANY, + mock.ANY, + "delete", + obj_fields.NotificationLevel.INFO, + obj_fields.NotificationStatus.START, + mock.ANY, + node=mock.ANY, + ), + mock.call( + mock.ANY, + mock.ANY, + "delete", + obj_fields.NotificationLevel.INFO, + obj_fields.NotificationStatus.END, + mock.ANY, + node=mock.ANY, + ), + ] + ) mock_sl.assert_called_once() mock_lg.assert_called_once() mock_ro.assert_called_once() @@ -534,30 +646,42 @@ def test_expire_with_parent(self, mock_notify, mock_save, mock_rl, mock_save.assert_called_once() self.assertEqual(lease.status, statuses.EXPIRED) - @mock.patch('esi_leap.objects.lease.Lease.resource_object') - @mock.patch('esi_leap.resource_objects.test_node.TestNode.get_lease_uuid') - @mock.patch('esi_leap.resource_objects.test_node.TestNode.remove_lease') - @mock.patch('esi_leap.objects.lease.Lease.save') - @mock.patch('esi_leap.common.notification_utils' - '._emit_notification') - def test_expire_no_expire(self, mock_notify, mock_save, mock_rl, - mock_glu, mock_ro): + @mock.patch("esi_leap.objects.lease.Lease.resource_object") + @mock.patch("esi_leap.resource_objects.test_node.TestNode.get_lease_uuid") + @mock.patch("esi_leap.resource_objects.test_node.TestNode.remove_lease") + @mock.patch("esi_leap.objects.lease.Lease.save") + @mock.patch("esi_leap.common.notification_utils" "._emit_notification") + def test_expire_no_expire(self, mock_notify, mock_save, mock_rl, mock_glu, mock_ro): lease = lease_obj.Lease(self.context, **self.test_lease_dict) - test_node = TestNode('test-node', '12345') + test_node = TestNode("test-node", "12345") mock_ro.return_value = test_node - mock_glu.return_value = 'some-other-lease-uuid' + mock_glu.return_value = "some-other-lease-uuid" lease.expire() - mock_notify.assert_has_calls([mock.call(mock.ANY, mock.ANY, 'delete', - obj_fields.NotificationLevel.INFO, - obj_fields.NotificationStatus.START, - mock.ANY, node=mock.ANY), - mock.call(mock.ANY, mock.ANY, 'delete', - obj_fields.NotificationLevel.INFO, - obj_fields.NotificationStatus.END, - mock.ANY, node=mock.ANY)]) + mock_notify.assert_has_calls( + [ + mock.call( + mock.ANY, + mock.ANY, + "delete", + obj_fields.NotificationLevel.INFO, + obj_fields.NotificationStatus.START, + mock.ANY, + node=mock.ANY, + ), + mock.call( + mock.ANY, + mock.ANY, + "delete", + obj_fields.NotificationLevel.INFO, + obj_fields.NotificationStatus.END, + mock.ANY, + node=mock.ANY, + ), + ] + ) mock_ro.assert_called_once() mock_glu.assert_called_once() mock_rl.assert_not_called() @@ -566,8 +690,9 @@ def test_expire_no_expire(self, mock_notify, mock_save, mock_rl, def test_destroy(self): lease = lease_obj.Lease(self.context, **self.test_lease_dict) - with mock.patch.object(self.db_api, 'lease_destroy', - autospec=True) as mock_lease_cancel: + with mock.patch.object( + self.db_api, "lease_destroy", autospec=True + ) as mock_lease_cancel: lease.destroy() mock_lease_cancel.assert_called_once_with(lease.uuid) @@ -575,143 +700,164 @@ def test_save(self): lease = lease_obj.Lease(self.context, **self.test_lease_dict) new_status = statuses.ACTIVE updated_at = datetime.datetime(2006, 12, 11, 0, 0) - with mock.patch.object(self.db_api, 'lease_update', - autospec=True) as mock_lease_update: + with mock.patch.object( + self.db_api, "lease_update", autospec=True + ) as mock_lease_update: updated_lease = self.test_lease_dict.copy() - updated_lease['status'] = new_status - updated_lease['updated_at'] = updated_at + updated_lease["status"] = new_status + updated_lease["updated_at"] = updated_at mock_lease_update.return_value = updated_lease lease.status = new_status lease.save(self.context) updated_values = self.test_lease_dict.copy() - updated_values['status'] = new_status - mock_lease_update.assert_called_once_with(lease.uuid, - updated_values) + updated_values["status"] = new_status + mock_lease_update.assert_called_once_with(lease.uuid, updated_values) self.assertEqual(self.context, lease._context) self.assertEqual(updated_at, lease.updated_at) - @mock.patch('esi_leap.objects.lease.get_resource_object') + @mock.patch("esi_leap.objects.lease.get_resource_object") def test_resource_object(self, mock_gro): lease = lease_obj.Lease(self.context, **self.test_lease_dict) lease.resource_object() - mock_gro.assert_called_once_with(lease.resource_type, - lease.resource_uuid) + mock_gro.assert_called_once_with(lease.resource_type, lease.resource_uuid) - @mock.patch('esi_leap.db.sqlalchemy.api.resource_verify_availability') - @mock.patch('esi_leap.db.sqlalchemy.api.offer_verify_availability') - @mock.patch('esi_leap.objects.offer.Offer.get') + @mock.patch("esi_leap.db.sqlalchemy.api.resource_verify_availability") + @mock.patch("esi_leap.db.sqlalchemy.api.offer_verify_availability") + @mock.patch("esi_leap.objects.offer.Offer.get") def test_verify_time_range(self, mock_og, mock_ova, mock_rva): lease = lease_obj.Lease(self.context, **self.test_lease_create_dict) - lease.verify_time_range(lease.start_time, lease.end_time, - None, None, - lease.resource_type, lease.resource_uuid) + lease.verify_time_range( + lease.start_time, + lease.end_time, + None, + None, + lease.resource_type, + lease.resource_uuid, + ) mock_og.assert_not_called mock_ova.assert_not_called - mock_rva.assert_called_once_with(lease.resource_type, - lease.resource_uuid, - lease.start_time, - lease.end_time) - - @mock.patch('esi_leap.db.sqlalchemy.api.resource_verify_availability') - @mock.patch('esi_leap.db.sqlalchemy.api.offer_verify_availability') - @mock.patch('esi_leap.objects.offer.Offer.get') + mock_rva.assert_called_once_with( + lease.resource_type, lease.resource_uuid, lease.start_time, lease.end_time + ) + + @mock.patch("esi_leap.db.sqlalchemy.api.resource_verify_availability") + @mock.patch("esi_leap.db.sqlalchemy.api.offer_verify_availability") + @mock.patch("esi_leap.objects.offer.Offer.get") def test_verify_time_range_with_offer(self, mock_og, mock_ova, mock_rva): - lease = lease_obj.Lease(self.context, - **self.test_lease_create_offer_dict) + lease = lease_obj.Lease(self.context, **self.test_lease_create_offer_dict) mock_og.return_value = self.test_offer - lease.verify_time_range(lease.start_time, lease.end_time, - lease.offer_uuid, None, - lease.resource_type, lease.resource_uuid) + lease.verify_time_range( + lease.start_time, + lease.end_time, + lease.offer_uuid, + None, + lease.resource_type, + lease.resource_uuid, + ) mock_og.assert_called_once_with(lease.offer_uuid) - mock_ova.assert_called_once_with(self.test_offer, - lease.start_time, - lease.end_time) + mock_ova.assert_called_once_with( + self.test_offer, lease.start_time, lease.end_time + ) mock_rva.assert_not_called - @mock.patch('esi_leap.db.sqlalchemy.api.lease_verify_child_availability') - @mock.patch('esi_leap.objects.lease.Lease.get') + @mock.patch("esi_leap.db.sqlalchemy.api.lease_verify_child_availability") + @mock.patch("esi_leap.objects.lease.Lease.get") def test_verify_time_range_with_parent_lease(self, mock_lg, mock_lvca): - lease = lease_obj.Lease(self.context, - **self.test_lease_create_parent_lease_dict) + lease = lease_obj.Lease( + self.context, **self.test_lease_create_parent_lease_dict + ) mock_lg.return_value = self.test_parent_lease - lease.verify_time_range(lease.start_time, lease.end_time, - None, lease.parent_lease_uuid, - lease.resource_type, lease.resource_uuid) - - mock_lg.assert_called_once_with('parent-lease-uuid') - mock_lvca.assert_called_once_with(self.test_parent_lease, - lease.start_time, - lease.end_time) - - @mock.patch('esi_leap.db.sqlalchemy.api.lease_verify_child_availability') - @mock.patch('esi_leap.objects.lease.Lease.get') - def test_verify_time_range_with_parent_lease_expired( - self, mock_lg, mock_lvca): - lease = lease_obj.Lease(self.context, - **self.test_lease_create_parent_lease_dict) + lease.verify_time_range( + lease.start_time, + lease.end_time, + None, + lease.parent_lease_uuid, + lease.resource_type, + lease.resource_uuid, + ) + + mock_lg.assert_called_once_with("parent-lease-uuid") + mock_lvca.assert_called_once_with( + self.test_parent_lease, lease.start_time, lease.end_time + ) + + @mock.patch("esi_leap.db.sqlalchemy.api.lease_verify_child_availability") + @mock.patch("esi_leap.objects.lease.Lease.get") + def test_verify_time_range_with_parent_lease_expired(self, mock_lg, mock_lvca): + lease = lease_obj.Lease( + self.context, **self.test_lease_create_parent_lease_dict + ) mock_lg.return_value = self.test_parent_lease_expired - self.assertRaises(exception.LeaseNotActive, - lease.verify_time_range, - lease.start_time, lease.end_time, - None, lease.parent_lease_uuid, - lease.resource_type, lease.resource_uuid) + self.assertRaises( + exception.LeaseNotActive, + lease.verify_time_range, + lease.start_time, + lease.end_time, + None, + lease.parent_lease_uuid, + lease.resource_type, + lease.resource_uuid, + ) - mock_lg.assert_called_once_with('parent-lease-uuid') + mock_lg.assert_called_once_with("parent-lease-uuid") mock_lvca.assert_not_called() def test_verify_time_range_invalid_time(self): bad_lease = { - 'id': 30, - 'name': 'bad-lease', - 'uuid': '534653c9-880d-4c2d-6d6d-44444444444', - 'project_id': 'le55ee_2', - 'owner_id': 'ownerid', - 'resource_type': 'dummy_node', - 'resource_uuid': '1111', - 'start_time': self.start_time + datetime.timedelta(days=30), - 'end_time': self.start_time + datetime.timedelta(days=20), - 'fulfill_time': self.start_time + datetime.timedelta(days=35), - 'expire_time': self.start_time + datetime.timedelta(days=40), + "id": 30, + "name": "bad-lease", + "uuid": "534653c9-880d-4c2d-6d6d-44444444444", + "project_id": "le55ee_2", + "owner_id": "ownerid", + "resource_type": "dummy_node", + "resource_uuid": "1111", + "start_time": self.start_time + datetime.timedelta(days=30), + "end_time": self.start_time + datetime.timedelta(days=20), + "fulfill_time": self.start_time + datetime.timedelta(days=35), + "expire_time": self.start_time + datetime.timedelta(days=40), } lease = lease_obj.Lease(self.context, **bad_lease) - self.assertRaises(exception.InvalidTimeRange, - lease.verify_time_range, - bad_lease['start_time'], bad_lease['end_time'], - None, None, - bad_lease['resource_type'], - bad_lease['resource_uuid']) + self.assertRaises( + exception.InvalidTimeRange, + lease.verify_time_range, + bad_lease["start_time"], + bad_lease["end_time"], + None, + None, + bad_lease["resource_type"], + bad_lease["resource_uuid"], + ) class TestLeaseCRUDPayloads(base.DBTestCase): - def setUp(self): super(TestLeaseCRUDPayloads, self).setUp() self.lease = lease_obj.Lease( - id='12345', - name='test_lease', + id="12345", + name="test_lease", start_time=datetime.datetime(2016, 7, 16, 19, 20, 30), end_time=datetime.datetime(2016, 8, 16, 19, 20, 30), fulfill_time=datetime.datetime(2016, 7, 16, 19, 21, 30), expire_time=datetime.datetime(2016, 8, 16, 19, 21, 30), - uuid='13921c8d-ce11-4b6d-99ed-10e19d184e5f', - resource_type='test_node', - resource_uuid='111', - project_id='lesseeid', - owner_id='ownerid', + uuid="13921c8d-ce11-4b6d-99ed-10e19d184e5f", + resource_type="test_node", + resource_uuid="111", + project_id="lesseeid", + owner_id="ownerid", parent_lease_uuid=None, offer_uuid=None, properties=None, - status='created', + status="created", purpose=None, ) - self.node = TestNode('test-node', '12345') + self.node = TestNode("test-node", "12345") def test_lease_crud_payload(self): payload = lease_obj.LeaseCRUDPayload(self.lease, self.node) @@ -726,17 +872,17 @@ def test_lease_crud_payload(self): self.assertEqual(self.lease.resource_uuid, payload.resource_uuid) self.assertEqual(self.lease.project_id, payload.project_id) self.assertEqual(self.lease.owner_id, payload.owner_id) - self.assertEqual(self.lease.parent_lease_uuid, - payload.parent_lease_uuid) + self.assertEqual(self.lease.parent_lease_uuid, payload.parent_lease_uuid) self.assertEqual(self.lease.offer_uuid, payload.offer_uuid) self.assertEqual(self.lease.properties, payload.properties) self.assertEqual(self.lease.status, payload.status) self.assertEqual(self.lease.purpose, payload.purpose) self.assertEqual(self.node.node_name, payload.node_name) self.assertEqual(self.node._uuid, payload.node_uuid) - self.assertEqual(self.node.node_power_state, - payload.node_power_state) - self.assertEqual(self.node.node_provision_state, - payload.node_provision_state), - self.assertEqual(self.node.node_properties, - payload.node_properties) + self.assertEqual(self.node.node_power_state, payload.node_power_state) + ( + self.assertEqual( + self.node.node_provision_state, payload.node_provision_state + ), + ) + self.assertEqual(self.node.node_properties, payload.node_properties) diff --git a/esi_leap/tests/objects/test_notification.py b/esi_leap/tests/objects/test_notification.py index c00879c8..2057e9fe 100644 --- a/esi_leap/tests/objects/test_notification.py +++ b/esi_leap/tests/objects/test_notification.py @@ -24,99 +24,101 @@ # Notification object borrowed from Ironic class TestNotificationBase(test_base.TestCase): - @versioned_objects_base.VersionedObjectRegistry.register class TestObject(base.ESILEAPObject): - VERSION = '1.0' + VERSION = "1.0" fields = { - 'fake_field_1': fields.StringField(nullable=True), - 'fake_field_2': fields.IntegerField(nullable=True) + "fake_field_1": fields.StringField(nullable=True), + "fake_field_2": fields.IntegerField(nullable=True), } @versioned_objects_base.VersionedObjectRegistry.register class TestObjectMissingField(base.ESILEAPObject): - VERSION = '1.0' + VERSION = "1.0" fields = { - 'fake_field_1': fields.StringField(nullable=True), + "fake_field_1": fields.StringField(nullable=True), } @versioned_objects_base.VersionedObjectRegistry.register class TestNotificationPayload(notification.NotificationPayloadBase): - VERSION = '1.0' + VERSION = "1.0" SCHEMA = { - 'fake_field_a': ('test_obj', 'fake_field_1'), - 'fake_field_b': ('test_obj', 'fake_field_2') + "fake_field_a": ("test_obj", "fake_field_1"), + "fake_field_b": ("test_obj", "fake_field_2"), } fields = { - 'fake_field_a': fields.StringField(nullable=True), - 'fake_field_b': fields.IntegerField(nullable=False), - 'an_extra_field': fields.StringField(nullable=False), - 'an_optional_field': fields.IntegerField(nullable=True) + "fake_field_a": fields.StringField(nullable=True), + "fake_field_b": fields.IntegerField(nullable=False), + "an_extra_field": fields.StringField(nullable=False), + "an_optional_field": fields.IntegerField(nullable=True), } @versioned_objects_base.VersionedObjectRegistry.register - class TestNotificationPayloadEmptySchema( - notification.NotificationPayloadBase): - VERSION = '1.0' + class TestNotificationPayloadEmptySchema(notification.NotificationPayloadBase): + VERSION = "1.0" - fields = { - 'fake_field': fields.StringField() - } + fields = {"fake_field": fields.StringField()} @versioned_objects_base.VersionedObjectRegistry.register class TestNotification(notification.NotificationBase): - VERSION = '1.0' - fields = { - 'payload': fields.ObjectField('TestNotificationPayload') - } + VERSION = "1.0" + fields = {"payload": fields.ObjectField("TestNotificationPayload")} @versioned_objects_base.VersionedObjectRegistry.register class TestNotificationEmptySchema(notification.NotificationBase): - VERSION = '1.0' - fields = { - 'payload': fields.ObjectField('TestNotificationPayloadEmptySchema') - } + VERSION = "1.0" + fields = {"payload": fields.ObjectField("TestNotificationPayloadEmptySchema")} def setUp(self): super(TestNotificationBase, self).setUp() - self.fake_obj = self.TestObject(fake_field_1='fake1', fake_field_2=2) - - def _verify_notification(self, mock_notifier, mock_context, - mock_event_create, expected_event_type, - expected_payload, expected_publisher, - notif_level): - mock_notifier.prepare.assert_called_once_with( - publisher_id=expected_publisher) + self.fake_obj = self.TestObject(fake_field_1="fake1", fake_field_2=2) + + def _verify_notification( + self, + mock_notifier, + mock_context, + mock_event_create, + expected_event_type, + expected_payload, + expected_publisher, + notif_level, + ): + mock_notifier.prepare.assert_called_once_with(publisher_id=expected_publisher) # Handler actually sending out the notification depends on the # notification level mock_notify = getattr(mock_notifier.prepare.return_value, notif_level) self.assertTrue(mock_notify.called) self.assertEqual(mock_context, mock_notify.call_args[0][0]) - self.assertEqual(expected_event_type, - mock_notify.call_args[1]['event_type']) - actual_payload = mock_notify.call_args[1]['payload'] - self.assertEqual(jsonutils.dumps(expected_payload, sort_keys=True), - jsonutils.dumps(actual_payload, sort_keys=True)) + self.assertEqual(expected_event_type, mock_notify.call_args[1]["event_type"]) + actual_payload = mock_notify.call_args[1]["payload"] + self.assertEqual( + jsonutils.dumps(expected_payload, sort_keys=True), + jsonutils.dumps(actual_payload, sort_keys=True), + ) mock_event_create.assert_called_once() - @mock.patch('esi_leap.objects.event.Event.create') - @mock.patch('esi_leap.common.rpc.VERSIONED_NOTIFIER') + @mock.patch("esi_leap.objects.event.Event.create") + @mock.patch("esi_leap.common.rpc.VERSIONED_NOTIFIER") def test_emit_notification(self, mock_notifier, mock_event_create): - self.config(notification_level='debug', group='notification') - payload = self.TestNotificationPayload(an_extra_field='extra', - an_optional_field=1) + self.config(notification_level="debug", group="notification") + payload = self.TestNotificationPayload( + an_extra_field="extra", an_optional_field=1 + ) payload.populate_schema(test_obj=self.fake_obj) notif = self.TestNotification( event_type=notification.EventType( - object='test_object', action='test', - status=fields.NotificationStatus.START), + object="test_object", + action="test", + status=fields.NotificationStatus.START, + ), level=fields.NotificationLevel.DEBUG, publisher=notification.NotificationPublisher( - service='esi-leap-api', - host='host'), - payload=payload) + service="esi-leap-api", host="host" + ), + payload=payload, + ) mock_context = mock.Mock() notif.emit(mock_context) @@ -125,100 +127,115 @@ def test_emit_notification(self, mock_notifier, mock_event_create): mock_notifier, mock_context, mock_event_create, - expected_event_type='esi_leap.test_object.test.start', + expected_event_type="esi_leap.test_object.test.start", expected_payload={ - 'esi_leap_object.name': 'TestNotificationPayload', - 'esi_leap_object.data': { - 'fake_field_a': 'fake1', - 'fake_field_b': 2, - 'an_extra_field': 'extra', - 'an_optional_field': 1 + "esi_leap_object.name": "TestNotificationPayload", + "esi_leap_object.data": { + "fake_field_a": "fake1", + "fake_field_b": 2, + "an_extra_field": "extra", + "an_optional_field": 1, }, - 'esi_leap_object.version': '1.0', - 'esi_leap_object.namespace': 'esi_leap'}, - expected_publisher='esi-leap-api.host', - notif_level=fields.NotificationLevel.DEBUG) - - @mock.patch('esi_leap.common.rpc.VERSIONED_NOTIFIER') + "esi_leap_object.version": "1.0", + "esi_leap_object.namespace": "esi_leap", + }, + expected_publisher="esi-leap-api.host", + notif_level=fields.NotificationLevel.DEBUG, + ) + + @mock.patch("esi_leap.common.rpc.VERSIONED_NOTIFIER") def test_no_emit_level_too_low(self, mock_notifier): # Make sure notification doesn't emit when set notification # level < config level - self.config(notification_level='warning', group='notification') - payload = self.TestNotificationPayload(an_extra_field='extra', - an_optional_field=1) + self.config(notification_level="warning", group="notification") + payload = self.TestNotificationPayload( + an_extra_field="extra", an_optional_field=1 + ) payload.populate_schema(test_obj=self.fake_obj) notif = self.TestNotification( event_type=notification.EventType( - object='test_object', action='test', - status=fields.NotificationStatus.START), + object="test_object", + action="test", + status=fields.NotificationStatus.START, + ), level=fields.NotificationLevel.DEBUG, publisher=notification.NotificationPublisher( - service='esi-leap-api', - host='host'), - payload=payload) + service="esi-leap-api", host="host" + ), + payload=payload, + ) mock_context = mock.Mock() notif.emit(mock_context) self.assertFalse(mock_notifier.called) - @mock.patch('esi_leap.common.rpc.VERSIONED_NOTIFIER') + @mock.patch("esi_leap.common.rpc.VERSIONED_NOTIFIER") def test_no_emit_notifs_disabled(self, mock_notifier): # Make sure notifications aren't emitted when notification_level # isn't defined, indicating notifications should be disabled - payload = self.TestNotificationPayload(an_extra_field='extra', - an_optional_field=1) + payload = self.TestNotificationPayload( + an_extra_field="extra", an_optional_field=1 + ) payload.populate_schema(test_obj=self.fake_obj) notif = self.TestNotification( event_type=notification.EventType( - object='test_object', action='test', - status=fields.NotificationStatus.START), + object="test_object", + action="test", + status=fields.NotificationStatus.START, + ), level=fields.NotificationLevel.DEBUG, publisher=notification.NotificationPublisher( - service='esi-leap-api', - host='host'), - payload=payload) + service="esi-leap-api", host="host" + ), + payload=payload, + ) mock_context = mock.Mock() notif.emit(mock_context) self.assertFalse(mock_notifier.called) - @mock.patch('esi_leap.common.rpc.VERSIONED_NOTIFIER') + @mock.patch("esi_leap.common.rpc.VERSIONED_NOTIFIER") def test_no_emit_schema_not_populated(self, mock_notifier): - self.config(notification_level='debug', group='notification') - payload = self.TestNotificationPayload(an_extra_field='extra', - an_optional_field=1) + self.config(notification_level="debug", group="notification") + payload = self.TestNotificationPayload( + an_extra_field="extra", an_optional_field=1 + ) notif = self.TestNotification( event_type=notification.EventType( - object='test_object', action='test', - status=fields.NotificationStatus.START), + object="test_object", + action="test", + status=fields.NotificationStatus.START, + ), level=fields.NotificationLevel.DEBUG, publisher=notification.NotificationPublisher( - service='esi-leap-api', - host='host'), - payload=payload) + service="esi-leap-api", host="host" + ), + payload=payload, + ) mock_context = mock.Mock() - self.assertRaises(exception.NotificationPayloadError, notif.emit, - mock_context) + self.assertRaises(exception.NotificationPayloadError, notif.emit, mock_context) self.assertFalse(mock_notifier.called) - @mock.patch('esi_leap.objects.event.Event.create') - @mock.patch('esi_leap.common.rpc.VERSIONED_NOTIFIER') - def test_emit_notification_empty_schema(self, mock_notifier, - mock_event_create): - self.config(notification_level='debug', group='notification') - payload = self.TestNotificationPayloadEmptySchema(fake_field='123') + @mock.patch("esi_leap.objects.event.Event.create") + @mock.patch("esi_leap.common.rpc.VERSIONED_NOTIFIER") + def test_emit_notification_empty_schema(self, mock_notifier, mock_event_create): + self.config(notification_level="debug", group="notification") + payload = self.TestNotificationPayloadEmptySchema(fake_field="123") notif = self.TestNotificationEmptySchema( event_type=notification.EventType( - object='test_object', action='test', - status=fields.NotificationStatus.ERROR), + object="test_object", + action="test", + status=fields.NotificationStatus.ERROR, + ), level=fields.NotificationLevel.ERROR, publisher=notification.NotificationPublisher( - service='esi-leap-api', - host='host'), - payload=payload) + service="esi-leap-api", host="host" + ), + payload=payload, + ) mock_context = mock.Mock() notif.emit(mock_context) @@ -227,33 +244,38 @@ def test_emit_notification_empty_schema(self, mock_notifier, mock_notifier, mock_context, mock_event_create, - expected_event_type='esi_leap.test_object.test.error', + expected_event_type="esi_leap.test_object.test.error", expected_payload={ - 'esi_leap_object.name': 'TestNotificationPayloadEmptySchema', - 'esi_leap_object.data': { - 'fake_field': '123', + "esi_leap_object.name": "TestNotificationPayloadEmptySchema", + "esi_leap_object.data": { + "fake_field": "123", }, - 'esi_leap_object.version': '1.0', - 'esi_leap_object.namespace': 'esi_leap'}, - expected_publisher='esi-leap-api.host', - notif_level=fields.NotificationLevel.ERROR) + "esi_leap_object.version": "1.0", + "esi_leap_object.namespace": "esi_leap", + }, + expected_publisher="esi-leap-api.host", + notif_level=fields.NotificationLevel.ERROR, + ) def test_populate_schema(self): - payload = self.TestNotificationPayload(an_extra_field='extra', - an_optional_field=1) + payload = self.TestNotificationPayload( + an_extra_field="extra", an_optional_field=1 + ) payload.populate_schema(test_obj=self.fake_obj) - self.assertEqual('extra', payload.an_extra_field) + self.assertEqual("extra", payload.an_extra_field) self.assertEqual(1, payload.an_optional_field) self.assertEqual(self.fake_obj.fake_field_1, payload.fake_field_a) self.assertEqual(self.fake_obj.fake_field_2, payload.fake_field_b) def test_populate_schema_missing_required_obj_field(self): - test_obj = self.TestObject(fake_field_1='populated') + test_obj = self.TestObject(fake_field_1="populated") # this payload requires missing fake_field_b - payload = self.TestNotificationPayload(an_extra_field='too extra') - self.assertRaises(exception.NotificationSchemaKeyError, - payload.populate_schema, - test_obj=test_obj) + payload = self.TestNotificationPayload(an_extra_field="too extra") + self.assertRaises( + exception.NotificationSchemaKeyError, + payload.populate_schema, + test_obj=test_obj, + ) def test_populate_schema_nullable_field_auto_populates(self): """Test that nullable fields always end up in the payload.""" @@ -263,33 +285,40 @@ def test_populate_schema_nullable_field_auto_populates(self): self.assertIsNone(payload.fake_field_a) def test_populate_schema_no_object_field(self): - test_obj = self.TestObjectMissingField(fake_field_1='foo') + test_obj = self.TestObjectMissingField(fake_field_1="foo") payload = self.TestNotificationPayload() - self.assertRaises(exception.NotificationSchemaKeyError, - payload.populate_schema, - test_obj=test_obj) + self.assertRaises( + exception.NotificationSchemaKeyError, + payload.populate_schema, + test_obj=test_obj, + ) def test_event_type_with_status(self): event_type = notification.EventType( - object="some_obj", action="some_action", status="success") - self.assertEqual("esi_leap.some_obj.some_action.success", - event_type.to_event_type_field()) + object="some_obj", action="some_action", status="success" + ) + self.assertEqual( + "esi_leap.some_obj.some_action.success", event_type.to_event_type_field() + ) def test_event_type_without_status_fails(self): - event_type = notification.EventType( - object="some_obj", action="some_action") - self.assertRaises(NotImplementedError, - event_type.to_event_type_field) + event_type = notification.EventType(object="some_obj", action="some_action") + self.assertRaises(NotImplementedError, event_type.to_event_type_field) def test_event_type_invalid_status_fails(self): - self.assertRaises(ValueError, - notification.EventType, object="some_obj", - action="some_action", status="invalid") + self.assertRaises( + ValueError, + notification.EventType, + object="some_obj", + action="some_action", + status="invalid", + ) def test_event_type_make_status_invalid(self): def make_status_invalid(): event_type.status = "Roar" event_type = notification.EventType( - object='test_object', action='test', status='start') + object="test_object", action="test", status="start" + ) self.assertRaises(ValueError, make_status_invalid) diff --git a/esi_leap/tests/objects/test_offer.py b/esi_leap/tests/objects/test_offer.py index 26eafb26..92281211 100644 --- a/esi_leap/tests/objects/test_offer.py +++ b/esi_leap/tests/objects/test_offer.py @@ -24,52 +24,51 @@ class TestOfferObject(base.DBTestCase): - def setUp(self): super(TestOfferObject, self).setUp() start = datetime.datetime(2016, 7, 16, 19, 20, 30) self.test_offer_data = { - 'id': 27, - 'name': 'o', - 'uuid': uuidutils.generate_uuid(), - 'project_id': '0wn5r', - 'lessee_id': None, - 'resource_type': 'dummy_node', - 'resource_uuid': '1718', - 'start_time': start, - 'end_time': start + datetime.timedelta(days=100), - 'status': statuses.AVAILABLE, - 'properties': {'floor_price': 3}, - 'parent_lease_uuid': None, - 'created_at': None, - 'updated_at': None + "id": 27, + "name": "o", + "uuid": uuidutils.generate_uuid(), + "project_id": "0wn5r", + "lessee_id": None, + "resource_type": "dummy_node", + "resource_uuid": "1718", + "start_time": start, + "end_time": start + datetime.timedelta(days=100), + "status": statuses.AVAILABLE, + "properties": {"floor_price": 3}, + "parent_lease_uuid": None, + "created_at": None, + "updated_at": None, } self.test_offer_create_data = { - 'name': 'o', - 'project_id': '0wn5r', - 'resource_type': 'dummy_node', - 'resource_uuid': '1718', - 'start_time': start, - 'end_time': start + datetime.timedelta(days=100), - 'properties': {'floor_price': 3}, + "name": "o", + "project_id": "0wn5r", + "resource_type": "dummy_node", + "resource_uuid": "1718", + "start_time": start, + "end_time": start + datetime.timedelta(days=100), + "properties": {"floor_price": 3}, } - self.test_offer_create_parent_lease_data = ( - self.test_offer_create_data.copy()) - self.test_offer_create_parent_lease_data['parent_lease_uuid'] = ( - 'parent-lease-uuid') + self.test_offer_create_parent_lease_data = self.test_offer_create_data.copy() + self.test_offer_create_parent_lease_data["parent_lease_uuid"] = ( + "parent-lease-uuid" + ) self.test_parent_lease = lease.Lease( - uuid=uuidutils.generate_uuid(), - status=statuses.ACTIVE) + uuid=uuidutils.generate_uuid(), status=statuses.ACTIVE + ) self.test_parent_lease_expired = lease.Lease( - uuid=uuidutils.generate_uuid(), - status=statuses.EXPIRED) + uuid=uuidutils.generate_uuid(), status=statuses.EXPIRED + ) - self.config(lock_path=tempfile.mkdtemp(), group='oslo_concurrency') + self.config(lock_path=tempfile.mkdtemp(), group="oslo_concurrency") - @mock.patch('esi_leap.db.sqlalchemy.api.offer_get_by_uuid') + @mock.patch("esi_leap.db.sqlalchemy.api.offer_get_by_uuid") def test_get(self, mock_offer_get_by_uuid): - offer_uuid = self.test_offer_data['uuid'] + offer_uuid = self.test_offer_data["uuid"] mock_offer_get_by_uuid.return_value = self.test_offer_data o = offer.Offer.get(offer_uuid, self.context) @@ -77,7 +76,7 @@ def test_get(self, mock_offer_get_by_uuid): mock_offer_get_by_uuid.assert_called_once_with(offer_uuid) self.assertEqual(self.context, o._context) - @mock.patch('esi_leap.db.sqlalchemy.api.offer_get_all') + @mock.patch("esi_leap.db.sqlalchemy.api.offer_get_all") def test_get_all(self, mock_offer_get_all): mock_offer_get_all.return_value = [self.test_offer_data] @@ -88,29 +87,37 @@ def test_get_all(self, mock_offer_get_all): self.assertIsInstance(offers[0], offer.Offer) self.assertEqual(self.context, offers[0]._context) - @mock.patch('esi_leap.db.sqlalchemy.api.offer_get_conflict_times') - @mock.patch('esi_leap.objects.offer.datetime') - def test_get_availabilities_offer_in_future(self, mock_datetime, - mock_ogct): + @mock.patch("esi_leap.db.sqlalchemy.api.offer_get_conflict_times") + @mock.patch("esi_leap.objects.offer.datetime") + def test_get_availabilities_offer_in_future(self, mock_datetime, mock_ogct): o = offer.Offer(self.context, **self.test_offer_data) # test offer start_time > now mock_datetime.datetime.now = mock.Mock( - return_value=o.start_time + datetime.timedelta(days=-5)) + return_value=o.start_time + datetime.timedelta(days=-5) + ) mock_ogct.return_value = [ - [o.start_time + datetime.timedelta(days=10), - o.start_time + datetime.timedelta(days=20)], - [o.start_time + datetime.timedelta(days=20), - o.start_time + datetime.timedelta(days=30)], - [o.start_time + datetime.timedelta(days=50), - o.start_time + datetime.timedelta(days=60)] + [ + o.start_time + datetime.timedelta(days=10), + o.start_time + datetime.timedelta(days=20), + ], + [ + o.start_time + datetime.timedelta(days=20), + o.start_time + datetime.timedelta(days=30), + ], + [ + o.start_time + datetime.timedelta(days=50), + o.start_time + datetime.timedelta(days=60), + ], ] expect = [ [o.start_time, o.start_time + datetime.timedelta(days=10)], - [o.start_time + datetime.timedelta(days=30), - o.start_time + datetime.timedelta(days=50)], - [o.start_time + datetime.timedelta(days=60), o.end_time] + [ + o.start_time + datetime.timedelta(days=30), + o.start_time + datetime.timedelta(days=50), + ], + [o.start_time + datetime.timedelta(days=60), o.end_time], ] a = o.get_availabilities() self.assertEqual(a, expect) @@ -125,10 +132,9 @@ def test_get_availabilities_offer_in_future(self, mock_datetime, a = o.get_availabilities() self.assertEqual(a, expect) - @mock.patch('esi_leap.db.sqlalchemy.api.offer_get_conflict_times') - @mock.patch('esi_leap.objects.offer.datetime') - def test_get_availabilities_conflicts_in_future(self, mock_datetime, - mock_ogct): + @mock.patch("esi_leap.db.sqlalchemy.api.offer_get_conflict_times") + @mock.patch("esi_leap.objects.offer.datetime") + def test_get_availabilities_conflicts_in_future(self, mock_datetime, mock_ogct): o = offer.Offer(self.context, **self.test_offer_data) # test offer start_time <= now < first conflict start_time @@ -140,26 +146,33 @@ def test_get_availabilities_conflicts_in_future(self, mock_datetime, a = o.get_availabilities() self.assertEqual(a, expect) mock_ogct.return_value = [ - [o.start_time + datetime.timedelta(days=10), - o.start_time + datetime.timedelta(days=20)], - [o.start_time + datetime.timedelta(days=20), - o.start_time + datetime.timedelta(days=30)], - [o.start_time + datetime.timedelta(days=50), - o.start_time + datetime.timedelta(days=60)] + [ + o.start_time + datetime.timedelta(days=10), + o.start_time + datetime.timedelta(days=20), + ], + [ + o.start_time + datetime.timedelta(days=20), + o.start_time + datetime.timedelta(days=30), + ], + [ + o.start_time + datetime.timedelta(days=50), + o.start_time + datetime.timedelta(days=60), + ], ] expect = [ - [o.start_time + datetime.timedelta(days=30), - o.start_time + datetime.timedelta(days=50)], - [o.start_time + datetime.timedelta(days=60), o.end_time] + [ + o.start_time + datetime.timedelta(days=30), + o.start_time + datetime.timedelta(days=50), + ], + [o.start_time + datetime.timedelta(days=60), o.end_time], ] a = o.get_availabilities() self.assertEqual(a, expect) - @mock.patch('esi_leap.db.sqlalchemy.api.offer_get_conflict_times') - @mock.patch('esi_leap.objects.offer.datetime') - def test_get_availabilities_conflicts_current(self, mock_datetime, - mock_ogct): + @mock.patch("esi_leap.db.sqlalchemy.api.offer_get_conflict_times") + @mock.patch("esi_leap.objects.offer.datetime") + def test_get_availabilities_conflicts_current(self, mock_datetime, mock_ogct): o = offer.Offer(self.context, **self.test_offer_data) # test a conflict is happening right now @@ -167,27 +180,36 @@ def test_get_availabilities_conflicts_current(self, mock_datetime, mock_datetime.datetime.now = mock.Mock(return_value=now) mock_ogct.return_value = [ [o.start_time, o.start_time + datetime.timedelta(days=4)], - [o.start_time + datetime.timedelta(days=5), - o.start_time + datetime.timedelta(days=15)], - [o.start_time + datetime.timedelta(days=20), - o.start_time + datetime.timedelta(days=30)], - [o.start_time + datetime.timedelta(days=50), - o.start_time + datetime.timedelta(days=60)] + [ + o.start_time + datetime.timedelta(days=5), + o.start_time + datetime.timedelta(days=15), + ], + [ + o.start_time + datetime.timedelta(days=20), + o.start_time + datetime.timedelta(days=30), + ], + [ + o.start_time + datetime.timedelta(days=50), + o.start_time + datetime.timedelta(days=60), + ], ] expect = [ - [o.start_time + datetime.timedelta(days=15), - o.start_time + datetime.timedelta(days=20)], - [o.start_time + datetime.timedelta(days=30), - o.start_time + datetime.timedelta(days=50)], - [o.start_time + datetime.timedelta(days=60), o.end_time] + [ + o.start_time + datetime.timedelta(days=15), + o.start_time + datetime.timedelta(days=20), + ], + [ + o.start_time + datetime.timedelta(days=30), + o.start_time + datetime.timedelta(days=50), + ], + [o.start_time + datetime.timedelta(days=60), o.end_time], ] a = o.get_availabilities() self.assertEqual(a, expect) - @mock.patch('esi_leap.db.sqlalchemy.api.offer_get_conflict_times') - @mock.patch('esi_leap.objects.offer.datetime') - def test_get_availabilities_conflicts_past(self, mock_datetime, - mock_ogct): + @mock.patch("esi_leap.db.sqlalchemy.api.offer_get_conflict_times") + @mock.patch("esi_leap.objects.offer.datetime") + def test_get_availabilities_conflicts_past(self, mock_datetime, mock_ogct): o = offer.Offer(self.context, **self.test_offer_data) # test all conflicts happened in the past @@ -195,89 +217,86 @@ def test_get_availabilities_conflicts_past(self, mock_datetime, mock_datetime.datetime.now = mock.Mock(return_value=now) mock_ogct.return_value = [ [o.start_time, o.start_time + datetime.timedelta(days=4)], - [o.start_time + datetime.timedelta(days=5), - o.start_time + datetime.timedelta(days=10)] + [ + o.start_time + datetime.timedelta(days=5), + o.start_time + datetime.timedelta(days=10), + ], ] expect = [[now, o.end_time]] a = o.get_availabilities() self.assertEqual(a, expect) - @mock.patch('esi_leap.db.sqlalchemy.api.resource_verify_availability') - @mock.patch('esi_leap.db.sqlalchemy.api.offer_create') + @mock.patch("esi_leap.db.sqlalchemy.api.resource_verify_availability") + @mock.patch("esi_leap.db.sqlalchemy.api.offer_create") def test_create(self, mock_oc, mock_rva): o = offer.Offer(self.context, **self.test_offer_create_data) mock_oc.return_value = self.test_offer_data o.create(self.context) - mock_rva.assert_called_once_with(o.resource_type, - o.resource_uuid, - o.start_time, - o.end_time) + mock_rva.assert_called_once_with( + o.resource_type, o.resource_uuid, o.start_time, o.end_time + ) mock_oc.assert_called_once_with(self.test_offer_create_data) def test_create_invalid_time(self): - start = self.test_offer_data['start_time'] + start = self.test_offer_data["start_time"] bad_offer = { - 'name': 'o', - 'project_id': '0wn5r', - 'resource_type': 'dummy_node', - 'resource_uuid': '1718', - 'start_time': start + datetime.timedelta(days=100), - 'end_time': start, - 'status': statuses.AVAILABLE, - 'properties': {'floor_price': 3}, + "name": "o", + "project_id": "0wn5r", + "resource_type": "dummy_node", + "resource_uuid": "1718", + "start_time": start + datetime.timedelta(days=100), + "end_time": start, + "status": statuses.AVAILABLE, + "properties": {"floor_price": 3}, } o = offer.Offer(self.context, **bad_offer) self.assertRaises(exception.InvalidTimeRange, o.create) - @mock.patch('esi_leap.db.sqlalchemy.api.lease_verify_child_availability') - @mock.patch('esi_leap.objects.lease.Lease.get') - @mock.patch('esi_leap.db.sqlalchemy.api.offer_create') + @mock.patch("esi_leap.db.sqlalchemy.api.lease_verify_child_availability") + @mock.patch("esi_leap.objects.lease.Lease.get") + @mock.patch("esi_leap.db.sqlalchemy.api.offer_create") def test_create_with_parent_lease(self, mock_oc, mock_lg, mock_lvca): - o = offer.Offer(self.context, - **self.test_offer_create_parent_lease_data) + o = offer.Offer(self.context, **self.test_offer_create_parent_lease_data) mock_lg.return_value = self.test_parent_lease mock_oc.return_value = self.test_offer_data o.create(self.context) - mock_lg.assert_called_once_with('parent-lease-uuid') - mock_lvca.assert_called_once_with(self.test_parent_lease, - o.start_time, - o.end_time) - mock_oc.assert_called_once_with( - self.test_offer_create_parent_lease_data) - - @mock.patch('esi_leap.db.sqlalchemy.api.lease_verify_child_availability') - @mock.patch('esi_leap.objects.lease.Lease.get') - @mock.patch('esi_leap.db.sqlalchemy.api.offer_create') - def test_create_with_parent_lease_expired(self, mock_oc, mock_lg, - mock_lvca): - o = offer.Offer(self.context, - **self.test_offer_create_parent_lease_data) + mock_lg.assert_called_once_with("parent-lease-uuid") + mock_lvca.assert_called_once_with( + self.test_parent_lease, o.start_time, o.end_time + ) + mock_oc.assert_called_once_with(self.test_offer_create_parent_lease_data) + + @mock.patch("esi_leap.db.sqlalchemy.api.lease_verify_child_availability") + @mock.patch("esi_leap.objects.lease.Lease.get") + @mock.patch("esi_leap.db.sqlalchemy.api.offer_create") + def test_create_with_parent_lease_expired(self, mock_oc, mock_lg, mock_lvca): + o = offer.Offer(self.context, **self.test_offer_create_parent_lease_data) mock_lg.return_value = self.test_parent_lease_expired mock_oc.return_value = self.test_offer_data self.assertRaises(exception.LeaseNotActive, o.create, self.context) - mock_lg.assert_called_once_with('parent-lease-uuid') + mock_lg.assert_called_once_with("parent-lease-uuid") mock_lvca.assert_not_called() mock_oc.assert_not_called() - @mock.patch('esi_leap.db.sqlalchemy.api.resource_verify_availability') - @mock.patch('esi_leap.db.sqlalchemy.api.offer_create') + @mock.patch("esi_leap.db.sqlalchemy.api.resource_verify_availability") + @mock.patch("esi_leap.db.sqlalchemy.api.offer_create") def test_create_concurrent(self, mock_oc, mock_rva): o = offer.Offer(self.context, **self.test_offer_create_data) o2 = offer.Offer(self.context, **self.test_offer_create_data) o2.id = 28 def update_mock(updates): - mock_rva.side_effect = Exception('bad') + mock_rva.side_effect = Exception("bad") mock_oc.side_effect = update_mock @@ -293,39 +312,39 @@ def update_mock(updates): self.assertEqual(mock_rva.call_count, 2) mock_oc.assert_called_once() - @mock.patch('esi_leap.db.sqlalchemy.api.offer_destroy') + @mock.patch("esi_leap.db.sqlalchemy.api.offer_destroy") def test_destroy(self, mock_offer_destroy): o = offer.Offer(self.context, **self.test_offer_data) o.destroy() mock_offer_destroy.assert_called_once_with(o.uuid) - @mock.patch('esi_leap.db.sqlalchemy.api.offer_update') + @mock.patch("esi_leap.db.sqlalchemy.api.offer_update") def test_save(self, mock_offer_update): o = offer.Offer(self.context, **self.test_offer_data) new_status = statuses.DELETED updated_at = datetime.datetime(2006, 12, 11, 0, 0) updated_offer = self.test_offer_data.copy() - updated_offer['status'] = new_status - updated_offer['updated_at'] = updated_at + updated_offer["status"] = new_status + updated_offer["updated_at"] = updated_at mock_offer_update.return_value = updated_offer o.status = new_status o.save(self.context) updated_values = self.test_offer_data.copy() - updated_values['status'] = new_status + updated_values["status"] = new_status mock_offer_update.assert_called_once_with(o.uuid, updated_values) self.assertEqual(self.context, o._context) self.assertEqual(updated_at, o.updated_at) - @mock.patch('esi_leap.db.sqlalchemy.api.offer_verify_availability') + @mock.patch("esi_leap.db.sqlalchemy.api.offer_verify_availability") def test_verify_availability(self, mock_ova): o = offer.Offer(self.context, **self.test_offer_data) o.verify_availability(o.start_time, o.end_time) mock_ova.assert_called_once_with(o, o.start_time, o.end_time) - @mock.patch('esi_leap.objects.offer.get_resource_object') + @mock.patch("esi_leap.objects.offer.get_resource_object") def test_resource_object(self, mock_gro): o = offer.Offer(self.context, **self.test_offer_data) o.resource_object() diff --git a/esi_leap/tests/resource_objects/test_base.py b/esi_leap/tests/resource_objects/test_base.py index e272ae59..c554f00c 100644 --- a/esi_leap/tests/resource_objects/test_base.py +++ b/esi_leap/tests/resource_objects/test_base.py @@ -30,6 +30,7 @@ def wrapper(*args, **kwargs): methods.add(name) cls.__abstractmethods__ = frozenset(methods) return cls(*args, **kwargs) + return wrapper @@ -43,8 +44,7 @@ def get_uuid(self): class TestResourceObjectInterface(base.TestCase): - - @mock.patch('esi_leap.db.sqlalchemy.api.resource_verify_availability') + @mock.patch("esi_leap.db.sqlalchemy.api.resource_verify_availability") def test_verify_availability_for_offer(self, mock_rva): start = datetime.datetime(2016, 7, 16, 19, 20, 30) end = start + datetime.timedelta(days=10) @@ -52,4 +52,4 @@ def test_verify_availability_for_offer(self, mock_rva): test_node = ResourceObjectStub(fake_uuid) test_node.verify_availability(start, end) - mock_rva.assert_called_once_with('base', fake_uuid, start, end) + mock_rva.assert_called_once_with("base", fake_uuid, start, end) diff --git a/esi_leap/tests/resource_objects/test_dummy_node.py b/esi_leap/tests/resource_objects/test_dummy_node.py index df3b04eb..1b6ba818 100644 --- a/esi_leap/tests/resource_objects/test_dummy_node.py +++ b/esi_leap/tests/resource_objects/test_dummy_node.py @@ -25,128 +25,126 @@ class FakeLease(object): def __init__(self): - self.uuid = '001' - self.project_id = '654321' + self.uuid = "001" + self.project_id = "654321" self.start_time = start + datetime.timedelta(days=5) self.end_time = start + datetime.timedelta(days=10) self.status = statuses.CREATED - self.offer_uuid = '534653c9-880d-4c2d-6d6d-f4f2a09e384' + self.offer_uuid = "534653c9-880d-4c2d-6d6d-f4f2a09e384" class TestDummyNode(base.TestCase): - test_node_1 = { - 'project_owner_id': '123456', - 'project_id': '654321', - 'lease_uuid': '001', - 'resource_class': 'fake', - 'power_state': 'off', - 'provision_state': 'enroll', - 'properties': { - 'new attribute XYZ': 'new attribute XYZ', - 'cpu_type': 'Intel Xeon', - 'cores': 16, - 'ram_gb': 512, - 'storage_type': 'samsung SSD', - 'storage_size_gb': 204 - } + "project_owner_id": "123456", + "project_id": "654321", + "lease_uuid": "001", + "resource_class": "fake", + "power_state": "off", + "provision_state": "enroll", + "properties": { + "new attribute XYZ": "new attribute XYZ", + "cpu_type": "Intel Xeon", + "cores": 16, + "ram_gb": 512, + "storage_type": "samsung SSD", + "storage_size_gb": 204, + }, } test_node_2 = { - 'project_owner_id': '123456', - 'resource_class': 'fake', - 'properties': { - 'new attribute XYZ': 'new attribute XYZ', - 'cpu_type': 'Intel Xeon', - 'cores': 16, - 'ram_gb': 512, - 'storage_type': 'samsung SSD', - 'storage_size_gb': 204 - } + "project_owner_id": "123456", + "resource_class": "fake", + "properties": { + "new attribute XYZ": "new attribute XYZ", + "cpu_type": "Intel Xeon", + "cores": 16, + "ram_gb": 512, + "storage_type": "samsung SSD", + "storage_size_gb": 204, + }, } def setUp(self): super(TestDummyNode, self).setUp() - self.fake_dummy_node = dummy_node.DummyNode('1111') + self.fake_dummy_node = dummy_node.DummyNode("1111") self.fake_read_data_1 = json.dumps(self.test_node_1) self.fake_read_data_2 = json.dumps(self.test_node_2) def test_resource_type(self): - self.assertEqual('dummy_node', self.fake_dummy_node.resource_type) + self.assertEqual("dummy_node", self.fake_dummy_node.resource_type) def test_get_uuid(self): - self.assertEqual('1111', self.fake_dummy_node.get_uuid()) + self.assertEqual("1111", self.fake_dummy_node.get_uuid()) def test_get_name(self): - self.assertEqual('dummy-node-1111', - self.fake_dummy_node.get_name()) + self.assertEqual("dummy-node-1111", self.fake_dummy_node.get_name()) def test_get_resource_class(self): mock_open = mock.mock_open(read_data=self.fake_read_data_1) - with mock.patch('builtins.open', mock_open) as mock_file_open: + with mock.patch("builtins.open", mock_open) as mock_file_open: resource_class = self.fake_dummy_node.get_resource_class() - self.assertEqual(resource_class, - self.test_node_1['resource_class']) + self.assertEqual(resource_class, self.test_node_1["resource_class"]) mock_file_open.assert_called_once() def test_get_properties(self): mock_open = mock.mock_open(read_data=self.fake_read_data_1) - with mock.patch('builtins.open', mock_open) as mock_file_open: + with mock.patch("builtins.open", mock_open) as mock_file_open: properties = self.fake_dummy_node.get_properties() - self.assertEqual(properties, self.test_node_1['properties']) + self.assertEqual(properties, self.test_node_1["properties"]) mock_file_open.assert_called_once() def test_get_owner_project_id(self): mock_open = mock.mock_open(read_data=self.fake_read_data_1) - with mock.patch('builtins.open', mock_open) as mock_file_open: - self.assertEqual(self.fake_dummy_node.get_owner_project_id(), - self.test_node_1['project_owner_id']) + with mock.patch("builtins.open", mock_open) as mock_file_open: + self.assertEqual( + self.fake_dummy_node.get_owner_project_id(), + self.test_node_1["project_owner_id"], + ) self.assertEqual(mock_file_open.call_count, 1) def test_get_lease_uuid(self): mock_open = mock.mock_open(read_data=self.fake_read_data_1) - with mock.patch('builtins.open', mock_open) as mock_file_open: + with mock.patch("builtins.open", mock_open) as mock_file_open: lease_uuid = self.fake_dummy_node.get_lease_uuid() - self.assertEqual(lease_uuid, '001') + self.assertEqual(lease_uuid, "001") mock_file_open.assert_called_once() def test_get_lessee_project_id(self): mock_open = mock.mock_open(read_data=self.fake_read_data_1) - with mock.patch('builtins.open', mock_open) as mock_file_open: + with mock.patch("builtins.open", mock_open) as mock_file_open: project_id = self.fake_dummy_node.get_lessee_project_id() - self.assertEqual(project_id, '654321') + self.assertEqual(project_id, "654321") mock_file_open.assert_called_once() def test_get_node_power_state(self): mock_open = mock.mock_open(read_data=self.fake_read_data_1) - with mock.patch('builtins.open', mock_open) as mock_file_open: + with mock.patch("builtins.open", mock_open) as mock_file_open: power_state = self.fake_dummy_node.get_node_power_state() - self.assertEqual(power_state, 'off') + self.assertEqual(power_state, "off") mock_file_open.assert_called_once() def test_get_node_provision_state(self): mock_open = mock.mock_open(read_data=self.fake_read_data_1) - with mock.patch('builtins.open', mock_open) as mock_file_open: + with mock.patch("builtins.open", mock_open) as mock_file_open: provision_state = self.fake_dummy_node.get_node_provision_state() - self.assertEqual(provision_state, 'enroll') + self.assertEqual(provision_state, "enroll") mock_file_open.assert_called_once() def test_set_lease(self): mock_open = mock.mock_open(read_data=self.fake_read_data_2) - with mock.patch('builtins.open', mock_open) as mock_file_open: + with mock.patch("builtins.open", mock_open) as mock_file_open: fake_lease = FakeLease() self.fake_dummy_node.set_lease(fake_lease) self.assertEqual(mock_file_open.call_count, 2) def test_remove_lease(self): mock_open = mock.mock_open(read_data=self.fake_read_data_1) - with mock.patch('builtins.open', mock_open) as mock_file_open: + with mock.patch("builtins.open", mock_open) as mock_file_open: fake_lease = FakeLease() self.fake_dummy_node.remove_lease(fake_lease) self.assertEqual(mock_file_open.call_count, 2) - @mock.patch('builtins.open') + @mock.patch("builtins.open") def test_get_deleted_node_info(self, mock_open): mock_open.side_effect = FileNotFoundError - self.assertEqual(self.fake_dummy_node.get_resource_class(), - 'unknown-class') + self.assertEqual(self.fake_dummy_node.get_resource_class(), "unknown-class") diff --git a/esi_leap/tests/resource_objects/test_ironic_node.py b/esi_leap/tests/resource_objects/test_ironic_node.py index b54a6822..ee70b9d8 100644 --- a/esi_leap/tests/resource_objects/test_ironic_node.py +++ b/esi_leap/tests/resource_objects/test_ironic_node.py @@ -21,43 +21,42 @@ from esi_leap.tests import base start = datetime.datetime(2016, 7, 16, 19, 20, 30) -fake_uuid = '13921c8d-ce11-4b6d-99ed-10e19d184e5f' +fake_uuid = "13921c8d-ce11-4b6d-99ed-10e19d184e5f" class FakeIronicNode(object): def __init__(self): self.created_at = start - self.lessee = 'abcdef' - self.owner = '123456' - self.name = 'fake-node' - self.properties = {'lease_uuid': '001', 'cpu': '40'} - self.provision_state = 'available' + self.lessee = "abcdef" + self.owner = "123456" + self.name = "fake-node" + self.properties = {"lease_uuid": "001", "cpu": "40"} + self.provision_state = "available" self.uuid = fake_uuid - self.resource_class = 'baremetal' - self.power_state = 'off' + self.resource_class = "baremetal" + self.power_state = "off" class FakeLease(object): def __init__(self): - self.uuid = '001' - self.project_id = '654321' + self.uuid = "001" + self.project_id = "654321" self.start_time = start + datetime.timedelta(days=5) self.end_time = start + datetime.timedelta(days=10) self.status = statuses.ACTIVE - self.offer_uuid = '534653c9-880d-4c2d-6d6d-f4f2a09e384' + self.offer_uuid = "534653c9-880d-4c2d-6d6d-f4f2a09e384" class TestIronicNode(base.TestCase): - def test_resource_type(self): test_ironic_node = ironic_node.IronicNode(fake_uuid) - self.assertEqual('ironic_node', test_ironic_node.resource_type) + self.assertEqual("ironic_node", test_ironic_node.resource_type) def test_get_uuid(self): test_ironic_node = ironic_node.IronicNode(fake_uuid) self.assertEqual(fake_uuid, test_ironic_node.get_uuid()) - @mock.patch('esi_leap.resource_objects.ironic_node.IronicNode._get_node') + @mock.patch("esi_leap.resource_objects.ironic_node.IronicNode._get_node") def test_get_name(self, mock_gn): test_ironic_node = ironic_node.IronicNode(fake_uuid) fake_get_node = FakeIronicNode() @@ -66,88 +65,90 @@ def test_get_name(self, mock_gn): self.assertEqual(fake_get_node.name, test_ironic_node.get_name()) mock_gn.assert_called_once() - @mock.patch.object(ironic_node, 'get_ironic_client', autospec=True) + @mock.patch.object(ironic_node, "get_ironic_client", autospec=True) def test_init_with_name(self, mock_gn): fake_get_node = FakeIronicNode() mock_gn.return_value.node.get.return_value = fake_get_node - test_ironic_node = ironic_node.IronicNode('node-name') + test_ironic_node = ironic_node.IronicNode("node-name") self.assertEqual(fake_uuid, test_ironic_node.get_uuid()) mock_gn.assert_called_once() - mock_gn.return_value.node.get.assert_called_once_with('node-name') + mock_gn.return_value.node.get.assert_called_once_with("node-name") - @mock.patch('esi_leap.resource_objects.ironic_node.IronicNode._get_node') + @mock.patch("esi_leap.resource_objects.ironic_node.IronicNode._get_node") def test_get_resource_class(self, mock_gn): test_ironic_node = ironic_node.IronicNode(fake_uuid) fake_get_node = FakeIronicNode() mock_gn.return_value = fake_get_node resource_class = test_ironic_node.get_resource_class() - self.assertEqual('baremetal', resource_class) + self.assertEqual("baremetal", resource_class) mock_gn.assert_called_once() - @mock.patch('esi_leap.resource_objects.ironic_node.IronicNode._get_node') + @mock.patch("esi_leap.resource_objects.ironic_node.IronicNode._get_node") def test_get_properties(self, mock_gn): fake_get_node = FakeIronicNode() mock_gn.return_value = fake_get_node test_ironic_node = ironic_node.IronicNode(fake_uuid) properties = test_ironic_node.get_properties() - expected_properties = {'cpu': '40'} + expected_properties = {"cpu": "40"} self.assertEqual(properties, expected_properties) mock_gn.assert_called_once() - @mock.patch('esi_leap.resource_objects.ironic_node.IronicNode._get_node') + @mock.patch("esi_leap.resource_objects.ironic_node.IronicNode._get_node") def test_get_owner_project_id(self, mock_gn): fake_get_node = FakeIronicNode() mock_gn.return_value = fake_get_node test_ironic_node = ironic_node.IronicNode(fake_uuid) - self.assertEqual(test_ironic_node.get_owner_project_id(), - fake_get_node.owner) + self.assertEqual(test_ironic_node.get_owner_project_id(), fake_get_node.owner) mock_gn.assert_called_once() - @mock.patch('esi_leap.resource_objects.ironic_node.IronicNode._get_node') + @mock.patch("esi_leap.resource_objects.ironic_node.IronicNode._get_node") def test_get_lease_uuid(self, mock_gn): fake_get_node = FakeIronicNode() mock_gn.return_value = fake_get_node test_ironic_node = ironic_node.IronicNode(fake_uuid) - self.assertEqual(test_ironic_node.get_lease_uuid(), - fake_get_node.properties.get('lease_uuid')) + self.assertEqual( + test_ironic_node.get_lease_uuid(), + fake_get_node.properties.get("lease_uuid"), + ) mock_gn.assert_called_once() - @mock.patch('esi_leap.resource_objects.ironic_node.IronicNode._get_node') + @mock.patch("esi_leap.resource_objects.ironic_node.IronicNode._get_node") def test_get_lessee_project_id(self, mock_gn): fake_get_node = FakeIronicNode() mock_gn.return_value = fake_get_node test_ironic_node = ironic_node.IronicNode(fake_uuid) - self.assertEqual(test_ironic_node.get_lessee_project_id(), - fake_get_node.lessee) + self.assertEqual(test_ironic_node.get_lessee_project_id(), fake_get_node.lessee) mock_gn.assert_called_once() - @mock.patch('esi_leap.resource_objects.ironic_node.IronicNode._get_node') + @mock.patch("esi_leap.resource_objects.ironic_node.IronicNode._get_node") def test_get_node_power_state(self, mock_gn): fake_get_node = FakeIronicNode() mock_gn.return_value = fake_get_node test_ironic_node = ironic_node.IronicNode(fake_uuid) - self.assertEqual(test_ironic_node.get_node_power_state(), - fake_get_node.power_state) + self.assertEqual( + test_ironic_node.get_node_power_state(), fake_get_node.power_state + ) mock_gn.assert_called_once() - @mock.patch('esi_leap.resource_objects.ironic_node.IronicNode._get_node') + @mock.patch("esi_leap.resource_objects.ironic_node.IronicNode._get_node") def test_get_node_provision_state(self, mock_gn): fake_get_node = FakeIronicNode() mock_gn.return_value = fake_get_node test_ironic_node = ironic_node.IronicNode(fake_uuid) - self.assertEqual(test_ironic_node.get_node_provision_state(), - fake_get_node.provision_state) + self.assertEqual( + test_ironic_node.get_node_provision_state(), fake_get_node.provision_state + ) mock_gn.assert_called_once() - @mock.patch.object(ironic_node, 'get_ironic_client', autospec=True) + @mock.patch.object(ironic_node, "get_ironic_client", autospec=True) def test_set_lease(self, client_mock): test_ironic_node = ironic_node.IronicNode(fake_uuid) fake_lease = FakeLease() @@ -155,22 +156,26 @@ def test_set_lease(self, client_mock): test_ironic_node.set_lease(fake_lease) client_mock.assert_called_once() client_mock.return_value.node.update.assert_called_once_with( - fake_uuid, [{'op': 'add', - 'path': '/properties/lease_uuid', - 'value': fake_lease.uuid}, - {'op': 'add', - 'path': '/lessee', - 'value': fake_lease.project_id}]) - - @mock.patch('esi_leap.resource_objects.ironic_node.IronicNode.' - 'get_lessee_project_id') - @mock.patch('esi_leap.resource_objects.ironic_node.IronicNode.' - 'get_lease_uuid') - @mock.patch('esi_leap.resource_objects.ironic_node.IronicNode._get_node') - @mock.patch.object(ironic_node, 'get_ironic_client', autospec=True) + fake_uuid, + [ + { + "op": "add", + "path": "/properties/lease_uuid", + "value": fake_lease.uuid, + }, + {"op": "add", "path": "/lessee", "value": fake_lease.project_id}, + ], + ) + + @mock.patch( + "esi_leap.resource_objects.ironic_node.IronicNode." "get_lessee_project_id" + ) + @mock.patch("esi_leap.resource_objects.ironic_node.IronicNode." "get_lease_uuid") + @mock.patch("esi_leap.resource_objects.ironic_node.IronicNode._get_node") + @mock.patch.object(ironic_node, "get_ironic_client", autospec=True) def test_remove_lease(self, mock_client, mock_gn, mock_glu, mock_glpi): fake_get_node = FakeIronicNode() - fake_get_node.provision_state = 'active' + fake_get_node.provision_state = "active" fake_lease = FakeLease() mock_gn.return_value = fake_get_node @@ -185,22 +190,26 @@ def test_remove_lease(self, mock_client, mock_gn, mock_glu, mock_glpi): self.assertEqual(mock_gn.call_count, 1) self.assertEqual(mock_client.call_count, 2) mock_client.return_value.node.update.assert_called_once_with( - fake_uuid, [{'op': 'remove', 'path': '/properties/lease_uuid'}, - {'op': 'remove', 'path': '/lessee'}]) - mock_client.return_value.node.set_provision_state. \ - assert_called_once_with(fake_uuid, 'deleted') - - @mock.patch('esi_leap.resource_objects.ironic_node.IronicNode.' - 'get_lease_uuid') + fake_uuid, + [ + {"op": "remove", "path": "/properties/lease_uuid"}, + {"op": "remove", "path": "/lessee"}, + ], + ) + mock_client.return_value.node.set_provision_state.assert_called_once_with( + fake_uuid, "deleted" + ) + + @mock.patch("esi_leap.resource_objects.ironic_node.IronicNode." "get_lease_uuid") def test_expire_lease_no_match(self, mock_glu): - mock_glu.return_value = 'none' + mock_glu.return_value = "none" test_ironic_node = ironic_node.IronicNode(fake_uuid) fake_lease = FakeLease() test_ironic_node.remove_lease(fake_lease) mock_glu.assert_called_once() - @mock.patch('esi_leap.common.ironic.get_node') + @mock.patch("esi_leap.common.ironic.get_node") def test_get_node(self, mock_gn): fake_get_node = FakeIronicNode() mock_gn.return_value = fake_get_node @@ -209,21 +218,19 @@ def test_get_node(self, mock_gn): self.assertEqual(test_ironic_node._get_node(), fake_get_node) mock_gn.assert_called_once_with(fake_uuid, None) - @mock.patch('esi_leap.common.ironic.get_node') + @mock.patch("esi_leap.common.ironic.get_node") def test_get_node_cache(self, mock_gn): fake_get_node = FakeIronicNode() mock_gn.return_value = fake_get_node test_ironic_node = ironic_node.IronicNode(fake_uuid) test_ironic_node._node = fake_get_node - self.assertEqual(fake_get_node, - test_ironic_node._get_node()) + self.assertEqual(fake_get_node, test_ironic_node._get_node()) mock_gn.assert_not_called() - @mock.patch('esi_leap.common.ironic.get_node') + @mock.patch("esi_leap.common.ironic.get_node") def test_get_unknown_node(self, mock_gn): mock_gn.side_effect = ir_exception.NotFound test_unknown_node = ironic_node.IronicNode(fake_uuid) - self.assertRaises(exception.NodeNotFound, - test_unknown_node._get_node) + self.assertRaises(exception.NodeNotFound, test_unknown_node._get_node) diff --git a/esi_leap/tests/resource_objects/test_resource_objects.py b/esi_leap/tests/resource_objects/test_resource_objects.py index 2f37c8ba..33a0f873 100644 --- a/esi_leap/tests/resource_objects/test_resource_objects.py +++ b/esi_leap/tests/resource_objects/test_resource_objects.py @@ -18,76 +18,79 @@ class TestResourceObjects(base.TestCase): - def test_get_type_valid(self): - types = {'ironic_node': resource_objects.ironic_node.IronicNode, - 'dummy_node': resource_objects.dummy_node.DummyNode, - 'test_node': resource_objects.test_node.TestNode} + types = { + "ironic_node": resource_objects.ironic_node.IronicNode, + "dummy_node": resource_objects.dummy_node.DummyNode, + "test_node": resource_objects.test_node.TestNode, + } for type_name, expected_type in types.items(): - self.assertEqual(resource_objects.get_type(type_name), - expected_type) + self.assertEqual(resource_objects.get_type(type_name), expected_type) def test_get_type_invalid(self): - invalid_types = ('ahhhh', '', 1234, None, True) + invalid_types = ("ahhhh", "", 1234, None, True) for type_name in invalid_types: - self.assertRaises(exception.ResourceTypeUnknown, - resource_objects.get_type, - type_name) + self.assertRaises( + exception.ResourceTypeUnknown, resource_objects.get_type, type_name + ) - @mock.patch('esi_leap.resource_objects.get_type') + @mock.patch("esi_leap.resource_objects.get_type") def test_get_resource_object(self, mock_gt): mock_type = mock.MagicMock() - mock_type.return_value = 'i have data!' + mock_type.return_value = "i have data!" mock_gt.return_value = mock_type - obj = resource_objects.get_resource_object('fake_node', 'data') + obj = resource_objects.get_resource_object("fake_node", "data") - self.assertEqual(obj, 'i have data!') - mock_type.assert_called_once_with('data') - mock_gt.assert_called_once_with('fake_node') + self.assertEqual(obj, "i have data!") + mock_type.assert_called_once_with("data") + mock_gt.assert_called_once_with("fake_node") - @mock.patch('esi_leap.resource_objects.ironic_node.is_uuid_like') + @mock.patch("esi_leap.resource_objects.ironic_node.is_uuid_like") def test_ironic_node(self, mock_iul): mock_iul.return_value = True - node = resource_objects.get_resource_object('ironic_node', '1111') + node = resource_objects.get_resource_object("ironic_node", "1111") - mock_iul.assert_called_once_with('1111') + mock_iul.assert_called_once_with("1111") self.assertIsInstance(node, resource_objects.ironic_node.IronicNode) - self.assertEqual('1111', node.get_uuid()) + self.assertEqual("1111", node.get_uuid()) - @mock.patch('esi_leap.resource_objects.ironic_node.get_ironic_client') - @mock.patch('esi_leap.resource_objects.ironic_node.is_uuid_like') + @mock.patch("esi_leap.resource_objects.ironic_node.get_ironic_client") + @mock.patch("esi_leap.resource_objects.ironic_node.is_uuid_like") def test_ironic_node_by_name(self, mock_iul, mock_gic): mock_ironic_client = mock.MagicMock() mock_ironic_node = mock.MagicMock() mock_uuid = mock.PropertyMock() - mock_uuid.return_value = '1111' + mock_uuid.return_value = "1111" type(mock_ironic_node).uuid = mock_uuid mock_ironic_client.node.get.return_value = mock_ironic_node mock_gic.return_value = mock_ironic_client mock_iul.return_value = False - node = resource_objects.get_resource_object('ironic_node', 'node-name') + node = resource_objects.get_resource_object("ironic_node", "node-name") - mock_iul.assert_called_with('node-name') + mock_iul.assert_called_with("node-name") mock_gic.assert_called_once_with() mock_uuid.assert_called_once_with() - mock_ironic_client.node.get.assert_called_once_with('node-name') + mock_ironic_client.node.get.assert_called_once_with("node-name") self.assertIsInstance(node, resource_objects.ironic_node.IronicNode) - self.assertEqual('1111', node.get_uuid()) + self.assertEqual("1111", node.get_uuid()) def test_dummy_node(self): - node = resource_objects.get_resource_object('dummy_node', '1111') + node = resource_objects.get_resource_object("dummy_node", "1111") self.assertIsInstance(node, resource_objects.dummy_node.DummyNode) - self.assertEqual('1111', node.get_uuid()) + self.assertEqual("1111", node.get_uuid()) def test_test_node(self): - node = resource_objects.get_resource_object('test_node', '1111') + node = resource_objects.get_resource_object("test_node", "1111") self.assertIsInstance(node, resource_objects.test_node.TestNode) - self.assertEqual('1111', node.get_uuid()) + self.assertEqual("1111", node.get_uuid()) def test_unknown_resource_type(self): - self.assertRaises(exception.ResourceTypeUnknown, - resource_objects.get_resource_object, - 'foo_node', '1111') + self.assertRaises( + exception.ResourceTypeUnknown, + resource_objects.get_resource_object, + "foo_node", + "1111", + ) diff --git a/esi_leap/tests/resource_objects/test_test_node.py b/esi_leap/tests/resource_objects/test_test_node.py index 754e35bf..2c681d2e 100644 --- a/esi_leap/tests/resource_objects/test_test_node.py +++ b/esi_leap/tests/resource_objects/test_test_node.py @@ -20,52 +20,51 @@ def get_test_lease(): return { - 'id': 12345, - 'name': 'c', - 'uuid': '534653c9-880d-4c2d-6d6d-11111111111', - 'project_id': 'le55ee', - 'start_time': start + datetime.timedelta(days=5), - 'end_time': start + datetime.timedelta(days=10), - 'fulfill_time': start + datetime.timedelta(days=5), - 'expire_time': start + datetime.timedelta(days=10), - 'status': statuses.CREATED, - 'properties': {}, - 'offer_uuid': '534653c9-880d-4c2d-6d6d-f4f2a09e384', - 'created_at': None, - 'updated_at': None + "id": 12345, + "name": "c", + "uuid": "534653c9-880d-4c2d-6d6d-11111111111", + "project_id": "le55ee", + "start_time": start + datetime.timedelta(days=5), + "end_time": start + datetime.timedelta(days=10), + "fulfill_time": start + datetime.timedelta(days=5), + "expire_time": start + datetime.timedelta(days=10), + "status": statuses.CREATED, + "properties": {}, + "offer_uuid": "534653c9-880d-4c2d-6d6d-f4f2a09e384", + "created_at": None, + "updated_at": None, } class TestTestNode(base.TestCase): - def setUp(self): super(TestTestNode, self).setUp() - self.fake_test_node = test_node.TestNode('1111', '123456') + self.fake_test_node = test_node.TestNode("1111", "123456") def test_resource_type(self): resource_type = self.fake_test_node.resource_type - self.assertEqual(resource_type, 'test_node') + self.assertEqual(resource_type, "test_node") def test_get_uuid(self): - self.assertEqual(self.fake_test_node.get_uuid(), '1111') + self.assertEqual(self.fake_test_node.get_uuid(), "1111") def test_get_name(self): - self.assertEqual(self.fake_test_node.get_name(), 'test-node-1111') + self.assertEqual(self.fake_test_node.get_name(), "test-node-1111") def test_get_resource_class(self): - self.assertEqual(self.fake_test_node.get_resource_class(), 'fake') + self.assertEqual(self.fake_test_node.get_resource_class(), "fake") def test_get_properties(self): self.assertEqual(self.fake_test_node.get_properties(), {}) def test_get_owner_project_id(self): - self.assertEqual(self.fake_test_node.get_owner_project_id(), '123456') + self.assertEqual(self.fake_test_node.get_owner_project_id(), "123456") def test_get_lease_uuid(self): - self.assertEqual(self.fake_test_node.get_lease_uuid(), '12345') + self.assertEqual(self.fake_test_node.get_lease_uuid(), "12345") def test_get_lessee_project_id(self): - self.assertEqual(self.fake_test_node.get_lessee_project_id(), '123456') + self.assertEqual(self.fake_test_node.get_lessee_project_id(), "123456") def test_set_lease(self): fake_lease = get_test_lease() @@ -76,8 +75,7 @@ def test_remove_lease(self): self.assertEqual(self.fake_test_node.remove_lease(fake_lease), None) def test_get_node_power_state(self): - self.assertEqual(self.fake_test_node.get_node_power_state(), 'Off') + self.assertEqual(self.fake_test_node.get_node_power_state(), "Off") def test_get_node_provision_state(self): - self.assertEqual(self.fake_test_node.get_node_provision_state(), - 'available') + self.assertEqual(self.fake_test_node.get_node_provision_state(), "available") diff --git a/esi_leap/version.py b/esi_leap/version.py index 31608ff8..737ebb80 100644 --- a/esi_leap/version.py +++ b/esi_leap/version.py @@ -12,4 +12,4 @@ from pbr import version -version_info = version.VersionInfo('esi-leap') +version_info = version.VersionInfo("esi-leap") diff --git a/setup.py b/setup.py index ac40c88f..212ec828 100644 --- a/setup.py +++ b/setup.py @@ -9,12 +9,14 @@ pass from pathlib import Path + this_directory = Path(__file__).parent long_description = (this_directory / "README.md").read_text() setuptools.setup( - setup_requires=['pbr>=2.0.0'], + setup_requires=["pbr>=2.0.0"], long_description=long_description, - long_description_content_type='text/markdown', - package_data={'esi_leap': ['templates/*']}, - pbr=True) + long_description_content_type="text/markdown", + package_data={"esi_leap": ["templates/*"]}, + pbr=True, +)