From 4004405f7a7d905a470a994653fe50db4b440ee0 Mon Sep 17 00:00:00 2001 From: Murilo Geraldini Date: Thu, 16 Jan 2025 16:55:40 -0300 Subject: [PATCH] refactor(hardware-details): alter response - Changed all response fields to snake case - Changed response structure - Added commonDetails.py to group all common types between hardware and tree details - Added types for hardware details in the BE and in the FE Part of #731 Part of #700 --- .../kernelCI_app/helpers/hardwareDetails.py | 24 ++-- backend/kernelCI_app/helpers/treeDetails.py | 2 +- .../kernelCI_app/typeModels/commonDetails.py | 113 ++++++++++++++++ .../typeModels/hardwareDetails.py | 28 +++- .../kernelCI_app/typeModels/treeDetails.py | 126 +++--------------- backend/kernelCI_app/views/buildTestsView.py | 14 +- .../kernelCI_app/views/hardwareDetailsView.py | 51 +++++-- .../views/issueDetailsTestsView.py | 2 +- .../views/treeDetailsBootsView.py | 6 +- .../views/treeDetailsBuildsView.py | 4 +- .../views/treeDetailsTestsView.py | 6 +- backend/schema.yml | 101 +++++++------- .../src/components/TestsTable/TestsTable.tsx | 2 +- .../pages/hardwareDetails/HardwareDetails.tsx | 51 ++++--- .../hardwareDetails/HardwareDetailsFilter.tsx | 26 ++-- .../HardwareDetailsHeaderTable.tsx | 42 +++--- .../hardwareDetails/Tabs/Boots/BootsTab.tsx | 38 +++--- .../hardwareDetails/Tabs/Build/BuildTab.tsx | 37 ++--- .../Tabs/HardwareCommitNavigationGraph.tsx | 10 +- .../Tabs/HardwareDetailsTabs.tsx | 14 +- .../hardwareDetails/Tabs/Tests/TestsTab.tsx | 38 +++--- dashboard/src/types/general.ts | 2 +- .../src/types/hardware/hardwareDetails.ts | 69 +++------- dashboard/src/types/tree/TreeDetails.tsx | 13 +- 24 files changed, 438 insertions(+), 381 deletions(-) create mode 100644 backend/kernelCI_app/typeModels/commonDetails.py diff --git a/backend/kernelCI_app/helpers/hardwareDetails.py b/backend/kernelCI_app/helpers/hardwareDetails.py index 1ddfb55e..67751559 100644 --- a/backend/kernelCI_app/helpers/hardwareDetails.py +++ b/backend/kernelCI_app/helpers/hardwareDetails.py @@ -109,14 +109,14 @@ def get_hardware_trees_data( for idx, tree in enumerate(trees_query_set): trees.append( { - "treeName": tree["build__checkout__tree_name"], - "gitRepositoryBranch": tree[ + "tree_name": tree["build__checkout__tree_name"], + "git_repository_branch": tree[ "build__checkout__git_repository_branch" ], - "gitRepositoryUrl": tree["build__checkout__git_repository_url"], - "headGitCommitName": tree["build__checkout__git_commit_name"], - "headGitCommitHash": tree["build__checkout__git_commit_hash"], - "headGitCommitTag": tree["build__checkout__git_commit_tags"], + "git_repository_url": tree["build__checkout__git_repository_url"], + "head_git_commit_name": tree["build__checkout__git_commit_name"], + "head_git_commit_hash": tree["build__checkout__git_commit_hash"], + "head_git_commit_tag": tree["build__checkout__git_commit_tags"], "index": str(idx), } ) @@ -132,14 +132,14 @@ def get_trees_with_status_summary( trees_with_status_count: List[Dict] = [] for tree in trees: summary = tree_status_summary.get(tree["index"]) - trees_with_status_count.append({**tree, "selectedCommitStatusSummary": summary}) + trees_with_status_count.append({**tree, "selected_commit_status": summary}) return trees_with_status_count def get_displayed_commit(*, tree: Dict, selected_commit: Optional[str]): if (not selected_commit) or (selected_commit == SELECTED_HEAD_TREE_VALUE): - return tree["headGitCommitHash"] + return tree["head_git_commit_hash"] return selected_commit @@ -161,9 +161,9 @@ def get_trees_with_selected_commit( selected.append( { - "tree_name": tree["treeName"], - "git_repository_branch": tree["gitRepositoryBranch"], - "git_repository_url": tree["gitRepositoryUrl"], + "tree_name": tree["tree_name"], + "git_repository_branch": tree["git_repository_branch"], + "git_repository_url": tree["git_repository_url"], "index": tree["index"], "git_commit_hash": displayed_commit, "is_tree_selected": is_tree_selected, @@ -306,7 +306,7 @@ def get_history(record: Dict): "status": record["status"], "path": record["path"], "duration": record["duration"], - "startTime": record["start_time"], + "start_time": record["start_time"], } diff --git a/backend/kernelCI_app/helpers/treeDetails.py b/backend/kernelCI_app/helpers/treeDetails.py index 42624d0b..65fa704a 100644 --- a/backend/kernelCI_app/helpers/treeDetails.py +++ b/backend/kernelCI_app/helpers/treeDetails.py @@ -199,7 +199,7 @@ def get_current_row_data(current_row: dict) -> dict: "duration": current_row_data["test_duration"], "path": current_row_data["test_path"], "start_time": current_row_data["test_start_time"], - "hardware": current_row[tmp_test_env_comp_key], + "environment_compatible": current_row[tmp_test_env_comp_key], "config": current_row_data["build_config_name"], "log_url": current_row_data["test_log_url"], "architecture": current_row_data["build_architecture"], diff --git a/backend/kernelCI_app/typeModels/commonDetails.py b/backend/kernelCI_app/typeModels/commonDetails.py new file mode 100644 index 00000000..981f9e13 --- /dev/null +++ b/backend/kernelCI_app/typeModels/commonDetails.py @@ -0,0 +1,113 @@ +from datetime import datetime +from typing import Dict, List, Optional, Union + +from pydantic import BaseModel + + +class TestStatusCount(BaseModel): + PASS: Optional[int] = None + ERROR: Optional[int] = None + FAIL: Optional[int] = None + SKIP: Optional[int] = None + NULL: Optional[int] = None + + +class BuildStatusCount(BaseModel): + valid: int + invalid: int + null: int + + +class TestArchSummaryItem(BaseModel): + arch: str + compiler: str + status: TestStatusCount + + +class BuildConfigs(BuildStatusCount): + valid: int + invalid: int + null: int + + +class IncidentsInfo(BaseModel): + incidentsCount: int + + +class TestIssuesItem(BaseModel): + id: str + comment: Optional[str] + report_url: Optional[str] + incidents_info: IncidentsInfo + + +class BuildsIssuesItem(BaseModel): + id: str + comment: Optional[str] + report_url: Optional[str] + incidents_info: IncidentsInfo + + +class BuildArchitectures(BuildStatusCount): + compilers: List[str] + + +class Misc(BaseModel): + platform: str + + +class TestHistoryItem(BaseModel): + id: str + status: Optional[str] + duration: Optional[Union[int, float]] + path: Optional[str] + start_time: Optional[Union[datetime, str]] + environment_compatible: Optional[Union[str, List[str]]] = None + # TODO: When these fields are added to hardwareDetails, there shouldn't be any need for `= None` anymore + config: Optional[str] = None + log_url: Optional[str] = None + architecture: Optional[str] = None + compiler: Optional[str] = None + misc: Optional[Misc] = None + + +class BuildHistoryItem(BaseModel): + id: str + architecture: Optional[str] + config_name: Optional[str] + misc: Optional[dict] + config_url: Optional[str] + compiler: Optional[str] + valid: Optional[bool] + duration: Optional[Union[int, float]] + log_url: Optional[str] + start_time: Optional[Union[datetime, str]] + git_repository_url: Optional[str] + git_repository_branch: Optional[str] + + +class TestSummary(BaseModel): + status: TestStatusCount + architectures: List[TestArchSummaryItem] + configs: Dict[str, TestStatusCount] + issues: List[TestIssuesItem] + unknown_issues: int + fail_reasons: Dict[str, int] + failed_platforms: List[str] + environment_compatible: Optional[Dict] = None + environment_misc: Optional[Dict] = None + platforms: Optional[Dict[str, TestStatusCount]] + + +class BuildSummary(BaseModel): + status: BuildStatusCount + architectures: Dict[str, BuildArchitectures] + configs: Dict[str, BuildConfigs] + issues: List[BuildsIssuesItem] + unknown_issues: int + + +class Summary(BaseModel): + builds: BuildSummary + boots: TestSummary + tests: TestSummary diff --git a/backend/kernelCI_app/typeModels/hardwareDetails.py b/backend/kernelCI_app/typeModels/hardwareDetails.py index 1bf61b13..92b6efb3 100644 --- a/backend/kernelCI_app/typeModels/hardwareDetails.py +++ b/backend/kernelCI_app/typeModels/hardwareDetails.py @@ -1,6 +1,7 @@ from datetime import datetime from typing import Annotated, Any, Dict, List, Literal, Optional, Union +from kernelCI_app.typeModels.commonDetails import BuildHistoryItem, Summary, TestHistoryItem from kernelCI_app.typeModels.databases import StatusValues from pydantic import BaseModel, BeforeValidator, Field @@ -47,17 +48,32 @@ class CommitHistoryValidCheckout(BaseModel): start_time: datetime -class HardwareDetailsFullResponse(BaseModel): - builds: Dict - tests: Dict - boots: Dict +class Tree(BaseModel): + index: str + tree_name: Optional[str] + git_repository_branch: Optional[str] + git_repository_url: Optional[str] + head_git_commit_name: Optional[str] + head_git_commit_hash: Optional[str] + head_git_commit_tag: Optional[List[str]] + selected_commit_status: Optional[Dict] + + +class HardwareSummary(Summary): + trees: List[Tree] configs: List[str] - archs: List[str] + architectures: List[str] compilers: List[str] - trees: List[Dict] compatibles: List[str] +class HardwareDetailsFullResponse(BaseModel): + builds: List[BuildHistoryItem] + boots: List[TestHistoryItem] + tests: List[TestHistoryItem] + summary: HardwareSummary + + type HardwareTreeList = List[Dict[str, str]] PossibleTestType = Literal["test", "boot"] diff --git a/backend/kernelCI_app/typeModels/treeDetails.py b/backend/kernelCI_app/typeModels/treeDetails.py index d392b6f7..ae9d03c1 100644 --- a/backend/kernelCI_app/typeModels/treeDetails.py +++ b/backend/kernelCI_app/typeModels/treeDetails.py @@ -1,6 +1,14 @@ -from datetime import datetime +from typing import Dict, List, Optional, Set + +from kernelCI_app.typeModels.commonDetails import ( + Summary, + BuildHistoryItem, + TestArchSummaryItem, + TestIssuesItem, + TestStatusCount, + TestHistoryItem, +) from pydantic import BaseModel -from typing import List, Dict, Optional, Set, Union class TreeLatestPathParameters(BaseModel): @@ -8,138 +16,38 @@ class TreeLatestPathParameters(BaseModel): branch: str -class TestStatusCount(BaseModel): - PASS: Optional[int] = None - ERROR: Optional[int] = None - FAIL: Optional[int] = None - SKIP: Optional[int] = None - NULL: Optional[int] = None - - -class TestArchSummaryItem(BaseModel): - arch: str - compiler: str - status: TestStatusCount - - -class BuildStatusCount(BaseModel): - valid: int - invalid: int - null: int - - -class BuildConfigs(BuildStatusCount): - valid: int - invalid: int - null: int - - -class BuildArchitectures(BuildStatusCount): - compilers: List[str] - - -class IncidentsInfo(BaseModel): - incidentsCount: int - - -class TestIssuesItem(BaseModel): - id: str - comment: Optional[str] - report_url: Optional[str] - incidents_info: IncidentsInfo - - -class TestEnvironmentCompatibleCount(TestStatusCount): - pass - - -class TestEnvironmentMiscCount(TestStatusCount): - pass - - -class BuildsIssuesItem(BaseModel): - id: str - comment: Optional[str] - report_url: Optional[str] - incidents_info: IncidentsInfo - - class TestSummary(BaseModel): status: TestStatusCount architectures: List[TestArchSummaryItem] configs: Dict[str, TestStatusCount] issues: List[TestIssuesItem] unknown_issues: int - enviroment_compatible: Dict[str, TestEnvironmentCompatibleCount] - enviroment_misc: Dict[str, TestEnvironmentMiscCount] + enviroment_compatible: Dict[str, TestStatusCount] + enviroment_misc: Dict[str, TestStatusCount] fail_reasons: Dict[str, int] failed_platforms: List[str] -class BuildSummary(BaseModel): - status: BuildStatusCount - architectures: Dict[str, BuildArchitectures] - configs: Dict[str, BuildConfigs] - issues: List[BuildsIssuesItem] - unknown_issues: int - - -class Summary(BaseModel): - builds: BuildSummary - boots: TestSummary - tests: TestSummary +class TreeSummary(Summary): hardware: Set[str] tree_url: str git_commit_tags: Optional[List[str]] class SummaryResponse(BaseModel): - summary: Summary - - -class Misc(BaseModel): - platform: str - - -class TestHistory(BaseModel): - id: str - status: Optional[str] - duration: Optional[Union[int, float]] - path: Optional[str] - start_time: Optional[Union[datetime, str]] - hardware: Optional[Union[str, List[str]]] - config: Optional[str] - log_url: Optional[str] - architecture: Optional[str] - compiler: Optional[str] - misc: Optional[Misc] + summary: TreeSummary class BootResponse(BaseModel): - bootHistory: List[TestHistory] + bootHistory: List[TestHistoryItem] class TestResponse(BaseModel): - testHistory: List[TestHistory] - - -class BuildItem(BaseModel): - id: str - architecture: Optional[str] - config_name: Optional[str] - misc: Optional[dict] - config_url: Optional[str] - compiler: Optional[str] - valid: Optional[bool] - duration: Optional[Union[int, float]] - log_url: Optional[str] - start_time: Optional[Union[datetime, str]] - git_repository_url: Optional[str] - git_repository_branch: Optional[str] + testHistory: List[TestHistoryItem] class BuildsResponse(BaseModel): - builds: List[BuildItem] + builds: List[BuildHistoryItem] class TreeQueryParameters(BaseModel): diff --git a/backend/kernelCI_app/views/buildTestsView.py b/backend/kernelCI_app/views/buildTestsView.py index 1d792c2e..3fe152b0 100644 --- a/backend/kernelCI_app/views/buildTestsView.py +++ b/backend/kernelCI_app/views/buildTestsView.py @@ -17,16 +17,4 @@ def get(self, request, build_id): status_code=HTTPStatus.NOT_FOUND, ) - json_result = [ - { - "id": test["id"], - "duration": test["duration"], - "status": test["status"], - "path": test["path"], - "start_time": test["start_time"], - "hardware": test["environment_compatible"], - } - for test in result - ] - - return JsonResponse(json_result, safe=False) + return JsonResponse(list(result), safe=False) diff --git a/backend/kernelCI_app/views/hardwareDetailsView.py b/backend/kernelCI_app/views/hardwareDetailsView.py index 4bd7d1e5..7f51b15c 100644 --- a/backend/kernelCI_app/views/hardwareDetailsView.py +++ b/backend/kernelCI_app/views/hardwareDetailsView.py @@ -213,17 +213,48 @@ def post(self, request, hardware_id): trees=trees, tree_status_summary=self.tree_status_summary ) + response = { + "builds": self.builds["items"], + "boots": self.boots["history"], + "tests": self.tests["history"], + "summary": { + "builds": { + "status": self.builds["summary"]["builds"], + "architectures": self.builds["summary"]["architectures"], + "configs": self.builds["summary"]["configs"], + "issues": self.builds["issues"], + "unknown_issues": self.builds["failedWithUnknownIssues"], + }, + "boots": { + "status": self.boots["statusSummary"], + "architectures": self.boots["archSummary"], + "configs": self.boots["configs"], + "issues": self.boots["issues"], + "unknown_issues": self.boots["failedWithUnknownIssues"], + "platforms": self.boots["platforms"], + "fail_reasons": self.boots["failReasons"], + "failed_platforms": list(self.boots["platformsFailing"]), + }, + "tests": { + "status": self.tests["statusSummary"], + "architectures": self.tests["archSummary"], + "configs": self.tests["configs"], + "issues": self.tests["issues"], + "unknown_issues": self.tests["failedWithUnknownIssues"], + "platforms": self.tests["platforms"], + "fail_reasons": self.tests["failReasons"], + "failed_platforms": list(self.tests["platformsFailing"]), + + }, + "trees": trees_with_status_summary, + "configs": configs, + "architectures": archs, + "compilers": compilers, + "compatibles": self.compatibles, + } + } try: - valid_response = HardwareDetailsFullResponse( - builds=self.builds, - tests=self.tests, - boots=self.boots, - configs=configs, - archs=archs, - compilers=compilers, - trees=trees_with_status_summary, - compatibles=self.compatibles, - ) + valid_response = HardwareDetailsFullResponse(**response) except ValidationError as e: return Response(data=e.errors(), status=HTTPStatus.BAD_REQUEST) diff --git a/backend/kernelCI_app/views/issueDetailsTestsView.py b/backend/kernelCI_app/views/issueDetailsTestsView.py index 3562b077..9659e0a5 100644 --- a/backend/kernelCI_app/views/issueDetailsTestsView.py +++ b/backend/kernelCI_app/views/issueDetailsTestsView.py @@ -30,7 +30,7 @@ def _fetch_incidents(self, *, issue_id: str, version: int) -> Optional[Dict]: "status": test["test__status"], "path": test["test__path"], "start_time": test["test__start_time"], - "hardware": test["test__environment_compatible"], + "environment_compatible": test["test__environment_compatible"], } for test in tests ] diff --git a/backend/kernelCI_app/views/treeDetailsBootsView.py b/backend/kernelCI_app/views/treeDetailsBootsView.py index 876af621..e657ca4e 100644 --- a/backend/kernelCI_app/views/treeDetailsBootsView.py +++ b/backend/kernelCI_app/views/treeDetailsBootsView.py @@ -18,9 +18,11 @@ ) from kernelCI_app.typeModels.treeDetails import ( BootResponse, - TestHistory, TreeQueryParameters, ) +from kernelCI_app.typeModels.commonDetails import ( + TestHistoryItem +) from kernelCI_app.utils import ( Issue, ) @@ -45,7 +47,7 @@ def _process_boots_test(self, row_data): if test_id in self.processedTests: return self.processedTests.add(test_id) - TestHistory(**history_item) + TestHistoryItem(**history_item) self.bootHistory.append(history_item) def _sanitize_rows(self, rows): diff --git a/backend/kernelCI_app/views/treeDetailsBuildsView.py b/backend/kernelCI_app/views/treeDetailsBuildsView.py index 7c9d4c1d..368bfa7d 100644 --- a/backend/kernelCI_app/views/treeDetailsBuildsView.py +++ b/backend/kernelCI_app/views/treeDetailsBuildsView.py @@ -15,7 +15,7 @@ get_tree_details_data, ) from kernelCI_app.typeModels.treeDetails import ( - BuildItem, + BuildHistoryItem, BuildsResponse, TreeQueryParameters, ) @@ -43,7 +43,7 @@ def _process_builds(self, row_data): build_item = get_build(row_data) - BuildItem(**build_item) + BuildHistoryItem(**build_item) self.builds.append(build_item) diff --git a/backend/kernelCI_app/views/treeDetailsTestsView.py b/backend/kernelCI_app/views/treeDetailsTestsView.py index 482768bb..6fb54854 100644 --- a/backend/kernelCI_app/views/treeDetailsTestsView.py +++ b/backend/kernelCI_app/views/treeDetailsTestsView.py @@ -16,10 +16,12 @@ is_test_boots_test, ) from kernelCI_app.typeModels.treeDetails import ( - TestHistory, TestResponse, TreeQueryParameters, ) +from kernelCI_app.typeModels.commonDetails import ( + TestHistoryItem +) from kernelCI_app.utils import ( Issue, ) @@ -47,7 +49,7 @@ def _process_non_boots_test(self, row_data): self.processedTests.add(test_id) - TestHistory(**history_item) + TestHistoryItem(**history_item) self.testHistory.append(history_item) diff --git a/backend/schema.yml b/backend/schema.yml index ff4cf1bc..78f7052f 100644 --- a/backend/schema.yml +++ b/backend/schema.yml @@ -575,6 +575,53 @@ components: - builds title: BuildsResponse type: object + HardwareDetailsFullResponse: + properties: + builds: + title: Builds + type: object + tests: + title: Tests + type: object + boots: + title: Boots + type: object + configs: + items: + type: string + title: Configs + type: array + archs: + items: + type: string + title: Archs + type: array + compilers: + items: + type: string + title: Compilers + type: array + trees: + items: + type: object + title: Trees + type: array + compatibles: + items: + type: string + title: Compatibles + type: array + required: + - builds + - tests + - boots + - configs + - archs + - compilers + - trees + - compatibles + title: HardwareDetailsFullResponse + type: object IncidentsInfo: properties: incidentsCount: @@ -625,54 +672,6 @@ components: - summary title: SummaryResponse type: object - HardwareDetailsFullResponse: - properties: - builds: - title: Builds - type: object - tests: - title: Tests - type: object - boots: - title: Boots - type: object - configs: - items: - type: string - title: Configs - type: array - archs: - items: - type: string - title: Archs - type: array - compilers: - items: - type: string - title: Compilers - type: array - trees: - items: - type: object - title: Trees - type: array - compatibles: - items: - type: string - title: Compatibles - type: array - required: - - builds - - tests - - boots - - configs - - archs - - compilers - - trees - - compatibles - title: HardwareDetailsFullResponse - type: object - IncidentsInfo: TestArchSummaryItem: properties: arch: @@ -778,13 +777,13 @@ components: - type: string - type: 'null' title: Path - startTime: + start_time: anyOf: - format: date-time type: string - type: string - type: 'null' - title: Starttime + title: Start Time hardware: anyOf: - type: string @@ -798,7 +797,7 @@ components: - status - duration - path - - startTime + - start_time - hardware title: TestHistory type: object diff --git a/dashboard/src/components/TestsTable/TestsTable.tsx b/dashboard/src/components/TestsTable/TestsTable.tsx index 983fba5e..0a59e3ba 100644 --- a/dashboard/src/components/TestsTable/TestsTable.tsx +++ b/dashboard/src/components/TestsTable/TestsTable.tsx @@ -102,7 +102,7 @@ export function TestsTable({ path: e.path, start_time: e.start_time, status: e.status, - hardware: e.hardware, + hardware: e.environment_compatible, }); switch (e.status) { case 'DONE': diff --git a/dashboard/src/pages/hardwareDetails/HardwareDetails.tsx b/dashboard/src/pages/hardwareDetails/HardwareDetails.tsx index a0f1448e..ea1b25b3 100644 --- a/dashboard/src/pages/hardwareDetails/HardwareDetails.tsx +++ b/dashboard/src/pages/hardwareDetails/HardwareDetails.tsx @@ -64,19 +64,19 @@ const prepareTreeItems = ({ }): PreparedTrees[] | void => treeItems?.map(tree => { const treeIdentifier = makeTreeIdentifierKey({ - treeName: tree.treeName ?? '', - gitRepositoryBranch: tree.gitRepositoryBranch ?? '', - gitRepositoryUrl: tree.gitRepositoryUrl ?? '', + treeName: tree.tree_name ?? '', + gitRepositoryBranch: tree.git_repository_branch ?? '', + gitRepositoryUrl: tree.git_repository_url ?? '', }); - const result = { - treeName: tree['treeName'] ?? '-', - gitRepositoryBranch: tree['gitRepositoryBranch'] ?? '-', - headGitCommitName: tree['headGitCommitName'] ?? '-', - headGitCommitHash: tree['headGitCommitHash'] ?? '-', - gitRepositoryUrl: tree['gitRepositoryUrl'] ?? '-', + const result: PreparedTrees = { + tree_name: tree['tree_name'] ?? '-', + git_repository_branch: tree['git_repository_branch'] ?? '-', + head_git_commit_name: tree['head_git_commit_name'] ?? '-', + head_git_commit_hash: tree['head_git_commit_hash'] ?? '-', + git_repository_url: tree['git_repository_url'] ?? '-', index: tree['index'], - selectedCommitStatusSummary: tree['selectedCommitStatusSummary'], + selected_commit_status: tree['selected_commit_status'], selectableCommits: commitHistoryData?.[treeIdentifier] ?? [], isCommitHistoryDataLoading, isMainPageLoading: isMainPageLoading, @@ -152,12 +152,12 @@ function HardwareDetails(): JSX.Element { const hardwareTableForCommitHistory = useMemo(() => { const result: CommitHead[] = []; if (!isLoading && data) { - data?.trees.forEach(tree => { + data?.summary.trees.forEach(tree => { const commitHead: CommitHead = { - treeName: tree.treeName ?? '', - repositoryUrl: tree.gitRepositoryUrl ?? '', - branch: tree.gitRepositoryBranch ?? '', - commitHash: tree.headGitCommitHash ?? '', + treeName: tree.tree_name ?? '', + repositoryUrl: tree.git_repository_url ?? '', + branch: tree.git_repository_branch ?? '', + commitHash: tree.head_git_commit_hash ?? '', }; result.push(commitHead); @@ -196,10 +196,9 @@ function HardwareDetails(): JSX.Element { const endDate = getFormattedDate(endTimestampInSeconds); const tabsCounts: TreeDetailsTabRightElement = useMemo(() => { - const { valid, invalid } = data?.builds.summary.builds ?? {}; - const { statusSummary: testStatusSummary } = data?.tests ?? {}; - - const { statusSummary: bootStatusSummary } = data?.boots ?? {}; + const { status: buildStatusSummary } = data?.summary.builds ?? {}; + const { status: testStatusSummary } = data?.summary.tests ?? {}; + const { status: bootStatusSummary } = data?.summary.boots ?? {}; return { 'global.tests': testStatusSummary ? ( @@ -220,29 +219,29 @@ function HardwareDetails(): JSX.Element { ) : ( <> ), - 'global.builds': data?.builds ? ( + 'global.builds': buildStatusSummary ? ( ) : ( <> ), }; - }, [data?.boots, data?.builds, data?.tests]); + }, [data?.summary.boots, data?.summary.builds, data?.summary.tests]); const treeData = useMemo( () => prepareTreeItems({ isCommitHistoryDataLoading: commitHistoryIsLoading, - treeItems: data?.trees, + treeItems: data?.summary.trees, commitHistoryData: commitHistoryData?.commit_history_table, isMainPageLoading: isPlaceholderData || isLoading, }), [ commitHistoryIsLoading, - data?.trees, + data?.summary.trees, commitHistoryData?.commit_history_table, isPlaceholderData, isLoading, @@ -315,7 +314,7 @@ function HardwareDetails(): JSX.Element { title={ } - compatibles={data.compatibles} + compatibles={data.summary.compatibles} /> )} diff --git a/dashboard/src/pages/hardwareDetails/HardwareDetailsFilter.tsx b/dashboard/src/pages/hardwareDetails/HardwareDetailsFilter.tsx index 20415369..75e5008a 100644 --- a/dashboard/src/pages/hardwareDetails/HardwareDetailsFilter.tsx +++ b/dashboard/src/pages/hardwareDetails/HardwareDetailsFilter.tsx @@ -57,10 +57,10 @@ export const createFilter = ( const treeIndexes: number[] = []; if (data) { - data.trees.forEach(tree => { + data.summary.trees.forEach(tree => { const treeIdx = Number(tree.index); - const treeName = tree.treeName ?? 'Unknown'; - const treeBranch = tree.gitRepositoryBranch ?? 'Unknown'; + const treeName = tree.tree_name ?? 'Unknown'; + const treeBranch = tree.git_repository_branch ?? 'Unknown'; let treeNameBranch = `${treeName}/${treeBranch}`; @@ -71,20 +71,24 @@ export const createFilter = ( treeIndexes.push(treeIdx); }); - data.archs.forEach(arch => { + data.summary.architectures.forEach(arch => { archs[arch ?? 'Unknown'] = false; }); - data.compilers.forEach(compiler => { + data.summary.compilers.forEach(compiler => { compilers[compiler ?? 'Unknown'] = false; }); - data.configs.forEach(config => { + data.summary.configs.forEach(config => { configs[config ?? 'Unknown'] = false; }); - data.builds.issues.forEach(i => (buildIssue[i.id] = false)); - data.boots.issues.forEach(i => (bootIssue[i.id] = false)); - data.tests.issues.forEach(i => (testIssue[i.id] = false)); - Object.keys(data.boots.platforms).forEach(i => (bootPlatform[i] = false)); - Object.keys(data.tests.platforms).forEach(i => (testPlatform[i] = false)); + data.summary.builds.issues.forEach(i => (buildIssue[i.id] = false)); + data.summary.boots.issues.forEach(i => (bootIssue[i.id] = false)); + data.summary.tests.issues.forEach(i => (testIssue[i.id] = false)); + Object.keys(data.summary.boots.platforms ?? {}).forEach( + i => (bootPlatform[i] = false), + ); + Object.keys(data.summary.tests.platforms ?? {}).forEach( + i => (testPlatform[i] = false), + ); } return { diff --git a/dashboard/src/pages/hardwareDetails/HardwareDetailsHeaderTable.tsx b/dashboard/src/pages/hardwareDetails/HardwareDetailsHeaderTable.tsx index 66c36e19..90f9ec70 100644 --- a/dashboard/src/pages/hardwareDetails/HardwareDetailsHeaderTable.tsx +++ b/dashboard/src/pages/hardwareDetails/HardwareDetailsHeaderTable.tsx @@ -210,40 +210,42 @@ const columns: ColumnDef[] = [ ), }, { - accessorKey: 'treeName', + accessorKey: 'tree_name', header: ({ column }): JSX.Element => ( ), cell: ({ row }): JSX.Element => ( - {row.getValue('treeName')} - {row.original.gitRepositoryUrl} + {row.getValue('tree_name')} + {row.original.git_repository_url} ), }, { - accessorKey: 'gitRepositoryBranch', + accessorKey: 'git_repository_branch', header: ({ column }): JSX.Element => ( ), }, { - accessorKey: 'headGitCommitName', + accessorKey: 'head_git_commit_name', header: ({ column }): JSX.Element => ( ), - cell: ({ row, table }): JSX.Element => ( - - ), + cell: ({ row, table }): JSX.Element => { + return ( + + ); + }, }, { accessorKey: 'selectedCommitStatusSummaryBuilds', @@ -251,7 +253,7 @@ const columns: ColumnDef[] = [ ), cell: ({ row }): JSX.Element => { - const statusSummary = row.original.selectedCommitStatusSummary?.builds; + const statusSummary = row.original.selected_commit_status?.builds; return ( [] = [ ), cell: ({ row }): JSX.Element => { - const statusSummary = row.original.selectedCommitStatusSummary?.boots; + const statusSummary = row.original.selected_commit_status?.boots; return ( [] = [ ), cell: ({ row }): JSX.Element => { - const statusSummary = row.original.selectedCommitStatusSummary?.tests; + const statusSummary = row.original.selected_commit_status?.tests; return ( { +const BootsTab = ({ + bootsSummary, + boots, + hardwareId, + trees, +}: IBootsTab): JSX.Element => { const { tableFilter, diffFilter } = useSearch({ from: '/hardware/$hardwareId', }); @@ -94,8 +100,8 @@ const BootsTab = ({ boots, hardwareId, trees }: TBootsTab): JSX.Element => { ); const platformItems = useMemo( - () => sanitizePlatforms(boots.platforms), - [boots.platforms], + () => sanitizePlatforms(bootsSummary.platforms), + [bootsSummary.platforms], ); return ( @@ -104,17 +110,17 @@ const BootsTab = ({ boots, hardwareId, trees }: TBootsTab): JSX.Element => {
} - statusCounts={boots.statusSummary} + statusCounts={bootsSummary.status} /> } - archCompilerErrors={boots.archSummary} + archCompilerErrors={bootsSummary.architectures} diffFilter={diffFilter} /> } - issues={boots.issues} - failedWithUnknownIssues={boots.failedWithUnknownIssues} + issues={bootsSummary.issues} + failedWithUnknownIssues={bootsSummary.unknown_issues} diffFilter={diffFilter} issueFilterSection="bootIssue" detailsId={hardwareId} @@ -128,7 +134,7 @@ const BootsTab = ({ boots, hardwareId, trees }: TBootsTab): JSX.Element => { /> } - configStatusCounts={boots.configs} + configStatusCounts={bootsSummary.configs} diffFilter={diffFilter} /> { } - statusCounts={boots.statusSummary} + statusCounts={bootsSummary.status} />
} - configStatusCounts={boots.configs} + configStatusCounts={bootsSummary.configs} diffFilter={diffFilter} /> { /> } - archCompilerErrors={boots.archSummary} + archCompilerErrors={bootsSummary.architectures} diffFilter={diffFilter} /> } - issues={boots.issues} - failedWithUnknownIssues={boots.failedWithUnknownIssues} + issues={bootsSummary.issues} + failedWithUnknownIssues={bootsSummary.unknown_issues} diffFilter={diffFilter} issueFilterSection="bootIssue" detailsId={hardwareId} @@ -177,7 +183,7 @@ const BootsTab = ({ boots, hardwareId, trees }: TBootsTab): JSX.Element => { tableKey="hardwareDetailsBoots" getRowLink={getRowLink} filter={tableFilter.bootsTable} - testHistory={boots.history} + testHistory={boots} onClickFilter={onClickFilter} updatePathFilter={updatePathFilter} currentPathFilter={currentPathFilter} diff --git a/dashboard/src/pages/hardwareDetails/Tabs/Build/BuildTab.tsx b/dashboard/src/pages/hardwareDetails/Tabs/Build/BuildTab.tsx index fe1b7a76..5dbe6e1b 100644 --- a/dashboard/src/pages/hardwareDetails/Tabs/Build/BuildTab.tsx +++ b/dashboard/src/pages/hardwareDetails/Tabs/Build/BuildTab.tsx @@ -25,13 +25,19 @@ import { RedirectFrom, type TFilterObjectsKeys } from '@/types/general'; import { HardwareDetailsBuildsTable } from './HardwareDetailsBuildsTable'; -interface TBuildTab { +interface IBuildTab { builds: THardwareDetails['builds']; - trees: THardwareDetails['trees']; + buildsSummary: THardwareDetails['summary']['builds']; + trees: THardwareDetails['summary']['trees']; hardwareId: string; } -const BuildTab = ({ builds, hardwareId, trees }: TBuildTab): JSX.Element => { +const BuildTab = ({ + buildsSummary, + builds, + hardwareId, + trees, +}: IBuildTab): JSX.Element => { const navigate = useNavigate({ from: '/hardware/$hardwareId', }); @@ -66,19 +72,16 @@ const BuildTab = ({ builds, hardwareId, trees }: TBuildTab): JSX.Element => { ); const archSummary = useMemo( - () => sanitizeArchs(builds.summary.architectures), - [builds.summary.architectures], + () => sanitizeArchs(buildsSummary.architectures), + [buildsSummary.architectures], ); const configsItems = useMemo( - () => sanitizeConfigs(builds.summary.configs), - [builds.summary.configs], + () => sanitizeConfigs(buildsSummary.configs), + [buildsSummary.configs], ); - const buildItems = useMemo( - () => sanitizeBuilds(builds.items), - [builds.items], - ); + const buildItems = useMemo(() => sanitizeBuilds(builds), [builds]); return (
@@ -86,7 +89,7 @@ const BuildTab = ({ builds, hardwareId, trees }: TBuildTab): JSX.Element => {
{ /> } - issues={builds.issues} - failedWithUnknownIssues={builds.failedWithUnknownIssues} + issues={buildsSummary.issues} + failedWithUnknownIssues={buildsSummary.unknown_issues} diffFilter={diffFilter} issueFilterSection="buildIssue" detailsId={hardwareId} @@ -119,7 +122,7 @@ const BuildTab = ({ builds, hardwareId, trees }: TBuildTab): JSX.Element => { { } - issues={builds.issues} - failedWithUnknownIssues={builds.failedWithUnknownIssues} + issues={buildsSummary.issues} + failedWithUnknownIssues={buildsSummary.unknown_issues} diffFilter={diffFilter} issueFilterSection="buildIssue" detailsId={hardwareId} diff --git a/dashboard/src/pages/hardwareDetails/Tabs/HardwareCommitNavigationGraph.tsx b/dashboard/src/pages/hardwareDetails/Tabs/HardwareCommitNavigationGraph.tsx index a99489da..c983f2bb 100644 --- a/dashboard/src/pages/hardwareDetails/Tabs/HardwareCommitNavigationGraph.tsx +++ b/dashboard/src/pages/hardwareDetails/Tabs/HardwareCommitNavigationGraph.tsx @@ -6,7 +6,7 @@ import type { THardwareDetails } from '@/types/hardware/hardwareDetails'; import CommitNavigationGraph from '@/components/CommitNavigationGraph/CommitNavigationGraph'; interface ICommitNavigationGraph { - trees: THardwareDetails['trees']; + trees: THardwareDetails['summary']['trees']; hardwareId: string; } const HardwareCommitNavigationGraph = ({ @@ -52,15 +52,15 @@ const HardwareCommitNavigationGraph = ({ if (!tree) return <>; - const treeId = treeCommits?.[treeIdx] ?? tree['headGitCommitHash']; + const treeId = treeCommits?.[treeIdx] ?? tree['head_git_commit_hash']; return ( ), @@ -71,9 +72,10 @@ const HardwareDetailsTabs = ({ name: 'global.boots', content: ( ), rightElement: countElements['global.boots'], @@ -83,9 +85,10 @@ const HardwareDetailsTabs = ({ name: 'global.tests', content: ( ), rightElement: countElements['global.tests'], @@ -93,8 +96,11 @@ const HardwareDetailsTabs = ({ }, ], [ + hardwareDetailsData.summary.builds, + hardwareDetailsData.summary.trees, + hardwareDetailsData.summary.boots, + hardwareDetailsData.summary.tests, hardwareDetailsData.builds, - hardwareDetailsData.trees, hardwareDetailsData.boots, hardwareDetailsData.tests, hardwareId, diff --git a/dashboard/src/pages/hardwareDetails/Tabs/Tests/TestsTab.tsx b/dashboard/src/pages/hardwareDetails/Tabs/Tests/TestsTab.tsx index 2095d8b7..049e5192 100644 --- a/dashboard/src/pages/hardwareDetails/Tabs/Tests/TestsTab.tsx +++ b/dashboard/src/pages/hardwareDetails/Tabs/Tests/TestsTab.tsx @@ -31,13 +31,19 @@ import { RedirectFrom } from '@/types/general'; import HardwareDetailsTestTable from './HardwareDetailsTestsTable'; -interface TTestsTab { +interface ITestsTab { tests: THardwareDetails['tests']; - trees: THardwareDetails['trees']; + testsSummary: THardwareDetails['summary']['tests']; + trees: THardwareDetails['summary']['trees']; hardwareId: string; } -const TestsTab = ({ tests, trees, hardwareId }: TTestsTab): JSX.Element => { +const TestsTab = ({ + testsSummary, + tests, + trees, + hardwareId, +}: ITestsTab): JSX.Element => { const { tableFilter, diffFilter } = useSearch({ from: '/hardware/$hardwareId', }); @@ -80,8 +86,8 @@ const TestsTab = ({ tests, trees, hardwareId }: TTestsTab): JSX.Element => { ); const platformItems = useMemo( - () => sanitizePlatforms(tests.platforms), - [tests.platforms], + () => sanitizePlatforms(testsSummary.platforms), + [testsSummary.platforms], ); return ( @@ -90,17 +96,17 @@ const TestsTab = ({ tests, trees, hardwareId }: TTestsTab): JSX.Element => {
} - statusCounts={tests.statusSummary} + statusCounts={testsSummary.status} /> } - archCompilerErrors={tests.archSummary} + archCompilerErrors={testsSummary.architectures} diffFilter={diffFilter} /> } - issues={tests.issues} - failedWithUnknownIssues={tests.failedWithUnknownIssues} + issues={testsSummary.issues} + failedWithUnknownIssues={testsSummary.unknown_issues} diffFilter={diffFilter} issueFilterSection="testIssue" detailsId={hardwareId} @@ -114,7 +120,7 @@ const TestsTab = ({ tests, trees, hardwareId }: TTestsTab): JSX.Element => { /> } - configStatusCounts={tests.configs} + configStatusCounts={testsSummary.configs} diffFilter={diffFilter} /> { } - statusCounts={tests.statusSummary} + statusCounts={testsSummary.status} />
} - configStatusCounts={tests.configs} + configStatusCounts={testsSummary.configs} diffFilter={diffFilter} /> { /> } - archCompilerErrors={tests.archSummary} + archCompilerErrors={testsSummary.architectures} diffFilter={diffFilter} /> } - issues={tests.issues} - failedWithUnknownIssues={tests.failedWithUnknownIssues} + issues={testsSummary.issues} + failedWithUnknownIssues={testsSummary.unknown_issues} diffFilter={diffFilter} issueFilterSection="testIssue" detailsId={hardwareId} @@ -161,7 +167,7 @@ const TestsTab = ({ tests, trees, hardwareId }: TTestsTab): JSX.Element => { ; - architectures: Record< - string, - { - valid: number; - invalid: number; - null: number; - compilers: string[]; - } - >; -}; - -type BuildsData = { - items: BuildsTabBuild[]; - issues: TIssue[]; - summary: BuildSummary; - platforms: Record; - failedWithUnknownIssues: number; -}; - -type Tests = { - archSummary: ArchCompilerStatus[]; - history: TestHistory[]; - platforms: Record; - platformsFailing: string[]; - statusSummary: StatusCounts; - failReasons: Record; - configs: Record; - issues: TIssue[]; - failedWithUnknownIssues: number; -}; +import type { BuildSummary, TestSummary } from '@/types/tree/TreeDetails'; type TTreesStatusSummary = { builds: Partial; @@ -51,13 +15,13 @@ type TTreesStatusSummary = { }; export type Trees = { - treeName?: string; - gitRepositoryBranch?: string; - gitRepositoryUrl?: string; - headGitCommitName?: string; - headGitCommitHash?: string; - headGitCommitTags?: string[]; - selectedCommitStatusSummary?: TTreesStatusSummary; + tree_name?: string; + git_repository_branch?: string; + git_repository_url?: string; + head_git_commit_name?: string; + head_git_commit_hash?: string; + head_git_commit_tags?: string[]; + selected_commit_status?: TTreesStatusSummary; index: string; }; @@ -67,17 +31,24 @@ export type PreparedTrees = Trees & { isMainPageLoading: boolean; }; -export type THardwareDetails = { - builds: BuildsData; - tests: Tests; - boots: Tests; +type HardwareSummary = { + builds: BuildSummary; + boots: TestSummary; + tests: TestSummary; trees: Trees[]; configs: string[]; - archs: string[]; + architectures: string[]; compilers: string[]; compatibles: string[]; }; +export type THardwareDetails = { + builds: BuildsTabBuild[]; + tests: TestHistory[]; + boots: TestHistory[]; + summary: HardwareSummary; +}; + export interface THardwareDetailsFilter extends Partial<{ [K in keyof Omit< diff --git a/dashboard/src/types/tree/TreeDetails.tsx b/dashboard/src/types/tree/TreeDetails.tsx index b6c5167b..1758dd37 100644 --- a/dashboard/src/types/tree/TreeDetails.tsx +++ b/dashboard/src/types/tree/TreeDetails.tsx @@ -63,19 +63,20 @@ export type TTreeTestsData = { environmentCompatible: PropertyStatusCounts; }; -type TestSummary = { +export type TestSummary = { status: StatusCounts; architectures: ArchCompilerStatus[]; configs: PropertyStatusCounts; issues: TIssue[]; unknown_issues: number; - enviroment_compatible: PropertyStatusCounts; - enviroment_misc: PropertyStatusCounts; fail_reasons: Record; failed_platforms: string[]; + enviroment_compatible?: PropertyStatusCounts; + enviroment_misc?: PropertyStatusCounts; + platforms?: PropertyStatusCounts; }; -type BuildSummary = { +export type BuildSummary = { status: BuildStatus; architectures: Architecture; configs: Record; @@ -83,7 +84,7 @@ type BuildSummary = { unknown_issues: number; }; -type Summary = { +type TreeSummary = { boots: TestSummary; builds: BuildSummary; tests: TestSummary; @@ -96,7 +97,7 @@ export type TTreeTestsFullData = { builds: BuildsTabBuild[]; boots: TestHistory[]; tests: TestHistory[]; - summary: Summary; + summary: TreeSummary; }; export const possibleTabs = [