diff --git a/.github/workflows/pr_check_load_test.yml b/.github/workflows/pr_check_load_test.yml index 74dfe36d..52d62a74 100644 --- a/.github/workflows/pr_check_load_test.yml +++ b/.github/workflows/pr_check_load_test.yml @@ -64,6 +64,7 @@ jobs: node-version: '20' - name: Installing dependencies and building latest changes + if: github.ref == 'refs/heads/main' || (github.event_name == 'pull_request' && github.base_ref == 'main') run: | npm install --include=dev -f npm ci diff --git a/README.md b/README.md index ed104edf..d5062407 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,13 @@ For using any credentials like Azure Service Principal in your workflow, add the with: creds: ${{ secrets.AZURE_CREDENTIALS }} ``` - + +## Breaking changes + +All minor versions under `1.1` (e.g., `1.1.x`) will stop working due to a breaking change. +To ensure continued compatibility, we recommend switching to the `v1` tag, which we will continue to support. +We are also bumping the minor version to `1.2.1`. If you prefer to pin to a specific version, please update your workflows to use `1.2.1`. + ## Azure Load Testing Action This section describes the Azure Load Testing GitHub action. You can use this action by referencing `azure/load-testing@v1` action in your workflow. The action runs on Windows, Linux, and Mac runners. diff --git a/lib/Constants/EnvironmentConstants.js b/lib/Constants/EnvironmentConstants.js index e5779f87..9a591adc 100644 --- a/lib/Constants/EnvironmentConstants.js +++ b/lib/Constants/EnvironmentConstants.js @@ -1,14 +1,15 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AzureUSGovernmentCloud = exports.AzurePublicCloud = void 0; +const TaskParameters_1 = require("../models/TaskParameters"); exports.AzurePublicCloud = { cloudName: "AzureCloud", - armTokenScope: "https://management.core.windows.net", - dataPlaneTokenScope: "https://loadtest.azure-dev.com", + armTokenScope: TaskParameters_1.armPublicTokenScope, + dataPlaneTokenScope: TaskParameters_1.publicTokenScope, armEndpoint: "https://management.azure.com", }; exports.AzureUSGovernmentCloud = { cloudName: "AzureUSGovernment", - armTokenScope: "https://management.usgovcloudapi.net", - dataPlaneTokenScope: "https://cnt-prod.loadtesting.azure.us", + armTokenScope: TaskParameters_1.armUsGovernmentTokenScope, + dataPlaneTokenScope: TaskParameters_1.usGovernmentTokenScope, }; diff --git a/lib/Utils/AzCliUtility.js b/lib/Utils/AzCliUtility.js index 4c847803..2979d520 100644 --- a/lib/Utils/AzCliUtility.js +++ b/lib/Utils/AzCliUtility.js @@ -9,13 +9,27 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", { value: true }); -exports.execAz = void 0; +exports.getDPTokens = getDPTokens; +exports.getAccounts = getAccounts; const child_process_1 = require("child_process"); +function getDPTokens(tokenScope) { + return __awaiter(this, void 0, void 0, function* () { + const cmdArguments = ["account", "get-access-token", "--resource"]; + cmdArguments.push(tokenScope); + return execAz(cmdArguments); + }); +} +function getAccounts(accountType) { + return __awaiter(this, void 0, void 0, function* () { + const cmdArguments = accountType === 'Subscription' ? ["account", "show"] : ["cloud", "show"]; + return execAz(cmdArguments); + }); +} function execAz(cmdArguments) { return __awaiter(this, void 0, void 0, function* () { const azCmd = process.platform === "win32" ? "az.cmd" : "az"; return new Promise((resolve, reject) => { - (0, child_process_1.execFile)(azCmd, [...cmdArguments, "--out", "json"], { encoding: "utf8", shell: true }, (error, stdout) => { + (0, child_process_1.execFile)(azCmd, [...cmdArguments, "--out", "json"], { encoding: "utf8", shell: process.platform === "win32" }, (error, stdout) => { if (error) { return reject(error); } @@ -31,4 +45,3 @@ function execAz(cmdArguments) { }); }); } -exports.execAz = execAz; diff --git a/lib/Utils/FetchUtils.js b/lib/Utils/FetchUtils.js index 61bc19eb..b16ea1e4 100644 --- a/lib/Utils/FetchUtils.js +++ b/lib/Utils/FetchUtils.js @@ -47,11 +47,13 @@ const methodEnumToString = { [UtilModels_1.FetchCallType.patch]: "patch" }; // (note mohit): shift to the enum later. -function httpClientRetries(urlSuffix_1, header_1, method_1) { - return __awaiter(this, arguments, void 0, function* (urlSuffix, header, method, retries = 1, data, isUploadCall = true, log = true) { +function httpClientRetries(urlSuffix, header, method, retries = 1, data, isUploadCall = true, log = true) { + return __awaiter(this, void 0, void 0, function* () { let httpResponse; + const retrriableCodes = [408, 429, 500, 502, 503, 504]; // 408 - Request Timeout, 429 - Too Many Requests, 500 - Internal Server Error, 502 - Bad Gateway, 503 - Service Unavailable, 504 - Gateway Timeout + let backOffTimeForRetry = 5; // seconds + let correlationId = `gh-actions-${(0, CommonUtils_1.getUniqueId)()}`; try { - let correlationId = `gh-actions-${(0, CommonUtils_1.getUniqueId)()}`; header[UtilModels_1.correlationHeader] = correlationId; // even if we put console.debug its printing along with the logs, so lets just go ahead with the differentiation with azdo, so we can search the timeframe for azdo in correlationid and resource filter. if (method == UtilModels_1.FetchCallType.get) { httpResponse = yield httpClient.get(urlSuffix, header); @@ -79,7 +81,10 @@ function httpClientRetries(urlSuffix_1, header_1, method_1) { if (httpResponse.message.statusCode != undefined && httpResponse.message.statusCode >= 300) { CoreUtils.debug(`correlation id : ${correlationId}`); } - if (httpResponse.message.statusCode != undefined && [408, 429, 502, 503, 504].includes(httpResponse.message.statusCode)) { + if (httpResponse.message.statusCode != undefined && retrriableCodes.includes(httpResponse.message.statusCode)) { + if (method == UtilModels_1.FetchCallType.patch) { + backOffTimeForRetry += 60; // extra 60 seconds for patch, basically this happens when the service didnot handle some of the external service dependencies, and the external can take time to recover. + } let err = yield (0, CommonUtils_1.getResultObj)(httpResponse); throw { message: (err && err.error && err.error.message) ? err.error.message : (0, CommonUtils_1.errorCorrection)(httpResponse) }; // throwing as message to catch it as err.message } @@ -87,7 +92,7 @@ function httpClientRetries(urlSuffix_1, header_1, method_1) { } catch (err) { if (retries) { - let sleeptime = (5 - retries) * 1000 + Math.floor(Math.random() * 5001); + let sleeptime = backOffTimeForRetry * 1000; if (log) { console.log(`Failed to connect to ${urlSuffix} due to ${err.message}, retrying in ${sleeptime / 1000} seconds`); } @@ -95,6 +100,7 @@ function httpClientRetries(urlSuffix_1, header_1, method_1) { return yield httpClientRetries(urlSuffix, header, method, retries - 1, data); } else { + console.log(err, "\ncorrelationId:" + correlationId); throw new Error(`Operation did not succeed after 3 retries. Pipeline failed with error : ${err.message}`); } } diff --git a/lib/Utils/TaskParametersUtil.js b/lib/Utils/TaskParametersUtil.js index bee71920..f11a3e66 100644 --- a/lib/Utils/TaskParametersUtil.js +++ b/lib/Utils/TaskParametersUtil.js @@ -15,13 +15,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? ( }) : function(o, v) { o["default"] = v; }); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -73,8 +83,7 @@ class TaskParametersUtil { static setSubscriptionParameters(taskParameters) { return __awaiter(this, void 0, void 0, function* () { try { - const cmdArguments = ["account", "show"]; - var result = yield AzCliUtility.execAz(cmdArguments); + var result = yield AzCliUtility.getAccounts('Subscription'); taskParameters.subscriptionId = result.id; taskParameters.subscriptionName = result.name; } @@ -88,8 +97,7 @@ class TaskParametersUtil { static setEndpointAndScopeParameters(taskParameters) { return __awaiter(this, void 0, void 0, function* () { try { - const cmdArguments = ["cloud", "show"]; - var result = yield AzCliUtility.execAz(cmdArguments); + var result = yield AzCliUtility.getAccounts('Cloud'); let env = result ? result.name : null; taskParameters.environment = env !== null && env !== void 0 ? env : EnvironmentConstants.AzurePublicCloud.cloudName; let endpointUrl = (result && result.endpoints) ? result.endpoints.resourceManager : null; diff --git a/lib/models/TaskParameters.js b/lib/models/TaskParameters.js index c8ad2e54..a3d8e6a6 100644 --- a/lib/models/TaskParameters.js +++ b/lib/models/TaskParameters.js @@ -1,2 +1,7 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); +exports.armUsGovernmentTokenScope = exports.armPublicTokenScope = exports.usGovernmentTokenScope = exports.publicTokenScope = void 0; +exports.publicTokenScope = "https://cnt-prod.loadtesting.azure.com"; +exports.usGovernmentTokenScope = "https://cnt-prod.loadtesting.azure.us"; +exports.armPublicTokenScope = "https://management.core.windows.net"; +exports.armUsGovernmentTokenScope = "https://management.usgovcloudapi.net"; diff --git a/lib/services/AuthenticatorService.js b/lib/services/AuthenticatorService.js index 679d8411..c3b44569 100644 --- a/lib/services/AuthenticatorService.js +++ b/lib/services/AuthenticatorService.js @@ -15,13 +15,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? ( }) : function(o, v) { o["default"] = v; }); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -71,9 +81,7 @@ class AuthenticatorService { return __awaiter(this, void 0, void 0, function* () { let tokenScopeDecoded = scope == UtilModels_1.TokenScope.Dataplane ? this.taskParameters.dataPlaneTokenScope : this.taskParameters.armTokenScope; try { - const cmdArguments = ["account", "get-access-token", "--resource"]; - cmdArguments.push(tokenScopeDecoded); - let result = yield AzCliUtility.execAz(cmdArguments); + let result = yield AzCliUtility.getDPTokens(tokenScopeDecoded); let token = result.accessToken; scope == UtilModels_1.TokenScope.ControlPlane ? this.controlPlaneToken = token : this.dataPlanetoken = token; return token; diff --git a/src/Constants/EnvironmentConstants.ts b/src/Constants/EnvironmentConstants.ts index 7a7e33bf..3f17a2b5 100644 --- a/src/Constants/EnvironmentConstants.ts +++ b/src/Constants/EnvironmentConstants.ts @@ -1,19 +1,21 @@ +import { ControlPlaneTokenScope, DataPlaneTokenScope, publicTokenScope, usGovernmentTokenScope, armUsGovernmentTokenScope, armPublicTokenScope } from "../models/TaskParameters"; + type EnvironmentSettings = { cloudName: string; - armTokenScope: string; - dataPlaneTokenScope: string; + armTokenScope: ControlPlaneTokenScope; + dataPlaneTokenScope: DataPlaneTokenScope; armEndpoint?: string; } export const AzurePublicCloud: EnvironmentSettings = { cloudName: "AzureCloud", - armTokenScope: "https://management.core.windows.net", - dataPlaneTokenScope: "https://loadtest.azure-dev.com", + armTokenScope: armPublicTokenScope, + dataPlaneTokenScope: publicTokenScope, armEndpoint: "https://management.azure.com", } export const AzureUSGovernmentCloud: EnvironmentSettings = { cloudName: "AzureUSGovernment", - armTokenScope: "https://management.usgovcloudapi.net", - dataPlaneTokenScope: "https://cnt-prod.loadtesting.azure.us", -} \ No newline at end of file + armTokenScope: armUsGovernmentTokenScope, + dataPlaneTokenScope: usGovernmentTokenScope, +} diff --git a/src/Utils/AzCliUtility.ts b/src/Utils/AzCliUtility.ts index 016d3a35..eeeacf9c 100644 --- a/src/Utils/AzCliUtility.ts +++ b/src/Utils/AzCliUtility.ts @@ -1,9 +1,21 @@ import { execFile } from "child_process"; +import { AccountType, ControlPlaneTokenScope, DataPlaneTokenScope } from "../models/TaskParameters"; -export async function execAz(cmdArguments: string[]): Promise { +export async function getDPTokens(tokenScope: ControlPlaneTokenScope| DataPlaneTokenScope): Promise { + const cmdArguments = ["account", "get-access-token", "--resource"]; + cmdArguments.push(tokenScope); + return execAz(cmdArguments); +} + +export async function getAccounts(accountType: AccountType): Promise { + const cmdArguments = accountType === 'Subscription' ? ["account", "show"] : ["cloud", "show"]; + return execAz(cmdArguments); +} + +async function execAz(cmdArguments: string[]): Promise { const azCmd = process.platform === "win32" ? "az.cmd" : "az"; return new Promise((resolve, reject) => { - execFile(azCmd, [...cmdArguments, "--out", "json"], { encoding: "utf8", shell : true }, (error:any, stdout:any) => { + execFile(azCmd, [...cmdArguments, "--out", "json"], { encoding: "utf8", shell : process.platform === "win32" }, (error:any, stdout:any) => { if (error) { return reject(error); } @@ -17,4 +29,4 @@ export async function execAz(cmdArguments: string[]): Promise { } }); }); -} \ No newline at end of file +} diff --git a/src/Utils/FetchUtils.ts b/src/Utils/FetchUtils.ts index 373427f3..41501724 100644 --- a/src/Utils/FetchUtils.ts +++ b/src/Utils/FetchUtils.ts @@ -17,8 +17,10 @@ const methodEnumToString : { [key in FetchCallType] : string } = { // (note mohit): shift to the enum later. export async function httpClientRetries(urlSuffix : string, header : IHeaders, method : FetchCallType , retries : number = 1, data : string , isUploadCall : boolean = true, log: boolean = true) : Promise{ let httpResponse : IHttpClientResponse; + const retrriableCodes = [408,429,500,502,503,504]; // 408 - Request Timeout, 429 - Too Many Requests, 500 - Internal Server Error, 502 - Bad Gateway, 503 - Service Unavailable, 504 - Gateway Timeout + let backOffTimeForRetry = 5; // seconds + let correlationId = `gh-actions-${getUniqueId()}`; try { - let correlationId = `gh-actions-${getUniqueId()}`; header[correlationHeader] = correlationId; // even if we put console.debug its printing along with the logs, so lets just go ahead with the differentiation with azdo, so we can search the timeframe for azdo in correlationid and resource filter. if(method == FetchCallType.get){ httpResponse = await httpClient.get(urlSuffix, header); @@ -45,7 +47,10 @@ export async function httpClientRetries(urlSuffix : string, header : IHeaders, m if(httpResponse.message.statusCode!= undefined && httpResponse.message.statusCode >= 300){ CoreUtils.debug(`correlation id : ${correlationId}`); } - if(httpResponse.message.statusCode!=undefined && [408,429,502,503,504].includes(httpResponse.message.statusCode)){ + if(httpResponse.message.statusCode!=undefined && retrriableCodes.includes(httpResponse.message.statusCode)){ + if(method == FetchCallType.patch){ + backOffTimeForRetry += 60; // extra 60 seconds for patch, basically this happens when the service didnot handle some of the external service dependencies, and the external can take time to recover. + } let err = await getResultObj(httpResponse); throw {message : (err && err.error && err.error.message) ? err.error.message : errorCorrection(httpResponse)}; // throwing as message to catch it as err.message } @@ -53,7 +58,7 @@ export async function httpClientRetries(urlSuffix : string, header : IHeaders, m } catch(err:any){ if(retries){ - let sleeptime = (5-retries)*1000 + Math.floor(Math.random() * 5001); + let sleeptime = backOffTimeForRetry * 1000; if (log) { console.log(`Failed to connect to ${urlSuffix} due to ${err.message}, retrying in ${sleeptime/1000} seconds`); } @@ -61,7 +66,8 @@ export async function httpClientRetries(urlSuffix : string, header : IHeaders, m return await httpClientRetries(urlSuffix,header,method,retries-1,data); } else{ + console.log(err, "\ncorrelationId:" + correlationId); throw new Error(`Operation did not succeed after 3 retries. Pipeline failed with error : ${err.message}`); } } -} \ No newline at end of file +} diff --git a/src/Utils/TaskParametersUtil.ts b/src/Utils/TaskParametersUtil.ts index 808cda52..9bf898fe 100644 --- a/src/Utils/TaskParametersUtil.ts +++ b/src/Utils/TaskParametersUtil.ts @@ -43,8 +43,7 @@ export class TaskParametersUtil { private static async setSubscriptionParameters(taskParameters: TaskParameters) { try { - const cmdArguments = ["account", "show"]; - var result: any = await AzCliUtility.execAz(cmdArguments); + var result: any = await AzCliUtility.getAccounts('Subscription'); taskParameters.subscriptionId = result.id; taskParameters.subscriptionName = result.name; @@ -60,8 +59,7 @@ export class TaskParametersUtil { private static async setEndpointAndScopeParameters(taskParameters: TaskParameters) { try { - const cmdArguments = ["cloud", "show"]; - var result: any = await AzCliUtility.execAz(cmdArguments); + var result: any = await AzCliUtility.getAccounts('Cloud'); let env = result ? result.name : null; taskParameters.environment = env ?? EnvironmentConstants.AzurePublicCloud.cloudName; @@ -80,4 +78,4 @@ export class TaskParametersUtil { throw new Error(message); } } -} \ No newline at end of file +} diff --git a/src/models/TaskParameters.ts b/src/models/TaskParameters.ts index 27e954f5..fbde7490 100644 --- a/src/models/TaskParameters.ts +++ b/src/models/TaskParameters.ts @@ -1,9 +1,18 @@ +export const publicTokenScope = "https://cnt-prod.loadtesting.azure.com"; +export const usGovernmentTokenScope = "https://cnt-prod.loadtesting.azure.us"; +export const armPublicTokenScope = "https://management.core.windows.net"; +export const armUsGovernmentTokenScope = "https://management.usgovcloudapi.net"; +export type ControlPlaneTokenScope = typeof armPublicTokenScope | typeof armUsGovernmentTokenScope; +export type DataPlaneTokenScope = typeof publicTokenScope | typeof usGovernmentTokenScope; + +export type AccountType = 'Subscription' | 'Cloud'; // cloud is what the service principal logged into, should be only 1. + export interface TaskParameters { subscriptionId: string; subscriptionName: string; environment: string; - armTokenScope: string; - dataPlaneTokenScope: string; + armTokenScope: ControlPlaneTokenScope; + dataPlaneTokenScope: DataPlaneTokenScope; resourceId: string; armEndpoint?: string; -} \ No newline at end of file +} diff --git a/src/services/AuthenticatorService.ts b/src/services/AuthenticatorService.ts index 57e5f49b..ed615fb2 100644 --- a/src/services/AuthenticatorService.ts +++ b/src/services/AuthenticatorService.ts @@ -41,9 +41,7 @@ export class AuthenticatorService { { let tokenScopeDecoded = scope == TokenScope.Dataplane ? this.taskParameters.dataPlaneTokenScope : this.taskParameters.armTokenScope; try { - const cmdArguments = ["account", "get-access-token", "--resource"]; - cmdArguments.push(tokenScopeDecoded); - let result: any = await AzCliUtility.execAz(cmdArguments); + let result: any = await AzCliUtility.getDPTokens(tokenScopeDecoded); let token = result.accessToken; scope == TokenScope.ControlPlane ? this.controlPlaneToken = token : this.dataPlanetoken = token; return token; @@ -66,4 +64,4 @@ export class AuthenticatorService { console.log("Error in getting the token"); } } -} \ No newline at end of file +} diff --git a/test/Utils/TestSupport.ts b/test/Utils/TestSupport.ts index 07274e6e..04c875b3 100644 --- a/test/Utils/TestSupport.ts +++ b/test/Utils/TestSupport.ts @@ -18,7 +18,7 @@ export class TestSupport { } public static setupMockForPostProcess(isTestRunCompleted: boolean = false) { - let stub = sinon.stub(AzCliUtility, "execAz"); + let stub = sinon.stub(AzCliUtility, "getAccounts"); let cloudShowResult = { name: EnvironmentConstants.AzurePublicCloud.cloudName, endpoints: { diff --git a/test/apiService.test.ts b/test/apiService.test.ts index 6cf89cf6..805aa66d 100644 --- a/test/apiService.test.ts +++ b/test/apiService.test.ts @@ -146,7 +146,7 @@ describe('api service tests', () => { await expect(apiService.deleteFileAPI("samplefile.jmx")).rejects.toThrow(); expect(authenticatorServiceMock.getDataPlaneHeaderCalled()).toBe(true); expect(authenticatorServiceMock.getARMTokenHeaderCalled()).toBe(false); - }); + }, 40000); it("createTestAPI returns resp on 201", async () => { let testId = "testid1"; @@ -306,4 +306,4 @@ describe('api service tests', () => { expect(authenticatorServiceMock.getDataPlaneHeaderCalled()).toBe(true); expect(authenticatorServiceMock.getARMTokenHeaderCalled()).toBe(false); }); -}) \ No newline at end of file +}) diff --git a/test/authenticatorService.test.ts b/test/authenticatorService.test.ts index 0da2002d..3977c6f8 100644 --- a/test/authenticatorService.test.ts +++ b/test/authenticatorService.test.ts @@ -18,12 +18,12 @@ describe('authenticator service tests', () => { let tokenResult = { accessToken: "token" }; - let stub = sinon.stub(AzCliUtility, "execAz").withArgs(["account", "get-access-token", "--resource", Constants.defaultTaskParameters.dataPlaneTokenScope]).resolves(tokenResult); + let stub = sinon.stub(AzCliUtility, "getDPTokens").withArgs(Constants.defaultTaskParameters.dataPlaneTokenScope).resolves(tokenResult); let authenticatorService = new AuthenticatorService(Constants.defaultTaskParameters); let result = await authenticatorService.getDataPlaneHeader(FetchCallType.get); - expect(stub.calledWith(["account", "get-access-token", "--resource", Constants.defaultTaskParameters.dataPlaneTokenScope])).toBe(true); + expect(stub.calledWith(Constants.defaultTaskParameters.dataPlaneTokenScope)).toBe(true); expect(result).toHaveProperty("Authorization"); }); @@ -31,13 +31,13 @@ describe('authenticator service tests', () => { let tokenResult = { accessToken: "token" }; - let stub = sinon.stub(AzCliUtility, "execAz").withArgs(["account", "get-access-token", "--resource", Constants.defaultTaskParameters.armTokenScope]).resolves(tokenResult); + let stub = sinon.stub(AzCliUtility, "getDPTokens").withArgs(Constants.defaultTaskParameters.armTokenScope).resolves(tokenResult); let authenticatorService = new AuthenticatorService(Constants.defaultTaskParameters); let result = await authenticatorService.getARMTokenHeader(); - expect(stub.calledWith(["account", "get-access-token", "--resource", Constants.defaultTaskParameters.armTokenScope])).toBe(true); + expect(stub.calledWith(Constants.defaultTaskParameters.armTokenScope)).toBe(true); expect(result).toHaveProperty("Authorization"); }); -}) \ No newline at end of file +}) diff --git a/test/taskParameters.test.ts b/test/taskParameters.test.ts index 836f708b..1c52f46d 100644 --- a/test/taskParameters.test.ts +++ b/test/taskParameters.test.ts @@ -21,7 +21,7 @@ describe('task parameters tests', () => { }); it("sets inputs for public cloud", async () => { - let stub = sinon.stub(AzCliUtility, "execAz"); + let stub = sinon.stub(AzCliUtility, "getAccounts"); let accountShowResult = { name: "fakeSubscriptionName", id: Constants.loadtestConfig.subscriptionId, @@ -38,8 +38,8 @@ describe('task parameters tests', () => { let taskParameters = await TaskParametersUtil.getTaskParameters(); - expect(stub.calledWith(["account", "show"])).toBe(true); - expect(stub.calledWith(["cloud", "show"])).toBe(true); + expect(stub.calledWith('Subscription')).toBe(true); + expect(stub.calledWith('Cloud')).toBe(true); expect(taskParameters.resourceId.toLowerCase()).toBe(Constants.loadtestResourceId.toLowerCase()); expect(taskParameters.subscriptionId).toBe(Constants.loadtestConfig.subscriptionId); expect(taskParameters.subscriptionName).toBe("fakeSubscriptionName"); @@ -50,7 +50,7 @@ describe('task parameters tests', () => { }); it("sets inputs for gov cloud", async () => { - let stub = sinon.stub(AzCliUtility, "execAz"); + let stub = sinon.stub(AzCliUtility, "getAccounts"); let accountShowResult = { name: "fakeSubscriptionName", id: Constants.loadtestConfig.subscriptionId, @@ -67,8 +67,8 @@ describe('task parameters tests', () => { let taskParameters = await TaskParametersUtil.getTaskParameters(); - expect(stub.calledWith(["account", "show"])).toBe(true); - expect(stub.calledWith(["cloud", "show"])).toBe(true); + expect(stub.calledWith('Subscription')).toBe(true); + expect(stub.calledWith('Cloud')).toBe(true); expect(taskParameters.resourceId.toLowerCase()).toBe(Constants.loadtestResourceId.toLowerCase()); expect(taskParameters.subscriptionId).toBe(Constants.loadtestConfig.subscriptionId); expect(taskParameters.subscriptionName).toBe("fakeSubscriptionName"); @@ -79,7 +79,7 @@ describe('task parameters tests', () => { }); it("sets inputs for gov cloud with different case", async () => { - let stub = sinon.stub(AzCliUtility, "execAz"); + let stub = sinon.stub(AzCliUtility, "getAccounts"); let accountShowResult = { name: "fakeSubscriptionName", id: Constants.loadtestConfig.subscriptionId, @@ -96,8 +96,8 @@ describe('task parameters tests', () => { let taskParameters = await TaskParametersUtil.getTaskParameters(); - expect(stub.calledWith(["account", "show"])).toBe(true); - expect(stub.calledWith(["cloud", "show"])).toBe(true); + expect(stub.calledWith('Subscription')).toBe(true); + expect(stub.calledWith('Cloud')).toBe(true); expect(taskParameters.resourceId.toLowerCase()).toBe(Constants.loadtestResourceId.toLowerCase()); expect(taskParameters.subscriptionId).toBe(Constants.loadtestConfig.subscriptionId); expect(taskParameters.subscriptionName).toBe("fakeSubscriptionName"); @@ -108,7 +108,7 @@ describe('task parameters tests', () => { }); it("does not set resource id for postprocess", async () => { - let stub = sinon.stub(AzCliUtility, "execAz"); + let stub = sinon.stub(AzCliUtility, "getAccounts"); let cloudShowResult = { name: EnvironmentConstants.AzurePublicCloud.cloudName, endpoints: { @@ -120,8 +120,8 @@ describe('task parameters tests', () => { let taskParameters = await TaskParametersUtil.getTaskParameters(true); - expect(stub.calledWith(["account", "show"])).toBe(false); - expect(stub.calledWith(["cloud", "show"])).toBe(true); + expect(stub.calledWith('Subscription')).toBe(false); + expect(stub.calledWith('Cloud')).toBe(true); expect(taskParameters.resourceId).toBe(''); expect(taskParameters.subscriptionId).toBe(''); expect(taskParameters.subscriptionName).toBe(''); @@ -132,7 +132,7 @@ describe('task parameters tests', () => { }); it("az cli cloud show error throws error", async () => { - let stub = sinon.stub(AzCliUtility, "execAz"); + let stub = sinon.stub(AzCliUtility, "getAccounts"); let accountShowResult = { name: "fakeSubscriptionName", id: Constants.loadtestConfig.subscriptionId, @@ -145,14 +145,14 @@ describe('task parameters tests', () => { }); it("az cli account show error throws error", async () => { - let accountShowStub = sinon.stub(AzCliUtility, "execAz").withArgs(["account", "show"]).rejects(new Error("Error")); + let accountShowStub = sinon.stub(AzCliUtility, "getAccounts").withArgs('Subscription').rejects(new Error("Error")); expect(async () => await TaskParametersUtil.getTaskParameters()).rejects.toThrow(`Azure CLI for getting subscription name`); expect(accountShowStub.calledOnce).toBe(true); }); it("missing resource group throws error", async () => { - let stub = sinon.stub(AzCliUtility, "execAz"); + let stub = sinon.stub(AzCliUtility, "getAccounts"); let accountShowResult = { name: "fakeSubscriptionName", id: Constants.loadtestConfig.subscriptionId, @@ -164,7 +164,7 @@ describe('task parameters tests', () => { }); it("missing load test resource throws error", async () => { - let stub = sinon.stub(AzCliUtility, "execAz"); + let stub = sinon.stub(AzCliUtility, "getAccounts"); let accountShowResult = { name: "fakeSubscriptionName", id: Constants.loadtestConfig.subscriptionId,