Skip to content

Commit

Permalink
feat: add misc and files section to test details
Browse files Browse the repository at this point in the history
  • Loading branch information
MarceloRobert committed Dec 19, 2024
1 parent ba5f1bb commit e690727
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 82 deletions.
10 changes: 10 additions & 0 deletions backend/kernelCI_app/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from django.utils import timezone
from datetime import timedelta

from kernelCI_app.helpers.logger import log_message

DEFAULT_QUERY_TIME_INTERVAL = {"days": 7}


Expand Down Expand Up @@ -69,3 +71,11 @@ def getQueryTimeInterval(**kwargs):

def getErrorResponseBody(reason: str):
return json.dumps({"error": True, "reason": reason})


def string_to_json(string: str) -> Optional[dict]:
if (string):
try:
return json.loads(string)
except json.JSONDecodeError as e:
log_message(e.msg)
12 changes: 9 additions & 3 deletions backend/kernelCI_app/views/testDetailsView.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from django.http import JsonResponse
from django.db import connection
from django.views import View
from kernelCI_app.utils import string_to_json


class TestDetails(View):
Expand All @@ -16,6 +17,7 @@ def get(self, _request, test_id: str | None):
"environment_misc": "combined_tests.environment_misc",
"start_time": "combined_tests.start_time",
"environment_compatible": "combined_tests.environment_compatible",
"output_files": "combined_tests.output_files",
"compiler": "builds.compiler",
"architecture": "builds.architecture",
"config_name": "builds.config_name",
Expand All @@ -36,6 +38,7 @@ def get(self, _request, test_id: str | None):
tests.environment_misc,
tests.start_time,
tests.environment_compatible,
tests.output_files,
builds.compiler,
builds.architecture,
builds.config_name,
Expand All @@ -53,9 +56,12 @@ def get(self, _request, test_id: str | None):
response = {}
with connection.cursor() as cursor:
cursor.execute(query, [test_id])
rows = cursor.fetchall()
if rows:
row = cursor.fetchone()
if row:
for idx, key in enumerate(names_map.keys()):
response[key] = rows[0][idx]
response[key] = row[idx]
response["misc"] = string_to_json(response["misc"])
response["environment_misc"] = string_to_json(response["environment_misc"])
response["output_files"] = string_to_json(response["output_files"])

return JsonResponse(response, safe=False)
209 changes: 132 additions & 77 deletions dashboard/src/components/TestDetails/TestDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,30 @@ import { Link, useRouterState, useSearch } from '@tanstack/react-router';

import { FiLink } from 'react-icons/fi';

import { truncateBigText } from '@/lib/string';
import { shouldTruncate, truncateBigText, valueOrEmpty } from '@/lib/string';
import type { TTestDetails } from '@/types/tree/TestDetails';
import { Sheet, SheetTrigger } from '@/components/Sheet';
import { useTestDetails, useTestIssues } from '@/api/testDetails';

import { RedirectFrom } from '@/types/general';

import { Subsection } from '@/components/Section/Section';
import type { ISubsection } from '@/components/Section/Section';
import { LogSheetContent } from '@/components/Log/LogSheetContent';
import type { ISection } from '@/components/Section/Section';
import { TooltipDateTime } from '@/components/TooltipDateTime';
import IssueSection from '@/components/Issue/IssueSection';
import { LogSheetContent } from '@/components/Log/LogSheetContent';
import SectionGroup from '@/components/Section/SectionGroup';
import { getMiscSection } from '@/components/Section/MiscSection';
import { getFilesSection } from '@/components/Section/FilesSection';

const emptyValue = '-';
const valueOrEmpty = (value: string | undefined): string => value || emptyValue;
import { TruncatedValueTooltip } from '../Tooltip/TruncatedValueTooltip';

const TestDetailsSection = ({ test }: { test: TTestDetails }): JSX.Element => {
const intl = useIntl();
const TestDetailsSections = ({ test }: { test: TTestDetails }): JSX.Element => {
const { formatMessage } = useIntl();
const historyState = useRouterState({ select: s => s.location.state });
const searchParams = useSearch({ from: '/test/$testId' });
const hardware: string =
test.environment_compatible?.join(' | ') ??
intl.formatMessage({ id: 'global.unknown' });
formatMessage({ id: 'global.unknown' });

const buildDetailsLink = useMemo(() => {
let linkTo = '';
Expand Down Expand Up @@ -66,73 +67,90 @@ const TestDetailsSection = ({ test }: { test: TTestDetails }): JSX.Element => {

const hasUsefulLogInfo = test.log_url || test.log_excerpt;

const infos: ISubsection['infos'] = useMemo(() => {
const baseInfo: ISubsection['infos'] = [
{
title: 'global.status',
linkText: truncateBigText(test.status),
},
{
title: 'global.path',
linkText: valueOrEmpty(test.path),
},
{
title: 'global.arch',
linkText: valueOrEmpty(test.architecture),
icon: <PiComputerTowerThin className="text-blue" />,
},
{
title: 'global.compiler',
linkText: valueOrEmpty(test.compiler),
},
{
title: 'global.logs',
icon: hasUsefulLogInfo ? (
<MdFolderOpen className="text-blue" />
) : undefined,
linkText: truncateBigText(valueOrEmpty(test.log_url)),
wrapperComponent: hasUsefulLogInfo ? SheetTrigger : undefined,
},
{
title: 'testDetails.gitCommitHash',
linkText: valueOrEmpty(test.git_commit_hash),
},
{
title: 'testDetails.gitRepositoryUrl',
linkText: truncateBigText(valueOrEmpty(test.git_repository_url)),
link: test.git_repository_url,
},
{
title: 'testDetails.gitRepositoryBranch',
linkText: valueOrEmpty(test.git_repository_branch),
},
{
title: 'testDetails.buildInfo',
linkText: truncateBigText(test.build_id),
linkComponent: buildDetailsLink,
},
{
title: 'global.hardware',
linkText: hardware,
icon: <GiFlatPlatform className="text-blue" />,
},
{
title: 'global.startTime',
linkText: (
<TooltipDateTime
dateTime={test.start_time}
lineBreak={true}
showLabelTime={true}
showLabelTZ={true}
/>
),
},
];

return baseInfo;
const generalSection: ISection = useMemo(() => {
return {
title: test.path,
eyebrow: formatMessage({ id: 'test.details' }),
subsections: [
{
infos: [
{
title: 'global.status',
linkText: truncateBigText(test.status),
},
{
title: 'global.path',
linkText: valueOrEmpty(test.path),
},
{
title: 'global.arch',
linkText: valueOrEmpty(test.architecture),
icon: <PiComputerTowerThin className="text-blue" />,
},
{
title: 'global.compiler',
linkText: valueOrEmpty(test.compiler),
},
{
title: 'global.logs',
icon: hasUsefulLogInfo ? (
<MdFolderOpen className="text-blue" />
) : undefined,
linkText: shouldTruncate(valueOrEmpty(test.log_url)) ? (
<TruncatedValueTooltip value={test.log_url} isUrl={true} />
) : (
valueOrEmpty(test.log_url)
),
wrapperComponent: hasUsefulLogInfo ? SheetTrigger : undefined,
},
{
title: 'testDetails.gitCommitHash',
linkText: valueOrEmpty(test.git_commit_hash),
},
{
title: 'testDetails.gitRepositoryUrl',
linkText: shouldTruncate(test.git_repository_url) ? (
<TruncatedValueTooltip
value={test.git_repository_url}
isUrl={true}
/>
) : (
test.git_repository_url
),
link: test.git_repository_url,
},
{
title: 'testDetails.gitRepositoryBranch',
linkText: valueOrEmpty(test.git_repository_branch),
},
{
title: 'testDetails.buildInfo',
linkText: truncateBigText(test.build_id),
linkComponent: buildDetailsLink,
},
{
title: 'global.hardware',
linkText: hardware,
icon: <GiFlatPlatform className="text-blue" />,
},
{
title: 'global.startTime',
linkText: (
<TooltipDateTime
dateTime={test.start_time}
lineBreak={true}
showLabelTime={true}
showLabelTZ={true}
/>
),
},
],
},
],
};
}, [
test.status,
test.path,
test.status,
test.architecture,
test.compiler,
test.log_url,
Expand All @@ -141,11 +159,49 @@ const TestDetailsSection = ({ test }: { test: TTestDetails }): JSX.Element => {
test.git_repository_branch,
test.build_id,
test.start_time,
formatMessage,
hasUsefulLogInfo,
buildDetailsLink,
hardware,
]);
return <Subsection infos={infos} />;

const miscSection: ISection | undefined = useMemo(():
| ISection
| undefined => {
return getMiscSection({
misc: test.misc,
title: formatMessage({ id: 'globalDetails.miscData' }),
});
}, [formatMessage, test.misc]);

const environmentMiscSection: ISection | undefined = useMemo(():
| ISection
| undefined => {
return getMiscSection({
misc: test.environment_misc,
title: formatMessage({ id: 'globalDetails.environmentMiscData' }),
});
}, [formatMessage, test.environment_misc]);

const filesSection: ISection | undefined = useMemo(():
| ISection
| undefined => {
return getFilesSection({
outputFiles: test.output_files,
title: formatMessage({ id: 'globalDetails.artifacts' }),
});
}, [formatMessage, test.output_files]);

const sectionsData: ISection[] = useMemo(() => {
return [
generalSection,
miscSection,
environmentMiscSection,
filesSection,
].filter(section => section !== undefined);
}, [generalSection, miscSection, environmentMiscSection, filesSection]);

return <SectionGroup sections={sectionsData} />;
};

interface TestsDetailsProps {
Expand Down Expand Up @@ -183,8 +239,7 @@ const TestDetails = ({
<div className="w-100 px-5 pb-8">
{breadcrumb}

<h1 className="mb-4 text-2xl font-bold">{data.path}</h1>
<TestDetailsSection test={data} />
<TestDetailsSections test={data} />
<IssueSection {...issuesQueryResult} />
</div>
<LogSheetContent logUrl={data.log_url} logExcerpt={data.log_excerpt} />
Expand Down
1 change: 1 addition & 0 deletions dashboard/src/locales/messages/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ export const messages = {
'global.unknown': 'Unknown',
'global.url': 'URL',
'globalDetails.artifacts': 'Artifacts',
'globalDetails.environmentMiscData': 'Environment Misc Data',
'globalDetails.miscData': 'Misc Data',
'globalTable.bootStatus': 'Boot Status',
'globalTable.branch': 'Branch',
Expand Down
5 changes: 3 additions & 2 deletions dashboard/src/types/tree/TestDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@ export type TTestDetails = {
build_id: string;
compiler: string;
config_name: string;
environment_misc: string | undefined;
git_commit_hash: string;
git_repository_branch: string;
git_repository_url: string;
id: string;
log_excerpt: string | undefined;
log_url: string | undefined;
misc: string | undefined;
path: string;
start_time: string;
status: string;
environment_compatible?: string[];
environment_misc?: Record<string, unknown>;
misc?: Record<string, unknown>;
output_files?: Record<string, unknown>;
};

0 comments on commit e690727

Please sign in to comment.