From ce29287f7a7dcdfe5d2580d872d2bd52cb9c8467 Mon Sep 17 00:00:00 2001 From: Marcos Date: Thu, 12 Sep 2024 10:41:19 -0300 Subject: [PATCH] feat: use new query on tests and boots tab --- dashboard/src/api/TreeDetails.tsx | 30 +------ dashboard/src/components/Table/BootsTable.tsx | 41 +++++----- dashboard/src/components/Table/TestsTable.tsx | 82 ++++++++++++++----- .../pages/TreeDetails/Tabs/Boots/BootsTab.tsx | 28 +++---- .../src/pages/TreeDetails/Tabs/TestCards.tsx | 22 ++--- .../pages/TreeDetails/Tabs/Tests/TestsTab.tsx | 24 +++--- dashboard/src/types/tree/TreeDetails.tsx | 30 ++++++- 7 files changed, 145 insertions(+), 112 deletions(-) diff --git a/dashboard/src/api/TreeDetails.tsx b/dashboard/src/api/TreeDetails.tsx index f91d10d8..9bf75787 100644 --- a/dashboard/src/api/TreeDetails.tsx +++ b/dashboard/src/api/TreeDetails.tsx @@ -3,12 +3,12 @@ import { useQuery, UseQueryResult } from '@tanstack/react-query'; import { useSearch } from '@tanstack/react-router'; import { - TTreeTestsData, BuildsTab, TTreeDetailsFilter, TTestByCommitHashResponse, TTreeCommitHistoryResponse, BuildCountsResponse, + TTreeTestsFullData, } from '@/types/tree/TreeDetails'; import { TPathTests } from '@/types/general'; @@ -99,49 +99,27 @@ const fetchTreeTestsData = async ( git_url: string; }, filter: TTreeDetailsFilter = {}, -): Promise => { +): Promise => { const urlParams = mapFiltersToUrlSearchParams(filter); if (params !== undefined) { Object.entries(params).forEach(([k, v]) => urlParams.append(k, v.toString()), ); } - const res = await http.get(`/api/tree/${treeId}/tests`, { + const res = await http.get(`/api/tree/${treeId}/full`, { params: urlParams, }); return res.data; }; -export const useBootsTab = ( - treeId: string, - origin: string, - git_branch: string, - git_url: string, - filter: TTreeDetailsFilter, -): UseQueryResult => { - const params = { - path: 'boot.', - origin: origin, - git_branch: git_branch, - git_url: git_url, - }; - - const bootsFilter = getTargetFilter(filter, 'boot'); - - return useQuery({ - queryKey: ['treeBootTests', treeId, bootsFilter, params], - queryFn: () => fetchTreeTestsData(treeId, params, bootsFilter), - }); -}; - export const useTestsTab = ( treeId: string, origin: string, git_branch: string, git_url: string, filter: TTreeDetailsFilter, -): UseQueryResult => { +): UseQueryResult => { const params = { origin: origin, git_branch: git_branch, diff --git a/dashboard/src/components/Table/BootsTable.tsx b/dashboard/src/components/Table/BootsTable.tsx index 45a9c7ad..f96fc9c9 100644 --- a/dashboard/src/components/Table/BootsTable.tsx +++ b/dashboard/src/components/Table/BootsTable.tsx @@ -9,9 +9,10 @@ import { TableInfo } from '@/components/Table/TableInfo'; import { TableCell, TableRow } from '@/components/ui/table'; import { usePagination } from '@/hooks/usePagination'; -import { useTestsByTreeAndCommitHash } from '@/api/TreeDetails'; - import { + TTestByCommitHashResponse, + TestByCommitHash, + TestHistory, TestsTableFilter, possibleTestsTableFilter, } from '@/types/tree/TreeDetails'; @@ -42,27 +43,31 @@ const ITEMS_PER_PAGE = 10; export interface ITestsTable { treeId: string; - isBootTable?: boolean; + testHistory: TestHistory[]; } -const BootsTable = ({ - treeId, - isBootTable = false, -}: ITestsTable): JSX.Element => { +const BootsTable = ({ treeId, testHistory }: ITestsTable): JSX.Element => { const navigate = useNavigate({ from: '/tree/$treeId' }); const intl = useIntl(); - const { origin, treeInfo, diffFilter } = useSearch({ + const { diffFilter } = useSearch({ from: '/tree/$treeId/', }); const { tableFilter } = useSearch({ from: '/tree/$treeId/', }); - const { data, error, isLoading } = useTestsByTreeAndCommitHash( - treeId, - isBootTable, - origin, - treeInfo.gitUrl, - treeInfo.gitBranch, + const data = useMemo( + (): TTestByCommitHashResponse => ({ + tests: testHistory.map( + (e): TestByCommitHash => ({ + duration: e.duration?.toString() ?? '', + id: e.id, + path: e.path, + startTime: e.startTime, + status: e.status, + }), + ), + }), + [testHistory], ); const onClickName = useCallback( @@ -105,7 +110,7 @@ const BootsTable = ({ useState(tableFilter.bootsTable); const rows = useMemo(() => { - if (!data || error) return <>; + if (!data) return <>; if (filteredData?.length === 0) { return ( @@ -126,7 +131,7 @@ const BootsTable = ({ )); - }, [filteredData, data, error, startIndex, endIndex, onClickName]); + }, [filteredData, data, startIndex, endIndex, onClickName]); const tableInfoElement = (
@@ -190,10 +195,6 @@ const BootsTable = ({ [intl, checkIfFilterIsSelected], ); - if (error) return ; - - if (isLoading) return ; - return (
diff --git a/dashboard/src/components/Table/TestsTable.tsx b/dashboard/src/components/Table/TestsTable.tsx index e2a5f8a0..d7d36094 100644 --- a/dashboard/src/components/Table/TestsTable.tsx +++ b/dashboard/src/components/Table/TestsTable.tsx @@ -2,21 +2,19 @@ import { useNavigate, useSearch } from '@tanstack/react-router'; import { useCallback, useMemo } from 'react'; -import { useIntl, FormattedMessage } from 'react-intl'; +import { useIntl } from 'react-intl'; import { TableInfo } from '@/components/Table/TableInfo'; import { usePagination } from '@/hooks/usePagination'; -import { useTreeTest } from '@/api/TreeDetails'; - import { + TestHistory, TestsTableFilter, possibleTestsTableFilter, } from '@/types/tree/TreeDetails'; -import { Skeleton } from '@/components/Skeleton'; - import { getStatusGroup } from '@/utils/status'; +import { TPathTests } from '@/types/general'; import Accordion from '../Accordion/Accordion'; @@ -25,21 +23,68 @@ import TableStatusFilter from './TableStatusFilter'; const ITEMS_PER_PAGE = 10; export interface ITestsTable { - treeId: string; + testHistory: TestHistory[]; } -const TestsTable = ({ treeId }: ITestsTable): JSX.Element => { - const { testPath, treeInfo, origin, tableFilter } = useSearch({ +const TestsTable = ({ testHistory }: ITestsTable): JSX.Element => { + const { tableFilter } = useSearch({ from: '/tree/$treeId/', }); const navigate = useNavigate({ from: '/tree/$treeId' }); - const { data, isLoading } = useTreeTest( - treeId, - testPath, - treeInfo.gitBranch ?? '', - treeInfo.gitUrl ?? '', - origin, - ); + + const data = useMemo((): TPathTests[] => { + type Groups = { + [K: string]: TPathTests; + }; + const groups: Groups = {}; + testHistory.forEach(e => { + const parts = e.path.split('.', 1); + const group = parts.length > 0 ? parts[0] : '-'; + if (!(group in groups)) { + groups[group] = { + done_tests: 0, + fail_tests: 0, + miss_tests: 0, + pass_tests: 0, + null_tests: 0, + skip_tests: 0, + error_tests: 0, + total_tests: 0, + path_group: group, + individual_tests: [], + }; + } + groups[group].total_tests++; + groups[group].individual_tests.push({ + duration: e.duration?.toString() ?? '', + path: e.path, + start_time: e.startTime, + status: e.status, + }); + switch (e.status) { + case 'DONE': + groups[group].done_tests++; + break; + case 'ERROR': + groups[group].error_tests++; + break; + case 'FAIL': + groups[group].fail_tests++; + break; + case 'MISS': + groups[group].miss_tests++; + break; + case 'PASS': + groups[group].pass_tests++; + break; + case 'SKIP': + groups[group].skip_tests++; + break; + } + }); + return Object.values(groups); + }, [testHistory]); + const data_len = data?.length || 0; const { startIndex, endIndex, onClickGoForward, onClickGoBack } = usePagination(data_len, ITEMS_PER_PAGE); @@ -144,13 +189,6 @@ const TestsTable = ({ treeId }: ITestsTable): JSX.Element => { } }, [tableFilter.testsTable, data]); - if (isLoading) - return ( - - - - ); - return (
diff --git a/dashboard/src/pages/TreeDetails/Tabs/Boots/BootsTab.tsx b/dashboard/src/pages/TreeDetails/Tabs/Boots/BootsTab.tsx index 1675161a..0a279304 100644 --- a/dashboard/src/pages/TreeDetails/Tabs/Boots/BootsTab.tsx +++ b/dashboard/src/pages/TreeDetails/Tabs/Boots/BootsTab.tsx @@ -2,7 +2,7 @@ import { FormattedMessage } from 'react-intl'; import { useParams, useSearch } from '@tanstack/react-router'; -import { useBootsTab } from '@/api/TreeDetails'; +import { useTestsTab } from '@/api/TreeDetails'; import BaseCard from '@/components/Cards/BaseCard'; import { Skeleton } from '@/components/Skeleton'; @@ -34,7 +34,7 @@ const BootsTab = ({ reqFilter }: BootsTabProps): JSX.Element => { const { origin, treeInfo } = useSearch({ from: '/tree/$treeId/', }); - const { isLoading, data, error } = useBootsTab( + const { isLoading, data, error } = useTestsTab( treeId ?? '', origin, treeInfo.gitBranch ?? '', @@ -78,61 +78,59 @@ const BootsTab = ({ reqFilter }: BootsTabProps): JSX.Element => {
} - statusCounts={data.statusCounts} + statusCounts={data.bootStatusSummary} /> } - configStatusCounts={data.configStatusCounts} + configStatusCounts={data.bootConfigs} /> } - architectureStatusCounts={data.architectureStatusCounts} - compilersPerArchitecture={data.compilersPerArchitecture} + archCompilerErrors={data.bootArchSummary} />
} - platformsWithError={data.platformsWithError} + platformsWithError={data.bootPlatformsFailing} /> } - errorMessageCounts={data.errorMessageCounts} + errorMessageCounts={data.bootFailReasons} />
} - statusCounts={data.statusCounts} + statusCounts={data.bootStatusSummary} />
} - configStatusCounts={data.configStatusCounts} + configStatusCounts={data.bootConfigs} /> } - architectureStatusCounts={data.architectureStatusCounts} - compilersPerArchitecture={data.compilersPerArchitecture} + archCompilerErrors={data.bootArchSummary} />
} - platformsWithError={data.platformsWithError} + platformsWithError={data.bootPlatformsFailing} /> } - errorMessageCounts={data.errorMessageCounts} + errorMessageCounts={data.bootFailReasons} />
- +
); }; diff --git a/dashboard/src/pages/TreeDetails/Tabs/TestCards.tsx b/dashboard/src/pages/TreeDetails/Tabs/TestCards.tsx index 52787479..4ccf7426 100644 --- a/dashboard/src/pages/TreeDetails/Tabs/TestCards.tsx +++ b/dashboard/src/pages/TreeDetails/Tabs/TestCards.tsx @@ -5,8 +5,8 @@ import { memo } from 'react'; import { DumbListingContent } from '@/components/ListingContent/ListingContent'; import BaseCard, { IBaseCard } from '@/components/Cards/BaseCard'; import ListingItem from '@/components/ListingItem/ListingItem'; -import { TTreeTestsData } from '@/types/tree/TreeDetails'; import { GroupedTestStatus, TestStatus } from '@/components/Status/Status'; +import { ArchCompilerStatus, TTreeTestsData } from '@/types/tree/TreeDetails'; import { DumbSummary, SummaryItem } from '@/components/Summary/Summary'; import StatusChartMemoized, { @@ -118,17 +118,13 @@ const ErrorCountList = ({ }; export const MemoizedErrorCountList = memo(ErrorCountList); -interface IErrorsSummary - extends Pick< - TTreeTestsData, - 'architectureStatusCounts' | 'compilersPerArchitecture' - > { +interface IErrorsSummary { + archCompilerErrors: ArchCompilerStatus[]; title: IBaseCard['title']; } const ErrorsSummary = ({ - architectureStatusCounts, - compilersPerArchitecture, + archCompilerErrors, title, }: IErrorsSummary): JSX.Element => { const summaryHeaders = [ @@ -141,14 +137,14 @@ const ErrorsSummary = ({ title={title} content={ - {Object.keys(architectureStatusCounts).map(architecture => { - const statusCounts = architectureStatusCounts[architecture]; - const currentCompilers = compilersPerArchitecture[architecture]; + {archCompilerErrors.map(e => { + const statusCounts = e.status; + const currentCompilers = [e.compiler]; return ( {
} - statusCounts={data.statusCounts} + statusCounts={data.testStatusSummary} /> } - configStatusCounts={data.configStatusCounts} + configStatusCounts={data.testConfigs} /> } - architectureStatusCounts={data.architectureStatusCounts} - compilersPerArchitecture={data.compilersPerArchitecture} + archCompilerErrors={data.testArchSummary} />
} - platformsWithError={data.platformsWithError} + platformsWithError={data.testPlatformsWithErrors} /> } - errorMessageCounts={data.errorMessageCounts} + errorMessageCounts={data.testFailReasons} />
} - statusCounts={data.statusCounts} + statusCounts={data.testStatusSummary} />
} - configStatusCounts={data.configStatusCounts} + configStatusCounts={data.testConfigs} /> } - architectureStatusCounts={data.architectureStatusCounts} - compilersPerArchitecture={data.compilersPerArchitecture} + archCompilerErrors={data.testArchSummary} />
} - platformsWithError={data.platformsWithError} + platformsWithError={data.testPlatformsWithErrors} /> } - errorMessageCounts={data.errorMessageCounts} + errorMessageCounts={data.testFailReasons} />
- +
); }; diff --git a/dashboard/src/types/tree/TreeDetails.tsx b/dashboard/src/types/tree/TreeDetails.tsx index 07de0dac..24d43fc9 100644 --- a/dashboard/src/types/tree/TreeDetails.tsx +++ b/dashboard/src/types/tree/TreeDetails.tsx @@ -76,9 +76,12 @@ export interface TTreeDetailsFilter valid?: string[]; } -type TestHistory = { - start_time: string; - status: string; +export type TestHistory = { + startTime: string; + status: Status; + path: string; + id: string; + duration?: number; }; type ErrorCounts = { @@ -97,6 +100,12 @@ type StatusCounts = { [key in Status]: number | undefined; }; +export type ArchCompilerStatus = { + arch: string; + compiler: string; + status: StatusCounts; +}; + type PropertyStatusCounts = Record; export type TTreeTestsData = { @@ -110,6 +119,21 @@ export type TTreeTestsData = { errorMessageCounts: ErrorMessageCounts; }; +export type TTreeTestsFullData = { + bootArchSummary: ArchCompilerStatus[]; + testArchSummary: ArchCompilerStatus[]; + bootFailReasons: ErrorMessageCounts; + testFailReasons: ErrorMessageCounts; + testPlatformsWithErrors: string[]; + bootPlatformsFailing: string[]; + testConfigs: PropertyStatusCounts; + bootConfigs: PropertyStatusCounts; + testStatusSummary: StatusCounts; + bootStatusSummary: StatusCounts; + bootHistory: TestHistory[]; + testHistory: TestHistory[]; +}; + export type PossibleTabs = Extract< MessagesKey, 'treeDetails.builds' | 'treeDetails.boots' | 'treeDetails.tests'