Skip to content

Commit 21c90e5

Browse files
committed
Fix parsing
1 parent 1b2338d commit 21c90e5

File tree

2 files changed

+80
-45
lines changed

2 files changed

+80
-45
lines changed

src/coldfront_plugin_cloud/management/commands/validate_allocations.py

Lines changed: 51 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,56 @@ def set_default_quota_on_allocation(allocation, allocator, coldfront_attr):
9090
utils.set_attribute_on_allocation(allocation, coldfront_attr, value)
9191
return value
9292

93+
@staticmethod
94+
def parse_quota_value(quota_str: str | None, attr: str) -> int | None:
95+
PATTERN = r"([0-9]+)(m|k|Ki|Mi|Gi|Ti|Pi|Ei|K|M|G|T|P|E)?"
96+
97+
suffix = {
98+
"Ki": 2**10,
99+
"Mi": 2**20,
100+
"Gi": 2**30,
101+
"Ti": 2**40,
102+
"Pi": 2**50,
103+
"Ei": 2**60,
104+
"m": 10**-3,
105+
"k": 10**3,
106+
"K": 10**3,
107+
"M": 10**6,
108+
"G": 10**9,
109+
"T": 10**12,
110+
"P": 10**15,
111+
"E": 10**18,
112+
}
113+
114+
if quota_str and quota_str != "0":
115+
result = re.search(PATTERN, quota_str)
116+
117+
if result is None:
118+
raise CommandError(
119+
f"Unable to parse quota_str = '{quota_str}' for {attr}"
120+
)
121+
122+
value = int(result.groups()[0])
123+
unit = result.groups()[1]
124+
125+
# Convert to number i.e. without any unit suffix
126+
127+
if unit is not None:
128+
quota_str = value * suffix[unit]
129+
else:
130+
quota_str = value
131+
132+
# Convert some attributes to units that coldfront uses
133+
134+
if "RAM" in attr:
135+
quota_str = round(quota_str / suffix["Mi"])
136+
elif "Storage" in attr:
137+
quota_str = round(quota_str / suffix["Gi"])
138+
elif quota_str and quota_str == "0":
139+
quota_str = 0
140+
141+
return quota_str
142+
93143
def check_institution_specific_code(self, allocation, apply):
94144
attr = attributes.ALLOCATION_INSTITUTION_SPECIFIC_CODE
95145
isc = allocation.get_attribute(attr)
@@ -250,51 +300,7 @@ def handle(self, *args, **options):
250300

251301
expected_value = allocation.get_attribute(attr)
252302
current_value = quota.get(key, None)
253-
254-
PATTERN = r"([0-9]+)(m|Ki|Mi|Gi|Ti|Pi|Ei|K|M|G|T|P|E)?"
255-
256-
suffix = {
257-
"Ki": 2**10,
258-
"Mi": 2**20,
259-
"Gi": 2**30,
260-
"Ti": 2**40,
261-
"Pi": 2**50,
262-
"Ei": 2**60,
263-
"m": 10**-3,
264-
"K": 10**3,
265-
"M": 10**6,
266-
"G": 10**9,
267-
"T": 10**12,
268-
"P": 10**15,
269-
"E": 10**18,
270-
}
271-
272-
if current_value and current_value != "0":
273-
result = re.search(PATTERN, current_value)
274-
275-
if result is None:
276-
raise CommandError(
277-
f"Unable to parse current_value = '{current_value}' for {attr}"
278-
)
279-
280-
value = int(result.groups()[0])
281-
unit = result.groups()[1]
282-
283-
# Convert to number i.e. without any unit suffix
284-
285-
if unit is not None:
286-
current_value = value * suffix[unit]
287-
else:
288-
current_value = value
289-
290-
# Convert some attributes to units that coldfront uses
291-
292-
if "RAM" in attr:
293-
current_value = round(current_value / suffix["Mi"])
294-
elif "Storage" in attr:
295-
current_value = round(current_value / suffix["Gi"])
296-
elif current_value and current_value == "0":
297-
current_value = 0
303+
current_value = self.parse_quota_value(current_value, attr)
298304

299305
if expected_value is None and current_value is not None:
300306
msg = (
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from django.core.management.base import CommandError
2+
3+
from coldfront_plugin_cloud.management.commands.validate_allocations import Command
4+
from coldfront_plugin_cloud.tests import base
5+
6+
7+
class TestParseQuotaUnit(base.TestBase):
8+
def test_parse_quota_unit(self):
9+
parse_quota_unit = Command().parse_quota_value
10+
answer_dict = [
11+
(("5m", "cpu"), 5 * 10**-3),
12+
(("10", "cpu"), 10),
13+
(("10k", "cpu"), 10 * 10**3),
14+
(("55M", "cpu"), 55 * 10**6),
15+
(("2G", "cpu"), 2 * 10**9),
16+
(("3T", "cpu"), 3 * 10**12),
17+
(("4P", "cpu"), 4 * 10**15),
18+
(("5E", "cpu"), 5 * 10**18),
19+
(("10", "memory"), 10),
20+
(("125Ki", "memory"), 125 * 2**10),
21+
(("55Mi", "memory"), 55 * 2**20),
22+
(("2Gi", "memory"), 2 * 2**30),
23+
(("3Ti", "memory"), 3 * 2**40),
24+
]
25+
for (input_value, resource_type), expected in answer_dict:
26+
self.assertEqual(parse_quota_unit(input_value, resource_type), expected)
27+
28+
with self.assertRaises(CommandError):
29+
parse_quota_unit("abc", "foo") # Non-numeric input

0 commit comments

Comments
 (0)