ciocore 6.0.0rc4__py2.py3-none-any.whl → 6.3.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 CHANGED
@@ -1 +1 @@
1
- 6.0.0-rc.4
1
+ 6.3.0
ciocore/data.py CHANGED
@@ -16,8 +16,6 @@ __products__ = None
16
16
  __fixtures_dir__ = None
17
17
  __platforms__ = None
18
18
 
19
- MISC_CATEGORY_LABEL = "-- Misc --"
20
-
21
19
  def init(*products, **kwargs):
22
20
  """
23
21
  Initialize and let the module know what host products to provide in the `software` property.
@@ -50,6 +48,7 @@ def init(*products, **kwargs):
50
48
  """
51
49
 
52
50
  global __products__
51
+ global __platforms__
53
52
  if products:
54
53
  if kwargs.get("product"):
55
54
  raise ValueError(
@@ -64,7 +63,9 @@ def init(*products, **kwargs):
64
63
  else:
65
64
  __products__ = []
66
65
 
67
-
66
+ __platforms__ = set(kwargs.get("platforms", ["windows", "linux"]))
67
+
68
+
68
69
  def data(force=False):
69
70
  """
70
71
  Provides projects, instance types, and software package data.
@@ -83,11 +84,6 @@ def data(force=False):
83
84
 
84
85
  * **`force`** -- If `True`, then fetch fresh data -- Defaults to `False`.
85
86
 
86
- * **`include_misc_category`** -- If `True`, then include the misc category in the
87
- instance types. The misc category is used for instance types that are uncategorized. If all
88
- instance types are uncategorized, then the misc category is included regardless of this
89
- flag since we never want an empty list. -- Defaults to `False`.
90
-
91
87
  Raises:
92
88
 
93
89
  * **`ValueError`** -- Module was not initialized with the [init()](#init) method.
@@ -97,7 +93,7 @@ def data(force=False):
97
93
  * A dictionary with 3 keys: `projects`, `instance_types`, `software`.
98
94
 
99
95
  * `projects` is a list of project names for the authenticated account.
100
- * `instance_types` is a list of machine specifications available.
96
+ * `instance_types` is an instace of HardwareSet, from which you can get the data in various forms.
101
97
  * `software` is a [PackageTree](/developer/ciocore/package_tree) object containing either all
102
98
  software available at conductor, or a subset according to the product specified on
103
99
  initialization.
@@ -129,7 +125,7 @@ def data(force=False):
129
125
  global __fixtures_dir__
130
126
  global __platforms__
131
127
 
132
- if __products__ == None:
128
+ if __products__ is None:
133
129
  raise ValueError(
134
130
  'Data must be initialized before use, e.g. data.init("maya-io") or data.init().'
135
131
  )
@@ -151,13 +147,14 @@ def data(force=False):
151
147
  instance_types = api_client.request_instance_types()
152
148
 
153
149
  it_platforms = set([it["operating_system"] for it in instance_types])
150
+ platforms = it_platforms.intersection(__platforms__)
154
151
 
155
152
  # SOFTWARE
156
153
  software = _get_json_fixture("software")
157
154
  if not software:
158
155
  software = api_client.request_software_packages()
159
156
 
160
- kwargs = {"platforms": it_platforms}
157
+ kwargs = {"platforms": platforms}
161
158
 
162
159
  # If there's only one product, it's possible to initialize the software tree with a plugin.
163
160
  # So we set the product kwarg. Otherwise, we set the host_products kwarg
@@ -166,12 +163,14 @@ def data(force=False):
166
163
  host_products = []
167
164
  kwargs["product"] = __products__[0]
168
165
 
166
+
169
167
  software_tree = PackageTree(software, *host_products, **kwargs)
170
168
 
171
169
  if software_tree:
172
170
  __data__["software"] = software_tree
173
171
  # Revisit instance types to filter out any that are not needed for any software package.
174
172
  sw_platforms = software_tree.platforms()
173
+
175
174
  instance_types = [
176
175
  it for it in instance_types if it["operating_system"] in sw_platforms
177
176
  ]
ciocore/hardware_set.py CHANGED
@@ -1,29 +1,46 @@
1
- MISC_CATEGORY_LABEL = "-- Misc --"
1
+
2
2
  import copy
3
+ import logging
4
+
5
+ logger = logging.getLogger(__name__)
3
6
 
4
7
  class HardwareSet(object):
5
8
  """A class to manage the categorized instance types.
6
9
 
7
10
  It takes flat instance types array and builds a nested structure where instance types exist in
8
11
  categories.
12
+
13
+ If after categorization there is only one category and it is the misc category, then we
14
+ recategorize by cpu and gpu.
9
15
  """
10
16
 
11
17
  def __init__(self, instance_types):
12
- self.instance_types = self.build_uniq(instance_types)
18
+
19
+ self.instance_types = self.build_unique(instance_types)
13
20
  self.categories = self.build_categories()
14
-
21
+
15
22
  @staticmethod
16
- def build_uniq(instance_types):
23
+ def build_unique(instance_types):
17
24
  """Build a dictionary of instance types using name as key.
18
25
 
19
26
  Remove any instance types whose description has already been seen. We can't have duplicate
20
27
  descriptions.
28
+
29
+ If categories exist, then remove any instance types that don't have a category. Otherwise,
30
+ since there are no categories, we can't remove any instance types.
21
31
  """
32
+ categories = [category for it in instance_types for category in (it.get("categories") or [])]
22
33
  result = {}
23
34
  seen_descriptions = set()
24
35
  for it in instance_types:
25
36
  if it["description"] in seen_descriptions:
26
37
  continue
38
+ if categories:
39
+ if it.get("categories") in [[], None]:
40
+ continue
41
+ else:
42
+ # make our own categories GPU/CPU
43
+ it["categories"] = [{'label': 'GPU', 'order': 2}] if "gpu" in it and it["gpu"] else [{'label': 'CPU', 'order': 1}]
27
44
  result[it["name"]] = it
28
45
  seen_descriptions.add(it["description"])
29
46
  return result
@@ -35,9 +52,7 @@ class HardwareSet(object):
35
52
  dikt = {}
36
53
  for key in self.instance_types:
37
54
  it = self.instance_types[key]
38
- categories = it.get("categories") or []
39
- if not categories:
40
- categories.append({"label": MISC_CATEGORY_LABEL, "order": 999})
55
+ categories = it["categories"]
41
56
  for category in categories:
42
57
  label = category["label"]
43
58
  if label not in dikt:
@@ -51,29 +66,78 @@ class HardwareSet(object):
51
66
  result.append(category)
52
67
  return sorted(result, key=lambda k: k["order"])
53
68
 
54
-
69
+ def recategorize(self, partitioner):
70
+ """Recategorize the instance types.
71
+
72
+ Partitioner is a function that takes an instance type and returns a list of categories.
73
+
74
+ If for example you want to append to the existing categories, then you can use a function like this:
75
+ lambda x: x["categories"] + [{'label': 'Low cores', 'order': 10}] if x["cores"] < 16 else [{'label': 'High cores', 'order': 20}]
76
+
77
+ Rebuilds the categories structure after assigning the new categories.
78
+ """
79
+ for key in self.instance_types:
80
+ self.instance_types[key]["categories"] = partitioner(self.instance_types[key])
81
+ self.categories = self.build_categories()
82
+
83
+
55
84
  def get_model(self, with_misc=False):
56
- """Returns the categories structure with filtering and renaming ready for some UI.
85
+ """Returns the categories structure with renaming ready for some UI.
57
86
 
58
- with_misc: Include misc category. The misc category is always included if it's only one.
87
+ NOTE: THIS METHOD WILL BE DEPRECATED. with_misc is no longer used, which means that this
88
+ function just renames a few keys. What's more, the init function ensures that every instance
89
+ type has a (non-misc) category. So this function is no longer needed. Submitters that use
90
+ it will work fine, but should be updated to use the categories structure directly.
59
91
  """
92
+ if with_misc:
93
+ logger.warning("with_misc is no longer used")
60
94
  result = []
61
- should_remove_misc = not with_misc and len( self.categories) > 1
62
-
63
95
  for category in self.categories:
64
- if should_remove_misc and category["label"] == MISC_CATEGORY_LABEL:
65
- continue
66
-
67
96
  result.append({
68
97
  "label": category["label"],
69
- "content": list(map(lambda k: {"label": k["description"], "value": k["name"]} , category["content"]))
98
+ "content": [{"label": k["description"], "value": k["name"]} for k in category["content"]]
70
99
  })
71
100
 
72
101
  return result
73
-
102
+
74
103
  def find(self, name):
104
+ """Find an instance type by name (sku).
105
+
106
+ Example: find("p3.2xlarge")
107
+
108
+ Returns and instance-type or None if not found.
109
+ """
75
110
  return self.instance_types.get(name)
76
111
 
112
+ def find_category(self, label):
113
+ """Find a category by label.
114
+
115
+ Example: find_category("GPU")
116
+
117
+ Returns the entire category and its contents or None if not found.
118
+ """
119
+ return next((c for c in self.categories if c["label"] == label), None)
120
+
121
+
122
+ def find_all(self, condition):
123
+ """Find all instance types that match a condition.
124
+
125
+ Example: find_all(lambda x: x["gpu"])
126
+ """
127
+ result = []
128
+ for key in self.instance_types:
129
+ if condition(self.instance_types[key]):
130
+ result.append(self.instance_types[key])
131
+ return result
132
+
133
+ def find_first(self, condition):
134
+ """Find the first instance type that matches a condition.
135
+
136
+ Example: find_first(lambda x: x["cores"] == 4)"])
137
+ """
138
+ return next(iter(self.find_all(condition)), None)
139
+
77
140
  def number_of_categories(self):
141
+ """Return the number of categories in the data."""
78
142
  return len(self.categories)
79
143
 
@@ -1,12 +1,10 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ciocore
3
- Version: 6.0.0rc4
3
+ Version: 6.3.0
4
4
  Summary: Core functionality for Conductor's client tools
5
5
  Home-page: https://github.com/ConductorTechnologies/ciocore
6
6
  Author: conductor
7
7
  Author-email: info@conductortech.com
8
- License: UNKNOWN
9
- Platform: UNKNOWN
10
8
  Classifier: Operating System :: OS Independent
11
9
  Classifier: Programming Language :: Python
12
10
  Classifier: Topic :: Multimedia :: Graphics :: 3D Rendering
@@ -25,86 +23,43 @@ Use the command-line uploader and downloader or develop your own tools using the
25
23
 
26
24
  **To install the latest version.**
27
25
  ```bash
28
- pip install --upgrade ciocore --target=$HOME/Conductor
29
- ```
30
-
31
- **To install a specific version, for example 0.1.0.**
32
- ```bash
33
- pip install --upgrade --force-reinstall ciocore==0.1.0 --target=$HOME/Conductor
26
+ pip install --upgrade ciocore
34
27
  ```
35
28
 
36
29
  Run the conductor command to confirm the package was installed.
37
- ```
38
- $HOME/ConductorStaging/bin/conductor --help
39
- ```
40
-
41
- To use the Python API, you must either set the PYTHONPATH or pip install, possibly to a virtualenv.
42
-
43
- Option 1. PYTHONPATH
44
- ```bash
45
- export PYTHONPATH=${HOME}/Conductor && python
46
- ```
47
-
48
- Option 2. Pip install to venv.
49
-
50
30
  ```bash
51
- # Create.
52
- python3.9 -m venv ~/venvs/cioapi
53
-
54
- # activate
55
- . ~/venvs/cioapi/bin/activate
56
-
57
- pip install --upgrade .
31
+ conductor --help
58
32
  ```
59
33
 
60
-
61
-
62
- Example API usage from.
63
- ```
34
+ Example API usage
35
+ ```python
64
36
  from ciocore import api_client
65
-
66
- print api_client.request_software_packages()[0]
37
+ print(api_client.request_software_packages()[0])
67
38
 
68
39
  ```
69
-
70
40
  ## Contributing
71
41
 
72
- Clone the repo.
42
+ See [CONTRIBUTING](CONTRIBUTING.md)
73
43
 
74
- ```
75
- git clone git@github.com:ConductorTechnologies/ciocore.git
76
- cd ciocore
77
- ```
78
-
79
- Set up a clean virtual envirionment for development (optional).
80
-
81
- ```
82
- python -m virtualenv venv
83
- . ./venv/bin/activate
84
- ```
85
-
86
- Install development dependencies
87
- ```
88
- pip install -r requirements_dev.txt
89
- ```
44
+ ## Changelog
90
45
 
91
- Run the automated tests
92
- ```
93
- tox
94
- ```
46
+ ## Version:6.3.0 -- 05 Jul 2023
95
47
 
96
- Build and install from this directory into to a convenient location for testing.
97
- ```
98
- pip install --upgrade . --target=$HOME/ConductorStaging
99
- ```
48
+ * In the absence of instance-type categories provided by the endpoint, the client generates default
49
+ categories CPU and GPU which at least splits the instance types into two groups, thereby making
50
+ dropdown menus more manageable, especially for CoreWeave's array of machines.
51
+ * update circleci config and related documentation
100
52
 
101
- See above for information on the conductor command and the Python API.
53
+ ## Version:6.1.0 -- 09 Jun 2023
102
54
 
55
+ Add the ability to specify which platforms to get resources for. This helps consumers of the API to
56
+ avoid fetching resources for Windows when the client is not ready.
103
57
 
104
- ## License
105
- [MIT](https://choosealicense.com/licenses/mit)
58
+ ## Version:6.0.0 -- 07 Jun 2023
106
59
 
107
- ## Changelog
60
+ This is a breaking change due instance types being provided as an instance of HardwareSet with
61
+ support for categories as opposed to a simple list. Consumers of the API will need to be updated to
62
+ support this change.
108
63
 
109
64
  ## Version:6.0.0-rc.4 -- 06 Jun 2023
110
65
 
@@ -113,7 +68,7 @@ See above for information on the conductor command and the Python API.
113
68
  ## Version:6.0.0-rc.3 -- 04 Jun 2023
114
69
 
115
70
  * Manage removal of the misc category [29742ea]
116
- * Instance_types contain a category list [aac9c8a]
71
+ * Instance types contain a category list [aac9c8a]
117
72
  * Convert CICD to use skulk-2 flow [724458a]
118
73
 
119
74
  ### Version:5.6.0 -- 6 April 2023
@@ -342,7 +297,7 @@ See above for information on the conductor command and the Python API.
342
297
  ### Version:0.2.10 -- 08 Sep 2020
343
298
 
344
299
  * Gpath allow colons in paths. [9c19d3a]
345
-
300
+
346
301
  ### Version:0.2.9 -- 06 Sep 2020
347
302
 
348
303
  * Sequence consumers must use factory. [01a7dd7]
@@ -458,4 +413,3 @@ See above for information on the conductor command and the Python API.
458
413
  ### Version:0.1.4 -- 14 Jun 2020
459
414
 
460
415
  * Ignore build dir. [8080df5]
461
-
@@ -1,4 +1,4 @@
1
- ciocore/VERSION,sha256=KCprTUeVc4afMvj_ODxHP72apTG8cFPBPqeTv013IlY,10
1
+ ciocore/VERSION,sha256=AcBmZzP8VI6iOQK01krLRTlT4Tu0al4tBEsVA7A-nUo,5
2
2
  ciocore/__about__.py,sha256=nTb4Xx0r9QtGROSFKgwDZ-Mr2LKjm2wVt1OkMQAkRAQ,241
3
3
  ciocore/__init__.py,sha256=zB_e7gBW2QloqbrGzcvccfpZhOhd6o9KACnScrwylm8,25
4
4
  ciocore/api_client.py,sha256=O9uvtnqgmE2IRkqlP9DoPn6CX_HAIuSLo9je5Om-800,17913
@@ -7,11 +7,11 @@ ciocore/common.py,sha256=FnggAL-IGW8VQB6kLsrKLnxWFgLpwGBhOtiZSHz130M,14725
7
7
  ciocore/compat.py,sha256=5uEXPSog_jxsDMaHBswAKEtfyXT25VgU6WNGIhz9PHU,256
8
8
  ciocore/conductor_submit.py,sha256=4a71RR5kOEfh_UdEx-sSnVjmHqyFbfBFoyHFbxwDN2A,7283
9
9
  ciocore/config.py,sha256=fcxnwaYmNAmvMXQeb5V-86Pwwy3a3NTPCA0CSLqog3s,5913
10
- ciocore/data.py,sha256=20mihsV7Y16hVBd9-WPxazf5XVMK8DaZegZTHAXIBLc,9102
10
+ ciocore/data.py,sha256=RQZEYGkZrVFgyyPqzBat-L99sq49h-SQUnSdGIPDI18,8938
11
11
  ciocore/downloader.py,sha256=oRmRePdIx_GdQwM39ipl9_e2c2ZkcGJRanuHOZmqpTM,51147
12
12
  ciocore/exceptions.py,sha256=c1K48hWcD8VOORfNoSf5qlQkLLEqwjryH8FUwUYAYU4,1431
13
13
  ciocore/file_utils.py,sha256=bAlL31B4YkRgX-yT8kF8UXBFktQlsE1PvxbKqTeAeOU,17174
14
- ciocore/hardware_set.py,sha256=nVY7ckYm9eafb5MPyLp1EONiWI0qt0OjWc1TnLKKKnI,2761
14
+ ciocore/hardware_set.py,sha256=txcSLrVSNewRGxKLye-wuM8szGMVloU29ktL8WHdUtM,5401
15
15
  ciocore/loggeria.py,sha256=dKKJC8ZtRZdghqD5R5XrA6eDoy8gKacfeTA-zNzXvDE,13482
16
16
  ciocore/package_environment.py,sha256=oEbNKXRtPSPzKR-yCoKtvgzu4OCmr-zaqAcNoLAN9Uk,7238
17
17
  ciocore/package_tree.py,sha256=kH03HVfjomj7nsaxJJtr-1KSQ_9ZSQY5msG_l9btvg8,16277
@@ -23,16 +23,16 @@ ciocore/auth/__init__.py,sha256=cdS-xZzMq41yXM5cz8sUlcYgo8CJYh8HcCCWmhbDgf0,606
23
23
  ciocore/auth/server.py,sha256=8btX9-EokUl6q55V8muDmEV2tvvbTBD0BHeWFbwkzUc,3892
24
24
  ciocore/cli/__init__.py,sha256=RmZKWJaMpzNyMdyYc2W3VXglaJiC8vyR2cgUlA-9Qmw,26
25
25
  ciocore/cli/conductor.py,sha256=snmlICkMgP94ZPKl6J7g299deB75QwGDWI0oCnZPfSI,10861
26
- ciocore-6.0.0rc4.data/scripts/conductor,sha256=Nk3QsLQqbUUrtaKDp4b5mr9__4tz-xnssENpQe5vuIo,409
27
- ciocore-6.0.0rc4.data/scripts/conductor.bat,sha256=T1_9ByheubBczgQZn8_LwfvMtWgE7Bt64EsEScnSXMs,447
26
+ ciocore-6.3.0.data/scripts/conductor,sha256=Nk3QsLQqbUUrtaKDp4b5mr9__4tz-xnssENpQe5vuIo,409
27
+ ciocore-6.3.0.data/scripts/conductor.bat,sha256=T1_9ByheubBczgQZn8_LwfvMtWgE7Bt64EsEScnSXMs,447
28
28
  tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
- tests/instance_type_fixtures.py,sha256=ajOfz_AO39Er1mKNN913oVcBVrW_El1ADBHQoYU6Pp4,2935
29
+ tests/instance_type_fixtures.py,sha256=gR6ordfghp34I94oM2eDg6jfIe5HAwE644GKIwspuW8,3469
30
30
  tests/package_fixtures.py,sha256=CsJnhB7oYzIxJH7b1tCOPyvnnVSCqEbSPhtCnsHL-nA,5070
31
31
  tests/test_api_client.py,sha256=dWOmAIKmX0gLaDGsT9VfAq9Hcs9HIQf2P5IMM_Bt5dE,1284
32
32
  tests/test_common.py,sha256=lJpzRdL-7u4McXFbLuwPQQoUnuEOnCVQtZEt6e_dIYs,638
33
33
  tests/test_config.py,sha256=nSmpinX2SmDNAprIcxs9UHdB0VakJB0snXaZmAoKJSc,12863
34
34
  tests/test_data.py,sha256=YdP1kZJivQ6yb9z96UK6oMDaOfJAl4YMJqzKvlCQaes,5744
35
- tests/test_hardware_set.py,sha256=9MAXI2sTziTddfSnE4uIJmMfIAf5ijukPsO-q7XE4JY,2400
35
+ tests/test_hardware_set.py,sha256=TcBh63rOxf1rKXxKlCPSnHueBFlz7rNP6BcoJjgVvPs,3065
36
36
  tests/test_imports_2and3.py,sha256=ehqpRYPVY7djBcb8OT_cnh86iCJJ9wuMWnfSR9RHxmY,507
37
37
  tests/test_package_environment.py,sha256=CdiC2PDVSnbcwTb4fsDTWqGYSzs1n5ca2KMoyISckGA,5893
38
38
  tests/test_package_tree.py,sha256=xCwNwYUmJrfmgCP2FGoHRFG-L0JPy8s4-66icxAls4o,6780
@@ -42,7 +42,7 @@ tests/test_validator.py,sha256=2fY66ayNc08PGyj2vTI-V_1yeCWJDngkj2zkUM5TTCI,1526
42
42
  tests/mocks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
43
43
  tests/mocks/api_client_mock.py,sha256=Wfv2JPFSZfyHftVqsqxcpXWJn136pEHx26I_esz567E,943
44
44
  tests/mocks/glob.py,sha256=J2MH7nqi6NJOHuGdVWxhfeBd700_Ckj6cLh_8jSNkfg,215
45
- ciocore-6.0.0rc4.dist-info/METADATA,sha256=TEm5oI4T0EYLHdRST3rD8TaobTSkKcz-7UmxBMC8-JY,14618
46
- ciocore-6.0.0rc4.dist-info/WHEEL,sha256=bb2Ot9scclHKMOLDEHY6B2sicWOgugjFKaJsT7vwMQo,110
47
- ciocore-6.0.0rc4.dist-info/top_level.txt,sha256=SvlM5JlqULzAz00JZWfiUhfjhqDzYzSWssA87zdJl0o,14
48
- ciocore-6.0.0rc4.dist-info/RECORD,,
45
+ ciocore-6.3.0.dist-info/METADATA,sha256=Jf9qxoQUVb1qnmIgguLei22xyWZTXtoHIEYWBf9pe4w,14285
46
+ ciocore-6.3.0.dist-info/WHEEL,sha256=a-zpFRIJzOq5QfuhBzbhiA1eHTzNCJn8OdRvhdNX0Rk,110
47
+ ciocore-6.3.0.dist-info/top_level.txt,sha256=SvlM5JlqULzAz00JZWfiUhfjhqDzYzSWssA87zdJl0o,14
48
+ ciocore-6.3.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.38.4)
2
+ Generator: bdist_wheel (0.40.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py2-none-any
5
5
  Tag: py3-none-any
@@ -105,7 +105,7 @@ CW_INSTANCE_TYPES = [
105
105
  "operating_system": "linux",
106
106
  "description": "Desc 8 C 32 M F",
107
107
  },
108
- {
108
+ {
109
109
  "cores": 8,
110
110
  "memory": 64,
111
111
  "name": "g-8-32",
@@ -114,3 +114,24 @@ CW_INSTANCE_TYPES = [
114
114
  "description": "Desc 8 C 32 M G",
115
115
  },
116
116
  ]
117
+
118
+ CW_INSTANCE_TYPES_WITH_GPUS = [
119
+ {
120
+ "cores": 8,
121
+ "memory": 64,
122
+ "name": "f-8-32-gpu",
123
+ "categories": [{"label": "high", "order": 3}],
124
+ "operating_system": "linux",
125
+ "description": "Desc 8 C 32 M F gpu",
126
+ "gpu": 1,
127
+ },
128
+ {
129
+ "cores": 8,
130
+ "memory": 64,
131
+ "name": "g-8-32-gpu",
132
+ "categories": [{"label": "high", "order": 3}],
133
+ "operating_system": "linux",
134
+ "description": "Desc 8 C 32 M G gpu",
135
+ "gpu": 1,
136
+ },
137
+ ] + CW_INSTANCE_TYPES
@@ -5,7 +5,7 @@
5
5
  import unittest
6
6
  from unittest.mock import patch
7
7
 
8
- from ciocore.hardware_set import MISC_CATEGORY_LABEL, HardwareSet
8
+ from ciocore.hardware_set import HardwareSet
9
9
 
10
10
  PROJECTS = [
11
11
  "Deadpool",
@@ -15,7 +15,7 @@ PROJECTS = [
15
15
  ]
16
16
 
17
17
  from package_fixtures import *
18
- from instance_type_fixtures import *
18
+ from instance_type_fixtures import CW_INSTANCE_TYPES, CW_INSTANCE_TYPES_WITH_GPUS, ALL_INSTANCE_TYPES
19
19
 
20
20
 
21
21
  class TestCategorizedInstanceTypes(unittest.TestCase):
@@ -23,7 +23,7 @@ class TestCategorizedInstanceTypes(unittest.TestCase):
23
23
  self.hs = HardwareSet(CW_INSTANCE_TYPES)
24
24
 
25
25
  def test_number_of_categories(self):
26
- self.assertEqual(self.hs.number_of_categories(), 5)
26
+ self.assertEqual(self.hs.number_of_categories(), 4)
27
27
 
28
28
  def test_categories_sorted_on_order(self):
29
29
  labels = [i["label"] for i in self.hs.get_model()]
@@ -39,17 +39,31 @@ class TestCategorizedInstanceTypes(unittest.TestCase):
39
39
  self.assertIn("a-4-16", low_category_values)
40
40
  self.assertIn("a-4-16", extra_category_values)
41
41
 
42
- def test_model_removes_misc_by_default(self):
43
- model = self.hs.get_model()
44
- labels = [c["label"] for c in model]
45
- self.assertNotIn(MISC_CATEGORY_LABEL, labels)
46
-
47
- def test_model_adds_misc_if_specified(self):
48
- model = self.hs.get_model(with_misc=True)
49
- labels = [c["label"] for c in model]
50
- self.assertIn(MISC_CATEGORY_LABEL, labels)
51
-
52
-
42
+ class TestRecategorizeInstanceTypes(unittest.TestCase):
43
+ def setUp(self):
44
+ self.hs = HardwareSet(CW_INSTANCE_TYPES_WITH_GPUS)
45
+
46
+ def test_recategorize_cpu_gpu(self):
47
+ test_func = lambda x: [{'label': 'GPU', 'order': 2}] if "gpu" in x and x["gpu"] else [{'label': 'CPU', 'order': 1}]
48
+ self.hs.recategorize(test_func)
49
+ self.assertEqual(self.hs.number_of_categories(), 2)
50
+
51
+ def test_find_all_by_condition(self):
52
+ test_func = lambda x: "gpu" in x and x["gpu"]
53
+ result = self.hs.find_all(test_func)
54
+ self.assertEqual(len(result), 2)
55
+
56
+ def test_find_first_by_condition(self):
57
+ test_func = lambda x: x[ "memory"] < 32
58
+ result = self.hs.find_first(test_func)
59
+ self.assertTrue(result["memory"] < 32)
60
+
61
+ def test_find_category(self):
62
+ label = "mid"
63
+ result = self.hs.find_category(label)
64
+ self.assertEqual(result["label"] , label)
65
+ self.assertEqual(result["order"] , 2)
66
+
53
67
  class TestUncategorizedInstanceTypes(unittest.TestCase):
54
68
  def setUp(self):
55
69
  self.hs = HardwareSet(ALL_INSTANCE_TYPES)