datacrunch 1.14.0__py3-none-any.whl → 1.16.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- datacrunch/InferenceClient/inference_client.py +200 -65
- datacrunch/__init__.py +2 -0
- datacrunch/_version.py +6 -0
- datacrunch/authentication/authentication.py +7 -14
- datacrunch/balance/balance.py +1 -3
- datacrunch/constants.py +19 -17
- datacrunch/containers/containers.py +151 -123
- datacrunch/datacrunch.py +18 -18
- datacrunch/helpers.py +7 -2
- datacrunch/http_client/http_client.py +14 -14
- datacrunch/images/images.py +9 -3
- datacrunch/instance_types/instance_types.py +42 -35
- datacrunch/instances/instances.py +74 -53
- datacrunch/locations/locations.py +1 -2
- datacrunch/ssh_keys/ssh_keys.py +3 -4
- datacrunch/startup_scripts/startup_scripts.py +10 -8
- datacrunch/volume_types/volume_types.py +10 -8
- datacrunch/volumes/volumes.py +60 -73
- {datacrunch-1.14.0.dist-info → datacrunch-1.16.0.dist-info}/METADATA +46 -72
- datacrunch-1.16.0.dist-info/RECORD +35 -0
- datacrunch-1.16.0.dist-info/WHEEL +4 -0
- datacrunch/__version__.py +0 -1
- datacrunch-1.14.0.dist-info/RECORD +0 -69
- datacrunch-1.14.0.dist-info/WHEEL +0 -5
- datacrunch-1.14.0.dist-info/licenses/LICENSE +0 -21
- datacrunch-1.14.0.dist-info/top_level.txt +0 -2
- tests/__init__.py +0 -0
- tests/integration_tests/__init__.py +0 -0
- tests/integration_tests/conftest.py +0 -20
- tests/integration_tests/test_instances.py +0 -36
- tests/integration_tests/test_locations.py +0 -65
- tests/integration_tests/test_volumes.py +0 -94
- tests/unit_tests/__init__.py +0 -0
- tests/unit_tests/authentication/__init__.py +0 -0
- tests/unit_tests/authentication/test_authentication.py +0 -202
- tests/unit_tests/balance/__init__.py +0 -0
- tests/unit_tests/balance/test_balance.py +0 -25
- tests/unit_tests/conftest.py +0 -21
- tests/unit_tests/containers/__init__.py +0 -1
- tests/unit_tests/containers/test_containers.py +0 -959
- tests/unit_tests/http_client/__init__.py +0 -0
- tests/unit_tests/http_client/test_http_client.py +0 -193
- tests/unit_tests/images/__init__.py +0 -0
- tests/unit_tests/images/test_images.py +0 -41
- tests/unit_tests/instance_types/__init__.py +0 -0
- tests/unit_tests/instance_types/test_instance_types.py +0 -87
- tests/unit_tests/instances/__init__.py +0 -0
- tests/unit_tests/instances/test_instances.py +0 -483
- tests/unit_tests/ssh_keys/__init__.py +0 -0
- tests/unit_tests/ssh_keys/test_ssh_keys.py +0 -198
- tests/unit_tests/startup_scripts/__init__.py +0 -0
- tests/unit_tests/startup_scripts/test_startup_scripts.py +0 -196
- tests/unit_tests/test_datacrunch.py +0 -65
- tests/unit_tests/test_exceptions.py +0 -33
- tests/unit_tests/volume_types/__init__.py +0 -0
- tests/unit_tests/volume_types/test_volume_types.py +0 -50
- tests/unit_tests/volumes/__init__.py +0 -0
- tests/unit_tests/volumes/test_volumes.py +0 -641
|
@@ -1,483 +0,0 @@
|
|
|
1
|
-
import pytest
|
|
2
|
-
import responses # https://github.com/getsentry/responses
|
|
3
|
-
|
|
4
|
-
from datacrunch.exceptions import APIException
|
|
5
|
-
from datacrunch.instances.instances import InstancesService, Instance
|
|
6
|
-
from datacrunch.constants import Actions, ErrorCodes, Locations
|
|
7
|
-
|
|
8
|
-
INVALID_REQUEST = ErrorCodes.INVALID_REQUEST
|
|
9
|
-
INVALID_REQUEST_MESSAGE = 'Your existence is invalid'
|
|
10
|
-
|
|
11
|
-
INSTANCE_ID = 'deadc0de-a5d2-4972-ae4e-d429115d055b'
|
|
12
|
-
SSH_KEY_ID = '12345dc1-a5d2-4972-ae4e-d429115d055b'
|
|
13
|
-
OS_VOLUME_ID = '46fc0247-8f65-4d8a-ad73-852a8b3dc1d3'
|
|
14
|
-
|
|
15
|
-
INSTANCE_TYPE = "1V100.6V"
|
|
16
|
-
INSTANCE_IMAGE = "ubuntu-24.04-cuda-12.8-open-docker"
|
|
17
|
-
INSTANCE_HOSTNAME = "I'll be your host for today"
|
|
18
|
-
INSTANCE_DESCRIPTION = "hope you enjoy your GPU"
|
|
19
|
-
INSTANCE_STATUS = 'running'
|
|
20
|
-
INSTANCE_PRICE_PER_HOUR = 0.60
|
|
21
|
-
INSTANCE_LOCATION = Locations.FIN_01
|
|
22
|
-
INSTANCE_IP = '1.2.3.4'
|
|
23
|
-
INSTANCE_CREATED_AT = "whatchalookingatboy?"
|
|
24
|
-
INSTANCE_OS_VOLUME = {"name": "os volume", "size": 50}
|
|
25
|
-
|
|
26
|
-
PAYLOAD = [
|
|
27
|
-
{
|
|
28
|
-
"created_at": INSTANCE_CREATED_AT,
|
|
29
|
-
"status": INSTANCE_STATUS,
|
|
30
|
-
"ip": INSTANCE_IP,
|
|
31
|
-
"cpu": {
|
|
32
|
-
"description": "super-duper-cpu",
|
|
33
|
-
"number_of_cores": 6
|
|
34
|
-
},
|
|
35
|
-
"gpu": {
|
|
36
|
-
"description": "super-duper-gpu",
|
|
37
|
-
"number_of_gpus": 1
|
|
38
|
-
},
|
|
39
|
-
"memory": {
|
|
40
|
-
"description": "super-duper-memory",
|
|
41
|
-
"size_in_gigabytes": 32
|
|
42
|
-
},
|
|
43
|
-
"gpu_memory": {
|
|
44
|
-
"description": "super-duper-memory",
|
|
45
|
-
"size_in_gigabytes": 20
|
|
46
|
-
},
|
|
47
|
-
"storage": {
|
|
48
|
-
"description": "super-duper-storage",
|
|
49
|
-
"size_in_gigabytes": 320
|
|
50
|
-
},
|
|
51
|
-
"hostname": INSTANCE_HOSTNAME,
|
|
52
|
-
"description": INSTANCE_DESCRIPTION,
|
|
53
|
-
"location": INSTANCE_LOCATION,
|
|
54
|
-
"price_per_hour": INSTANCE_PRICE_PER_HOUR,
|
|
55
|
-
"instance_type": INSTANCE_TYPE,
|
|
56
|
-
"image": INSTANCE_IMAGE,
|
|
57
|
-
"id": INSTANCE_ID,
|
|
58
|
-
"ssh_key_ids": [SSH_KEY_ID],
|
|
59
|
-
"os_volume_id": OS_VOLUME_ID
|
|
60
|
-
}
|
|
61
|
-
]
|
|
62
|
-
|
|
63
|
-
PAYLOAD_SPOT = PAYLOAD
|
|
64
|
-
PAYLOAD_SPOT[0]["is_spot"] = True
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
class TestInstancesService:
|
|
68
|
-
@pytest.fixture
|
|
69
|
-
def instances_service(self, http_client):
|
|
70
|
-
return InstancesService(http_client)
|
|
71
|
-
|
|
72
|
-
@pytest.fixture
|
|
73
|
-
def endpoint(self, http_client):
|
|
74
|
-
return http_client._base_url + "/instances"
|
|
75
|
-
|
|
76
|
-
def test_get_instances(self, instances_service, endpoint):
|
|
77
|
-
# arrange - add response mock
|
|
78
|
-
responses.add(
|
|
79
|
-
responses.GET,
|
|
80
|
-
endpoint,
|
|
81
|
-
json=PAYLOAD,
|
|
82
|
-
status=200
|
|
83
|
-
)
|
|
84
|
-
|
|
85
|
-
# act
|
|
86
|
-
instances = instances_service.get()
|
|
87
|
-
instance = instances[0]
|
|
88
|
-
|
|
89
|
-
# assert
|
|
90
|
-
assert type(instances) == list
|
|
91
|
-
assert len(instances) == 1
|
|
92
|
-
assert type(instance) == Instance
|
|
93
|
-
assert type(instance.ssh_key_ids) == list
|
|
94
|
-
assert instance.id == INSTANCE_ID
|
|
95
|
-
assert instance.ssh_key_ids == [SSH_KEY_ID]
|
|
96
|
-
assert instance.status == INSTANCE_STATUS
|
|
97
|
-
assert instance.image == INSTANCE_IMAGE
|
|
98
|
-
assert instance.instance_type == INSTANCE_TYPE
|
|
99
|
-
assert instance.price_per_hour == INSTANCE_PRICE_PER_HOUR
|
|
100
|
-
assert instance.location == INSTANCE_LOCATION
|
|
101
|
-
assert instance.description == INSTANCE_DESCRIPTION
|
|
102
|
-
assert instance.hostname == INSTANCE_HOSTNAME
|
|
103
|
-
assert instance.ip == INSTANCE_IP
|
|
104
|
-
assert instance.created_at == INSTANCE_CREATED_AT
|
|
105
|
-
assert type(instance.cpu) == dict
|
|
106
|
-
assert type(instance.gpu) == dict
|
|
107
|
-
assert type(instance.memory) == dict
|
|
108
|
-
assert type(instance.storage) == dict
|
|
109
|
-
assert responses.assert_call_count(endpoint, 1) is True
|
|
110
|
-
|
|
111
|
-
def test_get_instances_by_status_successful(self, instances_service, endpoint):
|
|
112
|
-
# arrange - add response mock
|
|
113
|
-
url = endpoint + "?status=running"
|
|
114
|
-
responses.add(
|
|
115
|
-
responses.GET,
|
|
116
|
-
url,
|
|
117
|
-
json=PAYLOAD,
|
|
118
|
-
status=200
|
|
119
|
-
)
|
|
120
|
-
|
|
121
|
-
# act
|
|
122
|
-
instances = instances_service.get(status='running')
|
|
123
|
-
instance = instances[0]
|
|
124
|
-
|
|
125
|
-
# assert
|
|
126
|
-
assert type(instances) == list
|
|
127
|
-
assert len(instances) == 1
|
|
128
|
-
assert type(instance) == Instance
|
|
129
|
-
assert type(instance.ssh_key_ids) == list
|
|
130
|
-
assert instance.id == INSTANCE_ID
|
|
131
|
-
assert instance.ssh_key_ids == [SSH_KEY_ID]
|
|
132
|
-
assert instance.status == INSTANCE_STATUS
|
|
133
|
-
assert instance.image == INSTANCE_IMAGE
|
|
134
|
-
assert instance.instance_type == INSTANCE_TYPE
|
|
135
|
-
assert instance.price_per_hour == INSTANCE_PRICE_PER_HOUR
|
|
136
|
-
assert instance.location == INSTANCE_LOCATION
|
|
137
|
-
assert instance.description == INSTANCE_DESCRIPTION
|
|
138
|
-
assert instance.hostname == INSTANCE_HOSTNAME
|
|
139
|
-
assert instance.ip == INSTANCE_IP
|
|
140
|
-
assert instance.created_at == INSTANCE_CREATED_AT
|
|
141
|
-
assert type(instance.cpu) == dict
|
|
142
|
-
assert type(instance.gpu) == dict
|
|
143
|
-
assert type(instance.memory) == dict
|
|
144
|
-
assert type(instance.storage) == dict
|
|
145
|
-
assert responses.assert_call_count(url, 1) is True
|
|
146
|
-
|
|
147
|
-
def test_get_instances_by_status_failed(self, instances_service, endpoint):
|
|
148
|
-
# arrange - add response mock
|
|
149
|
-
url = endpoint + "?status=blabbering"
|
|
150
|
-
responses.add(
|
|
151
|
-
responses.GET,
|
|
152
|
-
url,
|
|
153
|
-
json={"code": INVALID_REQUEST, "message": INVALID_REQUEST_MESSAGE},
|
|
154
|
-
status=400
|
|
155
|
-
)
|
|
156
|
-
|
|
157
|
-
# act
|
|
158
|
-
with pytest.raises(APIException) as excinfo:
|
|
159
|
-
instances_service.get(status='blabbering')
|
|
160
|
-
|
|
161
|
-
# assert
|
|
162
|
-
assert excinfo.value.code == INVALID_REQUEST
|
|
163
|
-
assert excinfo.value.message == INVALID_REQUEST_MESSAGE
|
|
164
|
-
assert responses.assert_call_count(url, 1) is True
|
|
165
|
-
|
|
166
|
-
def test_get_instance_by_id_successful(self, instances_service, endpoint):
|
|
167
|
-
# arrange - add response mock
|
|
168
|
-
url = endpoint + '/' + INSTANCE_ID
|
|
169
|
-
responses.add(
|
|
170
|
-
responses.GET,
|
|
171
|
-
url,
|
|
172
|
-
json=PAYLOAD[0],
|
|
173
|
-
status=200
|
|
174
|
-
)
|
|
175
|
-
|
|
176
|
-
# act
|
|
177
|
-
instance = instances_service.get_by_id(INSTANCE_ID)
|
|
178
|
-
|
|
179
|
-
# assert
|
|
180
|
-
assert type(instance) == Instance
|
|
181
|
-
assert instance.id == INSTANCE_ID
|
|
182
|
-
assert instance.ssh_key_ids == [SSH_KEY_ID]
|
|
183
|
-
assert instance.status == INSTANCE_STATUS
|
|
184
|
-
assert instance.image == INSTANCE_IMAGE
|
|
185
|
-
assert instance.instance_type == INSTANCE_TYPE
|
|
186
|
-
assert instance.price_per_hour == INSTANCE_PRICE_PER_HOUR
|
|
187
|
-
assert instance.location == INSTANCE_LOCATION
|
|
188
|
-
assert instance.description == INSTANCE_DESCRIPTION
|
|
189
|
-
assert instance.hostname == INSTANCE_HOSTNAME
|
|
190
|
-
assert instance.ip == INSTANCE_IP
|
|
191
|
-
assert instance.created_at == INSTANCE_CREATED_AT
|
|
192
|
-
assert type(instance.cpu) == dict
|
|
193
|
-
assert type(instance.gpu) == dict
|
|
194
|
-
assert type(instance.memory) == dict
|
|
195
|
-
assert type(instance.storage) == dict
|
|
196
|
-
assert responses.assert_call_count(url, 1) is True
|
|
197
|
-
|
|
198
|
-
def test_get_instance_by_id_failed(self, instances_service, endpoint):
|
|
199
|
-
# arrange - add response mock
|
|
200
|
-
url = endpoint + '/x'
|
|
201
|
-
responses.add(
|
|
202
|
-
responses.GET,
|
|
203
|
-
url,
|
|
204
|
-
json={"code": INVALID_REQUEST, "message": INVALID_REQUEST_MESSAGE},
|
|
205
|
-
status=400
|
|
206
|
-
)
|
|
207
|
-
|
|
208
|
-
# act
|
|
209
|
-
with pytest.raises(APIException) as excinfo:
|
|
210
|
-
instances_service.get_by_id('x')
|
|
211
|
-
|
|
212
|
-
# assert
|
|
213
|
-
assert excinfo.value.code == INVALID_REQUEST
|
|
214
|
-
assert excinfo.value.message == INVALID_REQUEST_MESSAGE
|
|
215
|
-
assert responses.assert_call_count(url, 1) is True
|
|
216
|
-
|
|
217
|
-
def test_create_instance_successful(self, instances_service, endpoint):
|
|
218
|
-
# arrange - add response mock
|
|
219
|
-
# create instance
|
|
220
|
-
responses.add(
|
|
221
|
-
responses.POST,
|
|
222
|
-
endpoint,
|
|
223
|
-
body=INSTANCE_ID,
|
|
224
|
-
status=200
|
|
225
|
-
)
|
|
226
|
-
# get instance by id
|
|
227
|
-
url = endpoint + '/' + INSTANCE_ID
|
|
228
|
-
responses.add(
|
|
229
|
-
responses.GET,
|
|
230
|
-
url,
|
|
231
|
-
json=PAYLOAD[0],
|
|
232
|
-
status=200
|
|
233
|
-
)
|
|
234
|
-
|
|
235
|
-
# act
|
|
236
|
-
instance = instances_service.create(
|
|
237
|
-
instance_type=INSTANCE_TYPE,
|
|
238
|
-
image=INSTANCE_IMAGE,
|
|
239
|
-
ssh_key_ids=[SSH_KEY_ID],
|
|
240
|
-
hostname=INSTANCE_HOSTNAME,
|
|
241
|
-
description=INSTANCE_DESCRIPTION,
|
|
242
|
-
os_volume=INSTANCE_OS_VOLUME
|
|
243
|
-
)
|
|
244
|
-
|
|
245
|
-
# assert
|
|
246
|
-
assert type(instance) == Instance
|
|
247
|
-
assert instance.id == INSTANCE_ID
|
|
248
|
-
assert instance.ssh_key_ids == [SSH_KEY_ID]
|
|
249
|
-
assert instance.status == INSTANCE_STATUS
|
|
250
|
-
assert instance.image == INSTANCE_IMAGE
|
|
251
|
-
assert instance.instance_type == INSTANCE_TYPE
|
|
252
|
-
assert instance.price_per_hour == INSTANCE_PRICE_PER_HOUR
|
|
253
|
-
assert instance.location == INSTANCE_LOCATION
|
|
254
|
-
assert instance.description == INSTANCE_DESCRIPTION
|
|
255
|
-
assert instance.hostname == INSTANCE_HOSTNAME
|
|
256
|
-
assert instance.ip == INSTANCE_IP
|
|
257
|
-
assert instance.created_at == INSTANCE_CREATED_AT
|
|
258
|
-
assert instance.os_volume_id == OS_VOLUME_ID
|
|
259
|
-
assert type(instance.cpu) == dict
|
|
260
|
-
assert type(instance.gpu) == dict
|
|
261
|
-
assert type(instance.memory) == dict
|
|
262
|
-
assert type(instance.gpu_memory) == dict
|
|
263
|
-
assert type(instance.storage) == dict
|
|
264
|
-
assert responses.assert_call_count(endpoint, 1) is True
|
|
265
|
-
assert responses.assert_call_count(url, 1) is True
|
|
266
|
-
assert type(instance.__str__()) == str
|
|
267
|
-
|
|
268
|
-
def test_create_spot_instance_successful(self, instances_service, endpoint):
|
|
269
|
-
# arrange - add response mock
|
|
270
|
-
# add response mock for the create instance endpoint
|
|
271
|
-
responses.add(
|
|
272
|
-
responses.POST,
|
|
273
|
-
endpoint,
|
|
274
|
-
body=INSTANCE_ID,
|
|
275
|
-
status=200
|
|
276
|
-
)
|
|
277
|
-
# add response mock for the get instance by id endpoint
|
|
278
|
-
url = endpoint + '/' + INSTANCE_ID
|
|
279
|
-
responses.add(
|
|
280
|
-
responses.GET,
|
|
281
|
-
url,
|
|
282
|
-
json=PAYLOAD_SPOT[0],
|
|
283
|
-
status=200
|
|
284
|
-
)
|
|
285
|
-
|
|
286
|
-
# act
|
|
287
|
-
instance = instances_service.create(
|
|
288
|
-
instance_type=INSTANCE_TYPE,
|
|
289
|
-
image=INSTANCE_IMAGE,
|
|
290
|
-
ssh_key_ids=[SSH_KEY_ID],
|
|
291
|
-
hostname=INSTANCE_HOSTNAME,
|
|
292
|
-
description=INSTANCE_DESCRIPTION,
|
|
293
|
-
os_volume=INSTANCE_OS_VOLUME
|
|
294
|
-
)
|
|
295
|
-
|
|
296
|
-
# assert
|
|
297
|
-
assert type(instance) == Instance
|
|
298
|
-
assert instance.id == INSTANCE_ID
|
|
299
|
-
assert instance.ssh_key_ids == [SSH_KEY_ID]
|
|
300
|
-
assert instance.status == INSTANCE_STATUS
|
|
301
|
-
assert instance.image == INSTANCE_IMAGE
|
|
302
|
-
assert instance.instance_type == INSTANCE_TYPE
|
|
303
|
-
assert instance.price_per_hour == INSTANCE_PRICE_PER_HOUR
|
|
304
|
-
assert instance.location == INSTANCE_LOCATION
|
|
305
|
-
assert instance.description == INSTANCE_DESCRIPTION
|
|
306
|
-
assert instance.hostname == INSTANCE_HOSTNAME
|
|
307
|
-
assert instance.ip == INSTANCE_IP
|
|
308
|
-
assert instance.created_at == INSTANCE_CREATED_AT
|
|
309
|
-
assert instance.os_volume_id == OS_VOLUME_ID
|
|
310
|
-
assert instance.is_spot == True
|
|
311
|
-
assert type(instance.cpu) == dict
|
|
312
|
-
assert type(instance.gpu) == dict
|
|
313
|
-
assert type(instance.memory) == dict
|
|
314
|
-
assert type(instance.gpu_memory) == dict
|
|
315
|
-
assert type(instance.storage) == dict
|
|
316
|
-
assert responses.assert_call_count(endpoint, 1) is True
|
|
317
|
-
assert responses.assert_call_count(url, 1) is True
|
|
318
|
-
|
|
319
|
-
def test_create_instance_attached_os_volume_successful(self, instances_service, endpoint):
|
|
320
|
-
# arrange - add response mock
|
|
321
|
-
# create instance
|
|
322
|
-
responses.add(
|
|
323
|
-
responses.POST,
|
|
324
|
-
endpoint,
|
|
325
|
-
body=INSTANCE_ID,
|
|
326
|
-
status=200
|
|
327
|
-
)
|
|
328
|
-
# get instance by id
|
|
329
|
-
url = endpoint + '/' + INSTANCE_ID
|
|
330
|
-
responses.add(
|
|
331
|
-
responses.GET,
|
|
332
|
-
url,
|
|
333
|
-
json=PAYLOAD[0],
|
|
334
|
-
status=200
|
|
335
|
-
)
|
|
336
|
-
|
|
337
|
-
# act
|
|
338
|
-
instance = instances_service.create(
|
|
339
|
-
instance_type=INSTANCE_TYPE,
|
|
340
|
-
image=OS_VOLUME_ID,
|
|
341
|
-
hostname=INSTANCE_HOSTNAME,
|
|
342
|
-
description=INSTANCE_DESCRIPTION,
|
|
343
|
-
)
|
|
344
|
-
|
|
345
|
-
# assert
|
|
346
|
-
assert type(instance) == Instance
|
|
347
|
-
assert instance.id == INSTANCE_ID
|
|
348
|
-
assert instance.ssh_key_ids == [SSH_KEY_ID]
|
|
349
|
-
assert instance.status == INSTANCE_STATUS
|
|
350
|
-
assert instance.image == INSTANCE_IMAGE
|
|
351
|
-
assert instance.instance_type == INSTANCE_TYPE
|
|
352
|
-
assert instance.price_per_hour == INSTANCE_PRICE_PER_HOUR
|
|
353
|
-
assert instance.location == INSTANCE_LOCATION
|
|
354
|
-
assert instance.description == INSTANCE_DESCRIPTION
|
|
355
|
-
assert instance.hostname == INSTANCE_HOSTNAME
|
|
356
|
-
assert instance.ip == INSTANCE_IP
|
|
357
|
-
assert instance.created_at == INSTANCE_CREATED_AT
|
|
358
|
-
assert instance.os_volume_id == OS_VOLUME_ID
|
|
359
|
-
assert type(instance.cpu) == dict
|
|
360
|
-
assert type(instance.gpu) == dict
|
|
361
|
-
assert type(instance.memory) == dict
|
|
362
|
-
assert type(instance.gpu_memory) == dict
|
|
363
|
-
assert type(instance.storage) == dict
|
|
364
|
-
assert responses.assert_call_count(endpoint, 1) is True
|
|
365
|
-
assert responses.assert_call_count(url, 1) is True
|
|
366
|
-
|
|
367
|
-
def test_create_instance_failed(self, instances_service, endpoint):
|
|
368
|
-
# arrange - add response mock
|
|
369
|
-
responses.add(
|
|
370
|
-
responses.POST,
|
|
371
|
-
endpoint,
|
|
372
|
-
json={"code": INVALID_REQUEST, "message": INVALID_REQUEST_MESSAGE},
|
|
373
|
-
status=400
|
|
374
|
-
)
|
|
375
|
-
|
|
376
|
-
# act
|
|
377
|
-
with pytest.raises(APIException) as excinfo:
|
|
378
|
-
instances_service.create(
|
|
379
|
-
instance_type=INSTANCE_TYPE,
|
|
380
|
-
image=INSTANCE_IMAGE,
|
|
381
|
-
ssh_key_ids=[SSH_KEY_ID],
|
|
382
|
-
hostname=INSTANCE_HOSTNAME,
|
|
383
|
-
description=INSTANCE_DESCRIPTION,
|
|
384
|
-
)
|
|
385
|
-
|
|
386
|
-
# assert
|
|
387
|
-
assert excinfo.value.code == INVALID_REQUEST
|
|
388
|
-
assert excinfo.value.message == INVALID_REQUEST_MESSAGE
|
|
389
|
-
assert responses.assert_call_count(endpoint, 1) is True
|
|
390
|
-
|
|
391
|
-
def test_action_successful(self, instances_service, endpoint):
|
|
392
|
-
# arrange - add response mock
|
|
393
|
-
url = endpoint
|
|
394
|
-
responses.add(
|
|
395
|
-
responses.PUT,
|
|
396
|
-
url,
|
|
397
|
-
status=202
|
|
398
|
-
)
|
|
399
|
-
|
|
400
|
-
# act
|
|
401
|
-
result = instances_service.action(
|
|
402
|
-
id_list=[INSTANCE_ID], action=Actions.SHUTDOWN)
|
|
403
|
-
|
|
404
|
-
# assert
|
|
405
|
-
assert result is None
|
|
406
|
-
assert responses.assert_call_count(url, 1) is True
|
|
407
|
-
|
|
408
|
-
def test_action_failed(self, instances_service, endpoint):
|
|
409
|
-
# arrange - add response mock
|
|
410
|
-
url = endpoint
|
|
411
|
-
responses.add(
|
|
412
|
-
responses.PUT,
|
|
413
|
-
url,
|
|
414
|
-
json={"code": INVALID_REQUEST, "message": INVALID_REQUEST_MESSAGE},
|
|
415
|
-
status=400
|
|
416
|
-
)
|
|
417
|
-
|
|
418
|
-
# act
|
|
419
|
-
with pytest.raises(APIException) as excinfo:
|
|
420
|
-
instances_service.action(
|
|
421
|
-
id_list=[INSTANCE_ID], action="fluxturcate")
|
|
422
|
-
|
|
423
|
-
# assert
|
|
424
|
-
assert excinfo.value.code == INVALID_REQUEST
|
|
425
|
-
assert excinfo.value.message == INVALID_REQUEST_MESSAGE
|
|
426
|
-
assert responses.assert_call_count(url, 1) is True
|
|
427
|
-
|
|
428
|
-
def test_is_available_successful(self, instances_service):
|
|
429
|
-
# arrange - add response mock
|
|
430
|
-
url = instances_service._http_client._base_url + \
|
|
431
|
-
'/instance-availability/' + INSTANCE_TYPE + "?isSpot=false"
|
|
432
|
-
responses.add(
|
|
433
|
-
responses.GET,
|
|
434
|
-
url,
|
|
435
|
-
json=True,
|
|
436
|
-
status=200
|
|
437
|
-
)
|
|
438
|
-
|
|
439
|
-
# act
|
|
440
|
-
is_available = instances_service.is_available(INSTANCE_TYPE)
|
|
441
|
-
|
|
442
|
-
# assert
|
|
443
|
-
assert is_available is True
|
|
444
|
-
assert responses.assert_call_count(url, 1) is True
|
|
445
|
-
|
|
446
|
-
def test_is_spot_available_successful(self, instances_service):
|
|
447
|
-
# arrange - add response mock
|
|
448
|
-
url = instances_service._http_client._base_url + \
|
|
449
|
-
'/instance-availability/' + INSTANCE_TYPE + '?isSpot=true'
|
|
450
|
-
responses.add(
|
|
451
|
-
responses.GET,
|
|
452
|
-
url,
|
|
453
|
-
json=True,
|
|
454
|
-
status=200
|
|
455
|
-
)
|
|
456
|
-
|
|
457
|
-
# act
|
|
458
|
-
is_available = instances_service.is_available(
|
|
459
|
-
INSTANCE_TYPE, is_spot=True)
|
|
460
|
-
|
|
461
|
-
# assert
|
|
462
|
-
assert is_available is True
|
|
463
|
-
assert responses.assert_call_count(url, 1) is True
|
|
464
|
-
|
|
465
|
-
def test_is_available_failed(self, instances_service):
|
|
466
|
-
# arrange - add response mock
|
|
467
|
-
url = instances_service._http_client._base_url + \
|
|
468
|
-
'/instance-availability/x' + "?isSpot=false"
|
|
469
|
-
responses.add(
|
|
470
|
-
responses.GET,
|
|
471
|
-
url,
|
|
472
|
-
json={"code": INVALID_REQUEST, "message": INVALID_REQUEST_MESSAGE},
|
|
473
|
-
status=400
|
|
474
|
-
)
|
|
475
|
-
|
|
476
|
-
# act
|
|
477
|
-
with pytest.raises(APIException) as excinfo:
|
|
478
|
-
instances_service.is_available('x')
|
|
479
|
-
|
|
480
|
-
# assert
|
|
481
|
-
assert excinfo.value.code == INVALID_REQUEST
|
|
482
|
-
assert excinfo.value.message == INVALID_REQUEST_MESSAGE
|
|
483
|
-
assert responses.assert_call_count(url, 1) is True
|
|
File without changes
|
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
import pytest
|
|
2
|
-
import responses # https://github.com/getsentry/responses
|
|
3
|
-
|
|
4
|
-
from datacrunch.exceptions import APIException
|
|
5
|
-
from datacrunch.ssh_keys.ssh_keys import SSHKeysService, SSHKey
|
|
6
|
-
|
|
7
|
-
INVALID_REQUEST = 'invalid_request'
|
|
8
|
-
INVALID_REQUEST_MESSAGE = 'Your existence is invalid'
|
|
9
|
-
|
|
10
|
-
KEY_ID = '01cf5dc1-a5d2-4972-ae4e-d429115d055b'
|
|
11
|
-
KEY_NAME = 'key to your heart'
|
|
12
|
-
KEY_VALUE = 'asdf'
|
|
13
|
-
|
|
14
|
-
KEY_ID_2 = '12345dc1-a5d2-4972-ae4e-d429115d055b'
|
|
15
|
-
|
|
16
|
-
PAYLOAD = [
|
|
17
|
-
{
|
|
18
|
-
'id': KEY_ID,
|
|
19
|
-
'name': KEY_NAME,
|
|
20
|
-
'key': KEY_VALUE
|
|
21
|
-
}
|
|
22
|
-
]
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
class TestSSHKeys:
|
|
26
|
-
|
|
27
|
-
@pytest.fixture
|
|
28
|
-
def ssh_key_service(self, http_client):
|
|
29
|
-
return SSHKeysService(http_client)
|
|
30
|
-
|
|
31
|
-
@pytest.fixture
|
|
32
|
-
def endpoint(self, http_client):
|
|
33
|
-
return http_client._base_url + "/sshkeys"
|
|
34
|
-
|
|
35
|
-
def test_get_keys(self, ssh_key_service, endpoint):
|
|
36
|
-
# arrange - add response mock
|
|
37
|
-
responses.add(
|
|
38
|
-
responses.GET,
|
|
39
|
-
endpoint,
|
|
40
|
-
json=PAYLOAD,
|
|
41
|
-
status=200
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
# act
|
|
45
|
-
keys = ssh_key_service.get()
|
|
46
|
-
|
|
47
|
-
# assert
|
|
48
|
-
assert type(keys) == list
|
|
49
|
-
assert len(keys) == 1
|
|
50
|
-
assert type(keys[0]) == SSHKey
|
|
51
|
-
assert keys[0].id == KEY_ID
|
|
52
|
-
assert keys[0].name == KEY_NAME
|
|
53
|
-
assert keys[0].public_key == KEY_VALUE
|
|
54
|
-
assert responses.assert_call_count(endpoint, 1) is True
|
|
55
|
-
|
|
56
|
-
def test_get_key_by_id_successful(self, ssh_key_service, endpoint):
|
|
57
|
-
# arrange - add response mock
|
|
58
|
-
url = endpoint + '/' + KEY_ID
|
|
59
|
-
responses.add(
|
|
60
|
-
responses.GET,
|
|
61
|
-
url,
|
|
62
|
-
json=PAYLOAD,
|
|
63
|
-
status=200
|
|
64
|
-
)
|
|
65
|
-
|
|
66
|
-
# act
|
|
67
|
-
key = ssh_key_service.get_by_id(KEY_ID)
|
|
68
|
-
|
|
69
|
-
# assert
|
|
70
|
-
assert type(key) == SSHKey
|
|
71
|
-
assert key.id == KEY_ID
|
|
72
|
-
assert key.name == KEY_NAME
|
|
73
|
-
assert key.public_key == KEY_VALUE
|
|
74
|
-
assert responses.assert_call_count(url, 1) is True
|
|
75
|
-
|
|
76
|
-
def test_get_key_by_id_failed(self, ssh_key_service, endpoint):
|
|
77
|
-
# arrange - add response mock
|
|
78
|
-
url = endpoint + '/x'
|
|
79
|
-
responses.add(
|
|
80
|
-
responses.GET,
|
|
81
|
-
url,
|
|
82
|
-
json={"code": INVALID_REQUEST, "message": INVALID_REQUEST_MESSAGE},
|
|
83
|
-
status=400
|
|
84
|
-
)
|
|
85
|
-
|
|
86
|
-
# act
|
|
87
|
-
with pytest.raises(APIException) as excinfo:
|
|
88
|
-
ssh_key_service.get_by_id('x')
|
|
89
|
-
|
|
90
|
-
# assert
|
|
91
|
-
assert excinfo.value.code == INVALID_REQUEST
|
|
92
|
-
assert excinfo.value.message == INVALID_REQUEST_MESSAGE
|
|
93
|
-
assert responses.assert_call_count(url, 1) is True
|
|
94
|
-
|
|
95
|
-
def test_create_key_successful(self, ssh_key_service, endpoint):
|
|
96
|
-
# arrange - add response mock
|
|
97
|
-
responses.add(
|
|
98
|
-
responses.POST,
|
|
99
|
-
endpoint,
|
|
100
|
-
body=KEY_ID,
|
|
101
|
-
status=201
|
|
102
|
-
)
|
|
103
|
-
|
|
104
|
-
# act
|
|
105
|
-
key = ssh_key_service.create(KEY_NAME, KEY_VALUE)
|
|
106
|
-
|
|
107
|
-
# assert
|
|
108
|
-
assert type(key) == SSHKey
|
|
109
|
-
assert type(key.id) == str
|
|
110
|
-
assert key.id == KEY_ID
|
|
111
|
-
assert responses.assert_call_count(endpoint, 1) is True
|
|
112
|
-
|
|
113
|
-
def test_create_key_failed(self, ssh_key_service, endpoint):
|
|
114
|
-
# arrange - add response mock
|
|
115
|
-
responses.add(
|
|
116
|
-
responses.POST,
|
|
117
|
-
endpoint,
|
|
118
|
-
json={"code": INVALID_REQUEST, "message": INVALID_REQUEST_MESSAGE},
|
|
119
|
-
status=400
|
|
120
|
-
)
|
|
121
|
-
|
|
122
|
-
# act
|
|
123
|
-
with pytest.raises(APIException) as excinfo:
|
|
124
|
-
ssh_key_service.create(KEY_NAME, KEY_VALUE)
|
|
125
|
-
|
|
126
|
-
# assert
|
|
127
|
-
assert excinfo.value.code == INVALID_REQUEST
|
|
128
|
-
assert excinfo.value.message == INVALID_REQUEST_MESSAGE
|
|
129
|
-
assert responses.assert_call_count(endpoint, 1) is True
|
|
130
|
-
|
|
131
|
-
def test_delete_keys_successful(self, ssh_key_service, endpoint):
|
|
132
|
-
# arrange - add response mock
|
|
133
|
-
responses.add(
|
|
134
|
-
responses.DELETE,
|
|
135
|
-
endpoint,
|
|
136
|
-
status=200
|
|
137
|
-
)
|
|
138
|
-
|
|
139
|
-
# act
|
|
140
|
-
result = ssh_key_service.delete([KEY_ID, KEY_ID_2])
|
|
141
|
-
|
|
142
|
-
# assert
|
|
143
|
-
assert result is None
|
|
144
|
-
assert responses.assert_call_count(endpoint, 1) is True
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
def test_delete_keys_failed(self, ssh_key_service, endpoint):
|
|
148
|
-
# arrange - add response mock
|
|
149
|
-
responses.add(
|
|
150
|
-
responses.DELETE,
|
|
151
|
-
endpoint,
|
|
152
|
-
json={"code": INVALID_REQUEST, "message": INVALID_REQUEST_MESSAGE},
|
|
153
|
-
status=400
|
|
154
|
-
)
|
|
155
|
-
|
|
156
|
-
# act
|
|
157
|
-
with pytest.raises(APIException) as excinfo:
|
|
158
|
-
ssh_key_service.delete(['x'])
|
|
159
|
-
|
|
160
|
-
# assert
|
|
161
|
-
assert excinfo.value.code == INVALID_REQUEST
|
|
162
|
-
assert excinfo.value.message == INVALID_REQUEST_MESSAGE
|
|
163
|
-
assert responses.assert_call_count(endpoint, 1) is True
|
|
164
|
-
|
|
165
|
-
def test_delete_key_by_id_successful(self, ssh_key_service, endpoint):
|
|
166
|
-
# arrange - add response mock
|
|
167
|
-
url = endpoint + '/' + KEY_ID
|
|
168
|
-
responses.add(
|
|
169
|
-
responses.DELETE,
|
|
170
|
-
url,
|
|
171
|
-
status=200
|
|
172
|
-
)
|
|
173
|
-
|
|
174
|
-
# act
|
|
175
|
-
result = ssh_key_service.delete_by_id(KEY_ID)
|
|
176
|
-
|
|
177
|
-
# assert
|
|
178
|
-
assert result == None
|
|
179
|
-
assert responses.assert_call_count(url, 1) is True
|
|
180
|
-
|
|
181
|
-
def test_delete_key_by_id_failed(self, ssh_key_service, endpoint):
|
|
182
|
-
# arrange - add response mock
|
|
183
|
-
url = endpoint + '/x'
|
|
184
|
-
responses.add(
|
|
185
|
-
responses.DELETE,
|
|
186
|
-
url,
|
|
187
|
-
json={"code": INVALID_REQUEST, "message": INVALID_REQUEST_MESSAGE},
|
|
188
|
-
status=400
|
|
189
|
-
)
|
|
190
|
-
|
|
191
|
-
# act
|
|
192
|
-
with pytest.raises(APIException) as excinfo:
|
|
193
|
-
ssh_key_service.delete_by_id('x')
|
|
194
|
-
|
|
195
|
-
# assert
|
|
196
|
-
assert excinfo.value.code == INVALID_REQUEST
|
|
197
|
-
assert excinfo.value.message == INVALID_REQUEST_MESSAGE
|
|
198
|
-
assert responses.assert_call_count(url, 1) is True
|
|
File without changes
|