ciocore 8.0.0rc1__py2.py3-none-any.whl → 8.1.0__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.
- ciocore/VERSION +1 -1
- ciocore/api_client.py +223 -1
- ciocore/cli.py +8 -10
- ciocore/docsite/404.html +1 -1
- ciocore/docsite/apidoc/api_client/index.html +267 -1
- ciocore/docsite/apidoc/apidoc/index.html +1 -1
- ciocore/docsite/apidoc/config/index.html +1 -1
- ciocore/docsite/apidoc/data/index.html +1 -1
- ciocore/docsite/apidoc/hardware_set/index.html +1 -1
- ciocore/docsite/apidoc/package_environment/index.html +1 -1
- ciocore/docsite/apidoc/package_tree/index.html +1 -1
- ciocore/docsite/cmdline/docs/index.html +1 -1
- ciocore/docsite/cmdline/downloader/index.html +1 -1
- ciocore/docsite/cmdline/packages/index.html +1 -1
- ciocore/docsite/cmdline/uploader/index.html +1 -1
- ciocore/docsite/how-to-guides/index.html +1 -1
- ciocore/docsite/index.html +1 -1
- ciocore/docsite/objects.inv +0 -0
- ciocore/docsite/search/search_index.json +1 -1
- ciocore/docsite/sitemap.xml.gz +0 -0
- ciocore/uploader/_uploader.py +8 -7
- ciocore/worker.py +10 -5
- {ciocore-8.0.0rc1.dist-info → ciocore-8.1.0.dist-info}/METADATA +11 -3
- {ciocore-8.0.0rc1.dist-info → ciocore-8.1.0.dist-info}/RECORD +29 -29
- tests/test_api_client.py +174 -1
- tests/test_cli.py +0 -14
- {ciocore-8.0.0rc1.dist-info → ciocore-8.1.0.dist-info}/WHEEL +0 -0
- {ciocore-8.0.0rc1.dist-info → ciocore-8.1.0.dist-info}/entry_points.txt +0 -0
- {ciocore-8.0.0rc1.dist-info → ciocore-8.1.0.dist-info}/top_level.txt +0 -0
ciocore/docsite/sitemap.xml.gz
CHANGED
|
Binary file
|
ciocore/uploader/_uploader.py
CHANGED
|
@@ -640,8 +640,7 @@ class Uploader(object):
|
|
|
640
640
|
(UploadWorker, [], {"thread_count": self.args["thread_count"]}),
|
|
641
641
|
]
|
|
642
642
|
|
|
643
|
-
manager = worker.JobManager(job_description)
|
|
644
|
-
manager.start()
|
|
643
|
+
manager = worker.JobManager(job_description)
|
|
645
644
|
return manager
|
|
646
645
|
|
|
647
646
|
@common.dec_catch_exception(raise_=True)
|
|
@@ -744,7 +743,7 @@ class Uploader(object):
|
|
|
744
743
|
return True
|
|
745
744
|
|
|
746
745
|
def mark_upload_failed(self, error_message, upload_id):
|
|
747
|
-
logger.error("Upload failed:
|
|
746
|
+
logger.error("Upload failed: %s", error_message)
|
|
748
747
|
|
|
749
748
|
# report error_message to the app
|
|
750
749
|
self.api_client.make_request(
|
|
@@ -793,6 +792,7 @@ class Uploader(object):
|
|
|
793
792
|
|
|
794
793
|
# create worker pools
|
|
795
794
|
self.manager = self.create_manager(project)
|
|
795
|
+
self.manager.start()
|
|
796
796
|
|
|
797
797
|
# create reporters
|
|
798
798
|
logger.debug("creating report status thread...")
|
|
@@ -931,16 +931,17 @@ class Uploader(object):
|
|
|
931
931
|
|
|
932
932
|
if error_messages:
|
|
933
933
|
self.mark_upload_failed(
|
|
934
|
-
error_message="\n".join(error_messages),
|
|
934
|
+
error_message="Uploader ERROR: {}".format("\n".join(error_messages)),
|
|
935
|
+
upload_id=upload_id
|
|
935
936
|
)
|
|
936
937
|
|
|
937
938
|
log_file = loggeria.LOG_PATH
|
|
938
|
-
sys.stderr.write("
|
|
939
|
+
sys.stderr.write("\nError uploading files:\n")
|
|
939
940
|
|
|
940
941
|
for err_msg in error_messages:
|
|
941
|
-
sys.stderr.write("\t
|
|
942
|
+
sys.stderr.write("\t{}\n".format(err_msg))
|
|
942
943
|
|
|
943
|
-
sys.stderr.write("\nSee log
|
|
944
|
+
sys.stderr.write("\nSee log {} for more details\n\n".format(log_file))
|
|
944
945
|
|
|
945
946
|
self.error_messages = []
|
|
946
947
|
|
ciocore/worker.py
CHANGED
|
@@ -252,7 +252,7 @@ class ThreadWorker(object):
|
|
|
252
252
|
return
|
|
253
253
|
|
|
254
254
|
# don't to anything if we were not provided an out_queue
|
|
255
|
-
logger.debug("Attempting to put job to out_queue (%s -> %s)", job,
|
|
255
|
+
logger.debug("Attempting to put job to out_queue (%s -> %s)", job, self.out_queue)
|
|
256
256
|
|
|
257
257
|
if not self.out_queue:
|
|
258
258
|
return
|
|
@@ -261,7 +261,7 @@ class ThreadWorker(object):
|
|
|
261
261
|
if not WORKING:
|
|
262
262
|
return
|
|
263
263
|
|
|
264
|
-
logger.debug("Adding job to out_queue (%s -> %s)", job,
|
|
264
|
+
logger.debug("Adding job to out_queue (%s -> %s)", job, self.out_queue)
|
|
265
265
|
|
|
266
266
|
# add item to job
|
|
267
267
|
self.out_queue.put(job)
|
|
@@ -491,10 +491,15 @@ class JobManager():
|
|
|
491
491
|
while not self.error_handler_stop:
|
|
492
492
|
|
|
493
493
|
try:
|
|
494
|
-
error = self.error_queue.get(True,
|
|
494
|
+
error = self.error_queue.get(True, 0.5)
|
|
495
495
|
|
|
496
496
|
except queue.Empty:
|
|
497
|
-
|
|
497
|
+
|
|
498
|
+
if self.error:
|
|
499
|
+
break
|
|
500
|
+
|
|
501
|
+
else:
|
|
502
|
+
continue
|
|
498
503
|
|
|
499
504
|
logger.error('Got something from the error queue: %s', error)
|
|
500
505
|
self.error.append(error)
|
|
@@ -503,7 +508,7 @@ class JobManager():
|
|
|
503
508
|
except ValueError:
|
|
504
509
|
pass
|
|
505
510
|
|
|
506
|
-
|
|
511
|
+
self.stop_work(force=True)
|
|
507
512
|
|
|
508
513
|
def start_error_handler(self):
|
|
509
514
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ciocore
|
|
3
|
-
Version: 8.0
|
|
3
|
+
Version: 8.1.0
|
|
4
4
|
Summary: Core functionality for Conductor's client tools
|
|
5
5
|
Home-page: https://github.com/ConductorTechnologies/ciocore
|
|
6
6
|
Author: conductor
|
|
@@ -51,10 +51,18 @@ See [CONTRIBUTING](CONTRIBUTING.md)
|
|
|
51
51
|
|
|
52
52
|
## Changelog
|
|
53
53
|
|
|
54
|
-
## Version:8.
|
|
54
|
+
## Version:8.1.0 -- 10 Jun 2024
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
* Adds two new calls to the API to get usage; get_compute_usage() and get_storage_usage()
|
|
57
57
|
|
|
58
|
+
## Version:8.0.1 -- 22 Apr 2024
|
|
59
|
+
|
|
60
|
+
* The uploader now sends all error messages to the dashboard - not just the first error.
|
|
61
|
+
* Fixed a bug where --log-to-console was not not working as expected in the command line upload subcommand.
|
|
62
|
+
* Fixed some errors in DEBUG-level logging messages.
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
## Version:8.0.0 -- 07 Apr 2024
|
|
58
66
|
|
|
59
67
|
* The `conductor` commandline interface (CLI) has undergone a complete overhaul to improve its functionality and performance. It is now installed as a Python console script, which simplifies the installation process on all platforms and ensures that the tool is always accessible. In addition, this standardized installation allows for better integration into our Companion application and potentially customers' own proprietary tools.
|
|
60
68
|
* The commandline downloader has been rewritten to improve its performance and reliability. In previous versions, the downloader would fetch all download URLs from the server before starting any downloads. This approach was inefficient and would lead to performance issues when handling jobs with large numbers of tasks. The new downloader fetches tasks in small batches, which allows the download to start almost immediately, regardless of the number of tasks. It provides several new commandline flags, such as filtering based on filenames, and better logging, giving users more control and visibility over the download process. In addition, the new downloader has been written as an event based system that can be seamlessly integrated into other pipeline tools and GUIs. Pipeline TDs need only to register handlers to any of the events that the downloader emits.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
ciocore/VERSION,sha256=
|
|
1
|
+
ciocore/VERSION,sha256=tLQREuN8_s0dGaKmIQt0W8MTSuMhtDpdcGwzW80I8nk,5
|
|
2
2
|
ciocore/__init__.py,sha256=aTP7LeeosQA8BZE67gDV4jgfTK5zxmwZRjiTRu_ZWj0,646
|
|
3
|
-
ciocore/api_client.py,sha256=
|
|
4
|
-
ciocore/cli.py,sha256=
|
|
3
|
+
ciocore/api_client.py,sha256=SBxEwAiwn2XtH7T_ipefUbWhczXjoNdNbQBur1RV-Bw,32810
|
|
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
|
|
@@ -18,22 +18,22 @@ ciocore/package_tree.py,sha256=vkORKXxQ7dO8l0_96eFwm-5AUVL0rP9bhgWYhW_v3lo,15649
|
|
|
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
|
|
21
|
-
ciocore/worker.py,sha256=
|
|
21
|
+
ciocore/worker.py,sha256=YnE0mGqkky9uxPMyDRmvdt1p1ER_GN39AeZPIGw6f4U,21832
|
|
22
22
|
ciocore/auth/__init__.py,sha256=cdS-xZzMq41yXM5cz8sUlcYgo8CJYh8HcCCWmhbDgf0,606
|
|
23
23
|
ciocore/auth/server.py,sha256=8btX9-EokUl6q55V8muDmEV2tvvbTBD0BHeWFbwkzUc,3892
|
|
24
|
-
ciocore/docsite/404.html,sha256=
|
|
25
|
-
ciocore/docsite/index.html,sha256=
|
|
24
|
+
ciocore/docsite/404.html,sha256=zUCnDe9r5yFZh8MXcTmzDaFyYBuRHz1gvuyJS2rYiTI,17207
|
|
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=
|
|
27
|
+
ciocore/docsite/objects.inv,sha256=XwmLactPEWWC4fAWqHNPBXGsluRxLLTrwDLQqq51ONY,775
|
|
28
28
|
ciocore/docsite/sitemap.xml,sha256=M_V85zl0y2adRvzJAnoCxlZH_Hl7TLnIb1A-6l_xGmI,109
|
|
29
|
-
ciocore/docsite/sitemap.xml.gz,sha256=
|
|
30
|
-
ciocore/docsite/apidoc/api_client/index.html,sha256=
|
|
31
|
-
ciocore/docsite/apidoc/apidoc/index.html,sha256=
|
|
32
|
-
ciocore/docsite/apidoc/config/index.html,sha256=
|
|
33
|
-
ciocore/docsite/apidoc/data/index.html,sha256=
|
|
34
|
-
ciocore/docsite/apidoc/hardware_set/index.html,sha256=
|
|
35
|
-
ciocore/docsite/apidoc/package_environment/index.html,sha256=
|
|
36
|
-
ciocore/docsite/apidoc/package_tree/index.html,sha256=
|
|
29
|
+
ciocore/docsite/sitemap.xml.gz,sha256=rZcI755TcvgYJvqQWgKtBrKCVKxIJd1pLTDyxi4NFv8,127
|
|
30
|
+
ciocore/docsite/apidoc/api_client/index.html,sha256=mh9VwU1J3Ks6MWvo5a-PcUt5GYdm8s7KsIVDWfnOeXY,188372
|
|
31
|
+
ciocore/docsite/apidoc/apidoc/index.html,sha256=KGsHBY6GBF380w338GfOIMWnwAyyLvw2i1RQFORdwlE,26171
|
|
32
|
+
ciocore/docsite/apidoc/config/index.html,sha256=n3koKPRUza5-uHUt8hK8H8XyH6HG_U2CsGobdaN4KfY,72559
|
|
33
|
+
ciocore/docsite/apidoc/data/index.html,sha256=QhqiXUd_3qk_jGRYB5JiqlJTem8Jg7aKa5mPPDT1978,50850
|
|
34
|
+
ciocore/docsite/apidoc/hardware_set/index.html,sha256=4GEBYy5uLVlJqvdG71RdyrN7sKKuxszxipgmRi_NCbM,123042
|
|
35
|
+
ciocore/docsite/apidoc/package_environment/index.html,sha256=1d4hVlBXPy4bldkBH1GsRjVd-bxdYANmB-Mg7xIAC_4,69248
|
|
36
|
+
ciocore/docsite/apidoc/package_tree/index.html,sha256=7GaOHXeM_oKH8Db25f2-h5kUI1R6pcp0bXxW1COCJxs,109393
|
|
37
37
|
ciocore/docsite/assets/_mkdocstrings.css,sha256=K3bqYEmxlOHQ3-M11JNbBWHCBDBLarkFRm8HuEYrAG4,341
|
|
38
38
|
ciocore/docsite/assets/images/favicon.png,sha256=AjhUxD_Eslt5XuSVHIAZ494Fk__rb5GLXR8qm0elfP4,1870
|
|
39
39
|
ciocore/docsite/assets/javascripts/bundle.4e31edb1.min.js,sha256=vMxCR_BtNIcbmbPV6j8Z-YDLQ9ckt4RzvGuzCTg034s,97250
|
|
@@ -76,12 +76,12 @@ ciocore/docsite/assets/stylesheets/main.83068744.min.css,sha256=gwaHRErdgDoSsYab
|
|
|
76
76
|
ciocore/docsite/assets/stylesheets/main.83068744.min.css.map,sha256=q8dWQkgGSfCcYT2Le1J0Tmxpcqxol5kZKaokp9d8Af0,42278
|
|
77
77
|
ciocore/docsite/assets/stylesheets/palette.ecc896b0.min.css,sha256=7MiWsGpIt19TLduugHr1OQv1TJ9rEsndnkc2V8D9VjM,12245
|
|
78
78
|
ciocore/docsite/assets/stylesheets/palette.ecc896b0.min.css.map,sha256=T8ZT8Mw8ws4vxyx_b1QAwyC9_pnv7r0KVaUdu2ST7ug,3639
|
|
79
|
-
ciocore/docsite/cmdline/docs/index.html,sha256=
|
|
80
|
-
ciocore/docsite/cmdline/downloader/index.html,sha256=
|
|
81
|
-
ciocore/docsite/cmdline/packages/index.html,sha256=
|
|
82
|
-
ciocore/docsite/cmdline/uploader/index.html,sha256=
|
|
83
|
-
ciocore/docsite/how-to-guides/index.html,sha256=
|
|
84
|
-
ciocore/docsite/search/search_index.json,sha256=
|
|
79
|
+
ciocore/docsite/cmdline/docs/index.html,sha256=Vte3vd2TtRY34Ft6cKvUREeQrWEI9jgdTkQ0XzjZuss,20051
|
|
80
|
+
ciocore/docsite/cmdline/downloader/index.html,sha256=917XE3waukGnIXI9qxl0zYEf3vHVIQPdY3ZybmABAqc,23171
|
|
81
|
+
ciocore/docsite/cmdline/packages/index.html,sha256=Ssb2R7eSubBNR824oc3jjhJfrG3JKOPojA-uiAczgeQ,20923
|
|
82
|
+
ciocore/docsite/cmdline/uploader/index.html,sha256=TtLbHNlu4ofZ4bQBqam87RelWdHnVDSL7_rw_YqBbC8,25123
|
|
83
|
+
ciocore/docsite/how-to-guides/index.html,sha256=rF-DMyk4k_jGUJRF3dKtMMiOgXS8OvBqAn-zxWy3AGs,20100
|
|
84
|
+
ciocore/docsite/search/search_index.json,sha256=vBLU-rkC0pxOPX0O3MNKXRKGfgsaS1-91KsV17Gf9SY,189092
|
|
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
|
|
@@ -95,7 +95,7 @@ ciocore/downloader/perpetual_downloader.py,sha256=cD7lnBH75-c-ZVVPHZc1vSnDhgJOnG
|
|
|
95
95
|
ciocore/downloader/registry.py,sha256=_JIOuqpWkJkgJGN33nt-DCvqN9Gw3xeFhzPq4RUxIoE,2903
|
|
96
96
|
ciocore/downloader/reporter.py,sha256=p1NK9k6iQ-jt7lRvZR0xFz0cGb2yo8tQcjlvYKR9SWM,4501
|
|
97
97
|
ciocore/uploader/__init__.py,sha256=hxRFJf5Lo86rtRObFXSjjot8nybQd-SebSfYCbgZwow,24
|
|
98
|
-
ciocore/uploader/_uploader.py,sha256=
|
|
98
|
+
ciocore/uploader/_uploader.py,sha256=40nzqO5DuFi4sx31VvjWxZPNkrWsWqM9jtFVxs_-o3o,37479
|
|
99
99
|
ciocore/uploader/upload_stats/__init__.py,sha256=Lg1y4zq1i0cwc6Hh2K1TAQDYymLff49W-uIo1xjcvdI,5309
|
|
100
100
|
ciocore/uploader/upload_stats/stats_formats.py,sha256=giNirtObU66VALWghPFSRhg3q_vw5MvESsnXhb_I3y8,2402
|
|
101
101
|
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -103,9 +103,9 @@ 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=
|
|
106
|
+
tests/test_api_client.py,sha256=4jhj-YrBPcLj7XZn3ngguau2DPxpCYGMSuqPJ3hW0GQ,14497
|
|
107
107
|
tests/test_base_downloader.py,sha256=SS7tWKv2ZZhpUDk4UCg1TkrNrpntjSewgzLl1mEubSE,3603
|
|
108
|
-
tests/test_cli.py,sha256=
|
|
108
|
+
tests/test_cli.py,sha256=_WTs2SWlEgd6wtg1hmOBlFnbWVdFLvqp0KqNhy-y2e8,5532
|
|
109
109
|
tests/test_common.py,sha256=tY_-SY-JmJX09UehFs9RIDqZ785AmhfTl6eVKJeIUFY,763
|
|
110
110
|
tests/test_config.py,sha256=-_G682Ss3Zr1FmcMkjla1zAZprX2tQKpKc5_wD28rII,13340
|
|
111
111
|
tests/test_data.py,sha256=NIBXpCjG3Os3vpc1CkiVONrebro8D_jqQyJ0N3kbucU,5433
|
|
@@ -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.
|
|
124
|
-
ciocore-8.0.
|
|
125
|
-
ciocore-8.0.
|
|
126
|
-
ciocore-8.0.
|
|
127
|
-
ciocore-8.0.
|
|
123
|
+
ciocore-8.1.0.dist-info/METADATA,sha256=lXpW_6Xfu_wAL__6D_ePH3DcB7oyBRtIMNvv_3sK3bo,18564
|
|
124
|
+
ciocore-8.1.0.dist-info/WHEEL,sha256=DZajD4pwLWue70CAfc7YaxT1wLUciNBvN_TTcvXpltE,110
|
|
125
|
+
ciocore-8.1.0.dist-info/entry_points.txt,sha256=cCqcALMYbC4d8545V9w0Zysfg9MVuKWhzDQ2er4UfGE,47
|
|
126
|
+
ciocore-8.1.0.dist-info/top_level.txt,sha256=SvlM5JlqULzAz00JZWfiUhfjhqDzYzSWssA87zdJl0o,14
|
|
127
|
+
ciocore-8.1.0.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
|
-
|
|
9
|
+
|
|
8
10
|
try:
|
|
9
11
|
from unittest import mock
|
|
10
12
|
except ImportError:
|
|
@@ -13,6 +15,8 @@ except ImportError:
|
|
|
13
15
|
from ciocore import api_client
|
|
14
16
|
|
|
15
17
|
from ciocore.api_client import request_extra_environment
|
|
18
|
+
from ciocore.api_client import _get_compute_usage, get_compute_usage
|
|
19
|
+
from ciocore.api_client import _get_storage_usage, get_storage_usage
|
|
16
20
|
|
|
17
21
|
class ApiClientTest(unittest.TestCase):
|
|
18
22
|
@staticmethod
|
|
@@ -164,3 +168,172 @@ class TestRequestExtraEnvironment(unittest.TestCase):
|
|
|
164
168
|
|
|
165
169
|
self.assertEqual("Error: Could not get account environment!", str(context.exception))
|
|
166
170
|
mock_ApiClient.assert_called_once()
|
|
171
|
+
|
|
172
|
+
class TestGetComputeUsage(unittest.TestCase):
|
|
173
|
+
|
|
174
|
+
def setUp(self):
|
|
175
|
+
|
|
176
|
+
# Precison is rounded to 4 places to avoid FP issues.
|
|
177
|
+
self.compute_response_data = {
|
|
178
|
+
"data": [
|
|
179
|
+
{
|
|
180
|
+
"cores": 0.5,
|
|
181
|
+
"instance_cost": 0.0200,
|
|
182
|
+
"license_cost": 0.0200,
|
|
183
|
+
"minutes": 6.9700,
|
|
184
|
+
"self_link": 0,
|
|
185
|
+
"start_time": "Tue, 09 Jan 2024 18:00:00 GMT"
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
"cores": 0.4,
|
|
189
|
+
"instance_cost": 0.0200,
|
|
190
|
+
"license_cost": 0.0200,
|
|
191
|
+
"minutes": 6.9600,
|
|
192
|
+
"self_link": 1,
|
|
193
|
+
"start_time": "Tue, 09 Jan 2024 19:00:00 GMT"
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
"cores": 0.9613,
|
|
197
|
+
"instance_cost": 0.0400,
|
|
198
|
+
"license_cost": 0.0800,
|
|
199
|
+
"minutes": 7.2100,
|
|
200
|
+
"self_link": 2,
|
|
201
|
+
"start_time": "Tue, 16 Jan 2024 17:00:00 GMT"
|
|
202
|
+
},
|
|
203
|
+
]
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
self.response_ok = mock.MagicMock(status_code=200, text=json.dumps(self.compute_response_data))
|
|
207
|
+
self.response_error = mock.MagicMock(status_code=500, text=json.dumps({"error": "Internal Server Error"}))
|
|
208
|
+
|
|
209
|
+
@mock.patch("ciocore.api_client.ApiClient")
|
|
210
|
+
@mock.patch("ciocore.api_client.read_conductor_credentials")
|
|
211
|
+
@mock.patch("ciocore.api_client.account_id_from_jwt")
|
|
212
|
+
def test_query_raw_compute_usage(self, mock_account_id_from_jwt, mock_read_conductor_credentials, mock_ApiClient):
|
|
213
|
+
# Set up mocks for successful execution
|
|
214
|
+
mock_read_conductor_credentials.return_value = "valid_token"
|
|
215
|
+
mock_account_id_from_jwt.return_value = "123"
|
|
216
|
+
mock_api_instance = mock_ApiClient.return_value
|
|
217
|
+
mock_api_instance.make_request.return_value = (self.response_ok.text, self.response_ok.status_code)
|
|
218
|
+
|
|
219
|
+
start_time = datetime.datetime(2024, 1, 1)
|
|
220
|
+
end_time = datetime.datetime(2024, 3, 20)
|
|
221
|
+
|
|
222
|
+
result = _get_compute_usage(start_time, end_time)
|
|
223
|
+
|
|
224
|
+
self.assertEqual(result, self.compute_response_data['data'])
|
|
225
|
+
|
|
226
|
+
@mock.patch("ciocore.api_client.ApiClient")
|
|
227
|
+
@mock.patch("ciocore.api_client.read_conductor_credentials")
|
|
228
|
+
@mock.patch("ciocore.api_client.account_id_from_jwt")
|
|
229
|
+
def test_compute_usage(self, mock_account_id_from_jwt, mock_read_conductor_credentials, mock_ApiClient):
|
|
230
|
+
# Set up mocks for successful execution
|
|
231
|
+
mock_read_conductor_credentials.return_value = "valid_token"
|
|
232
|
+
mock_account_id_from_jwt.return_value = "123"
|
|
233
|
+
mock_api_instance = mock_ApiClient.return_value
|
|
234
|
+
mock_api_instance.make_request.return_value = (self.response_ok.text, self.response_ok.status_code)
|
|
235
|
+
|
|
236
|
+
start_time = datetime.datetime(2024, 1, 1)
|
|
237
|
+
end_time = datetime.datetime(2024, 3, 20)
|
|
238
|
+
|
|
239
|
+
result = get_compute_usage(start_time=start_time, end_time=end_time)
|
|
240
|
+
|
|
241
|
+
self.assertEqual(result, { '2024-01-09': {'cost': 0.08,
|
|
242
|
+
'corehours': 0.9,
|
|
243
|
+
'walltime': 13.93},
|
|
244
|
+
'2024-01-16': { 'cost': 0.12,
|
|
245
|
+
'corehours': 0.9613,
|
|
246
|
+
'walltime': 7.21}})
|
|
247
|
+
|
|
248
|
+
@mock.patch("ciocore.api_client.ApiClient")
|
|
249
|
+
def test_get_compute_usage_api_failure(self, mock_ApiClient):
|
|
250
|
+
# Set up mock for API failure
|
|
251
|
+
mock_api_instance = mock_ApiClient.return_value
|
|
252
|
+
mock_api_instance.make_request.return_value = (self.response_error.text, self.response_error.status_code)
|
|
253
|
+
|
|
254
|
+
start_time = datetime.datetime(2024, 1, 1)
|
|
255
|
+
end_time = datetime.datetime(2024, 3, 20)
|
|
256
|
+
|
|
257
|
+
# Assert exception raised when the API call fails
|
|
258
|
+
with self.assertRaises(Exception) as context:
|
|
259
|
+
get_compute_usage(start_time, end_time)
|
|
260
|
+
|
|
261
|
+
self.assertIn('Failed to query compute usage', str(context.exception))
|
|
262
|
+
mock_ApiClient.assert_called_once()
|
|
263
|
+
class TestGetStorageUsage(unittest.TestCase):
|
|
264
|
+
|
|
265
|
+
def setUp(self):
|
|
266
|
+
|
|
267
|
+
self.storage_response_data = {
|
|
268
|
+
"data": [
|
|
269
|
+
{
|
|
270
|
+
"cost": "28.96",
|
|
271
|
+
"cost_per_day": [
|
|
272
|
+
4.022,
|
|
273
|
+
4.502,
|
|
274
|
+
4.502,
|
|
275
|
+
5.102,
|
|
276
|
+
5.102,
|
|
277
|
+
5.732
|
|
278
|
+
],
|
|
279
|
+
"currency": "USD",
|
|
280
|
+
"daily_price": "0.006",
|
|
281
|
+
"end_date": "2024-01-07",
|
|
282
|
+
"gibs_per_day": [
|
|
283
|
+
679.714,
|
|
284
|
+
750.34,
|
|
285
|
+
750.34,
|
|
286
|
+
850.36,
|
|
287
|
+
850.35,
|
|
288
|
+
955.32
|
|
289
|
+
],
|
|
290
|
+
"gibs_used": "806.07",
|
|
291
|
+
"monthly_price": "0.18",
|
|
292
|
+
"start_date": "2024-01-01",
|
|
293
|
+
"storage_unit": "GiB"
|
|
294
|
+
}
|
|
295
|
+
]
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
self.response_ok = mock.MagicMock(status_code=200, text=json.dumps(self.storage_response_data))
|
|
299
|
+
self.response_error = mock.MagicMock(status_code=500, text=json.dumps({"error": "Internal Server Error"}))
|
|
300
|
+
|
|
301
|
+
@mock.patch("ciocore.api_client.ApiClient")
|
|
302
|
+
@mock.patch("ciocore.api_client.read_conductor_credentials")
|
|
303
|
+
@mock.patch("ciocore.api_client.account_id_from_jwt")
|
|
304
|
+
def test_query_raw_storage_usage(self, mock_account_id_from_jwt, mock_read_conductor_credentials, mock_ApiClient):
|
|
305
|
+
# Set up mocks for successful execution
|
|
306
|
+
mock_read_conductor_credentials.return_value = "valid_token"
|
|
307
|
+
mock_account_id_from_jwt.return_value = "123"
|
|
308
|
+
mock_api_instance = mock_ApiClient.return_value
|
|
309
|
+
mock_api_instance.make_request.return_value = (self.response_ok.text, self.response_ok.status_code)
|
|
310
|
+
|
|
311
|
+
start_time = datetime.datetime(2024, 5, 1)
|
|
312
|
+
end_time = datetime.datetime(2024, 5, 17)
|
|
313
|
+
|
|
314
|
+
result = _get_storage_usage(start_time, end_time)
|
|
315
|
+
|
|
316
|
+
self.assertEqual(result, self.storage_response_data['data'][0])
|
|
317
|
+
|
|
318
|
+
@mock.patch("ciocore.api_client.ApiClient")
|
|
319
|
+
@mock.patch("ciocore.api_client.read_conductor_credentials")
|
|
320
|
+
@mock.patch("ciocore.api_client.account_id_from_jwt")
|
|
321
|
+
def test_storage_usage(self, mock_account_id_from_jwt, mock_read_conductor_credentials, mock_ApiClient):
|
|
322
|
+
# Set up mocks for successful execution
|
|
323
|
+
mock_read_conductor_credentials.return_value = "valid_token"
|
|
324
|
+
mock_account_id_from_jwt.return_value = "123"
|
|
325
|
+
mock_api_instance = mock_ApiClient.return_value
|
|
326
|
+
mock_api_instance.make_request.return_value = (self.response_ok.text, self.response_ok.status_code)
|
|
327
|
+
|
|
328
|
+
start_time = datetime.datetime(2024, 1, 1)
|
|
329
|
+
end_time = datetime.datetime(2024, 1, 7)
|
|
330
|
+
|
|
331
|
+
result = get_storage_usage(start_time=start_time, end_time=end_time)
|
|
332
|
+
|
|
333
|
+
self.assertEqual(result, { '2024-01-01': {'cost': 4.022, 'GiB': 679.714},
|
|
334
|
+
'2024-01-02': {'cost': 4.502, 'GiB': 750.34},
|
|
335
|
+
'2024-01-03': {'cost': 4.502, 'GiB': 750.34},
|
|
336
|
+
'2024-01-04': {'cost': 5.102, 'GiB': 850.36},
|
|
337
|
+
'2024-01-05': {'cost': 5.102, 'GiB': 850.35},
|
|
338
|
+
'2024-01-06': {'cost': 5.732, 'GiB': 955.32}
|
|
339
|
+
})
|
tests/test_cli.py
CHANGED
|
@@ -13,8 +13,6 @@ class CliTestUploaderOptions(unittest.TestCase):
|
|
|
13
13
|
"database_filepath": None,
|
|
14
14
|
"location": None,
|
|
15
15
|
"md5_caching": True,
|
|
16
|
-
"log_level": "INFO",
|
|
17
|
-
"log_dir": None,
|
|
18
16
|
"thread_count": mock.ANY,
|
|
19
17
|
}
|
|
20
18
|
init_patcher = mock.patch("ciocore.cli.Uploader.__init__", autospec=True)
|
|
@@ -43,18 +41,6 @@ class CliTestUploaderOptions(unittest.TestCase):
|
|
|
43
41
|
expected.update({"md5_caching": False})
|
|
44
42
|
self.mock_init.assert_called_once_with(mock.ANY, expected)
|
|
45
43
|
|
|
46
|
-
def test_log_level_arg(self):
|
|
47
|
-
self.runner.invoke(cli_upload, ["--log_level", "DEBUG"])
|
|
48
|
-
expected = self.default_args
|
|
49
|
-
expected.update({"log_level": "DEBUG"})
|
|
50
|
-
self.mock_init.assert_called_once_with(mock.ANY, expected)
|
|
51
|
-
|
|
52
|
-
def test_log_dir_arg(self):
|
|
53
|
-
self.runner.invoke(cli_upload, ["--log_dir", "foo"])
|
|
54
|
-
expected = self.default_args
|
|
55
|
-
expected.update({"log_dir": "foo"})
|
|
56
|
-
self.mock_init.assert_called_once_with(mock.ANY, expected)
|
|
57
|
-
|
|
58
44
|
def test_thread_count_arg(self):
|
|
59
45
|
self.runner.invoke(cli_upload, ["--thread_count", 4])
|
|
60
46
|
expected = self.default_args
|
|
File without changes
|
|
File without changes
|
|
File without changes
|