ciocore 8.0.1__py2.py3-none-any.whl → 8.1.0b3__py2.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.

Potentially problematic release.


This version of ciocore might be problematic. Click here for more details.

Binary file
ciocore/package_tree.py CHANGED
@@ -14,6 +14,7 @@ The only functions you should need from this module are:
14
14
 
15
15
  import copy
16
16
  import json
17
+ import re
17
18
 
18
19
  WINDOWS = "windows"
19
20
  LINUX = "linux"
@@ -382,15 +383,11 @@ def _find_by_path(tree, path):
382
383
  finds a matching package, we use that package as the root of the tree for the next search. As we
383
384
  are searching for an exact path match, we limit the search to one level deep each time.
384
385
  """
385
-
386
- if not path:
387
- return None
388
-
389
-
390
386
  result = None
391
- for name in [p for p in path.split("/") if p]:
392
- tree = _find_by_name(tree, name, 1)
393
- result = tree
387
+ if path:
388
+ for name in [p for p in re.split(r'[\/|]', path) if p]:
389
+ tree = _find_by_name(tree, name, 1)
390
+ result = tree
394
391
  return result
395
392
 
396
393
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ciocore
3
- Version: 8.0.1
3
+ Version: 8.1.0b3
4
4
  Summary: Core functionality for Conductor's client tools
5
5
  Home-page: https://github.com/ConductorTechnologies/ciocore
6
6
  Author: conductor
@@ -9,7 +9,6 @@ Classifier: Operating System :: OS Independent
9
9
  Classifier: Programming Language :: Python
10
10
  Classifier: Topic :: Multimedia :: Graphics :: 3D Rendering
11
11
  Description-Content-Type: text/markdown
12
- Requires-Dist: requests[use_chardet_on_py3] ==2.28.1
13
12
  Requires-Dist: pyjwt ==1.7.1
14
13
  Requires-Dist: future >=0.18.2
15
14
  Requires-Dist: cioseq <1.0.0,>=0.4.1
@@ -51,6 +50,13 @@ See [CONTRIBUTING](CONTRIBUTING.md)
51
50
 
52
51
  ## Changelog
53
52
 
53
+ ## Unreleased:
54
+
55
+ * 8.1.0-beta.2
56
+ * Allow bar and fw slash as separators for package paths
57
+ * Adds a get_account_data method to the Python API so we can provide account ID in requests
58
+ * Remove chardet from requirements as it caused conflicts
59
+
54
60
  ## Version:8.0.1 -- 22 Apr 2024
55
61
 
56
62
  * The uploader now sends all error messages to the dashboard - not just the first error.
@@ -1,20 +1,20 @@
1
- ciocore/VERSION,sha256=NUqt24vsbMosc7cU07CLlLBV2gAdKgs8roFBqy0xjlA,5
1
+ ciocore/VERSION,sha256=2DRqOK9nMlSC11Nee86uSKsieXWZ1KvFlSNzs6gNdTs,12
2
2
  ciocore/__init__.py,sha256=aTP7LeeosQA8BZE67gDV4jgfTK5zxmwZRjiTRu_ZWj0,646
3
- ciocore/api_client.py,sha256=TyHXGmK4uTmKV93O_IpAvttZhbexIIZTGP-IVn_WyWM,24599
3
+ ciocore/api_client.py,sha256=LvxG1EfUte3NjLiuVqFUwP2iBRaUdaNSKt4wMu9Bajs,33508
4
4
  ciocore/cli.py,sha256=jZ1lOKQiUcrMhsVmD9SVmPMFwHtgDF4SaoAf2-PBS54,15449
5
5
  ciocore/client_db.py,sha256=tTz3bl2xeDPPcYSDS3g3QgV_xYihJMx0Kj6OeN2klK0,12978
6
6
  ciocore/common.py,sha256=mBIS6KiYoQsjWe6aIFUGRRvCMl8BIN2kmLZ4J8icap8,14982
7
7
  ciocore/compat.py,sha256=5uEXPSog_jxsDMaHBswAKEtfyXT25VgU6WNGIhz9PHU,256
8
8
  ciocore/conductor_submit.py,sha256=ONE0LsA5hGavTJIOXXYx8qzl8_vBPADwhd6Ytq_0E0c,9382
9
9
  ciocore/config.py,sha256=rCL7kaFn1tYgSglN8q9Wx6SwMpoXTq0BMQGwPRVwVIg,8973
10
- ciocore/data.py,sha256=Ji0qUk8nJXBNakoHSqBiVx8O58SbZXyt273SHlEDn3U,7027
10
+ ciocore/data.py,sha256=_FD0sZLvLrJUXo03as3cb1RsHihL95jDCDz3MoyvNvQ,7315
11
11
  ciocore/exceptions.py,sha256=4Oq-WX-qiN6kPUdBCHvvd6mtSQ0nCkDbJxWt2CNtpv8,1504
12
12
  ciocore/file_utils.py,sha256=swA7th9WhDEloW69YViRTKB-oeC9UmNdEGegfH1r-Gw,17176
13
13
  ciocore/hardware_set.py,sha256=FlRQiGCLRcSW7Oko_gzgVK8ZqJ_J92eT8e_AleAbS2E,17047
14
14
  ciocore/loggeria.py,sha256=2xdQRFb9NyXynU2O_pSOszJWcpoHgPwTUWJvERg7ODY,15251
15
15
  ciocore/package_environment.py,sha256=MEHV7jfs3NJIEYCIaW8JfJdBmelvPHZMmBzPlXETiRo,7808
16
16
  ciocore/package_query.py,sha256=2m5EBXfu1lmqupZrFF8f8mfkX_PgijpdMxCtFI5e5s0,5574
17
- ciocore/package_tree.py,sha256=vkORKXxQ7dO8l0_96eFwm-5AUVL0rP9bhgWYhW_v3lo,15649
17
+ ciocore/package_tree.py,sha256=r_UBxV5sVthdrFEGOkJlM-8ktKakkwsq_y9aBMz1ti4,15653
18
18
  ciocore/post_install.py,sha256=zu5Ctz2ANbKD-f5G2ODLIhKkWENBi4F3UKKu50OEWrg,1000
19
19
  ciocore/retry.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
20
  ciocore/validator.py,sha256=f_K7gxz122W_i5AxVx6dKhckOygl8TnmQiVj7tyX5zw,2344
@@ -24,13 +24,13 @@ ciocore/auth/server.py,sha256=8btX9-EokUl6q55V8muDmEV2tvvbTBD0BHeWFbwkzUc,3892
24
24
  ciocore/docsite/404.html,sha256=zUCnDe9r5yFZh8MXcTmzDaFyYBuRHz1gvuyJS2rYiTI,17207
25
25
  ciocore/docsite/index.html,sha256=xz215H_KHWBYI1HT7IRpAZ4d1ptUiO8Y4DlOmbEPgPk,20945
26
26
  ciocore/docsite/logo.png,sha256=gArgFFWdw8w985-0TkuGIgU_pW9sziEMZdqytXb5WLo,2825
27
- ciocore/docsite/objects.inv,sha256=s2FKStLlVIQbfG7U2-nw-7rz4unvd1W0u00YtLBxAKo,758
27
+ ciocore/docsite/objects.inv,sha256=la6BNz_7lZoDCr3Nin1oAB7Y7DvIy4ZOKUvR-9hfwko,785
28
28
  ciocore/docsite/sitemap.xml,sha256=M_V85zl0y2adRvzJAnoCxlZH_Hl7TLnIb1A-6l_xGmI,109
29
- ciocore/docsite/sitemap.xml.gz,sha256=mBXMN84utPFOOhXBKJnq47kV3Zp6NvUz5Xxy7lDOxq8,127
30
- ciocore/docsite/apidoc/api_client/index.html,sha256=0AdyUY-LmL5ZqUeqxIjjzmoZDbupNcImCWf7RFeO5-o,170218
29
+ ciocore/docsite/sitemap.xml.gz,sha256=em4iu7zKmOkZgFbmMbI_E6t_BlR_viXFUAOuB44IrWY,127
30
+ ciocore/docsite/apidoc/api_client/index.html,sha256=qXLzKggMPnORGOzywLCYVD2Lre1M_3y3dli8fdj3ulo,193119
31
31
  ciocore/docsite/apidoc/apidoc/index.html,sha256=KGsHBY6GBF380w338GfOIMWnwAyyLvw2i1RQFORdwlE,26171
32
32
  ciocore/docsite/apidoc/config/index.html,sha256=n3koKPRUza5-uHUt8hK8H8XyH6HG_U2CsGobdaN4KfY,72559
33
- ciocore/docsite/apidoc/data/index.html,sha256=QhqiXUd_3qk_jGRYB5JiqlJTem8Jg7aKa5mPPDT1978,50850
33
+ ciocore/docsite/apidoc/data/index.html,sha256=cXDztSoMYKeHP5cz370AoyMjKOH-gmF6oYCZk0psNGY,51962
34
34
  ciocore/docsite/apidoc/hardware_set/index.html,sha256=4GEBYy5uLVlJqvdG71RdyrN7sKKuxszxipgmRi_NCbM,123042
35
35
  ciocore/docsite/apidoc/package_environment/index.html,sha256=1d4hVlBXPy4bldkBH1GsRjVd-bxdYANmB-Mg7xIAC_4,69248
36
36
  ciocore/docsite/apidoc/package_tree/index.html,sha256=7GaOHXeM_oKH8Db25f2-h5kUI1R6pcp0bXxW1COCJxs,109393
@@ -81,7 +81,7 @@ ciocore/docsite/cmdline/downloader/index.html,sha256=917XE3waukGnIXI9qxl0zYEf3vH
81
81
  ciocore/docsite/cmdline/packages/index.html,sha256=Ssb2R7eSubBNR824oc3jjhJfrG3JKOPojA-uiAczgeQ,20923
82
82
  ciocore/docsite/cmdline/uploader/index.html,sha256=TtLbHNlu4ofZ4bQBqam87RelWdHnVDSL7_rw_YqBbC8,25123
83
83
  ciocore/docsite/how-to-guides/index.html,sha256=rF-DMyk4k_jGUJRF3dKtMMiOgXS8OvBqAn-zxWy3AGs,20100
84
- ciocore/docsite/search/search_index.json,sha256=ZMAbHLAlwOTujgA32XJTA7SHogRYh9i-ioPFOxjjJ0s,182633
84
+ ciocore/docsite/search/search_index.json,sha256=PZRdMiiSfYE_yytH50tR7cYO1CRmlknnrbM2BFDl2Oc,190641
85
85
  ciocore/docsite/stylesheets/extra.css,sha256=_Cxe9Dhg1BBi6Kqaz_iZD9z9VyqxA9vtONRjP4PVic0,354
86
86
  ciocore/docsite/stylesheets/tables.css,sha256=LE_zwGRxGcdPIy-9QiVPecOzlEBSqZb_WP5vDkFE0ZM,3235
87
87
  ciocore/downloader/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -103,7 +103,7 @@ tests/extra_env_fixtures.py,sha256=8qvU4d8SXGKzRVNR5whVqKCQOwOVMiFVfbKBAjxa2gE,1
103
103
  tests/instance_type_fixtures.py,sha256=uIzQduqKQVgjllMuyXaYnRC-pwqk5lnTx3NY2M5Nujo,4320
104
104
  tests/package_fixtures.py,sha256=CsJnhB7oYzIxJH7b1tCOPyvnnVSCqEbSPhtCnsHL-nA,5070
105
105
  tests/project_fixtures.py,sha256=iBm_th_JtAw76vlNu7Jjhh9tLH4oOaNi-MgtPzCV7yQ,138
106
- tests/test_api_client.py,sha256=tnYkIYvDILGJRatZM0nrtr83x8yBJstMP0Rt151U2gI,6757
106
+ tests/test_api_client.py,sha256=qQATQRBBUYr0G2deZHeCflNvvPo36CJyn_5xS29YPUA,16244
107
107
  tests/test_base_downloader.py,sha256=SS7tWKv2ZZhpUDk4UCg1TkrNrpntjSewgzLl1mEubSE,3603
108
108
  tests/test_cli.py,sha256=_WTs2SWlEgd6wtg1hmOBlFnbWVdFLvqp0KqNhy-y2e8,5532
109
109
  tests/test_common.py,sha256=tY_-SY-JmJX09UehFs9RIDqZ785AmhfTl6eVKJeIUFY,763
@@ -120,8 +120,8 @@ tests/test_uploader.py,sha256=B1llTJt_fqR6e_V_Jxfw9z73QgkFlEPU87xLYGzt-TQ,2914
120
120
  tests/test_validator.py,sha256=2fY66ayNc08PGyj2vTI-V_1yeCWJDngkj2zkUM5TTCI,1526
121
121
  tests/mocks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
122
122
  tests/mocks/glob.py,sha256=J2MH7nqi6NJOHuGdVWxhfeBd700_Ckj6cLh_8jSNkfg,215
123
- ciocore-8.0.1.dist-info/METADATA,sha256=798KBccoox0YMHAcd09zV7pIzVkXN_GNoBWhckmK4D4,18440
124
- ciocore-8.0.1.dist-info/WHEEL,sha256=DZajD4pwLWue70CAfc7YaxT1wLUciNBvN_TTcvXpltE,110
125
- ciocore-8.0.1.dist-info/entry_points.txt,sha256=cCqcALMYbC4d8545V9w0Zysfg9MVuKWhzDQ2er4UfGE,47
126
- ciocore-8.0.1.dist-info/top_level.txt,sha256=SvlM5JlqULzAz00JZWfiUhfjhqDzYzSWssA87zdJl0o,14
127
- ciocore-8.0.1.dist-info/RECORD,,
123
+ ciocore-8.1.0b3.dist-info/METADATA,sha256=2xTpGaHNdwWS50Z-TLAAokcROv9uxcY2Y_DD4-YwPKM,18644
124
+ ciocore-8.1.0b3.dist-info/WHEEL,sha256=DZajD4pwLWue70CAfc7YaxT1wLUciNBvN_TTcvXpltE,110
125
+ ciocore-8.1.0b3.dist-info/entry_points.txt,sha256=cCqcALMYbC4d8545V9w0Zysfg9MVuKWhzDQ2er4UfGE,47
126
+ ciocore-8.1.0b3.dist-info/top_level.txt,sha256=SvlM5JlqULzAz00JZWfiUhfjhqDzYzSWssA87zdJl0o,14
127
+ ciocore-8.1.0b3.dist-info/RECORD,,
tests/test_api_client.py CHANGED
@@ -2,9 +2,11 @@
2
2
 
3
3
  isort:skip_file
4
4
  """
5
+ import datetime
6
+ import json
5
7
  import sys
6
8
  import unittest
7
- import json
9
+
8
10
  try:
9
11
  from unittest import mock
10
12
  except ImportError:
@@ -12,7 +14,11 @@ except ImportError:
12
14
 
13
15
  from ciocore import api_client
14
16
 
15
- from ciocore.api_client import request_extra_environment
17
+
18
+ from ciocore.api_client import _get_compute_usage, get_compute_usage
19
+ from ciocore.api_client import _get_storage_usage, get_storage_usage
20
+ from ciocore.api_client import request_extra_environment, get_account_data
21
+
16
22
 
17
23
  class ApiClientTest(unittest.TestCase):
18
24
  @staticmethod
@@ -164,3 +170,212 @@ class TestRequestExtraEnvironment(unittest.TestCase):
164
170
 
165
171
  self.assertEqual("Error: Could not get account environment!", str(context.exception))
166
172
  mock_ApiClient.assert_called_once()
173
+
174
+ class TestGetComputeUsage(unittest.TestCase):
175
+
176
+ def setUp(self):
177
+
178
+ # Precison is rounded to 4 places to avoid FP issues.
179
+ self.compute_response_data = {
180
+ "data": [
181
+ {
182
+ "cores": 0.5,
183
+ "instance_cost": 0.0200,
184
+ "license_cost": 0.0200,
185
+ "minutes": 6.9700,
186
+ "self_link": 0,
187
+ "start_time": "Tue, 09 Jan 2024 18:00:00 GMT"
188
+ },
189
+ {
190
+ "cores": 0.4,
191
+ "instance_cost": 0.0200,
192
+ "license_cost": 0.0200,
193
+ "minutes": 6.9600,
194
+ "self_link": 1,
195
+ "start_time": "Tue, 09 Jan 2024 19:00:00 GMT"
196
+ },
197
+ {
198
+ "cores": 0.9613,
199
+ "instance_cost": 0.0400,
200
+ "license_cost": 0.0800,
201
+ "minutes": 7.2100,
202
+ "self_link": 2,
203
+ "start_time": "Tue, 16 Jan 2024 17:00:00 GMT"
204
+ },
205
+ ]
206
+ }
207
+
208
+ self.response_ok = mock.MagicMock(status_code=200, text=json.dumps(self.compute_response_data))
209
+ self.response_error = mock.MagicMock(status_code=500, text=json.dumps({"error": "Internal Server Error"}))
210
+
211
+ @mock.patch("ciocore.api_client.ApiClient")
212
+ @mock.patch("ciocore.api_client.read_conductor_credentials")
213
+ @mock.patch("ciocore.api_client.account_id_from_jwt")
214
+ def test_query_raw_compute_usage(self, mock_account_id_from_jwt, mock_read_conductor_credentials, mock_ApiClient):
215
+ # Set up mocks for successful execution
216
+ mock_read_conductor_credentials.return_value = "valid_token"
217
+ mock_account_id_from_jwt.return_value = "123"
218
+ mock_api_instance = mock_ApiClient.return_value
219
+ mock_api_instance.make_request.return_value = (self.response_ok.text, self.response_ok.status_code)
220
+
221
+ start_time = datetime.datetime(2024, 1, 1)
222
+ end_time = datetime.datetime(2024, 3, 20)
223
+
224
+ result = _get_compute_usage(start_time, end_time)
225
+
226
+ self.assertEqual(result, self.compute_response_data['data'])
227
+
228
+ @mock.patch("ciocore.api_client.ApiClient")
229
+ @mock.patch("ciocore.api_client.read_conductor_credentials")
230
+ @mock.patch("ciocore.api_client.account_id_from_jwt")
231
+ def test_compute_usage(self, mock_account_id_from_jwt, mock_read_conductor_credentials, mock_ApiClient):
232
+ # Set up mocks for successful execution
233
+ mock_read_conductor_credentials.return_value = "valid_token"
234
+ mock_account_id_from_jwt.return_value = "123"
235
+ mock_api_instance = mock_ApiClient.return_value
236
+ mock_api_instance.make_request.return_value = (self.response_ok.text, self.response_ok.status_code)
237
+
238
+ start_time = datetime.datetime(2024, 1, 1)
239
+ end_time = datetime.datetime(2024, 3, 20)
240
+
241
+ result = get_compute_usage(start_time=start_time, end_time=end_time)
242
+
243
+ self.assertEqual(result, { '2024-01-09': {'cost': 0.08,
244
+ 'corehours': 0.9,
245
+ 'walltime': 13.93},
246
+ '2024-01-16': { 'cost': 0.12,
247
+ 'corehours': 0.9613,
248
+ 'walltime': 7.21}})
249
+
250
+ @mock.patch("ciocore.api_client.ApiClient")
251
+ def test_get_compute_usage_api_failure(self, mock_ApiClient):
252
+ # Set up mock for API failure
253
+ mock_api_instance = mock_ApiClient.return_value
254
+ mock_api_instance.make_request.return_value = (self.response_error.text, self.response_error.status_code)
255
+
256
+ start_time = datetime.datetime(2024, 1, 1)
257
+ end_time = datetime.datetime(2024, 3, 20)
258
+
259
+ # Assert exception raised when the API call fails
260
+ with self.assertRaises(Exception) as context:
261
+ get_compute_usage(start_time, end_time)
262
+
263
+ self.assertIn('Failed to query compute usage', str(context.exception))
264
+ mock_ApiClient.assert_called_once()
265
+ class TestGetStorageUsage(unittest.TestCase):
266
+
267
+ def setUp(self):
268
+
269
+ self.storage_response_data = {
270
+ "data": [
271
+ {
272
+ "cost": "28.96",
273
+ "cost_per_day": [
274
+ 4.022,
275
+ 4.502,
276
+ 4.502,
277
+ 5.102,
278
+ 5.102,
279
+ 5.732
280
+ ],
281
+ "currency": "USD",
282
+ "daily_price": "0.006",
283
+ "end_date": "2024-01-07",
284
+ "gibs_per_day": [
285
+ 679.714,
286
+ 750.34,
287
+ 750.34,
288
+ 850.36,
289
+ 850.35,
290
+ 955.32
291
+ ],
292
+ "gibs_used": "806.07",
293
+ "monthly_price": "0.18",
294
+ "start_date": "2024-01-01",
295
+ "storage_unit": "GiB"
296
+ }
297
+ ]
298
+ }
299
+
300
+ self.response_ok = mock.MagicMock(status_code=200, text=json.dumps(self.storage_response_data))
301
+ self.response_error = mock.MagicMock(status_code=500, text=json.dumps({"error": "Internal Server Error"}))
302
+
303
+ @mock.patch("ciocore.api_client.ApiClient")
304
+ @mock.patch("ciocore.api_client.read_conductor_credentials")
305
+ @mock.patch("ciocore.api_client.account_id_from_jwt")
306
+ def test_query_raw_storage_usage(self, mock_account_id_from_jwt, mock_read_conductor_credentials, mock_ApiClient):
307
+ # Set up mocks for successful execution
308
+ mock_read_conductor_credentials.return_value = "valid_token"
309
+ mock_account_id_from_jwt.return_value = "123"
310
+ mock_api_instance = mock_ApiClient.return_value
311
+ mock_api_instance.make_request.return_value = (self.response_ok.text, self.response_ok.status_code)
312
+
313
+ start_time = datetime.datetime(2024, 5, 1)
314
+ end_time = datetime.datetime(2024, 5, 17)
315
+
316
+ result = _get_storage_usage(start_time, end_time)
317
+
318
+ self.assertEqual(result, self.storage_response_data['data'][0])
319
+
320
+ @mock.patch("ciocore.api_client.ApiClient")
321
+ @mock.patch("ciocore.api_client.read_conductor_credentials")
322
+ @mock.patch("ciocore.api_client.account_id_from_jwt")
323
+ def test_storage_usage(self, mock_account_id_from_jwt, mock_read_conductor_credentials, mock_ApiClient):
324
+ # Set up mocks for successful execution
325
+ mock_read_conductor_credentials.return_value = "valid_token"
326
+ mock_account_id_from_jwt.return_value = "123"
327
+ mock_api_instance = mock_ApiClient.return_value
328
+ mock_api_instance.make_request.return_value = (self.response_ok.text, self.response_ok.status_code)
329
+
330
+ start_time = datetime.datetime(2024, 1, 1)
331
+ end_time = datetime.datetime(2024, 1, 7)
332
+
333
+ result = get_storage_usage(start_time=start_time, end_time=end_time)
334
+
335
+ self.assertEqual(result, { '2024-01-01': {'cost': 4.022, 'GiB': 679.714},
336
+ '2024-01-02': {'cost': 4.502, 'GiB': 750.34},
337
+ '2024-01-03': {'cost': 4.502, 'GiB': 750.34},
338
+ '2024-01-04': {'cost': 5.102, 'GiB': 850.36},
339
+ '2024-01-05': {'cost': 5.102, 'GiB': 850.35},
340
+ '2024-01-06': {'cost': 5.732, 'GiB': 955.32}
341
+ })
342
+
343
+ class TestGetAccountData(unittest.TestCase):
344
+
345
+ @mock.patch('ciocore.api_client.read_conductor_credentials')
346
+ @mock.patch('ciocore.api_client.jwt.decode')
347
+ def test_get_account_data_success(self, mock_decode, mock_read_credentials):
348
+ # Setup the mocks
349
+ mock_token = 'mocked_token'
350
+ mock_read_credentials.return_value = mock_token
351
+ mock_payload = {
352
+ "email": "user@example.com",
353
+ "aud": "com.domain",
354
+ "account": "123456",
355
+ "id": "user_id",
356
+ "role": 0,
357
+ "iat": 1609459200, # 2021-01-01 00:00:00 UTC
358
+ "exp": 1612137600, # 2021-02-01 00:00:00 UTC
359
+ }
360
+ mock_decode.return_value = mock_payload
361
+
362
+ account_data = get_account_data()
363
+
364
+ # Assertions
365
+ self.assertIsNotNone(account_data)
366
+ self.assertEqual(account_data['email'], mock_payload['email'])
367
+ self.assertEqual(account_data['domain'], 'domain')
368
+ self.assertEqual(account_data['account_id'], mock_payload['account'])
369
+ self.assertEqual(account_data['user_id'], mock_payload['id'])
370
+ self.assertEqual(account_data['role'], mock_payload['role'])
371
+ self.assertEqual(account_data['issued'], datetime.datetime.fromtimestamp(mock_payload['iat']))
372
+ self.assertEqual(account_data['expiry'], datetime.datetime.fromtimestamp(mock_payload['exp']))
373
+ self.assertEqual(account_data['token'], mock_token)
374
+
375
+ @mock.patch('ciocore.api_client.read_conductor_credentials')
376
+ def test_get_account_data_no_token(self, mock_read_credentials):
377
+ mock_read_credentials.return_value = None
378
+
379
+ # Call it
380
+ account_data = get_account_data()
381
+ self.assertIsNone(account_data)