Skip to content

Commit 61f2beb

Browse files
authored
Update live tests to use generated matrix configuration (Azure#18131)
* Update live tests to use generated matrix configuration. Update generation features. * Simplify matrix config filter code * Use sparse matrix for identity live tests * Invert base matrix selection. Fix matrix object field dimension bug. * Simplify matrix filter regex filter syntax * Fix windows pool name in platform matrix * Change live test platform matrix configuration to sparse * Add UseProjectRef on net5.0 to live test matrix
1 parent 7ad6c91 commit 61f2beb

12 files changed

+504
-180
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
parameters:
2+
- name: AdditionalParameters
3+
type: object
4+
- name: CloudConfig
5+
type: object
6+
default: {}
7+
- name: MatrixConfigs
8+
type: object
9+
default: []
10+
11+
jobs:
12+
- job: generate_matrix
13+
variables:
14+
displayNameFilter: $[ coalesce(variables.jobMatrixFilter, '.*') ]
15+
pool:
16+
name: azsdk-pool-mms-ubuntu-1804-general
17+
vmImage: MMSUbuntu18.04
18+
displayName: Generate Job Matrix
19+
steps:
20+
- ${{ each config in parameters.MatrixConfigs }}:
21+
- ${{ if eq(config.GenerateVMJobs, 'true') }}:
22+
- pwsh: |
23+
Write-Host "DISPLAY NAME FILTER: $(displayNameFilter)"
24+
eng/scripts/job-matrix/Create-JobMatrix.ps1 `
25+
-ConfigPath ${{ config.Path }} `
26+
-Selection ${{ config.Selection }} `
27+
-DisplayNameFilter "$(displayNameFilter)" `
28+
-Filters @("container=^$", "SupportedClouds=^$|${{ parameters.CloudConfig.Cloud }}")
29+
name: generate_vm_job_matrix_${{ config.Name }}
30+
displayName: Generate VM Job Matrix
31+
32+
- ${{ if eq(config.GenerateContainerJobs, 'true') }}:
33+
- pwsh: |
34+
Write-Host "DISPLAY NAME FILTER: $(displayNameFilter)"
35+
eng/scripts/job-matrix/Create-JobMatrix.ps1 `
36+
-ConfigPath ${{ config.Path }} `
37+
-Selection ${{ config.Selection }} `
38+
-DisplayNameFilter "$(displayNameFilter)" `
39+
-Filters @("container=.*", "SupportedClouds=$^$|{{ parameters.CloudConfig.Cloud }}")
40+
name: generate_container_job_matrix_${{ config.Name }}
41+
displayName: Generate Container Job Matrix
42+
43+
- ${{ each config in parameters.MatrixConfigs }}:
44+
- ${{ if eq(config.GenerateVMJobs, 'true') }}:
45+
- template: ./archetype-sdk-tests-jobs.yml
46+
parameters:
47+
UsePlatformContainer: false
48+
Matrix: dependencies.generate_matrix.outputs['generate_vm_job_matrix_${{ config.Name }}.matrix']
49+
DependsOn: generate_matrix
50+
CloudConfig: ${{ parameters.CloudConfig }}
51+
${{ each param in parameters.AdditionalParameters }}:
52+
${{ param.key }}: ${{ param.value }}
53+
54+
- ${{ if eq(config.GenerateContainerJobs, 'true') }}:
55+
- template: ./archetype-sdk-tests-jobs.yml
56+
parameters:
57+
UsePlatformContainer: true
58+
Matrix: dependencies.generate_matrix.outputs['generate_container_job_matrix_${{ config.Name }}.matrix']
59+
DependsOn: generate_matrix
60+
CloudConfig: ${{ parameters.CloudConfig }}
61+
${{ each param in parameters.AdditionalParameters }}:
62+
${{ param.key }}: ${{ param.value }}

eng/pipelines/templates/jobs/archetype-sdk-tests-host.yml

Lines changed: 0 additions & 40 deletions
This file was deleted.

eng/pipelines/templates/jobs/archetype-sdk-tests-jobs.yml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,22 @@ parameters:
3535
- name: Platforms
3636
type: object
3737
default: {}
38+
- name: Matrix
39+
type: string
40+
- name: DependsOn
41+
type: string
42+
default: ''
3843
- name: UsePlatformContainer
3944
type: boolean
4045
default: false
4146

4247
jobs:
4348
- job:
49+
dependsOn: ${{ parameters.DependsOn }}
50+
condition: ne(${{ parameters.Matrix }}, '{}')
4451
strategy:
4552
maxParallel: ${{ parameters.MaxParallel }}
46-
matrix: ${{ parameters.Platforms }}
53+
matrix: $[ ${{ parameters.Matrix }} ]
4754

4855
variables:
4956
- template: ../variables/globals.yml
@@ -64,6 +71,7 @@ jobs:
6471
vmImage: $(OSVmImage)
6572

6673
${{ if eq(parameters.UsePlatformContainer, 'true') }}:
74+
# Add a default so the job doesn't fail when the matrix is empty
6775
container: $[ variables['Container'] ]
6876

6977
steps:

eng/pipelines/templates/stages/archetype-sdk-tests.yml

Lines changed: 15 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -52,46 +52,16 @@ parameters:
5252
SubscriptionConfiguration: $(sub-config-gov-test-resources)
5353
China:
5454
SubscriptionConfiguration: $(sub-config-cn-test-resources)
55-
- name: Platforms
55+
- name: MatrixConfigs
5656
type: object
5757
default:
58-
Linux:
59-
Pool: azsdk-pool-mms-ubuntu-1804-general
60-
OSVmImage: MMSUbuntu18.04
61-
TestTargetFramework: netcoreapp2.1
62-
Windows_NetCoreApp:
63-
Pool: azsdk-pool-mms-win-2019-general
64-
OSVmImage: MMS2019
65-
TestTargetFramework: netcoreapp2.1
66-
SupportsRecording: true
67-
Windows_NetCoreApp_ProjectReferences:
68-
Pool: azsdk-pool-mms-win-2019-general
69-
OSVmImage: MMS2019
70-
TestTargetFramework: netcoreapp2.1
71-
AdditionalTestArguments: "/p:UseProjectReferenceToAzureClients=true"
72-
Windows_NetFramework:
73-
Pool: azsdk-pool-mms-win-2019-general
74-
OSVmImage: MMS2019
75-
TestTargetFramework: net461
76-
Windows_NetFramework_ProjectReferences:
77-
Pool: azsdk-pool-mms-win-2019-general
78-
OSVmImage: MMS2019
79-
TestTargetFramework: net461
80-
AdditionalTestArguments: "/p:UseProjectReferenceToAzureClients=true"
81-
MacOS:
82-
Pool: Azure Pipelines
83-
OSVmImage: "macOS-10.15"
84-
TestTargetFramework: netcoreapp2.1
85-
SupportedClouds: 'Public'
86-
Windows_Net50:
87-
Pool: azsdk-pool-mms-win-2019-general
88-
OSVmImage: MMS2019
89-
TestTargetFramework: net5.0
90-
Windows_Net50_ProjectReferences:
91-
Pool: azsdk-pool-mms-win-2019-general
92-
OSVmImage: MMS2019
93-
TestTargetFramework: net5.0
94-
AdditionalTestArguments: "/p:UseProjectReferenceToAzureClients=true"
58+
- Name: NET_live_test_base
59+
Path: eng/pipelines/templates/stages/platform-matrix.json
60+
Selection: sparse
61+
GenerateVMJobs: true
62+
- name: AdditionalMatrixConfigs
63+
type: object
64+
default: []
9565
- name: PlatformPreSteps
9666
type: object
9767
default:
@@ -126,13 +96,8 @@ stages:
12696
- stage: ${{ cloud.key }}
12797
dependsOn: []
12898
jobs:
129-
- template: ../jobs/archetype-sdk-tests-host.yml
99+
- template: /eng/pipelines/templates/jobs/archetype-sdk-tests-generate.yml
130100
parameters:
131-
# Flag to include the job template with a container field
132-
${{ each platform in parameters.AdditionalPlatforms }}:
133-
${{ if or(not(platform.value.SupportedClouds), contains(platform.value.SupportedClouds, cloud.key)) }}:
134-
${{ if platform.value.Container }}:
135-
UsePlatformContainer: true
136101
AdditionalParameters:
137102
PreSteps:
138103
- ${{ parameters.PlatformPreSteps }}
@@ -148,14 +113,13 @@ stages:
148113
SDKType: ${{ parameters.SDKType }}
149114
ServiceDirectory: ${{ parameters.ServiceDirectory }}
150115
TestSetupSteps: ${{ parameters.TestSetupSteps }}
151-
Platforms:
116+
MatrixConfigs:
152117
# Enumerate platforms and additional platforms based on supported clouds (sparse platform<-->cloud matrix).
153-
${{ each platform in parameters.Platforms }}:
154-
${{ if or(not(platform.value.SupportedClouds), contains(platform.value.SupportedClouds, cloud.key)) }}:
155-
${{ platform.key }}: ${{ platform.value }}
156-
${{ each platform in parameters.AdditionalPlatforms }}:
157-
${{ if or(not(platform.value.SupportedClouds), contains(platform.value.SupportedClouds, cloud.key)) }}:
158-
${{ platform.key }}: ${{ platform.value }}
118+
- ${{ each config in parameters.MatrixConfigs }}:
119+
- ${{ config }}
120+
- ${{ each config in parameters.AdditionalMatrixConfigs }}:
121+
- ${{ config }}
159122
CloudConfig:
160123
SubscriptionConfiguration: ${{ cloud.value.SubscriptionConfiguration }}
161124
Location: ${{ coalesce(parameters.Location, cloud.value.Location) }}
125+
Cloud: ${{ cloud.key }}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"displayNames": {
3+
"/p:UseProjectReferenceToAzureClients=true": "UseProjectRef",
4+
"true": "Record"
5+
},
6+
"matrix": {
7+
"Agent": {
8+
"ubuntu-18.04": { "OSVmImage": "MMSUbuntu18.04", "Pool": "azsdk-pool-mms-ubuntu-1804-general" },
9+
"windows-2019": { "OSVmImage": "MMS2019", "Pool": "azsdk-pool-mms-win-2019-general" },
10+
"macOS-10.15": { "OSVmImage": "macOS-10.15", "Pool": "Azure Pipelines" }
11+
},
12+
"TestTargetFramework": [ "netcoreapp2.1", "net5.0" ]
13+
},
14+
"include": [
15+
{
16+
"Agent": {
17+
"windows-2019": { "OSVmImage": "MMS2019", "Pool": "azsdk-pool-mms-win-2019-general" }
18+
},
19+
"TestTargetFramework": [ "net461", "net5.0" ],
20+
"AdditionalTestArguments": "/p:UseProjectReferenceToAzureClients=true"
21+
},
22+
{
23+
"Agent": {
24+
"windows-2019": { "OSVmImage": "MMS2019", "Pool": "azsdk-pool-mms-win-2019-general" }
25+
},
26+
"TestTargetFramework": "netcoreapp2.1",
27+
"SupportsRecording": true
28+
}
29+
]
30+
}

eng/scripts/job-matrix/Create-JobMatrix.ps1

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,16 @@
1010
[CmdletBinding()]
1111
param (
1212
[Parameter(Mandatory=$True)][string] $ConfigPath,
13-
[Parameter(Mandatory=$True)][string] $Selection
13+
[Parameter(Mandatory=$True)][string] $Selection,
14+
[Parameter(Mandatory=$False)][string] $DisplayNameFilter,
15+
[Parameter(Mandatory=$False)][array] $Filters
1416
)
1517

16-
Import-Module $PSScriptRoot/job-matrix-functions.psm1
18+
. $PSScriptRoot/job-matrix-functions.ps1
1719

1820
$config = GetMatrixConfigFromJson (Get-Content $ConfigPath)
1921

20-
[array]$matrix = GenerateMatrix $config $Selection
22+
[array]$matrix = GenerateMatrix $config $Selection $DisplayNameFilter $Filters
2123
$serialized = SerializePipelineMatrix $matrix
2224

2325
Write-Output $serialized.pretty

eng/scripts/job-matrix/README.md

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,20 +38,35 @@ jobs:
3838
- Name: base_product_matrix
3939
Path: /eng/pipelines/matrix.json
4040
Selection: sparse
41+
GenerateVMJobs: true
4142
- Name: sdk_specific_matrix
4243
Path: /sdk/foobar/matrix.json
4344
Selection: all
45+
GenerateContainerJobs: true
4446
steps:
4547
- pwsh:
4648
...
4749
```
4850

4951
## Matrix config file syntax
5052

53+
Matrix parameters can either be a list of strings, or a set of grouped strings (represented as a hash). The latter parameter
54+
type is useful for when 2 or more parameters need to be grouped together, but without generating more than one matrix permutation.
55+
5156
```
5257
"matrix": {
5358
"<parameter1 name>": [ <values...> ],
54-
"<parameter2 name>": [ <values...> ]
59+
"<parameter2 name>": [ <values...> ],
60+
"<parameter set>": {
61+
"<parameter set 1 name>": {
62+
"<parameter set 1 value 1": "value",
63+
"<parameter set 1 value 2": "<value>",
64+
},
65+
"<parameter set 2 name>": {
66+
"<parameter set 2 value 1": "value",
67+
"<parameter set 2 value 2": "<value>",
68+
}
69+
}
5570
}
5671
"include": [ <matrix>, <matrix>, ... ],
5772
"exclude": [ <matrix>, <matrix>, ... ],
@@ -202,19 +217,30 @@ The top level keys are used as job names, meaning they get displayed in the azur
202217

203218
The logic for generating display names works like this:
204219

205-
1. Sort the matrix by: parameter length, parameter name, and sort the parameter values arrays.
206-
2. In sorted order, join parameter values by "_"
220+
- Join parameter values by "_"
207221
a. If the parameter value exists as a key in `displayNames` in the matrix config, replace it with that value.
208-
b. For each name value, strip all `.-_` characters from the string.
209-
210-
The matrix is then sorted by display name, before being sent to azure pipelines. The underlying matrix may have a different
211-
sorted order than the display name output. The sorting needs to be separate so that sparse matrix generation can be deterministic.
222+
b. For each name value, strip all non-alphanumeric characters (excluding "_").
223+
c. If the name is greater than 100 characters, truncate it.
212224

213225
#### Filters
214226

215-
To be implemented. A basic example of a filter is "all" vs. "sparse" generation, but eventually will be a more programmable
216-
way of processing excludes, such as an expression that only includes entries with a container image specified. The intent
217-
is that these filters can be entered at runtime, as opposed to statically in yaml.
227+
Filters can be passed to the matrix as an array of strings, each matching the format of <key>=<regex>. When a matrix entry
228+
does not contain the specified key, it will default to a value of empty string for regex parsing. This can be used to specify
229+
filters for keys that don't exist or keys that optionally exist and match a regex, as seen in the below example.
230+
231+
Display name filters can also be passed as a single regex string that runs against the [generated display name](#displaynames) of the matrix job.
232+
The intent of display name filters is to be defined primarily as a top level variable at template queue time in the azure pipelines UI.
233+
234+
For example, the below command will filter for matrix entries with "windows" in the job display name, no matrix variable
235+
named "ExcludedKey", a framework variable containing either "461" or "5.0", and an optional key "SupportedClouds" that, if exists, must contain "Public":
236+
237+
```
238+
./Create-JobMatrix.ps1 `
239+
-ConfigPath samples/matrix.json `
240+
-Selection all `
241+
-DisplayNameFilter ".*windows.*" `
242+
-Filters @("ExcludedKey=^$", "framework=(461|5\.0)", "SupportedClouds=^$|.*Public.*")
243+
```
218244

219245
#### Under the hood
220246

0 commit comments

Comments
 (0)