573 lines
17 KiB
PowerShell
573 lines
17 KiB
PowerShell
Import-Module Pester
|
|
|
|
|
|
BeforeAll {
|
|
. $PSScriptRoot/../job-matrix-functions.ps1
|
|
|
|
function CompareMatrices([Array]$matrix, [Array]$expected) {
|
|
$matrix.Length | Should -Be $expected.Length
|
|
|
|
for ($i = 0; $i -lt $matrix.Length; $i++) {
|
|
foreach ($entry in $matrix[$i]) {
|
|
$entry.name | Should -Be $expected[$i].name
|
|
foreach ($param in $entry.parameters.GetEnumerator()) {
|
|
$param.Value | Should -Be $expected[$i].parameters[$param.Name]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Describe "Platform Matrix nonSparse" -Tag "nonsparse" {
|
|
BeforeEach {
|
|
$matrixJson = @'
|
|
{
|
|
"matrix": {
|
|
"testField1": [ 1, 2 ],
|
|
"testField2": [ 1, 2, 3 ],
|
|
"testField3": [ 1, 2, 3, 4 ],
|
|
}
|
|
}
|
|
'@
|
|
$config = GetMatrixConfigFromJson $matrixJson
|
|
}
|
|
|
|
It "Should process nonSparse parameters" {
|
|
$parameters, $nonSparse = ProcessNonSparseParameters $config.matrixParameters "testField1","testField3"
|
|
|
|
$parameters.Count | Should -Be 1
|
|
$parameters[0].Name | Should -Be "testField2"
|
|
$parameters[0].Value | Should -Be 1,2,3
|
|
|
|
$nonSparse.Count | Should -Be 2
|
|
$nonSparse[0].Name | Should -Be "testField1"
|
|
$nonSparse[0].Value | Should -Be 1,2
|
|
$nonSparse[1].Name | Should -Be "testField3"
|
|
$nonSparse[1].Value | Should -Be 1,2,3,4
|
|
|
|
$parameters, $nonSparse = ProcessNonSparseParameters $config.matrixParameters "testField3"
|
|
$parameters.Count | Should -Be 2
|
|
($parameters).Name -match "testField3" | Should -Be $null
|
|
|
|
$nonSparse.Count | Should -Be 1
|
|
$nonSparse[0].Name | Should -Be "testField3"
|
|
$nonSparse[0].Value | Should -Be 1,2,3,4
|
|
}
|
|
|
|
It "Should ignore nonSparse with all selection" {
|
|
$matrix = GenerateMatrix $config "all" -nonSparseParameters "testField3"
|
|
$matrix.Length | Should -Be 24
|
|
}
|
|
|
|
It "Should combine sparse matrix with nonSparse parameters" {
|
|
$matrix = GenerateMatrix $config "sparse" -nonSparseParameters "testField3"
|
|
$matrix.Length | Should -Be 12
|
|
}
|
|
|
|
It "Should combine with multiple nonSparse fields" {
|
|
$matrixJson = @'
|
|
{
|
|
"matrix": {
|
|
"testField1": [ 1, 2 ],
|
|
"testField2": [ 1, 2 ],
|
|
"testField3": [ 31, 32 ],
|
|
"testField4": [ 41, 42 ]
|
|
}
|
|
}
|
|
'@
|
|
$config = GetMatrixConfigFromJson $matrixJson
|
|
|
|
$matrix = GenerateMatrix $config "all" -nonSparseParameters "testField3","testField4"
|
|
$matrix.Length | Should -Be 16
|
|
|
|
$matrix = GenerateMatrix $config "sparse" -nonSparseParameters "testField3","testField4"
|
|
$matrix.Length | Should -Be 8
|
|
}
|
|
|
|
It "Should apply nonSparseParameters to an imported matrix" {
|
|
$matrixJson = @'
|
|
{
|
|
"matrix": {
|
|
"$IMPORT": "./test-import-matrix.json",
|
|
"TestField1": "test1"
|
|
},
|
|
"exclude": [ { "Baz": "importedBaz" } ]
|
|
}
|
|
'@
|
|
|
|
$expectedMatrix = @'
|
|
[
|
|
{
|
|
"parameters": { "TestField1": "test1", "Foo": "foo1", "Bar": "bar1" },
|
|
"name": "test1_foo1_bar1"
|
|
},
|
|
{
|
|
"parameters": { "TestField1": "test1", "Foo": "foo1", "Bar": "bar2" },
|
|
"name": "test1_foo1_bar2"
|
|
},
|
|
{
|
|
"parameters": { "TestField1": "test1", "Foo": "foo2", "Bar": "bar1" },
|
|
"name": "test1_foo2_bar1"
|
|
},
|
|
{
|
|
"parameters": { "TestField1": "test1", "Foo": "foo2", "Bar": "bar2" },
|
|
"name": "test1_foo2_bar2"
|
|
}
|
|
]
|
|
'@
|
|
|
|
$importConfig = GetMatrixConfigFromJson $matrixJson
|
|
$matrix = GenerateMatrix $importConfig "sparse" -nonSparseParameters "Foo"
|
|
$expected = $expectedMatrix | ConvertFrom-Json -AsHashtable
|
|
|
|
$matrix.Length | Should -Be 4
|
|
CompareMatrices $matrix $expected
|
|
}
|
|
}
|
|
|
|
Describe "Platform Matrix Import" -Tag "import" {
|
|
It "Should generate a sparse matrix where the entire base matrix is imported" {
|
|
$matrixJson = @'
|
|
{
|
|
"matrix": {
|
|
"$IMPORT": "./test-import-matrix.json"
|
|
},
|
|
"include": [
|
|
{
|
|
"fooinclude": "fooinclude"
|
|
}
|
|
]
|
|
}
|
|
'@
|
|
|
|
$expectedMatrix = @'
|
|
[
|
|
{
|
|
"parameters": { "Foo": "foo1", "Bar": "bar1" },
|
|
"name": "foo1_bar1"
|
|
},
|
|
{
|
|
"parameters": { "Foo": "foo2", "Bar": "bar2" },
|
|
"name": "foo2_bar2"
|
|
},
|
|
{
|
|
"parameters": { "Baz": "importedBaz" },
|
|
"name": "importedBazName"
|
|
},
|
|
{
|
|
"parameters": { "fooinclude": "fooinclude" },
|
|
"name": "fooinclude"
|
|
},
|
|
]
|
|
'@
|
|
|
|
$importConfig = GetMatrixConfigFromJson $matrixJson
|
|
$matrix = GenerateMatrix $importConfig "sparse"
|
|
$expected = $expectedMatrix | ConvertFrom-Json -AsHashtable
|
|
|
|
$matrix.Length | Should -Be 4
|
|
CompareMatrices $matrix $expected
|
|
}
|
|
|
|
It "Should import a matrix and combine with length=1 vectors" {
|
|
$matrixJson = @'
|
|
{
|
|
"matrix": {
|
|
"$IMPORT": "./test-import-matrix.json",
|
|
"TestField1": "test1",
|
|
"TestField2": "test2"
|
|
},
|
|
"exclude": [ { "Baz": "importedBaz" } ]
|
|
}
|
|
'@
|
|
|
|
$expectedMatrix = @'
|
|
[
|
|
{
|
|
"parameters": { "TestField1": "test1", "TestField2": "test2", "Foo": "foo1", "Bar": "bar1" },
|
|
"name": "test1_test2_foo1_bar1"
|
|
},
|
|
{
|
|
"parameters": { "TestField1": "test1", "TestField2": "test2", "Foo": "foo2", "Bar": "bar2" },
|
|
"name": "test1_test2_foo2_bar2"
|
|
}
|
|
]
|
|
'@
|
|
|
|
$importConfig = GetMatrixConfigFromJson $matrixJson
|
|
$matrix = GenerateMatrix $importConfig "sparse"
|
|
$expected = $expectedMatrix | ConvertFrom-Json -AsHashtable
|
|
|
|
$matrix.Length | Should -Be 2
|
|
CompareMatrices $matrix $expected
|
|
}
|
|
|
|
It "Should generate a matrix with nonSparseParameters and an imported sparse matrix" {
|
|
$matrixJson = @'
|
|
{
|
|
"matrix": {
|
|
"$IMPORT": "./test-import-matrix.json",
|
|
"testField": [ "test1", "test2" ]
|
|
}
|
|
}
|
|
'@
|
|
$importConfig = GetMatrixConfigFromJson $matrixJson
|
|
$matrix = GenerateMatrix $importConfig "sparse" -nonSparseParameters "testField"
|
|
|
|
$matrix.Length | Should -Be 6
|
|
|
|
$matrix[0].name | Should -Be test1_foo1_bar1
|
|
$matrix[0].parameters.testField | Should -Be "test1"
|
|
$matrix[0].parameters.Foo | Should -Be "foo1"
|
|
$matrix[2].name | Should -Be test1_importedBazName
|
|
$matrix[2].parameters.testField | Should -Be "test1"
|
|
$matrix[2].parameters.Baz | Should -Be "importedBaz"
|
|
$matrix[4].name | Should -Be test2_foo2_bar2
|
|
$matrix[4].parameters.testField | Should -Be "test2"
|
|
$matrix[4].parameters.Foo | Should -Be "foo2"
|
|
}
|
|
|
|
It "Should source imported display name lookups" {
|
|
$matrixJson = @'
|
|
{
|
|
"displayNames": {
|
|
"test1": "test1DisplayName",
|
|
"importedBaz": "importedBazNameOverride"
|
|
},
|
|
"matrix": {
|
|
"$IMPORT": "./test-import-matrix.json",
|
|
"testField": [ "test1", "test2" ]
|
|
}
|
|
}
|
|
'@
|
|
$importConfig = GetMatrixConfigFromJson $matrixJson
|
|
$matrix = GenerateMatrix $importConfig "sparse" -nonSparseParameters "testField"
|
|
|
|
$matrix[0].name | Should -Be test1DisplayName_foo1_bar1
|
|
$matrix[2].name | Should -Be test1DisplayName_importedBazNameOverride
|
|
}
|
|
|
|
It "Should generate a sparse matrix with an imported sparse matrix" {
|
|
$matrixJson = @'
|
|
{
|
|
"matrix": {
|
|
"$IMPORT": "./test-import-matrix.json",
|
|
"testField1": [ "test11", "test12" ],
|
|
"testField2": [ "test21", "test22" ]
|
|
}
|
|
}
|
|
'@
|
|
|
|
$expectedMatrix = @'
|
|
[
|
|
{
|
|
"parameters": { "testField1": "test11", "testField2": "test21", "Foo": "foo1", "Bar": "bar1" },
|
|
"name": "test11_test21_foo1_bar1"
|
|
},
|
|
{
|
|
"parameters": { "testField1": "test11", "testField2": "test21", "Foo": "foo2", "Bar": "bar2" },
|
|
"name": "test11_test21_foo2_bar2"
|
|
},
|
|
{
|
|
"parameters": { "testField1": "test11", "testField2": "test21", "Baz": "importedBaz" },
|
|
"name": "test11_test21_importedBazName"
|
|
},
|
|
{
|
|
"parameters": { "testField1": "test12", "testField2": "test22", "Foo": "foo1", "Bar": "bar1" },
|
|
"name": "test12_test22_foo1_bar1"
|
|
},
|
|
{
|
|
"parameters": { "testField1": "test12", "testField2": "test22", "Foo": "foo2", "Bar": "bar2" },
|
|
"name": "test12_test22_foo2_bar2"
|
|
},
|
|
{
|
|
"parameters": { "testField1": "test12", "testField2": "test22", "Baz": "importedBaz" },
|
|
"name": "test12_test22_importedBazName"
|
|
}
|
|
]
|
|
'@
|
|
|
|
$importConfig = GetMatrixConfigFromJson $matrixJson
|
|
$matrix = GenerateMatrix $importConfig "sparse"
|
|
$expected = $expectedMatrix | ConvertFrom-Json -AsHashtable
|
|
|
|
$matrix.Length | Should -Be 6
|
|
CompareMatrices $matrix $expected
|
|
}
|
|
|
|
It "Should import a sparse matrix with import, include, and exclude" {
|
|
$matrixJson = @'
|
|
{
|
|
"matrix": {
|
|
"$IMPORT": "./test-import-matrix.json",
|
|
"testField": [ "test1", "test2", "test3" ],
|
|
},
|
|
"include": [
|
|
{
|
|
"testImportIncludeName": [ "testInclude1", "testInclude2" ]
|
|
}
|
|
],
|
|
"exclude": [
|
|
{
|
|
"testField": "test1"
|
|
},
|
|
{
|
|
"testField": "test3",
|
|
"Baz": "importedBaz"
|
|
}
|
|
]
|
|
}
|
|
'@
|
|
|
|
$expectedMatrix = @'
|
|
[
|
|
{
|
|
"parameters": { "testField": "test2", "Foo": "foo1", "Bar": "bar1" },
|
|
"name": "test2_foo1_bar1"
|
|
},
|
|
{
|
|
"parameters": { "testField": "test2", "Foo": "foo2", "Bar": "bar2" },
|
|
"name": "test2_foo2_bar2"
|
|
},
|
|
{
|
|
"parameters": { "testField": "test2", "Baz": "importedBaz" },
|
|
"name": "test2_importedBazName"
|
|
},
|
|
{
|
|
"parameters": { "testField": "test3", "Foo": "foo1", "Bar": "bar1" },
|
|
"name": "test3_foo1_bar1"
|
|
},
|
|
{
|
|
"parameters": { "testField": "test3", "Foo": "foo2", "Bar": "bar2" },
|
|
"name": "test3_foo2_bar2"
|
|
},
|
|
{
|
|
"parameters": { "testImportIncludeName": "testInclude1" },
|
|
"name": "testInclude1"
|
|
},
|
|
{
|
|
"parameters": { "testImportIncludeName": "testInclude2" },
|
|
"name": "testInclude2"
|
|
}
|
|
]
|
|
'@
|
|
|
|
$importConfig = GetMatrixConfigFromJson $matrixJson
|
|
$matrix = GenerateMatrix $importConfig "sparse"
|
|
$expected = $expectedMatrix | ConvertFrom-Json -AsHashtable
|
|
|
|
$matrix.Length | Should -Be 7
|
|
CompareMatrices $matrix $expected
|
|
}
|
|
|
|
It "Should not combine matrices with duplicate keys" {
|
|
$matrixJson = @'
|
|
{
|
|
"matrix": {
|
|
"$IMPORT": "./test-import-matrix.json",
|
|
"Foo": [ "fooOverride1", "fooOverride2" ],
|
|
}
|
|
}
|
|
'@
|
|
|
|
$importConfig = GetMatrixConfigFromJson $matrixJson
|
|
{ GenerateMatrix $importConfig "sparse" } | Should -Throw
|
|
}
|
|
|
|
}
|
|
|
|
Describe "Platform Matrix Replace" -Tag "replace" {
|
|
It "Should parse replacement syntax" -TestCases @(
|
|
@{ query = 'foo=bar/baz'; key = '^foo$'; value = '^bar$'; replace = 'baz' },
|
|
@{ query = 'foo=\/p:bar/\/p:baz'; key = '^foo$'; value = '^\/p:bar$'; replace = '/p:baz' },
|
|
@{ query = 'f\=o\/o=\/p:b\=ar/\/p:b\=az'; key = '^f\=o\/o$'; value = '^\/p:b\=ar$'; replace = '/p:b=az' },
|
|
@{ query = 'foo=bar/'; key = '^foo$'; value = '^bar$'; replace = '' },
|
|
@{ query = 'foo=/baz'; key = '^foo$'; value = '^$'; replace = 'baz' }
|
|
) {
|
|
$parsed = ParseReplacement $query
|
|
$parsed.key | Should -Be $key
|
|
$parsed.value | Should -Be $value
|
|
$parsed.replace | Should -Be $replace
|
|
}
|
|
|
|
It "Should fail for invalid replacement syntax" -TestCases @(
|
|
@{ query = '' },
|
|
@{ query = 'asdf' },
|
|
@{ query = 'asdf=foo/bar/baz' },
|
|
@{ query = 'asdf=foo=bar/baz' },
|
|
@{ query = 'asdf=foo' }
|
|
) {
|
|
{ $parsed = ParseReplacement $query } | Should -Throw
|
|
{ $parsed = ParseReplacement $query } | Should -Throw
|
|
{ $parsed = ParseReplacement $query } | Should -Throw
|
|
{ $parsed = ParseReplacement $query } | Should -Throw
|
|
{ $parsed = ParseReplacement $query } | Should -Throw
|
|
}
|
|
|
|
It "Should replace values in a matrix" {
|
|
$matrixJson = @'
|
|
{
|
|
"matrix": {
|
|
"Foo": [ "foo1", "foo2" ],
|
|
"Bar": [ "bar1", "bar2" ]
|
|
},
|
|
"include": [ { "Baz": "baz1" } ]
|
|
}
|
|
'@
|
|
|
|
$expectedMatrix = @'
|
|
[
|
|
{
|
|
"parameters": { "Foo": "foo1Replaced", "Bar": "bar1" },
|
|
"name": "foo1Replaced_bar1"
|
|
},
|
|
{
|
|
"parameters": { "Foo": "fooDefaultReplaced", "Bar": "bar2" },
|
|
"name": "fooDefaultReplaced_bar2"
|
|
},
|
|
{
|
|
"parameters": { "Baz": "bazReplaced" },
|
|
"name": "bazReplaced"
|
|
}
|
|
]
|
|
'@
|
|
|
|
$replace = @(
|
|
"Foo=foo1/foo1Replaced",
|
|
"Foo=foo.*/fooDefaultReplaced",
|
|
".*=B.z\d/bazReplaced"
|
|
)
|
|
|
|
$importConfig = GetMatrixConfigFromJson $matrixJson
|
|
$matrix = GenerateMatrix -config $importConfig -selectFromMatrixType "sparse" -replace $replace
|
|
$expected = $expectedMatrix | ConvertFrom-Json -AsHashtable
|
|
|
|
$matrix.Length | Should -Be 3
|
|
CompareMatrices $matrix $expected
|
|
}
|
|
|
|
It "Should replace values in a matrix with import and nonSparseParameters" {
|
|
$matrixJson = @'
|
|
{
|
|
"matrix": {
|
|
"$IMPORT": "./test-import-matrix.json",
|
|
"testField": [ "test1", "test2" ]
|
|
}
|
|
}
|
|
'@
|
|
$importConfig = GetMatrixConfigFromJson $matrixJson
|
|
$matrix = GenerateMatrix $importConfig "sparse" -nonSparseParameters "testField" -replace @("testField=test1/testReplaced", "Baz=.*/bazReplaced")
|
|
|
|
$matrix.Length | Should -Be 6
|
|
|
|
$matrix[0].name | Should -Be testReplaced_foo1_bar1
|
|
$matrix[0].parameters.testField | Should -Be "testReplaced"
|
|
$matrix[0].parameters.Foo | Should -Be "foo1"
|
|
$matrix[2].name | Should -Be testReplaced_bazReplaced
|
|
$matrix[2].parameters.testField | Should -Be "testReplaced"
|
|
$matrix[2].parameters.Baz | Should -Be "bazReplaced"
|
|
$matrix[4].name | Should -Be test2_foo2_bar2
|
|
$matrix[4].parameters.testField | Should -Be "test2"
|
|
$matrix[4].parameters.Foo | Should -Be "foo2"
|
|
}
|
|
|
|
It "Should replace values in groupings" {
|
|
$matrixJson = @'
|
|
{
|
|
"matrix": {
|
|
"Agent": {
|
|
"ubuntu-1804": { "OSVmImage": "MMSUbuntu18.04", "Pool": "azsdk-pool-mms-ubuntu-1804-general" }
|
|
},
|
|
"JavaTestVersion": [ "1.8", "1.11" ]
|
|
}
|
|
}
|
|
'@
|
|
$importConfig = GetMatrixConfigFromJson $matrixJson
|
|
$matrix = GenerateMatrix $importConfig "all" -replace @("JavaTestVersion=1.8/2.0", "Pool=.*ubuntu.*/custom-ubuntu-pool")
|
|
|
|
$matrix.Length | Should -Be 2
|
|
# Replacements of inner values will preserve the grouping name
|
|
$matrix[0].name | Should -Be "ubuntu1804_20"
|
|
$matrix[0].parameters.JavaTestVersion | Should -Be "2.0"
|
|
$matrix[0].parameters.Pool | Should -Be "custom-ubuntu-pool"
|
|
$matrix[0].parameters.OSVmImage | Should -Be "MMSUbuntu18.04"
|
|
|
|
# Make sure non-literal keys still replace under the hood
|
|
$matrix = GenerateMatrix $importConfig "all" -replace ".*=.*ubuntu.*/custom-ubuntu-pool"
|
|
|
|
$matrix.Length | Should -Be 2
|
|
$matrix[0].name | Should -Be "ubuntu1804_18"
|
|
$matrix[0].parameters.Pool | Should -Be "custom-ubuntu-pool"
|
|
}
|
|
|
|
It "Should replace values and apply regex capture groups" {
|
|
$matrixJson = @'
|
|
{
|
|
"matrix": {
|
|
"Foo": [ "foo1", "foo2" ],
|
|
"Bar": [ "bar1", "bar2" ]
|
|
}
|
|
}
|
|
'@
|
|
$importConfig = GetMatrixConfigFromJson $matrixJson
|
|
$replace = 'Foo=(foo)1/$1ReplacedFoo1', 'B.*=(.*)2/$1ReplacedBar2'
|
|
$matrix = GenerateMatrix $importConfig "sparse" -replace $replace
|
|
|
|
$matrix.Length | Should -Be 2
|
|
$matrix[0].name | Should -Be "fooReplacedFoo1_bar1"
|
|
$matrix[0].parameters.Foo | Should -Be "fooReplacedFoo1"
|
|
|
|
$matrix[1].name | Should -Be "foo2_barReplacedBar2"
|
|
$matrix[1].parameters.Bar | Should -Be "barReplacedBar2"
|
|
}
|
|
|
|
It "Should only fully match a string for replace" {
|
|
$matrixJson = @'
|
|
{
|
|
"matrix": {
|
|
"Foo": [ "foo1", "foo2" ],
|
|
"Bar": "bar1"
|
|
}
|
|
}
|
|
'@
|
|
|
|
$importConfig = GetMatrixConfigFromJson $matrixJson
|
|
|
|
$replace = @("Foo=foo/shouldNotReplaceFoo", "B=bar1/shouldNotReplaceBar")
|
|
$matrix = GenerateMatrix -config $importConfig -selectFromMatrixType "sparse" -replace $replace
|
|
|
|
$matrix.Length | Should -Be 2
|
|
$matrix[0].parameters.Foo | Should -Be "foo1"
|
|
$matrix[0].parameters.Bar | Should -Be "bar1"
|
|
$matrix[1].parameters.Foo | Should -Be "foo2"
|
|
$matrix[1].parameters.Bar | Should -Be "bar1"
|
|
}
|
|
|
|
It "Should parse replacement syntax and source imported display name lookups" {
|
|
$matrixJson = @'
|
|
{
|
|
"displayNames": {
|
|
"replaceme": ""
|
|
},
|
|
"matrix": {
|
|
"$IMPORT": "./test-import-matrix.json",
|
|
"replaceme": "replaceme"
|
|
}
|
|
}
|
|
'@
|
|
$importConfig = GetMatrixConfigFromJson $matrixJson
|
|
$replace = 'Foo=(foo)1/$1ReplacedFoo1', 'B.*=(.*)2/$1ReplacedBar2'
|
|
$matrix = GenerateMatrix $importConfig "sparse" -replace $replace
|
|
|
|
$matrix.Length | Should -Be 3
|
|
$matrix[0].name | Should -Be "fooReplacedFoo1_bar1"
|
|
$matrix[0].parameters.Foo | Should -Be "fooReplacedFoo1"
|
|
$matrix[1].name | Should -Be "foo2_barReplacedBar2"
|
|
$matrix[1].parameters.Bar | Should -Be "barReplacedBar2"
|
|
$matrix[2].name | Should -Be "importedBazName"
|
|
$matrix[2].parameters.Baz | Should -Be "importedBaz"
|
|
$matrix[2].parameters.replaceme | Should -Be "replaceme"
|
|
}
|
|
|
|
}
|