Skip to content

Commit df37ebd

Browse files
committed
Improve record testing and fix errors found
Include missing fields in CloudRecord when being rendered (i.e. remove the `exlude_unset` argument when exporting, and remove versions from rendering. Fixes: #118 SemVer: bufgix
1 parent 8554846 commit df37ebd

File tree

4 files changed

+43
-30
lines changed

4 files changed

+43
-30
lines changed

caso/messenger/ssm.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,6 @@ def push(self, records):
183183
entries_storage = []
184184
opts = {
185185
"by_alias": True,
186-
"exclude_unset": True,
187186
"exclude_none": True,
188187
}
189188
for record in records:

caso/record.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616

1717
"""Module containing all the cloud accounting records."""
1818

19-
import abc
2019
import datetime
20+
import enum
2121
import typing
2222
import uuid as m_uuid
2323

@@ -29,23 +29,33 @@
2929
LOG = log.getLogger(__name__)
3030

3131

32-
class _BaseRecord(pydantic.BaseModel, abc.ABC):
32+
class _BaseRecord(pydantic.BaseModel):
3333
"""This is the base cASO record object."""
3434

35-
version: str
35+
version: str = pydantic.Field(..., exclude=True)
3636

3737
site_name: str
38-
cloud_type = caso.user_agent
38+
cloud_type: str = caso.user_agent
3939
compute_service: str
4040

4141

42+
class _ValidCloudStatus(str, enum.Enum):
43+
started = "started"
44+
completed = "completed"
45+
error = "error"
46+
paused = "paused"
47+
suspended = "suspended"
48+
stopped = "stopped"
49+
unknown = "unknown"
50+
51+
4252
class CloudRecord(_BaseRecord):
4353
"""The CloudRecord class holds information for each of the records.
4454
4555
This class is versioned, following the Cloud Accounting Record versions.
4656
"""
4757

48-
version: str = "0.4"
58+
version: str = pydantic.Field("0.4", exclude=True)
4959

5060
uuid: m_uuid.UUID
5161
name: str
@@ -55,7 +65,7 @@ class CloudRecord(_BaseRecord):
5565
group_id: str
5666
fqan: str
5767

58-
status: str
68+
status: _ValidCloudStatus
5969

6070
image_id: typing.Optional[str]
6171

@@ -156,7 +166,7 @@ class IPRecord(_BaseRecord):
156166
This class is versioned, following the Public IP Usage Record versions.
157167
"""
158168

159-
version = "0.2"
169+
version: str = pydantic.Field("0.2", exclude=True)
160170

161171
uuid: m_uuid.UUID
162172

caso/tests/conftest.py

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@
2020

2121
import pytest
2222

23+
import caso
2324
import caso.record
2425

2526
now = datetime.datetime(2023, 5, 25, 21, 59, 6, 0)
27+
cloud_type = caso.user_agent
2628

27-
valid_records_fields = [
29+
valid_cloud_records_fields = [
2830
dict(
2931
uuid="721cf1db-0e0f-4c24-a5ea-cd75e0f303e8",
3032
site_name="TEST-Site",
@@ -35,7 +37,7 @@
3537
start_time=now - datetime.timedelta(days=5),
3638
end_time=now,
3739
compute_service="Fake Cloud Service",
38-
status="ACTIVE",
40+
status="started",
3941
image_id="b39a8ed9-e15d-4b71-ada2-daf88efbac0a",
4042
user_dn="User DN",
4143
benchmark_type=None,
@@ -55,7 +57,7 @@
5557
start_time=now - datetime.timedelta(days=6),
5658
end_time=now,
5759
compute_service="Fake Cloud Service",
58-
status="ACTIVE",
60+
status="completed",
5961
image_id="b39a8ed9-e15d-4b71-ada2-daf88efbac0a",
6062
user_dn="User DN",
6163
benchmark_type=None,
@@ -67,11 +69,12 @@
6769
),
6870
]
6971

70-
valid_records_dict = [
72+
valid_cloud_records_dict = [
7173
{
7274
"CloudComputeService": "Fake Cloud Service",
7375
"CpuCount": 8,
7476
"CpuDuration": 3456000,
77+
"CloudType": cloud_type,
7578
"Disk": 250,
7679
"StartTime": 1684612746,
7780
"EndTime": 1685044746,
@@ -84,14 +87,15 @@
8487
"Memory": 16,
8588
"PublicIPCount": 7,
8689
"SiteName": "TEST-Site",
87-
"Status": "ACTIVE",
90+
"Status": "started",
8891
"VMUUID": "721cf1db-0e0f-4c24-a5ea-cd75e0f303e8",
8992
"WallDuration": 432000,
9093
},
9194
{
9295
"CloudComputeService": "Fake Cloud Service",
9396
"CpuCount": 8,
9497
"CpuDuration": 3456000,
98+
"CloudType": cloud_type,
9599
"Disk": 250,
96100
"StartTime": 1684526346,
97101
"EndTime": 1685044746,
@@ -104,7 +108,7 @@
104108
"Memory": 16,
105109
"PublicIPCount": 7,
106110
"SiteName": "TEST-Site",
107-
"Status": "ACTIVE",
111+
"Status": "completed",
108112
"VMUUID": "a53738e1-13eb-4047-800c-067d14ce3d22",
109113
"WallDuration": 432000,
110114
},
@@ -116,7 +120,7 @@
116120
@pytest.fixture(scope="module")
117121
def cloud_record():
118122
"""Get a fixture for the CloudRecord."""
119-
record = caso.record.CloudRecord(**valid_records_fields[0])
123+
record = caso.record.CloudRecord(**valid_cloud_records_fields[0])
120124
# Remove this when moving to Pydantic 2
121125
record.wall_duration = 432000
122126
record.cpu_duration = 3456000
@@ -126,28 +130,28 @@ def cloud_record():
126130
@pytest.fixture(scope="module")
127131
def another_cloud_record():
128132
"""Get another fixture for the CloudRecord."""
129-
record = caso.record.CloudRecord(**valid_records_fields[1])
133+
record = caso.record.CloudRecord(**valid_cloud_records_fields[1])
130134
record.wall_duration = 432000
131135
record.cpu_duration = 3456000
132136
return record
133137

134138

135139
@pytest.fixture(scope="module")
136-
def valid_record():
140+
def valid_cloud_record():
137141
"""Get a fixture for a valid record."""
138-
return valid_records_dict[0]
142+
return valid_cloud_records_dict[0]
139143

140144

141145
@pytest.fixture(scope="module")
142-
def valid_records():
146+
def valid_cloud_records():
143147
"""Get a fixture for valid records as a dict."""
144-
return valid_records_dict
148+
return valid_cloud_records_dict
145149

146150

147151
@pytest.fixture(scope="module")
148-
def another_valid_record():
152+
def another_valid_cloud_record():
149153
"""Get another fixture for a valid record as a dict."""
150-
return valid_records_dict[0]
154+
return valid_cloud_records_dict[0]
151155

152156

153157
@pytest.fixture(scope="module")
@@ -164,6 +168,7 @@ def expected_entries_cloud():
164168
"""Get a fixture for all cloud entries."""
165169
ssm_entries = [
166170
"CloudComputeService: Fake Cloud Service\n"
171+
f"CloudType: {cloud_type}\n"
167172
"CpuCount: 8\n"
168173
"CpuDuration: 3456000\n"
169174
"Disk: 250\n"
@@ -178,10 +183,11 @@ def expected_entries_cloud():
178183
"PublicIPCount: 7\n"
179184
"SiteName: TEST-Site\n"
180185
"StartTime: 1684612746\n"
181-
"Status: ACTIVE\n"
186+
"Status: started\n"
182187
"VMUUID: 721cf1db-0e0f-4c24-a5ea-cd75e0f303e8\n"
183188
"WallDuration: 432000",
184189
"CloudComputeService: Fake Cloud Service\n"
190+
f"CloudType: {cloud_type}\n"
185191
"CpuCount: 8\n"
186192
"CpuDuration: 3456000\n"
187193
"Disk: 250\n"
@@ -196,7 +202,7 @@ def expected_entries_cloud():
196202
"PublicIPCount: 7\n"
197203
"SiteName: TEST-Site\n"
198204
"StartTime: 1684526346\n"
199-
"Status: ACTIVE\n"
205+
"Status: completed\n"
200206
"VMUUID: a53738e1-13eb-4047-800c-067d14ce3d22\n"
201207
"WallDuration: 432000",
202208
]

caso/tests/test_record.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,18 +36,17 @@ def test_cloud_record(cloud_record):
3636

3737

3838
@pytest.mark.skip(reason="Pydantic 1 does not support computed fields")
39-
def test_cloud_record_map_opts(cloud_record, valid_record):
39+
def test_cloud_record_map_opts(cloud_record, valid_cloud_record):
4040
"""Test a cloud record is correctly rendered."""
4141
opts = {
4242
"by_alias": True,
43-
"exclude_unset": True,
4443
"exclude_none": True,
4544
}
4645

47-
assert json.loads(cloud_record.json(**opts)) == valid_record
46+
assert json.loads(cloud_record.json(**opts)) == valid_cloud_record
4847

4948

50-
def test_cloud_record_map_opts_custom_wall_cpu(cloud_record, valid_record):
49+
def test_cloud_record_map_opts_custom_wall_cpu(cloud_record, valid_cloud_record):
5150
"""Test a cloud record is correctly rendered with custom wall and cpu times."""
5251
wall = datetime.timedelta(days=5).total_seconds()
5352
cpu = wall * cloud_record.cpu_count
@@ -56,11 +55,10 @@ def test_cloud_record_map_opts_custom_wall_cpu(cloud_record, valid_record):
5655

5756
opts = {
5857
"by_alias": True,
59-
"exclude_unset": True,
6058
"exclude_none": True,
6159
}
6260

63-
assert json.loads(cloud_record.json(**opts)) == valid_record
61+
assert json.loads(cloud_record.json(**opts)) == valid_cloud_record
6462

6563

6664
@pytest.mark.skip(reason="Pydantic 1 does not support computed fields")

0 commit comments

Comments
 (0)