Skip to content

Commit 144becd

Browse files
feat: add param to return full environment_misc (#1833)
1 parent 4eed231 commit 144becd

17 files changed

Lines changed: 563 additions & 39 deletions

backend/kernelCI_app/constants/localization.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ class DocStrings:
113113
TREE_QUERY_ORIGIN_DESCRIPTION = "Origin of the tree"
114114
TREE_QUERY_GIT_URL_DESCRIPTION = "Git repository URL of the tree"
115115

116+
FULL_ENVIRONMENT_MISC_DESCRIPTION = (
117+
"When true, returns all fields from environment_misc instead of only platform"
118+
)
119+
116120
STATUS_HISTORY_PATH_DESCRIPTION = "Test path filter"
117121
STATUS_HISTORY_ORIGIN_DESCRIPTION = "Origin filter to retrieve tests"
118122
STATUS_HISTORY_GIT_URL_DESCRIPTION = "Git repository URL to retrieve tests"

backend/kernelCI_app/helpers/hardwareDetails.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@
2020
should_increment_test_issue,
2121
)
2222
from kernelCI_app.helpers.logger import log_message
23-
from kernelCI_app.helpers.misc import misc_value_or_default, handle_misc
23+
from kernelCI_app.helpers.misc import (
24+
get_environment_misc_value,
25+
handle_misc,
26+
misc_value_or_default,
27+
)
2428
from kernelCI_app.typeModels.databases import (
2529
FAIL_STATUS,
2630
NULL_STATUS,
@@ -272,8 +276,10 @@ def handle_tree_status_summary(
272276

273277
def create_record_test_platform(*, record: Dict) -> str:
274278
environment_misc = handle_misc(record["environment_misc"])
275-
test_platform = misc_value_or_default(environment_misc).get("platform")
279+
resolved_misc = misc_value_or_default(environment_misc)
280+
test_platform = resolved_misc.get("platform")
276281
record["test_platform"] = test_platform
282+
record["parsed_environment_misc"] = resolved_misc
277283

278284
return test_platform
279285

@@ -282,10 +288,17 @@ def handle_test_history(
282288
*,
283289
record: Dict,
284290
task: List[HardwareTestHistoryItem],
291+
full_environment_misc: bool = False,
285292
) -> None:
286293
create_record_test_platform(record=record)
287294
record_misc = sanitize_dict(record.get("misc"))
288295

296+
environment_misc_dict = get_environment_misc_value(
297+
full_environment_misc=full_environment_misc,
298+
parsed_environment_misc=record.get("parsed_environment_misc"),
299+
)
300+
environment_misc = EnvironmentMisc(**environment_misc_dict)
301+
289302
test_history_item = HardwareTestHistoryItem(
290303
id=record["id"],
291304
origin=record["test_origin"],
@@ -298,7 +311,7 @@ def handle_test_history(
298311
log_url=record["log_url"],
299312
architecture=record["build__architecture"],
300313
compiler=record["build__compiler"],
301-
environment_misc=EnvironmentMisc(platform=record["test_platform"]),
314+
environment_misc=environment_misc,
302315
tree_name=record["build__checkout__tree_name"],
303316
git_repository_branch=record["build__checkout__git_repository_branch"],
304317
lab=(

backend/kernelCI_app/helpers/misc.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,23 @@
33
from kernelCI_app.utils import sanitize_dict
44

55

6-
class Misc(TypedDict):
6+
class Misc(TypedDict, total=False):
77
platform: str
88
lab: Optional[str]
99

1010

11-
def handle_misc(misc: Union[str, dict, None]) -> Optional[Misc]:
11+
def handle_misc(misc: Union[str, dict, None]) -> Optional[dict]:
1212
"""
1313
Handle misc data (environment or build) by parsing JSON string or dict.
14-
Also sets some default values and returns only the necessary fields.
14+
Preserves all fields and sets default values for known fields.
1515
"""
1616

1717
misc = sanitize_dict(misc)
1818
if misc is None:
1919
return None
2020

21-
parsed_misc: Misc = {}
22-
parsed_misc["platform"] = misc.get("platform", UNKNOWN_STRING)
23-
if "lab" in misc:
24-
parsed_misc["lab"] = misc.get("lab")
21+
parsed_misc = dict(misc)
22+
parsed_misc.setdefault("platform", UNKNOWN_STRING)
2523

2624
return parsed_misc
2725

@@ -35,3 +33,15 @@ def misc_value_or_default(misc: Optional[Misc]) -> Misc:
3533
if misc is not None:
3634
return misc
3735
return default_misc
36+
37+
38+
def get_environment_misc_value(
39+
*,
40+
full_environment_misc: bool,
41+
parsed_environment_misc: Optional[dict],
42+
) -> dict:
43+
"""Return the appropriate environment_misc value based on the full_environment_misc flag."""
44+
platform = parsed_environment_misc.get("platform")
45+
if full_environment_misc:
46+
return parsed_environment_misc or {"platform": platform}
47+
return {"platform": platform}

backend/kernelCI_app/helpers/treeDetails.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from kernelCI_app.typeModels.issues import Issue, IssueDict
1919
from kernelCI_app.utils import create_issue_typed, extract_error_message, sanitize_dict
2020
from kernelCI_app.helpers.misc import (
21+
get_environment_misc_value,
2122
handle_misc,
2223
misc_value_or_default,
2324
)
@@ -64,7 +65,9 @@ def create_checkouts_where_clauses(
6465
}
6566

6667

67-
def get_current_row_data(current_row: dict) -> dict:
68+
def get_current_row_data(
69+
current_row: dict, full_environment_misc: bool = False
70+
) -> dict:
6871
tmp_test_env_comp_key = 12
6972
current_row_data = {
7073
"test_id": current_row[0],
@@ -107,10 +110,11 @@ def get_current_row_data(current_row: dict) -> dict:
107110
"issue_report_url": current_row[37],
108111
}
109112

110-
environment_misc = handle_misc(
113+
parsed_environment_misc = handle_misc(
111114
misc_value_or_default(current_row_data["test_environment_misc"])
112115
)
113-
current_row_data["test_platform"] = environment_misc.get("platform")
116+
current_row_data["test_platform"] = parsed_environment_misc.get("platform")
117+
current_row_data["parsed_environment_misc"] = parsed_environment_misc
114118
test_misc = sanitize_dict(current_row_data["test_misc"])
115119
test_runtime_lab = UNKNOWN_STRING
116120
if test_misc is not None:
@@ -145,6 +149,11 @@ def get_current_row_data(current_row: dict) -> dict:
145149
if current_row_data["test_path"] is None:
146150
current_row_data["test_path"] = UNKNOWN_STRING
147151

152+
environment_misc_value = get_environment_misc_value(
153+
full_environment_misc=full_environment_misc,
154+
parsed_environment_misc=parsed_environment_misc,
155+
)
156+
148157
current_row_data["history_item"] = {
149158
"id": current_row_data["test_id"],
150159
"origin": current_row_data["test_origin"],
@@ -157,7 +166,7 @@ def get_current_row_data(current_row: dict) -> dict:
157166
"log_url": current_row_data["test_log_url"],
158167
"architecture": current_row_data["build_architecture"],
159168
"compiler": current_row_data["build_compiler"],
160-
"environment_misc": {"platform": current_row_data["test_platform"]},
169+
"environment_misc": environment_misc_value,
161170
"lab": test_runtime_lab,
162171
}
163172

backend/kernelCI_app/tests/unitTests/helpers/hardwareDetails_helpers_test.py

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,9 @@ def test_create_record_test_platform(
477477

478478
assert result == "hp-x360-14a-cb0001xx-zork"
479479
assert record["test_platform"] == "hp-x360-14a-cb0001xx-zork"
480+
assert record["parsed_environment_misc"] == {
481+
"platform": "hp-x360-14a-cb0001xx-zork"
482+
}
480483
mock_handle_env_misc.assert_called_once_with("{}")
481484
mock_env_misc_value.assert_called_once_with(
482485
{"platform": "hp-x360-14a-cb0001xx-zork"}
@@ -486,10 +489,11 @@ def test_create_record_test_platform(
486489
class TestHandleTestHistory:
487490
@patch("kernelCI_app.helpers.hardwareDetails.create_record_test_platform")
488491
def test_handle_test_history(self, mock_create_platform):
489-
"""Test handle_test_history function."""
492+
"""Test handle_test_history function with default behavior."""
490493

491494
def mock_create_platform_side_effect(record):
492495
record["test_platform"] = "x86_64"
496+
record["parsed_environment_misc"] = {"platform": "x86_64"}
493497
return "x86_64"
494498

495499
mock_create_platform.side_effect = mock_create_platform_side_effect
@@ -521,6 +525,96 @@ def mock_create_platform_side_effect(record):
521525
assert task[0].environment_misc.platform == "x86_64"
522526
mock_create_platform.assert_called_once_with(record=record)
523527

528+
@patch("kernelCI_app.helpers.hardwareDetails.create_record_test_platform")
529+
def test_handle_test_history_full_environment_misc(self, mock_create_platform):
530+
"""Test handle_test_history with full_environment_misc=True includes all fields."""
531+
532+
def mock_create_platform_side_effect(record):
533+
record["test_platform"] = "x86_64"
534+
record["parsed_environment_misc"] = {
535+
"platform": "x86_64",
536+
"laa_uid": "uid-1",
537+
"dut_uid": "dut-1",
538+
"device": "dev-a",
539+
}
540+
return "x86_64"
541+
542+
mock_create_platform.side_effect = mock_create_platform_side_effect
543+
544+
record = {
545+
"id": "test123",
546+
"test_origin": "test",
547+
"status": "PASS",
548+
"duration": 100,
549+
"path": "test.specific",
550+
"start_time": "2024-01-15T10:00:00Z",
551+
"environment_compatible": "x86_64",
552+
"build__config_name": "defconfig",
553+
"log_url": "http://example.com/log",
554+
"build__architecture": "x86_64",
555+
"build__compiler": "gcc",
556+
"environment_misc": "{}",
557+
"build__checkout__tree_name": "mainline",
558+
"build__checkout__git_repository_branch": "master",
559+
}
560+
561+
task = []
562+
563+
handle_test_history(record=record, task=task, full_environment_misc=True)
564+
565+
assert len(task) == 1
566+
assert task[0].id == "test123"
567+
assert task[0].environment_misc.platform == "x86_64"
568+
assert task[0].environment_misc.laa_uid == "uid-1"
569+
assert task[0].environment_misc.dut_uid == "dut-1"
570+
assert task[0].environment_misc.device == "dev-a"
571+
mock_create_platform.assert_called_once_with(record=record)
572+
573+
@patch("kernelCI_app.helpers.hardwareDetails.create_record_test_platform")
574+
def test_handle_test_history_default_no_extra_fields(self, mock_create_platform):
575+
"""Test handle_test_history with full_environment_misc=False only includes platform."""
576+
577+
def mock_create_platform_side_effect(record):
578+
record["test_platform"] = "x86_64"
579+
record["parsed_environment_misc"] = {
580+
"platform": "x86_64",
581+
"laa_uid": "uid-1",
582+
"dut_uid": "dut-1",
583+
"device": "dev-a",
584+
}
585+
return "x86_64"
586+
587+
mock_create_platform.side_effect = mock_create_platform_side_effect
588+
589+
record = {
590+
"id": "test123",
591+
"test_origin": "test",
592+
"status": "PASS",
593+
"duration": 100,
594+
"path": "test.specific",
595+
"start_time": "2024-01-15T10:00:00Z",
596+
"environment_compatible": "x86_64",
597+
"build__config_name": "defconfig",
598+
"log_url": "http://example.com/log",
599+
"build__architecture": "x86_64",
600+
"build__compiler": "gcc",
601+
"environment_misc": "{}",
602+
"build__checkout__tree_name": "mainline",
603+
"build__checkout__git_repository_branch": "master",
604+
}
605+
606+
task = []
607+
608+
# Default behavior (full_environment_misc=False or omitted)
609+
handle_test_history(record=record, task=task, full_environment_misc=False)
610+
611+
assert len(task) == 1
612+
assert task[0].id == "test123"
613+
assert task[0].environment_misc.platform == "x86_64"
614+
# Verify extra fields are NOT present when flag is False
615+
assert not hasattr(task[0].environment_misc, "laa_uid")
616+
mock_create_platform.assert_called_once_with(record=record)
617+
524618

525619
class TestHandleTestSummary:
526620
@patch("kernelCI_app.helpers.hardwareDetails.process_issue")

backend/kernelCI_app/tests/unitTests/helpers/misc_test.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@ def test_handle_misc_with_dict(self):
2828
assert result == {"platform": "arm64"}
2929

3030
def test_handle_misc_with_dict_missing_platform(self):
31-
"""Test handle_misc with dict missing platform key."""
31+
"""Test handle_misc with dict missing platform key preserves other fields."""
3232
misc_dict = {"other": "value"}
3333

3434
result = handle_misc(misc_dict)
3535

36-
assert result == {"platform": UNKNOWN_STRING}
36+
assert result == {"other": "value", "platform": UNKNOWN_STRING}
3737

3838
def test_handle_misc_with_none(self):
3939
"""Test handle_misc with None input."""
@@ -55,6 +55,24 @@ def test_handle_misc_with_lab(self):
5555

5656
assert result == {"platform": "x86_64", "lab": "lab1"}
5757

58+
def test_handle_misc_preserves_extra_fields(self):
59+
"""Test handle_misc preserves all extra fields like laa_uid, dut_uid, device."""
60+
misc_dict = {
61+
"platform": "x86_64",
62+
"laa_uid": "uid-1",
63+
"dut_uid": "dut-1",
64+
"device": "dev-a",
65+
}
66+
67+
result = handle_misc(misc_dict)
68+
69+
assert result == {
70+
"platform": "x86_64",
71+
"laa_uid": "uid-1",
72+
"dut_uid": "dut-1",
73+
"device": "dev-a",
74+
}
75+
5876

5977
class TestMiscValueOrDefault:
6078
def test_misc_value_or_default_with_valid_misc(self):

0 commit comments

Comments
 (0)