blob: 9ee945c8eb92e15afe321cf7f2e679cd30f6404b [file]
/**
* @license
* Copyright 2023 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
import {TagColor} from '@gerritcodereview/typescript-api/checks';
import {FaultAttribute, FaultAttributeProperties} from '../failure-analysis';
import {
assignFaultAttributesToVariants,
getFaultAttributeEntryKey,
getFaultAttributeTagColor,
getFaultAttributeTagDisplayName,
getFaultAttributeTagTooltip,
} from '../failure-analysis-utils';
import {assert} from '@open-wc/testing';
import {TestVariant, TestVariantStatus} from '../resultdb-client';
import {Build} from '../checks-fetcher';
import {BuildStatus} from '../buildbucket-client';
suite('failure analysis utils', () => {
test('getFaultAttributeEntryKey returns a hyphened combination of test variant properties in the correct order', () => {
const buildId = '12345';
const buildTarget = 'buildTarget';
const modelName = 'model';
const testName = 'some.test';
const boardAndModelKey = getFaultAttributeEntryKey(
buildId,
buildTarget,
modelName,
testName
);
assert.equal(
boardAndModelKey,
`${buildId}-${buildTarget}-${modelName}-${testName}`
);
const boardKey = getFaultAttributeEntryKey(
buildId,
buildTarget,
'',
testName
);
assert.equal(boardKey, `${buildId}-${buildTarget}-${testName}`);
});
test('assignFaultAttributesToVariants correctly assigns fault attributes to test variants', () => {
// Set up test data.
const testVariant1ForBuild1FaultAttribute = {
comparisonSnapshot: {
sourceBuildId: '8775275012462334081',
sourceStartedUnixTimestamp: '1689668613',
},
snapshotComparisonFaultAttribution: FaultAttribute.SUCCESS_FOUND,
testName: 'test1',
likelyFlaky: true,
} as FaultAttributeProperties;
const testVariant2ForBuild1FaultAttribute = {
comparisonSnapshot: {
sourceBuildId: '8775275012462334081',
sourceStartedUnixTimestamp: '1689668613',
},
snapshotComparisonFaultAttribution: FaultAttribute.MATCHING_FAILURE_FOUND,
testName: 'test2',
} as FaultAttributeProperties;
const orchBuild1 = {
id: '1',
builder: {
id: {
builder: 'cq-orchestrator',
},
builder: 'cq-orchestrator',
},
status: BuildStatus.SUCCESS,
createTime: '1/1/2023',
startTime: '1/1/2023',
endTime: '1/1/2023',
output: {
properties: {
rts_was_used: false,
cq_fault_attributions: {
testFailureAttributions: [
{
buildTarget: 'target',
faultAttributes: [
testVariant1ForBuild1FaultAttribute,
testVariant2ForBuild1FaultAttribute,
],
},
],
},
},
},
} as Build;
const testVariant1ForBuild2FaultAttribute = {
comparisonSnapshot: {
sourceBuildId: '8775275012462334081',
sourceStartedUnixTimestamp: '1689668613',
},
snapshotComparisonFaultAttribution:
FaultAttribute.DIFFERING_FAILURE_FOUND,
testName: 'test1',
} as FaultAttributeProperties;
const orchBuild2 = {
id: '2',
builder: {
id: {
builder: 'cq-orchestrator',
},
builder: 'cq-orchestrator',
},
status: BuildStatus.SUCCESS,
createTime: '1/1/2023',
startTime: '1/1/2023',
endTime: '1/1/2023',
output: {
properties: {
rts_was_used: false,
cq_fault_attributions: {
testFailureAttributions: [
{
buildTarget: 'target',
faultAttributes: [testVariant1ForBuild2FaultAttribute],
},
],
},
},
},
} as Build;
const testVariant1ForNonOrchBuildFaultAttribute = {
comparisonSnapshot: {
sourceBuildId: '8775275012462334081',
sourceStartedUnixTimestamp: '1689668613',
},
snapshotComparisonFaultAttribution: FaultAttribute.MATCHING_FAILURE_FOUND,
testName: 'test1',
};
const nonOrchBuild = {
id: '3',
builder: {
id: {
builder: 'cq-orchestrator',
},
builder: 'cq-orchestrator',
},
status: BuildStatus.SUCCESS,
createTime: '1/1/2023',
startTime: '1/1/2023',
endTime: '1/1/2023',
output: {
properties: {
rts_was_used: false,
cq_fault_attributions: {
testFailureAttributions: [
{
buildTarget: 'target',
faultAttributes: [testVariant1ForNonOrchBuildFaultAttribute],
},
],
},
},
},
} as Build;
const testVariant1ForBuild1 = {
testId: 'test1',
variant: {
def: {
build_target: 'target',
},
results: [],
exonerations: [],
status: TestVariantStatus.UNEXPECTED,
},
} as TestVariant;
const testVariant2ForBuild1 = {
testId: 'test2',
variant: {
def: {
build_target: 'target',
},
results: [],
exonerations: [],
status: TestVariantStatus.UNEXPECTED,
},
} as TestVariant;
const testVariant1ForBuild2 = {
testId: 'test1',
variant: {
def: {
build_target: 'target',
},
results: [],
exonerations: [],
status: TestVariantStatus.UNEXPECTED,
},
} as TestVariant;
const testVariant1ForNonOrchBuild = {
testId: 'test1',
variant: {
def: {
build_target: 'target',
},
results: [],
exonerations: [],
status: TestVariantStatus.UNEXPECTED,
},
} as TestVariant;
const tvsByBuilds = {
'1': {
variants: [testVariant1ForBuild1, testVariant2ForBuild1],
errorMessage: '',
},
'2': {variants: [testVariant1ForBuild2], errorMessage: ''},
'3': {variants: [testVariant1ForNonOrchBuild], errorMessage: ''},
};
const attemptsByBuilder = {
'cq-orchestrator': [
{isQuickRun: false, build: orchBuild1},
{isQuickRun: false, build: orchBuild2},
],
'non-orch-build': [{isQuickRun: false, build: nonOrchBuild}],
};
// Run operation.
assignFaultAttributesToVariants(tvsByBuilds, attemptsByBuilder);
// Verify expectations.
assert.equal(
testVariant1ForBuild1.faultAttribute,
testVariant1ForBuild1FaultAttribute
);
});
suite('failure analysis tag properties', () => {
const flakyFaultAttribute = {
testName: 'some.test',
snapshotComparisonFaultAttribution:
FaultAttribute.DIFFERING_FAILURE_FOUND,
likelyFlaky: true,
} as FaultAttributeProperties;
const newFailureFaultAttribute = {
testName: 'some.test',
snapshotComparisonFaultAttribution: FaultAttribute.SUCCESS_FOUND,
} as FaultAttributeProperties;
const preexistingDiffFailureFaultAttribute = {
testName: 'some.test',
snapshotComparisonFaultAttribution:
FaultAttribute.DIFFERING_FAILURE_FOUND,
} as FaultAttributeProperties;
const preexistingSameFailureFaultAttribute = {
testName: 'some.test',
snapshotComparisonFaultAttribution: FaultAttribute.MATCHING_FAILURE_FOUND,
} as FaultAttributeProperties;
const anyOtherFaultAttribute = {
testName: 'some.test',
snapshotComparisonFaultAttribution: FaultAttribute.NO_COMPARISON,
} as FaultAttributeProperties;
test('getFaultAttributeTagDisplayName returns expected display names', () => {
assert.equal(
getFaultAttributeTagDisplayName(flakyFaultAttribute),
'Likely flaky'
);
assert.equal(
getFaultAttributeTagDisplayName(newFailureFaultAttribute),
'New failure'
);
assert.equal(
getFaultAttributeTagDisplayName(preexistingDiffFailureFaultAttribute),
'Pre-existing differing failure'
);
assert.equal(
getFaultAttributeTagDisplayName(preexistingSameFailureFaultAttribute),
'Pre-existing identical failure'
);
assert.isNull(getFaultAttributeTagDisplayName(anyOtherFaultAttribute));
});
test('getFaultAttributeTagColor returns expected tag colors', () => {
assert.equal(
getFaultAttributeTagColor(flakyFaultAttribute),
TagColor.YELLOW
);
assert.equal(
getFaultAttributeTagColor(newFailureFaultAttribute),
TagColor.PINK
);
assert.equal(
getFaultAttributeTagColor(preexistingDiffFailureFaultAttribute),
TagColor.YELLOW
);
assert.equal(
getFaultAttributeTagColor(preexistingSameFailureFaultAttribute),
TagColor.GRAY
);
assert.isNull(getFaultAttributeTagColor(anyOtherFaultAttribute));
});
test('getFaultAttributeTagTooltip returns expected tooltip', () => {
assert.equal(
getFaultAttributeTagTooltip(flakyFaultAttribute),
'This test failure is likely flaky'
);
assert.equal(
getFaultAttributeTagTooltip(newFailureFaultAttribute),
'This test failure is not present in ToT and may need some additional debugging'
);
assert.equal(
getFaultAttributeTagTooltip(preexistingDiffFailureFaultAttribute),
'This test failure occurred in an earlier snapshot build with a different failure reason'
);
assert.equal(
getFaultAttributeTagTooltip(preexistingSameFailureFaultAttribute),
'This test failure occurred in an earlier snapshot build with an identical failure reason'
);
assert.isNull(getFaultAttributeTagTooltip(anyOtherFaultAttribute));
});
});
});