Skip to content

Commit 28875fe

Browse files
authored
Error handling in runTestPlan and FetchTestPlanData files (#20872)
* Handling errors in RunTestPlan and FetchTestPlan * Bumping up the task version
1 parent f3ff565 commit 28875fe

File tree

4 files changed

+125
-65
lines changed

4 files changed

+125
-65
lines changed

Tasks/AzureTestPlanV0/runTestPlan.ts

+98-48
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,122 @@
11
import * as tl from 'azure-pipelines-task-lib/task';
2-
import { manualTestsFlow } from './Manual Flow/manualTests'
3-
import { getTestPlanData, TestPlanData } from './testPlanData'
4-
import { automatedTestsFlow } from './OldAutomatedFlow/automatedTests'
2+
import { manualTestsFlow } from './Manual Flow/manualTests';
3+
import { getTestPlanData, TestPlanData } from './testPlanData';
4+
import { automatedTestsFlow } from './OldAutomatedFlow/automatedTests';
55
import { publishEvent, ciDictionary } from './Common/ciEventLogger';
66
import { IOperationResult } from './Interface/IOperationResult';
77
import { newAutomatedTestsFlow } from './Automated Flow/automatedFlow';
88

9-
function setupCiData(testSelectorInput: string, testPlanInfo: TestPlanData) {
10-
let ciData: ciDictionary = {
11-
TestSelector: testSelectorInput,
12-
totalNumOfManualTestPoint: testPlanInfo.listOfManualTestPoints.length,
13-
totalNumOfAutomatedTestPoint: testPlanInfo.listOfAutomatedTestPoints.length,
14-
totalNumOfTestSuites: testPlanInfo.testSuiteIds.length
15-
}
16-
17-
return ciData;
9+
function updateCiData(testSelectorInput: string, testPlanInfo: TestPlanData, ciData: ciDictionary) {
10+
ciData.TestSelector = testSelectorInput;
11+
ciData.totalNumOfManualTestPoint = testPlanInfo.listOfManualTestPoints.length;
12+
ciData.totalNumOfAutomatedTestPoint = testPlanInfo.listOfAutomatedTestPoints.length;
13+
ciData.totalNumOfTestSuites = testPlanInfo.testSuiteIds.length;
1814
}
1915

20-
export async function run() {
21-
22-
const testSelectorInput = tl.getInput('testSelector');
23-
console.log('Test Selector selected : ' + testSelectorInput);
24-
25-
let testPlanInfo: TestPlanData;
16+
async function fetchTestPlanData(ciData: ciDictionary): Promise<TestPlanData | null> {
2617
try {
27-
testPlanInfo = await getTestPlanData();
18+
return await getTestPlanData(ciData);
2819
} catch (err) {
29-
tl.setResult(tl.TaskResult.Failed, `Error in fetching test plan data: ${err}`);
30-
return 1;
20+
ciData.returnCode = 1;
21+
ciData.errorMessage = `Error in fetching test plan data: ${err}`;
22+
return null;
3123
}
24+
}
3225

33-
let ciData: ciDictionary = setupCiData(testSelectorInput, testPlanInfo);
34-
35-
let manualFlowResult: IOperationResult = { returnCode: 0, errorMessage: '' };
36-
let automatedFlowResult: IOperationResult = { returnCode: 0, errorMessage: '' };
37-
const myEnvVar = tl.getVariable('Use_NewAutomatedFlow');
38-
tl.debug(`The value of Use_NewAutomatedFlow is: ${myEnvVar}`);
26+
async function executeTestFlows(testSelectorInput: string, testPlanInfo: TestPlanData, ciData: ciDictionary): Promise<IOperationResult> {
27+
const defaultResult: IOperationResult = { returnCode: 0, errorMessage: '' };
28+
let manualFlowResult: IOperationResult = { ...defaultResult };
29+
let automatedFlowResult: IOperationResult = { ...defaultResult };
3930

40-
// trigger manual, automated or both tests based on user's input
31+
// Handle manual tests execution
4132
if (testSelectorInput.includes('manualTests')) {
42-
manualFlowResult = await manualTestsFlow(testPlanInfo, ciData);
43-
tl.debug(`Execution Status Code for Manual Test Flow is ${manualFlowResult.returnCode}`);
44-
45-
if(manualFlowResult.returnCode){
46-
tl.debug(`Error in Manual Test Flow: ${manualFlowResult.errorMessage}`);
47-
}
48-
ciData["manualTestFlowReturnCode"] = manualFlowResult.returnCode;
33+
manualFlowResult = await executeManualTests(testPlanInfo, ciData);
4934
}
5035

36+
// Handle automated tests execution
5137
if (testSelectorInput.includes('automatedTests')) {
52-
if(myEnvVar){
53-
automatedFlowResult = await newAutomatedTestsFlow(testPlanInfo, testSelectorInput, ciData);
54-
tl.debug(`Execution Status Code for Automated Test Flow is ${automatedFlowResult.returnCode}`);
55-
ciData["automatedTestFlowReturnCode"] = automatedFlowResult.returnCode;
56-
}
57-
else{
58-
automatedFlowResult = await automatedTestsFlow(testPlanInfo, testSelectorInput, ciData);
59-
tl.debug(`Execution Status Code for Automated Test Flow is ${automatedFlowResult.returnCode}`);
60-
ciData["automatedTestFlowReturnCode"] = automatedFlowResult.returnCode;
61-
62-
}
38+
automatedFlowResult = await executeAutomatedTests(testPlanInfo, testSelectorInput, ciData);
6339
}
6440

65-
if( manualFlowResult.returnCode || automatedFlowResult.returnCode){
66-
tl.setResult(tl.TaskResult.Failed, "Faced error in execution.");
41+
// Handle errors and return results
42+
return handleOperationErrorsAndResults(manualFlowResult, automatedFlowResult, ciData);
43+
}
44+
45+
async function executeManualTests(testPlanInfo: TestPlanData, ciData: ciDictionary): Promise<IOperationResult> {
46+
const result = await manualTestsFlow(testPlanInfo, ciData);
47+
tl.debug(`Execution Status Code for Manual Test Flow is ${result.returnCode}`);
48+
49+
if (result.returnCode) {
50+
tl.debug(`Error in Manual Test Flow: ${result.errorMessage}`);
6751
}
52+
ciData.manualTestFlowReturnCode = result.returnCode;
53+
return result;
54+
}
55+
56+
async function executeAutomatedTests(testPlanInfo: TestPlanData, testSelectorInput: string, ciData: ciDictionary): Promise<IOperationResult> {
57+
const disableNewAutomatedFlow = tl.getVariable('Disable_NewAutomatedFlow') === 'true';
58+
tl.debug(`The value of Disable_NewAutomatedFlow is: ${disableNewAutomatedFlow}`);
6859

60+
const result = disableNewAutomatedFlow
61+
? await automatedTestsFlow(testPlanInfo, testSelectorInput, ciData)
62+
: await newAutomatedTestsFlow(testPlanInfo, testSelectorInput, ciData);
63+
64+
tl.debug(`Execution Status Code for Automated Test Flow is ${result.returnCode}`);
65+
ciData.automatedTestFlowReturnCode = result.returnCode;
66+
return result;
67+
}
68+
69+
function handleOperationErrorsAndResults(manualResult: IOperationResult, automatedResult: IOperationResult, ciData: ciDictionary): IOperationResult {
70+
if (manualResult.returnCode && automatedResult.returnCode) {
71+
ciData.returnCode = 1;
72+
ciData.errorMessage = `${manualResult.errorMessage}\n${automatedResult.errorMessage}`;
73+
manualResult.errorMessage = ciData.errorMessage;
74+
return manualResult;
75+
}
76+
77+
if (manualResult.returnCode) {
78+
ciData.returnCode = 1;
79+
ciData.errorMessage = manualResult.errorMessage;
80+
return manualResult;
81+
}
82+
83+
if (automatedResult.returnCode) {
84+
ciData.returnCode = 1;
85+
ciData.errorMessage = automatedResult.errorMessage;
86+
return automatedResult;
87+
}
88+
89+
return manualResult;
90+
}
91+
92+
export async function run() {
93+
const testSelectorInput = tl.getInput('testSelector');
94+
console.log('Test Selector selected: ' + testSelectorInput);
95+
96+
let ciData: ciDictionary = {
97+
TestSelector: testSelectorInput,
98+
totalNumOfManualTestPoint: 0,
99+
totalNumOfAutomatedTestPoint: 0,
100+
totalNumOfTestSuites: 0,
101+
result: '',
102+
errorMessage: ''
103+
};
104+
105+
const testPlanInfo = await fetchTestPlanData(ciData);
106+
if (testPlanInfo === null) {
107+
publishEvent(ciData);
108+
tl.setResult(tl.TaskResult.Failed, ciData.errorMessage);
109+
return;
110+
}
111+
112+
updateCiData(testSelectorInput, testPlanInfo, ciData);
113+
let operationResult: IOperationResult = await executeTestFlows(testSelectorInput, testPlanInfo, ciData);
69114
publishEvent(ciData);
115+
116+
if (operationResult.returnCode !== 0) {
117+
tl.setResult(tl.TaskResult.Failed, operationResult.errorMessage);
118+
}
119+
70120
}
71121

72122
run();

Tasks/AzureTestPlanV0/task.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"version": {
1515
"Major": 0,
1616
"Minor": 253,
17-
"Patch": 4
17+
"Patch": 6
1818
},
1919
"preview": true,
2020
"demands": [],

Tasks/AzureTestPlanV0/task.loc.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"version": {
1515
"Major": 0,
1616
"Minor": 253,
17-
"Patch": 4
17+
"Patch": 6
1818
},
1919
"preview": true,
2020
"demands": [],

Tasks/AzureTestPlanV0/testPlanData.ts

+25-15
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { PagedList } from 'azure-devops-node-api/interfaces/common/VSSInterfaces
55
import {TestCaseResult} from 'azure-devops-node-api/interfaces/TestInterfaces';
66
import constants = require('./Common/constants');
77
import { getVstsWepApi } from './Common/ApiHelper';
8+
import { ciDictionary } from './Common/ciEventLogger';
89

910
export const personalAccessTokenRegexp = /^.{76}AZDO.{4}$/;
1011

@@ -22,7 +23,7 @@ export interface ManualTestRunData {
2223
runUrl: string;
2324
}
2425

25-
export async function getTestPlanData(): Promise<TestPlanData> {
26+
export async function getTestPlanData(ciData: ciDictionary): Promise<TestPlanData | null> {
2627

2728
const testPlanDataResponse: TestPlanData = {
2829
listOfFQNOfTestCases: [],
@@ -56,8 +57,10 @@ export async function getTestPlanData(): Promise<TestPlanData> {
5657
testPlanDataResponse.listOfAutomatedTestPoints = testPlanData.listOfAutomatedTestPoints;
5758
})
5859
.catch((error) => {
59-
tl.error("Error while fetching Test Plan Data :" + error);
60-
tl.setResult(tl.TaskResult.Failed, tl.loc('ErrorFailTaskOnAPIFailure'));
60+
ciData.returnCode = 1;
61+
ciData.errorMessage = error.message || String(error);
62+
ciData.taskErrorMessage = tl.loc('ErrorFailTaskOnAPIFailure');
63+
return null;
6164
});
6265

6366
return testPlanDataResponse;
@@ -91,24 +94,30 @@ export async function getTestPlanDataPoints(testPlanInputId: number, testSuitesI
9194

9295
do {
9396
try {
94-
let testCasesResponse = await getTestCaseListAsync(testPlanInputId, testSuiteId, testPlanConfigInputId.toString(), token);
97+
const testCasesResponse = await getTestCaseListAsync(testPlanInputId, testSuiteId, testPlanConfigInputId.toString(), token);
9598

96-
token = testCasesResponse.continuationToken;
99+
if(testCasesResponse === null){
100+
tl.debug("No respone while fetching Test cases List for test suite id: " + testSuiteId + " and test plan id: " + testPlanInputId
101+
+ " and test configuration id: " + testPlanConfigInputId + " with continuation token: " + token);
102+
break;
103+
}
97104

98-
for (let key in testCasesResponse) {
99-
if (testCasesResponse.hasOwnProperty(key)) {
100-
testCasesData.push(testCasesResponse[key]);
101-
}
105+
token = testCasesResponse.continuationToken;
106+
107+
for (let key in testCasesResponse) {
108+
if (testCasesResponse.hasOwnProperty(key)) {
109+
testCasesData.push(testCasesResponse[key]);
102110
}
111+
}
103112

104113
} catch (error) {
105-
tl.error("Error fetching test cases list:" + error);
114+
tl.debug("Error fetching test cases list: " + error);
106115
token = undefined;
107116
}
108-
} while ((token !== undefined) && (token !== null));
117+
} while (token);
109118

110119
if (testCasesData.length === 0) {
111-
console.log(`No test cases for test suite ${testSuiteId}`);
120+
console.log(`No test cases for test suite: ${testSuiteId} and test plan: ${testPlanInputId}`);
112121
continue;
113122
}
114123

@@ -171,12 +180,13 @@ export async function getTestPlanDataPoints(testPlanInputId: number, testSuitesI
171180
}
172181
}
173182
});
183+
tl.debug("Number of Automated Test point ids :" + testPlanData.listOfAutomatedTestPoints.length + " after fetching test cases for test suite id: " + testSuiteId);
184+
tl.debug("Number of Manual Test point ids :" + testPlanData.listOfManualTestPoints.length + " after fetching test cases for test suite id: " + testSuiteId);
174185

175186
}
176187

177-
console.log("Number of Automated Test point ids :", testPlanData.listOfAutomatedTestPoints.length);
178-
console.log("Number of Manual Test point ids :", testPlanData.listOfManualTestPoints.length);
179-
188+
console.log("Total number of Automated Test point ids :" + testPlanData.listOfAutomatedTestPoints.length);
189+
console.log("Total number of Manual Test point ids :" + testPlanData.listOfManualTestPoints.length);
180190
return testPlanData;
181191
}
182192

0 commit comments

Comments
 (0)