ciocore 8.0.0b11__py2.py3-none-any.whl → 8.0.0b14__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
@@ -81,7 +81,9 @@ def temp_file(filepath):
81
81
  dirpath, filename = os.path.split(filepath)
82
82
  # ensure the directory exists
83
83
  os.makedirs(dirpath, exist_ok=True)
84
- temp_file_path = tempfile.mkstemp(prefix=filename, dir=dirpath)[1]
84
+ temp_file_desc = tempfile.mkstemp(prefix=filename, dir=dirpath)
85
+ temp_file_path = temp_file_desc[1]
86
+ os.close(temp_file_desc[0])
85
87
  yield temp_file_path
86
88
 
87
89
  shutil.move(temp_file_path, filepath)
@@ -26,7 +26,7 @@ class JobDownloader(BaseDownloader):
26
26
  CLIENT_NAME = "JobDownloader"
27
27
 
28
28
  def __init__(self, jobs, *args, **kwargs):
29
-
29
+
30
30
  super().__init__(*args, **kwargs)
31
31
  """Initialize the downloader."""
32
32
  logger.debug("Initializing paged job downloader")
@@ -35,20 +35,20 @@ class JobDownloader(BaseDownloader):
35
35
 
36
36
  def get_some_tasks(self, locator):
37
37
  """Fetch the next page of tasks from the server.
38
-
38
+
39
39
  locator: a dictionary containing the index of the current job, and the cursor for the next page of tasks for the job.
40
40
  """
41
41
 
42
42
  # What is a locator? It's the information needed to request the next page of tasks. It consists of the index of the current job, and the cursor for the next page of tasks. It is provided to this method as a parameter, and when we're done, a new locator is returned to the run loop. The run loop passes it back to us the next time it is called.
43
-
43
+
44
44
  # On the first call, the provided locator is None. In that case, we start with the first job, and no cursor.
45
-
45
+
46
46
  # We return the locator to the run loop in the base class, along with any tasks to be downloaded. If we return a falsy locator, the run loop is exited, since it means we downloaded everything OR there was an error fetching tasks.
47
-
47
+
48
48
  # If we got to the end of the current job, we increment the job index and reset the cursor to None. The next time this method is called, we'll start with the next job.
49
-
49
+
50
50
  # If we got a next_cursor from the request, we return it in the locator along withh the current job index. This is what we'll be given on the next call.
51
-
51
+
52
52
  if not locator:
53
53
  locator = {}
54
54
 
@@ -14,7 +14,6 @@ back to the server.
14
14
 
15
15
 
16
16
  import logging
17
- from queue import Queue
18
17
  from ciocore.downloader.download_runner_base import DownloadRunnerBase
19
18
 
20
19
  LOG_FORMATTER = logging.Formatter(
@@ -72,7 +71,7 @@ class LoggingDownloadRunner(DownloadRunnerBase):
72
71
 
73
72
  If we find any, then report them as pending.
74
73
  """
75
- logger.info(f"Download done")
74
+ logger.info("Download done")
76
75
  messages = []
77
76
  for job_id in evt["registry"]:
78
77
  job = evt["registry"][job_id]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ciocore
3
- Version: 8.0.0b11
3
+ Version: 8.0.0b14
4
4
  Summary: Core functionality for Conductor's client tools
5
5
  Home-page: https://github.com/ConductorTechnologies/ciocore
6
6
  Author: conductor
@@ -56,6 +56,9 @@ See [CONTRIBUTING](CONTRIBUTING.md)
56
56
 
57
57
  ## Unreleased:
58
58
 
59
+ * 8.0.0-beta.13
60
+ * fixed permissions error bug with file downloads
61
+
59
62
  * 8.0.0-beta.5
60
63
  * adds kill_tasks kill_jobs get_jobs get_log
61
64
  * remove old docs stuff
@@ -1,12 +1,12 @@
1
- ciocore/VERSION,sha256=hZKXw8UttJU6x8lR3MHguhunJ99ewsc05-zoXgHvN84,13
1
+ ciocore/VERSION,sha256=5fucTzbeOAkHbJHYqnYwCQgQRPfbsxTCi587-fEGr5s,13
2
2
  ciocore/__init__.py,sha256=aTP7LeeosQA8BZE67gDV4jgfTK5zxmwZRjiTRu_ZWj0,646
3
- ciocore/api_client.py,sha256=_kT-qXutqRTT9gDR2G6q4Wh6hgBPwpU9Wjnw7ztNxlI,25292
4
- ciocore/cli.py,sha256=WvtLAIiXXFk9-0Ce0X4ZCJjLx4u8ekt2xRJHWbOYLqI,17022
3
+ ciocore/api_client.py,sha256=BTDGXT-59-48SLz3BzP8OtGEhBYDiiEvyytsRUxaK9I,23555
4
+ ciocore/cli.py,sha256=R3tWhlrzUoIcdat70i9tTAaEDQ92dxRj4YaaYFCxSMA,17139
5
5
  ciocore/client_db.py,sha256=tTz3bl2xeDPPcYSDS3g3QgV_xYihJMx0Kj6OeN2klK0,12978
6
6
  ciocore/common.py,sha256=FnggAL-IGW8VQB6kLsrKLnxWFgLpwGBhOtiZSHz130M,14725
7
7
  ciocore/compat.py,sha256=5uEXPSog_jxsDMaHBswAKEtfyXT25VgU6WNGIhz9PHU,256
8
8
  ciocore/conductor_submit.py,sha256=ONE0LsA5hGavTJIOXXYx8qzl8_vBPADwhd6Ytq_0E0c,9382
9
- ciocore/config.py,sha256=n0L_EnGR-xr4jutwtRaU1UxUC5hzR97gfAk6HaKSLp0,8675
9
+ ciocore/config.py,sha256=rCL7kaFn1tYgSglN8q9Wx6SwMpoXTq0BMQGwPRVwVIg,8973
10
10
  ciocore/data.py,sha256=m_SqSlcrpjMPHhGtzx3Gn9sHzEmTQKsha3VNIBl1DY0,7349
11
11
  ciocore/data_cache.py,sha256=LasIBqKei-VHRZfRVJEbvSRAot-54-xZ3ZYZOUq-yJI,6859
12
12
  ciocore/dev_inst_tagger.py,sha256=bPfoFbE7IPCpDbtbVHxW7IlMwvspdnJhPuNq-u4fJN4,3497
@@ -26,12 +26,12 @@ ciocore/auth/server.py,sha256=8btX9-EokUl6q55V8muDmEV2tvvbTBD0BHeWFbwkzUc,3892
26
26
  ciocore/docsite/404.html,sha256=DQCrQsaKh8M0zlCFZmjFHUtqy7_gx_i2Rpc3OoDdDI4,17207
27
27
  ciocore/docsite/index.html,sha256=p_Dq_6_8cwZZPDI5zjahfCWUkfbSj14NJtoQFAZv0WI,20945
28
28
  ciocore/docsite/logo.png,sha256=gArgFFWdw8w985-0TkuGIgU_pW9sziEMZdqytXb5WLo,2825
29
- ciocore/docsite/objects.inv,sha256=V2CTA5ifhR2WS1ELU2clCxzwRMF_hGKCprr18jmkb3s,724
29
+ ciocore/docsite/objects.inv,sha256=UhlZWOqRV8tA4CzS8HKmk322X-so5ZmIe55155t_7Ls,746
30
30
  ciocore/docsite/sitemap.xml,sha256=M_V85zl0y2adRvzJAnoCxlZH_Hl7TLnIb1A-6l_xGmI,109
31
- ciocore/docsite/sitemap.xml.gz,sha256=vRqzJ582KFZkp7VxUflQMfSIKydB_QG2nAcRz4LVBw0,127
32
- ciocore/docsite/apidoc/api_client/index.html,sha256=udeUpwlzyhVz_BH4qRPw6Bj4ktj7YsxX4cOdPVT1LvU,165043
31
+ ciocore/docsite/sitemap.xml.gz,sha256=WwV7ZDDXdjDLWQW8ZdVWO7ToorPQikaMxmLw-ftiYBc,127
32
+ ciocore/docsite/apidoc/api_client/index.html,sha256=DYVIV4xZRhTEiDJoIRn-76YRjGia_ce6LDss7G2stsE,164621
33
33
  ciocore/docsite/apidoc/apidoc/index.html,sha256=NQn8wjapxa7O2IQhsbE7Y-VMfMFL6Tby-L7qIF6K3m4,26171
34
- ciocore/docsite/apidoc/config/index.html,sha256=W8jqv5hUJGlmem36w8NrU6zpnEnh3yacZ9Qx_NJLxQg,73311
34
+ ciocore/docsite/apidoc/config/index.html,sha256=1GWkyClM7LJlLBpx07BqCi3xDkU-SKVPjNUEeKuwbNs,72559
35
35
  ciocore/docsite/apidoc/data/index.html,sha256=K4Sr6Vmq38Nq1xTQG6ennLjxpD_37bMNEgKZe8S0lJ0,50724
36
36
  ciocore/docsite/apidoc/hardware_set/index.html,sha256=DMlpzQCy2ypJ078tcFNrZAvG2sU7P5-ZwU4ZRCObtQg,123042
37
37
  ciocore/docsite/apidoc/package_environment/index.html,sha256=S5IE1EgnJaaLVsEpgPogwBvj3jxT6ycNp-1GAlJrPt4,65729
@@ -83,16 +83,16 @@ ciocore/docsite/cmdline/downloader/index.html,sha256=DAVErhWEPuEtkQr7y9D_wjylzM9
83
83
  ciocore/docsite/cmdline/packages/index.html,sha256=j1YeMgdwZ6FyJGJii05AdtUWKRjyu1fOr3_bKJsLfEU,20923
84
84
  ciocore/docsite/cmdline/uploader/index.html,sha256=y0728lIAYC4b9mfpjNVfwQqXoqJrsdG49UY5u7B1p94,25123
85
85
  ciocore/docsite/how-to-guides/index.html,sha256=OFrFBTb9tuMn60Jd4oeM10Mw-d-0pyqwoKoo9g1biBM,20100
86
- ciocore/docsite/search/search_index.json,sha256=KXnkq9QBss78-d5Y30b5ZFou0TakUlWPqmu4I5L43O4,180228
86
+ ciocore/docsite/search/search_index.json,sha256=xpYzauCSGogatE3F2UoDih_GCpa4UdbvRtm9bDr17I0,180065
87
87
  ciocore/docsite/stylesheets/extra.css,sha256=qgfcao9TEBzf6ieAWN5rPyrea7YM_YgVg5qr4NPrxoU,354
88
88
  ciocore/docsite/stylesheets/tables.css,sha256=O2PEwlKC0RfvZCRV9UERqQRvhb6jcqO84PLew0bafF0,3279
89
89
  ciocore/downloader/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
90
- ciocore/downloader/base_downloader.py,sha256=1sYWc6e-1FelFN7p1_xt4Zbsz9xtVaN86Nb6jMWF_Zc,20587
90
+ ciocore/downloader/base_downloader.py,sha256=asyjHQ4NQL7uisqXe8IWU6lid5b83PiE_8KpPA1WXjA,20663
91
91
  ciocore/downloader/daemon_downloader.py,sha256=ksdfw0PzfO6xnNxMebM27nkHl75lh-rAtf5XT6WmipI,1327
92
92
  ciocore/downloader/download_runner_base.py,sha256=x74pmn4vdGKKlR9gaFdtmjIRfN0ME1oyX5e9k92Nn1w,6455
93
- ciocore/downloader/job_downloader.py,sha256=lzSYff9XS9qX6qOf_BsNpoRBu35UVaINJZsw41lU9cI,5473
93
+ ciocore/downloader/job_downloader.py,sha256=hYDh8Fqn-ZhD0xM8uHQauglhdi70_HK9UQ7nKPFyqds,5417
94
94
  ciocore/downloader/legacy_downloader.py,sha256=1dCkagDoRYliQjGUYD2kAw49TQ-4k2AO592e--UHhf4,52087
95
- ciocore/downloader/logging_download_runner.py,sha256=c232qepb-G-SL0oZYy0ONhR0Oc9u8lrcTw6Cgq5I9zY,3258
95
+ ciocore/downloader/logging_download_runner.py,sha256=KqnR-Hy_kTIqHkZJhCIBkZlkVvkylV30bFLG32rlB88,3233
96
96
  ciocore/sequence_checker/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
97
97
  ciocore/sequence_checker/bar_chart.py,sha256=Trx_By3A2Eucwp2f0fWWowXphAB1MLSXfZudzwCjXWM,8715
98
98
  ciocore/sequence_checker/check_sequence.py,sha256=aZ5h7yWensTjruuC8japRVnS9EZGx8cJagUSQhD6o_I,6673
@@ -106,15 +106,15 @@ tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
106
106
  tests/instance_type_fixtures.py,sha256=uIzQduqKQVgjllMuyXaYnRC-pwqk5lnTx3NY2M5Nujo,4320
107
107
  tests/package_fixtures.py,sha256=CsJnhB7oYzIxJH7b1tCOPyvnnVSCqEbSPhtCnsHL-nA,5070
108
108
  tests/project_fixtures.py,sha256=iBm_th_JtAw76vlNu7Jjhh9tLH4oOaNi-MgtPzCV7yQ,138
109
- tests/test_api_client.py,sha256=CQKt-ndYI5AV7h4P5iMHaEGF3i2OxXcenR_ZqCPHoug,1402
109
+ tests/test_api_client.py,sha256=lDUkVi6Xq1ilkSepFLebgBAhgchumvfyZnTtei1fnrI,3642
110
110
  tests/test_base_downloader.py,sha256=dOtA3uoOBl8KrbyTlI5g4yvXTBH9e1m95rco-lWfJoA,3765
111
111
  tests/test_cli.py,sha256=OPcKAQ-zO43_46nFN3UTAuHfHEQMIzfdZ5kNFm0FH9E,6203
112
- tests/test_common.py,sha256=xA0y_KgEmag7jRKfhEHZgIQkS2WmjrYEcss-rwhQOOs,747
112
+ tests/test_common.py,sha256=tY_-SY-JmJX09UehFs9RIDqZ785AmhfTl6eVKJeIUFY,763
113
113
  tests/test_config.py,sha256=-_G682Ss3Zr1FmcMkjla1zAZprX2tQKpKc5_wD28rII,13340
114
114
  tests/test_data.py,sha256=ZT_61MQPl6DajXzGAkkJZsVpYaFMsxpZLjtPaoEaPpE,5471
115
115
  tests/test_data_cache.py,sha256=PDbRNoMHea_bMw2wgEjWRd9sFEqTt2PEpyxV6nNjoQ4,8719
116
- tests/test_downloader.py,sha256=-V941RloByv3byiYefd1vt1aR7mWR6HuYEveBrZrZGA,4609
117
- tests/test_hardware_set.py,sha256=_UE1Q5ii9WP-LByIzKGThDMa4dBAQe41cI9B5fm9w_Y,4452
116
+ tests/test_downloader.py,sha256=-d8MCPnBkd5WS0wqvmoICXvNAhEdPXr2JJXZRWoKPlw,4678
117
+ tests/test_hardware_set.py,sha256=hW7A_suyYdU7WkB7qoHSBPLxaAP2CKqI0i_ULfO5GeY,4408
118
118
  tests/test_imports_2and3.py,sha256=ehqpRYPVY7djBcb8OT_cnh86iCJJ9wuMWnfSR9RHxmY,507
119
119
  tests/test_job_downloader.py,sha256=_dZqyLZhc2Bq2n7-skERfodHx1JgFyHw8TamHp6ID9I,7025
120
120
  tests/test_package_environment.py,sha256=CdiC2PDVSnbcwTb4fsDTWqGYSzs1n5ca2KMoyISckGA,5893
@@ -124,8 +124,8 @@ tests/test_uploader.py,sha256=B1llTJt_fqR6e_V_Jxfw9z73QgkFlEPU87xLYGzt-TQ,2914
124
124
  tests/test_validator.py,sha256=2fY66ayNc08PGyj2vTI-V_1yeCWJDngkj2zkUM5TTCI,1526
125
125
  tests/mocks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
126
126
  tests/mocks/glob.py,sha256=J2MH7nqi6NJOHuGdVWxhfeBd700_Ckj6cLh_8jSNkfg,215
127
- ciocore-8.0.0b11.dist-info/METADATA,sha256=FLxrkHs_N6lYfjJHWbvd_U1pjM96NoaQGT2cQUn8Z-w,16139
128
- ciocore-8.0.0b11.dist-info/WHEEL,sha256=iYlv5fX357PQyRT2o6tw1bN-YcKFFHKqB_LwHO5wP-g,110
129
- ciocore-8.0.0b11.dist-info/entry_points.txt,sha256=cCqcALMYbC4d8545V9w0Zysfg9MVuKWhzDQ2er4UfGE,47
130
- ciocore-8.0.0b11.dist-info/top_level.txt,sha256=SvlM5JlqULzAz00JZWfiUhfjhqDzYzSWssA87zdJl0o,14
131
- ciocore-8.0.0b11.dist-info/RECORD,,
127
+ ciocore-8.0.0b14.dist-info/METADATA,sha256=ZEO52RjWMXBEL4NBymTzAWYBZRptAh_UwPSDzp_4Y2w,16208
128
+ ciocore-8.0.0b14.dist-info/WHEEL,sha256=iYlv5fX357PQyRT2o6tw1bN-YcKFFHKqB_LwHO5wP-g,110
129
+ ciocore-8.0.0b14.dist-info/entry_points.txt,sha256=cCqcALMYbC4d8545V9w0Zysfg9MVuKWhzDQ2er4UfGE,47
130
+ ciocore-8.0.0b14.dist-info/top_level.txt,sha256=SvlM5JlqULzAz00JZWfiUhfjhqDzYzSWssA87zdJl0o,14
131
+ ciocore-8.0.0b14.dist-info/RECORD,,
tests/test_api_client.py CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  isort:skip_file
4
4
  """
5
-
5
+ import sys
6
6
  import unittest
7
7
 
8
8
  try:
@@ -45,3 +45,63 @@ class ApiClientTest(unittest.TestCase):
45
45
  fn = api_client.get_creds_path(api_key=True).replace("\\", "/")
46
46
  self.assertEqual(fn, "/users/joebloggs/.config/conductor/api_key_credentials")
47
47
 
48
+
49
+ class TestTruncateMiddle(unittest.TestCase):
50
+
51
+ def test_truncation_not_needed(self):
52
+ self.assertEqual(api_client.truncate_middle("short", 10), "short")
53
+
54
+ def test_truncation_with_even_max_length(self):
55
+ self.assertEqual(api_client.truncate_middle("1234567890ABCDEF", 8), "1234~DEF")
56
+
57
+ def test_truncation_with_odd_max_length(self):
58
+ self.assertEqual(api_client.truncate_middle("1234567890ABCDEF", 9), "1234~CDEF")
59
+
60
+ def test_empty_string(self):
61
+ self.assertEqual(api_client.truncate_middle("", 5), "")
62
+
63
+ def test_non_string_input(self):
64
+ with self.assertRaises(TypeError):
65
+ api_client.truncate_middle(12345, 5)
66
+
67
+ class TestRegisterClient(unittest.TestCase):
68
+ USER_AGENT_MAX_PATH_LENGTH = 10 # Example max length for testing
69
+
70
+ @classmethod
71
+ def setUpClass(cls):
72
+ cls.original_executable = sys.executable
73
+ sys.executable = '/usr/bin/python3' # Example path for testing
74
+
75
+ @classmethod
76
+ def tearDownClass(cls):
77
+ sys.executable = cls.original_executable
78
+
79
+ def test_register_client_with_version(self):
80
+ client_name = 'ApiClient'
81
+ client_version = '1.0'
82
+
83
+ with mock.patch('platform.python_version', return_value='3.8.2'), \
84
+ mock.patch('platform.system', return_value='Linux'), \
85
+ mock.patch('platform.release', return_value='5.4.0-42-generic'):
86
+ user_agent = api_client.ApiClient.register_client(client_name, client_version)
87
+
88
+ expected_user_agent = (
89
+ f"ApiClient/1.0 (python 3.8.2; Linux 5.4.0-42-generic; "
90
+ )
91
+ self.assertTrue(user_agent.startswith(expected_user_agent))
92
+
93
+ def test_register_client_without_version(self):
94
+ client_name = 'ApiClient'
95
+
96
+ with mock.patch('platform.python_version', return_value='3.8.2'), \
97
+ mock.patch('platform.system', return_value='Linux'), \
98
+ mock.patch('platform.release', return_value='5.4.0-42-generic'):
99
+ user_agent = api_client.ApiClient.register_client(client_name)
100
+
101
+
102
+ expected_user_agent = (
103
+ f"ApiClient/unknown (python 3.8.2; Linux 5.4.0-42-generic; "
104
+ )
105
+
106
+ self.assertTrue(user_agent.startswith(expected_user_agent))
107
+
tests/test_common.py CHANGED
@@ -10,14 +10,14 @@ FILES_PATH = os.path.join(os.path.dirname(__file__), "files")
10
10
 
11
11
  class TestMd5(unittest.TestCase):
12
12
 
13
- def test_get_base64_md5_is_correct_md5(self):
14
- from ciocore import common
15
- fn1 = os.path.join(FILES_PATH, "one")
16
- md5=common.get_base64_md5(fn1)
17
- if os.name == "nt":
18
- self.assertEqual(md5, "w8F8opHbdwHIozghPc63XA==")
19
- else:
20
- self.assertEqual(md5, "9iVbsBxkj+lncU1SqJ6OnA==")
13
+ # def test_get_base64_md5_is_correct_md5(self):
14
+ # from ciocore import common
15
+ # fn1 = os.path.join(FILES_PATH, "one")
16
+ # md5=common.get_base64_md5(fn1)
17
+ # if os.name == "nt":
18
+ # self.assertEqual(md5, "w8F8opHbdwHIozghPc63XA==")
19
+ # else:
20
+ # self.assertEqual(md5, "9iVbsBxkj+lncU1SqJ6OnA==")
21
21
 
22
22
 
23
23
  def test_get_base64_md5_is_correct_type(self):
tests/test_downloader.py CHANGED
@@ -15,6 +15,7 @@ class TempFileTests(unittest.TestCase):
15
15
  # Create a temporary file and test if it exists
16
16
  with temp_file("tests/files/file.txt") as temp_path:
17
17
  self.assertTrue(os.path.exists(temp_path))
18
+ self.assertTrue(os.access(temp_path, os.W_OK & os.R_OK))
18
19
 
19
20
  def test_temp_file_overwrite_existing(self):
20
21
  # Test if existing file is overwritten by the temporary file
@@ -3,7 +3,6 @@
3
3
  isort:skip_file
4
4
  """
5
5
  import unittest
6
-
7
6
 
8
7
 
9
8
  from ciocore.hardware_set import HardwareSet
@@ -16,7 +15,12 @@ PROJECTS = [
16
15
  ]
17
16
 
18
17
  from package_fixtures import *
19
- from instance_type_fixtures import CW_INSTANCE_TYPES, AWS_INSTANCE_TYPES, CW_INSTANCE_TYPES_WITH_GPUS, ALL_INSTANCE_TYPES
18
+ from instance_type_fixtures import (
19
+ CW_INSTANCE_TYPES,
20
+ AWS_INSTANCE_TYPES,
21
+ CW_INSTANCE_TYPES_WITH_GPUS,
22
+ ALL_INSTANCE_TYPES,
23
+ )
20
24
 
21
25
 
22
26
  class TestCategorizedInstanceTypes(unittest.TestCase):
@@ -41,18 +45,20 @@ class TestCategorizedInstanceTypes(unittest.TestCase):
41
45
  self.assertIn("cw-a-4-16", extra_category_values)
42
46
 
43
47
  def test_category_names(self):
44
-
45
- names = self.hs.labels()
48
+ names = self.hs.labels()
46
49
  self.assertEqual(names, ["low", "mid", "high", "extra"])
47
50
 
48
51
 
49
-
50
52
  class TestRecategorizeInstanceTypes(unittest.TestCase):
51
53
  def setUp(self):
52
54
  self.hs = HardwareSet(CW_INSTANCE_TYPES_WITH_GPUS)
53
-
55
+
54
56
  def test_recategorize_cpu_gpu(self):
55
- test_func = lambda x: [{'label': 'GPU', 'order': 2}] if "gpu" in x and x["gpu"] else [{'label': 'CPU', 'order': 1}]
57
+ test_func = (
58
+ lambda x: [{"label": "GPU", "order": 2}]
59
+ if "gpu" in x and x["gpu"]
60
+ else [{"label": "CPU", "order": 1}]
61
+ )
56
62
  self.hs.recategorize(test_func)
57
63
  self.assertEqual(self.hs.number_of_categories(), 2)
58
64
 
@@ -61,25 +67,23 @@ class TestRecategorizeInstanceTypes(unittest.TestCase):
61
67
  result = self.hs.find_all(test_func)
62
68
  self.assertEqual(len(result), 2)
63
69
  print(self.hs)
64
-
70
+
65
71
  def test_find_first_by_condition(self):
66
- test_func = lambda x: x[ "memory"] < 32
72
+ test_func = lambda x: x["memory"] < 32
67
73
  result = self.hs.find_first(test_func)
68
74
  self.assertTrue(result["memory"] < 32)
69
-
75
+
70
76
  def test_find_category(self):
71
77
  label = "mid"
72
78
  result = self.hs.find_category(label)
73
- self.assertEqual(result["label"] , label)
74
- self.assertEqual(result["order"] , 2)
75
-
76
-
79
+ self.assertEqual(result["label"], label)
80
+ self.assertEqual(result["order"], 2)
77
81
 
78
82
 
79
83
  class TestFind(unittest.TestCase):
80
84
  def setUp(self):
81
85
  self.hs = HardwareSet(CW_INSTANCE_TYPES_WITH_GPUS)
82
-
86
+
83
87
  def test_find_unspecified_category(self):
84
88
  result = self.hs.find("cw-e-4-32")
85
89
  self.assertIsNotNone(result)
@@ -87,15 +91,16 @@ class TestFind(unittest.TestCase):
87
91
  def test_category_that_exists(self):
88
92
  result = self.hs.find("cw-e-4-32", category="high")
89
93
  self.assertIsNotNone(result)
90
-
94
+
91
95
  def test_returns_none_if_not_in_category(self):
92
96
  result = self.hs.find("cw-e-4-32", category="low")
93
97
  self.assertIsNone(result)
94
-
98
+
95
99
  def test_returns_none_if_non_existent_category(self):
96
100
  result = self.hs.find("cw-e-4-32", category="foo")
97
101
  self.assertIsNone(result)
98
-
102
+
103
+
99
104
  class TestUncategorizedInstanceTypes(unittest.TestCase):
100
105
  def setUp(self):
101
106
  self.hs = HardwareSet(ALL_INSTANCE_TYPES)
@@ -109,28 +114,26 @@ class TestUncategorizedInstanceTypes(unittest.TestCase):
109
114
  self.assertEqual(
110
115
  result,
111
116
  [
112
- 'windows 4 core 26.0GB Mem',
113
- 'linux 4 core 27.0GB Mem',
114
- 'linux 8 core 30.0GB Mem',
115
- 'windows 32 core 208.0GB Mem',
116
- 'linux 32 core 208.0GB Mem',
117
- 'windows 64 core 416.0GB Mem',
118
- 'linux 64 core 416.0GB Mem'
117
+ "windows 4 core 26.0GB Mem",
118
+ "linux 4 core 27.0GB Mem",
119
+ "linux 8 core 30.0GB Mem",
120
+ "windows 32 core 208.0GB Mem",
121
+ "linux 32 core 208.0GB Mem",
122
+ "windows 64 core 416.0GB Mem",
123
+ "linux 64 core 416.0GB Mem",
119
124
  ],
120
125
  )
121
126
 
122
-
123
- class TestProvider(unittest.TestCase):
124
127
 
128
+ class TestProvider(unittest.TestCase):
125
129
  def test_gcp_provider(self):
126
130
  hs = HardwareSet(ALL_INSTANCE_TYPES)
127
131
  self.assertEqual(hs.provider, "gcp")
128
-
132
+
129
133
  def test_cw_provider(self):
130
134
  hs = HardwareSet(CW_INSTANCE_TYPES_WITH_GPUS)
131
135
  self.assertEqual(hs.provider, "cw")
132
-
136
+
133
137
  def test_aws_provider(self):
134
138
  hs = HardwareSet(AWS_INSTANCE_TYPES)
135
139
  self.assertEqual(hs.provider, "aws")
136
-