Skip to content

Commit bf30be5

Browse files
authored
[Multi-Region] Adding pipeline changes for Multi region load tests (#93) (#94)
* multi region changes * update version * Pr comments * compile ts
1 parent a74772c commit bf30be5

File tree

10 files changed

+265
-36
lines changed

10 files changed

+265
-36
lines changed

lib/constants.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ exports.defaultYaml = {
99
description: 'Load test website home page',
1010
testPlan: 'SampleTest.jmx',
1111
testType: 'JMX',
12-
engineInstances: 1,
12+
engineInstances: 2,
1313
subnetId: '/subscriptions/abcdef01-2345-6789-0abc-def012345678/resourceGroups/sample-rg/providers/Microsoft.Network/virtualNetworks/load-testing-vnet/subnets/load-testing',
1414
publicIPDisabled: false,
1515
configurationFiles: ['sampledata.csv'],
@@ -36,5 +36,15 @@ exports.defaultYaml = {
3636
],
3737
autoStop: { errorPercentage: 80, timeWindow: 60 },
3838
keyVaultReferenceIdentity: '/subscriptions/abcdef01-2345-6789-0abc-def012345678/resourceGroups/sample-rg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/sample-identity',
39-
keyVaultReferenceIdentityType: 'SystemAssigned'
39+
keyVaultReferenceIdentityType: 'SystemAssigned',
40+
regionalLoadTestConfig: [
41+
{
42+
region: 'eastus',
43+
engineInstances: 1,
44+
},
45+
{
46+
region: 'westus',
47+
engineInstances: 1,
48+
}
49+
]
4050
};

lib/main.js

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ function run() {
7575
}
7676
function getTestAPI(validate) {
7777
return __awaiter(this, void 0, void 0, function* () {
78-
var urlSuffix = "tests/" + testId + "?api-version=" + util.apiConstants.tm2023Version;
78+
var urlSuffix = "tests/" + testId + "?api-version=" + util.apiConstants.tm20240301previewVersion;
7979
urlSuffix = baseURL + urlSuffix;
8080
let header = yield map.getTestHeader();
8181
let testResult = yield util.httpClientRetries(urlSuffix, header, 'get', 3, "");
@@ -115,7 +115,7 @@ function getTestAPI(validate) {
115115
}
116116
function deleteFileAPI(filename) {
117117
return __awaiter(this, void 0, void 0, function* () {
118-
var urlSuffix = "tests/" + testId + "/files/" + filename + "?api-version=" + util.apiConstants.tm2023Version;
118+
var urlSuffix = "tests/" + testId + "/files/" + filename + "?api-version=" + util.apiConstants.tm20240301previewVersion;
119119
urlSuffix = baseURL + urlSuffix;
120120
let header = yield map.getTestHeader();
121121
let delFileResult = yield util.httpClientRetries(urlSuffix, header, 'del', 3, "");
@@ -128,7 +128,7 @@ function deleteFileAPI(filename) {
128128
}
129129
function createTestAPI() {
130130
return __awaiter(this, void 0, void 0, function* () {
131-
var urlSuffix = "tests/" + testId + "?api-version=" + util.apiConstants.tm2023Version;
131+
var urlSuffix = "tests/" + testId + "?api-version=" + util.apiConstants.tm20240301previewVersion;
132132
urlSuffix = baseURL + urlSuffix;
133133
var createData = map.createTestData();
134134
let header = yield map.createTestHeader();
@@ -191,7 +191,7 @@ function uploadTestPlan() {
191191
let retry = 5;
192192
let filepath = map.getTestFile();
193193
let filename = map.getFileName(filepath);
194-
var urlSuffix = "tests/" + testId + "/files/" + filename + "?api-version=" + util.apiConstants.tm2023Version;
194+
var urlSuffix = "tests/" + testId + "/files/" + filename + "?api-version=" + util.apiConstants.tm20240301previewVersion;
195195
if (map.getTestKind() == util_2.TestKind.URL) {
196196
urlSuffix = urlSuffix + ("&fileType=" + FileType.URL_TEST_CONFIG);
197197
}
@@ -238,7 +238,7 @@ function uploadConfigFile() {
238238
if (configFiles != undefined && configFiles.length > 0) {
239239
for (let filepath of configFiles) {
240240
let filename = map.getFileName(filepath);
241-
var urlSuffix = "tests/" + testId + "/files/" + filename + "?api-version=" + util.apiConstants.tm2023Version;
241+
var urlSuffix = "tests/" + testId + "/files/" + filename + "?api-version=" + util.apiConstants.tm20240301previewVersion;
242242
urlSuffix = baseURL + urlSuffix;
243243
let headers = yield map.UploadAndValidateHeader();
244244
let uploadresult = yield util.httpClientRetries(urlSuffix, headers, 'put', 3, filepath, true);
@@ -254,14 +254,14 @@ function uploadConfigFile() {
254254
});
255255
}
256256
function uploadZipArtifacts() {
257-
var _a;
258257
return __awaiter(this, void 0, void 0, function* () {
258+
var _a;
259259
let zipFiles = map.getZipFiles();
260260
if (zipFiles != undefined && zipFiles.length > 0) {
261261
console.log("Uploading and validating the zip artifacts");
262262
for (let filepath of zipFiles) {
263263
let filename = map.getFileName(filepath);
264-
var urlSuffix = "tests/" + testId + "/files/" + filename + "?api-version=" + util.apiConstants.tm2023Version + "&fileType=" + FileType.ZIPPED_ARTIFACTS;
264+
var urlSuffix = "tests/" + testId + "/files/" + filename + "?api-version=" + util.apiConstants.tm20240301previewVersion + "&fileType=" + FileType.ZIPPED_ARTIFACTS;
265265
urlSuffix = baseURL + urlSuffix;
266266
let headers = yield map.UploadAndValidateHeader();
267267
let uploadresult = yield util.httpClientRetries(urlSuffix, headers, 'put', 3, filepath, true);
@@ -278,7 +278,7 @@ function uploadZipArtifacts() {
278278
let zipInvalid = false;
279279
let zipFailureReason = "";
280280
while (maxAllowedTime > (new Date()) && flagValidationPending) {
281-
var urlSuffix = "tests/" + testId + "?api-version=" + util.apiConstants.tm2023Version;
281+
var urlSuffix = "tests/" + testId + "?api-version=" + util.apiConstants.tm20240301previewVersion;
282282
urlSuffix = baseURL + urlSuffix;
283283
let header = yield map.getTestHeader();
284284
let testResult = yield util.httpClientRetries(urlSuffix, header, 'get', 3, "");
@@ -324,7 +324,7 @@ function uploadPropertyFile() {
324324
let propertyFile = map.getPropertyFile();
325325
if (propertyFile != undefined) {
326326
let filename = map.getFileName(propertyFile);
327-
var urlSuffix = "tests/" + testId + "/files/" + filename + "?api-version=" + util.apiConstants.tm2023Version + "&fileType=" + FileType.USER_PROPERTIES;
327+
var urlSuffix = "tests/" + testId + "/files/" + filename + "?api-version=" + util.apiConstants.tm20240301previewVersion + "&fileType=" + FileType.USER_PROPERTIES;
328328
urlSuffix = baseURL + urlSuffix;
329329
let headers = yield map.UploadAndValidateHeader();
330330
let uploadresult = yield util.httpClientRetries(urlSuffix, headers, 'put', 3, propertyFile);
@@ -342,7 +342,7 @@ function createTestRun() {
342342
return __awaiter(this, void 0, void 0, function* () {
343343
const tenantId = map.getTenantId();
344344
const testRunId = util.getUniqueId();
345-
var urlSuffix = "test-runs/" + testRunId + "?tenantId=" + tenantId + "&api-version=" + util.apiConstants.tm2023Version;
345+
var urlSuffix = "test-runs/" + testRunId + "?tenantId=" + tenantId + "&api-version=" + util.apiConstants.tm20240301previewVersion;
346346
urlSuffix = baseURL + urlSuffix;
347347
const ltres = core.getInput('loadTestResource');
348348
const runDisplayName = core.getInput('loadTestRunName');
@@ -378,7 +378,7 @@ function createTestRun() {
378378
}
379379
function getTestRunAPI(testRunId, testStatus, startTime) {
380380
return __awaiter(this, void 0, void 0, function* () {
381-
var urlSuffix = "test-runs/" + testRunId + "?api-version=" + util.apiConstants.tm2023Version;
381+
var urlSuffix = "test-runs/" + testRunId + "?api-version=" + util.apiConstants.tm20240301previewVersion;
382382
urlSuffix = baseURL + urlSuffix;
383383
while (!util.isTerminalTestStatus(testStatus)) {
384384
let header = yield map.getTestRunHeader();

lib/mappers.js

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ var armEndpoint = "https://management.azure.com";
6262
var tenantId = "";
6363
var yamlFile = "";
6464
var passFailCriteria = [];
65+
var regionalLoadTestConfig = null;
6566
var autoStop = null;
6667
var kvRefId = null;
6768
var kvRefType = null;
@@ -70,6 +71,7 @@ var splitCSVs = null;
7071
var certificate = null;
7172
let kind;
7273
let publicIPDisabled = false;
74+
;
7375
var paramType;
7476
(function (paramType) {
7577
paramType["env"] = "env";
@@ -103,11 +105,12 @@ function createTestData() {
103105
testId: testId,
104106
description: testdesc,
105107
displayName: displayName,
106-
quickStartTest: false,
108+
quickStartTest: false, // always quick test will be false because GH-actions doesnot support it now.
107109
loadTestConfiguration: {
108110
engineInstances: engineInstances,
109111
splitAllCSVs: splitCSVs,
110-
optionalLoadTestConfig: null
112+
optionalLoadTestConfig: null,
113+
regionalLoadTestConfig: regionalLoadTestConfig,
111114
},
112115
secrets: secretsYaml,
113116
kind: kind,
@@ -209,8 +212,8 @@ function getResourceId() {
209212
}
210213
exports.getResourceId = getResourceId;
211214
function getInputParams() {
212-
var _a, _b, _c, _d;
213215
return __awaiter(this, void 0, void 0, function* () {
216+
var _a, _b, _c, _d;
214217
yield setEndpointAndScope();
215218
yield getAccessToken(armTokenScope);
216219
yamlFile = core.getInput("loadTestConfigFile");
@@ -296,6 +299,9 @@ function getInputParams() {
296299
kvRefType = "UserAssigned";
297300
kvRefId = config.keyVaultReferenceIdentity;
298301
}
302+
if (config.regionalLoadTestConfig != undefined) {
303+
regionalLoadTestConfig = getMultiRegionLoadTestConfig(config.regionalLoadTestConfig);
304+
}
299305
getRunTimeParams();
300306
validateTestRunParams();
301307
if (testId === "" ||
@@ -653,3 +659,14 @@ function getAutoStopCriteria(autoStopInput) {
653659
autoStop = data;
654660
}
655661
}
662+
function getMultiRegionLoadTestConfig(multiRegionalConfig) {
663+
let parsedMultiRegionConfiguration = [];
664+
multiRegionalConfig.forEach(regionConfig => {
665+
let data = {
666+
region: regionConfig.region,
667+
engineInstances: regionConfig.engineInstances,
668+
};
669+
parsedMultiRegionConfiguration.push(data);
670+
});
671+
return parsedMultiRegionConfiguration;
672+
}

lib/util.js

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ var TestKind;
5454
(function (TestKind) {
5555
TestKind["URL"] = "URL";
5656
TestKind["JMX"] = "JMX"; // default
57-
})(TestKind = exports.TestKind || (exports.TestKind = {}));
57+
})(TestKind || (exports.TestKind = TestKind = {}));
5858
const validConditionList = {
5959
'response_time_ms': ['>', '<'],
6060
'requests_per_sec': ['>', '<'],
@@ -64,15 +64,16 @@ const validConditionList = {
6464
};
6565
var apiConstants;
6666
(function (apiConstants) {
67+
apiConstants.tm20240301previewVersion = '2024-03-01-preview';
6768
apiConstants.tm2023Version = '2023-04-01-preview';
6869
apiConstants.tm2022Version = '2022-11-01';
6970
apiConstants.cp2022Version = '2022-12-01';
70-
})(apiConstants = exports.apiConstants || (exports.apiConstants = {}));
71+
})(apiConstants || (exports.apiConstants = apiConstants = {}));
7172
var ManagedIdentityType;
7273
(function (ManagedIdentityType) {
7374
ManagedIdentityType["SystemAssigned"] = "SystemAssigned";
7475
ManagedIdentityType["UserAssigned"] = "UserAssigned";
75-
})(ManagedIdentityType = exports.ManagedIdentityType || (exports.ManagedIdentityType = {}));
76+
})(ManagedIdentityType || (exports.ManagedIdentityType = ManagedIdentityType = {}));
7677
function uploadFileData(filepath) {
7778
try {
7879
let filedata = fs.readFileSync(filepath);
@@ -89,8 +90,8 @@ function uploadFileData(filepath) {
8990
}
9091
exports.uploadFileData = uploadFileData;
9192
const correlationHeader = 'x-ms-correlation-request-id';
92-
function httpClientRetries(urlSuffix, header, method, retries = 1, data, isUploadCall = true) {
93-
return __awaiter(this, void 0, void 0, function* () {
93+
function httpClientRetries(urlSuffix_1, header_1, method_1) {
94+
return __awaiter(this, arguments, void 0, function* (urlSuffix, header, method, retries = 1, data, isUploadCall = true) {
9495
let httpResponse;
9596
try {
9697
let correlationId = `gh-actions-${getUniqueId()}`;
@@ -226,8 +227,8 @@ function printClientMetrics(obj) {
226227
}
227228
exports.printClientMetrics = printClientMetrics;
228229
function getStatisticsFile(obj) {
229-
var obj;
230230
return __awaiter(this, void 0, void 0, function* () {
231+
var obj;
231232
let target = path.join('dropResults', "reports");
232233
try {
233234
var filepath = path.join('dropResults', 'results.zip');
@@ -321,7 +322,7 @@ function inValidEngineInstances(engines) {
321322
return false;
322323
}
323324
function checkValidityYaml(givenYaml) {
324-
var _a;
325+
var _a, _b;
325326
if (!isDictionary(givenYaml)) {
326327
return { valid: false, error: `Invalid YAML syntax.` };
327328
}
@@ -422,6 +423,28 @@ function checkValidityYaml(givenYaml) {
422423
return { valid: false, error: 'Invalid value for "autoStop", for disabling auto stop use "autoStop: disable"' };
423424
}
424425
}
426+
if (givenYaml.regionalLoadTestConfig) {
427+
if (!Array.isArray(givenYaml.regionalLoadTestConfig)) {
428+
return { valid: false, error: `The value "${givenYaml.regionalLoadTestConfig}" for regionalLoadTestConfig is invalid. Provide a valid list of region configuration for Multi-region load test.` };
429+
}
430+
if (givenYaml.regionalLoadTestConfig.length < 2) {
431+
return { valid: false, error: `Multi-region load tests should contain a minimum of 2 geographic regions in the configuration.` };
432+
}
433+
var totalEngineCount = 0;
434+
for (let i = 0; i < givenYaml.regionalLoadTestConfig.length; i++) {
435+
if ((0, util_1.isNullOrUndefined)(givenYaml.regionalLoadTestConfig[i].region) || typeof givenYaml.regionalLoadTestConfig[i].region != 'string' || givenYaml.regionalLoadTestConfig[i].region == "") {
436+
return { valid: false, error: `The value "${givenYaml.regionalLoadTestConfig[i].region}" for region in regionalLoadTestConfig is invalid. Provide a valid string.` };
437+
}
438+
if ((0, util_1.isNullOrUndefined)(givenYaml.regionalLoadTestConfig[i].engineInstances) || isNaN(givenYaml.regionalLoadTestConfig[i].engineInstances) || inValidEngineInstances(givenYaml.regionalLoadTestConfig[i].engineInstances)) {
439+
return { valid: false, error: `The value "${givenYaml.regionalLoadTestConfig[i].engineInstances}" for engineInstances in regionalLoadTestConfig is invalid. The value should be an integer between 1 and 400.` };
440+
}
441+
totalEngineCount += givenYaml.regionalLoadTestConfig[i].engineInstances;
442+
}
443+
let engineInstances = (_b = givenYaml.engineInstances) !== null && _b !== void 0 ? _b : 1;
444+
if (totalEngineCount != givenYaml.engineInstances) {
445+
return { valid: false, error: `The sum of engineInstances in regionalLoadTestConfig should be equal to the value of totalEngineInstances "${engineInstances}" in the test configuration.` };
446+
}
447+
}
425448
return { valid: true, error: "" };
426449
}
427450
exports.checkValidityYaml = checkValidityYaml;

src/constants.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export const defaultYaml : any =
77
description: 'Load test website home page',
88
testPlan: 'SampleTest.jmx',
99
testType: 'JMX',
10-
engineInstances: 1,
10+
engineInstances: 2,
1111
subnetId: '/subscriptions/abcdef01-2345-6789-0abc-def012345678/resourceGroups/sample-rg/providers/Microsoft.Network/virtualNetworks/load-testing-vnet/subnets/load-testing',
1212
publicIPDisabled: false,
1313
configurationFiles: [ 'sampledata.csv' ],
@@ -34,5 +34,15 @@ export const defaultYaml : any =
3434
],
3535
autoStop: { errorPercentage: 80, timeWindow: 60 },
3636
keyVaultReferenceIdentity: '/subscriptions/abcdef01-2345-6789-0abc-def012345678/resourceGroups/sample-rg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/sample-identity',
37-
keyVaultReferenceIdentityType: 'SystemAssigned'
37+
keyVaultReferenceIdentityType: 'SystemAssigned',
38+
regionalLoadTestConfig: [
39+
{
40+
region: 'eastus',
41+
engineInstances: 1,
42+
},
43+
{
44+
region: 'westus',
45+
engineInstances: 1,
46+
}
47+
]
3848
}

0 commit comments

Comments
 (0)