From 9d5646678fd916ebbfda770eaebcd9a3dc3fdb61 Mon Sep 17 00:00:00 2001 From: Lars Kellogg-Stedman Date: Fri, 12 Jul 2024 16:55:01 -0400 Subject: [PATCH 1/3] Add pre-commit configuration and workflow Add a pre-commit [1] configuration in `.pre-commit-config.yaml` and a corresponding GitHub workflow to run the checks on pull requests. The pre-commit checks use ruff [2] for both linting and formatting. Developers should integrate these checks into their local workflow by installing pre-commit and running `pre-commit install` to enable the local pre-commit hook. Note that we have removed `tox -e pep8` from the existing test workflow, since there's no reason to run the linting as part of the Python version matrix. [1]: https://pre-commit.com/ [2]: https://docs.astral.sh/ruff/ --- .github/workflows/precommit.yaml | 31 +++++++++++++++++++ .../workflows/{tests.yml => unit-tests.yaml} | 2 -- .pre-commit-config.yaml | 24 ++++++++++++++ 3 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/precommit.yaml rename .github/workflows/{tests.yml => unit-tests.yaml} (92%) create mode 100644 .pre-commit-config.yaml 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 From b8585c40acb757f6fb977206e0703113aaf77301 Mon Sep 17 00:00:00 2001 From: Lars Kellogg-Stedman Date: Fri, 12 Jul 2024 17:02:04 -0400 Subject: [PATCH 2/3] Fix linting and formatting errors reported by pre-commit This commit consists of the changes introduced by using ruff to format all the source files in the repository and the changes necessary to correct any linting errors reported by ruff. --- LICENSE | 1 - babel.cfg | 1 - docs/esi-leap-api-ref.md | 18 +- docs/esi-leap-reporting.md | 2 +- docs/esi-leap-requirements.md | 8 +- esi_leap/api/app.py | 12 +- esi_leap/api/controllers/base.py | 1 - esi_leap/api/controllers/root.py | 20 +- esi_leap/api/controllers/types.py | 26 +- esi_leap/api/controllers/v1/event.py | 69 +- esi_leap/api/controllers/v1/lease.py | 242 +++-- esi_leap/api/controllers/v1/node.py | 99 +- esi_leap/api/controllers/v1/offer.py | 214 ++-- esi_leap/api/controllers/v1/root.py | 18 +- esi_leap/api/controllers/v1/utils.py | 92 +- esi_leap/api/service.py | 11 +- esi_leap/api/wsgi.py | 4 +- esi_leap/cmd/api.py | 4 +- esi_leap/cmd/dbsync.py | 45 +- esi_leap/cmd/manager.py | 4 +- esi_leap/common/constants.py | 2 +- esi_leap/common/exception.py | 130 ++- esi_leap/common/i18n.py | 2 +- esi_leap/common/ironic.py | 19 +- esi_leap/common/keystone.py | 15 +- esi_leap/common/notification_utils.py | 116 ++- esi_leap/common/policy.py | 173 ++-- esi_leap/common/rpc.py | 17 +- esi_leap/common/service.py | 14 +- esi_leap/common/statuses.py | 18 +- esi_leap/common/utils.py | 4 +- esi_leap/conf/__init__.py | 2 +- esi_leap/conf/api.py | 20 +- esi_leap/conf/dummy_node.py | 4 +- esi_leap/conf/ironic.py | 17 +- esi_leap/conf/keystone.py | 17 +- esi_leap/conf/netconf.py | 2 +- esi_leap/conf/notification.py | 39 +- esi_leap/conf/opts.py | 14 +- esi_leap/conf/pecan.py | 11 +- esi_leap/db/api.py | 38 +- esi_leap/db/migration.py | 7 +- esi_leap/db/sqlalchemy/alembic/env.py | 4 +- .../a1ea63fec697_create_events_table.py | 44 +- esi_leap/db/sqlalchemy/api.py | 281 ++--- esi_leap/db/sqlalchemy/migration.py | 13 +- esi_leap/db/sqlalchemy/models.py | 60 +- esi_leap/manager/rpcapi.py | 4 +- esi_leap/manager/service.py | 87 +- esi_leap/manager/utils.py | 13 +- esi_leap/objects/__init__.py | 6 +- esi_leap/objects/base.py | 17 +- esi_leap/objects/event.py | 20 +- esi_leap/objects/fields.py | 24 +- esi_leap/objects/lease.py | 348 +++---- esi_leap/objects/notification.py | 77 +- esi_leap/objects/offer.py | 112 +- esi_leap/resource_objects/__init__.py | 5 +- esi_leap/resource_objects/base.py | 2 +- esi_leap/resource_objects/dummy_node.py | 94 +- esi_leap/resource_objects/error.py | 18 +- esi_leap/resource_objects/ironic_node.py | 140 ++- esi_leap/resource_objects/test_node.py | 15 +- esi_leap/send_email_notification.py | 108 +- esi_leap/templates/lease_create_email.txt | 2 +- esi_leap/templates/lease_expire_email.txt | 2 +- esi_leap/tests/api/base.py | 127 ++- esi_leap/tests/api/controllers/test_types.py | 22 +- .../tests/api/controllers/v1/test_event.py | 69 +- .../tests/api/controllers/v1/test_lease.py | 978 +++++++++--------- .../tests/api/controllers/v1/test_node.py | 91 +- .../tests/api/controllers/v1/test_offer.py | 745 +++++++------ .../tests/api/controllers/v1/test_utils.py | 707 +++++++------ esi_leap/tests/base.py | 25 +- esi_leap/tests/common/test_ironic.py | 35 +- esi_leap/tests/common/test_keystone.py | 66 +- .../tests/common/test_notification_utils.py | 57 +- esi_leap/tests/common/test_policy.py | 25 +- esi_leap/tests/common/test_rpc.py | 96 +- esi_leap/tests/common/test_utils.py | 12 +- esi_leap/tests/db/sqlalchemy/test_api.py | 874 +++++++++------- esi_leap/tests/manager/test_service.py | 179 ++-- esi_leap/tests/objects/test_event.py | 46 +- esi_leap/tests/objects/test_fields.py | 41 +- esi_leap/tests/objects/test_lease.py | 912 +++++++++------- esi_leap/tests/objects/test_notification.py | 293 +++--- esi_leap/tests/objects/test_offer.py | 273 ++--- esi_leap/tests/resource_objects/test_base.py | 6 +- .../tests/resource_objects/test_dummy_node.py | 106 +- .../resource_objects/test_ironic_node.py | 139 +-- .../resource_objects/test_resource_objects.py | 71 +- .../tests/resource_objects/test_test_node.py | 48 +- esi_leap/version.py | 2 +- setup.py | 10 +- 94 files changed, 4902 insertions(+), 4221 deletions(-) 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/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, +) From f2916f4ddeeca2476d00b3e0f017fb56d4b9a167 Mon Sep 17 00:00:00 2001 From: Lars Kellogg-Stedman Date: Tue, 16 Jul 2024 09:28:30 -0400 Subject: [PATCH 3/3] Add documentation about linters to README --- README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) 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