Improve LRO polling (#922)
* add validation for final state via * add validation for azure async operation * fix comment * add live validation for LRO final get * fix comments * fix comment * add more ARM validation * update post man rule generation * improve postman assertion * fix test * Azure-AsyncOperation is prior * fix print detail response log * fix lint error * fix baseUri * update snapshot * generate examples for LRO final get * fix lint error * update change log * update package lock --------- Co-authored-by: jianyexi <jianyxi@microsoft.com> Co-authored-by: Lei Ni <7233663+leni-msft@users.noreply.github.com>
This commit is contained in:
Родитель
a993efe883
Коммит
34676f38e4
|
@ -1,5 +1,12 @@
|
|||
# Change Log - oav
|
||||
|
||||
## 02/23/2023 3.2.6
|
||||
|
||||
- Improved the API scenario long running operation pooling mechanism.
|
||||
- support for checking final-via-state
|
||||
- update the mechanism of gettig the lro polling url.
|
||||
- Support generating the ARM rules for api scenario.
|
||||
|
||||
## 02/19/2023 3.2.6
|
||||
|
||||
- LiveValidator - logging INVALID_TYPE error for additionalProperties for RpaaS call
|
||||
|
|
|
@ -154,6 +154,8 @@ const stepIsFatal = (sr: StepResult) => sr.runtimeError && sr.runtimeError.lengt
|
|||
const stepIsFailed = (sr: StepResult) =>
|
||||
(sr.liveValidationResult && sr.liveValidationResult.requestValidationResult.errors.length > 0) ||
|
||||
(sr.liveValidationResult && sr.liveValidationResult.responseValidationResult.errors.length > 0) ||
|
||||
(sr.liveValidationForLroFinalGetResult &&
|
||||
sr.liveValidationForLroFinalGetResult.responseValidationResult.errors.length > 0) ||
|
||||
(sr.roundtripValidationResult && sr.roundtripValidationResult.errors.length > 0);
|
||||
|
||||
const asMarkdownStepResult = (sr: StepResult): ApiScenarioMarkdownStepResult => {
|
||||
|
@ -167,6 +169,9 @@ const asMarkdownStepResult = (sr: StepResult): ApiScenarioMarkdownStepResult =>
|
|||
const failedErrorsCount =
|
||||
(sr.liveValidationResult ? sr.liveValidationResult.requestValidationResult.errors.length : 0) +
|
||||
(sr.liveValidationResult ? sr.liveValidationResult.responseValidationResult.errors.length : 0) +
|
||||
(sr.liveValidationForLroFinalGetResult
|
||||
? sr.liveValidationForLroFinalGetResult.responseValidationResult.errors.length
|
||||
: 0) +
|
||||
(sr.roundtripValidationResult ? sr.roundtripValidationResult.errors.length : 0);
|
||||
|
||||
const r: ApiScenarioMarkdownStepResult = {
|
||||
|
|
|
@ -60,6 +60,7 @@ export interface StepResult {
|
|||
runtimeError?: RuntimeError[];
|
||||
liveValidationResult?: RequestResponseLiveValidationResult;
|
||||
roundtripValidationResult?: LiveValidationResult;
|
||||
liveValidationForLroFinalGetResult?: RequestResponseLiveValidationResult;
|
||||
}
|
||||
|
||||
export interface RuntimeError {
|
||||
|
@ -173,14 +174,34 @@ export class NewmanReportValidator {
|
|||
}
|
||||
|
||||
const payload = this.convertToLiveValidationPayload(it);
|
||||
let lroFinalPayLoad;
|
||||
|
||||
// associate final get response to the
|
||||
if (it.annotation.type === "LRO" && [200, 201, 202].includes(it.response.statusCode)) {
|
||||
const lroFinalGetExecution = this.getLROFinalResponse(
|
||||
newmanReport.executions,
|
||||
it.annotation.step
|
||||
);
|
||||
if (lroFinalGetExecution?.response.statusCode === 200) {
|
||||
lroFinalPayLoad = this.convertToLROLiveValidationPayload(it, lroFinalGetExecution);
|
||||
}
|
||||
}
|
||||
|
||||
let payloadFilePath;
|
||||
let lroPayloadFilePath;
|
||||
if (this.opts.savePayload) {
|
||||
payloadFilePath = `./payloads/${it.annotation.itemName}.json`;
|
||||
await this.fileLoader.writeFile(
|
||||
path.resolve(path.dirname(this.opts.reportOutputFilePath), payloadFilePath),
|
||||
JSON.stringify(payload, null, 2)
|
||||
);
|
||||
if (lroFinalPayLoad) {
|
||||
lroPayloadFilePath = `./payloads/${it.annotation.itemName}-finalResult.json`;
|
||||
await this.fileLoader.writeFile(
|
||||
path.resolve(path.dirname(this.opts.reportOutputFilePath), lroPayloadFilePath),
|
||||
JSON.stringify(lroFinalPayLoad, null, 2)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const matchedStep = this.getMatchedStep(it.annotation.step);
|
||||
|
@ -207,24 +228,38 @@ export class NewmanReportValidator {
|
|||
|
||||
let liveValidationResult = undefined;
|
||||
let roundtripValidationResult = undefined;
|
||||
let liveValidationForLroFinalGetResult = undefined;
|
||||
let specFilePath = undefined;
|
||||
if (matchedStep.type === "restCall" && !matchedStep.externalReference) {
|
||||
if (this.opts.generateExample) {
|
||||
const statusCode = `${it.response.statusCode}`;
|
||||
let statusCodes = {
|
||||
[statusCode]: {
|
||||
headers: payload.liveResponse.headers,
|
||||
body: payload.liveResponse.body,
|
||||
},
|
||||
};
|
||||
if (lroFinalPayLoad) {
|
||||
const statusCode = lroFinalPayLoad.liveResponse.statusCode;
|
||||
statusCodes[statusCode] = {
|
||||
headers: lroFinalPayLoad.liveResponse.headers,
|
||||
body: lroFinalPayLoad.liveResponse.body,
|
||||
};
|
||||
}
|
||||
|
||||
const generatedExample: SwaggerExample = {
|
||||
operationId: matchedStep.operationId,
|
||||
title: matchedStep.step,
|
||||
description: matchedStep.description,
|
||||
parameters: matchedStep._resolvedParameters!,
|
||||
responses: {
|
||||
[statusCode]: {
|
||||
headers: payload.liveResponse.headers,
|
||||
body: payload.liveResponse.body,
|
||||
},
|
||||
...statusCodes,
|
||||
},
|
||||
};
|
||||
|
||||
const exampleFilePath = `./examples/${matchedStep.operationId}_${statusCode}.json`;
|
||||
const exampleFilePath = `./examples/${matchedStep.operationId}_${Object.keys(
|
||||
statusCodes
|
||||
).join("_")}.json`;
|
||||
await this.fileLoader.writeFile(
|
||||
path.resolve(path.dirname(this.opts.reportOutputFilePath), exampleFilePath),
|
||||
JSON.stringify(generatedExample, null, 2)
|
||||
|
@ -236,6 +271,11 @@ export class NewmanReportValidator {
|
|||
? await this.liveValidator.validateLiveRequestResponse(payload)
|
||||
: undefined;
|
||||
|
||||
liveValidationForLroFinalGetResult =
|
||||
!this.opts.skipValidation && lroFinalPayLoad && matchedStep.isManagementPlane
|
||||
? await this.liveValidator.validateLiveRequestResponse(lroFinalPayLoad)
|
||||
: undefined;
|
||||
|
||||
// // Roundtrip validation
|
||||
// if (
|
||||
// !this.opts.skipValidation &&
|
||||
|
@ -271,6 +311,7 @@ export class NewmanReportValidator {
|
|||
stepName: it.annotation.step,
|
||||
liveValidationResult,
|
||||
roundtripValidationResult,
|
||||
liveValidationForLroFinalGetResult,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -295,28 +336,28 @@ export class NewmanReportValidator {
|
|||
};
|
||||
}
|
||||
|
||||
// private convertToLROLiveValidationPayload(
|
||||
// putReq: NewmanExecution,
|
||||
// getReq: NewmanExecution
|
||||
// ): RequestResponsePair {
|
||||
// const request = putReq.request;
|
||||
// const response = getReq.response;
|
||||
// const liveRequest: LiveRequest = {
|
||||
// url: request.url,
|
||||
// method: request.method.toLowerCase(),
|
||||
// headers: request.headers,
|
||||
// body: this.parseBody(request.body),
|
||||
// };
|
||||
// const liveResponse: LiveResponse = {
|
||||
// statusCode: `${response.statusCode}`,
|
||||
// headers: response.headers,
|
||||
// body: this.parseBody(response.body),
|
||||
// };
|
||||
// return {
|
||||
// liveRequest,
|
||||
// liveResponse,
|
||||
// };
|
||||
// }
|
||||
private convertToLROLiveValidationPayload(
|
||||
putReq: NewmanExecution,
|
||||
getReq: NewmanExecution
|
||||
): RequestResponsePair {
|
||||
const request = putReq.request;
|
||||
const response = getReq.response;
|
||||
const liveRequest: LiveRequest = {
|
||||
url: request.url,
|
||||
method: request.method.toLowerCase(),
|
||||
headers: request.headers,
|
||||
body: this.parseBody(request.body),
|
||||
};
|
||||
const liveResponse: LiveResponse = {
|
||||
statusCode: `${response.statusCode}`,
|
||||
headers: response.headers,
|
||||
body: this.parseBody(response.body),
|
||||
};
|
||||
return {
|
||||
liveRequest,
|
||||
liveResponse,
|
||||
};
|
||||
}
|
||||
|
||||
// body may not be json string
|
||||
private parseBody(body: string): any {
|
||||
|
@ -348,11 +389,11 @@ export class NewmanReportValidator {
|
|||
return result;
|
||||
}
|
||||
|
||||
// private getLROFinalResponse(executions: NewmanExecution[], initialStep: string) {
|
||||
// return executions.find(
|
||||
// (it) => it.annotation?.type === "finalGet" && it.annotation.step === initialStep
|
||||
// );
|
||||
// }
|
||||
private getLROFinalResponse(executions: NewmanExecution[], initialStep: string) {
|
||||
return executions.find(
|
||||
(it) => it.annotation?.type === "finalGet" && it.annotation.step === initialStep
|
||||
);
|
||||
}
|
||||
|
||||
private getMatchedStep(stepName: string): Step | undefined {
|
||||
return this.scenario.steps?.find((s) => s.step === stepName);
|
||||
|
|
|
@ -0,0 +1,146 @@
|
|||
import { Item } from "postman-collection";
|
||||
import { StepArmTemplate, StepResponseAssertion, StepRestCall } from "./apiScenarioTypes";
|
||||
|
||||
type HttpMethod = "put" | "get" | "post" | "patch" | "delete" | "head" | "option";
|
||||
type OpenapiType = "Dataplane" | "Management";
|
||||
type AssertMatchParameter = { item?: Item; step?: StepArmTemplate | StepRestCall; opts?: any };
|
||||
|
||||
export type CallType = "lroPolling" | "lroFinalGet" | "stepCall" | "armTemplateCall";
|
||||
export type AssertionRule = {
|
||||
name: string;
|
||||
assertion?: { stepAssertion?: StepResponseAssertion; postmanTestScript?: string[] };
|
||||
conditions: {
|
||||
openapiTypes: OpenapiType | OpenapiType[];
|
||||
httpMethods: HttpMethod | HttpMethod[];
|
||||
callTypes: CallType | CallType[];
|
||||
isAsync?: boolean;
|
||||
match?: (params: AssertMatchParameter) => boolean;
|
||||
};
|
||||
};
|
||||
|
||||
// RPC-Async-V1-08 Async PATCH should return 202.
|
||||
const AsyncPatchShouldReturn202: AssertionRule = {
|
||||
name: "AsyncPatchShouldReturn202",
|
||||
assertion: { stepAssertion: { 202: {} } },
|
||||
conditions: {
|
||||
openapiTypes: "Management",
|
||||
isAsync: true,
|
||||
httpMethods: "patch",
|
||||
callTypes: "stepCall",
|
||||
},
|
||||
};
|
||||
|
||||
// RPC-Async-V1-09 Async DELETE should return 202.
|
||||
const AsyncDeleteShouldReturn202: AssertionRule = {
|
||||
name: "AsyncDeleteShouldReturn202",
|
||||
assertion: { stepAssertion: { 202: {} } },
|
||||
conditions: {
|
||||
openapiTypes: "Management",
|
||||
isAsync: true,
|
||||
httpMethods: "delete",
|
||||
callTypes: "stepCall",
|
||||
},
|
||||
};
|
||||
|
||||
// RPC-Async-V1-11 Async POST should return 202.
|
||||
const AsyncPostShouldReturn202: AssertionRule = {
|
||||
name: "AsyncPostShouldReturn202",
|
||||
assertion: { stepAssertion: { 202: {} } },
|
||||
conditions: {
|
||||
openapiTypes: "Management",
|
||||
isAsync: true,
|
||||
httpMethods: "post",
|
||||
callTypes: "stepCall",
|
||||
},
|
||||
};
|
||||
|
||||
//RPC-Async-V1-01 Async PUT should return 201/200.
|
||||
const AsyncPutShouldReturn201: AssertionRule = {
|
||||
name: "AsyncPutShouldReturn201",
|
||||
assertion: { stepAssertion: { 201: {}, 200: {} } },
|
||||
conditions: {
|
||||
openapiTypes: "Management",
|
||||
isAsync: true,
|
||||
httpMethods: "put",
|
||||
callTypes: "stepCall",
|
||||
},
|
||||
};
|
||||
|
||||
// RPC-Async-V1-07 Location header must be supported for all async operations that return 202. Azure-AsyncOperation header is optional.
|
||||
const Async202ResponseShouldIncludeLocationHeader: AssertionRule = {
|
||||
name: "Async202ResponseShouldIncludeLocationHeader",
|
||||
assertion: {
|
||||
postmanTestScript: ['if(pm.response.code === 202) { pm.response.to.have.header("Location");}'],
|
||||
},
|
||||
conditions: {
|
||||
openapiTypes: "Management",
|
||||
isAsync: true,
|
||||
httpMethods: ["put", "patch", "post", "delete"],
|
||||
callTypes: "stepCall",
|
||||
},
|
||||
};
|
||||
|
||||
const ArmTemplateStatusCodeCheck: AssertionRule = {
|
||||
name: "ArmTemplateStatusCodeCheck",
|
||||
assertion: {
|
||||
postmanTestScript: [
|
||||
"pm.response.to.be.success;",
|
||||
'pm.expect(pm.response.json().status).to.be.oneOf(["Succeeded", "Accepted", "Running", "Ready", "Creating", "Created", "Deleting", "Deleted", "Canceled", "Updating"]);',
|
||||
],
|
||||
},
|
||||
conditions: {
|
||||
openapiTypes: "Management",
|
||||
httpMethods: "put",
|
||||
callTypes: "armTemplateCall",
|
||||
},
|
||||
};
|
||||
|
||||
const DetailResponseLog: AssertionRule = {
|
||||
name: "DetailResponseLog",
|
||||
assertion: {
|
||||
postmanTestScript: ["console.log(pm.response.text());"],
|
||||
},
|
||||
conditions: {
|
||||
openapiTypes: ["Management", "Dataplane"],
|
||||
httpMethods: ["put", "get", "delete", "patch", "option", "post", "head"],
|
||||
callTypes: ["armTemplateCall", "lroFinalGet", "lroPolling", "stepCall"],
|
||||
match: (params: AssertMatchParameter) => {
|
||||
return params.opts?.verbose === true;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
// RPC-Async-V1-06 x-ms-long-running-operation-options should indicate the type of response header to track the async operation.
|
||||
// Here is for checking the case of final-state-via:azureAsyncOperation.
|
||||
const AzureAsyncOperationFinalStateCheck: AssertionRule = {
|
||||
name: "AzureAsyncOperationFinalStateCheck",
|
||||
assertion: {
|
||||
stepAssertion: {
|
||||
"200": [{ test: "/body/properties", expression: "to.be.not.undefined" }],
|
||||
},
|
||||
},
|
||||
conditions: {
|
||||
openapiTypes: "Management",
|
||||
httpMethods: ["put"],
|
||||
callTypes: "lroFinalGet",
|
||||
match: (params: AssertMatchParameter) => {
|
||||
const step = params.step;
|
||||
return (
|
||||
step?.type === "restCall" &&
|
||||
step.operation?.["x-ms-long-running-operation-options"]?.["final-state-via"] ===
|
||||
"azure-async-operation"
|
||||
);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const postmanArmRules = [
|
||||
AsyncPatchShouldReturn202,
|
||||
AsyncDeleteShouldReturn202,
|
||||
AsyncPostShouldReturn202,
|
||||
AsyncPutShouldReturn201,
|
||||
Async202ResponseShouldIncludeLocationHeader,
|
||||
ArmTemplateStatusCodeCheck,
|
||||
AzureAsyncOperationFinalStateCheck,
|
||||
DetailResponseLog,
|
||||
];
|
|
@ -13,7 +13,13 @@ import {
|
|||
VariableScope,
|
||||
} from "postman-collection";
|
||||
import { urlParse } from "@azure-tools/openapi-tools-common";
|
||||
import { xmsLongRunningOperation, xmsSkipUrlEncoding } from "../util/constants";
|
||||
import { isArray } from "lodash";
|
||||
import {
|
||||
xmsLongRunningOperation,
|
||||
xmsLongRunningOperationOptions,
|
||||
xmsLongRunningOperationOptionsField,
|
||||
xmsSkipUrlEncoding,
|
||||
} from "../util/constants";
|
||||
import { JsonLoader } from "../swagger/jsonLoader";
|
||||
import { usePseudoRandom } from "../util/utils";
|
||||
import {
|
||||
|
@ -39,6 +45,7 @@ import {
|
|||
import { DEFAULT_ARM_API_VERSION } from "./constants";
|
||||
import * as PostmanHelper from "./postmanHelper";
|
||||
import { VariableEnv } from "./variableEnv";
|
||||
import { CallType, postmanArmRules } from "./postmanAssertionRules";
|
||||
|
||||
export interface PostmanCollectionRunnerClientOption {
|
||||
scenarioFile: string;
|
||||
|
@ -65,6 +72,54 @@ interface PostmanAzureKeyAuthOption {
|
|||
|
||||
type PostmanAuthOption = PostmanAADTokenAuthOption | PostmanAzureKeyAuthOption;
|
||||
|
||||
function generatePostmanAssertion(parameter: {
|
||||
step: StepRestCall | StepArmTemplate;
|
||||
item: Item;
|
||||
type: CallType;
|
||||
opts?: any;
|
||||
}) {
|
||||
const scripts: string[] = [];
|
||||
if (parameter.step.type === "armTemplateDeployment") {
|
||||
return;
|
||||
}
|
||||
const rules = postmanArmRules;
|
||||
for (const rule of rules) {
|
||||
const conditions = rule.conditions;
|
||||
const httpMethods = isArray(conditions.httpMethods)
|
||||
? conditions.httpMethods
|
||||
: [conditions.httpMethods];
|
||||
const openapiTypes = isArray(conditions.openapiTypes)
|
||||
? conditions.openapiTypes
|
||||
: [conditions.openapiTypes];
|
||||
const callTypes = isArray(conditions.callTypes) ? conditions.callTypes : [conditions.callTypes];
|
||||
if (
|
||||
!!(parameter.step as StepRestCall).isManagementPlane ===
|
||||
openapiTypes.includes("Management") &&
|
||||
httpMethods.includes(parameter.step.operation?._method as any) &&
|
||||
callTypes.includes(parameter.type) &&
|
||||
(conditions.isAsync === undefined ||
|
||||
!!parameter.step.operation?.[xmsLongRunningOperation] === conditions.isAsync) &&
|
||||
(!conditions.match || conditions.match(parameter))
|
||||
) {
|
||||
if (rule.assertion?.stepAssertion) {
|
||||
PostmanHelper.appendScripts(scripts, {
|
||||
name: rule.name!,
|
||||
types: ["ResponseDataAssertion", "StatusCodeAssertion"],
|
||||
responseAssertion: rule.assertion.stepAssertion,
|
||||
});
|
||||
}
|
||||
if (rule.assertion?.postmanTestScript) {
|
||||
scripts.push(`pm.test("${rule.name}", function() {`);
|
||||
rule.assertion.postmanTestScript.forEach((s) => scripts.push(s));
|
||||
scripts.push("});");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (scripts.length) {
|
||||
PostmanHelper.addEvent(parameter.item.events, "test", scripts);
|
||||
}
|
||||
}
|
||||
|
||||
export class PostmanCollectionRunnerClient implements ApiScenarioRunnerClient {
|
||||
private opts: PostmanCollectionRunnerClientOption;
|
||||
private collection: Collection;
|
||||
|
@ -656,9 +711,7 @@ pm.test("Stopped TestProxy recording", function() {
|
|||
value: `{{${outputName}}}`,
|
||||
});
|
||||
}
|
||||
const scriptTypes: PostmanHelper.TestScriptType[] = this.opts.verbose
|
||||
? ["DetailResponseLog", "StatusCodeAssertion"]
|
||||
: ["StatusCodeAssertion"];
|
||||
const scriptTypes: PostmanHelper.TestScriptType[] = ["StatusCodeAssertion"];
|
||||
|
||||
if (step.responseAssertion) {
|
||||
step.responseAssertion = env.resolveObjectValues(step.responseAssertion);
|
||||
|
@ -681,14 +734,8 @@ pm.test("Stopped TestProxy recording", function() {
|
|||
step: item.name,
|
||||
};
|
||||
item.description = JSON.stringify(metadata);
|
||||
this.lroPoll(
|
||||
itemGroup!,
|
||||
item,
|
||||
clientRequest.host,
|
||||
postScripts,
|
||||
false,
|
||||
step.responseAssertion
|
||||
);
|
||||
|
||||
this.lroPoll(itemGroup!, item, step, clientRequest.host, postScripts);
|
||||
|
||||
// generate final get
|
||||
if (step.operation?._method !== "post") {
|
||||
|
@ -696,9 +743,10 @@ pm.test("Stopped TestProxy recording", function() {
|
|||
this.generateFinalGetItem(
|
||||
item.name,
|
||||
baseUri,
|
||||
item.request.url,
|
||||
item.name,
|
||||
step.operation._method
|
||||
step,
|
||||
step.operation._method,
|
||||
undefined,
|
||||
undefined
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -716,38 +764,83 @@ pm.test("Stopped TestProxy recording", function() {
|
|||
if (postScripts.length > 0) {
|
||||
PostmanHelper.addEvent(item.events, "test", postScripts);
|
||||
}
|
||||
generatePostmanAssertion({ step, type: "stepCall", item, opts: this.opts });
|
||||
}
|
||||
|
||||
private lroPoll(
|
||||
itemGroup: ItemGroup<Item>,
|
||||
item: Item,
|
||||
step: StepRestCall | StepArmTemplate,
|
||||
baseUri: string,
|
||||
postScripts: string[],
|
||||
checkStatus: boolean = false,
|
||||
responseAssertion?: StepResponseAssertion
|
||||
postScripts: string[]
|
||||
) {
|
||||
const finalStateVia =
|
||||
step.type === "restCall"
|
||||
? step?.operation?.[xmsLongRunningOperationOptions]?.[xmsLongRunningOperationOptionsField]
|
||||
: undefined;
|
||||
const isManagementPlane = step.type === "armTemplateDeployment" || step.isManagementPlane;
|
||||
if (this.opts.skipLroPoll) return;
|
||||
const url = item.request.url;
|
||||
const urlStr = `${baseUri}${url.getPathWithQuery()}`;
|
||||
|
||||
// For ARM put or patch operations , by default the final get is original url.
|
||||
const isArmResourceCreate =
|
||||
isManagementPlane && ["put", "patch"].includes(item.request.method.toLowerCase());
|
||||
postScripts.push(
|
||||
`
|
||||
const pollingUrl = pm.response.headers.get("Location") || pm.response.headers.get("Azure-AsyncOperation") || pm.response.headers.get("Operation-Location");
|
||||
// RPC-Async-V1-06 x-ms-long-running-operation-options should indicate the type of response header to track the async operation.
|
||||
function getLroFinalGetUrl(finalStateVia) {
|
||||
if (!finalStateVia) {
|
||||
// by default, the final url header is Location for ARM, Operation-Location for dataplane.
|
||||
return ${
|
||||
isArmResourceCreate
|
||||
? `'${urlStr}'`
|
||||
: `pm.response.headers.get("Location") || pm.response.headers.get("Operation-Location")`
|
||||
}
|
||||
}
|
||||
switch (finalStateVia) {
|
||||
case "location": {
|
||||
return pm.response.headers.get("Location");
|
||||
}
|
||||
case "azure-async-operation": {
|
||||
return pm.response.headers.get("Azure-AsyncOperation");
|
||||
}
|
||||
case "original-uri": {
|
||||
return "${urlStr}";
|
||||
}
|
||||
case "operation-location": {
|
||||
return pm.response.headers.get("Operation-Location");
|
||||
}
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
function getProxyUrl(url) {
|
||||
return "${this.opts.testProxy ?? ""}" ? url.replace("${baseUri}","${
|
||||
this.opts.testProxy ?? ""
|
||||
}") : url
|
||||
}
|
||||
const pollingUrl = pm.response.headers.get("Azure-AsyncOperation") || pm.response.headers.get("Location") || pm.response.headers.get("Operation-Location") || ${
|
||||
isArmResourceCreate ? `'${urlStr}'` : "''"
|
||||
}
|
||||
if (pollingUrl) {
|
||||
pm.variables.set("x_polling_url", ${
|
||||
this.opts.testProxy
|
||||
? `pollingUrl.replace("${baseUri}","${this.opts.testProxy}")`
|
||||
: "pollingUrl"
|
||||
});
|
||||
pm.variables.set("x_polling_url", getProxyUrl(pollingUrl));
|
||||
pm.variables.set("x_final_get_url", getProxyUrl(getLroFinalGetUrl("${finalStateVia ?? ""}")))
|
||||
pm.variables.set("x_retry_after", "3");
|
||||
}`
|
||||
);
|
||||
|
||||
const { item: delayItem } = this.addNewItem("Blank", {
|
||||
name: `_${item.name}_delay`,
|
||||
request: {
|
||||
url: "https://postman-echo.com/delay/{{x_retry_after}}",
|
||||
method: "GET",
|
||||
const { item: delayItem } = this.addNewItem(
|
||||
"Blank",
|
||||
{
|
||||
name: `_${item.name}_delay`,
|
||||
request: {
|
||||
url: "https://postman-echo.com/delay/{{x_retry_after}}",
|
||||
method: "GET",
|
||||
},
|
||||
},
|
||||
});
|
||||
baseUri
|
||||
);
|
||||
const delayItemMetadata: DelayItemMetadata = {
|
||||
type: "delay",
|
||||
lro_item_name: item.name,
|
||||
|
@ -799,25 +892,10 @@ try {
|
|||
`
|
||||
);
|
||||
|
||||
if (checkStatus) {
|
||||
PostmanHelper.appendScripts(pollerPostScripts, {
|
||||
name: "armTemplate deployment status check",
|
||||
types: ["StatusCodeAssertion", "ARMDeploymentStatusAssertion"],
|
||||
});
|
||||
}
|
||||
|
||||
if (responseAssertion) {
|
||||
PostmanHelper.appendScripts(pollerPostScripts, {
|
||||
name: "LRO response assertion",
|
||||
types: ["ResponseDataAssertion"],
|
||||
responseAssertion: responseAssertion,
|
||||
});
|
||||
}
|
||||
|
||||
if (postScripts.length > 0) {
|
||||
PostmanHelper.addEvent(pollerItem.events, "test", pollerPostScripts);
|
||||
}
|
||||
|
||||
generatePostmanAssertion({ step, type: "lroPolling", item: pollerItem, opts: this.opts });
|
||||
itemGroup.items.add(pollerItem);
|
||||
}
|
||||
|
||||
|
@ -825,12 +903,10 @@ try {
|
|||
types: PostmanHelper.TestScriptType[] = ["StatusCodeAssertion"],
|
||||
overwriteVariables?: Map<string, string>,
|
||||
armTemplate?: ArmTemplate,
|
||||
responseAssertion?: StepResponseAssertion
|
||||
responseAssertion?: StepResponseAssertion,
|
||||
name?: string
|
||||
): string[] {
|
||||
const scripts: string[] = [];
|
||||
if (this.opts.verbose) {
|
||||
types.push("DetailResponseLog");
|
||||
}
|
||||
if (overwriteVariables !== undefined) {
|
||||
types.push("OverwriteVariables");
|
||||
}
|
||||
|
@ -841,7 +917,7 @@ try {
|
|||
if (types.length > 0) {
|
||||
// generate assertion from example
|
||||
PostmanHelper.appendScripts(scripts, {
|
||||
name: "response status code assertion.",
|
||||
name: name || "response status code assertion.",
|
||||
types: types,
|
||||
variables: overwriteVariables,
|
||||
armTemplate,
|
||||
|
@ -901,9 +977,7 @@ try {
|
|||
raw: JSON.stringify(body, null, 2),
|
||||
});
|
||||
item.request.addHeader({ key: "Content-Type", value: "application/json" });
|
||||
const scriptTypes: PostmanHelper.TestScriptType[] = this.opts.verbose
|
||||
? ["StatusCodeAssertion", "DetailResponseLog"]
|
||||
: ["StatusCodeAssertion"];
|
||||
const scriptTypes: PostmanHelper.TestScriptType[] = ["StatusCodeAssertion"];
|
||||
|
||||
const postScripts: string[] = [];
|
||||
PostmanHelper.appendScripts(postScripts, {
|
||||
|
@ -912,20 +986,20 @@ try {
|
|||
variables: undefined,
|
||||
});
|
||||
|
||||
this.lroPoll(itemGroup!, item, armEndpoint, postScripts, true);
|
||||
this.lroPoll(itemGroup!, item, step, armEndpoint, postScripts);
|
||||
|
||||
if (postScripts.length > 0) {
|
||||
// to be improved
|
||||
PostmanHelper.addEvent(item.events, "test", postScripts);
|
||||
}
|
||||
|
||||
const generatedGetScriptTypes: PostmanHelper.TestScriptType[] = this.opts.verbose
|
||||
? ["DetailResponseLog", "ExtractARMTemplateOutput"]
|
||||
: ["ExtractARMTemplateOutput"];
|
||||
generatePostmanAssertion({ step, type: "armTemplateCall", item: item, opts: this.opts });
|
||||
|
||||
const generatedGetScriptTypes: PostmanHelper.TestScriptType[] = ["ExtractARMTemplateOutput"];
|
||||
const generatedGetOperationItem = this.generateFinalGetItem(
|
||||
item.name,
|
||||
armEndpoint,
|
||||
item.request.url,
|
||||
step.step,
|
||||
step,
|
||||
"put",
|
||||
generatedGetScriptTypes,
|
||||
armTemplate
|
||||
|
@ -936,11 +1010,11 @@ try {
|
|||
private generateFinalGetItem(
|
||||
name: string,
|
||||
baseUri: string,
|
||||
url: Url,
|
||||
step: string,
|
||||
step: StepRestCall | StepArmTemplate,
|
||||
prevMethod: string = "put",
|
||||
scriptTypes: PostmanHelper.TestScriptType[] = [],
|
||||
armTemplate?: ArmTemplate
|
||||
armTemplate?: ArmTemplate,
|
||||
finalStateVia?: string
|
||||
): Item {
|
||||
const { item } = this.addNewItem(
|
||||
"Blank",
|
||||
|
@ -948,26 +1022,36 @@ try {
|
|||
name: `_${name}_final_get`,
|
||||
request: {
|
||||
method: "GET",
|
||||
url: "",
|
||||
url: `{{x_final_get_url}}`,
|
||||
},
|
||||
},
|
||||
baseUri
|
||||
);
|
||||
item.request.url = url;
|
||||
|
||||
const metadata: FinalGetItemMetadata = {
|
||||
type: "finalGet",
|
||||
lro_item_name: name,
|
||||
step,
|
||||
step: step.step,
|
||||
};
|
||||
item.description = JSON.stringify(metadata);
|
||||
item.request.addHeader({ key: "Content-Type", value: "application/json" });
|
||||
if (prevMethod !== "delete") {
|
||||
scriptTypes.push("StatusCodeAssertion");
|
||||
}
|
||||
const postScripts = this.generatePostScripts(scriptTypes, undefined, armTemplate);
|
||||
const postScripts = this.generatePostScripts(scriptTypes, undefined, armTemplate, undefined);
|
||||
if (postScripts.length > 0) {
|
||||
// to be improved
|
||||
PostmanHelper.addEvent(item.events, "test", postScripts);
|
||||
}
|
||||
if (finalStateVia && finalStateVia !== "original-uri") {
|
||||
PostmanHelper.addEvent(item.events, "prerequest", [
|
||||
`pm.test("LRO final-state-via is valid", () =>
|
||||
{
|
||||
pm.expect(pm.variables.get("x_final_get_url")).to.be.not.undefined;
|
||||
})`,
|
||||
]);
|
||||
}
|
||||
generatePostmanAssertion({ step, type: "lroFinalGet", item: item, opts: this.opts });
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -179,6 +179,7 @@ export function appendScripts(scripts: string[], parameter: TestScriptParameter)
|
|||
if (parameter.types.includes("ResponseDataAssertion") && parameter.responseAssertion) {
|
||||
assertions.push(generateResponseDataAssertionScript(parameter.responseAssertion));
|
||||
}
|
||||
|
||||
if (assertions.length > 0) {
|
||||
scripts.push(`pm.test("${parameter.name}", function() {`);
|
||||
assertions.forEach((s) => scripts.push(s));
|
||||
|
|
|
@ -104,14 +104,14 @@
|
|||
}
|
||||
},
|
||||
"@azure/core-http": {
|
||||
"version": "2.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@azure/core-http/-/core-http-2.2.7.tgz",
|
||||
"integrity": "sha512-TyGMeDm90mkRS8XzSQbSMD+TqnWL1XKGCh0x0QVGMD8COH2yU0q5SaHm/IBEBkzcq0u73NhS/p57T3KVSgUFqQ==",
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@azure/core-http/-/core-http-2.3.1.tgz",
|
||||
"integrity": "sha512-cur03BUwV0Tbv81bQBOLafFB02B6G++K6F2O3IMl8pSE2QlXm3cu11bfyBNlDUKi5U+xnB3GC63ae3athhkx6Q==",
|
||||
"requires": {
|
||||
"@azure/abort-controller": "^1.0.0",
|
||||
"@azure/core-auth": "^1.3.0",
|
||||
"@azure/core-tracing": "1.0.0-preview.13",
|
||||
"@azure/core-util": "^1.1.0",
|
||||
"@azure/core-util": "^1.1.1",
|
||||
"@azure/logger": "^1.0.0",
|
||||
"@types/node-fetch": "^2.5.0",
|
||||
"@types/tunnel": "^0.0.3",
|
||||
|
@ -125,6 +125,15 @@
|
|||
"xml2js": "^0.4.19"
|
||||
},
|
||||
"dependencies": {
|
||||
"@azure/core-util": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.1.1.tgz",
|
||||
"integrity": "sha512-A4TBYVQCtHOigFb2ETiiKFDocBoI1Zk2Ui1KpI42aJSIDexF7DHQFpnjonltXAIU/ceH+1fsZAWWgvX6/AKzog==",
|
||||
"requires": {
|
||||
"@azure/abort-controller": "^1.0.0",
|
||||
"tslib": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"form-data": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
|
||||
|
@ -151,14 +160,6 @@
|
|||
"tslib": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"@azure/core-util": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.1.0.tgz",
|
||||
"integrity": "sha512-+i93lNJNA3Pl3KSuC6xKP2jTL4YFeDfO6VNOaYdk0cppZcLCxt811gS878VsqsCisaltdhl9lhMzK5kbxCiF4w==",
|
||||
"requires": {
|
||||
"tslib": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"@azure/logger": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.0.3.tgz",
|
||||
|
@ -1103,9 +1104,9 @@
|
|||
}
|
||||
},
|
||||
"@opentelemetry/api": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.2.0.tgz",
|
||||
"integrity": "sha512-0nBr+VZNKm9tvNDZFstI3Pq1fCTEDK5OZTnVKNvBNAKgd0yIvmwsP4m61rEv7ZP+tOUjWJhROpxK5MsnlF911g=="
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.4.0.tgz",
|
||||
"integrity": "sha512-IgMK9i3sFGNUqPMbjABm0G26g0QCKCUBfglhQ7rQq6WcxbKfEHRcmwsoER4hZcuYqJgkYn2OeuoJIv7Jsftp7g=="
|
||||
},
|
||||
"@postman/form-data": {
|
||||
"version": "3.1.1",
|
||||
|
@ -3039,12 +3040,13 @@
|
|||
}
|
||||
},
|
||||
"eslint-module-utils": {
|
||||
"version": "2.7.4",
|
||||
"resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz",
|
||||
"integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==",
|
||||
"version": "2.7.3",
|
||||
"resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz",
|
||||
"integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"debug": "^3.2.7"
|
||||
"debug": "^3.2.7",
|
||||
"find-up": "^2.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
|
@ -3178,9 +3180,9 @@
|
|||
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
|
||||
},
|
||||
"esquery": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
|
||||
"integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
|
||||
"version": "1.4.2",
|
||||
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.2.tgz",
|
||||
"integrity": "sha512-JVSoLdTlTDkmjFmab7H/9SL9qGSyjElT3myyKp7krqjVFQCDLmj1QFaCLRFBszBKI0XVZaiiXvuPIX3ZwHe1Ng==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"estraverse": "^5.1.0"
|
||||
|
@ -3576,6 +3578,15 @@
|
|||
"to-regex-range": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"find-up": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
|
||||
"integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"locate-path": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"flat-cache": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
|
||||
|
@ -3587,9 +3598,9 @@
|
|||
}
|
||||
},
|
||||
"flatted": {
|
||||
"version": "3.2.5",
|
||||
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz",
|
||||
"integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==",
|
||||
"version": "3.2.7",
|
||||
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz",
|
||||
"integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
|
||||
"dev": true
|
||||
},
|
||||
"fn.name": {
|
||||
|
@ -5194,9 +5205,9 @@
|
|||
"integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA=="
|
||||
},
|
||||
"json5": {
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
|
||||
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
|
||||
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
|
||||
"dev": true
|
||||
},
|
||||
"jsonfile": {
|
||||
|
@ -5309,6 +5320,16 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"locate-path": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
|
||||
"integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"p-locate": "^2.0.0",
|
||||
"path-exists": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
|
@ -6126,6 +6147,30 @@
|
|||
"integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==",
|
||||
"dev": true
|
||||
},
|
||||
"p-limit": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
|
||||
"integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"p-try": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"p-locate": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
|
||||
"integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"p-limit": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"p-try": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
|
||||
"integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==",
|
||||
"dev": true
|
||||
},
|
||||
"parent-module": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
||||
|
@ -6162,6 +6207,12 @@
|
|||
"integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==",
|
||||
"dev": true
|
||||
},
|
||||
"path-exists": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
|
||||
"integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
|
||||
"dev": true
|
||||
},
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
|
@ -6517,9 +6568,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"prettier": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
|
||||
"integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz",
|
||||
"integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==",
|
||||
"dev": true
|
||||
},
|
||||
"prettier-linter-helpers": {
|
||||
|
@ -6880,12 +6931,6 @@
|
|||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="
|
||||
},
|
||||
"require-from-string": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
|
||||
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
|
||||
"dev": true
|
||||
},
|
||||
"require-main-filename": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
|
||||
|
@ -7888,6 +7933,12 @@
|
|||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
|
||||
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
|
||||
"dev": true
|
||||
},
|
||||
"require-from-string": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
|
||||
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -8101,9 +8152,9 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"json5": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
|
||||
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
|
||||
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minimist": "^1.2.0"
|
||||
|
@ -8636,7 +8687,7 @@
|
|||
"xml": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz",
|
||||
"integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==",
|
||||
"integrity": "sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=",
|
||||
"dev": true
|
||||
},
|
||||
"xml-name-validator": {
|
||||
|
|
|
@ -12,7 +12,7 @@ import { inversifyGetInstance } from "../lib/inversifyUtils";
|
|||
import { JsonLoader } from "../lib/swagger/jsonLoader";
|
||||
import { setDefaultOpts } from "../lib/swagger/loader";
|
||||
import { SwaggerLoader, SwaggerLoaderOption } from "../lib/swagger/swaggerLoader";
|
||||
import { getInputFiles } from "../lib/util/utils";
|
||||
import { getInputFiles, resetPseudoRandomSeed } from "../lib/util/utils";
|
||||
|
||||
jest.setTimeout(9999999);
|
||||
|
||||
|
@ -97,6 +97,10 @@ function isCommonSpec(swagger:string) {
|
|||
}
|
||||
|
||||
describe("Api Test rule based generator test", () => {
|
||||
beforeEach(() => {
|
||||
resetPseudoRandomSeed(0);
|
||||
});
|
||||
|
||||
const specFolder = resolve(`${__dirname}/../regression/azure-rest-api-specs`);
|
||||
const specPaths: string[] = glob.sync(
|
||||
join(specFolder, "specification/**/resource-manager/readme.md"),
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Загрузка…
Ссылка в новой задаче