1Import-Module Pester
2
3
4BeforeAll {
5 . $PSScriptRoot/../job-matrix-functions.ps1
6
7 function CompareMatrices([Array]$matrix, [Array]$expected) {
8 $matrix.Length | Should -Be $expected.Length
9
10 for ($i = 0; $i -lt $matrix.Length; $i++) {
11 foreach ($entry in $matrix[$i]) {
12 $entry.name | Should -Be $expected[$i].name
13 foreach ($param in $entry.parameters.GetEnumerator()) {
14 $param.Value | Should -Be $expected[$i].parameters[$param.Name]
15 }
16 }
17 }
18 }
19}
20
21Describe "Platform Matrix nonSparse" -Tag "nonsparse" {
22 BeforeEach {
23 $matrixJson = @'
24{
25 "matrix": {
26 "testField1": [ 1, 2 ],
27 "testField2": [ 1, 2, 3 ],
28 "testField3": [ 1, 2, 3, 4 ],
29 }
30}
31'@
32 $config = GetMatrixConfigFromJson $matrixJson
33 }
34
35 It "Should process nonSparse parameters" {
36 $parameters, $nonSparse = ProcessNonSparseParameters $config.matrixParameters "testField1","testField3"
37
38 $parameters.Count | Should -Be 1
39 $parameters[0].Name | Should -Be "testField2"
40 $parameters[0].Value | Should -Be 1,2,3
41
42 $nonSparse.Count | Should -Be 2
43 $nonSparse[0].Name | Should -Be "testField1"
44 $nonSparse[0].Value | Should -Be 1,2
45 $nonSparse[1].Name | Should -Be "testField3"
46 $nonSparse[1].Value | Should -Be 1,2,3,4
47
48 $parameters, $nonSparse = ProcessNonSparseParameters $config.matrixParameters "testField3"
49 $parameters.Count | Should -Be 2
50 ($parameters).Name -match "testField3" | Should -Be $null
51
52 $nonSparse.Count | Should -Be 1
53 $nonSparse[0].Name | Should -Be "testField3"
54 $nonSparse[0].Value | Should -Be 1,2,3,4
55 }
56
57 It "Should ignore nonSparse with all selection" {
58 $matrix = GenerateMatrix $config "all" -nonSparseParameters "testField3"
59 $matrix.Length | Should -Be 24
60 }
61
62 It "Should combine sparse matrix with nonSparse parameters" {
63 $matrix = GenerateMatrix $config "sparse" -nonSparseParameters "testField3"
64 $matrix.Length | Should -Be 12
65 }
66
67 It "Should combine with multiple nonSparse fields" {
68 $matrixJson = @'
69{
70 "matrix": {
71 "testField1": [ 1, 2 ],
72 "testField2": [ 1, 2 ],
73 "testField3": [ 31, 32 ],
74 "testField4": [ 41, 42 ]
75 }
76}
77'@
78 $config = GetMatrixConfigFromJson $matrixJson
79
80 $matrix = GenerateMatrix $config "all" -nonSparseParameters "testField3","testField4"
81 $matrix.Length | Should -Be 16
82
83 $matrix = GenerateMatrix $config "sparse" -nonSparseParameters "testField3","testField4"
84 $matrix.Length | Should -Be 8
85 }
86
87 It "Should apply nonSparseParameters to an imported matrix" {
88 $matrixJson = @'
89{
90 "matrix": {
91 "$IMPORT": "./test-import-matrix.json",
92 "TestField1": "test1"
93 },
94 "exclude": [ { "Baz": "importedBaz" } ]
95}
96'@
97
98 $expectedMatrix = @'
99[
100 {
101 "parameters": { "TestField1": "test1", "Foo": "foo1", "Bar": "bar1" },
102 "name": "test1_foo1_bar1"
103 },
104 {
105 "parameters": { "TestField1": "test1", "Foo": "foo1", "Bar": "bar2" },
106 "name": "test1_foo1_bar2"
107 },
108 {
109 "parameters": { "TestField1": "test1", "Foo": "foo2", "Bar": "bar1" },
110 "name": "test1_foo2_bar1"
111 },
112 {
113 "parameters": { "TestField1": "test1", "Foo": "foo2", "Bar": "bar2" },
114 "name": "test1_foo2_bar2"
115 }
116]
117'@
118
119 $importConfig = GetMatrixConfigFromJson $matrixJson
120 $matrix = GenerateMatrix $importConfig "sparse" -nonSparseParameters "Foo"
121 $expected = $expectedMatrix | ConvertFrom-Json -AsHashtable
122
123 $matrix.Length | Should -Be 4
124 CompareMatrices $matrix $expected
125 }
126}
127
128Describe "Platform Matrix Import" -Tag "import" {
129 It "Should generate a sparse matrix where the entire base matrix is imported" {
130 $matrixJson = @'
131{
132 "matrix": {
133 "$IMPORT": "./test-import-matrix.json"
134 },
135 "include": [
136 {
137 "fooinclude": "fooinclude"
138 }
139 ]
140}
141'@
142
143 $expectedMatrix = @'
144[
145 {
146 "parameters": { "Foo": "foo1", "Bar": "bar1" },
147 "name": "foo1_bar1"
148 },
149 {
150 "parameters": { "Foo": "foo2", "Bar": "bar2" },
151 "name": "foo2_bar2"
152 },
153 {
154 "parameters": { "Baz": "importedBaz" },
155 "name": "importedBazName"
156 },
157 {
158 "parameters": { "fooinclude": "fooinclude" },
159 "name": "fooinclude"
160 },
161]
162'@
163
164 $importConfig = GetMatrixConfigFromJson $matrixJson
165 $matrix = GenerateMatrix $importConfig "sparse"
166 $expected = $expectedMatrix | ConvertFrom-Json -AsHashtable
167
168 $matrix.Length | Should -Be 4
169 CompareMatrices $matrix $expected
170 }
171
172 It "Should import a matrix and combine with length=1 vectors" {
173 $matrixJson = @'
174{
175 "matrix": {
176 "$IMPORT": "./test-import-matrix.json",
177 "TestField1": "test1",
178 "TestField2": "test2"
179 },
180 "exclude": [ { "Baz": "importedBaz" } ]
181}
182'@
183
184 $expectedMatrix = @'
185[
186 {
187 "parameters": { "TestField1": "test1", "TestField2": "test2", "Foo": "foo1", "Bar": "bar1" },
188 "name": "test1_test2_foo1_bar1"
189 },
190 {
191 "parameters": { "TestField1": "test1", "TestField2": "test2", "Foo": "foo2", "Bar": "bar2" },
192 "name": "test1_test2_foo2_bar2"
193 }
194]
195'@
196
197 $importConfig = GetMatrixConfigFromJson $matrixJson
198 $matrix = GenerateMatrix $importConfig "sparse"
199 $expected = $expectedMatrix | ConvertFrom-Json -AsHashtable
200
201 $matrix.Length | Should -Be 2
202 CompareMatrices $matrix $expected
203 }
204
205 It "Should generate a matrix with nonSparseParameters and an imported sparse matrix" {
206 $matrixJson = @'
207{
208 "matrix": {
209 "$IMPORT": "./test-import-matrix.json",
210 "testField": [ "test1", "test2" ]
211 }
212}
213'@
214 $importConfig = GetMatrixConfigFromJson $matrixJson
215 $matrix = GenerateMatrix $importConfig "sparse" -nonSparseParameters "testField"
216
217 $matrix.Length | Should -Be 6
218
219 $matrix[0].name | Should -Be test1_foo1_bar1
220 $matrix[0].parameters.testField | Should -Be "test1"
221 $matrix[0].parameters.Foo | Should -Be "foo1"
222 $matrix[2].name | Should -Be test1_importedBazName
223 $matrix[2].parameters.testField | Should -Be "test1"
224 $matrix[2].parameters.Baz | Should -Be "importedBaz"
225 $matrix[4].name | Should -Be test2_foo2_bar2
226 $matrix[4].parameters.testField | Should -Be "test2"
227 $matrix[4].parameters.Foo | Should -Be "foo2"
228 }
229
230 It "Should source imported display name lookups" {
231 $matrixJson = @'
232{
233 "displayNames": {
234 "test1": "test1DisplayName",
235 "importedBaz": "importedBazNameOverride"
236 },
237 "matrix": {
238 "$IMPORT": "./test-import-matrix.json",
239 "testField": [ "test1", "test2" ]
240 }
241}
242'@
243 $importConfig = GetMatrixConfigFromJson $matrixJson
244 $matrix = GenerateMatrix $importConfig "sparse" -nonSparseParameters "testField"
245
246 $matrix[0].name | Should -Be test1DisplayName_foo1_bar1
247 $matrix[2].name | Should -Be test1DisplayName_importedBazNameOverride
248 }
249
250 It "Should generate a sparse matrix with an imported sparse matrix" {
251 $matrixJson = @'
252{
253 "matrix": {
254 "$IMPORT": "./test-import-matrix.json",
255 "testField1": [ "test11", "test12" ],
256 "testField2": [ "test21", "test22" ]
257 }
258}
259'@
260
261 $expectedMatrix = @'
262[
263 {
264 "parameters": { "testField1": "test11", "testField2": "test21", "Foo": "foo1", "Bar": "bar1" },
265 "name": "test11_test21_foo1_bar1"
266 },
267 {
268 "parameters": { "testField1": "test11", "testField2": "test21", "Foo": "foo2", "Bar": "bar2" },
269 "name": "test11_test21_foo2_bar2"
270 },
271 {
272 "parameters": { "testField1": "test11", "testField2": "test21", "Baz": "importedBaz" },
273 "name": "test11_test21_importedBazName"
274 },
275 {
276 "parameters": { "testField1": "test12", "testField2": "test22", "Foo": "foo1", "Bar": "bar1" },
277 "name": "test12_test22_foo1_bar1"
278 },
279 {
280 "parameters": { "testField1": "test12", "testField2": "test22", "Foo": "foo2", "Bar": "bar2" },
281 "name": "test12_test22_foo2_bar2"
282 },
283 {
284 "parameters": { "testField1": "test12", "testField2": "test22", "Baz": "importedBaz" },
285 "name": "test12_test22_importedBazName"
286 }
287]
288'@
289
290 $importConfig = GetMatrixConfigFromJson $matrixJson
291 $matrix = GenerateMatrix $importConfig "sparse"
292 $expected = $expectedMatrix | ConvertFrom-Json -AsHashtable
293
294 $matrix.Length | Should -Be 6
295 CompareMatrices $matrix $expected
296 }
297
298 It "Should import a sparse matrix with import, include, and exclude" {
299 $matrixJson = @'
300{
301 "matrix": {
302 "$IMPORT": "./test-import-matrix.json",
303 "testField": [ "test1", "test2", "test3" ],
304 },
305 "include": [
306 {
307 "testImportIncludeName": [ "testInclude1", "testInclude2" ]
308 }
309 ],
310 "exclude": [
311 {
312 "testField": "test1"
313 },
314 {
315 "testField": "test3",
316 "Baz": "importedBaz"
317 }
318 ]
319}
320'@
321
322 $expectedMatrix = @'
323[
324 {
325 "parameters": { "testField": "test2", "Foo": "foo1", "Bar": "bar1" },
326 "name": "test2_foo1_bar1"
327 },
328 {
329 "parameters": { "testField": "test2", "Foo": "foo2", "Bar": "bar2" },
330 "name": "test2_foo2_bar2"
331 },
332 {
333 "parameters": { "testField": "test2", "Baz": "importedBaz" },
334 "name": "test2_importedBazName"
335 },
336 {
337 "parameters": { "testField": "test3", "Foo": "foo1", "Bar": "bar1" },
338 "name": "test3_foo1_bar1"
339 },
340 {
341 "parameters": { "testField": "test3", "Foo": "foo2", "Bar": "bar2" },
342 "name": "test3_foo2_bar2"
343 },
344 {
345 "parameters": { "testImportIncludeName": "testInclude1" },
346 "name": "testInclude1"
347 },
348 {
349 "parameters": { "testImportIncludeName": "testInclude2" },
350 "name": "testInclude2"
351 }
352]
353'@
354
355 $importConfig = GetMatrixConfigFromJson $matrixJson
356 $matrix = GenerateMatrix $importConfig "sparse"
357 $expected = $expectedMatrix | ConvertFrom-Json -AsHashtable
358
359 $matrix.Length | Should -Be 7
360 CompareMatrices $matrix $expected
361 }
362
363 It "Should not combine matrices with duplicate keys" {
364 $matrixJson = @'
365{
366 "matrix": {
367 "$IMPORT": "./test-import-matrix.json",
368 "Foo": [ "fooOverride1", "fooOverride2" ],
369 }
370}
371'@
372
373 $importConfig = GetMatrixConfigFromJson $matrixJson
374 { GenerateMatrix $importConfig "sparse" } | Should -Throw
375 }
376
377}
378
379Describe "Platform Matrix Replace" -Tag "replace" {
380 It "Should parse replacement syntax" -TestCases @(
381 @{ query = 'foo=bar/baz'; key = '^foo$'; value = '^bar$'; replace = 'baz' },
382 @{ query = 'foo=\/p:bar/\/p:baz'; key = '^foo$'; value = '^\/p:bar$'; replace = '/p:baz' },
383 @{ query = 'f\=o\/o=\/p:b\=ar/\/p:b\=az'; key = '^f\=o\/o$'; value = '^\/p:b\=ar$'; replace = '/p:b=az' },
384 @{ query = 'foo=bar/'; key = '^foo$'; value = '^bar$'; replace = '' },
385 @{ query = 'foo=/baz'; key = '^foo$'; value = '^$'; replace = 'baz' }
386 ) {
387 $parsed = ParseReplacement $query
388 $parsed.key | Should -Be $key
389 $parsed.value | Should -Be $value
390 $parsed.replace | Should -Be $replace
391 }
392
393 It "Should fail for invalid replacement syntax" -TestCases @(
394 @{ query = '' },
395 @{ query = 'asdf' },
396 @{ query = 'asdf=foo/bar/baz' },
397 @{ query = 'asdf=foo=bar/baz' },
398 @{ query = 'asdf=foo' }
399 ) {
400 { $parsed = ParseReplacement $query } | Should -Throw
401 { $parsed = ParseReplacement $query } | Should -Throw
402 { $parsed = ParseReplacement $query } | Should -Throw
403 { $parsed = ParseReplacement $query } | Should -Throw
404 { $parsed = ParseReplacement $query } | Should -Throw
405 }
406
407 It "Should replace values in a matrix" {
408 $matrixJson = @'
409{
410 "matrix": {
411 "Foo": [ "foo1", "foo2" ],
412 "Bar": [ "bar1", "bar2" ]
413 },
414 "include": [ { "Baz": "baz1" } ]
415}
416'@
417
418 $expectedMatrix = @'
419[
420 {
421 "parameters": { "Foo": "foo1Replaced", "Bar": "bar1" },
422 "name": "foo1Replaced_bar1"
423 },
424 {
425 "parameters": { "Foo": "fooDefaultReplaced", "Bar": "bar2" },
426 "name": "fooDefaultReplaced_bar2"
427 },
428 {
429 "parameters": { "Baz": "bazReplaced" },
430 "name": "bazReplaced"
431 }
432]
433'@
434
435 $replace = @(
436 "Foo=foo1/foo1Replaced",
437 "Foo=foo.*/fooDefaultReplaced",
438 ".*=B.z\d/bazReplaced"
439 )
440
441 $importConfig = GetMatrixConfigFromJson $matrixJson
442 $matrix = GenerateMatrix -config $importConfig -selectFromMatrixType "sparse" -replace $replace
443 $expected = $expectedMatrix | ConvertFrom-Json -AsHashtable
444
445 $matrix.Length | Should -Be 3
446 CompareMatrices $matrix $expected
447 }
448
449 It "Should replace values in a matrix with import and nonSparseParameters" {
450 $matrixJson = @'
451{
452 "matrix": {
453 "$IMPORT": "./test-import-matrix.json",
454 "testField": [ "test1", "test2" ]
455 }
456}
457'@
458 $importConfig = GetMatrixConfigFromJson $matrixJson
459 $matrix = GenerateMatrix $importConfig "sparse" -nonSparseParameters "testField" -replace @("testField=test1/testReplaced", "Baz=.*/bazReplaced")
460
461 $matrix.Length | Should -Be 6
462
463 $matrix[0].name | Should -Be testReplaced_foo1_bar1
464 $matrix[0].parameters.testField | Should -Be "testReplaced"
465 $matrix[0].parameters.Foo | Should -Be "foo1"
466 $matrix[2].name | Should -Be testReplaced_bazReplaced
467 $matrix[2].parameters.testField | Should -Be "testReplaced"
468 $matrix[2].parameters.Baz | Should -Be "bazReplaced"
469 $matrix[4].name | Should -Be test2_foo2_bar2
470 $matrix[4].parameters.testField | Should -Be "test2"
471 $matrix[4].parameters.Foo | Should -Be "foo2"
472 }
473
474 It "Should replace values in groupings" {
475 $matrixJson = @'
476{
477 "matrix": {
478 "Agent": {
479 "ubuntu-1804": { "OSVmImage": "MMSUbuntu18.04", "Pool": "azsdk-pool-mms-ubuntu-1804-general" }
480 },
481 "JavaTestVersion": [ "1.8", "1.11" ]
482 }
483}
484'@
485 $importConfig = GetMatrixConfigFromJson $matrixJson
486 $matrix = GenerateMatrix $importConfig "all" -replace @("JavaTestVersion=1.8/2.0", "Pool=.*ubuntu.*/custom-ubuntu-pool")
487
488 $matrix.Length | Should -Be 2
489 # Replacements of inner values will preserve the grouping name
490 $matrix[0].name | Should -Be "ubuntu1804_20"
491 $matrix[0].parameters.JavaTestVersion | Should -Be "2.0"
492 $matrix[0].parameters.Pool | Should -Be "custom-ubuntu-pool"
493 $matrix[0].parameters.OSVmImage | Should -Be "MMSUbuntu18.04"
494
495 # Make sure non-literal keys still replace under the hood
496 $matrix = GenerateMatrix $importConfig "all" -replace ".*=.*ubuntu.*/custom-ubuntu-pool"
497
498 $matrix.Length | Should -Be 2
499 $matrix[0].name | Should -Be "ubuntu1804_18"
500 $matrix[0].parameters.Pool | Should -Be "custom-ubuntu-pool"
501 }
502
503 It "Should replace values and apply regex capture groups" {
504 $matrixJson = @'
505{
506 "matrix": {
507 "Foo": [ "foo1", "foo2" ],
508 "Bar": [ "bar1", "bar2" ]
509 }
510}
511'@
512 $importConfig = GetMatrixConfigFromJson $matrixJson
513 $replace = 'Foo=(foo)1/$1ReplacedFoo1', 'B.*=(.*)2/$1ReplacedBar2'
514 $matrix = GenerateMatrix $importConfig "sparse" -replace $replace
515
516 $matrix.Length | Should -Be 2
517 $matrix[0].name | Should -Be "fooReplacedFoo1_bar1"
518 $matrix[0].parameters.Foo | Should -Be "fooReplacedFoo1"
519
520 $matrix[1].name | Should -Be "foo2_barReplacedBar2"
521 $matrix[1].parameters.Bar | Should -Be "barReplacedBar2"
522 }
523
524 It "Should only fully match a string for replace" {
525 $matrixJson = @'
526{
527 "matrix": {
528 "Foo": [ "foo1", "foo2" ],
529 "Bar": "bar1"
530 }
531}
532'@
533
534 $importConfig = GetMatrixConfigFromJson $matrixJson
535
536 $replace = @("Foo=foo/shouldNotReplaceFoo", "B=bar1/shouldNotReplaceBar")
537 $matrix = GenerateMatrix -config $importConfig -selectFromMatrixType "sparse" -replace $replace
538
539 $matrix.Length | Should -Be 2
540 $matrix[0].parameters.Foo | Should -Be "foo1"
541 $matrix[0].parameters.Bar | Should -Be "bar1"
542 $matrix[1].parameters.Foo | Should -Be "foo2"
543 $matrix[1].parameters.Bar | Should -Be "bar1"
544 }
545}
View as plain text