oscar-python 1.3.4b1__tar.gz → 2.0.0b1__tar.gz
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.
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/PKG-INFO +1 -1
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/oscar_python/_providers/_s3.py +1 -1
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/oscar_python/_utils.py +22 -4
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/oscar_python/client.py +120 -6
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/oscar_python/local_test.py +1 -1
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/oscar_python/storage.py +3 -4
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/oscar_python.egg-info/PKG-INFO +1 -1
- oscar_python-2.0.0b1/tests/test_client.py +324 -0
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/tests/test_default_client.py +6 -2
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/tests/test_storage.py +5 -1
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/tests/test_utils.py +68 -1
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/tests/test_webdav.py +1 -1
- oscar_python-1.3.4b1/tests/test_client.py +0 -138
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/.github/workflows/release-build.yaml +0 -0
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/.github/workflows/tests.yaml +0 -0
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/.gitignore +0 -0
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/LICENSE +0 -0
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/README.md +0 -0
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/jupyter_example/oscar_notebook.ipynb +0 -0
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/jupyter_example/services/cowsay_example/cowsay.yaml +0 -0
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/jupyter_example/services/cowsay_example/script.sh +0 -0
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/oscar_python/__init__.py +0 -0
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/oscar_python/_oidc.py +0 -0
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/oscar_python/_providers/_minio.py +0 -0
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/oscar_python/_providers/_onedata.py +0 -0
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/oscar_python/_providers/_providers_base.py +0 -0
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/oscar_python/_providers/_webdav.py +0 -0
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/oscar_python/client_anon.py +0 -0
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/oscar_python/default_client.py +0 -0
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/oscar_python.egg-info/SOURCES.txt +0 -0
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/oscar_python.egg-info/dependency_links.txt +0 -0
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/oscar_python.egg-info/requires.txt +0 -0
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/oscar_python.egg-info/top_level.txt +0 -0
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/pyproject.toml +0 -0
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/setup.cfg +0 -0
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/setup.py +0 -0
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/tests/test_oidc.py +0 -0
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/tests/test_onedata.py +0 -0
- {oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/tests/test_s3.py +0 -0
|
@@ -59,7 +59,7 @@ class S3(StorageProvider):
|
|
|
59
59
|
bucket_name = remote_path.split('/')[0]
|
|
60
60
|
file_key = remote_path.split('/', 1)[1]
|
|
61
61
|
file_name = local_path.split('/')[-1]
|
|
62
|
-
print("Uploading to bucket '{0}' with key '{1}'".format(bucket_name,file_key))
|
|
62
|
+
print("Uploading to bucket '{0}' with key '{1}'".format(bucket_name, file_key))
|
|
63
63
|
with open(local_path, 'rb') as data:
|
|
64
64
|
try:
|
|
65
65
|
self.client.upload_fileobj(data, bucket_name, file_key + "/" + file_name)
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
import base64
|
|
16
|
+
import json
|
|
16
17
|
import os
|
|
17
18
|
import requests
|
|
18
19
|
import liboidcagent as agent
|
|
@@ -32,14 +33,16 @@ def make_request(c, path, method, **kwargs):
|
|
|
32
33
|
url = c.endpoint+path
|
|
33
34
|
|
|
34
35
|
if method in ["post", "put"]:
|
|
35
|
-
if "token" in kwargs.keys() and kwargs["token"]:
|
|
36
|
+
if "token" in kwargs.keys() and kwargs["token"]:
|
|
36
37
|
headers = get_headers_with_token(kwargs["token"])
|
|
38
|
+
req_kwargs = {"headers": headers, "verify": c.ssl, "timeout": timeout}
|
|
37
39
|
if "data" in kwargs.keys() and kwargs["data"]:
|
|
38
|
-
|
|
40
|
+
req_kwargs["data"] = kwargs["data"]
|
|
41
|
+
result = requests.request(method, url, **req_kwargs)
|
|
39
42
|
else:
|
|
40
43
|
result = requests.request(method, url, headers=headers, verify=c.ssl, timeout=timeout)
|
|
41
44
|
|
|
42
|
-
if "handle" in kwargs.keys() and kwargs["handle"]
|
|
45
|
+
if "handle" in kwargs.keys() and kwargs["handle"] is False:
|
|
43
46
|
return result
|
|
44
47
|
|
|
45
48
|
result.raise_for_status()
|
|
@@ -94,7 +97,7 @@ def decode_b64(b64_str, file_out):
|
|
|
94
97
|
except ValueError:
|
|
95
98
|
print('Error decoding output: Invalid base64 string.')
|
|
96
99
|
except OSError:
|
|
97
|
-
print('Error decoding output: Failed to write decoded data to file.')
|
|
100
|
+
print('Error decoding output: Failed to write decoded data to file.')
|
|
98
101
|
|
|
99
102
|
|
|
100
103
|
def encode_input(data):
|
|
@@ -111,6 +114,21 @@ def encode_input(data):
|
|
|
111
114
|
return base64.b64encode(message_bytes)
|
|
112
115
|
|
|
113
116
|
|
|
117
|
+
def load_config(config_path, cluster_name="default"):
|
|
118
|
+
with open(config_path) as f:
|
|
119
|
+
config = json.load(f)
|
|
120
|
+
cluster = config["clusters"][cluster_name]
|
|
121
|
+
opts = {
|
|
122
|
+
"cluster_id": cluster_name,
|
|
123
|
+
"endpoint": cluster["endpoint"],
|
|
124
|
+
"ssl": cluster.get("ssl", True),
|
|
125
|
+
}
|
|
126
|
+
for key in ("user", "password", "shortname", "oidc_token", "refresh_token"):
|
|
127
|
+
if key in cluster:
|
|
128
|
+
opts[key] = cluster[key]
|
|
129
|
+
return opts
|
|
130
|
+
|
|
131
|
+
|
|
114
132
|
def decode_output(output, file_path):
|
|
115
133
|
if isBase64(output):
|
|
116
134
|
decode_b64(output, file_path)
|
|
@@ -27,7 +27,12 @@ _CONFIG_PATH = "/system/config"
|
|
|
27
27
|
_SVC_PATH = "/system/services"
|
|
28
28
|
_LOGS_PATH = "/system/logs"
|
|
29
29
|
_RUN_PATH = "/run"
|
|
30
|
-
_STATUS_PATH="/system/status"
|
|
30
|
+
_STATUS_PATH = "/system/status"
|
|
31
|
+
_HEALTH_PATH = "/health"
|
|
32
|
+
_VOLUMES_PATH = "/system/volumes"
|
|
33
|
+
_BUCKETS_PATH = "/system/buckets"
|
|
34
|
+
_METRICS_PATH = "/system/metrics"
|
|
35
|
+
_QUOTAS_USER_PATH = "/system/quotas/user"
|
|
31
36
|
|
|
32
37
|
|
|
33
38
|
# _JOB_PATH = "/job"
|
|
@@ -101,13 +106,13 @@ class Client(DefaultClient):
|
|
|
101
106
|
""" Creates a generic storage client to interact with the storage providers
|
|
102
107
|
defined on a specific service of the refered OSCAR cluster """
|
|
103
108
|
def create_storage_client(self, svc=None):
|
|
104
|
-
if svc
|
|
109
|
+
if svc is not None:
|
|
105
110
|
return Storage(
|
|
106
111
|
client_obj=self, svc_name=svc)
|
|
107
112
|
else:
|
|
108
113
|
return Storage(
|
|
109
114
|
client_obj=self)
|
|
110
|
-
|
|
115
|
+
|
|
111
116
|
""" Function to get cluster info """
|
|
112
117
|
def get_cluster_info(self):
|
|
113
118
|
return utils.make_request(self, _INFO_PATH, _GET)
|
|
@@ -137,17 +142,18 @@ class Client(DefaultClient):
|
|
|
137
142
|
raise Exception("FDL clusterID does not match current clusterID: {0}".format(err))
|
|
138
143
|
try:
|
|
139
144
|
if os.path.isabs(svc["script"]):
|
|
140
|
-
script_path =
|
|
145
|
+
script_path = svc["script"]
|
|
141
146
|
else:
|
|
142
147
|
fdl_directory = os.path.dirname(fdl_path)
|
|
143
148
|
script_path = os.path.join(fdl_directory, svc['script'])
|
|
144
149
|
with open(script_path) as s:
|
|
145
150
|
svc["script"] = s.read()
|
|
146
|
-
except IOError
|
|
151
|
+
except IOError:
|
|
147
152
|
raise Exception("Couldn't read script")
|
|
148
153
|
|
|
149
154
|
# cpu parameter has to be string on the request
|
|
150
|
-
if type(svc["cpu"]) is int or type(svc["cpu"]) is float:
|
|
155
|
+
if type(svc["cpu"]) is int or type(svc["cpu"]) is float:
|
|
156
|
+
svc["cpu"] = str(svc["cpu"])
|
|
151
157
|
|
|
152
158
|
except ValueError as err:
|
|
153
159
|
print(err)
|
|
@@ -226,3 +232,111 @@ class Client(DefaultClient):
|
|
|
226
232
|
""" Remove all service jobs """
|
|
227
233
|
def remove_all_jobs(self, svc):
|
|
228
234
|
return utils.make_request(self, _LOGS_PATH+"/"+svc, _DELETE)
|
|
235
|
+
|
|
236
|
+
""" Check cluster health """
|
|
237
|
+
def health_check(self):
|
|
238
|
+
return utils.make_request(self, _HEALTH_PATH, _GET)
|
|
239
|
+
|
|
240
|
+
""" Get deployment status of a service """
|
|
241
|
+
def get_deployment_status(self, name):
|
|
242
|
+
return utils.make_request(self, _SVC_PATH + "/" + name + "/deployment", _GET)
|
|
243
|
+
|
|
244
|
+
""" Get deployment logs of a service """
|
|
245
|
+
def get_deployment_logs(self, name):
|
|
246
|
+
return utils.make_request(self, _SVC_PATH + "/" + name + "/deployment/logs", _GET)
|
|
247
|
+
|
|
248
|
+
""" List all managed volumes """
|
|
249
|
+
def list_volumes(self):
|
|
250
|
+
return utils.make_request(self, _VOLUMES_PATH, _GET)
|
|
251
|
+
|
|
252
|
+
""" Create a new managed volume """
|
|
253
|
+
def create_volume(self, name, size):
|
|
254
|
+
data = json.dumps({"name": name, "size": size})
|
|
255
|
+
return utils.make_request(self, _VOLUMES_PATH, _POST, data=data)
|
|
256
|
+
|
|
257
|
+
""" Get a specific managed volume """
|
|
258
|
+
def get_volume(self, name):
|
|
259
|
+
return utils.make_request(self, _VOLUMES_PATH + "/" + name, _GET)
|
|
260
|
+
|
|
261
|
+
""" Delete a managed volume """
|
|
262
|
+
def delete_volume(self, name):
|
|
263
|
+
return utils.make_request(self, _VOLUMES_PATH + "/" + name, _DELETE)
|
|
264
|
+
|
|
265
|
+
""" Create a bucket """
|
|
266
|
+
def create_bucket(self, name, visibility="private", allowed_users=None):
|
|
267
|
+
data = json.dumps({
|
|
268
|
+
"bucket_name": name,
|
|
269
|
+
"visibility": visibility,
|
|
270
|
+
"allowed_users": allowed_users or []
|
|
271
|
+
})
|
|
272
|
+
return utils.make_request(self, _BUCKETS_PATH, _POST, data=data)
|
|
273
|
+
|
|
274
|
+
""" Update a bucket """
|
|
275
|
+
def update_bucket(self, name, visibility, allowed_users=None):
|
|
276
|
+
data = json.dumps({
|
|
277
|
+
"bucket_name": name,
|
|
278
|
+
"visibility": visibility,
|
|
279
|
+
"allowed_users": allowed_users or []
|
|
280
|
+
})
|
|
281
|
+
return utils.make_request(self, _BUCKETS_PATH, _PUT, data=data)
|
|
282
|
+
|
|
283
|
+
""" List all buckets """
|
|
284
|
+
def list_buckets(self):
|
|
285
|
+
return utils.make_request(self, _BUCKETS_PATH, _GET)
|
|
286
|
+
|
|
287
|
+
""" Get a specific bucket """
|
|
288
|
+
def get_bucket(self, name):
|
|
289
|
+
return utils.make_request(self, _BUCKETS_PATH + "/" + name, _GET)
|
|
290
|
+
|
|
291
|
+
""" Delete a bucket """
|
|
292
|
+
def delete_bucket(self, name):
|
|
293
|
+
return utils.make_request(self, _BUCKETS_PATH + "/" + name, _DELETE)
|
|
294
|
+
|
|
295
|
+
""" Get a presigned URL for a bucket file """
|
|
296
|
+
def presign_bucket(self, name, object_key, operation="download", expires=0, content_type="", extra_headers=None):
|
|
297
|
+
path = _BUCKETS_PATH + "/" + name + "/presign"
|
|
298
|
+
data = json.dumps({
|
|
299
|
+
"object_key": object_key,
|
|
300
|
+
"operation": operation,
|
|
301
|
+
"expires": expires,
|
|
302
|
+
"content_type": content_type,
|
|
303
|
+
"extra_headers": extra_headers or {},
|
|
304
|
+
})
|
|
305
|
+
return utils.make_request(self, path, _POST, data=data)
|
|
306
|
+
|
|
307
|
+
""" Get system logs (admin only) """
|
|
308
|
+
def get_system_logs(self, timestamps=False, previous=False):
|
|
309
|
+
path = _LOGS_PATH
|
|
310
|
+
params = []
|
|
311
|
+
if timestamps:
|
|
312
|
+
params.append("timestamps=true")
|
|
313
|
+
if previous:
|
|
314
|
+
params.append("previous=true")
|
|
315
|
+
if params:
|
|
316
|
+
path += "?" + "&".join(params)
|
|
317
|
+
return utils.make_request(self, path, _GET)
|
|
318
|
+
|
|
319
|
+
""" Get metrics summary """
|
|
320
|
+
def get_metrics_summary(self):
|
|
321
|
+
return utils.make_request(self, _METRICS_PATH, _GET)
|
|
322
|
+
|
|
323
|
+
""" Get metrics breakdown """
|
|
324
|
+
def get_metrics_breakdown(self, group_by="service"):
|
|
325
|
+
return utils.make_request(self, _METRICS_PATH + "/breakdown?group_by=" + group_by, _GET)
|
|
326
|
+
|
|
327
|
+
""" Get metrics for a specific service """
|
|
328
|
+
def get_service_metrics(self, service_name):
|
|
329
|
+
return utils.make_request(self, _METRICS_PATH + "/" + service_name, _GET)
|
|
330
|
+
|
|
331
|
+
""" Get own quota """
|
|
332
|
+
def get_own_quota(self):
|
|
333
|
+
return utils.make_request(self, _QUOTAS_USER_PATH, _GET)
|
|
334
|
+
|
|
335
|
+
""" Get quota for a specific user """
|
|
336
|
+
def get_user_quota(self, user_id):
|
|
337
|
+
return utils.make_request(self, _QUOTAS_USER_PATH + "/" + user_id, _GET)
|
|
338
|
+
|
|
339
|
+
""" Update quota for a user """
|
|
340
|
+
def update_user_quota(self, user_id, cpu, memory):
|
|
341
|
+
data = json.dumps({"cpu": cpu, "memory": memory})
|
|
342
|
+
return utils.make_request(self, _QUOTAS_USER_PATH + "/" + user_id, _PUT, data=data)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from client import Client
|
|
2
2
|
|
|
3
|
-
client = Client("oscar-gpu-cluster","https://focused-boyd8.im.grycap.net", "oscar", "oscar123", True)
|
|
3
|
+
client = Client("oscar-gpu-cluster", "https://focused-boyd8.im.grycap.net", "oscar", "oscar123", True)
|
|
4
4
|
|
|
5
5
|
res = client.remove_service("cowsay")
|
|
6
6
|
if res:
|
|
@@ -31,10 +31,10 @@ _SVC_PATH = "/system/services"
|
|
|
31
31
|
|
|
32
32
|
# TODO check returns from functions
|
|
33
33
|
class Storage:
|
|
34
|
-
def __init__(self, client_obj, svc_name
|
|
34
|
+
def __init__(self, client_obj, svc_name=None) -> None:
|
|
35
35
|
self.client_obj = client_obj
|
|
36
36
|
self.storage_providers = {}
|
|
37
|
-
if svc_name
|
|
37
|
+
if svc_name is not None:
|
|
38
38
|
self.svc_name = svc_name
|
|
39
39
|
self._store_provider_from_service()
|
|
40
40
|
self._store_default_minio_provider()
|
|
@@ -46,13 +46,12 @@ class Storage:
|
|
|
46
46
|
|
|
47
47
|
""" Function to store the user credentials for the default MinIO provider """
|
|
48
48
|
def _store_default_minio_provider(self):
|
|
49
|
-
config = utils.make_request(self.client_obj, _CONFIG_PATH + "/"
|
|
49
|
+
config = utils.make_request(self.client_obj, _CONFIG_PATH + "/", _GET)
|
|
50
50
|
if _MINIO in self.storage_providers:
|
|
51
51
|
self.storage_providers[_MINIO]["default"] = json.loads(config.text)["minio_provider"]
|
|
52
52
|
else:
|
|
53
53
|
default = {"default": json.loads(config.text)["minio_provider"]}
|
|
54
54
|
self.storage_providers[_MINIO] = default
|
|
55
|
-
|
|
56
55
|
|
|
57
56
|
""" Function to retreive credentials of a specific storage provider """
|
|
58
57
|
def _get_provider_creds(self, provider, provider_name):
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
import json
|
|
3
|
+
from unittest.mock import patch, mock_open
|
|
4
|
+
from oscar_python.client import Client
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@pytest.fixture
|
|
8
|
+
def options():
|
|
9
|
+
return {
|
|
10
|
+
'cluster_id': 'test_cluster',
|
|
11
|
+
'endpoint': 'http://test.endpoint',
|
|
12
|
+
'user': 'test_user',
|
|
13
|
+
'password': 'test_password',
|
|
14
|
+
'ssl': True,
|
|
15
|
+
'shortname': 'test_shortname',
|
|
16
|
+
'oidc_token': 'test_oidc_token'
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def test_basic_auth_client(options):
|
|
21
|
+
client = Client(options)
|
|
22
|
+
assert client.id == options['cluster_id']
|
|
23
|
+
assert client.endpoint == options['endpoint']
|
|
24
|
+
assert client.user == options['user']
|
|
25
|
+
assert client.password == options['password']
|
|
26
|
+
assert client.ssl == options['ssl']
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def test_oidc_agent_client(options):
|
|
30
|
+
del options['user']
|
|
31
|
+
client = Client(options)
|
|
32
|
+
assert client.id == options['cluster_id']
|
|
33
|
+
assert client.endpoint == options['endpoint']
|
|
34
|
+
assert client.shortname == options['shortname']
|
|
35
|
+
assert client.ssl == options['ssl']
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def test_oidc_client(options):
|
|
39
|
+
del options['user']
|
|
40
|
+
del options['shortname']
|
|
41
|
+
client = Client(options)
|
|
42
|
+
assert client.id == options['cluster_id']
|
|
43
|
+
assert client.endpoint == options['endpoint']
|
|
44
|
+
assert client.oidc_token == options['oidc_token']
|
|
45
|
+
assert client.ssl == options['ssl']
|
|
46
|
+
|
|
47
|
+
del options['oidc_token']
|
|
48
|
+
options['refresh_token'] = 'test_refresh_token'
|
|
49
|
+
options['scopes'] = ['openid', 'profile', 'email']
|
|
50
|
+
options['token_endpoint'] = 'test_token_endpoint'
|
|
51
|
+
client = Client(options)
|
|
52
|
+
assert client.refresh_token == options['refresh_token']
|
|
53
|
+
assert client.scopes == ['openid', 'profile', 'email']
|
|
54
|
+
assert client.token_endpoint == options['token_endpoint']
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def test_set_auth_type(options):
|
|
58
|
+
client = Client(options)
|
|
59
|
+
assert client._AUTH_TYPE == "basicauth"
|
|
60
|
+
|
|
61
|
+
del options['user']
|
|
62
|
+
client = Client(options)
|
|
63
|
+
assert client._AUTH_TYPE == "oidc-agent"
|
|
64
|
+
|
|
65
|
+
del options['shortname']
|
|
66
|
+
options['oidc_token'] = 'test_oidc_token'
|
|
67
|
+
client = Client(options)
|
|
68
|
+
assert client._AUTH_TYPE == "oidc"
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def test_get_cluster_info(options):
|
|
72
|
+
client = Client(options)
|
|
73
|
+
with patch('oscar_python._utils.make_request') as mock_request:
|
|
74
|
+
client.get_cluster_info()
|
|
75
|
+
mock_request.assert_called_once_with(client, "/system/info", "get")
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def test_get_cluster_config(options):
|
|
79
|
+
client = Client(options)
|
|
80
|
+
with patch('oscar_python._utils.make_request') as mock_request:
|
|
81
|
+
client.get_cluster_config()
|
|
82
|
+
mock_request.assert_called_once_with(client, "/system/config", "get")
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def test_list_services(options):
|
|
86
|
+
client = Client(options)
|
|
87
|
+
with patch('oscar_python._utils.make_request') as mock_request:
|
|
88
|
+
client.list_services()
|
|
89
|
+
mock_request.assert_called_once_with(client, "/system/services", "get")
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def test_get_service(options):
|
|
93
|
+
client = Client(options)
|
|
94
|
+
with patch('oscar_python._utils.make_request') as mock_request:
|
|
95
|
+
client.get_service("test_service")
|
|
96
|
+
mock_request.assert_called_once_with(client, "/system/services/test_service", "get")
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def test_create_service_from_dict(options):
|
|
100
|
+
client = Client(options)
|
|
101
|
+
service_definition = {"name": "test_service"}
|
|
102
|
+
with patch('oscar_python._utils.make_request') as mock_request:
|
|
103
|
+
client.create_service(service_definition)
|
|
104
|
+
mock_request.assert_called_with(client, "/system/services", "post",
|
|
105
|
+
data=json.dumps(service_definition))
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def test_create_service_from_file(options):
|
|
109
|
+
client = Client(options)
|
|
110
|
+
service_definition = (
|
|
111
|
+
"functions:\n oscar:\n - test_cluster:\n"
|
|
112
|
+
" name: test_service\n"
|
|
113
|
+
" script: test_script\n"
|
|
114
|
+
" cpu: 1"
|
|
115
|
+
)
|
|
116
|
+
service_file = "path/to/service.yaml"
|
|
117
|
+
with patch('os.path.isfile', return_value=True), \
|
|
118
|
+
patch('builtins.open', mock_open(read_data=service_definition)), \
|
|
119
|
+
patch('oscar_python._utils.make_request') as mock_request:
|
|
120
|
+
client.create_service(service_file)
|
|
121
|
+
assert mock_request.call_args[0][0] == client
|
|
122
|
+
assert mock_request.call_args[0][1] == "/system/services"
|
|
123
|
+
assert mock_request.call_args[0][2] == "post"
|
|
124
|
+
assert json.loads(mock_request.call_args[1]['data']) == {"name": "test_service",
|
|
125
|
+
"cpu": "1",
|
|
126
|
+
"script": service_definition}
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def test_update_service_from_dict(options):
|
|
130
|
+
client = Client(options)
|
|
131
|
+
new_service = {"name": "test_service"}
|
|
132
|
+
with patch('oscar_python._utils.make_request') as mock_request:
|
|
133
|
+
mock_request.return_value.status_code = 200
|
|
134
|
+
client.update_service("test_service", new_service)
|
|
135
|
+
mock_request.assert_called_with(client, "/system/services",
|
|
136
|
+
"put", data=json.dumps(new_service))
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def test_remove_service(options):
|
|
140
|
+
client = Client(options)
|
|
141
|
+
with patch('oscar_python._utils.make_request') as mock_request:
|
|
142
|
+
client.remove_service("test_service")
|
|
143
|
+
mock_request.assert_called_once_with(client, "/system/services/test_service", "delete")
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def test_health_check(options):
|
|
147
|
+
client = Client(options)
|
|
148
|
+
with patch('oscar_python._utils.make_request') as mock_request:
|
|
149
|
+
client.health_check()
|
|
150
|
+
mock_request.assert_called_once_with(client, "/health", "get")
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def test_get_deployment_status(options):
|
|
154
|
+
client = Client(options)
|
|
155
|
+
with patch('oscar_python._utils.make_request') as mock_request:
|
|
156
|
+
client.get_deployment_status("test_service")
|
|
157
|
+
mock_request.assert_called_once_with(client, "/system/services/test_service/deployment", "get")
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def test_get_deployment_logs(options):
|
|
161
|
+
client = Client(options)
|
|
162
|
+
with patch('oscar_python._utils.make_request') as mock_request:
|
|
163
|
+
client.get_deployment_logs("test_service")
|
|
164
|
+
mock_request.assert_called_once_with(client, "/system/services/test_service/deployment/logs", "get")
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def test_list_volumes(options):
|
|
168
|
+
client = Client(options)
|
|
169
|
+
with patch('oscar_python._utils.make_request') as mock_request:
|
|
170
|
+
client.list_volumes()
|
|
171
|
+
mock_request.assert_called_once_with(client, "/system/volumes", "get")
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def test_create_volume(options):
|
|
175
|
+
client = Client(options)
|
|
176
|
+
with patch('oscar_python._utils.make_request') as mock_request:
|
|
177
|
+
client.create_volume("test_vol", "1Gi")
|
|
178
|
+
mock_request.assert_called_once_with(client, "/system/volumes", "post",
|
|
179
|
+
data=json.dumps({"name": "test_vol", "size": "1Gi"}))
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def test_get_volume(options):
|
|
183
|
+
client = Client(options)
|
|
184
|
+
with patch('oscar_python._utils.make_request') as mock_request:
|
|
185
|
+
client.get_volume("test_vol")
|
|
186
|
+
mock_request.assert_called_once_with(client, "/system/volumes/test_vol", "get")
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def test_delete_volume(options):
|
|
190
|
+
client = Client(options)
|
|
191
|
+
with patch('oscar_python._utils.make_request') as mock_request:
|
|
192
|
+
client.delete_volume("test_vol")
|
|
193
|
+
mock_request.assert_called_once_with(client, "/system/volumes/test_vol", "delete")
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def test_list_buckets(options):
|
|
197
|
+
client = Client(options)
|
|
198
|
+
with patch('oscar_python._utils.make_request') as mock_request:
|
|
199
|
+
client.list_buckets()
|
|
200
|
+
mock_request.assert_called_once_with(client, "/system/buckets", "get")
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
def test_get_bucket(options):
|
|
204
|
+
client = Client(options)
|
|
205
|
+
with patch('oscar_python._utils.make_request') as mock_request:
|
|
206
|
+
client.get_bucket("test_bucket")
|
|
207
|
+
mock_request.assert_called_once_with(client, "/system/buckets/test_bucket", "get")
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
def test_create_bucket(options):
|
|
211
|
+
client = Client(options)
|
|
212
|
+
with patch('oscar_python._utils.make_request') as mock_request:
|
|
213
|
+
client.create_bucket("test_bucket")
|
|
214
|
+
mock_request.assert_called_once_with(
|
|
215
|
+
client, "/system/buckets", "post",
|
|
216
|
+
data=json.dumps({"bucket_name": "test_bucket",
|
|
217
|
+
"visibility": "private",
|
|
218
|
+
"allowed_users": []}))
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
def test_create_bucket_with_visibility(options):
|
|
222
|
+
client = Client(options)
|
|
223
|
+
with patch('oscar_python._utils.make_request') as mock_request:
|
|
224
|
+
client.create_bucket("test_bucket", visibility="public", allowed_users=["user1"])
|
|
225
|
+
mock_request.assert_called_once_with(
|
|
226
|
+
client, "/system/buckets", "post",
|
|
227
|
+
data=json.dumps({"bucket_name": "test_bucket",
|
|
228
|
+
"visibility": "public",
|
|
229
|
+
"allowed_users": ["user1"]}))
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def test_update_bucket(options):
|
|
233
|
+
client = Client(options)
|
|
234
|
+
with patch('oscar_python._utils.make_request') as mock_request:
|
|
235
|
+
client.update_bucket("test_bucket", "public", ["user1"])
|
|
236
|
+
mock_request.assert_called_once_with(
|
|
237
|
+
client, "/system/buckets", "put",
|
|
238
|
+
data=json.dumps({"bucket_name": "test_bucket",
|
|
239
|
+
"visibility": "public",
|
|
240
|
+
"allowed_users": ["user1"]}))
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
def test_delete_bucket(options):
|
|
244
|
+
client = Client(options)
|
|
245
|
+
with patch('oscar_python._utils.make_request') as mock_request:
|
|
246
|
+
client.delete_bucket("test_bucket")
|
|
247
|
+
mock_request.assert_called_once_with(client, "/system/buckets/test_bucket", "delete")
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
def test_presign_bucket(options):
|
|
251
|
+
client = Client(options)
|
|
252
|
+
with patch('oscar_python._utils.make_request') as mock_request:
|
|
253
|
+
client.presign_bucket("test_bucket", "file.txt", operation="upload", expires=3600)
|
|
254
|
+
mock_request.assert_called_once_with(
|
|
255
|
+
client, "/system/buckets/test_bucket/presign", "post",
|
|
256
|
+
data=json.dumps({"object_key": "file.txt",
|
|
257
|
+
"operation": "upload",
|
|
258
|
+
"expires": 3600,
|
|
259
|
+
"content_type": "",
|
|
260
|
+
"extra_headers": {}}))
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
def test_get_system_logs(options):
|
|
264
|
+
client = Client(options)
|
|
265
|
+
with patch('oscar_python._utils.make_request') as mock_request:
|
|
266
|
+
client.get_system_logs()
|
|
267
|
+
mock_request.assert_called_once_with(client, "/system/logs", "get")
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
def test_get_system_logs_with_flags(options):
|
|
271
|
+
client = Client(options)
|
|
272
|
+
with patch('oscar_python._utils.make_request') as mock_request:
|
|
273
|
+
client.get_system_logs(timestamps=True, previous=True)
|
|
274
|
+
mock_request.assert_called_once_with(client, "/system/logs?timestamps=true&previous=true", "get")
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
def test_get_metrics_summary(options):
|
|
278
|
+
client = Client(options)
|
|
279
|
+
with patch('oscar_python._utils.make_request') as mock_request:
|
|
280
|
+
client.get_metrics_summary()
|
|
281
|
+
mock_request.assert_called_once_with(client, "/system/metrics", "get")
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
def test_get_metrics_breakdown(options):
|
|
285
|
+
client = Client(options)
|
|
286
|
+
with patch('oscar_python._utils.make_request') as mock_request:
|
|
287
|
+
client.get_metrics_breakdown("user")
|
|
288
|
+
mock_request.assert_called_once_with(client, "/system/metrics/breakdown?group_by=user", "get")
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
def test_get_metrics_breakdown_default(options):
|
|
292
|
+
client = Client(options)
|
|
293
|
+
with patch('oscar_python._utils.make_request') as mock_request:
|
|
294
|
+
client.get_metrics_breakdown()
|
|
295
|
+
mock_request.assert_called_once_with(client, "/system/metrics/breakdown?group_by=service", "get")
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
def test_get_service_metrics(options):
|
|
299
|
+
client = Client(options)
|
|
300
|
+
with patch('oscar_python._utils.make_request') as mock_request:
|
|
301
|
+
client.get_service_metrics("test_service")
|
|
302
|
+
mock_request.assert_called_once_with(client, "/system/metrics/test_service", "get")
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
def test_get_own_quota(options):
|
|
306
|
+
client = Client(options)
|
|
307
|
+
with patch('oscar_python._utils.make_request') as mock_request:
|
|
308
|
+
client.get_own_quota()
|
|
309
|
+
mock_request.assert_called_once_with(client, "/system/quotas/user", "get")
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
def test_get_user_quota(options):
|
|
313
|
+
client = Client(options)
|
|
314
|
+
with patch('oscar_python._utils.make_request') as mock_request:
|
|
315
|
+
client.get_user_quota("test_user")
|
|
316
|
+
mock_request.assert_called_once_with(client, "/system/quotas/user/test_user", "get")
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
def test_update_user_quota(options):
|
|
320
|
+
client = Client(options)
|
|
321
|
+
with patch('oscar_python._utils.make_request') as mock_request:
|
|
322
|
+
client.update_user_quota("test_user", "2", "4Gi")
|
|
323
|
+
mock_request.assert_called_once_with(client, "/system/quotas/user/test_user", "put",
|
|
324
|
+
data=json.dumps({"cpu": "2", "memory": "4Gi"}))
|
|
@@ -25,7 +25,9 @@ def test_run_service_with_input_and_token(mock_decode_output, mock_encode_input,
|
|
|
25
25
|
response = client.run_service("test_service", input="test_input", token="test_token", output="output_file", timeout=30)
|
|
26
26
|
|
|
27
27
|
mock_encode_input.assert_called_once_with("test_input")
|
|
28
|
-
mock_make_request.assert_called_once_with(
|
|
28
|
+
mock_make_request.assert_called_once_with(
|
|
29
|
+
client, _RUN_PATH+"/test_service", _POST,
|
|
30
|
+
data="encoded_input", token="test_token", timeout=30)
|
|
29
31
|
mock_decode_output.assert_called_once_with("response_text", "output_file")
|
|
30
32
|
assert response == mock_response
|
|
31
33
|
|
|
@@ -41,7 +43,9 @@ def test_run_service_with_input_no_token(mock_encode_input, mock_make_request, c
|
|
|
41
43
|
response = client.run_service("test_service", input="test_input")
|
|
42
44
|
|
|
43
45
|
mock_encode_input.assert_called_once_with("test_input")
|
|
44
|
-
mock_make_request.assert_called_once_with(
|
|
46
|
+
mock_make_request.assert_called_once_with(
|
|
47
|
+
client, _RUN_PATH+"/test_service", _POST,
|
|
48
|
+
data="encoded_input", token="test_token", timeout=None)
|
|
45
49
|
assert response == mock_response
|
|
46
50
|
|
|
47
51
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import json
|
|
1
2
|
import pytest
|
|
2
3
|
from unittest.mock import MagicMock, patch
|
|
3
4
|
from oscar_python.storage import Storage
|
|
@@ -11,7 +12,10 @@ def mock_client_obj():
|
|
|
11
12
|
@pytest.fixture
|
|
12
13
|
def storage(mock_client_obj):
|
|
13
14
|
mock_response = MagicMock()
|
|
14
|
-
mock_response.text =
|
|
15
|
+
mock_response.text = json.dumps({
|
|
16
|
+
"minio_provider": {"access_key": "key", "secret_key": "secret",
|
|
17
|
+
"endpoint": "http://test.endpoint",
|
|
18
|
+
"region": "us-east-1", "verify": False}})
|
|
15
19
|
with patch('oscar_python._utils.make_request', return_value=mock_response):
|
|
16
20
|
return Storage(mock_client_obj)
|
|
17
21
|
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import base64
|
|
2
|
+
import json
|
|
3
|
+
import pytest
|
|
2
4
|
from unittest.mock import patch, MagicMock, mock_open
|
|
3
5
|
|
|
4
6
|
import oscar_python._utils as utils
|
|
@@ -74,7 +76,72 @@ def test_make_request_post():
|
|
|
74
76
|
mock_request.return_value.raise_for_status = MagicMock()
|
|
75
77
|
response = utils.make_request(c, "/test", "post", data="test_data", token="test_token")
|
|
76
78
|
assert response.status_code == 200
|
|
77
|
-
mock_request.assert_called_once_with(
|
|
79
|
+
mock_request.assert_called_once_with(
|
|
80
|
+
"post", "http://test.com/test",
|
|
81
|
+
headers={"Authorization": "Bearer test_token"},
|
|
82
|
+
verify=True, data="test_data", timeout=60)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def test_load_config(tmp_path):
|
|
86
|
+
config_file = tmp_path / "config.json"
|
|
87
|
+
config_file.write_text(json.dumps({
|
|
88
|
+
"clusters": {
|
|
89
|
+
"default": {
|
|
90
|
+
"endpoint": "http://test.cluster",
|
|
91
|
+
"user": "test_user",
|
|
92
|
+
"password": "test_pass",
|
|
93
|
+
"ssl": False
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}))
|
|
97
|
+
opts = utils.load_config(str(config_file))
|
|
98
|
+
assert opts["cluster_id"] == "default"
|
|
99
|
+
assert opts["endpoint"] == "http://test.cluster"
|
|
100
|
+
assert opts["user"] == "test_user"
|
|
101
|
+
assert opts["password"] == "test_pass"
|
|
102
|
+
assert opts["ssl"] is False
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def test_load_config_with_oidc(tmp_path):
|
|
106
|
+
config_file = tmp_path / "config.json"
|
|
107
|
+
config_file.write_text(json.dumps({
|
|
108
|
+
"clusters": {
|
|
109
|
+
"oidc_cluster": {
|
|
110
|
+
"endpoint": "http://oidc.cluster",
|
|
111
|
+
"oidc_token": "test_token",
|
|
112
|
+
"ssl": True
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}))
|
|
116
|
+
opts = utils.load_config(str(config_file), "oidc_cluster")
|
|
117
|
+
assert opts["cluster_id"] == "oidc_cluster"
|
|
118
|
+
assert opts["endpoint"] == "http://oidc.cluster"
|
|
119
|
+
assert "user" not in opts
|
|
120
|
+
assert opts["oidc_token"] == "test_token"
|
|
121
|
+
assert opts["ssl"] is True
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def test_load_config_missing_cluster(tmp_path):
|
|
125
|
+
config_file = tmp_path / "config.json"
|
|
126
|
+
config_file.write_text(json.dumps({"clusters": {}}))
|
|
127
|
+
with pytest.raises(KeyError):
|
|
128
|
+
utils.load_config(str(config_file), "nonexistent")
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def test_load_config_minimal(tmp_path):
|
|
132
|
+
config_file = tmp_path / "config.json"
|
|
133
|
+
config_file.write_text(json.dumps({
|
|
134
|
+
"clusters": {
|
|
135
|
+
"minimal": {
|
|
136
|
+
"endpoint": "http://minimal.cluster"
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}))
|
|
140
|
+
opts = utils.load_config(str(config_file), "minimal")
|
|
141
|
+
assert opts["endpoint"] == "http://minimal.cluster"
|
|
142
|
+
assert opts["ssl"] is True
|
|
143
|
+
for key in ("user", "password", "shortname", "oidc_token", "refresh_token"):
|
|
144
|
+
assert key not in opts
|
|
78
145
|
|
|
79
146
|
|
|
80
147
|
def test_make_request_get():
|
|
@@ -34,7 +34,7 @@ def test_webdav_download_file(webdav):
|
|
|
34
34
|
webdav.client = MagicMock(["download_sync"])
|
|
35
35
|
webdav.client.download_sync.return_value = None
|
|
36
36
|
|
|
37
|
-
with patch("builtins.open", mock_open())
|
|
37
|
+
with patch("builtins.open", mock_open()):
|
|
38
38
|
webdav.download_file('local_path', 'remote_path/file.txt')
|
|
39
39
|
|
|
40
40
|
webdav.client.download_sync.assert_called_with('remote_path/file.txt', 'local_path/file.txt')
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
import pytest
|
|
2
|
-
import json
|
|
3
|
-
from unittest.mock import patch, mock_open
|
|
4
|
-
from oscar_python.client import Client
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
@pytest.fixture
|
|
8
|
-
def options():
|
|
9
|
-
return {
|
|
10
|
-
'cluster_id': 'test_cluster',
|
|
11
|
-
'endpoint': 'http://test.endpoint',
|
|
12
|
-
'user': 'test_user',
|
|
13
|
-
'password': 'test_password',
|
|
14
|
-
'ssl': True,
|
|
15
|
-
'shortname': 'test_shortname',
|
|
16
|
-
'oidc_token': 'test_oidc_token'
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def test_basic_auth_client(options):
|
|
21
|
-
client = Client(options)
|
|
22
|
-
assert client.id == options['cluster_id']
|
|
23
|
-
assert client.endpoint == options['endpoint']
|
|
24
|
-
assert client.user == options['user']
|
|
25
|
-
assert client.password == options['password']
|
|
26
|
-
assert client.ssl == options['ssl']
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
def test_oidc_agent_client(options):
|
|
30
|
-
del options['user']
|
|
31
|
-
client = Client(options)
|
|
32
|
-
assert client.id == options['cluster_id']
|
|
33
|
-
assert client.endpoint == options['endpoint']
|
|
34
|
-
assert client.shortname == options['shortname']
|
|
35
|
-
assert client.ssl == options['ssl']
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
def test_oidc_client(options):
|
|
39
|
-
del options['user']
|
|
40
|
-
del options['shortname']
|
|
41
|
-
client = Client(options)
|
|
42
|
-
assert client.id == options['cluster_id']
|
|
43
|
-
assert client.endpoint == options['endpoint']
|
|
44
|
-
assert client.oidc_token == options['oidc_token']
|
|
45
|
-
assert client.ssl == options['ssl']
|
|
46
|
-
|
|
47
|
-
del options['oidc_token']
|
|
48
|
-
options['refresh_token'] = 'test_refresh_token'
|
|
49
|
-
options['scopes'] = ['openid', 'profile', 'email']
|
|
50
|
-
options['token_endpoint'] = 'test_token_endpoint'
|
|
51
|
-
client = Client(options)
|
|
52
|
-
assert client.refresh_token == options['refresh_token']
|
|
53
|
-
assert client.scopes == ['openid', 'profile', 'email']
|
|
54
|
-
assert client.token_endpoint == options['token_endpoint']
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
def test_set_auth_type(options):
|
|
58
|
-
client = Client(options)
|
|
59
|
-
assert client._AUTH_TYPE == "basicauth"
|
|
60
|
-
|
|
61
|
-
del options['user']
|
|
62
|
-
client = Client(options)
|
|
63
|
-
assert client._AUTH_TYPE == "oidc-agent"
|
|
64
|
-
|
|
65
|
-
del options['shortname']
|
|
66
|
-
options['oidc_token'] = 'test_oidc_token'
|
|
67
|
-
client = Client(options)
|
|
68
|
-
assert client._AUTH_TYPE == "oidc"
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
def test_get_cluster_info(options):
|
|
72
|
-
client = Client(options)
|
|
73
|
-
with patch('oscar_python._utils.make_request') as mock_request:
|
|
74
|
-
client.get_cluster_info()
|
|
75
|
-
mock_request.assert_called_once_with(client, "/system/info", "get")
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
def test_get_cluster_config(options):
|
|
79
|
-
client = Client(options)
|
|
80
|
-
with patch('oscar_python._utils.make_request') as mock_request:
|
|
81
|
-
client.get_cluster_config()
|
|
82
|
-
mock_request.assert_called_once_with(client, "/system/config", "get")
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
def test_list_services(options):
|
|
86
|
-
client = Client(options)
|
|
87
|
-
with patch('oscar_python._utils.make_request') as mock_request:
|
|
88
|
-
client.list_services()
|
|
89
|
-
mock_request.assert_called_once_with(client, "/system/services", "get")
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
def test_get_service(options):
|
|
93
|
-
client = Client(options)
|
|
94
|
-
with patch('oscar_python._utils.make_request') as mock_request:
|
|
95
|
-
client.get_service("test_service")
|
|
96
|
-
mock_request.assert_called_once_with(client, "/system/services/test_service", "get")
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
def test_create_service_from_dict(options):
|
|
100
|
-
client = Client(options)
|
|
101
|
-
service_definition = {"name": "test_service"}
|
|
102
|
-
with patch('oscar_python._utils.make_request') as mock_request:
|
|
103
|
-
client.create_service(service_definition)
|
|
104
|
-
mock_request.assert_called_with(client, "/system/services", "post",
|
|
105
|
-
data=json.dumps(service_definition))
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
def test_create_service_from_file(options):
|
|
109
|
-
client = Client(options)
|
|
110
|
-
service_definition = "functions:\n oscar:\n - test_cluster:\n name: test_service\n script: test_script\n cpu: 1"
|
|
111
|
-
service_file = "path/to/service.yaml"
|
|
112
|
-
with patch('os.path.isfile', return_value=True), \
|
|
113
|
-
patch('builtins.open', mock_open(read_data=service_definition)), \
|
|
114
|
-
patch('oscar_python._utils.make_request') as mock_request:
|
|
115
|
-
client.create_service(service_file)
|
|
116
|
-
assert mock_request.call_args[0][0] == client
|
|
117
|
-
assert mock_request.call_args[0][1] == "/system/services"
|
|
118
|
-
assert mock_request.call_args[0][2] == "post"
|
|
119
|
-
assert json.loads(mock_request.call_args[1]['data']) == {"name": "test_service",
|
|
120
|
-
"cpu": "1",
|
|
121
|
-
"script": service_definition}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
def test_update_service_from_dict(options):
|
|
125
|
-
client = Client(options)
|
|
126
|
-
new_service = {"name": "test_service"}
|
|
127
|
-
with patch('oscar_python._utils.make_request') as mock_request:
|
|
128
|
-
mock_request.return_value.status_code = 200
|
|
129
|
-
client.update_service("test_service", new_service)
|
|
130
|
-
mock_request.assert_called_with(client, "/system/services",
|
|
131
|
-
"put", data=json.dumps(new_service))
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
def test_remove_service(options):
|
|
135
|
-
client = Client(options)
|
|
136
|
-
with patch('oscar_python._utils.make_request') as mock_request:
|
|
137
|
-
client.remove_service("test_service")
|
|
138
|
-
mock_request.assert_called_once_with(client, "/system/services/test_service", "delete")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/jupyter_example/services/cowsay_example/cowsay.yaml
RENAMED
|
File without changes
|
{oscar_python-1.3.4b1 → oscar_python-2.0.0b1}/jupyter_example/services/cowsay_example/script.sh
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|