Skip to content

Commit

Permalink
updates to object attributes, addition of functional tests
Browse files Browse the repository at this point in the history
  • Loading branch information
DanNiESh committed Apr 24, 2024
1 parent 6f2b419 commit 278b0be
Show file tree
Hide file tree
Showing 21 changed files with 269 additions and 89 deletions.
13 changes: 13 additions & 0 deletions esi/lease/v1/_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
13 changes: 7 additions & 6 deletions esi/lease/v1/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,23 @@ 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.
timestamp = resource.Header("x-timestamp")
#: 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")
38 changes: 37 additions & 1 deletion esi/lease/v1/lease.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
# License for the specific language governing permissions and limitations
# under the License.

from openstack import exceptions
from openstack import resource


Expand All @@ -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

Expand All @@ -32,13 +34,21 @@ 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.
timestamp = resource.Header("x-timestamp")
#: 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")
Expand All @@ -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()
2 changes: 2 additions & 0 deletions esi/lease/v1/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
15 changes: 13 additions & 2 deletions esi/lease/v1/offer.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
Expand Down
8 changes: 4 additions & 4 deletions esi/tests/fakes.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand All @@ -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():
Expand Down
25 changes: 25 additions & 0 deletions esi/tests/functional/lease/README.md
Original file line number Diff line number Diff line change
@@ -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"
```
7 changes: 6 additions & 1 deletion esi/tests/functional/lease/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
17 changes: 11 additions & 6 deletions esi/tests/functional/lease/test_esi_leap_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -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])
74 changes: 54 additions & 20 deletions esi/tests/functional/lease/test_esi_leap_lease.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand All @@ -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)
Loading

0 comments on commit 278b0be

Please sign in to comment.