Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Run Source #3391

Merged
merged 1 commit into from
Nov 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 0 additions & 1 deletion api/tests.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
openapi: 3.0.0
components:
schemas:

TestResourceList:
type: object
properties:
Expand Down
7 changes: 6 additions & 1 deletion cli/runner/orchestrator.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,16 +335,21 @@ func (a orchestrator) writeJUnitReport(ctx context.Context, r Runner, result Run
return err
}

var source = "cli"

func getMetadata() map[string]string {
ci := cienvironment.DetectCIEnvironment()
if ci == nil {
return map[string]string{}
return map[string]string{
"source": source,
}
}

metadata := map[string]string{
"name": ci.Name,
"url": ci.URL,
"buildNumber": ci.BuildNumber,
"source": source,
}

if ci.Git != nil {
Expand Down
2 changes: 1 addition & 1 deletion server/executor/test_suite_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func (r persistentTransactionRunner) ProcessItem(ctx context.Context, job Job) {
}

func (r persistentTransactionRunner) runTransactionStep(ctx context.Context, tr testsuite.TestSuiteRun, step int, testObj test.Test) (testsuite.TestSuiteRun, error) {
testRun := r.testRunner.Run(ctx, testObj, tr.Metadata, tr.VariableSet, tr.RequiredGates)
testRun := r.testRunner.Run(ctx, testObj, tr.RunMetadata(step), tr.VariableSet, tr.RequiredGates)
tr, err := r.updateStepRun(ctx, tr, step, testRun)
if err != nil {
return testsuite.TestSuiteRun{}, fmt.Errorf("could not update transaction run: %w", err)
Expand Down
9 changes: 9 additions & 0 deletions server/testsuite/testsuite_run_entities.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,12 @@ func (tr TestSuiteRun) StepsGatesValidation() bool {

return true
}

func (tr TestSuiteRun) RunMetadata(step int) test.RunMetadata {
tr.Metadata["step"] = fmt.Sprintf("%d", step+1)
tr.Metadata["testsuite_run_id"] = fmt.Sprintf("%d", tr.ID)
tr.Metadata["testsuite_id"] = string(tr.TestSuiteID)
tr.Metadata["testsuite_version"] = fmt.Sprintf("%d", tr.TestSuiteVersion)

return tr.Metadata
}
22 changes: 7 additions & 15 deletions web/src/components/RunCard/TestRunCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const TestRunCard = ({
state,
createdAt,
testVersion,
metadata,
metadata: {name, buildNumber, branch, url, source},
testSuiteId,
testSuiteRunId,
linter,
Expand All @@ -37,10 +37,6 @@ const TestRunCard = ({
linkTo,
}: IProps) => {
const {navigate} = useDashboard();
const metadataName = metadata?.name;
const metadataBuildNumber = metadata?.buildNumber;
const metadataBranch = metadata?.branch;
const metadataUrl = metadata?.url;

const handleResultClick = (
event: React.MouseEvent<HTMLDivElement, MouseEvent>,
Expand All @@ -64,13 +60,14 @@ const TestRunCard = ({
</Tooltip>

{isRunStateFinished(state) && <S.Text>&nbsp;• {executionTime}s</S.Text>}
{source && <S.Text>&nbsp;• Run via {source.toUpperCase()}</S.Text>}

{metadataName && (
<a href={metadataUrl} target="_blank" onClick={event => event.stopPropagation()}>
<S.Text $hasLink={Boolean(metadataUrl)}>&nbsp;• {`${metadataName} ${metadataBuildNumber}`}</S.Text>
{name && (
<a href={url} target="_blank" onClick={event => event.stopPropagation()}>
<S.Text $hasLink={Boolean(url)}>&nbsp;• {`${name} ${buildNumber}`}</S.Text>
</a>
)}
{metadataBranch && <S.Text>&nbsp;• Branch: {metadataBranch}</S.Text>}
{branch && <S.Text>&nbsp;• Branch: {branch}</S.Text>}
</S.Row>
</S.Info>

Expand Down Expand Up @@ -108,12 +105,7 @@ const TestRunCard = ({
)}

<div>
<RunActionsMenu
resultId={runId}
testId={testId}
testSuiteRunId={testSuiteRunId}
testSuiteId={testSuiteId}
/>
<RunActionsMenu resultId={runId} testId={testId} testSuiteRunId={testSuiteRunId} testSuiteId={testSuiteId} />
</div>
</S.Container>
</Link>
Expand Down
117 changes: 60 additions & 57 deletions web/src/components/RunCard/TestSuiteRunCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,68 +15,71 @@ interface IProps {
}

const TestSuiteRunCard = ({
run: {id: runId, createdAt, state, metadata, version, pass, fail, allStepsRequiredGatesPassed},
run: {
id: runId,
createdAt,
state,
metadata: {name, buildNumber, branch, url, source},
version,
pass,
fail,
allStepsRequiredGatesPassed,
},
testSuiteId,
linkTo,
}: IProps) => {
const metadataName = metadata?.name;
const metadataBuildNumber = metadata?.buildNumber;
const metadataBranch = metadata?.branch;
const metadataUrl = metadata?.url;

return (
<Link to={linkTo}>
<S.Container $isWhite>
<TestSuiteRunStatusIcon state={state} hasFailedTests={!allStepsRequiredGatesPassed} />
<S.Info>
<div>
<S.Title>v{version}</S.Title>
</div>
<S.Row>
<Tooltip title={Date.format(createdAt)}>
<S.Text>{Date.getTimeAgo(createdAt)}</S.Text>
</Tooltip>
{/* Adding this latter when is available */}
{/* <S.Text>&nbsp;• 0s (executionTime missing from API)</S.Text> */}

{metadataName && (
<a href={metadataUrl} target="_blank" onClick={event => event.stopPropagation()}>
<S.Text $hasLink={Boolean(metadataUrl)}>&nbsp;• {`${metadataName} ${metadataBuildNumber}`}</S.Text>
</a>
)}
{metadataBranch && <S.Text>&nbsp;• Branch: {metadataBranch}</S.Text>}
</S.Row>
</S.Info>

{state !== TestStateEnum.FAILED && state !== TestStateEnum.FINISHED && (
<div>
<TestState testState={state} />
</div>
)}
}: IProps) => (
<Link to={linkTo}>
<S.Container $isWhite>
<TestSuiteRunStatusIcon state={state} hasFailedTests={!allStepsRequiredGatesPassed} />
<S.Info>
<div>
<S.Title>v{version}</S.Title>
</div>
<S.Row>
<Tooltip title={Date.format(createdAt)}>
<S.Text>{Date.getTimeAgo(createdAt)}</S.Text>
</Tooltip>
{source && <S.Text>&nbsp;• Run via {source.toUpperCase()}</S.Text>}
{/* Adding this latter when is available */}
{/* <S.Text>&nbsp;• 0s (executionTime missing from API)</S.Text> */}
Comment on lines +43 to +44
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a dead code? Or is it something that will be added in future PRs?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should go back and add this to the BE, iw would be nice to have this in the UI


{(state === TestStateEnum.FAILED || state === TestStateEnum.FINISHED) && (
<S.Row>
<Tooltip title="Passed assertions">
<S.HeaderDetail>
<S.HeaderDot $passed />
{pass}
</S.HeaderDetail>
</Tooltip>
<Tooltip title="Failed assertions">
<S.HeaderDetail>
<S.HeaderDot $passed={false} />
{fail}
</S.HeaderDetail>
</Tooltip>
</S.Row>
)}
{name && (
<a href={url} target="_blank" onClick={event => event.stopPropagation()}>
<S.Text $hasLink={Boolean(url)}>&nbsp;• {`${name} ${buildNumber}`}</S.Text>
</a>
)}
{branch && <S.Text>&nbsp;• Branch: {branch}</S.Text>}
</S.Row>
</S.Info>

{state !== TestStateEnum.FAILED && state !== TestStateEnum.FINISHED && (
<div>
<TestSuiteRunActionsMenu runId={runId} testSuiteId={testSuiteId} />
<TestState testState={state} />
</div>
</S.Container>
</Link>
);
};
)}

{(state === TestStateEnum.FAILED || state === TestStateEnum.FINISHED) && (
<S.Row>
<Tooltip title="Passed assertions">
<S.HeaderDetail>
<S.HeaderDot $passed />
{pass}
</S.HeaderDetail>
</Tooltip>
<Tooltip title="Failed assertions">
<S.HeaderDetail>
<S.HeaderDot $passed={false} />
{fail}
</S.HeaderDetail>
</Tooltip>
</S.Row>
)}

<div>
<TestSuiteRunActionsMenu runId={runId} testSuiteId={testSuiteId} />
</div>
</S.Container>
</Link>
);

export default TestSuiteRunCard;
21 changes: 16 additions & 5 deletions web/src/components/RunDetailLayout/HeaderLeft.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,19 @@ interface IProps {
}

const HeaderLeft = ({name, triggerType, origin}: IProps) => {
const {run: {createdAt, testSuiteId, testSuiteRunId, executionTime, trace, traceId, testVersion} = {}, run} =
useTestRun();
const {
run: {
createdAt,
testSuiteId,
testSuiteRunId,
executionTime,
trace,
traceId,
testVersion,
metadata: {source} = {},
} = {},
run,
} = useTestRun();
const {onEdit, isEditLoading: isLoading, test} = useTest();
const createdTimeAgo = Date.getTimeAgo(createdAt ?? '');
const {navigate} = useDashboard();
Expand All @@ -33,8 +44,8 @@ const HeaderLeft = ({name, triggerType, origin}: IProps) => {
const description = useMemo(() => {
return (
<>
v{testVersion} • {triggerType} • Ran {createdTimeAgo}
{testSuiteId && testSuiteRunId && (
v{testVersion} • {triggerType} • Ran {createdTimeAgo} • {source && <>Run via {source.toUpperCase()}</>}
{testSuiteId && !!testSuiteRunId && (
<>
{' '}
•{' '}
Expand All @@ -45,7 +56,7 @@ const HeaderLeft = ({name, triggerType, origin}: IProps) => {
)}
</>
);
}, [triggerType, createdTimeAgo, testSuiteId, testSuiteRunId, testVersion]);
}, [testVersion, triggerType, createdTimeAgo, source, testSuiteId, testSuiteRunId]);

return (
<S.Section $justifyContent="flex-start">
Expand Down
31 changes: 31 additions & 0 deletions web/src/components/RunDetailTriggerResponse/ResponseMetadata.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import {useTestRun} from 'providers/TestRun/TestRun.provider';
import {useMemo} from 'react';
import * as S from './RunDetailTriggerResponse.styled';
import KeyValueRow from '../KeyValueRow';

const ResponseMetadata = () => {
const {
run: {metadata},
} = useTestRun();

const entries = useMemo(() => Object.entries(metadata).filter(([, value]) => !!value), [metadata]);

if (!entries.length) {
return (
<S.EmptyContainer>
<S.EmptyIcon />
<S.EmptyTitle>There are no metadata entries used in this test</S.EmptyTitle>
</S.EmptyContainer>
);
}

return (
<S.ResponseVarsContainer>
{entries.map(([key, value]) => (
<KeyValueRow key={key} keyName={key} value={value} />
))}
</S.ResponseVarsContainer>
);
};

export default ResponseMetadata;
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ import ResponseVariableSet from './ResponseVariableSet';
import ResponseHeaders from './ResponseHeaders';
import * as S from './RunDetailTriggerResponse.styled';
import {IPropsComponent} from './RunDetailTriggerResponseFactory';
import ResponseMetadata from './ResponseMetadata';

const TabsKeys = {
Body: 'body',
Headers: 'headers',
VariableSet: 'variable-set',
Metadata: 'metadata',
};

const tracetestTriggerSelector = 'span[tracetest.span.type="general" name="Tracetest trigger"]';
Expand Down Expand Up @@ -146,6 +148,9 @@ const RunDetailTriggerResponse = ({
<Tabs.TabPane key={TabsKeys.VariableSet} tab="Variable Set">
<ResponseVariableSet />
</Tabs.TabPane>
<Tabs.TabPane key={TabsKeys.Metadata} tab="Metadata">
<ResponseMetadata />
</Tabs.TabPane>
</Tabs>
</S.TabsContainer>
</S.Container>
Expand Down
1 change: 0 additions & 1 deletion web/src/components/VariableSet/VariableSetForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ const VariableSetForm = ({form, initialValues, onSubmit, onValidate}: IProps) =>
<Form.Item
label="Description"
name="description"
rules={[{required: true, message: 'Please input a description'}]}
>
<Input />
</Form.Item>
Expand Down
44 changes: 44 additions & 0 deletions web/src/models/RunMetadata.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import {Model} from 'types/Common.types';

export type TRawRunMetadata = Record<string, string>;

export enum KnownSources {
WEB = 'web',
CLI = 'cli',
API = 'api',
K6 = 'k6',
UNKNOWN = 'unknown',
}

type TKnownSources = KnownSources | string;

type RunMetadata = Model<
Record<string, string>,
{
name: string;
buildNumber: string;
branch: string;
url: string;
source: TKnownSources;
}
>;

function RunMetadata({
name = '',
buildNumber = '',
branch = '',
url = '',
source = '',
...rest
}: TRawRunMetadata): RunMetadata {
return {
name,
buildNumber,
branch,
url,
source,
...rest,
};
}

export default RunMetadata;