зеркало из https://github.com/Azure/autorest.az.git
20210207 preparer gen (#736)
* for configurable test preparers decorator forInstance fix gen preparers multiline fix refactor output multiline subnet multiline minor fix dictionary output findresource by className and objectName test-unique-resource check delete httpmethod test-unique-resource for testResource in swagger resume multiline integrate oav clear oldstyle preparer codes esLint work around autorest linux file:/// bug oav@2.2.0 clean code support split in scenario fix npm test WIP test case test * remove runLintball * oav 2.2.0 * debug * revert temp debug * debug mac * check mac os * initTest in unittest * format preparers.py * clean * refactor * test-unique-resource doc * refactor
This commit is contained in:
Родитель
6178150352
Коммит
05501e01bc
|
@ -459,6 +459,9 @@ require:
|
|||
- ./readme.cli.md
|
||||
- $(this-folder)/readme.az.common.md
|
||||
|
||||
try-require:
|
||||
- ./readme.test.md
|
||||
|
||||
pipeline-model: v3
|
||||
|
||||
scope-clicommon:
|
||||
|
|
|
@ -404,4 +404,15 @@ You can ask autorest.az to generate minimal tests (using only required parameter
|
|||
az:
|
||||
...
|
||||
gen-min-test: true
|
||||
~~~
|
||||
|
||||
|
||||
## How to merge resource names in example files
|
||||
In some RPs the resource names in example files is not well defined. For instance: every example file use a different resource group name. This will generate many resource groups in test files.
|
||||
|
||||
Below flag can require test codegen to use only one resource name for each resource type.
|
||||
~~~
|
||||
az:
|
||||
...
|
||||
test-unique-resource: true
|
||||
~~~
|
|
@ -71,6 +71,7 @@
|
|||
"jszip-sync": "^3.2.1-sync",
|
||||
"node-yaml": "^3.2.0",
|
||||
"nunjucks": "^3.2.2",
|
||||
"oav": "2.2.0",
|
||||
"prettier": "^2.2.1",
|
||||
"request": "^2.87.0",
|
||||
"request-promise-native": "1.0.8",
|
||||
|
|
|
@ -32,6 +32,43 @@ cli:
|
|||
cli-flatten-payload: true
|
||||
cli-flatten-schema: false
|
||||
cli-flatten-all-overwrite-swagger: false
|
||||
|
||||
az:
|
||||
preparers:
|
||||
virtualNetworks:
|
||||
abbr: vn
|
||||
alias:
|
||||
- virtualnetwork
|
||||
create:
|
||||
- az network vnet create --resource-group {resourceGroups} --name {name}
|
||||
delete:
|
||||
- az network vnet delete --resource-group {resourceGroups} --name {name}
|
||||
|
||||
subnets:
|
||||
alias:
|
||||
- subnet
|
||||
create: |-
|
||||
az network vnet subnet create -n {name} --vnet-name {virtualNetworks} -g {resourceGroups} --address-prefixes "10.0.0.0/21"
|
||||
delete: |-
|
||||
az network vnet subnet delete --name {name} --resource-group {resourceGroups} --vnet-name {virtualNetworks}
|
||||
|
||||
serviceEndpointPolicies:
|
||||
abbr: sep
|
||||
alias:
|
||||
- serviceendpointpolicy
|
||||
create: |-
|
||||
az network service-endpoint policy create --name {name} --resource-group {resourceGroups}
|
||||
delete: |-
|
||||
az network service-endpoint policy delete --name {name} -g {resourceGroups}
|
||||
|
||||
networkInterfaces:
|
||||
abbr: nic
|
||||
alias:
|
||||
- virtualinterface
|
||||
create:
|
||||
- az network nic create --resource-group {resourceGroups} --name {name} --vnet-name {virtualNetworks} --subnet {subnets}
|
||||
delete:
|
||||
- az network nic delete --resource-group {resourceGroups} --name {name}
|
||||
```
|
||||
|
||||
``` yaml $(python) && ($(generate-sdk) == 'yes' || ($(target-mode) != 'core' && !$(generate-sdk)))
|
||||
|
|
|
@ -2,6 +2,7 @@ import { Host } from '@autorest/extension-base';
|
|||
import { AzConfiguration, CodeGenConstants, PathConstants } from './utils/models';
|
||||
import * as path from 'path';
|
||||
import { runPython3 } from './python/setup';
|
||||
import { NeedPreparers } from './generate/renders/tests/CliTestStep';
|
||||
|
||||
export class AzLinter {
|
||||
async process(fileName: string): Promise<void> {
|
||||
|
@ -22,6 +23,18 @@ export async function processRequest(host: Host): Promise<void> {
|
|||
);
|
||||
const azLinter = new AzLinter();
|
||||
await azLinter.process(fileName);
|
||||
|
||||
if (NeedPreparers().size > 0) {
|
||||
await azLinter.process(
|
||||
path.join(
|
||||
folder,
|
||||
azextFolder,
|
||||
PathConstants.testFolder,
|
||||
PathConstants.latestFolder,
|
||||
PathConstants.preparersFile,
|
||||
),
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`${__filename} - FAILURE ${JSON.stringify(error)} ${error.stack}`);
|
||||
throw error;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* ---------------------------------------------------------------------------------------------
|
||||
/* ---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*-------------------------------------------------------------------------------------------- */
|
||||
|
@ -6,6 +6,7 @@
|
|||
import { Operation, OperationGroup, Parameter, Property, Schema } from '@azure-tools/codemodel';
|
||||
import { CodeModelTypes, DataGraph, GenerationMode, RenderInput } from '../utils/models';
|
||||
import { ResourcePool } from './renders/tests/ScenarioTool';
|
||||
import { TestStepExampleFileRestCall } from 'oav/dist/lib/testScenario/testResourceTypes';
|
||||
|
||||
export class MethodParam {
|
||||
public value: any;
|
||||
|
@ -254,7 +255,13 @@ export interface CodeModelAz {
|
|||
GenerateTestInit(): void;
|
||||
SelectFirstExample(): boolean;
|
||||
SelectNextExample(): boolean;
|
||||
FindExampleById(id: string, commandParams: any, examples: any[], minimum: boolean): string[][];
|
||||
FindExampleById(
|
||||
id: string,
|
||||
commandParams: any,
|
||||
examples: any[],
|
||||
minimum: boolean,
|
||||
step?: TestStepExampleFileRestCall,
|
||||
): string[][];
|
||||
SelectFirstAzExample(): boolean;
|
||||
SelectNextAzExample(): boolean;
|
||||
AzExample: CommandExample;
|
||||
|
@ -264,7 +271,7 @@ export interface CodeModelAz {
|
|||
GetSubscriptionKey(): string;
|
||||
GetPreparerEntities(): any[];
|
||||
GatherInternalResource();
|
||||
FindExampleWaitById(id: string): string[][];
|
||||
FindExampleWaitById(id: string, step?: TestStepExampleFileRestCall): string[][];
|
||||
GetExampleItems(example: CommandExample, isTest: boolean, commandParams: any): string[];
|
||||
GetExampleChecks(example: CommandExample): string[];
|
||||
RandomizeNames: boolean;
|
||||
|
@ -278,4 +285,5 @@ export interface CodeModelAz {
|
|||
inputProperties: Map<CodeModelTypes, RenderInput>,
|
||||
dependencies: DataGraph,
|
||||
);
|
||||
GetTestUniqueResource: boolean;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* ---------------------------------------------------------------------------------------------
|
||||
/* ---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*-------------------------------------------------------------------------------------------- */
|
||||
|
@ -58,9 +58,11 @@ import {
|
|||
ResourcePool,
|
||||
ObjectStatus,
|
||||
GroupTestScenario,
|
||||
LoadPreparesConfig,
|
||||
} from './renders/tests/ScenarioTool';
|
||||
import { readFile } from '@azure-tools/async-io';
|
||||
|
||||
import { TestStepExampleFileRestCall } from 'oav/dist/lib/testScenario/testResourceTypes';
|
||||
import * as process from 'process';
|
||||
class ActionParam {
|
||||
public constructor(
|
||||
public groupOpActionName: string,
|
||||
|
@ -126,6 +128,7 @@ export class CodeModelCliImpl implements CodeModelAz {
|
|||
this._clientAuthenticationPolicy = this.options[
|
||||
CodeGenConstants.clientAuthenticationPolicy
|
||||
];
|
||||
LoadPreparesConfig(this.options[CodeGenConstants.preparers]);
|
||||
// this.sortOperationByAzCommand();
|
||||
}
|
||||
|
||||
|
@ -138,8 +141,6 @@ export class CodeModelCliImpl implements CodeModelAz {
|
|||
this.sortOperationByAzCommand();
|
||||
this.calcOptionRequiredByMethod();
|
||||
this.dealingParameterAlias();
|
||||
this.GenerateTestInit();
|
||||
this.GetAllExamples();
|
||||
}
|
||||
|
||||
private sortOperationByAzCommand() {
|
||||
|
@ -207,6 +208,12 @@ export class CodeModelCliImpl implements CodeModelAz {
|
|||
return true;
|
||||
}
|
||||
|
||||
public get GetTestUniqueResource(): boolean {
|
||||
const ret = this.options?.[CodeGenConstants.testUniqueResource];
|
||||
if (ret) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public get GenMinTest(): boolean {
|
||||
const genMinTest = this.options?.['gen-min-test'];
|
||||
if (genMinTest) return true;
|
||||
|
@ -228,7 +235,10 @@ export class CodeModelCliImpl implements CodeModelAz {
|
|||
v.indexOf('specification') > 0
|
||||
) {
|
||||
const p = v.indexOf('specification');
|
||||
return v.slice('file:///'.length, p - 1);
|
||||
if (process.platform.toLowerCase().startsWith('win')) {
|
||||
return v.slice('file:///'.length, p - 1);
|
||||
}
|
||||
return v.slice('file:///'.length - 1, p - 1);
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
|
@ -772,15 +782,13 @@ export class CodeModelCliImpl implements CodeModelAz {
|
|||
//= ================================================================================================================
|
||||
|
||||
public GenerateTestInit(): void {
|
||||
if (this.codeModel['test-scenario']) {
|
||||
// if ('examples' in this.codeModel['test-scenario']) {
|
||||
// //new style of example configuration
|
||||
// this._testScenario = this.codeModel['test-scenario']['examples'];
|
||||
// }
|
||||
// else {
|
||||
// //old style of example configuration
|
||||
// this._testScenario = this.codeModel['test-scenario']
|
||||
// }
|
||||
if (this.GetResourcePool().hasTestResourceScenario) {
|
||||
this._testScenario = GroupTestScenario(
|
||||
this.GetResourcePool().generateTestScenario(),
|
||||
this.Extension_NameUnderscored,
|
||||
);
|
||||
this._configuredScenario = true;
|
||||
} else if (this.codeModel['test-scenario']) {
|
||||
this._testScenario = GroupTestScenario(
|
||||
this.codeModel['test-scenario'],
|
||||
this.Extension_NameUnderscored,
|
||||
|
@ -791,6 +799,7 @@ export class CodeModelCliImpl implements CodeModelAz {
|
|||
this._configuredScenario = false;
|
||||
}
|
||||
this.GatherInternalResource();
|
||||
this.GetAllExamples();
|
||||
}
|
||||
|
||||
public get ConfiguredScenario(): boolean {
|
||||
|
@ -3039,6 +3048,32 @@ export class CodeModelCliImpl implements CodeModelAz {
|
|||
if (!isNullOrUndefined(this.Method_AzExamples) && this.Method_AzExamples.length > 0) {
|
||||
return this.Method_AzExamples;
|
||||
}
|
||||
const examples: CommandExample[] = [];
|
||||
if (this.Examples) {
|
||||
Object.entries(this.Examples).forEach(([id, exampleObj]) => {
|
||||
const example = this.CreateCommandExample(id, exampleObj);
|
||||
if (!isNullOrUndefined(example)) examples.push(example);
|
||||
});
|
||||
}
|
||||
this.Method_AzExamples = examples;
|
||||
return examples;
|
||||
}
|
||||
|
||||
public GetExampleById(id: string, exampleObj: any): CommandExample {
|
||||
let ret: CommandExample = undefined;
|
||||
if (this.Examples) {
|
||||
Object.entries(this.Examples).forEach(([_id, _exampleObj]) => {
|
||||
if (!isNullOrUndefined(ret)) return;
|
||||
if (!isNullOrUndefined(id) && id.toLowerCase() !== _id.toLowerCase()) return;
|
||||
if (!isNullOrUndefined(exampleObj)) _exampleObj = exampleObj;
|
||||
const example = this.CreateCommandExample(_id, _exampleObj);
|
||||
if (!isNullOrUndefined(example)) ret = example;
|
||||
});
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public CreateCommandExample(id: string, exampleObj: any): CommandExample {
|
||||
function forUpdate(model: CodeModelCliImpl, exampleName: string): boolean {
|
||||
const lowercase: string = exampleName.toLowerCase();
|
||||
return (
|
||||
|
@ -3049,61 +3084,51 @@ export class CodeModelCliImpl implements CodeModelAz {
|
|||
);
|
||||
}
|
||||
|
||||
const examples: CommandExample[] = [];
|
||||
if (this.Examples) {
|
||||
Object.entries(this.Examples).forEach(([id, exampleObj]) => {
|
||||
const example = new CommandExample();
|
||||
example.Method = this.Command_MethodName;
|
||||
example.Id = `/${this.CommandGroup_Key}/${this.Method_HttpMethod}/${id}`;
|
||||
example.Title = exampleObj.title || id;
|
||||
example.Path = this.Method_Path;
|
||||
example.HttpMethod = this.Method_HttpMethod;
|
||||
example.ResourceClassName = this.CommandGroup_Key;
|
||||
const params = this.GetExampleParameters(exampleObj);
|
||||
example.Parameters = this.ConvertToCliParameters(params);
|
||||
example.MethodResponses = this.Method.responses || [];
|
||||
example.Method_IsLongRun = !!this.Method.extensions?.[
|
||||
'x-ms-long-running-operation'
|
||||
];
|
||||
example.ExampleObj = exampleObj;
|
||||
if (this.Method_GetSplitOriginalOperation) {
|
||||
// filter example by name for generic createorupdate
|
||||
if (
|
||||
this.Command_MethodName.toLowerCase() === 'update' &&
|
||||
!forUpdate(this, id)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
if (this.Command_MethodName.toLowerCase() !== 'update' && forUpdate(this, id)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (this.filterExampleByPoly(exampleObj, example)) {
|
||||
for (let i = 0; i < example.Parameters.length; i++) {
|
||||
if (this.isDiscriminator(example.Parameters[i].methodParam.value)) {
|
||||
example.Parameters.splice(i, 1);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
examples.push(example);
|
||||
}
|
||||
example.commandStringItems = this.GetExampleItems(example, false, undefined);
|
||||
example.CommandString = example.commandStringItems.join(' ');
|
||||
example.WaitCommandString = this.GetExampleWait(example).join(' ');
|
||||
});
|
||||
const example = new CommandExample();
|
||||
example.Method = this.Command_MethodName;
|
||||
example.Id = `/${this.CommandGroup_Key}/${this.Method_HttpMethod}/${id}`;
|
||||
example.Title = exampleObj.title || id;
|
||||
example.Path = this.Method_Path;
|
||||
example.HttpMethod = this.Method_HttpMethod;
|
||||
example.ResourceClassName = this.CommandGroup_Key;
|
||||
const params = this.GetExampleParameters(exampleObj);
|
||||
example.Parameters = this.ConvertToCliParameters(params);
|
||||
example.MethodResponses = this.Method.responses || [];
|
||||
example.Method_IsLongRun = !!this.Method.extensions?.['x-ms-long-running-operation'];
|
||||
example.ExampleObj = exampleObj;
|
||||
if (this.Method_GetSplitOriginalOperation) {
|
||||
// filter example by name for generic createorupdate
|
||||
if (this.Command_MethodName.toLowerCase() === 'update' && !forUpdate(this, id)) {
|
||||
return;
|
||||
}
|
||||
if (this.Command_MethodName.toLowerCase() !== 'update' && forUpdate(this, id)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.Method_AzExamples = examples;
|
||||
return examples;
|
||||
if (this.filterExampleByPoly(exampleObj, example)) {
|
||||
for (let i = 0; i < example.Parameters.length; i++) {
|
||||
if (this.isDiscriminator(example.Parameters[i].methodParam.value)) {
|
||||
example.Parameters.splice(i, 1);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
example.commandStringItems = this.GetExampleItems(example, false, undefined);
|
||||
example.CommandString = example.commandStringItems.join(' ');
|
||||
example.WaitCommandString = this.GetExampleWait(example).join(' ');
|
||||
return example;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public GetExampleChecks(example: CommandExample): string[] {
|
||||
const ret: string[] = [];
|
||||
if (!this.GenChecks) return ret;
|
||||
let resourceObjectName;
|
||||
let resourceObjectName = undefined;
|
||||
for (const param of example.Parameters) {
|
||||
if (
|
||||
example.ResourceClassName &&
|
||||
this.resourcePool.isResource(param.defaultName) === example.ResourceClassName
|
||||
this.resourcePool.isResource(param.defaultName, param.rawValue) ===
|
||||
example.ResourceClassName
|
||||
) {
|
||||
resourceObjectName = param.value;
|
||||
}
|
||||
|
@ -3137,21 +3162,21 @@ export class CodeModelCliImpl implements CodeModelAz {
|
|||
continue;
|
||||
let paramValue = param.value;
|
||||
if (isTest || this.FormalizeNames) {
|
||||
let replacedValue = this.resourcePool.addEndpointResource(
|
||||
let replacedValue = this.resourcePool.addParamResource(
|
||||
param.defaultName,
|
||||
paramValue,
|
||||
param.isJson,
|
||||
param.keyValue,
|
||||
[],
|
||||
[],
|
||||
param,
|
||||
isTest,
|
||||
);
|
||||
if (replacedValue === paramValue) {
|
||||
replacedValue = this.resourcePool.addParamResource(
|
||||
param.defaultName,
|
||||
replacedValue = this.resourcePool.addEndpointResource(
|
||||
paramValue,
|
||||
param.isJson,
|
||||
param.keyValue,
|
||||
[],
|
||||
[],
|
||||
param,
|
||||
isTest,
|
||||
);
|
||||
}
|
||||
|
@ -3170,7 +3195,8 @@ export class CodeModelCliImpl implements CodeModelAz {
|
|||
|
||||
if (
|
||||
example.ResourceClassName &&
|
||||
this.resourcePool.isResource(param.defaultName) === example.ResourceClassName
|
||||
this.resourcePool.isResource(param.defaultName, param.rawValue) ===
|
||||
example.ResourceClassName
|
||||
) {
|
||||
resourceObjectName = param.value;
|
||||
}
|
||||
|
@ -3236,23 +3262,24 @@ export class CodeModelCliImpl implements CodeModelAz {
|
|||
const paramKey = param.methodParam.value.language?.['cli']?.cliKey;
|
||||
if (
|
||||
paramKey === 'resourceGroupName' ||
|
||||
this.resourcePool.isResource(paramKey) === example.ResourceClassName
|
||||
this.resourcePool.isResource(paramKey, param.rawValue) ===
|
||||
example.ResourceClassName
|
||||
) {
|
||||
let paramValue = param.value;
|
||||
let replacedValue = this.resourcePool.addEndpointResource(
|
||||
let replacedValue = this.resourcePool.addParamResource(
|
||||
param.defaultName,
|
||||
paramValue,
|
||||
param.isJson,
|
||||
param.keyValue,
|
||||
[],
|
||||
[],
|
||||
param,
|
||||
);
|
||||
if (replacedValue === paramValue) {
|
||||
replacedValue = this.resourcePool.addParamResource(
|
||||
param.defaultName,
|
||||
replacedValue = this.resourcePool.addEndpointResource(
|
||||
paramValue,
|
||||
param.isJson,
|
||||
param.keyValue,
|
||||
[],
|
||||
[],
|
||||
param,
|
||||
);
|
||||
}
|
||||
paramValue = replacedValue;
|
||||
|
@ -3262,7 +3289,10 @@ export class CodeModelCliImpl implements CodeModelAz {
|
|||
}
|
||||
parameters.push(param.name + ' ' + slp);
|
||||
}
|
||||
if (this.resourcePool.isResource(paramKey) === example.ResourceClassName)
|
||||
if (
|
||||
this.resourcePool.isResource(paramKey, param.rawValue) ===
|
||||
example.ResourceClassName
|
||||
)
|
||||
foundResource = true;
|
||||
}
|
||||
}
|
||||
|
@ -3286,21 +3316,33 @@ export class CodeModelCliImpl implements CodeModelAz {
|
|||
commandParams: any,
|
||||
examples: CommandExample[],
|
||||
minimum = false,
|
||||
step: TestStepExampleFileRestCall = undefined,
|
||||
): string[][] {
|
||||
const ret: string[][] = [];
|
||||
this.GetAllExamples(id, (example) => {
|
||||
examples.push(example);
|
||||
ret.push(this.GetExampleItems(example, true, commandParams, minimum));
|
||||
});
|
||||
this.GetAllExamples(
|
||||
id,
|
||||
(example) => {
|
||||
examples.push(example);
|
||||
ret.push(this.GetExampleItems(example, true, commandParams, minimum));
|
||||
},
|
||||
step?.exampleTemplate,
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public FindExampleWaitById(id: string): string[][] {
|
||||
public FindExampleWaitById(
|
||||
id: string,
|
||||
step: TestStepExampleFileRestCall = undefined,
|
||||
): string[][] {
|
||||
const ret: string[][] = [];
|
||||
this.GetAllExamples(id, (example) => {
|
||||
const waitCmd = this.GetExampleWait(example);
|
||||
if (waitCmd.length > 0) ret.push(waitCmd);
|
||||
});
|
||||
this.GetAllExamples(
|
||||
id,
|
||||
(example) => {
|
||||
const waitCmd = this.GetExampleWait(example);
|
||||
if (waitCmd.length > 0) ret.push(waitCmd);
|
||||
},
|
||||
step?.exampleTemplate,
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -3366,7 +3408,7 @@ export class CodeModelCliImpl implements CodeModelAz {
|
|||
this.MethodParameter?.schema?.type !== 'constant'
|
||||
) {
|
||||
const paramName = this.MethodParameter.language['cli'].cliKey;
|
||||
const onResource = this.resourcePool.isResource(paramName);
|
||||
const onResource = this.resourcePool.isResource(paramName, undefined);
|
||||
for (const example of examples) {
|
||||
for (const param of example.Parameters) {
|
||||
if (
|
||||
|
@ -3550,12 +3592,24 @@ export class CodeModelCliImpl implements CodeModelAz {
|
|||
);
|
||||
}
|
||||
|
||||
public GetAllExamples(id?: string, callback?: (example) => void): CommandExample[] {
|
||||
public GetAllExamples(
|
||||
id?: string,
|
||||
callback?: (example) => void,
|
||||
exampleTemplate?: any,
|
||||
): CommandExample[] {
|
||||
const ret: CommandExample[] = [];
|
||||
let found = false;
|
||||
this.GetAllMethods(null, () => {
|
||||
if (found) return;
|
||||
for (const example of this.GetExamples()) {
|
||||
let examples: CommandExample[];
|
||||
if (!isNullOrUndefined(exampleTemplate)) {
|
||||
const example = this.GetExampleById(id, exampleTemplate);
|
||||
if (isNullOrUndefined(example)) return;
|
||||
examples = [example];
|
||||
} else {
|
||||
examples = this.GetExamples();
|
||||
}
|
||||
for (const example of examples) {
|
||||
if (id && !this.matchExample(example, id)) continue;
|
||||
if (callback) {
|
||||
callback(example);
|
||||
|
|
|
@ -31,6 +31,8 @@ export async function processRequest(host: Host) {
|
|||
}
|
||||
|
||||
openInplaceGen();
|
||||
await model.resourcePool.loadTestResources();
|
||||
model.GenerateTestInit();
|
||||
const generator = AzGeneratorFactory.createAzGenerator(model);
|
||||
await generator.generateAll();
|
||||
const files = generator.files;
|
||||
|
|
|
@ -34,6 +34,9 @@ export abstract class GeneratorBase {
|
|||
!fs.existsSync(path.join(this.model.azOutputFolder, template.relativePath))
|
||||
) {
|
||||
const genContent = await template.fullGeneration();
|
||||
if (template.skip) {
|
||||
return;
|
||||
}
|
||||
if (inplace) {
|
||||
this.files[template.relativePath] = inplaceGen(
|
||||
this.model.azOutputFolder,
|
||||
|
@ -57,6 +60,9 @@ export abstract class GeneratorBase {
|
|||
.toString();
|
||||
}
|
||||
const genContent = await template.incrementalGeneration(base);
|
||||
if (template.skip) {
|
||||
return;
|
||||
}
|
||||
if (inplace) {
|
||||
this.files[template.relativePath] = inplaceGen(
|
||||
this.model.azOutputFolder,
|
||||
|
|
|
@ -20,7 +20,7 @@ import { GenerateAzureCliValidators } from '../renders/generated/CliValidators';
|
|||
import { CliTestInit } from '../renders/tests/CliTestInit';
|
||||
import { CliTestPrepare } from '../renders/tests/CliTestPrepare';
|
||||
import { CliTestScenario } from '../renders/tests/CliTestScenario';
|
||||
import { CliTestStep, NeedPreparer } from '../renders/tests/CliTestStep';
|
||||
import { CliTestStep, NeedPreparers } from '../renders/tests/CliTestStep';
|
||||
import { GenerateMetaFile } from '../renders/CliMeta';
|
||||
export class AzCoreFullGenerator extends GeneratorBase {
|
||||
constructor(model: CodeModelAz) {
|
||||
|
@ -103,9 +103,22 @@ export class AzCoreFullGenerator extends GeneratorBase {
|
|||
true,
|
||||
);
|
||||
}
|
||||
if (NeedPreparer()) {
|
||||
await this.generateFullSingleAndAddtoOutput(new CliTestPrepare(model));
|
||||
const needPreparers = NeedPreparers();
|
||||
if (needPreparers.size > 0) {
|
||||
await this.generateFullSingleAndAddtoOutput(
|
||||
new CliTestPrepare(model, [...needPreparers]),
|
||||
);
|
||||
}
|
||||
model
|
||||
.GetResourcePool()
|
||||
.generateArmTemplate(
|
||||
files,
|
||||
path.join(
|
||||
model.azOutputFolder,
|
||||
PathConstants.testFolder,
|
||||
PathConstants.latestFolder,
|
||||
),
|
||||
);
|
||||
GenerateMetaFile(model);
|
||||
} while (model.SelectNextExtension());
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ import { GenerateAzureCliValidators } from '../renders/generated/CliValidators';
|
|||
import { CliTestInit } from '../renders/tests/CliTestInit';
|
||||
import { CliTestPrepare } from '../renders/tests/CliTestPrepare';
|
||||
import { CliTestScenario } from '../renders/tests/CliTestScenario';
|
||||
import { CliTestStep, NeedPreparer } from '../renders/tests/CliTestStep';
|
||||
import { CliTestStep, NeedPreparers } from '../renders/tests/CliTestStep';
|
||||
import { GenerateMetaFile } from '../renders/CliMeta';
|
||||
import { CliExtSetupPy } from '../renders/extraExt/CliExtSetupPy';
|
||||
|
||||
|
@ -145,9 +145,22 @@ export class AzCoreIncrementalGenerator extends GeneratorBase {
|
|||
true,
|
||||
);
|
||||
}
|
||||
if (NeedPreparer()) {
|
||||
await this.generateIncrementalSingleAndAddtoOutput(new CliTestPrepare(this.model));
|
||||
const needPreparers = NeedPreparers();
|
||||
if (needPreparers.size > 0) {
|
||||
await this.generateIncrementalSingleAndAddtoOutput(
|
||||
new CliTestPrepare(this.model, [...needPreparers]),
|
||||
);
|
||||
}
|
||||
this.model
|
||||
.GetResourcePool()
|
||||
.generateArmTemplate(
|
||||
this.files,
|
||||
path.join(
|
||||
this.model.azOutputFolder,
|
||||
PathConstants.testFolder,
|
||||
PathConstants.latestFolder,
|
||||
),
|
||||
);
|
||||
GenerateMetaFile(this.model);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ import { GenerateAzureCliValidators } from '../renders/generated/CliValidators';
|
|||
import { CliTestInit } from '../renders/tests/CliTestInit';
|
||||
import { CliTestPrepare } from '../renders/tests/CliTestPrepare';
|
||||
import { CliTestScenario } from '../renders/tests/CliTestScenario';
|
||||
import { CliTestStep, NeedPreparer } from '../renders/tests/CliTestStep';
|
||||
import { CliTestStep, NeedPreparers } from '../renders/tests/CliTestStep';
|
||||
import { GenerateMetaFile } from '../renders/CliMeta';
|
||||
import { CliExtSetupCfg } from '../renders/extraExt/CliExtSetupCfg';
|
||||
import { CliExtHistory } from '../renders/extraExt/CliExtHistory';
|
||||
|
@ -101,9 +101,18 @@ export class AzExtensionFullGenerator extends GeneratorBase {
|
|||
true,
|
||||
);
|
||||
}
|
||||
if (NeedPreparer()) {
|
||||
await this.generateFullSingleAndAddtoOutput(new CliTestPrepare(this.model));
|
||||
const needPreparers = NeedPreparers();
|
||||
if (needPreparers.size > 0) {
|
||||
await this.generateFullSingleAndAddtoOutput(
|
||||
new CliTestPrepare(this.model, [...needPreparers]),
|
||||
);
|
||||
}
|
||||
this.model
|
||||
.GetResourcePool()
|
||||
.generateArmTemplate(
|
||||
this.files,
|
||||
path.join(this.azDirectory, PathConstants.testFolder, PathConstants.latestFolder),
|
||||
);
|
||||
GenerateMetaFile(this.model);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ import { GenerateAzureCliValidators } from '../renders/generated/CliValidators';
|
|||
import { CliTestInit } from '../renders/tests/CliTestInit';
|
||||
import { CliTestPrepare } from '../renders/tests/CliTestPrepare';
|
||||
import { CliTestScenario } from '../renders/tests/CliTestScenario';
|
||||
import { CliTestStep, NeedPreparer } from '../renders/tests/CliTestStep';
|
||||
import { CliTestStep, NeedPreparers } from '../renders/tests/CliTestStep';
|
||||
import { GenerateMetaFile } from '../renders/CliMeta';
|
||||
|
||||
export class AzExtensionIncrementalGenerator extends GeneratorBase {
|
||||
|
@ -132,9 +132,18 @@ export class AzExtensionIncrementalGenerator extends GeneratorBase {
|
|||
true,
|
||||
);
|
||||
}
|
||||
if (NeedPreparer()) {
|
||||
await this.generateIncrementalSingleAndAddtoOutput(new CliTestPrepare(this.model));
|
||||
const needPreparers = NeedPreparers();
|
||||
if (needPreparers.size > 0) {
|
||||
await this.generateIncrementalSingleAndAddtoOutput(
|
||||
new CliTestPrepare(this.model, [...needPreparers]),
|
||||
);
|
||||
}
|
||||
this.model
|
||||
.GetResourcePool()
|
||||
.generateArmTemplate(
|
||||
this.files,
|
||||
path.join(this.azDirectory, PathConstants.testFolder, PathConstants.latestFolder),
|
||||
);
|
||||
GenerateMetaFile(this.model);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,12 +11,14 @@ export abstract class TemplateBase {
|
|||
protected isDebugMode: boolean;
|
||||
public relativePath: string;
|
||||
protected tmplPath: string;
|
||||
public skip: boolean;
|
||||
|
||||
constructor(model: CodeModelAz) {
|
||||
this.model = model;
|
||||
this.isDebugMode = AzConfiguration.getValue(CodeGenConstants.debug);
|
||||
this.relativePath = '';
|
||||
this.tmplPath = '';
|
||||
this.skip = false;
|
||||
}
|
||||
|
||||
public abstract async fullGeneration(): Promise<string[]>;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* ---------------------------------------------------------------------------------------------
|
||||
/* ---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*-------------------------------------------------------------------------------------------- */
|
||||
|
|
|
@ -10,15 +10,11 @@ import { PathConstants } from '../../../utils/models';
|
|||
export class CliTestInit extends TemplateBase {
|
||||
constructor(model: CodeModelAz) {
|
||||
super(model);
|
||||
if (this.model.IsCliCore) {
|
||||
this.relativePath = path.join(PathConstants.testFolder, PathConstants.initFile);
|
||||
} else {
|
||||
this.relativePath = path.join(
|
||||
model.AzextFolder,
|
||||
PathConstants.testFolder,
|
||||
PathConstants.initFile,
|
||||
);
|
||||
}
|
||||
this.relativePath = path.join(
|
||||
model.AzextFolder,
|
||||
PathConstants.testFolder,
|
||||
PathConstants.initFile,
|
||||
);
|
||||
this.tmplPath = path.join(PathConstants.templateRootFolder, 'tests/init.py.njx');
|
||||
}
|
||||
|
||||
|
|
|
@ -1,30 +1,43 @@
|
|||
import * as path from 'path';
|
||||
import { CodeModelAz } from '../../CodeModelAz';
|
||||
import { HeaderGenerator } from '../Header';
|
||||
import { TemplateBase } from '../TemplateBase';
|
||||
import { PathConstants } from '../../../utils/models';
|
||||
import { GenPreparerName, preparerInfos } from './ScenarioTool';
|
||||
import { ToJsonString } from '../../../utils/helper';
|
||||
|
||||
class FuncData {
|
||||
constructor(public cmdTemplate: string, public cmdFormats: string[]) {}
|
||||
}
|
||||
export class PreparerData {
|
||||
public initParamPairs: [string, string][];
|
||||
public attributes: string[];
|
||||
public createFunc: FuncData;
|
||||
public removeFunc: FuncData;
|
||||
|
||||
constructor(public className: string) {
|
||||
this.initParamPairs = [];
|
||||
this.attributes = [];
|
||||
this.createFunc = new FuncData(undefined, []);
|
||||
this.removeFunc = new FuncData(undefined, []);
|
||||
}
|
||||
}
|
||||
|
||||
export class CliTestPrepare extends TemplateBase {
|
||||
constructor(model: CodeModelAz) {
|
||||
resourceNames: string[];
|
||||
constructor(model: CodeModelAz, resourceNames: string[]) {
|
||||
super(model);
|
||||
if (this.model.IsCliCore) {
|
||||
this.relativePath = path.join(
|
||||
PathConstants.testFolder,
|
||||
PathConstants.latestFolder,
|
||||
PathConstants.preparersFile,
|
||||
);
|
||||
} else {
|
||||
this.relativePath = path.join(
|
||||
model.AzextFolder,
|
||||
PathConstants.testFolder,
|
||||
PathConstants.latestFolder,
|
||||
PathConstants.preparersFile,
|
||||
);
|
||||
}
|
||||
this.resourceNames = resourceNames;
|
||||
this.relativePath = path.join(
|
||||
model.AzextFolder,
|
||||
PathConstants.testFolder,
|
||||
PathConstants.latestFolder,
|
||||
PathConstants.preparersFile,
|
||||
);
|
||||
this.tmplPath = path.join(PathConstants.templateRootFolder, 'tests/latest/prepares.py.njx');
|
||||
}
|
||||
|
||||
public async fullGeneration(): Promise<string[]> {
|
||||
// this.GenerateAzureCliTestPrepare(this.model);
|
||||
return await this.render();
|
||||
}
|
||||
|
||||
|
@ -32,8 +45,77 @@ export class CliTestPrepare extends TemplateBase {
|
|||
return await this.fullGeneration();
|
||||
}
|
||||
|
||||
public async GetRenderData(model: CodeModelAz): Promise<string[]> {
|
||||
const output: string[] = [];
|
||||
return output;
|
||||
public async GetRenderData(model: CodeModelAz): Promise<any> {
|
||||
const data = {
|
||||
preparers: [],
|
||||
};
|
||||
for (const resourceName of this.resourceNames) {
|
||||
data.preparers.push(this.CreatePreparer(model, resourceName));
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
private CreatePreparer(model: CodeModelAz, resourceName: string) {
|
||||
const preparerInfo = preparerInfos[resourceName];
|
||||
const preparerData = new PreparerData(GenPreparerName(preparerInfo.className));
|
||||
for (let i = 0; i < preparerInfo.dependResources.length; i++) {
|
||||
preparerData.initParamPairs.push([
|
||||
preparerInfos[preparerInfo.className].dependParameters[i],
|
||||
ToJsonString(
|
||||
preparerInfos[preparerInfos[preparerInfo.className].dependResources[i]].key,
|
||||
),
|
||||
]);
|
||||
}
|
||||
preparerData.initParamPairs.push(['key', ToJsonString(preparerInfo.key)]);
|
||||
for (const k in preparerInfo.config.inits) {
|
||||
preparerData.initParamPairs.push([k, ToJsonString(preparerInfo.config.inits[k])]);
|
||||
}
|
||||
|
||||
for (const param of preparerInfo.dependParameters.concat(
|
||||
Object.getOwnPropertyNames(preparerInfo.config.inits),
|
||||
)) {
|
||||
preparerData.attributes.push(param);
|
||||
}
|
||||
|
||||
function genLiveRun(templates: string[], funcData: FuncData) {
|
||||
for (const template of templates) {
|
||||
const variables: string[] = [];
|
||||
let depends: string[] = template.match(/\{.*?\}/g);
|
||||
depends = depends.map((x: string) => {
|
||||
return x.substr(1, x.length - 2).toLowerCase();
|
||||
});
|
||||
for (const depend of depends) {
|
||||
if (depend == 'name') {
|
||||
variables.push(`name`);
|
||||
} else {
|
||||
for (
|
||||
let i = 0;
|
||||
i < preparerInfos[preparerInfo.className].dependParameters.length;
|
||||
i++
|
||||
) {
|
||||
if (
|
||||
model
|
||||
.GetResourcePool()
|
||||
.isResource(
|
||||
preparerInfos[preparerInfo.className].dependResources[i],
|
||||
null,
|
||||
) === model.GetResourcePool().isResource(depend, null)
|
||||
) {
|
||||
variables.push(
|
||||
`self.test_class_instance.kwargs.get(self.${
|
||||
preparerInfos[preparerInfo.className].dependParameters[i]
|
||||
})`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
funcData.cmdTemplate = template.replace(/\{.*?\}/g, '{}');
|
||||
funcData.cmdFormats = variables;
|
||||
}
|
||||
}
|
||||
genLiveRun(preparerInfo.config.create, preparerData.createFunc);
|
||||
genLiveRun(preparerInfo.config.delete, preparerData.removeFunc);
|
||||
return preparerData;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* ---------------------------------------------------------------------------------------------
|
||||
/* ---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*-------------------------------------------------------------------------------------------- */
|
||||
|
@ -11,32 +11,24 @@ import { TemplateBase } from '../TemplateBase';
|
|||
import { CodeGenConstants, PathConstants } from '../../../utils/models';
|
||||
|
||||
export class CliTestScenario extends TemplateBase {
|
||||
constructor(model: CodeModelAz, testFilename: string, configValue: any, groupName: string) {
|
||||
super(model);
|
||||
if (this.model.IsCliCore) {
|
||||
this.relativePath = path.join(
|
||||
PathConstants.testFolder,
|
||||
PathConstants.latestFolder,
|
||||
testFilename,
|
||||
);
|
||||
} else {
|
||||
this.relativePath = path.join(
|
||||
model.AzextFolder,
|
||||
PathConstants.testFolder,
|
||||
PathConstants.latestFolder,
|
||||
testFilename,
|
||||
);
|
||||
}
|
||||
this.configValue = configValue;
|
||||
this.groupName = groupName;
|
||||
}
|
||||
|
||||
public configValue: any;
|
||||
private groupName: string;
|
||||
|
||||
private header: HeaderGenerator = new HeaderGenerator();
|
||||
private scenarios: string[] = [];
|
||||
|
||||
constructor(model: CodeModelAz, testFilename: string, configValue: any, groupName: string) {
|
||||
super(model);
|
||||
this.relativePath = path.join(
|
||||
model.AzextFolder,
|
||||
PathConstants.testFolder,
|
||||
PathConstants.latestFolder,
|
||||
testFilename,
|
||||
);
|
||||
this.configValue = configValue;
|
||||
this.groupName = groupName;
|
||||
this.skip = true;
|
||||
}
|
||||
|
||||
public async fullGeneration(): Promise<string[]> {
|
||||
this.StartGenerateAzureCliTestScenario();
|
||||
for (const scenarioName of Object.getOwnPropertyNames(this.configValue)) {
|
||||
|
@ -109,7 +101,7 @@ export class CliTestScenario extends TemplateBase {
|
|||
),
|
||||
);
|
||||
|
||||
function buildSenario(header: HeaderGenerator, outputFunc: string[], minimum: boolean) {
|
||||
function buildSenario(template: CliTestScenario, outputFunc: string[], minimum: boolean) {
|
||||
model.GetResourcePool().clearExampleParams();
|
||||
|
||||
// go through the examples to generate steps
|
||||
|
@ -127,6 +119,7 @@ export class CliTestScenario extends TemplateBase {
|
|||
commandParams,
|
||||
examples,
|
||||
minimum,
|
||||
config[ci].step,
|
||||
)) {
|
||||
exampleIdx += 1;
|
||||
if (exampleCmd && exampleCmd.length > 0) {
|
||||
|
@ -152,7 +145,7 @@ export class CliTestScenario extends TemplateBase {
|
|||
!disabled &&
|
||||
check.indexOf('json.loads') >= 0
|
||||
) {
|
||||
header.addImport('json');
|
||||
template.header.addImport('json');
|
||||
jsonAdded = true;
|
||||
}
|
||||
}
|
||||
|
@ -169,7 +162,8 @@ export class CliTestScenario extends TemplateBase {
|
|||
}
|
||||
}
|
||||
if (found) {
|
||||
header.addFromImport('.example_steps', [functionName]);
|
||||
template.header.addFromImport('.example_steps', [functionName]);
|
||||
template.skip = false;
|
||||
} else {
|
||||
outputFunc.push(...ToMultiLine(` # STEP NOT FOUND: ${exampleId}`));
|
||||
}
|
||||
|
@ -184,7 +178,14 @@ export class CliTestScenario extends TemplateBase {
|
|||
)}):`,
|
||||
),
|
||||
);
|
||||
steps.push(' pass');
|
||||
if (
|
||||
functionName.startsWith('setup_') &&
|
||||
model.GetResourcePool().hasTestResourceScenario
|
||||
) {
|
||||
steps.push(...model.GetResourcePool().setupWithArmTemplate());
|
||||
} else {
|
||||
steps.push(' pass');
|
||||
}
|
||||
steps.push('');
|
||||
steps.push('');
|
||||
}
|
||||
|
@ -198,7 +199,7 @@ export class CliTestScenario extends TemplateBase {
|
|||
outputFunc.push('');
|
||||
outputFunc.push('');
|
||||
}
|
||||
buildSenario(this.header, funcScenario, false);
|
||||
buildSenario(this, funcScenario, false);
|
||||
if (model.GenMinTest) {
|
||||
funcMinScenario.push('@try_manual');
|
||||
funcMinScenario.push(
|
||||
|
@ -208,7 +209,7 @@ export class CliTestScenario extends TemplateBase {
|
|||
)}):`,
|
||||
),
|
||||
);
|
||||
buildSenario(this.header, funcMinScenario, true);
|
||||
buildSenario(this, funcMinScenario, true);
|
||||
}
|
||||
classInfo.push(' def __init__(self, *args, **kwargs):');
|
||||
classInfo.push(` super(${testClassName}, self).__init__(*args, **kwargs)`);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* ---------------------------------------------------------------------------------------------
|
||||
/* ---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*-------------------------------------------------------------------------------------------- */
|
||||
|
@ -10,37 +10,29 @@ import { HeaderGenerator } from '../Header';
|
|||
import { TemplateBase } from '../TemplateBase';
|
||||
import { CodeGenConstants, PathConstants } from '../../../utils/models';
|
||||
|
||||
let usePreparers: boolean, shortToLongName, funcNames, allSteps, stepBuff: any;
|
||||
let usePreparers: Set<string>, shortToLongName, funcNames, allSteps, stepBuff: Record<string, any>;
|
||||
|
||||
function initVars() {
|
||||
usePreparers = false;
|
||||
usePreparers = new Set<string>();
|
||||
shortToLongName = {};
|
||||
funcNames = {};
|
||||
allSteps = [];
|
||||
stepBuff = {};
|
||||
}
|
||||
|
||||
export function NeedPreparer(): boolean {
|
||||
export function NeedPreparers(): Set<string> {
|
||||
return usePreparers;
|
||||
}
|
||||
|
||||
export class CliTestStep extends TemplateBase {
|
||||
constructor(model: CodeModelAz) {
|
||||
super(model);
|
||||
if (this.model.IsCliCore) {
|
||||
this.relativePath = path.join(
|
||||
PathConstants.testFolder,
|
||||
PathConstants.latestFolder,
|
||||
PathConstants.testStepFile,
|
||||
);
|
||||
} else {
|
||||
this.relativePath = path.join(
|
||||
model.AzextFolder,
|
||||
PathConstants.testFolder,
|
||||
PathConstants.latestFolder,
|
||||
PathConstants.testStepFile,
|
||||
);
|
||||
}
|
||||
this.relativePath = path.join(
|
||||
model.AzextFolder,
|
||||
PathConstants.testFolder,
|
||||
PathConstants.latestFolder,
|
||||
PathConstants.testStepFile,
|
||||
);
|
||||
}
|
||||
|
||||
public async fullGeneration(): Promise<string[]> {
|
||||
|
@ -61,7 +53,15 @@ export class CliTestStep extends TemplateBase {
|
|||
steps.push('');
|
||||
|
||||
const commandParams = model.GatherInternalResource();
|
||||
const config: any = deepCopy(model.Extension_DefaultTestScenario);
|
||||
let config: any = [];
|
||||
if (model.GetResourcePool().hasTestResourceScenario) {
|
||||
for (const g in model.Extension_TestScenario) {
|
||||
for (const s in model.Extension_TestScenario[g])
|
||||
config.push(...model.Extension_TestScenario[g][s]);
|
||||
}
|
||||
} else {
|
||||
config = deepCopy(model.Extension_DefaultTestScenario);
|
||||
}
|
||||
|
||||
const header: HeaderGenerator = new HeaderGenerator();
|
||||
|
||||
|
@ -95,6 +95,7 @@ export class CliTestStep extends TemplateBase {
|
|||
commandParams,
|
||||
examples,
|
||||
minimum,
|
||||
config[ci].step,
|
||||
)) {
|
||||
exampleIdx += 1;
|
||||
if (exampleCmd && exampleCmd.length > 0) {
|
||||
|
@ -131,7 +132,10 @@ export class CliTestStep extends TemplateBase {
|
|||
);
|
||||
} else {
|
||||
stepBuff[cmdString] = functionName;
|
||||
if (exampleCmd[0].indexOf(' delete') > -1) {
|
||||
if (
|
||||
exampleCmd[0].indexOf(' delete') > -1 &&
|
||||
examples[exampleIdx].HttpMethod.toLowerCase() === 'delete'
|
||||
) {
|
||||
exampleCmd[0] += ' -y';
|
||||
}
|
||||
|
||||
|
@ -236,10 +240,13 @@ export class CliTestStep extends TemplateBase {
|
|||
const parameterNames = [];
|
||||
for (const entity of model.GetPreparerEntities() as PreparerEntity[]) {
|
||||
if (!entity.info.name) {
|
||||
const created = model.GetTestUniqueResource
|
||||
? entity.info.createdObjectNames.length > 0
|
||||
: entity.info.createdObjectNames.indexOf(entity.objectName) >= 0;
|
||||
internalObjects.push([
|
||||
entity.info.className,
|
||||
getResourceKey(entity.info.className, entity.objectName),
|
||||
entity.info.createdObjectNames.indexOf(entity.objectName) >= 0,
|
||||
created,
|
||||
entity.objectName,
|
||||
]);
|
||||
continue;
|
||||
|
@ -263,13 +270,11 @@ export class CliTestStep extends TemplateBase {
|
|||
line += ')';
|
||||
ToMultiLine(line, decorators);
|
||||
if (decorated.indexOf(entity.info.name) < 0) {
|
||||
if (entity.info.name === 'ResourceGroupPreparer') {
|
||||
if (!entity.info.needGen) {
|
||||
header.addFromImport('azure.cli.testsdk', [entity.info.name]);
|
||||
} else if (entity.info.name === 'StorageAccountPreparer') {
|
||||
header.addFromImport('azure.cli.testsdk', [entity.info.name]);
|
||||
} else {
|
||||
} else if (entity.info.needGen) {
|
||||
header.addFromImport('.preparers', [entity.info.name]);
|
||||
usePreparers = true;
|
||||
usePreparers.add(entity.info.className);
|
||||
}
|
||||
decorated.push(entity.info.name);
|
||||
}
|
||||
|
|
|
@ -7,8 +7,21 @@ import {
|
|||
changeCamelToDash,
|
||||
MergeSort,
|
||||
isNullOrUndefined,
|
||||
Capitalize,
|
||||
ToSnakeCase,
|
||||
setPathValue,
|
||||
checkNested,
|
||||
} from '../../../utils/helper';
|
||||
import { EnglishPluralizationService } from '@azure-tools/codegen';
|
||||
import { AzConfiguration, CodeGenConstants } from '../../../utils/models';
|
||||
import { TestResourceLoader } from 'oav/dist/lib/testScenario/testResourceLoader';
|
||||
import {
|
||||
TestDefinitionFile,
|
||||
TestStepArmTemplateDeployment,
|
||||
TestStepExampleFileRestCall,
|
||||
} from 'oav/dist/lib/testScenario/testResourceTypes';
|
||||
import * as path from 'path';
|
||||
import * as process from 'process';
|
||||
|
||||
export const azOptions = {};
|
||||
|
||||
|
@ -127,8 +140,13 @@ export function GroupTestScenario(testScenario: any, extensionName: string) {
|
|||
}
|
||||
}
|
||||
} else if (Array.isArray(testScenario)) {
|
||||
let curGroup = extensionName;
|
||||
for (let ci = 0; ci < testScenario.length; ci++) {
|
||||
addScenario(extensionName, defaultScenario, [testScenario[ci]]);
|
||||
if (Object.prototype.hasOwnProperty.call(testScenario[ci], 'split')) {
|
||||
curGroup = testScenario[ci].split;
|
||||
} else {
|
||||
addScenario(curGroup, defaultScenario, [testScenario[ci]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -136,42 +154,18 @@ export function GroupTestScenario(testScenario: any, extensionName: string) {
|
|||
}
|
||||
|
||||
const SUBSCRIPTIONS = 'subscriptions';
|
||||
const RESOUREGROUP = 'resource-group';
|
||||
const VIRTUALNETWORK = 'virtual-network';
|
||||
const STORAGEACCOUNT = 'storage-account';
|
||||
const SUBNET = 'subnet';
|
||||
const NETWORKINTERFACE = 'network-interface';
|
||||
|
||||
const resourceClassDepends = {
|
||||
[RESOUREGROUP]: [],
|
||||
[VIRTUALNETWORK]: [RESOUREGROUP],
|
||||
[SUBNET]: [VIRTUALNETWORK, RESOUREGROUP],
|
||||
[STORAGEACCOUNT]: [RESOUREGROUP],
|
||||
[NETWORKINTERFACE]: [VIRTUALNETWORK, RESOUREGROUP],
|
||||
};
|
||||
|
||||
const resourceLanguages = {
|
||||
[RESOUREGROUP]: ['resource-group', 'resourceGroupName', 'resourceGroups'],
|
||||
[VIRTUALNETWORK]: ['virtual-network', 'virtualNetworkName', 'virtualNetworks'],
|
||||
[SUBNET]: ['subnet', 'subnetName', 'subnets'],
|
||||
[STORAGEACCOUNT]: ['storage-account', 'storageAccountName', 'storageAccounts'],
|
||||
[NETWORKINTERFACE]: ['network-interface', 'networkInterfaceName', 'networkInterfaces'],
|
||||
};
|
||||
|
||||
const resourceClassKeys = {
|
||||
[RESOUREGROUP]: 'rg',
|
||||
[VIRTUALNETWORK]: 'vn',
|
||||
[SUBNET]: 'sn',
|
||||
[STORAGEACCOUNT]: 'sa',
|
||||
[NETWORKINTERFACE]: 'nic',
|
||||
};
|
||||
const RESOUREGROUP = 'resourceGroups';
|
||||
const STORAGEACCOUNT = 'storageAccounts';
|
||||
|
||||
export function TopoSortResource() {
|
||||
const ret = [];
|
||||
const resources = Object.keys(resourceClassDepends);
|
||||
// let reverse_depends = { };
|
||||
const depends = deepCopy(resourceClassDepends);
|
||||
while (ret.length < Object.keys(resourceClassDepends).length) {
|
||||
const resources = Object.keys(preparerInfos);
|
||||
//let reverse_depends = { };
|
||||
const depends = {};
|
||||
for (const r in preparerInfos) {
|
||||
depends[r] = deepCopy(preparerInfos[r].dependResources);
|
||||
}
|
||||
while (ret.length < Object.keys(preparerInfos).length) {
|
||||
let decreasing = false;
|
||||
for (const a of resources) {
|
||||
if (!isNullOrUndefined(depends[a]) && depends[a].length === 0) {
|
||||
|
@ -199,53 +193,131 @@ export function TopoSortResource() {
|
|||
return ret;
|
||||
}
|
||||
|
||||
class PreparerInfo {
|
||||
export class PreparerConfig {
|
||||
resource: string;
|
||||
fullType: string;
|
||||
abbr: string;
|
||||
alias: string[];
|
||||
forInstance: string;
|
||||
create: string[];
|
||||
delete: string[];
|
||||
inits: { [key: string]: any };
|
||||
}
|
||||
|
||||
export class PreparerInfo {
|
||||
name: string;
|
||||
className: string;
|
||||
dependParameters: string[];
|
||||
dependResources: string[];
|
||||
needGen: boolean;
|
||||
key: string;
|
||||
alias: string[];
|
||||
config: PreparerConfig;
|
||||
public createdObjectNames: string[];
|
||||
public constructor(
|
||||
name: string,
|
||||
className: string,
|
||||
dependParameters: string[],
|
||||
dependResources: string[],
|
||||
key: string,
|
||||
alias: string[],
|
||||
needGen = false,
|
||||
config: PreparerConfig = undefined,
|
||||
) {
|
||||
this.name = name;
|
||||
this.className = className;
|
||||
this.dependParameters = dependParameters;
|
||||
this.dependResources = dependResources;
|
||||
this.createdObjectNames = [];
|
||||
this.key = key;
|
||||
this.alias = alias;
|
||||
this.needGen = needGen;
|
||||
this.config = config;
|
||||
}
|
||||
}
|
||||
const preparerInfos = {
|
||||
[RESOUREGROUP]: new PreparerInfo('ResourceGroupPreparer', RESOUREGROUP, [], []),
|
||||
[VIRTUALNETWORK]: new PreparerInfo(
|
||||
'VirtualNetworkPreparer',
|
||||
VIRTUALNETWORK,
|
||||
['resource_group_key'],
|
||||
[RESOUREGROUP],
|
||||
),
|
||||
[SUBNET]: new PreparerInfo(
|
||||
'VnetSubnetPreparer',
|
||||
SUBNET,
|
||||
['resource_group_key', 'vnet_key'],
|
||||
[RESOUREGROUP, VIRTUALNETWORK],
|
||||
),
|
||||
|
||||
export const preparerInfos: { [key: string]: PreparerInfo } = {
|
||||
[RESOUREGROUP]: new PreparerInfo('ResourceGroupPreparer', RESOUREGROUP, [], [], 'rg', [
|
||||
'resource-group',
|
||||
'resourceGroupName',
|
||||
'resourceGroups',
|
||||
]),
|
||||
[STORAGEACCOUNT]: new PreparerInfo(
|
||||
'StorageAccountPreparer',
|
||||
STORAGEACCOUNT,
|
||||
['resource_group_parameter_name'],
|
||||
[RESOUREGROUP],
|
||||
),
|
||||
[NETWORKINTERFACE]: new PreparerInfo(
|
||||
'VnetNicPreparer',
|
||||
NETWORKINTERFACE,
|
||||
['resource_group_key', 'vnet_key'],
|
||||
[RESOUREGROUP, VIRTUALNETWORK],
|
||||
'sa',
|
||||
['storage-account', 'storageAccountName', 'storageAccounts'],
|
||||
),
|
||||
};
|
||||
|
||||
export function GenPreparerName(className: string): string {
|
||||
const eps = new EnglishPluralizationService();
|
||||
return Capitalize(eps.singularize(ToCamelCase(ToSnakeCase(className)))) + 'Preparer';
|
||||
}
|
||||
|
||||
export function GenPreparerDependParamName(className: string): string {
|
||||
const eps = new EnglishPluralizationService();
|
||||
return ToSnakeCase(eps.singularize(className)) + '_key';
|
||||
}
|
||||
|
||||
export function LoadPreparesConfig(preparers: { [key: string]: PreparerConfig }) {
|
||||
if (isNullOrUndefined(preparers)) return;
|
||||
for (const resourceClass in preparers) {
|
||||
// let resourceClass: string = config.resource;
|
||||
const config = preparers[resourceClass];
|
||||
let classKey = config.abbr;
|
||||
if (isNullOrUndefined(classKey)) {
|
||||
classKey = resourceClass;
|
||||
}
|
||||
// resourceClassKeys[resourceClass] = classKey;
|
||||
// resourceLanguages[resourceClass] = [resourceClass];
|
||||
const alias = [resourceClass];
|
||||
if (config.alias) {
|
||||
alias.push(...config.alias);
|
||||
}
|
||||
if (typeof config.create === 'string') {
|
||||
config.create = [config.create];
|
||||
}
|
||||
if (typeof config.delete === 'string') {
|
||||
config.delete = [config.delete];
|
||||
}
|
||||
if (isNullOrUndefined(config.inits)) {
|
||||
config.inits = {};
|
||||
}
|
||||
if (Object.getOwnPropertyNames(config.inits).indexOf('name_prefix') < 0) {
|
||||
config.inits['name_prefix'] = 'clitest.' + classKey;
|
||||
}
|
||||
if (Object.getOwnPropertyNames(config.inits).indexOf('random_name_length') < 0) {
|
||||
config.inits['random_name_length'] = 24;
|
||||
}
|
||||
let depends: string[] = config.create
|
||||
.concat(config.delete)
|
||||
.join('\n')
|
||||
.match(/\{.*?\}/g);
|
||||
depends = depends.map((x: string) => {
|
||||
return x.substr(1, x.length - 2);
|
||||
});
|
||||
depends = Array.from(new Set(depends));
|
||||
const nameIndex = depends.indexOf('name');
|
||||
if (nameIndex !== -1) {
|
||||
depends.splice(nameIndex, 1);
|
||||
}
|
||||
// resourceClassDepends[resourceClass] = depends;
|
||||
preparerInfos[resourceClass] = new PreparerInfo(
|
||||
GenPreparerName(resourceClass),
|
||||
resourceClass,
|
||||
depends.map(GenPreparerDependParamName),
|
||||
depends,
|
||||
classKey,
|
||||
alias,
|
||||
true,
|
||||
config,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export class PreparerEntity {
|
||||
info: PreparerInfo;
|
||||
objectName: string;
|
||||
|
@ -481,11 +553,26 @@ function singlizeLast(word: string) {
|
|||
return ws.join('-');
|
||||
}
|
||||
|
||||
const keyCache = {}; // className+objectname->key
|
||||
const keyCache = {}; //class_name+objectname->key
|
||||
const formalCache = {};
|
||||
const keySeq = {}; // className ->seq
|
||||
const keySeq = {}; // class_name ->seq
|
||||
const uniqueNames = {};
|
||||
|
||||
function addUniqueName(className: string, objectName: string): string {
|
||||
let ret = objectName;
|
||||
if (azOptions?.[CodeGenConstants.testUniqueResource]) {
|
||||
if (Object.prototype.hasOwnProperty.call(uniqueNames, className)) {
|
||||
ret = uniqueNames[className];
|
||||
} else {
|
||||
uniqueNames[className] = ret;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
export function getResourceKey(className: string, objectName: string, formalName = false): string {
|
||||
const longKey = (resourceClassKeys[className] || className) + '_' + objectName;
|
||||
const originObjectName = addUniqueName(className, objectName);
|
||||
const longKey = (preparerInfos[className]?.key || className) + '_' + originObjectName;
|
||||
if (formalName && longKey in formalCache) {
|
||||
return formalCache[longKey];
|
||||
}
|
||||
|
@ -494,7 +581,7 @@ export function getResourceKey(className: string, objectName: string, formalName
|
|||
}
|
||||
|
||||
if (Object.prototype.hasOwnProperty.call(keySeq, className)) {
|
||||
const key = (resourceClassKeys[className] || className) + '_' + keySeq[className];
|
||||
const key = (preparerInfos[className]?.key || className) + '_' + keySeq[className];
|
||||
keySeq[className] += 1;
|
||||
formalCache[longKey] = ToCamelCase(`my-${singlizeLast(className)}${keySeq[className] - 1}`);
|
||||
if (preparerInfos[className]?.name) {
|
||||
|
@ -510,11 +597,11 @@ export function getResourceKey(className: string, objectName: string, formalName
|
|||
formalCache[longKey] = ToCamelCase(`my-${singlizeLast(className)}`);
|
||||
if (preparerInfos[className]?.name) {
|
||||
// is external resource
|
||||
keyCache[longKey] = resourceClassKeys[className] || className;
|
||||
keyCache[longKey] = preparerInfos[className]?.key || className;
|
||||
} else {
|
||||
// is internal resource
|
||||
// generally, internal resource objectName is shorter than className
|
||||
// keyCache[longKey] = objectName;
|
||||
// generally, internal resource object_name is shorter than class_name
|
||||
// keyCache[longKey] = object_name;
|
||||
keyCache[longKey] = ToCamelCase(`my-${singlizeLast(className)}`);
|
||||
}
|
||||
}
|
||||
|
@ -544,8 +631,6 @@ export class ResourcePool {
|
|||
entitys: PreparerEntity[],
|
||||
preparings: string[][],
|
||||
) {
|
||||
if (className === SUBNET) return; // use default subnet, no need to prepare it.
|
||||
|
||||
function inPreparings(): boolean {
|
||||
for (const [pCName, pOName] of preparings) {
|
||||
if (className === pCName && objectName === pOName) return true;
|
||||
|
@ -660,6 +745,7 @@ export class ResourcePool {
|
|||
objectName: string,
|
||||
parentObject: ResourceObject,
|
||||
): ResourceObject {
|
||||
objectName = addUniqueName(className, objectName);
|
||||
const resources: Map<string, ResourceClass> = parentObject
|
||||
? parentObject.subResources
|
||||
: this.root;
|
||||
|
@ -806,6 +892,7 @@ export class ResourcePool {
|
|||
}
|
||||
|
||||
public addMapResource(className: string, objectName: string): ResourceObject {
|
||||
objectName = addUniqueName(className, objectName);
|
||||
const resourceObject = this.findTreeResource(className, objectName, this.root);
|
||||
if (resourceObject) {
|
||||
return resourceObject;
|
||||
|
@ -822,14 +909,53 @@ export class ResourcePool {
|
|||
return this.map[className].objects[objectName];
|
||||
}
|
||||
|
||||
public isResource(language: string): string | null {
|
||||
public matchFullType(preparerConfig: PreparerConfig, instanceName: string, fullType: string[]) {
|
||||
const configedFullType = preparerConfig?.fullType?.split('/');
|
||||
if (isNullOrUndefined(configedFullType) || isNullOrUndefined(fullType)) return true;
|
||||
if (configedFullType.length != fullType.length) return false;
|
||||
for (let i = 0; i < configedFullType.length; i++) {
|
||||
const resourceA = configedFullType[i];
|
||||
const resourceB = fullType[i];
|
||||
if (
|
||||
resourceA.toLowerCase() != resourceB.toLowerCase() &&
|
||||
this.isResource(resourceA, instanceName) != this.isResource(resourceB, instanceName)
|
||||
)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public isResource(
|
||||
language: string,
|
||||
instanceName: string,
|
||||
fullType: string[] = undefined,
|
||||
): string | null {
|
||||
if (language.startsWith('--')) language = language.substr(2);
|
||||
for (const resource in resourceLanguages) {
|
||||
for (const resourceLanguage of resourceLanguages[resource]) {
|
||||
if (resourceLanguage.toLowerCase() === language.toLowerCase()) return resource;
|
||||
let classResource = null;
|
||||
let instanceResource = null;
|
||||
for (const resource in preparerInfos) {
|
||||
for (const resourceLanguage of preparerInfos[resource]?.alias || []) {
|
||||
if (
|
||||
resourceLanguage.toLowerCase() == language.toLowerCase() &&
|
||||
this.matchFullType(preparerInfos[resource]?.config, instanceName, fullType)
|
||||
) {
|
||||
if (isNullOrUndefined(preparerInfos[resource]?.config?.forInstance)) {
|
||||
classResource = resource;
|
||||
} else if (
|
||||
typeof instanceName === 'string' &&
|
||||
preparerInfos[resource]?.config?.forInstance?.toLowerCase() ==
|
||||
instanceName?.toLowerCase()
|
||||
) {
|
||||
instanceResource = resource;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
if (isNullOrUndefined(instanceName)) {
|
||||
return classResource;
|
||||
}
|
||||
|
||||
return instanceResource || classResource;
|
||||
}
|
||||
|
||||
private formatable(str: string, placeholders: string[]) {
|
||||
|
@ -837,6 +963,17 @@ export class ResourcePool {
|
|||
for (const placeholder of placeholders) {
|
||||
str = str.split(`{${placeholder}}`).join(placeholder);
|
||||
}
|
||||
|
||||
// apply replace in testResource scenario
|
||||
let p = str.indexOf('$(');
|
||||
let q = 0;
|
||||
while (p >= 0 && q >= 0) {
|
||||
q = str.indexOf(')', p);
|
||||
if (q >= 0) {
|
||||
str = str.slice(0, p) + '{' + str.slice(p + 2, q) + '}' + str.slice(q + 1);
|
||||
p = str.indexOf('$(');
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
|
@ -1048,21 +1185,24 @@ export class ResourcePool {
|
|||
this.useSubscription = true;
|
||||
let i = 3;
|
||||
let resourceObject: ResourceObject = null;
|
||||
const fullType: string[] = [];
|
||||
while (i < nodes.length - 1) {
|
||||
const resource = this.isResource(nodes[i]);
|
||||
if (nodes[i].toLowerCase() == 'providers') {
|
||||
fullType.push(nodes[i + 1].toLowerCase());
|
||||
} else {
|
||||
if (fullType.length >= 1) {
|
||||
fullType.push(nodes[i].toLowerCase());
|
||||
}
|
||||
}
|
||||
const resource = this.isResource(nodes[i], nodes[i + 1], fullType);
|
||||
if (resource) {
|
||||
if (resource === SUBNET) {
|
||||
// since the subnet can't be created with rand name, just use the dfault one.
|
||||
nodes[i + 1] = 'default';
|
||||
} else {
|
||||
resourceObject = this.addTreeResource(resource, nodes[i + 1], resourceObject);
|
||||
nodes[i + 1] = resourceObject.placeholder(isTest);
|
||||
if (placeholders.indexOf(resourceObject.placeholder(isTest)) < 0) {
|
||||
placeholders.push(resourceObject.placeholder(isTest));
|
||||
}
|
||||
if (resources.indexOf(resource) < 0) {
|
||||
resources.push(resource);
|
||||
}
|
||||
resourceObject = this.addTreeResource(resource, nodes[i + 1], resourceObject);
|
||||
nodes[i + 1] = resourceObject.placeholder(isTest);
|
||||
if (placeholders.indexOf(resourceObject.placeholder(isTest)) < 0) {
|
||||
placeholders.push(resourceObject.placeholder(isTest));
|
||||
}
|
||||
if (resources.indexOf(resource) < 0) {
|
||||
resources.push(resource);
|
||||
}
|
||||
} else {
|
||||
nodes[i + 1] = this.getPlaceholder(nodes[i + 1], isTest);
|
||||
|
@ -1086,13 +1226,9 @@ export class ResourcePool {
|
|||
if (paramName.startsWith('--')) {
|
||||
paramName = paramName.substr(2);
|
||||
}
|
||||
const resource = this.isResource(paramName);
|
||||
const resource = this.isResource(paramName, paramValue);
|
||||
if (!resource) {
|
||||
return this.getPlaceholder(paramValue, isTest);
|
||||
}
|
||||
if (resource === SUBNET) {
|
||||
// since the subnet can't be created with rand name, just use the dfault one.
|
||||
return 'default';
|
||||
return this.getPlaceholder(paramValue, isTest, null, resource);
|
||||
}
|
||||
const resourceObject = this.addMapResource(resource, paramValue);
|
||||
if (resourceObject) {
|
||||
|
@ -1106,9 +1242,11 @@ export class ResourcePool {
|
|||
objectName: string,
|
||||
isTest: boolean,
|
||||
placeholders: string[] = null,
|
||||
targetClassName = undefined,
|
||||
): string {
|
||||
// find in MapResource
|
||||
for (const className in this.map) {
|
||||
if (!isNullOrUndefined(targetClassName) && className != targetClassName) continue;
|
||||
if (
|
||||
!isNullOrUndefined(this.map[className].objects) &&
|
||||
Object.prototype.hasOwnProperty.call(this.map[className].objects, objectName)
|
||||
|
@ -1124,7 +1262,7 @@ export class ResourcePool {
|
|||
}
|
||||
|
||||
// find in TreeResource
|
||||
const resourceObject = this.findTreeResource(null, objectName, this.root);
|
||||
const resourceObject = this.findTreeResource(targetClassName, objectName, this.root);
|
||||
if (resourceObject) {
|
||||
const ret = resourceObject.placeholder(isTest);
|
||||
if (!isNullOrUndefined(placeholders)) {
|
||||
|
@ -1147,10 +1285,24 @@ export class ResourcePool {
|
|||
return objectName;
|
||||
}
|
||||
|
||||
public addResourcesInfo(resources: any) {
|
||||
public addResourcesInfo(resources: Record<string, any>) {
|
||||
for (const className in resources) {
|
||||
resourceClassKeys[className] = className; // TODO: brief key for internal resources
|
||||
resourceLanguages[className] = resources[className];
|
||||
if (!(className in preparerInfos)) {
|
||||
preparerInfos[className] = new PreparerInfo(
|
||||
null,
|
||||
className,
|
||||
[],
|
||||
[],
|
||||
className,
|
||||
resources[className],
|
||||
);
|
||||
} else {
|
||||
preparerInfos[className].key = className; // TODO: brief key for internal resources
|
||||
for (const a of resources[className]) {
|
||||
if (preparerInfos[className].alias.indexOf(a) < 0)
|
||||
preparerInfos[className].alias.push(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1160,21 +1312,21 @@ export class ResourcePool {
|
|||
dependParameters: string[],
|
||||
createdObjectNames: string[],
|
||||
) {
|
||||
if (!(resourceClassName in resourceClassDepends)) {
|
||||
resourceClassDepends[resourceClassName] = deepCopy(dependResources);
|
||||
if (!(resourceClassName in preparerInfos)) {
|
||||
preparerInfos[resourceClassName] = new PreparerInfo(
|
||||
null,
|
||||
resourceClassName,
|
||||
dependParameters,
|
||||
dependResources,
|
||||
deepCopy(dependResources) as string[],
|
||||
resourceClassName,
|
||||
[resourceClassName],
|
||||
);
|
||||
} else {
|
||||
for (let i = 0; i < dependResources.length; i++) {
|
||||
const dependResource = dependResources[i];
|
||||
if (resourceClassDepends[resourceClassName].indexOf(dependResource) < 0) {
|
||||
resourceClassDepends[resourceClassName].push(dependResource);
|
||||
if (preparerInfos[resourceClassName].dependResources.indexOf(dependResource) < 0) {
|
||||
preparerInfos[resourceClassName].dependParameters.push(dependParameters[i]);
|
||||
preparerInfos[resourceClassName].dependResources.push(dependResources[i]);
|
||||
preparerInfos[resourceClassName].dependResources.push(dependResource);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1187,7 +1339,7 @@ export class ResourcePool {
|
|||
}
|
||||
|
||||
public isDependResource(child: string, parent: string) {
|
||||
const depends = resourceClassDepends[child];
|
||||
const depends = preparerInfos[child].dependResources;
|
||||
return depends && depends.indexOf(parent) >= 0;
|
||||
}
|
||||
|
||||
|
@ -1210,4 +1362,115 @@ export class ResourcePool {
|
|||
resource.exampleParams = [];
|
||||
}
|
||||
}
|
||||
|
||||
public testDefs: TestDefinitionFile[] = [];
|
||||
public async loadTestResources() {
|
||||
function getSwaggerFolder() {
|
||||
const parentsOptions = AzConfiguration.getValue(CodeGenConstants.parents);
|
||||
for (const k in parentsOptions) {
|
||||
const v: string = parentsOptions[k];
|
||||
if (k.endsWith('.json') && typeof v === 'string' && v.startsWith('file:///')) {
|
||||
if (process.platform.toLowerCase().startsWith('win')) {
|
||||
return v.slice('file:///'.length);
|
||||
}
|
||||
return v.slice('file:///'.length - 1);
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const loader = new TestResourceLoader({
|
||||
useJsonParser: false,
|
||||
checkUnderFileRoot: false,
|
||||
fileRoot: getSwaggerFolder(),
|
||||
swaggerFilePaths: AzConfiguration.getValue(CodeGenConstants.inputFile),
|
||||
});
|
||||
|
||||
for (const testResource of AzConfiguration.getValue(CodeGenConstants.testResources) || []) {
|
||||
const testDef = await loader.load(testResource[CodeGenConstants.test]);
|
||||
this.testDefs.push(testDef);
|
||||
}
|
||||
}
|
||||
|
||||
public generateArmTemplate(files: Record<string, any>, templateFolder: string) {
|
||||
for (const testDef of this.testDefs) {
|
||||
for (let prepareStep of testDef.prepareSteps) {
|
||||
if ((prepareStep as TestStepArmTemplateDeployment).armTemplateDeployment) {
|
||||
prepareStep = prepareStep as TestStepArmTemplateDeployment;
|
||||
files[
|
||||
path.join(templateFolder, prepareStep.armTemplateDeployment)
|
||||
] = JSON.stringify(prepareStep.armTemplatePayload, null, 4).split('\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public setupWithArmTemplate(): string[] {
|
||||
const ret: string[] = [];
|
||||
for (const testDef of this.testDefs) {
|
||||
for (const prepareStep of testDef.prepareSteps) {
|
||||
if ((prepareStep as TestStepArmTemplateDeployment).armTemplateDeployment) {
|
||||
const templateFile = (prepareStep as TestStepArmTemplateDeployment)
|
||||
.armTemplateDeployment;
|
||||
ret.push(
|
||||
` cmd = "az deployment group create --resource-group {{rg}} --template-file \\"{}\\"".format(os.path.join(TEST_DIR, '${templateFile}'))`,
|
||||
);
|
||||
ret.push(` o = test.cmd(cmd).get_output_in_json()`);
|
||||
ret.push(
|
||||
` kwargs = {k: v.get("value") for k, v in o.get('properties', {}).get('outputs', {}).items()}`,
|
||||
);
|
||||
ret.push(` test.kwargs.update(kwargs)`);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ret.length == 0) {
|
||||
ret.push(' pass');
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public generateTestScenario() {
|
||||
const cliScenario = {};
|
||||
for (const testDef of this.testDefs) {
|
||||
for (const testScenario of testDef.testScenarios) {
|
||||
cliScenario[testScenario.description] = [];
|
||||
for (let step of testScenario.steps) {
|
||||
if ((step as TestStepExampleFileRestCall).exampleId) {
|
||||
step = step as TestStepExampleFileRestCall;
|
||||
this.applyTestResourceReplace(step);
|
||||
cliScenario[testScenario.description].push({
|
||||
name: step.exampleId,
|
||||
step: step,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return cliScenario;
|
||||
}
|
||||
|
||||
public get hasTestResourceScenario(): boolean {
|
||||
return this.testDefs.length > 0;
|
||||
}
|
||||
|
||||
public applyTestResourceReplace(step: TestStepExampleFileRestCall) {
|
||||
for (const replace of step.replace) {
|
||||
if (replace.pathInBody) {
|
||||
for (const k in step.exampleTemplate.parameters) {
|
||||
if (checkNested(step.exampleTemplate.parameters[k], replace.pathInBody)) {
|
||||
setPathValue(
|
||||
step.exampleTemplate.parameters[k],
|
||||
replace.pathInBody,
|
||||
replace.to,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (replace.pathInExample) {
|
||||
if (checkNested(step.exampleTemplate, replace.pathInBody)) {
|
||||
setPathValue(step.exampleTemplate, replace.pathInBody, replace.to);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,152 +8,37 @@
|
|||
# regenerated.
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
import os
|
||||
from datetime import datetime
|
||||
from azure_devtools.scenario_tests import SingleValueReplacer
|
||||
from azure.cli.testsdk.preparers import NoTrafficRecordingPreparer
|
||||
from azure.cli.testsdk.exceptions import CliTestError
|
||||
from azure.cli.testsdk.reverse_dependency import get_dummy_cli
|
||||
{% for preparerData in preparers %}
|
||||
|
||||
|
||||
KEY_RESOURCE_GROUP = 'rg'
|
||||
KEY_VIRTUAL_NETWORK = 'vnet'
|
||||
KEY_VNET_SUBNET = 'subnet'
|
||||
KEY_VNET_NIC = 'nic'
|
||||
|
||||
|
||||
class VirtualNetworkPreparer(NoTrafficRecordingPreparer, SingleValueReplacer):
|
||||
def __init__(self, name_prefix='clitest.vn',
|
||||
parameter_name='virtual_network',
|
||||
resource_group_name=None,
|
||||
resource_group_key=KEY_RESOURCE_GROUP,
|
||||
dev_setting_name='AZURE_CLI_TEST_DEV_VIRTUAL_NETWORK_NAME',
|
||||
random_name_length=24, key=KEY_VIRTUAL_NETWORK):
|
||||
if ' ' in name_prefix:
|
||||
raise CliTestError(
|
||||
'Error: Space character in name prefix \'%s\'' % name_prefix)
|
||||
super(VirtualNetworkPreparer, self).__init__(
|
||||
name_prefix, random_name_length)
|
||||
class {{preparerData.className}}(NoTrafficRecordingPreparer, SingleValueReplacer):
|
||||
def __init__(self,
|
||||
{%- for paramPair in preparerData.initParamPairs %}
|
||||
{{paramPair[0]}}={{paramPair[1]}},
|
||||
{%- endfor %}
|
||||
):
|
||||
super({{preparerData.className}}, self).__init__(name_prefix, random_name_length)
|
||||
self.cli_ctx = get_dummy_cli()
|
||||
self.parameter_name = parameter_name
|
||||
self.key = key
|
||||
self.resource_group_name = resource_group_name
|
||||
self.resource_group_key = resource_group_key
|
||||
self.dev_setting_name = os.environ.get(dev_setting_name, None)
|
||||
{%- for attribute in preparerData.attributes %}
|
||||
self.{{attribute}} = {{attribute}}
|
||||
{%- endfor %}
|
||||
|
||||
def create_resource(self, name, **_):
|
||||
if self.dev_setting_name:
|
||||
return {self.parameter_name: self.dev_setting_name, }
|
||||
|
||||
if not self.resource_group_name:
|
||||
self.resource_group_name = self.test_class_instance.kwargs.get(
|
||||
self.resource_group_key)
|
||||
if not self.resource_group_name:
|
||||
raise CliTestError("Error: No resource group configured!")
|
||||
|
||||
tags = {'product': 'azurecli', 'cause': 'automation',
|
||||
'date': datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ')}
|
||||
if 'ENV_JOB_NAME' in os.environ:
|
||||
tags['job'] = os.environ['ENV_JOB_NAME']
|
||||
tags = ' '.join(['{}={}'.format(key, value)
|
||||
for key, value in tags.items()])
|
||||
template = 'az network vnet create --resource-group {} --name {} --subnet-name default --tag ' + tags
|
||||
self.live_only_execute(self.cli_ctx, template.format(
|
||||
self.resource_group_name, name))
|
||||
|
||||
cmd = '{{preparerData.createFunc.cmdTemplate}}'
|
||||
{% if preparerData.createFunc.cmdFormats.length > 0 -%}
|
||||
cmd = cmd.format({{preparerData.createFunc.cmdFormats|join(", ")}})
|
||||
{% endif -%}
|
||||
self.live_only_execute(self.cli_ctx, cmd)
|
||||
self.test_class_instance.kwargs[self.key] = name
|
||||
return {self.parameter_name: name}
|
||||
return {self.key: name}
|
||||
|
||||
def remove_resource(self, name, **_):
|
||||
# delete vnet if test is being recorded and if the vnet is not a dev rg
|
||||
if not self.dev_setting_name:
|
||||
self.live_only_execute(
|
||||
self.cli_ctx,
|
||||
'az network vnet delete --name {} --resource-group {}'.format(name, self.resource_group_name))
|
||||
|
||||
|
||||
class VnetSubnetPreparer(NoTrafficRecordingPreparer, SingleValueReplacer):
|
||||
def __init__(self, name_prefix='clitest.vn',
|
||||
parameter_name='subnet',
|
||||
resource_group_key=KEY_RESOURCE_GROUP,
|
||||
vnet_key=KEY_VIRTUAL_NETWORK,
|
||||
address_prefixes="11.0.0.0/24",
|
||||
dev_setting_name='AZURE_CLI_TEST_DEV_VNET_SUBNET_NAME',
|
||||
key=KEY_VNET_SUBNET):
|
||||
if ' ' in name_prefix:
|
||||
raise CliTestError(
|
||||
'Error: Space character in name prefix \'%s\'' % name_prefix)
|
||||
super(VnetSubnetPreparer, self).__init__(name_prefix, 15)
|
||||
self.cli_ctx = get_dummy_cli()
|
||||
self.parameter_name = parameter_name
|
||||
self.key = key
|
||||
self.resource_group = [resource_group_key, None]
|
||||
self.vnet = [vnet_key, None]
|
||||
self.address_prefixes = address_prefixes
|
||||
self.dev_setting_name = os.environ.get(dev_setting_name, None)
|
||||
|
||||
def create_resource(self, name, **_):
|
||||
if self.dev_setting_name:
|
||||
return {self.parameter_name: self.dev_setting_name, }
|
||||
|
||||
if not self.resource_group[1]:
|
||||
self.resource_group[1] = self.test_class_instance.kwargs.get(
|
||||
self.resource_group[0])
|
||||
if not self.resource_group[1]:
|
||||
raise CliTestError("Error: No resource group configured!")
|
||||
if not self.vnet[1]:
|
||||
self.vnet[1] = self.test_class_instance.kwargs.get(self.vnet[0])
|
||||
if not self.vnet[1]:
|
||||
raise CliTestError("Error: No vnet configured!")
|
||||
|
||||
self.test_class_instance.kwargs[self.key] = 'default'
|
||||
return {self.parameter_name: name}
|
||||
|
||||
def remove_resource(self, name, **_):
|
||||
pass
|
||||
|
||||
|
||||
class VnetNicPreparer(NoTrafficRecordingPreparer, SingleValueReplacer):
|
||||
def __init__(self, name_prefix='clitest.nic',
|
||||
parameter_name='subnet',
|
||||
resource_group_key=KEY_RESOURCE_GROUP,
|
||||
vnet_key=KEY_VIRTUAL_NETWORK,
|
||||
dev_setting_name='AZURE_CLI_TEST_DEV_VNET_NIC_NAME',
|
||||
key=KEY_VNET_NIC):
|
||||
if ' ' in name_prefix:
|
||||
raise CliTestError(
|
||||
'Error: Space character in name prefix \'%s\'' % name_prefix)
|
||||
super(VnetNicPreparer, self).__init__(name_prefix, 15)
|
||||
self.cli_ctx = get_dummy_cli()
|
||||
self.parameter_name = parameter_name
|
||||
self.key = key
|
||||
self.resource_group = [resource_group_key, None]
|
||||
self.vnet = [vnet_key, None]
|
||||
self.dev_setting_name = os.environ.get(dev_setting_name, None)
|
||||
|
||||
def create_resource(self, name, **_):
|
||||
if self.dev_setting_name:
|
||||
return {self.parameter_name: self.dev_setting_name, }
|
||||
|
||||
if not self.resource_group[1]:
|
||||
self.resource_group[1] = self.test_class_instance.kwargs.get(
|
||||
self.resource_group[0])
|
||||
if not self.resource_group[1]:
|
||||
raise CliTestError("Error: No resource group configured!")
|
||||
if not self.vnet[1]:
|
||||
self.vnet[1] = self.test_class_instance.kwargs.get(self.vnet[0])
|
||||
if not self.vnet[1]:
|
||||
raise CliTestError("Error: No vnet configured!")
|
||||
|
||||
template = 'az network nic create --resource-group {} --name {} --vnet-name {} --subnet default '
|
||||
self.live_only_execute(self.cli_ctx, template.format(
|
||||
self.resource_group[1], name, self.vnet[1]))
|
||||
|
||||
self.test_class_instance.kwargs[self.key] = name
|
||||
return {self.parameter_name: name}
|
||||
|
||||
def remove_resource(self, name, **_):
|
||||
if not self.dev_setting_name:
|
||||
self.live_only_execute(
|
||||
self.cli_ctx,
|
||||
'az network nic delete --name {} --resource-group {}'.format(name, self.resource_group[1]))
|
||||
cmd = '{{preparerData.removeFunc.cmdTemplate}}'
|
||||
{% if preparerData.removeFunc.cmdFormats.length > 0 -%}
|
||||
cmd = cmd.format({{preparerData.removeFunc.cmdFormats|join(", ")}})
|
||||
{% endif -%}
|
||||
self.live_only_execute(self.cli_ctx, cmd)
|
||||
{% endfor -%}
|
|
@ -726,3 +726,39 @@ export function getGitStatus(folder: string) {
|
|||
export function isNullOrUndefined(obj: any) {
|
||||
return obj === null || obj === undefined;
|
||||
}
|
||||
|
||||
export function setPathValue(obj, path, value) {
|
||||
if (Object(obj) !== obj) return obj; // When obj is not an object
|
||||
// If not yet an array, get the keys from the string-path
|
||||
if (!Array.isArray(path)) path = path.toString().match(/[^.[\]]+/g) || [];
|
||||
path.slice(0, -1).reduce(
|
||||
(
|
||||
a,
|
||||
c,
|
||||
i, // Iterate all of them except the last one
|
||||
) =>
|
||||
Object(a[c]) === a[c] // Does the key exist and is its value an object?
|
||||
? // Yes: then follow that path
|
||||
a[c]
|
||||
: // No: create the key. Is the next key a potential array-index?
|
||||
(a[c] =
|
||||
Math.abs(path[i + 1]) >> 0 === +path[i + 1]
|
||||
? [] // Yes: assign a new array object
|
||||
: {}), // No: assign a new plain object
|
||||
obj,
|
||||
)[path[path.length - 1]] = value; // Finally assign the value to the last key
|
||||
return obj; // Return the top-level object to allow chaining
|
||||
}
|
||||
|
||||
export function checkNested(obj, path: string) {
|
||||
if (Object(obj) !== obj) return false; // When obj is not an object
|
||||
const args = path.split('.');
|
||||
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
if (!obj || !(args[i] in obj)) {
|
||||
return false;
|
||||
}
|
||||
obj = obj[args[i]];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -107,7 +107,7 @@ export enum CodeGenConstants {
|
|||
debug = 'debug',
|
||||
use = 'use',
|
||||
directive = 'directive',
|
||||
parents = '_parents',
|
||||
parents = '__parents',
|
||||
azOutputFolder = 'az-output-folder',
|
||||
generationMode = 'generation-mode',
|
||||
clearOutputFolder = 'clear-output-folder',
|
||||
|
@ -121,6 +121,9 @@ export enum CodeGenConstants {
|
|||
azureCliExtFolder = 'azure-cli-extension-folder',
|
||||
pythonSdkOutputFolder = 'python-sdk-output-folder',
|
||||
cliCoreLib = 'cli-core-lib',
|
||||
inputFile = 'input-file',
|
||||
testResources = 'test-resources',
|
||||
preparers = 'preparers',
|
||||
|
||||
// some configuration keys under az section
|
||||
namespace = 'namespace',
|
||||
|
@ -129,6 +132,7 @@ export enum CodeGenConstants {
|
|||
clientBaseUrlBound = 'client-base-url-bound',
|
||||
clientSubscriptionBound = 'client-subscription-bound',
|
||||
clientAuthenticationPolicy = 'client-authentication-policy',
|
||||
testUniqueResource = 'test-unique-resource',
|
||||
|
||||
// default constant values
|
||||
minCliCoreVersion = '2.15.0',
|
||||
|
@ -138,6 +142,9 @@ export enum CodeGenConstants {
|
|||
AZ_ENTRY_CODE_MODEL_NAME = 'az-entry-code-model.yaml',
|
||||
PYLINT_MAX_CODE_LENGTH = 119,
|
||||
PYLINT_MAX_OPERATION_TEMPLATE_LENGTH = 92,
|
||||
|
||||
//configuration keys under test-resources section
|
||||
test = 'test',
|
||||
}
|
||||
|
||||
export interface AzextMetadata {
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
## Test-Resources
|
||||
|
||||
These settings is for the test prerequisites.
|
||||
|
||||
``` yaml
|
||||
test-resources:
|
||||
- test: ../input/test-scenarios/testDataExport.yaml
|
||||
```
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
},
|
||||
"variables": {
|
||||
"storageAccountName": "[uniqueString(resourceGroup().id)]"
|
||||
},
|
||||
"resources": [{
|
||||
"type": "Microsoft.Storage/storageAccounts",
|
||||
"apiVersion": "2019-06-01",
|
||||
"name": "[variables('storageAccountName')]",
|
||||
"kind": "StorageV2",
|
||||
"location": "[resourceGroup().location]",
|
||||
"sku": {
|
||||
"name": "Standard_LRS"
|
||||
}
|
||||
}],
|
||||
"outputs": {
|
||||
"storageAccountId": {
|
||||
"type": "string",
|
||||
"value": "[resourceId('Microsoft.Storage/storageAccounts',variables('storageAccountName'))]"
|
||||
},
|
||||
"workspaceName": {
|
||||
"type": "string",
|
||||
"value": "[uniqueString(resourceGroup().id)]"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
scope: ResourceGroup
|
||||
|
||||
prepareSteps:
|
||||
- armTemplateDeployment: depSto.json
|
||||
|
||||
testScenarios:
|
||||
- description: FakedTestScenario
|
||||
steps:
|
||||
- exampleFile: ../examples/Create_AttestationProvider.json
|
||||
- exampleFile: ../examples/Update_AttestationProvider.json
|
||||
replace:
|
||||
- pathInBody: tags.Property1
|
||||
to: $(storageAccountId)
|
||||
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {},
|
||||
"variables": {
|
||||
"storageAccountName": "[uniqueString(resourceGroup().id)]"
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"type": "Microsoft.Storage/storageAccounts",
|
||||
"apiVersion": "2019-06-01",
|
||||
"name": "[variables('storageAccountName')]",
|
||||
"kind": "StorageV2",
|
||||
"location": "[resourceGroup().location]",
|
||||
"sku": {
|
||||
"name": "Standard_LRS"
|
||||
}
|
||||
}
|
||||
],
|
||||
"outputs": {
|
||||
"storageAccountId": {
|
||||
"type": "string",
|
||||
"value": "[resourceId('Microsoft.Storage/storageAccounts',variables('storageAccountName'))]"
|
||||
},
|
||||
"workspaceName": {
|
||||
"type": "string",
|
||||
"value": "[uniqueString(resourceGroup().id)]"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,76 +12,25 @@
|
|||
from .. import try_manual
|
||||
|
||||
|
||||
# EXAMPLE: /AttestationProviders/get/AttestationProviders_Get
|
||||
@try_manual
|
||||
def step_attestation_provider_show(test, rg, rg_2, rg_3, checks=None):
|
||||
if checks is None:
|
||||
checks = []
|
||||
test.cmd('az attestation attestation-provider show '
|
||||
'--provider-name "myattestationprovider" '
|
||||
'--resource-group "{rg}"',
|
||||
checks=checks)
|
||||
|
||||
|
||||
# EXAMPLE: /AttestationProviders/get/AttestationProviders_List
|
||||
@try_manual
|
||||
def step_attestation_provider_provider_list(test, rg, rg_2, rg_3, checks=None):
|
||||
if checks is None:
|
||||
checks = []
|
||||
test.cmd('az attestation attestation-provider provider list '
|
||||
'-g ""',
|
||||
checks=checks)
|
||||
|
||||
|
||||
# EXAMPLE: /AttestationProviders/get/AttestationProviders_ListByResourceGroup
|
||||
@try_manual
|
||||
def step_attestation_provider_provider_list2(test, rg, rg_2, rg_3, checks=None):
|
||||
if checks is None:
|
||||
checks = []
|
||||
test.cmd('az attestation attestation-provider provider list '
|
||||
'--resource-group "{rg_2}"',
|
||||
checks=checks)
|
||||
|
||||
|
||||
# EXAMPLE: /AttestationProviders/patch/AttestationProviders_Update
|
||||
@try_manual
|
||||
def step_attestation_provider_update(test, rg, rg_2, rg_3, checks=None):
|
||||
if checks is None:
|
||||
checks = []
|
||||
test.cmd('az attestation attestation-provider update '
|
||||
'--provider-name "myattestationprovider" '
|
||||
'--resource-group "{rg}" '
|
||||
'--tags Property1="Value1" Property2="Value2" Property3="Value3"',
|
||||
checks=checks)
|
||||
|
||||
|
||||
# EXAMPLE: /AttestationProviders/delete/AttestationProviders_Delete
|
||||
@try_manual
|
||||
def step_attestation_provider_delete(test, rg, rg_2, rg_3, checks=None):
|
||||
if checks is None:
|
||||
checks = []
|
||||
test.cmd('az attestation attestation-provider delete -y '
|
||||
'--provider-name "myattestationprovider" '
|
||||
'--resource-group "{rg_3}"',
|
||||
checks=checks)
|
||||
|
||||
|
||||
# EXAMPLE: /Operation/put/AttestationProviders_Create
|
||||
# EXAMPLE: AttestationProviders_Create
|
||||
@try_manual
|
||||
def step_create_provider(test, rg, rg_2, rg_3, checks=None):
|
||||
if checks is None:
|
||||
checks = []
|
||||
test.cmd('az attestation create-provider '
|
||||
'--provider-name "myattestationprovider" '
|
||||
'--resource-group "{rg}"',
|
||||
'--resource-group "{rg_4}" '
|
||||
'--provider-name "myattestationprovider"',
|
||||
checks=checks)
|
||||
|
||||
|
||||
# EXAMPLE: /Operation/get/Operations_List
|
||||
# EXAMPLE: AttestationProviders_Update
|
||||
@try_manual
|
||||
def step_list_operation(test, rg, rg_2, rg_3, checks=None):
|
||||
def step_attestation_provider_update(test, rg, rg_2, rg_3, checks=None):
|
||||
if checks is None:
|
||||
checks = []
|
||||
test.cmd('az attestation list-operation',
|
||||
test.cmd('az attestation attestation-provider update '
|
||||
'--resource-group "{rg_4}" '
|
||||
'--provider-name "myattestationprovider" '
|
||||
'--tags Property1="{storageAccountId}" Property2="Value2" Property3="Value3"',
|
||||
checks=checks)
|
||||
|
||||
|
|
|
@ -7,16 +7,13 @@
|
|||
# Changes may cause incorrect behavior and will be lost if the code is
|
||||
# regenerated.
|
||||
# --------------------------------------------------------------------------
|
||||
# pylint: disable=line-too-long
|
||||
|
||||
import os
|
||||
from azure.cli.testsdk import ScenarioTest
|
||||
from azure.cli.testsdk import ResourceGroupPreparer
|
||||
from .example_steps import step_list_operation
|
||||
from .example_steps import step_create_provider
|
||||
from .example_steps import step_attestation_provider_show
|
||||
from .example_steps import step_attestation_provider_provider_list
|
||||
from .example_steps import step_attestation_provider_provider_list2
|
||||
from .example_steps import step_attestation_provider_delete
|
||||
from .example_steps import step_attestation_provider_update
|
||||
from .. import (
|
||||
try_manual,
|
||||
raise_if,
|
||||
|
@ -29,50 +26,44 @@ TEST_DIR = os.path.abspath(os.path.join(os.path.abspath(__file__), '..'))
|
|||
|
||||
# Env setup_scenario
|
||||
@try_manual
|
||||
def setup_scenario(test, rg, rg_2, rg_3):
|
||||
pass
|
||||
|
||||
|
||||
# Env mytest
|
||||
@try_manual
|
||||
def mytest(test, rg, rg_2, rg_3):
|
||||
pass
|
||||
def setup_scenario(test, rg, rg_2, rg_3, rg_4):
|
||||
cmd = "az deployment group create --resource-group {{rg}} --template-file \"{}\"".format(os.path.join(TEST_DIR, 'depSto.json'))
|
||||
o = test.cmd(cmd).get_output_in_json()
|
||||
kwargs = {k: v.get("value") for k, v in o.get('properties', {}).get('outputs', {}).items()}
|
||||
test.kwargs.update(kwargs)
|
||||
|
||||
|
||||
# Env cleanup_scenario
|
||||
@try_manual
|
||||
def cleanup_scenario(test, rg, rg_2, rg_3):
|
||||
def cleanup_scenario(test, rg, rg_2, rg_3, rg_4):
|
||||
pass
|
||||
|
||||
|
||||
# Testcase: Scenario
|
||||
@try_manual
|
||||
def call_scenario(test, rg, rg_2, rg_3):
|
||||
setup_scenario(test, rg, rg_2, rg_3)
|
||||
step_list_operation(test, rg, rg_2, rg_3, checks=[])
|
||||
step_create_provider(test, rg, rg_2, rg_3, checks=[])
|
||||
step_attestation_provider_show(test, rg, rg_2, rg_3, checks=[])
|
||||
mytest(test, rg, rg_2, rg_3)
|
||||
step_attestation_provider_provider_list(test, rg, rg_2, rg_3, checks=[])
|
||||
step_attestation_provider_provider_list2(test, rg, rg_2, rg_3, checks=[])
|
||||
step_attestation_provider_delete(test, rg, rg_2, rg_3, checks=[])
|
||||
cleanup_scenario(test, rg, rg_2, rg_3)
|
||||
def call_scenario(test, rg, rg_2, rg_3, rg_4):
|
||||
setup_scenario(test, rg, rg_2, rg_3, rg_4)
|
||||
step_create_provider(test, rg, rg_2, rg_3, rg_4, checks=[])
|
||||
step_attestation_provider_update(test, rg, rg_2, rg_3, rg_4, checks=[])
|
||||
cleanup_scenario(test, rg, rg_2, rg_3, rg_4)
|
||||
|
||||
|
||||
# Test class for Scenario
|
||||
@try_manual
|
||||
class AttestationScenarioTest(ScenarioTest):
|
||||
class FakedTestScenarioScenarioTest(ScenarioTest):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(AttestationScenarioTest, self).__init__(*args, **kwargs)
|
||||
super(FakedTestScenarioScenarioTest, self).__init__(*args, **kwargs)
|
||||
|
||||
|
||||
@ResourceGroupPreparer(name_prefix='clitestattestation_MyResourceGroup'[:7], key='rg', parameter_name='rg')
|
||||
@ResourceGroupPreparer(name_prefix='clitestattestation_testrg1'[:7], key='rg_2', parameter_name='rg_2')
|
||||
@ResourceGroupPreparer(name_prefix='clitestattestation_sample-resource-group'[:7], key='rg_3',
|
||||
parameter_name='rg_3')
|
||||
def test_attestation_Scenario(self, rg, rg_2, rg_3):
|
||||
call_scenario(self, rg, rg_2, rg_3)
|
||||
@ResourceGroupPreparer(name_prefix='clitestattestation_$(resourceGroupName)'[:7], key='rg_4',
|
||||
parameter_name='rg_4')
|
||||
def test_FakedTestScenario_Scenario(self, rg, rg_2, rg_3, rg_4):
|
||||
call_scenario(self, rg, rg_2, rg_3, rg_4)
|
||||
calc_coverage(__file__)
|
||||
raise_if()
|
||||
|
|
@ -12,7 +12,7 @@ az extension add --name managed-network
|
|||
##### Create #####
|
||||
```
|
||||
az managed-network mn create \
|
||||
--managed-network "{\\"location\\":\\"eastus\\",\\"tags\\":{},\\"managementGroups\\":[{\\"id\\":\\"/providers/Microsoft.Management/managementGroups/20000000-0001-0000-0000-000000000000\\"},{\\"id\\":\\"/providers/Microsoft.Management/managementGroups/20000000-0002-0000-0000-000000000000\\"}],\\"subscriptions\\":[{\\"id\\":\\"subscriptionA\\"},{\\"id\\":\\"subscriptionB\\"}],\\"virtualNetworks\\":[{\\"id\\":\\"/subscriptions/subscriptionC/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVirtualNetwork\\"},{\\"id\\":\\"/subscriptions/subscriptionC/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVirtualNetwork2\\"}],\\"subnets\\":[{\\"id\\":\\"/subscriptions/subscriptionC/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVirtualNetwork3/subnets/default\\"},{\\"id\\":\\"/subscriptions/subscriptionC/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVirtualNetwork3/subnets/default\\"}]}" \
|
||||
--managed-network "{\\"location\\":\\"eastus\\",\\"tags\\":{},\\"managementGroups\\":[{\\"id\\":\\"/providers/Microsoft.Management/managementGroups/20000000-0001-0000-0000-000000000000\\"},{\\"id\\":\\"/providers/Microsoft.Management/managementGroups/20000000-0002-0000-0000-000000000000\\"}],\\"subscriptions\\":[{\\"id\\":\\"subscriptionA\\"},{\\"id\\":\\"subscriptionB\\"}],\\"virtualNetworks\\":[{\\"id\\":\\"/subscriptions/subscriptionC/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVirtualNetwork\\"},{\\"id\\":\\"/subscriptions/subscriptionC/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVirtualNetwork2\\"}],\\"subnets\\":[{\\"id\\":\\"/subscriptions/subscriptionC/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVirtualNetwork3/subnets/mySubnet\\"},{\\"id\\":\\"/subscriptions/subscriptionC/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVirtualNetwork3/subnets/mySubnet2\\"}]}" \
|
||||
--name "myManagedNetwork" --resource-group "myResourceGroup"
|
||||
```
|
||||
##### List #####
|
||||
|
@ -54,7 +54,7 @@ az managed-network mn scope-assignment delete --scope "subscriptions/subscriptio
|
|||
##### Create #####
|
||||
```
|
||||
az managed-network mn group create --management-groups "[]" \
|
||||
--subnets id="/subscriptions/subscriptionB/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVirtualNetwork/subnets/default" id="/subscriptions/subscriptionB/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVirtualNetwork2/subnets/default" \
|
||||
--subnets id="/subscriptions/subscriptionB/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVirtualNetwork/subnets/mySubnet" id="/subscriptions/subscriptionB/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVirtualNetwork2/subnets/mySubnet2" \
|
||||
--virtual-networks id="/subscriptionB/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/VnetA" \
|
||||
--virtual-networks id="/subscriptionB/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/VnetB" \
|
||||
--group-name "myManagedNetworkGroup" --managed-network-name "myManagedNetwork" --resource-group "myResourceGroup"
|
||||
|
|
|
@ -45,8 +45,8 @@ d\\":\\"/providers/Microsoft.Management/managementGroups/20000000-0002-0000-0000
|
|||
criptionC/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVirtualNetwork\\"},{\\"id\\":\\"\
|
||||
/subscriptions/subscriptionC/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVirtualNetwor\
|
||||
k2\\"}],\\"subnets\\":[{\\"id\\":\\"/subscriptions/subscriptionC/resourceGroups/myResourceGroup/providers/Microsoft.Net\
|
||||
work/virtualNetworks/myVirtualNetwork3/subnets/default\\"},{\\"id\\":\\"/subscriptions/subscriptionC/resourceGroups/myR\
|
||||
esourceGroup/providers/Microsoft.Network/virtualNetworks/myVirtualNetwork3/subnets/default\\"}]}" --name \
|
||||
work/virtualNetworks/myVirtualNetwork3/subnets/mySubnet\\"},{\\"id\\":\\"/subscriptions/subscriptionC/resourceGroups/my\
|
||||
ResourceGroup/providers/Microsoft.Network/virtualNetworks/myVirtualNetwork3/subnets/mySubnet2\\"}]}" --name \
|
||||
"myManagedNetwork" --resource-group "myResourceGroup"
|
||||
"""
|
||||
|
||||
|
@ -188,11 +188,11 @@ helps['managed-network mn group create'] = """
|
|||
- name: Create/Update Managed Network Group
|
||||
text: |-
|
||||
az managed-network mn group create --management-groups "[]" --subnets id="/subscriptions/subscriptionB/r\
|
||||
esourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVirtualNetwork/subnets/default" \
|
||||
esourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVirtualNetwork/subnets/mySubnet" \
|
||||
id="/subscriptions/subscriptionB/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVirtualNe\
|
||||
twork2/subnets/default" --virtual-networks id="/subscriptionB/resourceGroups/myResourceGroup/providers/Microsoft.Networ\
|
||||
k/virtualNetworks/VnetA" --virtual-networks id="/subscriptionB/resourceGroups/myResourceGroup/providers/Microsoft.Netwo\
|
||||
rk/virtualNetworks/VnetB" --group-name "myManagedNetworkGroup" --managed-network-name "myManagedNetwork" \
|
||||
twork2/subnets/mySubnet2" --virtual-networks id="/subscriptionB/resourceGroups/myResourceGroup/providers/Microsoft.Netw\
|
||||
ork/virtualNetworks/VnetA" --virtual-networks id="/subscriptionB/resourceGroups/myResourceGroup/providers/Microsoft.Net\
|
||||
work/virtualNetworks/VnetB" --group-name "myManagedNetworkGroup" --managed-network-name "myManagedNetwork" \
|
||||
--resource-group "myResourceGroup"
|
||||
"""
|
||||
|
||||
|
|
|
@ -25,9 +25,9 @@ def step_mn_create(test, rg, checks=None):
|
|||
'":\\"/subscriptions/{subscription_id}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vn'
|
||||
'}\\"}},{{\\"id\\":\\"/subscriptions/{subscription_id}/resourceGroups/{rg}/providers/Microsoft.Network/vir'
|
||||
'tualNetworks/{vn_2}\\"}}],\\"subnets\\":[{{\\"id\\":\\"/subscriptions/{subscription_id}/resourceGroups/{r'
|
||||
'g}/providers/Microsoft.Network/virtualNetworks/{vn_3}/subnets/default\\"}},{{\\"id\\":\\"/subscriptions/{'
|
||||
'subscription_id}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vn_3}/subnets/default\\'
|
||||
'"}}]}}" '
|
||||
'g}/providers/Microsoft.Network/virtualNetworks/{vn_3}/subnets/{subnets}\\"}},{{\\"id\\":\\"/subscriptions'
|
||||
'/{subscription_id}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNetworks/{vn_3}/subnets/{subnet'
|
||||
's_2}\\"}}]}}" '
|
||||
'--name "{myManagedNetwork}" '
|
||||
'--resource-group "{rg}"',
|
||||
checks=checks)
|
||||
|
@ -108,8 +108,8 @@ def step_mn_group_create(test, rg, checks=None):
|
|||
test.cmd('az managed-network mn group create '
|
||||
'--management-groups "[]" '
|
||||
'--subnets id="/subscriptions/{subscription_id}/resourceGroups/{rg}/providers/Microsoft.Network/virtualNet'
|
||||
'works/{vn}/subnets/default" id="/subscriptions/{subscription_id}/resourceGroups/{rg}/providers/Microsoft.'
|
||||
'Network/virtualNetworks/{vn_2}/subnets/default" '
|
||||
'works/{vn}/subnets/{subnets}" id="/subscriptions/{subscription_id}/resourceGroups/{rg}/providers/Microsof'
|
||||
't.Network/virtualNetworks/{vn_2}/subnets/{subnets_2}" '
|
||||
'--virtual-networks id="/subscriptionB/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualN'
|
||||
'etworks/VnetA" '
|
||||
'--virtual-networks id="/subscriptionB/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualN'
|
||||
|
|
|
@ -8,152 +8,72 @@
|
|||
# regenerated.
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
import os
|
||||
from datetime import datetime
|
||||
from azure_devtools.scenario_tests import SingleValueReplacer
|
||||
from azure.cli.testsdk.preparers import NoTrafficRecordingPreparer
|
||||
from azure.cli.testsdk.exceptions import CliTestError
|
||||
from azure.cli.testsdk.reverse_dependency import get_dummy_cli
|
||||
|
||||
|
||||
KEY_RESOURCE_GROUP = 'rg'
|
||||
KEY_VIRTUAL_NETWORK = 'vnet'
|
||||
KEY_VNET_SUBNET = 'subnet'
|
||||
KEY_VNET_NIC = 'nic'
|
||||
|
||||
|
||||
class VirtualNetworkPreparer(NoTrafficRecordingPreparer, SingleValueReplacer):
|
||||
def __init__(self, name_prefix='clitest.vn',
|
||||
parameter_name='virtual_network',
|
||||
resource_group_name=None,
|
||||
resource_group_key=KEY_RESOURCE_GROUP,
|
||||
dev_setting_name='AZURE_CLI_TEST_DEV_VIRTUAL_NETWORK_NAME',
|
||||
random_name_length=24, key=KEY_VIRTUAL_NETWORK):
|
||||
if ' ' in name_prefix:
|
||||
raise CliTestError(
|
||||
'Error: Space character in name prefix \'%s\'' % name_prefix)
|
||||
super(VirtualNetworkPreparer, self).__init__(
|
||||
name_prefix, random_name_length)
|
||||
def __init__(
|
||||
self,
|
||||
resource_group_key="rg",
|
||||
key="vn",
|
||||
name_prefix="clitest.vn",
|
||||
random_name_length=24,
|
||||
):
|
||||
super(VirtualNetworkPreparer, self).__init__(name_prefix, random_name_length)
|
||||
self.cli_ctx = get_dummy_cli()
|
||||
self.parameter_name = parameter_name
|
||||
self.key = key
|
||||
self.resource_group_name = resource_group_name
|
||||
self.resource_group_key = resource_group_key
|
||||
self.dev_setting_name = os.environ.get(dev_setting_name, None)
|
||||
self.name_prefix = name_prefix
|
||||
self.random_name_length = random_name_length
|
||||
|
||||
def create_resource(self, name, **_):
|
||||
if self.dev_setting_name:
|
||||
return {self.parameter_name: self.dev_setting_name, }
|
||||
|
||||
if not self.resource_group_name:
|
||||
self.resource_group_name = self.test_class_instance.kwargs.get(
|
||||
self.resource_group_key)
|
||||
if not self.resource_group_name:
|
||||
raise CliTestError("Error: No resource group configured!")
|
||||
|
||||
tags = {'product': 'azurecli', 'cause': 'automation',
|
||||
'date': datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ')}
|
||||
if 'ENV_JOB_NAME' in os.environ:
|
||||
tags['job'] = os.environ['ENV_JOB_NAME']
|
||||
tags = ' '.join(['{}={}'.format(key, value)
|
||||
for key, value in tags.items()])
|
||||
template = 'az network vnet create --resource-group {} --name {} --subnet-name default --tag ' + tags
|
||||
self.live_only_execute(self.cli_ctx, template.format(
|
||||
self.resource_group_name, name))
|
||||
|
||||
cmd = 'az network vnet create --resource-group {} --name {}'
|
||||
cmd = cmd.format(self.test_class_instance.kwargs.get(self.resource_group_key), name)
|
||||
self.live_only_execute(self.cli_ctx, cmd)
|
||||
self.test_class_instance.kwargs[self.key] = name
|
||||
return {self.parameter_name: name}
|
||||
return {self.key: name}
|
||||
|
||||
def remove_resource(self, name, **_):
|
||||
# delete vnet if test is being recorded and if the vnet is not a dev rg
|
||||
if not self.dev_setting_name:
|
||||
self.live_only_execute(
|
||||
self.cli_ctx,
|
||||
'az network vnet delete --name {} --resource-group {}'.format(name, self.resource_group_name))
|
||||
cmd = 'az network vnet delete --resource-group {} --name {}'
|
||||
cmd = cmd.format(self.test_class_instance.kwargs.get(self.resource_group_key), name)
|
||||
self.live_only_execute(self.cli_ctx, cmd)
|
||||
|
||||
|
||||
class VnetSubnetPreparer(NoTrafficRecordingPreparer, SingleValueReplacer):
|
||||
def __init__(self, name_prefix='clitest.vn',
|
||||
parameter_name='subnet',
|
||||
resource_group_key=KEY_RESOURCE_GROUP,
|
||||
vnet_key=KEY_VIRTUAL_NETWORK,
|
||||
address_prefixes="11.0.0.0/24",
|
||||
dev_setting_name='AZURE_CLI_TEST_DEV_VNET_SUBNET_NAME',
|
||||
key=KEY_VNET_SUBNET):
|
||||
if ' ' in name_prefix:
|
||||
raise CliTestError(
|
||||
'Error: Space character in name prefix \'%s\'' % name_prefix)
|
||||
super(VnetSubnetPreparer, self).__init__(name_prefix, 15)
|
||||
class SubnetPreparer(NoTrafficRecordingPreparer, SingleValueReplacer):
|
||||
def __init__(
|
||||
self,
|
||||
virtual_network_key="vn",
|
||||
resource_group_key="rg",
|
||||
key="subnets",
|
||||
name_prefix="clitest.subnets",
|
||||
random_name_length=24,
|
||||
):
|
||||
super(SubnetPreparer, self).__init__(name_prefix, random_name_length)
|
||||
self.cli_ctx = get_dummy_cli()
|
||||
self.parameter_name = parameter_name
|
||||
self.key = key
|
||||
self.resource_group = [resource_group_key, None]
|
||||
self.vnet = [vnet_key, None]
|
||||
self.address_prefixes = address_prefixes
|
||||
self.dev_setting_name = os.environ.get(dev_setting_name, None)
|
||||
self.virtual_network_key = virtual_network_key
|
||||
self.resource_group_key = resource_group_key
|
||||
self.name_prefix = name_prefix
|
||||
self.random_name_length = random_name_length
|
||||
|
||||
def create_resource(self, name, **_):
|
||||
if self.dev_setting_name:
|
||||
return {self.parameter_name: self.dev_setting_name, }
|
||||
|
||||
if not self.resource_group[1]:
|
||||
self.resource_group[1] = self.test_class_instance.kwargs.get(
|
||||
self.resource_group[0])
|
||||
if not self.resource_group[1]:
|
||||
raise CliTestError("Error: No resource group configured!")
|
||||
if not self.vnet[1]:
|
||||
self.vnet[1] = self.test_class_instance.kwargs.get(self.vnet[0])
|
||||
if not self.vnet[1]:
|
||||
raise CliTestError("Error: No vnet configured!")
|
||||
|
||||
self.test_class_instance.kwargs[self.key] = 'default'
|
||||
return {self.parameter_name: name}
|
||||
|
||||
def remove_resource(self, name, **_):
|
||||
pass
|
||||
|
||||
|
||||
class VnetNicPreparer(NoTrafficRecordingPreparer, SingleValueReplacer):
|
||||
def __init__(self, name_prefix='clitest.nic',
|
||||
parameter_name='subnet',
|
||||
resource_group_key=KEY_RESOURCE_GROUP,
|
||||
vnet_key=KEY_VIRTUAL_NETWORK,
|
||||
dev_setting_name='AZURE_CLI_TEST_DEV_VNET_NIC_NAME',
|
||||
key=KEY_VNET_NIC):
|
||||
if ' ' in name_prefix:
|
||||
raise CliTestError(
|
||||
'Error: Space character in name prefix \'%s\'' % name_prefix)
|
||||
super(VnetNicPreparer, self).__init__(name_prefix, 15)
|
||||
self.cli_ctx = get_dummy_cli()
|
||||
self.parameter_name = parameter_name
|
||||
self.key = key
|
||||
self.resource_group = [resource_group_key, None]
|
||||
self.vnet = [vnet_key, None]
|
||||
self.dev_setting_name = os.environ.get(dev_setting_name, None)
|
||||
|
||||
def create_resource(self, name, **_):
|
||||
if self.dev_setting_name:
|
||||
return {self.parameter_name: self.dev_setting_name, }
|
||||
|
||||
if not self.resource_group[1]:
|
||||
self.resource_group[1] = self.test_class_instance.kwargs.get(
|
||||
self.resource_group[0])
|
||||
if not self.resource_group[1]:
|
||||
raise CliTestError("Error: No resource group configured!")
|
||||
if not self.vnet[1]:
|
||||
self.vnet[1] = self.test_class_instance.kwargs.get(self.vnet[0])
|
||||
if not self.vnet[1]:
|
||||
raise CliTestError("Error: No vnet configured!")
|
||||
|
||||
template = 'az network nic create --resource-group {} --name {} --vnet-name {} --subnet default '
|
||||
self.live_only_execute(self.cli_ctx, template.format(
|
||||
self.resource_group[1], name, self.vnet[1]))
|
||||
|
||||
cmd = 'az network vnet subnet create -n {} --vnet-name {} -g {} --address-prefixes "10.0.0.0/21"'
|
||||
cmd = cmd.format(
|
||||
name,
|
||||
self.test_class_instance.kwargs.get(self.virtual_network_key),
|
||||
self.test_class_instance.kwargs.get(self.resource_group_key),
|
||||
)
|
||||
self.live_only_execute(self.cli_ctx, cmd)
|
||||
self.test_class_instance.kwargs[self.key] = name
|
||||
return {self.parameter_name: name}
|
||||
return {self.key: name}
|
||||
|
||||
def remove_resource(self, name, **_):
|
||||
if not self.dev_setting_name:
|
||||
self.live_only_execute(
|
||||
self.cli_ctx,
|
||||
'az network nic delete --name {} --resource-group {}'.format(name, self.resource_group[1]))
|
||||
cmd = 'az network vnet subnet delete --name {} --resource-group {} --vnet-name {}'
|
||||
cmd = cmd.format(
|
||||
name,
|
||||
self.test_class_instance.kwargs.get(self.resource_group_key),
|
||||
self.test_class_instance.kwargs.get(self.virtual_network_key),
|
||||
)
|
||||
self.live_only_execute(self.cli_ctx, cmd)
|
||||
|
|
|
@ -12,6 +12,7 @@ import os
|
|||
from azure.cli.testsdk import ScenarioTest
|
||||
from azure.cli.testsdk import ResourceGroupPreparer
|
||||
from .preparers import VirtualNetworkPreparer
|
||||
from .preparers import SubnetPreparer
|
||||
from .example_steps import step_mn_create
|
||||
from .example_steps import step_mn_group_create
|
||||
from .example_steps import step_managed_network_peering
|
||||
|
@ -113,6 +114,10 @@ class ManagedNetworksscenario1Test(ScenarioTest):
|
|||
@VirtualNetworkPreparer(name_prefix='clitestmanaged_network_VnetB'[:7], key='vn_2', resource_group_key='rg')
|
||||
@VirtualNetworkPreparer(name_prefix='clitestmanaged_network_VnetC'[:7], key='vn_3', resource_group_key='rg')
|
||||
@VirtualNetworkPreparer(name_prefix='clitestmanaged_network_myHubVnet'[:7], key='vn_4', resource_group_key='rg')
|
||||
@SubnetPreparer(name_prefix='clitestmanaged_network_subnetA'[:7], key='subnets', virtual_network_key='vn',
|
||||
resource_group_key='rg')
|
||||
@SubnetPreparer(name_prefix='clitestmanaged_network_subnetB'[:7], key='subnets_2', virtual_network_key='vn_2',
|
||||
resource_group_key='rg')
|
||||
def test_ManagedNetworks_scenario1(self, rg):
|
||||
call_scenario1(self, rg)
|
||||
calc_coverage(__file__)
|
||||
|
@ -124,6 +129,10 @@ class ManagedNetworksscenario1Test(ScenarioTest):
|
|||
@VirtualNetworkPreparer(name_prefix='clitestmanaged_network_VnetB'[:7], key='vn_2', resource_group_key='rg')
|
||||
@VirtualNetworkPreparer(name_prefix='clitestmanaged_network_VnetC'[:7], key='vn_3', resource_group_key='rg')
|
||||
@VirtualNetworkPreparer(name_prefix='clitestmanaged_network_myHubVnet'[:7], key='vn_4', resource_group_key='rg')
|
||||
@SubnetPreparer(name_prefix='clitestmanaged_network_subnetA'[:7], key='subnets', virtual_network_key='vn',
|
||||
resource_group_key='rg')
|
||||
@SubnetPreparer(name_prefix='clitestmanaged_network_subnetB'[:7], key='subnets_2', virtual_network_key='vn_2',
|
||||
resource_group_key='rg')
|
||||
def test_ManagedNetworks_scenario1_min(self, rg):
|
||||
call_scenario1_min(self, rg)
|
||||
calc_coverage(__file__)
|
||||
|
@ -188,6 +197,10 @@ class ManagedNetworksscenario2Test(ScenarioTest):
|
|||
@VirtualNetworkPreparer(name_prefix='clitestmanaged_network_VnetB'[:7], key='vn_2', resource_group_key='rg')
|
||||
@VirtualNetworkPreparer(name_prefix='clitestmanaged_network_VnetC'[:7], key='vn_3', resource_group_key='rg')
|
||||
@VirtualNetworkPreparer(name_prefix='clitestmanaged_network_myHubVnet'[:7], key='vn_4', resource_group_key='rg')
|
||||
@SubnetPreparer(name_prefix='clitestmanaged_network_subnetA'[:7], key='subnets', virtual_network_key='vn',
|
||||
resource_group_key='rg')
|
||||
@SubnetPreparer(name_prefix='clitestmanaged_network_subnetB'[:7], key='subnets_2', virtual_network_key='vn_2',
|
||||
resource_group_key='rg')
|
||||
def test_ManagedNetworks_scenario2(self, rg):
|
||||
call_scenario2(self, rg)
|
||||
calc_coverage(__file__)
|
||||
|
@ -199,6 +212,10 @@ class ManagedNetworksscenario2Test(ScenarioTest):
|
|||
@VirtualNetworkPreparer(name_prefix='clitestmanaged_network_VnetB'[:7], key='vn_2', resource_group_key='rg')
|
||||
@VirtualNetworkPreparer(name_prefix='clitestmanaged_network_VnetC'[:7], key='vn_3', resource_group_key='rg')
|
||||
@VirtualNetworkPreparer(name_prefix='clitestmanaged_network_myHubVnet'[:7], key='vn_4', resource_group_key='rg')
|
||||
@SubnetPreparer(name_prefix='clitestmanaged_network_subnetA'[:7], key='subnets', virtual_network_key='vn',
|
||||
resource_group_key='rg')
|
||||
@SubnetPreparer(name_prefix='clitestmanaged_network_subnetB'[:7], key='subnets_2', virtual_network_key='vn_2',
|
||||
resource_group_key='rg')
|
||||
def test_ManagedNetworks_scenario2_min(self, rg):
|
||||
call_scenario2_min(self, rg)
|
||||
calc_coverage(__file__)
|
||||
|
@ -263,6 +280,10 @@ class ManagedNetworksscenario3Test(ScenarioTest):
|
|||
@VirtualNetworkPreparer(name_prefix='clitestmanaged_network_VnetB'[:7], key='vn_2', resource_group_key='rg')
|
||||
@VirtualNetworkPreparer(name_prefix='clitestmanaged_network_VnetC'[:7], key='vn_3', resource_group_key='rg')
|
||||
@VirtualNetworkPreparer(name_prefix='clitestmanaged_network_myHubVnet'[:7], key='vn_4', resource_group_key='rg')
|
||||
@SubnetPreparer(name_prefix='clitestmanaged_network_subnetA'[:7], key='subnets', virtual_network_key='vn',
|
||||
resource_group_key='rg')
|
||||
@SubnetPreparer(name_prefix='clitestmanaged_network_subnetB'[:7], key='subnets_2', virtual_network_key='vn_2',
|
||||
resource_group_key='rg')
|
||||
def test_ManagedNetworks_scenario3(self, rg):
|
||||
call_scenario3(self, rg)
|
||||
calc_coverage(__file__)
|
||||
|
@ -274,6 +295,10 @@ class ManagedNetworksscenario3Test(ScenarioTest):
|
|||
@VirtualNetworkPreparer(name_prefix='clitestmanaged_network_VnetB'[:7], key='vn_2', resource_group_key='rg')
|
||||
@VirtualNetworkPreparer(name_prefix='clitestmanaged_network_VnetC'[:7], key='vn_3', resource_group_key='rg')
|
||||
@VirtualNetworkPreparer(name_prefix='clitestmanaged_network_myHubVnet'[:7], key='vn_4', resource_group_key='rg')
|
||||
@SubnetPreparer(name_prefix='clitestmanaged_network_subnetA'[:7], key='subnets', virtual_network_key='vn',
|
||||
resource_group_key='rg')
|
||||
@SubnetPreparer(name_prefix='clitestmanaged_network_subnetB'[:7], key='subnets_2', virtual_network_key='vn_2',
|
||||
resource_group_key='rg')
|
||||
def test_ManagedNetworks_scenario3_min(self, rg):
|
||||
call_scenario3_min(self, rg)
|
||||
calc_coverage(__file__)
|
||||
|
|
|
@ -12,6 +12,7 @@ import os
|
|||
from azure.cli.testsdk import ScenarioTest
|
||||
from azure.cli.testsdk import ResourceGroupPreparer
|
||||
from .preparers import VirtualNetworkPreparer
|
||||
from .preparers import SubnetPreparer
|
||||
from .example_steps import step_mn_scope_assignment_create
|
||||
from .example_steps import step_mn_scope_assignment_show
|
||||
from .example_steps import step_mn_scope_assignment_list
|
||||
|
@ -102,6 +103,10 @@ class ScopeAssignmentsScenarioTest(ScenarioTest):
|
|||
@VirtualNetworkPreparer(name_prefix='clitestmanaged_network_VnetB'[:7], key='vn_2', resource_group_key='rg')
|
||||
@VirtualNetworkPreparer(name_prefix='clitestmanaged_network_VnetC'[:7], key='vn_3', resource_group_key='rg')
|
||||
@VirtualNetworkPreparer(name_prefix='clitestmanaged_network_myHubVnet'[:7], key='vn_4', resource_group_key='rg')
|
||||
@SubnetPreparer(name_prefix='clitestmanaged_network_subnetA'[:7], key='subnets', virtual_network_key='vn',
|
||||
resource_group_key='rg')
|
||||
@SubnetPreparer(name_prefix='clitestmanaged_network_subnetB'[:7], key='subnets_2', virtual_network_key='vn_2',
|
||||
resource_group_key='rg')
|
||||
def test_ScopeAssignments_Scenario(self, rg):
|
||||
call_scenario(self, rg)
|
||||
calc_coverage(__file__)
|
||||
|
@ -113,6 +118,10 @@ class ScopeAssignmentsScenarioTest(ScenarioTest):
|
|||
@VirtualNetworkPreparer(name_prefix='clitestmanaged_network_VnetB'[:7], key='vn_2', resource_group_key='rg')
|
||||
@VirtualNetworkPreparer(name_prefix='clitestmanaged_network_VnetC'[:7], key='vn_3', resource_group_key='rg')
|
||||
@VirtualNetworkPreparer(name_prefix='clitestmanaged_network_myHubVnet'[:7], key='vn_4', resource_group_key='rg')
|
||||
@SubnetPreparer(name_prefix='clitestmanaged_network_subnetA'[:7], key='subnets', virtual_network_key='vn',
|
||||
resource_group_key='rg')
|
||||
@SubnetPreparer(name_prefix='clitestmanaged_network_subnetB'[:7], key='subnets_2', virtual_network_key='vn_2',
|
||||
resource_group_key='rg')
|
||||
def test_ScopeAssignments_Scenario_min(self, rg):
|
||||
call_scenario_min(self, rg)
|
||||
calc_coverage(__file__)
|
||||
|
|
|
@ -207,8 +207,8 @@ ubscriptionA\\"},{\\"id\\":\\"subscriptionB\\"}],\\"virtualNetworks\\":[{\\"id\\
|
|||
rceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVirtualNetwork\\"},{\\"id\\":\\"/subscriptions/\
|
||||
subscriptionC/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVirtualNetwork2\\"}],\\"subn\
|
||||
ets\\":[{\\"id\\":\\"/subscriptions/subscriptionC/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNet\
|
||||
works/myVirtualNetwork3/subnets/default\\"},{\\"id\\":\\"/subscriptions/subscriptionC/resourceGroups/myResourceGroup/pr\
|
||||
oviders/Microsoft.Network/virtualNetworks/myVirtualNetwork3/subnets/default\\"}]}" --name "myManagedNetwork" \
|
||||
works/myVirtualNetwork3/subnets/mySubnet\\"},{\\"id\\":\\"/subscriptions/subscriptionC/resourceGroups/myResourceGroup/p\
|
||||
roviders/Microsoft.Network/virtualNetworks/myVirtualNetwork3/subnets/mySubnet2\\"}]}" --name "myManagedNetwork" \
|
||||
--resource-group "myResourceGroup"
|
||||
```
|
||||
##### <a name="ParametersManagedNetworksCreateOrUpdate#Create">Parameters</a>
|
||||
|
@ -289,11 +289,11 @@ az managed-network mn group show --group-name "myManagedNetworkGroup" --managed-
|
|||
##### <a name="ExamplesManagedNetworkGroupsCreateOrUpdate#Create">Example</a>
|
||||
```
|
||||
az managed-network mn group create --management-groups "[]" --subnets id="/subscriptions/subscriptionB/resourceGroups/m\
|
||||
yResourceGroup/providers/Microsoft.Network/virtualNetworks/myVirtualNetwork/subnets/default" \
|
||||
yResourceGroup/providers/Microsoft.Network/virtualNetworks/myVirtualNetwork/subnets/mySubnet" \
|
||||
id="/subscriptions/subscriptionB/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVirtualNe\
|
||||
twork2/subnets/default" --virtual-networks id="/subscriptionB/resourceGroups/myResourceGroup/providers/Microsoft.Networ\
|
||||
k/virtualNetworks/VnetA" --virtual-networks id="/subscriptionB/resourceGroups/myResourceGroup/providers/Microsoft.Netwo\
|
||||
rk/virtualNetworks/VnetB" --group-name "myManagedNetworkGroup" --managed-network-name "myManagedNetwork" \
|
||||
twork2/subnets/mySubnet2" --virtual-networks id="/subscriptionB/resourceGroups/myResourceGroup/providers/Microsoft.Netw\
|
||||
ork/virtualNetworks/VnetA" --virtual-networks id="/subscriptionB/resourceGroups/myResourceGroup/providers/Microsoft.Net\
|
||||
work/virtualNetworks/VnetB" --group-name "myManagedNetworkGroup" --managed-network-name "myManagedNetwork" \
|
||||
--resource-group "myResourceGroup"
|
||||
```
|
||||
##### <a name="ParametersManagedNetworkGroupsCreateOrUpdate#Create">Parameters</a>
|
||||
|
|
|
@ -34,6 +34,7 @@ export class RenderDataBase {
|
|||
await entry.init();
|
||||
|
||||
const model = new CodeModelCliImpl(session);
|
||||
model.GenerateTestInit();
|
||||
|
||||
this.model = model;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче