diff --git a/esi/lease/v1/_proxy.py b/esi/lease/v1/_proxy.py index 9cde520..0018d81 100644 --- a/esi/lease/v1/_proxy.py +++ b/esi/lease/v1/_proxy.py @@ -174,6 +174,19 @@ def create_lease(self, **attrs): """ return self._create(_lease.Lease, **attrs) + def update_lease(self, lease, **attrs): + """Update a lease. + + :param lease: The value can be the ID of a lease or a + :class:`~esi_leap.v1.lease.Lease` instance. + :param dict attrs: The attributes to update on the lease. + + :returns: The updated lease + :rtype: :class:`~esi_leap.v1.lease.Lease`. + """ + res = self._get_resource(_lease.Lease, lease) + return res.update(self, **attrs) + def get_lease(self, lease, fields=None): """Get a specific lease. diff --git a/esi/lease/v1/event.py b/esi/lease/v1/event.py index 004a962..825c03f 100644 --- a/esi/lease/v1/event.py +++ b/esi/lease/v1/event.py @@ -28,11 +28,12 @@ class Event(resource.Resource): # client-side query parameter _query_mapping = resource.QueryParameters( - 'ID', + 'last_event_id', 'event_type', - 'event_time', + 'last_event_time', 'resource_type', - 'resource_uuid' + 'resource_uuid', + 'lessee_or_owner_id' ) #: The transaction date and time. @@ -40,10 +41,10 @@ class Event(resource.Resource): #: The value of the resource. Also available in headers. id = resource.Body("id", alternate_id=True) event_type = resource.Body("event_type") - event_time = resource.Body("event_time") + last_event_id = resource.Body("last_event_id") + last_event_time = resource.Body("last_event_time") object_type = resource.Body("object_type") object_uuid = resource.Body("object_uuid") node_type = resource.Body("resource_type") resource_uuid = resource.Body("resource_uuid") - lease_id = resource.Body("lease_id") - owner_id = resource.Body("owner_id") + lessee_or_owner_id = resource.Body("lessee_or_owner_id") diff --git a/esi/lease/v1/lease.py b/esi/lease/v1/lease.py index 02c2dae..0d987c6 100644 --- a/esi/lease/v1/lease.py +++ b/esi/lease/v1/lease.py @@ -10,6 +10,7 @@ # License for the specific language governing permissions and limitations # under the License. +from openstack import exceptions from openstack import resource @@ -23,6 +24,7 @@ class Lease(resource.Resource): allow_commit = True allow_delete = True allow_list = True + allow_patch = True commit_method = 'PATCH' commit_jsonpatch = True @@ -32,6 +34,13 @@ class Lease(resource.Resource): 'resource_type', 'status', 'uuid', + 'project_id', + 'start_time', + 'end_time', + 'owner_id', + 'resource_class', + 'purpose', + 'properties', ) #: The transaction date and time. @@ -39,6 +48,7 @@ class Lease(resource.Resource): #: The value of the resource. Also available in headers. id = resource.Body("uuid", alternate_id=True) node_type = resource.Body("resource_type") + resource_name = resource.Body("resource") resource_id = resource.Body("resource_uuid") resource_class = resource.Body("resource_class") offer_uuid = resource.Body("offer_uuid") @@ -53,6 +63,32 @@ class Lease(resource.Resource): name = resource.Body("name") project = resource.Body("project") project_id = resource.Body("project_id") - lease_resource = resource.Body("resource") properties = resource.Body("properties") + resource_properties = resource.Body("resource_properties") purpose = resource.Body("purpose") + + def update(self, session, **kwargs): + """Update a lease. + + :param session: The session to use for making this request. + :type session: :class:`~keystoneauth1.adapter.Adapter` + + :returns: The result of update. + :rtype: Response json data. + """ + session = self._get_session(session) + + request = self._prepare_request(requires_id=True) + response = session.patch( + request.url, + json=kwargs, + headers=request.headers, + microversion=None, + retriable_status_codes=None, + ) + + msg = ( + "Failed to update lease {lease} ".format(lease=self.id) + ) + exceptions.raise_from_response(response, error_message=msg) + return response.json() diff --git a/esi/lease/v1/node.py b/esi/lease/v1/node.py index a991d56..0235c44 100644 --- a/esi/lease/v1/node.py +++ b/esi/lease/v1/node.py @@ -46,3 +46,5 @@ class Node(resource.Resource): lease_id = resource.Body("lease_uuid") future_offers = resource.Body("future_offers") future_leases = resource.Body("future_leases") + properties = resource.Body("properties") + resource_class = resource.Body("resource_class") diff --git a/esi/lease/v1/offer.py b/esi/lease/v1/offer.py index ede9e3e..2e02963 100644 --- a/esi/lease/v1/offer.py +++ b/esi/lease/v1/offer.py @@ -32,9 +32,18 @@ class Offer(resource.Resource): _query_mapping = resource.QueryParameters( 'resource_uuid', 'resource_type', + 'resource_class', 'status', 'uuid', 'lessee', + 'start_time', + 'end_time', + 'lessee_id', + 'name', + 'properties', + 'project_id', + 'available_start_time', + 'available_end_time', ) #: The transaction date and time. @@ -50,12 +59,14 @@ class Offer(resource.Resource): start_time = resource.Body("start_time") end_time = resource.Body("end_time") status = resource.Body("status") - availabilities = resource.Body("availabilities") + available_start_time = resource.Body("available_start_time") + available_end_time = resource.Body("available_end_time") name = resource.Body("name") project = resource.Body("project") project_id = resource.Body("project_id") - offer_resource = resource.Body("resource") + resource_name = resource.Body("resource") properties = resource.Body("properties") + resource_properties = resource.Body("resource_properties") def claim_offer(self, session, **kwargs): """Claim an offer. diff --git a/esi/tests/fakes.py b/esi/tests/fakes.py index dd2b853..1de4443 100644 --- a/esi/tests/fakes.py +++ b/esi/tests/fakes.py @@ -44,10 +44,10 @@ def __init__(self, id, offer_id, lease_id): class FakeEvent: - def __init__(self, id, event_type, event_time): + def __init__(self, id, event_type, last_event_time): self.id = id self.event_type = event_type - self.event_time = event_time + self.last_event_time = last_event_time def make_fake_offer(id, node_id, node_type): @@ -69,10 +69,10 @@ def make_fake_node(id, offer_id, lease_id): lease_id=lease_id)) -def make_fake_event(id, event_type, event_time): +def make_fake_event(id, event_type, last_event_time): return meta.obj_to_munch(FakeEvent(id=id, event_type=event_type, - event_time=event_time)) + last_event_time=last_event_time)) def get_lease_endpoint(): diff --git a/esi/tests/functional/lease/README.md b/esi/tests/functional/lease/README.md new file mode 100644 index 0000000..9ebfee1 --- /dev/null +++ b/esi/tests/functional/lease/README.md @@ -0,0 +1,25 @@ +### Prerequisites + +These tests are intended to be run against a functioning OpenStack cloud with esi-leap services enabled and running (https://github.com/CCI-MOC/esi-leap). Please set the following environment variables in order to run full tests: +* TestESILEAPLease and TestESILEAPOffer: set `NODE_1_UUID`, `NODE_1_TYPE`, `NODE_2_UUID`, `NODE_2_TYPE` in tox.ini. These nodes should not be associated with any existing leases/offers during testing. +* TestESILEAPEvent: set `LAST_EVENT_ID`, `NODE_1_UUID` and `NODE_1_TYPE` in tox.ini. +* TestESILEAPNode: set `NODE_3_NAME` in tox.ini. This node should be associated with leases/offers. + +The clouds.yaml file should be like this: https://github.com/openstack/openstacksdk/blob/master/doc/source/contributor/clouds.yaml + +### Running the tests + +By default, the functional tests will not run when invoking `tox` with no additional options. To run them, you must specify the 'functional' testenv like this: + +``` +$ tox -e functional +``` + +To run specific tests, +``` +$ tox -e functional -- "test_node_list" +``` +or +``` +$ tox -e functional -- "TestESILEAPOffer" +``` \ No newline at end of file diff --git a/esi/tests/functional/lease/base.py b/esi/tests/functional/lease/base.py index f8caf11..6878516 100644 --- a/esi/tests/functional/lease/base.py +++ b/esi/tests/functional/lease/base.py @@ -11,10 +11,15 @@ # under the License. from esi import connection - from openstack.tests.functional import base +#: Defines the OpenStack Client Config (OCC) cloud key in your OCC config +#: file, typically in $HOME/.config/openstack/clouds.yaml. That configuration +#: will determine where the functional tests will be run and what resource +#: defaults will be used to run the functional tests. + + class BaseESILEAPTest(base.BaseFunctionalTest): min_microversion = None diff --git a/esi/tests/functional/lease/test_esi_leap_event.py b/esi/tests/functional/lease/test_esi_leap_event.py index fae0d47..ac29256 100644 --- a/esi/tests/functional/lease/test_esi_leap_event.py +++ b/esi/tests/functional/lease/test_esi_leap_event.py @@ -11,24 +11,29 @@ # under the License. from esi.tests.functional.lease import base +import os class TestESILEAPEvent(base.BaseESILEAPTest): def setUp(self): super(TestESILEAPEvent, self).setUp() self.project_id = self.conn.session.get_project_id() + self.node_1_uuid = os.getenv('NODE_1_UUID') + self.node_1_type = os.getenv('NODE_1_TYPE') + self.last_event_id = os.getenv('LAST_EVENT_ID') def test_event_list(self): """ Tests functionality "esi event list" using node_uuid or node name. - checks node_uuid or node_name is present in node list or not. + checks node_uuid or node_name is present in event list or not. Test steps: 1) Create a lease for a node - 2) Checks that the output of "event list" contains + 2) Run event list with the last event id + 3) Checks that the output of "event list" contains the node uuid it's tested with. """ - self.create_lease('1719', + self.create_lease(self.node_1_uuid, self.project_id, - node_type='dummy_node') - events = self.conn.lease.events() + node_type=self.node_1_type) + events = self.conn.lease.events(last_event_id=self.last_event_id) self.assertNotEqual(events, []) - self.assertIn('1719', [x['resource_uuid'] for x in events]) + self.assertIn(self.node_1_uuid, [x['resource_uuid'] for x in events]) diff --git a/esi/tests/functional/lease/test_esi_leap_lease.py b/esi/tests/functional/lease/test_esi_leap_lease.py index 9879407..a8ba681 100644 --- a/esi/tests/functional/lease/test_esi_leap_lease.py +++ b/esi/tests/functional/lease/test_esi_leap_lease.py @@ -10,39 +10,44 @@ # License for the specific language governing permissions and limitations # under the License. -from datetime import datetime, timedelta +from datetime import datetime, timedelta, timezone from esi.tests.functional.lease import base from openstack import exceptions +import os class TestESILEAPLease(base.BaseESILEAPTest): def setUp(self): super(TestESILEAPLease, self).setUp() self.project_id = self.conn.session.get_project_id() + self.node_1_uuid = os.getenv('NODE_1_UUID') + self.node_1_type = os.getenv('NODE_1_TYPE') + self.node_2_uuid = os.getenv('NODE_2_UUID') + self.node_2_type = os.getenv('NODE_2_TYPE') def test_lease_create_show_delete(self): - time_now = datetime.now() + time_now = datetime.now(timezone.utc) start_time = time_now + timedelta(minutes=5) end_time = start_time + timedelta(minutes=30) - extra_fields = {"node_type": "dummy_node", + extra_fields = {"node_type": self.node_1_type, "start_time": start_time, "end_time": end_time} - lease = self.create_lease('1719', + lease = self.create_lease(self.node_1_uuid, self.project_id, **extra_fields) - self.assertEqual(lease.resource_id, '1719') + self.assertEqual(lease.resource_id, self.node_1_uuid) self.assertEqual(lease.project_id, self.project_id) - self.assertEqual(lease.node_type, 'dummy_node') + self.assertEqual(lease.node_type, self.node_1_type) loaded = self.conn.lease.get_lease(lease.id) self.assertEqual(loaded.id, lease.id) - self.assertEqual(loaded.resource_id, '1719') - self.assertEqual(loaded.node_type, 'dummy_node') + self.assertEqual(loaded.resource_id, self.node_1_uuid) + self.assertEqual(loaded.node_type, self.node_1_type) self.conn.lease.delete_lease(lease.id, ignore_missing=False) - leases = self.conn.lease.leases(resource_id='1719') + leases = self.conn.lease.leases(resource_id=self.node_1_uuid) self.assertNotIn(lease.id, [l.id for l in leases]) def test_lease_show_not_found(self): @@ -53,28 +58,57 @@ def test_lease_show_not_found(self): ) def test_lease_list(self): - time_now = datetime.now() + time_now = datetime.now(timezone.utc) start_time_1 = time_now + timedelta(minutes=5) end_time_1 = start_time_1 + timedelta(minutes=30) start_time_2 = end_time_1 + timedelta(minutes=5) end_time_2 = start_time_2 + timedelta(minutes=30) - lease1 = self.create_lease('1719', + lease1 = self.create_lease(self.node_1_uuid, self.project_id, - **{"node_type": "dummy_node", + **{"node_type": self.node_1_type, "start_time": start_time_1, "end_time": end_time_1}) - lease2 = self.create_lease('1719', + lease2 = self.create_lease(self.node_1_uuid, self.project_id, - **{"node_type": "dummy_node", + **{"node_type": self.node_1_type, "start_time": start_time_2, "end_time": end_time_2}) - lease3 = self.create_lease('1720', + lease3 = self.create_lease(self.node_2_uuid, self.project_id, - node_type='dummy_node') - leases_1719 = self.conn.lease.leases(resource_id='1719') - lease_id_list = [l.id for l in leases_1719] + node_type=self.node_2_type) + leases_node1 = self.conn.lease.leases(resource_id=self.node_1_uuid) + lease_id_list = [l.id for l in leases_node1] for lease_id in lease1.id, lease2.id: self.assertIn(lease_id, lease_id_list) - leases_1720 = self.conn.lease.leases(resource_id='1720') - self.assertEqual([l.id for l in leases_1720], [lease3.id]) + leases_node2 = self.conn.lease.leases(resource_id=self.node_2_uuid) + self.assertEqual([l.id for l in leases_node2], [lease3.id]) + + def test_lease_update_valid(self): + time_now = datetime.now(timezone.utc).replace(microsecond=0) + start_time = time_now + timedelta(minutes=5) + end_time = start_time + timedelta(minutes=30) + end_time_new = end_time + timedelta(minutes=30) + extra_fields = {"node_type": self.node_1_type, + "start_time": start_time, + "end_time": end_time} + lease = self.create_lease(self.node_1_uuid, + self.project_id, + **extra_fields) + updated_lease = self.conn.lease.update_lease(lease, end_time=end_time_new) + self.assertEqual(updated_lease.get("end_time"), end_time_new.isoformat()) + + def test_lease_update_invalid(self): + time_now = datetime.now(timezone.utc).replace(microsecond=0) + start_time = time_now + timedelta(minutes=5) + end_time = start_time + timedelta(minutes=30) + start_time_new = start_time + timedelta(minutes=10) + extra_fields = {"node_type": self.node_1_type, + "start_time": start_time, + "end_time": end_time} + lease = self.create_lease(self.node_1_uuid, + self.project_id, + **extra_fields) + self.assertRaises(exceptions.HttpException, + self.conn.lease.update_lease, + lease, start_time=start_time_new) diff --git a/esi/tests/functional/lease/test_esi_leap_node.py b/esi/tests/functional/lease/test_esi_leap_node.py index 2bb6f8f..65f7c69 100644 --- a/esi/tests/functional/lease/test_esi_leap_node.py +++ b/esi/tests/functional/lease/test_esi_leap_node.py @@ -23,18 +23,14 @@ def test_node_list(self): """ Tests functionality "esi node list" using node_uuid or node name. checks node_uuid or node_name is present in node list or not. Test steps: - 1) Set either of the environment variables using - export OS_FUNCTIONAL_NODE_UUID=node_uuid or - export OS_FUNCTIONAL_NODE_NAME=node_name + 1) Set the environment variables using + export NODE_3_NAME=node_name 2) Checks that the output of "node list" contains the node uuid or node name it's tested with. """ - node_uuid = os.getenv('OS_FUNCTIONAL_NODE_UUID') - node_name = os.getenv('OS_FUNCTIONAL_NODE_NAME') + node_name = os.getenv('NODE_3_NAME') nodes = self.conn.lease.nodes() self.assertNotEqual(nodes, []) - if node_uuid is not None: - self.assertIn(node_uuid, [x['UUID'] for x in nodes]) if node_name is not None: - self.assertIn(node_name, [x['Name'] for x in nodes]) + self.assertIn(node_name, [x.name for x in nodes]) diff --git a/esi/tests/functional/lease/test_esi_leap_offer.py b/esi/tests/functional/lease/test_esi_leap_offer.py index 667a6b7..8e64979 100644 --- a/esi/tests/functional/lease/test_esi_leap_offer.py +++ b/esi/tests/functional/lease/test_esi_leap_offer.py @@ -10,45 +10,51 @@ # License for the specific language governing permissions and limitations # under the License. -from datetime import datetime, timedelta +from datetime import datetime, timedelta, timezone from openstack import exceptions from esi.tests.functional.lease import base +import os + class TestESILEAPOffer(base.BaseESILEAPTest): def setUp(self): super(TestESILEAPOffer, self).setUp() self.project_id = self.conn.session.get_project_id() + self.node_1_uuid = os.getenv('NODE_1_UUID') + self.node_1_type = os.getenv('NODE_1_TYPE') + self.node_2_uuid = os.getenv('NODE_2_UUID') + self.node_2_type = os.getenv('NODE_2_TYPE') def test_offer_create_show_delete(self): - offer = self.create_offer('1719', 'dummy_node') + offer = self.create_offer(self.node_1_uuid, self.node_1_type) - self.assertEqual(offer.resource_id, '1719') - self.assertEqual(offer.node_type, 'dummy_node') + self.assertEqual(offer.resource_id, self.node_1_uuid) + self.assertEqual(offer.node_type, self.node_1_type) loaded = self.conn.lease.get_offer(offer.id) self.assertEqual(loaded.id, offer.id) - self.assertEqual(loaded.resource_id, '1719') - self.assertEqual(loaded.node_type, 'dummy_node') + self.assertEqual(loaded.resource_id, self.node_1_uuid) + self.assertEqual(loaded.node_type, self.node_1_type) self.conn.lease.delete_offer(offer.id, ignore_missing=False) - offers = self.conn.lease.offers(resource_id='1719') + offers = self.conn.lease.offers(resource_id=self.node_1_uuid) self.assertNotIn(offer.id, [o.id for o in offers]) def test_offer_create_detail(self): - time_now = datetime.now() + time_now = datetime.now(timezone.utc) start_time = time_now + timedelta(minutes=5) end_time = start_time + timedelta(minutes=30) extra_fields = {"lessee_id": self.project_id, "start_time": start_time, "end_time": end_time} - offer = self.create_offer('1719', 'dummy_node', **extra_fields) + offer = self.create_offer(self.node_1_uuid, self.node_1_type, **extra_fields) loaded = self.conn.lease.get_offer(offer.id) self.assertEqual(loaded.id, offer.id) - self.assertEqual(loaded.resource_id, '1719') - self.assertEqual(loaded.node_type, 'dummy_node') + self.assertEqual(loaded.resource_id, self.node_1_uuid) + self.assertEqual(loaded.node_type, self.node_1_type) self.assertEqual(loaded.lessee_id, self.project_id) def test_offer_show_not_found(self): @@ -59,37 +65,37 @@ def test_offer_show_not_found(self): ) def test_offer_list(self): - time_now = datetime.now() + time_now = datetime.now(timezone.utc) start_time_1 = time_now + timedelta(minutes=5) end_time_1 = start_time_1 + timedelta(minutes=30) start_time_2 = end_time_1 + timedelta(minutes=5) end_time_2 = start_time_2 + timedelta(minutes=30) - offer1 = self.create_offer('1719', 'dummy_node', + offer1 = self.create_offer(self.node_1_uuid, self.node_1_type, **{"start_time": start_time_1, "end_time": end_time_1}) - offer2 = self.create_offer('1719', 'dummy_node', + offer2 = self.create_offer(self.node_1_uuid, self.node_1_type, **{"start_time": start_time_2, "end_time": end_time_2}) - offer3 = self.create_offer('1720', 'dummy_node') + offer3 = self.create_offer(self.node_2_uuid, self.node_2_type) - offers_1719 = self.conn.lease.offers(resource_id='1719') - offer_id_list = [o.id for o in offers_1719] + offers_node1 = self.conn.lease.offers(resource_id=self.node_1_uuid) + offer_id_list = [o.id for o in offers_node1] self.assertEqual(len(offer_id_list), 2) for offer_id in offer1.id, offer2.id: self.assertIn(offer_id, offer_id_list) - offers_1720 = self.conn.lease.offers(resource_id='1720') - self.assertEqual([o.id for o in offers_1720], [offer3.id]) + offers_node2 = self.conn.lease.offers(resource_id=self.node_2_uuid) + self.assertEqual([o.id for o in offers_node2], [offer3.id]) def test_offer_claim(self): - offer = self.create_offer('1719', 'dummy_node') + offer = self.create_offer(self.node_1_uuid, self.node_1_type) fields = {"name": "new_lease"} lease = self.conn.lease.claim_offer(offer, **fields) self.assertNotEqual(lease, {}) def test_offer_claim_multiple(self): - offer = self.create_offer('1719', 'dummy_node') - time_now = datetime.now() + offer = self.create_offer(self.node_1_uuid, self.node_1_type) + time_now = datetime.now(timezone.utc) lease1_start_time = time_now + timedelta(minutes=5) lease1_end_time = lease1_start_time + timedelta(minutes=30) lease2_start_time = lease1_end_time + timedelta(minutes=5) @@ -106,7 +112,7 @@ def test_offer_claim_multiple(self): lease2 = self.conn.lease.claim_offer(offer, **new_lease2) self.assertNotEqual(lease2, {}) - lease_list = self.conn.lease.leases(resource_id='1719') + lease_list = self.conn.lease.leases(resource_id=self.node_1_uuid) uuid_list = [l.id for l in lease_list] self.assertNotEqual(lease_list, []) for lease_id in lease1["uuid"], lease2["uuid"]: diff --git a/esi/tests/unit/base.py b/esi/tests/unit/base.py deleted file mode 100644 index e69de29..0000000 diff --git a/esi/tests/unit/lease/v1/test_event.py b/esi/tests/unit/lease/v1/test_event.py index de2addc..8af41ae 100644 --- a/esi/tests/unit/lease/v1/test_event.py +++ b/esi/tests/unit/lease/v1/test_event.py @@ -19,9 +19,9 @@ FAKE = {'id': 'abc_001', 'event_type': 'notification', - 'event_time': event_time, - 'lease_id': 'lease_id', - 'owner_id': 'owner_id', + 'last_event_time': event_time, + 'last_event_id': '001', + 'lessee_or_owner_id': 'lease_or_id', 'object_type': 'offer', 'object_uuid': 'offer_001', 'resource_type': 'baremetal', @@ -46,9 +46,12 @@ def test_instantiate(self): e = event.Event(**FAKE) self.assertEqual(FAKE['id'], e.id) self.assertEqual(FAKE['event_type'], e.event_type) - self.assertEqual(FAKE['event_time'], e.event_time) - self.assertEqual(FAKE['lease_id'], e.lease_id) - self.assertEqual(FAKE['owner_id'], e.owner_id) + self.assertEqual(FAKE['last_event_time'], + e.last_event_time) + self.assertEqual(FAKE['last_event_id'], + e.last_event_id) + self.assertEqual(FAKE['lessee_or_owner_id'], + e.lessee_or_owner_id) self.assertEqual(FAKE['object_type'], e.object_type) self.assertEqual(FAKE['object_uuid'], e.object_uuid) self.assertEqual(FAKE['resource_type'], e.node_type) diff --git a/esi/tests/unit/lease/v1/test_lease.py b/esi/tests/unit/lease/v1/test_lease.py index 4d6c9b7..0f8bc03 100644 --- a/esi/tests/unit/lease/v1/test_lease.py +++ b/esi/tests/unit/lease/v1/test_lease.py @@ -13,7 +13,11 @@ import datetime from esi.lease.v1 import lease +from keystoneauth1 import adapter + +from openstack import exceptions from openstack.tests.unit import base +from unittest import mock start = datetime.datetime(2016, 7, 16, 19, 20, 30) FAKE = {'uuid': 'lease_uuid', @@ -32,9 +36,10 @@ 'name': 'offer_name', 'project': 'project_name', 'project_id': 'project_id', - 'resource': 'resource', 'properties': None, 'purpose': 'test', + 'resource_properties': None, + 'resource_name': 'node-1819' } @@ -48,6 +53,7 @@ def test_basic(self): self.assertTrue(l.allow_fetch) self.assertTrue(l.allow_commit) self.assertTrue(l.allow_delete) + self.assertTrue(l.allow_patch) self.assertTrue(l.allow_list) self.assertEqual('PATCH', l.commit_method) @@ -66,6 +72,27 @@ def test_instantiate(self): self.assertEqual(FAKE['name'], l.name) self.assertEqual(FAKE['project'], l.project) self.assertEqual(FAKE['project_id'], l.project_id) - self.assertEqual(FAKE['resource'], l.lease_resource) self.assertEqual(FAKE['properties'], l.properties) self.assertEqual(FAKE['purpose'], l.purpose) + self.assertEqual(FAKE['resource_properties'], l.resource_properties) + self.assertEqual(FAKE['resource_name'], l.resource_name) + + +@mock.patch.object(exceptions, 'raise_from_response', mock.Mock()) +class TestLeaseUpdate(object): + def setUp(self): + super(TestLeaseUpdate, self).setUp() + self.lease = lease.Lease(**FAKE) + self.session = lease.Mock( + spec=adapter.Adapter, default_microversion=None + ) + self.session.log = mock.Mock() + + def test_update_lease(self): + self.lease.update(self.session) + self.session.get.assert_called_once_with( + 'lease/%s' % self.lease.id, + headers=mock.ANY, + microversion=None, + retriable_status_codes=None, + ) diff --git a/esi/tests/unit/lease/v1/test_node.py b/esi/tests/unit/lease/v1/test_node.py index c17e9a0..32fd1f0 100644 --- a/esi/tests/unit/lease/v1/test_node.py +++ b/esi/tests/unit/lease/v1/test_node.py @@ -23,6 +23,8 @@ 'lease_uuid': 'lease_001', 'future_offers': None, 'future_leases': None, + 'resource_class': 'test', + 'properties': None } @@ -50,3 +52,5 @@ def test_instantiate(self): self.assertEqual(FAKE['lease_uuid'], n.lease_id) self.assertEqual(FAKE['future_offers'], n.future_offers) self.assertEqual(FAKE['future_leases'], n.future_leases) + self.assertEqual(FAKE['resource_class'], n.resource_class) + self.assertEqual(FAKE['properties'], n.properties) diff --git a/esi/tests/unit/lease/v1/test_offer.py b/esi/tests/unit/lease/v1/test_offer.py index c8018a4..6ac68e0 100644 --- a/esi/tests/unit/lease/v1/test_offer.py +++ b/esi/tests/unit/lease/v1/test_offer.py @@ -31,12 +31,14 @@ 'start_time': start, 'end_time': start + datetime.timedelta(days=100), 'status': 'available', - 'availabilities': 'Availabilities', + 'available_start_time': start, + 'available_end_time': start + datetime.timedelta(days=101), 'name': 'offer_name', 'project': 'project_name', 'project_id': 'project_id', - 'resource': 'resource', + 'resource_name': 'resource', 'properties': None, + 'resource_properties': None } @@ -65,12 +67,17 @@ def test_instantiate(self): self.assertEqual(FAKE['start_time'], o.start_time) self.assertEqual(FAKE['end_time'], o.end_time) self.assertEqual(FAKE['status'], o.status) - self.assertEqual(FAKE['availabilities'], o.availabilities) + self.assertEqual(FAKE['available_start_time'], + o.available_start_time) + self.assertEqual(FAKE['available_end_time'], + o.available_end_time) self.assertEqual(FAKE['name'], o.name) self.assertEqual(FAKE['project'], o.project) self.assertEqual(FAKE['project_id'], o.project_id) - self.assertEqual(FAKE['resource'], o.offer_resource) + self.assertEqual(FAKE['resource_name'], o.resource_name) self.assertEqual(FAKE['properties'], o.properties) + self.assertEqual(FAKE['resource_properties'], + o.resource_properties) @mock.patch.object(exceptions, 'raise_from_response', mock.Mock()) diff --git a/examples/__init__.py b/examples/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/setup.cfg b/setup.cfg index e2c9eea..e3a2e27 100644 --- a/setup.cfg +++ b/setup.cfg @@ -23,7 +23,4 @@ python_requires = >=3.6 [files] packages = - esisdk - -# [entry_points] - + esi diff --git a/test-requirements.txt b/test-requirements.txt index db7622a..ea97f63 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -16,4 +16,4 @@ statsd>=3.3.0 stestr>=1.0.0 # Apache-2.0 testscenarios>=0.4 # Apache-2.0/BSD testtools>=2.2.0 # MIT -pylibmc \ No newline at end of file +importlib-metadata<5.0.0; python_version<'3.8' # Apache-2.0 diff --git a/tox.ini b/tox.ini index dcd6538..f000613 100644 --- a/tox.ini +++ b/tox.ini @@ -34,7 +34,15 @@ setenv = OS_TEST_TIMEOUT=600 OPENSTACKSDK_FUNC_TEST_TIMEOUT_LOAD_BALANCER=600 OPENSTACKSDK_EXAMPLE_CONFIG_KEY=functional - OPENSTACKSDK_FUNC_TEST_TIMEOUT_PROJECT_CLEANUP=1200 + OPENSTACKSDK_FUNC_TEST_TIMEOUT_PROJECT_CLEANUP=120 + # TODO: edit the values here + NODE_1_UUID=d62347eb-2f7a-4887-a13f-c4d4e87bdd06 + NODE_1_TYPE=ironic_node + NODE_2_UUID=697f1cd0-60ec-426e-bdd8-e75e915b2de0 + NODE_2_TYPE=ironic_node + LAST_EVENT_ID=3035 + NODE_3_NAME=oct4-12 + commands = stestr --test-path ./esi/tests/functional/ run --serial {posargs} stestr slowest