From df023175f2891e6fddc306153c581943528cc818 Mon Sep 17 00:00:00 2001 From: Murilo Geraldini Date: Tue, 21 Jan 2025 12:57:07 -0300 Subject: [PATCH] feat(tree-details): add filters field - Added `process_filter` function to helpers/treeDetails.py, the function responsible to get the value of all possible filters in the tree details response - Added 'common' and 'filters' fields to tree details summary response - Added 'common' and 'filters' fields to tree details response Part of #792 --- backend/kernelCI_app/helpers/treeDetails.py | 31 ++++++++++++++++ .../kernelCI_app/typeModels/treeDetails.py | 23 ++++++++++-- .../views/treeDetailsSummaryView.py | 35 ++++++++++++++++--- backend/kernelCI_app/views/treeDetailsView.py | 27 ++++++++++++++ .../src/pages/TreeDetails/TreeDetails.tsx | 6 ++-- .../pages/TreeDetails/TreeDetailsFilter.tsx | 2 +- dashboard/src/types/tree/TreeDetails.tsx | 24 +++++++++++++ 7 files changed, 138 insertions(+), 10 deletions(-) diff --git a/backend/kernelCI_app/helpers/treeDetails.py b/backend/kernelCI_app/helpers/treeDetails.py index 41451672..badc62ef 100644 --- a/backend/kernelCI_app/helpers/treeDetails.py +++ b/backend/kernelCI_app/helpers/treeDetails.py @@ -478,3 +478,34 @@ def process_boots_summary(instance, row_data): ] += 1 else: instance.bootEnvironmentMisc[test_platform][test_status] += 1 + + +def process_filters(instance, row_data) -> None: + if row_data["build_id"] is not None: + instance.globalConfigs.add(row_data["build_config_name"]) + instance.globalArchitectures.add(row_data["build_architecture"]) + instance.globalCompilers.add(row_data["build_config_name"]) + + issue_id = row_data["issue_id"] + incident_test_id = row_data["incident_test_id"] + build_valid = row_data["build_valid"] + + issue_id, is_build_issue = should_increment_build_issue( + issue_id=issue_id, + incident_test_id=incident_test_id, + build_valid=build_valid, + ) + + if issue_id is not None and is_build_issue: + instance.unfilteredBuildIssues.add(issue_id) + + issue_id, is_test_issue = should_increment_test_issue( + issue_id=issue_id, + incident_test_id=incident_test_id, + ) + + if issue_id is not None and is_test_issue: + if is_boot(row_data["test_path"]): + instance.unfilteredBootIssues.add(issue_id) + else: + instance.unfilteredTestIssues.add(issue_id) diff --git a/backend/kernelCI_app/typeModels/treeDetails.py b/backend/kernelCI_app/typeModels/treeDetails.py index 8e52987f..82363b82 100644 --- a/backend/kernelCI_app/typeModels/treeDetails.py +++ b/backend/kernelCI_app/typeModels/treeDetails.py @@ -28,14 +28,33 @@ class TestSummary(BaseModel): failed_platforms: List[str] -class TreeSummary(Summary): +class TreeCommon(BaseModel): hardware: Optional[List[str]] tree_url: Optional[str] git_commit_tags: Optional[List[str]] +class TreeGlobalFilters(BaseModel): + configs: List[str] + architectures: List[str] + compilers: List[str] + + +class TreeLocalFilters(BaseModel): + issues: List[str] + + +class TreeFilters(BaseModel): + all: TreeGlobalFilters + builds: TreeLocalFilters + boots: TreeLocalFilters + tests: TreeLocalFilters + + class SummaryResponse(BaseModel): - summary: TreeSummary + common: TreeCommon + summary: Summary + filters: TreeFilters class BootResponse(BaseModel): diff --git a/backend/kernelCI_app/views/treeDetailsSummaryView.py b/backend/kernelCI_app/views/treeDetailsSummaryView.py index 282cdec2..37ca6d47 100644 --- a/backend/kernelCI_app/views/treeDetailsSummaryView.py +++ b/backend/kernelCI_app/views/treeDetailsSummaryView.py @@ -17,6 +17,7 @@ process_builds_issue, process_test_summary, process_tests_issue, + process_filters, ) from kernelCI_app.typeModels.treeDetails import SummaryResponse from kernelCI_app.utils import ( @@ -65,6 +66,13 @@ def __init__(self): self.tree_url = "" self.git_commit_tags = [] + self.globalConfigs = set() + self.globalArchitectures = set() + self.globalCompilers = set() + self.unfilteredTestIssues = set() + self.unfilteredBootIssues = set() + self.unfilteredBuildIssues = set() + def _process_boots_test(self, row_data): test_id = row_data["test_id"] @@ -118,6 +126,7 @@ def _sanitize_rows(self, rows): call_based_on_compatible_and_misc_platform(row_data, self.hardwareUsed.add) process_tree_url(self, row_data) + process_filters(self, row_data) is_record_filter_out = decide_if_is_full_row_filtered_out(self, row_data) @@ -151,6 +160,11 @@ def get(self, request, commit_hash: str | None): self._sanitize_rows(rows) response = { + "common": { + "tree_url": self.tree_url, + "hardware": list(self.hardwareUsed), + "git_commit_tags": self.git_commit_tags, + }, "summary": { "builds": { "status": self.build_summary["builds"], @@ -181,10 +195,23 @@ def get(self, request, commit_hash: str | None): "fail_reasons": self.testFailReasons, "failed_platforms": list(self.testPlatformsWithErrors), }, - "hardware": list(self.hardwareUsed), - "tree_url": self.tree_url, - "git_commit_tags": self.git_commit_tags, - } + }, + "filters": { + "all": { + "configs": list(self.globalConfigs), + "architectures": list(self.globalArchitectures), + "compilers": list(self.globalCompilers), + }, + "builds": { + "issues": list(self.unfilteredBuildIssues), + }, + "boots": { + "issues": list(self.unfilteredBootIssues), + }, + "tests": { + "issues": list(self.unfilteredTestIssues), + }, + }, } try: diff --git a/backend/kernelCI_app/views/treeDetailsView.py b/backend/kernelCI_app/views/treeDetailsView.py index fe6a60f0..4530044e 100644 --- a/backend/kernelCI_app/views/treeDetailsView.py +++ b/backend/kernelCI_app/views/treeDetailsView.py @@ -22,6 +22,7 @@ process_builds_issue, process_test_summary, process_tests_issue, + process_filters, ) from kernelCI_app.utils import ( Issue, @@ -72,6 +73,13 @@ def __init__(self): self.tree_url = "" self.git_commit_tags = [] + self.globalConfigs = set() + self.globalArchitectures = set() + self.globalCompilers = set() + self.unfilteredTestIssues = set() + self.unfilteredBootIssues = set() + self.unfilteredBuildIssues = set() + def _process_boots_test(self, row_data): test_id = row_data["test_id"] history_item = row_data["history_item"] @@ -129,6 +137,7 @@ def _sanitize_rows(self, rows): call_based_on_compatible_and_misc_platform(row_data, self.hardwareUsed.add) process_tree_url(self, row_data) + process_filters(self, row_data) is_record_filter_out = decide_if_is_full_row_filtered_out(self, row_data) @@ -198,10 +207,28 @@ def get(self, request, commit_hash: str | None): "fail_reasons": self.testFailReasons, "failed_platforms": list(self.testPlatformsWithErrors), }, + }, + "common": { "hardware": list(self.hardwareUsed), "tree_url": self.tree_url, "git_commit_tags": self.git_commit_tags, }, + "filters": { + "all": { + "configs": list(self.globalConfigs), + "architectures": list(self.globalArchitectures), + "compilers": list(self.globalCompilers), + }, + "builds": { + "issues": list(self.unfilteredBuildIssues), + }, + "boots": { + "issues": list(self.unfilteredBootIssues), + }, + "tests": { + "issues": list(self.unfilteredTestIssues), + }, + }, }, safe=False, ) diff --git a/dashboard/src/pages/TreeDetails/TreeDetails.tsx b/dashboard/src/pages/TreeDetails/TreeDetails.tsx index 5624f27c..529306f6 100644 --- a/dashboard/src/pages/TreeDetails/TreeDetails.tsx +++ b/dashboard/src/pages/TreeDetails/TreeDetails.tsx @@ -262,13 +262,13 @@ function TreeDetails(): JSX.Element { gitUrl={treeInfo?.gitUrl} commitHash={treeId} commitName={treeInfo?.commitName} - commitTags={data?.summary.git_commit_tags} + commitTags={data?.common.git_commit_tags} />
} - hardwareUsed={data?.summary.hardware} + hardwareUsed={data?.common.hardware} diffFilter={diffFilter} />
@@ -278,7 +278,7 @@ function TreeDetails(): JSX.Element { {data && isAllReady && !isAnyLoading && ( )} {!isAllReady && isAnyLoading && ( diff --git a/dashboard/src/pages/TreeDetails/TreeDetailsFilter.tsx b/dashboard/src/pages/TreeDetails/TreeDetailsFilter.tsx index 8a03f7ef..cbcb6e67 100644 --- a/dashboard/src/pages/TreeDetails/TreeDetailsFilter.tsx +++ b/dashboard/src/pages/TreeDetails/TreeDetailsFilter.tsx @@ -55,7 +55,7 @@ export const createFilter = (data: TTreeTestsFullData | undefined): TFilter => { compilers[b.compiler ?? 'Unknown'] = false; }); - data.summary.hardware.forEach(h => (hardware[h] = false)); + data.common.hardware.forEach(h => (hardware[h] = false)); data.summary.builds.issues.forEach(i => (buildIssue[i.id] = false)); data.summary.boots.issues.forEach(i => (bootIssue[i.id] = false)); diff --git a/dashboard/src/types/tree/TreeDetails.tsx b/dashboard/src/types/tree/TreeDetails.tsx index f2edaa53..d10b250b 100644 --- a/dashboard/src/types/tree/TreeDetails.tsx +++ b/dashboard/src/types/tree/TreeDetails.tsx @@ -88,20 +88,44 @@ type TreeSummary = { boots: TestSummary; builds: BuildSummary; tests: TestSummary; +}; + +type TreeCommon = { hardware: string[]; tree_url: string; git_commit_tags: string[]; }; +type TreeGlobalFilters = { + configs: string[]; + architectures: string[]; + compilers: string[]; +}; + +type TreeLocalFilters = { + issues: string[]; +}; + +type TreeFilters = { + all: TreeGlobalFilters; + builds: TreeLocalFilters; + boots: TreeLocalFilters; + tests: TreeLocalFilters; +}; + export type TTreeTestsFullData = { builds: BuildsTabBuild[]; boots: TestHistory[]; tests: TestHistory[]; summary: TreeSummary; + common: TreeCommon; + filters: TreeFilters; }; export type TreeDetailsSummary = { summary: TreeSummary; + common: TreeCommon; + filters: TreeFilters; }; export type TreeDetailsBuilds = {