Skip to content

Commit f8c2215

Browse files
committed
added __str__ for Instance, Volumes, Images, added spot test
1 parent 1dcd06d commit f8c2215

6 files changed

Lines changed: 95 additions & 0 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ We use pytest for testing.
134134

135135
### Local Manual Testing
136136

137+
Create this file in the root directory of the project:
138+
137139
```python
138140
from datacrunch.datacrunch import DataCrunchClient
139141

datacrunch/helpers.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from typing import Type
2+
import json
3+
4+
def stringify_class_object_properties(class_object: Type) -> str:
5+
"""Generates a json string representation of a class object's properties and values
6+
7+
:param class_object: An instance of a class
8+
:type class_object: Type
9+
:return: _description_
10+
:rtype: json string representation of a class object's properties and values
11+
"""
12+
class_properties = {property: getattr(class_object, property, '') for property in class_object.__dir__() if property[:1] != '_' and type(getattr(class_object, property, '')).__name__ != 'method'}
13+
return json.dumps(class_properties, indent=2)

datacrunch/images/images.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from typing import List
2+
from datacrunch.helpers import stringify_class_object_properties
23

34
IMAGES_ENDPOINT = '/images'
45

@@ -59,6 +60,14 @@ def details(self) -> List[str]:
5960
"""
6061
return self._details
6162

63+
def __str__(self) -> str:
64+
"""Returns a string of the json representation of the image
65+
66+
:return: json representation of the image
67+
:rtype: str
68+
"""
69+
return stringify_class_object_properties(self)
70+
6271

6372
class ImagesService:
6473
"""A service for interacting with the images endpoint"""

datacrunch/instances/instances.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from typing import List, Union, Optional, Dict
2+
from datacrunch.helpers import stringify_class_object_properties
23

34
INSTANCES_ENDPOINT = '/instances'
45

@@ -259,6 +260,14 @@ def is_spot(self) -> bool:
259260
"""
260261
return self._is_spot
261262

263+
def __str__(self) -> str:
264+
"""Returns a string of the json representation of the instance
265+
266+
:return: json representation of the instance
267+
:rtype: str
268+
"""
269+
return stringify_class_object_properties(self)
270+
262271
class InstancesService:
263272
"""A service for interacting with the instances endpoint"""
264273

datacrunch/volumes/volumes.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from typing import List, Union, Optional
22
from datacrunch.constants import VolumeActions
3+
from datacrunch.helpers import stringify_class_object_properties
34

45
VOLUMES_ENDPOINT = '/volumes'
56

@@ -157,6 +158,14 @@ def ssh_key_ids(self) -> List[str]:
157158
"""
158159
return self._ssh_key_ids
159160

161+
def __str__(self) -> str:
162+
"""Returns a string of the json representation of the volume
163+
164+
:return: json representation of the volume
165+
:rtype: str
166+
"""
167+
return stringify_class_object_properties(self)
168+
160169
class VolumesService:
161170
"""A service for interacting with the volumes endpoint"""
162171

tests/unit_tests/instances/test_instances.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@
6060
}
6161
]
6262

63+
PAYLOAD_SPOT = PAYLOAD
64+
PAYLOAD_SPOT[0]["is_spot"] = True
6365

6466
class TestInstancesService:
6567
@pytest.fixture
@@ -261,6 +263,57 @@ def test_create_instance_successful(self, instances_service, endpoint):
261263
assert responses.assert_call_count(endpoint, 1) is True
262264
assert responses.assert_call_count(url, 1) is True
263265

266+
def test_create_spot_instance_successful(self, instances_service, endpoint):
267+
# arrange - add response mock
268+
# add response mock for the create instance endpoint
269+
responses.add(
270+
responses.POST,
271+
endpoint,
272+
body=INSTANCE_ID,
273+
status=200
274+
)
275+
# add response mock for the get instance by id endpoint
276+
url = endpoint + '/' + INSTANCE_ID
277+
responses.add(
278+
responses.GET,
279+
url,
280+
json=PAYLOAD_SPOT[0],
281+
status=200
282+
)
283+
284+
# act
285+
instance = instances_service.create(
286+
instance_type=INSTANCE_TYPE,
287+
image=INSTANCE_IMAGE,
288+
ssh_key_ids=[SSH_KEY_ID],
289+
hostname=INSTANCE_HOSTNAME,
290+
description=INSTANCE_DESCRIPTION,
291+
os_volume=INSTANCE_OS_VOLUME
292+
)
293+
294+
# assert
295+
assert type(instance) == Instance
296+
assert instance.id == INSTANCE_ID
297+
assert instance.ssh_key_ids == [SSH_KEY_ID]
298+
assert instance.status == INSTANCE_STATUS
299+
assert instance.image == INSTANCE_IMAGE
300+
assert instance.instance_type == INSTANCE_TYPE
301+
assert instance.price_per_hour == INSTANCE_PRICE_PER_HOUR
302+
assert instance.location == INSTANCE_LOCATION
303+
assert instance.description == INSTANCE_DESCRIPTION
304+
assert instance.hostname == INSTANCE_HOSTNAME
305+
assert instance.ip == INSTANCE_IP
306+
assert instance.created_at == INSTANCE_CREATED_AT
307+
assert instance.os_volume_id == OS_VOLUME_ID
308+
assert instance.is_spot == True
309+
assert type(instance.cpu) == dict
310+
assert type(instance.gpu) == dict
311+
assert type(instance.memory) == dict
312+
assert type(instance.gpu_memory) == dict
313+
assert type(instance.storage) == dict
314+
assert responses.assert_call_count(endpoint, 1) is True
315+
assert responses.assert_call_count(url, 1) is True
316+
264317
def test_create_instance_attached_os_volume_successful(self, instances_service, endpoint):
265318
# arrange - add response mock
266319
# create instance

0 commit comments

Comments
 (0)