Skip to content

Commit 5408eae

Browse files
leniatghzhenglaizhangsonwan2020ruowanTianxiang Chen
authored andcommitted
apiscenario doc (Azure#18476)
* sync signalr test scenarios * remove extra template.json * add asc scenarios file * add uploadJar scripts * add uploadJar * add deploymentScripts * update readme * update doc and use blob sas url to download * delete unused powershell file and format scripts * adjust asc scenarios file * update springCloud test scenario * update powershell scripts * v2 schema * fix * prettier * securestring * fix action * fix * fit 2.9.0, waiting for verify * fix domainName * json to yaml * fix output variable type * remove redundent defaultValue in armTemplate * generate uniq name * Adapt to v1.1 schema * remove unnecesary file * fix patch step * update springCloud test scenario * update spring cloud yaml * prettier * add overwrite variable * new schema * delete unused file * rename armTemplateDeployment to armTemplate * webpubsub * v1.2 schema * v1.2 schema * webpubsub * v1.2 schema * adapt asc/signalr to v1.2 schema * more data types in v1.2 schema * v1.2 schema * convert to new syntax * restore example * tiny change * refine variables schema * fix scenarios * fix scenarios * signalr basic crud * cdn scenario coverage 57% * add responses schema * use readmeTag insteadof swagger * fix rp * fix schema * fix step scope variables * fix step variables * fix * [ApiScenario] update doc (Azure#18424) * update doc * Update documentation/api-scenario/how-to/generateABasicApiScenario.md Co-authored-by: Tianxiang Chen <[email protected]> Co-authored-by: Lei Ni <[email protected]> * update docs * fix schema * Update variables.md * commit scenario files * remove scenario files * update schema line * remove resourceUpdate * remove resourceUpdate * requestUpdate convention * convention in pseudo-code Co-authored-by: Zhenglai Zhang <[email protected]> Co-authored-by: Songbo Wang <[email protected]> Co-authored-by: ruowan <[email protected]> Co-authored-by: Tianxiang Chen <[email protected]> Co-authored-by: tianxchen-ms <[email protected]>
1 parent 0963de1 commit 5408eae

File tree

8 files changed

+398
-243
lines changed

8 files changed

+398
-243
lines changed

documentation/api-scenario/how-to/QuickStart.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ Now write your basic API scenario. For more detail about API scenario file forma
4343
[API Scenario Definition Reference](../references/ApiScenarioDefinition.md).
4444

4545
```yaml
46-
# yaml-language-server: $schema=https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/documentation/api-scenario/references/v1.1/schema.json
46+
# yaml-language-server: $schema=https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/documentation/api-scenario/references/v1.2/schema.json
4747

4848
scope: ResourceGroup
4949
scenarios:

documentation/api-scenario/how-to/generateABasicApiScenario.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,16 @@ We use `oav` tools to generate basic API scenario. `oav` analyze swagger file an
88

99
`oav` support rule based API scenario file generation. We use this command to generate API scenario file.
1010

11-
`oav generate-static-api-scenario --readme <readme> --tag <tag> --rules <generated-rules>`
11+
`oav generate-api-scenario static --readme <readme> --tag <tag> --specs <specs> --rules <generated-rules>`
12+
13+
OR
14+
15+
`oav generate-api-scenario static --readme <readme> --tag <tag> --specs <specs> --dependency <dependency-path>`
1216

1317
- readme: swagger readme file.
1418
- tag: which tag to generate. oav will analyze swagger file under the tag and generate API scenario.
19+
- specs: one or more spec file paths. type: array.
20+
- dependency: The file path of the RESTler dependency. It cannot be used with `rules`.
1521
- rules: Currently support two types. `resource-put-delete`, `operations-list`. Default: `resource-put-delete`
1622
- `resource-put-delete`: generate resource put and delete API scenario.
1723
- `operations-list`: generate operations list API scenario. `operations-list` is the simplest API which must be defined in swagger.

documentation/api-scenario/readme.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ _**Caution**: This project is in early preview phase, hence breaking changes sho
66

77
## Features
88

9-
- Simple to use: Intuitive step definition based on Swagger examples and raw REST call.
9+
- Simple to use: Intuitive step definition based on Swagger operations and examples.
1010
- ARM Template integration: Support creating external Azure resources with ARM Template and executing Azure Powershell or Azure CLI scripts with ARM Template deployment script.
11-
- Implementation independent: [oav](https://github.com/Azure/oav) is the default API scenario runner, and more runners will be supported, like SDKs in different languages.
11+
- Implementation independent: [oav](https://github.com/Azure/oav) is the default API scenario runner. More runners will be supported, like SDKs in different languages.
1212

1313
### Demo gif
1414

documentation/api-scenario/references/ApiScenarioDefinition.md

Lines changed: 84 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## API Scenario Definition File
44

5-
See [API Scenario Definition File Schema](./v1.1/schema.json#L1)
5+
See [API Scenario Definition File Schema](./v1.2/schema.json#L1)
66

77
File should be in format of yaml.
88

@@ -19,9 +19,7 @@ scenarios:
1919
- description: test_network_public_ip
2020
steps:
2121
- step: Create_publicIPAddresses_pubipdns
22-
resourceName: publicIPAddresses_pubipdns
2322
exampleFile: ../examples/Create_publicIPAddresses_pubipdns_Generated.json
24-
operationId: PublicIPAddresses_CreateOrUpdate
2523
variables:
2624
publicIpAddressName: pubipdns
2725
```
@@ -30,27 +28,30 @@ scenarios:
3028
3129
- **scope**
3230
- **Type:** Required, Enum
33-
- **Enum:** ResourceGroup
31+
- **Enum:** ResourceGroup, Subscription, Tenant
3432
- Now only "ResourceGroup" is supported.
3533
- **ResourceGroup:** All of the following API scenario and steps should be under some resourceGroup. It means:
3634
- The consumer (API scenario runner or anything consumes API scenario) SHOULD maintain the resource group itself. Usually it requires user to input the subscriptionId/location, then it creates the resource group before test running, and deletes the resource group after running
3735
- The consumer SHOULD set the following variables:
3836
- **subscriptionId**
3937
- **resourceGroupName**
4038
- **location**
41-
- For details of how variables works please see [Variables](./Variables.md)
39+
- For details of how variables work please see [Variables](./Variables.md)
4240
- **variables**
43-
- **Type:** Optional, Map of strings
41+
- **Type:** Optional, Map of strings or variable containers
4442
- See [Variables](./Variables.md)
4543
- **prepareSteps**
4644
- **Type:** Optional, Array of [Step](#step)
4745
- Steps that should run before every API scenario steps.
4846
- **scenarios**
4947
- **Type:** Required, Array of [Scenario](#scenario)
48+
- **cleanUpSteps**
49+
- **Type:** Optional, Array of [Step](#step)
50+
- Steps that should run after every API scenario steps.
5051
5152
## Scenario
5253
53-
See [Scenario Schema](./v1.1/schema.json#L83).
54+
See [Scenario Schema](./v1.2/schema.json#L249).
5455
5556
It defines one API scenario that could go through on its own.
5657
@@ -61,7 +62,6 @@ description: test_network_public_ip
6162
shareScope: true
6263
steps:
6364
- step: Create_publicIPAddresses_pubipdns
64-
resourceName: publicIPAddresses_pubipdns
6565
exampleFile: ../examples/Create_publicIPAddresses_pubipdns_Generated.json
6666
operationId: PublicIPAddresses_CreateOrUpdate
6767
variables:
@@ -76,10 +76,10 @@ variables:
7676
- **shareScope**
7777
- **Type:** Optional, Boolean or String
7878
- **Default:** true
79-
- Describe how the scope (ResourceGroup if scope is ResourceGroup) could be shared with other tests. If it's true or it's the same string setting for different API scenario, then they share the same scope, which means:
80-
- These tests will run under the same scope (e.g. ResourceGroup). They may launch in parallel.
81-
- **prepareSteps** will only run once in the scope. The variables will be shared.
82-
- By default all the API scenario in one definition file will be launched in the same scope. If shareScope is false then it will not share anything with other API scenarios in the same file.
79+
- Describe how the scope (ResourceGroup if scope is ResourceGroup) could be shared with other scenarios. If true or the same string value for different API scenario, they share the same scope, which means:
80+
- These API scenarios will run under the same scope (e.g. ResourceGroup).
81+
- **prepareSteps** and **cleanUpSteps** will run only once in the scope. The variables will be shared.
82+
- By default all the API scenario in one definition file will be launched in the same scope. If shareScope is false, the API scenarios will not share anything with others in the same file.
8383
- **variables**
8484
- **Type:** Optional, Map of strings
8585
- See [Variables](./Variables.md)
@@ -89,30 +89,33 @@ variables:
8989
9090
## Step
9191
92-
See [Step Schema](./v1.1/schema.json#L114).
92+
See [Step Schema](./v1.2/schema.json#L280).
9393
9494
Defines one step in API scenario.
9595
9696
Should be one of the following:
9797
9898
- [Step REST Call](#step-rest-call)
99-
- [REST Call](#rest-call)
100-
- [REST Call by ResourceName Tracking and Update](#rest-call-by-resourcename-tracking-and-update)
99+
- [REST Operation](#rest-operation)
100+
- [REST Example](#rest-example)
101101
- [Step ARM Template](#step-arm-template)
102102
- [Step ARM Deployment Script](#step-arm-deployment-script)
103103
104104
All of the above definitions share the following fields:
105105
106-
- **variables**
107-
- **Type:** Optional, Map of Strings
108-
- See [Variables](./Variables.md)
109106
- **step**
110107
- **Type:** Required, String
111108
- Step name. Must be unique in the same file.
109+
- **description**
110+
- **Type:** Optional, String
111+
- A brief explanation about the step
112+
- **variables**
113+
- **Type:** Optional, Map of Strings or variables
114+
- See [Variables](./Variables.md)
112115
113116
## Step ARM Template
114117
115-
See [Step ARM Template Schema](./v1.1/schema.json#L250).
118+
See [Step ARM Template Schema](./v1.2/schema.json#L427).
116119
117120
Step to deploy ARM template to the scope. Template parameters and outputs will also interact with variables automatically, see [Variables](./Variables.md).
118121
@@ -129,10 +132,9 @@ Step to deploy ARM template to the scope. Template parameters and outputs will a
129132
- **Type:** Required, String
130133
- Path to ARM template json file. See [ARM Template](https://docs.microsoft.com/azure/templates/).
131134
132-
133135
## Step ARM Deployment Script
134136
135-
See [Step ARM Deployment Script Schema](./v1.1/schema.json#L266).
137+
See [Step ARM Deployment Script Schema](./v1.2/schema.json#L448).
136138
137139
Step to deploy ARM deployment script to the scope. Template parameters and outputs will also interact with variables automatically, see [Variables](./Variables.md).
138140
@@ -186,98 +188,104 @@ Step to deploy ARM deployment script to the scope. Template parameters and outpu
186188
187189
## Step REST Call
188190
189-
See [Step REST Call Schema](./v1.1/schema.json#L208)
191+
Step to run a rest call defined in swagger operation. This may not be just one http call.
190192
191-
Step to run a swagger operation defined rest call. This may not be just one http call.
192-
193-
- If the operation is a long running operation (LRO), then follow the LRO polling strategy.
193+
- If the operation is a long running operation (LRO), then follow the LRO polling strategy:
194194
- Response statusCode must be 200 if the LRO succeeded, no matter what code the initial response is.
195195
- If the LRO is PUT/PATCH, the runner should automatically insert a GET after the polling to verify the resource update result.
196196
- If the operation is DELETE, then after the operation, the runner should automatically insert a GET to verify resource cannot be found.
197197
198-
Rest call step could be defined either by an example file, or by resourceName tracking and update.
198+
REST call step could be defined either by an operation, or by an example file. REST call will have computed **requestParameter** and **responseExpected** after parsing and loading.
199+
200+
### REST Operation
201+
202+
See [Step Operation Schema](./v1.2/schema.json#L339)
199203
200-
Rest call will have computed **requestParameter** and **responseExpected** after parsing and loading:
204+
**Example:**
205+
```yml
206+
- step: createPublicIPAddress
207+
operationId: PublicIPAddresses_CreateOrUpdate
208+
```
209+
210+
**Fields:**
211+
212+
- **operationId:**
213+
- **Type:** Required, String
214+
- OperationId defined in Swagger.
215+
- **parameters:**
216+
- **Type:** Optional, Map from parameter name to parameter value
217+
- **responses:**
218+
- **Type:** Optional, Map from expected response code to response headers and body.
219+
- **outputVariables**
220+
- **Type:** Optional, Map from variable name to object with property:
221+
- **type**: Required, String
222+
- **fromRequest**
223+
- **Type:** Required, String
224+
- Path to the request field to be used as variable.
225+
- **fromResponse**
226+
- **Type:** Required, String
227+
- Path to the response field to be used as variable.
201228
202-
- **requestParameter**
229+
### REST Example
203230
204-
### REST Call
231+
See [Step Example Schema](./v1.2/schema.json#L389)
205232
206233
**Example:**
207234
208235
```yaml
209236
- step: Create_publicIPAddresses_pubipdns
210-
resourceName: publicIPAddresses_pubipdns
211237
exampleFile: ../examples/Create_publicIPAddresses_pubipdns_Generated.json
212-
operationId: PublicIPAddresses_CreateOrUpdate
213-
statusCode: 200
214238
```
215239
216240
**Fields:**
217241
218242
- **exampleFile**
219-
- **Type:** Optional, String
243+
- **Type:** Required, String
220244
- Path to example file. Should be in format of "x-ms-example" files.
221-
- **operationId**
222-
- **Type:** Optional, String
223-
- OperationId defined in swagger operation. It could be skipped if the example file is referenced by only one operation so we could detect the operationId.
224-
- **statusCode:**
225-
- **Type:** Optional, Number
226-
- **Default:** 200
227-
- Expected response code.
228-
- For LRO it must be 200 to indicate succeeded result, and must be 400 to indicate failed result.
229245
- **requestUpdate**
230246
- **Type:** Optional, Array of [JsonPatchOp](#jsonpatchop)
231-
- Updates that applied to the requestParameters before sending it.
247+
- Updates that apply to the **requestParameters** before sending it, with `/parameters` in example as root of Json path.
232248
- **responseUpdate**
233249
- **Type:** Optional, Array of [JsonPatchOp](#jsonpatchop)
234-
- Updates that applied to the responseExpected.
250+
- Updates that apply to the **responseExpected**, with `/responses` in example as root of Json path.
235251
- **outputVariables**
236252
- **Type:** Optional, Map from variable name to object with property:
253+
- **type**: Required, String
254+
- **fromRequest**
255+
- **Type:** Required, String
256+
- Path to the request field to be used as variable.
237257
- **fromResponse**
238258
- **Type:** Required, String
239259
- Path to the response field to be used as variable.
240260

241-
### Rest Call by ResourceName Tracking and Update
261+
**Conventions:**
242262

243-
**Example**
263+
When the scope is `ResourceGroup` and the request is a PUT/PATCH, the **requestUpdate** JsonPatchOp items starting with body parameter name SHOULD be applied to the response body (if any) for all successful status codes, excluding writeOnly properties - `x-ms-secret: true` or `x-ms-mutability` doesn't contain `read`.
244264

245-
```yaml
246-
- step: Create_publicIPAddresses_pubipdns
247-
resourceName: publicIPAddresses_pubipdns
248-
exampleFile: ../examples/Create_publicIPAddresses_pubipdns_Generated.json
249-
operationId: PublicIPAddresses_CreateOrUpdate
250-
statusCode: 200
265+
The **responseUpdate** SHOULD be applied after the **requestUpdate**, providing option to override the behavior by convention.
251266

252-
- step: Update_publicIPAddresses
253-
resourceName: publicIPAddresses_pubipdns
254-
resourceUpdate:
255-
- replace: /properties/location
256-
value: westus
257-
```
258-
259-
Different steps with the same resourceName will be tracked by the API scenario. It knows that you are trying to update the same resource. You can use the first request with example to specify the request and resource id, then the following step with the same resourceName will use the same resource id to update the resource. For the
260-
261-
**Fields:**
267+
The behavior of applying **requestUpdate** to the response body should follow JSON merge-patch ([RFC 7396](https://tools.ietf.org/html/rfc7396)).
262268

263-
- **resourceName**
264-
- **Type:** Required, String
265-
- The user-defined resource name of the resource to be tracked. It's only used as a name of that resource and do not need to be same as the actual resource name.
266-
- **resourceUpdate**
267-
- **Type:** Optional, Array of [JsonPatchOp](#jsonpatchop)
268-
- Array of changes to be applied to the resource.
269-
270-
resourceUpdate will help to automate compute the request body and the expected response body. The algorithm will be:
271-
272-
- Get the expected response body from previous step with same `resourceName`, or from current step with example loaded.
273-
- For each change in `resourceUpdate`, apply the change to the expected response body, mark as `computedAllProperties`.
274-
- Let new request body parameter value to be: `computedAllProperties` without `readOnly` fields and `x-ms-mutability` fields that don't contains `update`.
275-
- Let new response expected to be: `computedAllProperties` without `x-ms-secrets` fields and `x-ms-mutability` fields that don't contain `read`.
276-
- Let the operationId to be: resource PUT operationId.
269+
The whole process is illustrated as below pseudo-code:
270+
```
271+
if (scope is 'ResourceGroup' && operation.verb in ('PUT', 'PATCH')) {
272+
updatedRequestBody = apply_JsonPatchOp(initialRequestBody, requestUpdate.body);
273+
mergePatch = generate_JsonMergePatch(initialRequestBody, updatedRequestBody);
274+
for (each successful status code) {
275+
if (response.body is not empty) {
276+
updatedResponseBody = apply_JsonMergePatch(initialResponseBody, mergePatch);
277+
updatedResponseBody = exclude_WriteOnly_Properties(updatedResponseBody);
278+
updatedResponseBody = apply_JsonPatchOp(updatedResponseBody, responseUpdate.body);
279+
}
280+
}
281+
}
282+
```
277283

278284
### JsonPatchOp
279285

280-
JsonPatchOp is used to define the update operation on json. You could add, remove, replace, move, copy and merge on json path.
286+
See [Json Patch Operation Schema](./v1.2/schema.json#L490)
287+
288+
JsonPatchOp is used to define the update operation on json. You could add, remove, replace, copy, move, and test on json path.
281289
All the json path used in JsonPatchOp is in format of [JsonPointer](https://datatracker.ietf.org/doc/html/rfc6901).
282290

283291
- [JsonPatchOp](#jsonpatchop)

documentation/api-scenario/references/Variables.md

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,34 @@
11
# Variables in API scenario
22

3-
## Variable definition and replacement
3+
## Variable types
44

5-
Variables could be defined in different level of API scenario:
5+
Variables could be of different types:
6+
- `array`
7+
- `bool`
8+
- `int`
9+
- `object`
10+
- `secureString`
11+
- `secureObject`
12+
- `string`
13+
14+
## Variable definition
615

7-
- `runtime`: Variables specified at runtime
8-
- `global`: API scenario definition level variable definition
9-
- `scope`: Scope level variable
10-
- `scenario`: API scenario level variable definition
11-
- `step`: Step level variable definition
16+
Variables could be defined in different level of API scenario:
1217

13-
Variable could be referenced by `$(variableName)`. Currently variable type must be string.
18+
- `runtime`: Variables specified at runtime. Only `string` or `secureString` type is allowed in runtime level.
19+
- `global`: API scenario file level variable definition.
20+
- `scope`: Scope level variable. If the scope of API scenario is `ResourceGroup`, variable `resourceGroupName` will be available in scope level.
21+
- `scenario`: API scenario level variable definition.
22+
- `step`: Step level variable definition.
1423

15-
For example, in the following API scenario:
24+
Variable could be referenced by `$(variableName)`. For example, in the following API scenario:
1625

1726
```yaml
1827
variables:
1928
resourceName: level-1
2029

2130
scenarios:
22-
- definition: Create some resource
31+
- description: Create some resource
2332
variables:
2433
resourceName: level-2
2534
steps:
@@ -29,7 +38,7 @@ scenarios:
2938
exampleFile: ../examples/ResourceCreate.json
3039
```
3140
32-
if in `../examples/ResourceCreate.json` we have `$(resourceName)` in some string, it would be replaced with `level-3`.
41+
If in `../examples/ResourceCreate.json` there is `$(resourceName)` in some string, it would be replaced with `level-3`.
3342

3443
Variables could also be defined on test running. For example you could set `subscriptionId` or `resourceGroupName` on the global scope. How to set global env is based on the API scenario consumer.
3544

@@ -41,9 +50,7 @@ variables:
4150
resourceId: Microsoft.Contoso/$(resourceName)
4251
```
4352

44-
Then `$(resourceId)` would be resolved to `Microsoft.Contoso/abc`.
45-
46-
Variable resolving is limited to at most 100 times for certain string.
53+
Then `$(resourceId)` would be resolved to `Microsoft.Contoso/abc`. Note that variables referencing `secureString` should be regarded as `secureString` in API Scenario runner.
4754

4855
## Convention: parameter name in example
4956

0 commit comments

Comments
 (0)