diff --git a/arm-ttk/testcases/CreateUIDefinition/VMSizes-Must-Match-Template.test.ps1 b/arm-ttk/testcases/CreateUIDefinition/VMSizes-Must-Match-Template.test.ps1 index 793abf91..2b7aa9cd 100644 --- a/arm-ttk/testcases/CreateUIDefinition/VMSizes-Must-Match-Template.test.ps1 +++ b/arm-ttk/testcases/CreateUIDefinition/VMSizes-Must-Match-Template.test.ps1 @@ -21,6 +21,44 @@ $MainTemplateParameters #Write-Warning "Skipping Test..." #break +# Helper function to recursively search for a pattern in nested objects +# Returns the top-level property name and the matching value when found +function Find-OutputProperty { + param( + [Parameter(Mandatory=$true)] + [PSObject]$Object, + + [Parameter(Mandatory=$true)] + [string]$Pattern, + + [Parameter(Mandatory=$false)] + [string]$TopLevelPropertyName = $null + ) + + foreach ($prop in $Object.psobject.properties) { + # Track the top-level property name for matching with template parameters + # This is the property name we'll use to look up in MainTemplateParameters + $topLevelName = if ($TopLevelPropertyName) { $TopLevelPropertyName } else { $prop.Name } + + if ($prop.Value -is [string] -and $prop.Value -like $Pattern) { + # Found a matching string value - return the top-level property name + return [PSCustomObject]@{ + Name = $topLevelName + Value = $prop.Value + } + } + elseif ($prop.Value -is [PSCustomObject] -or $prop.Value -is [System.Collections.Specialized.OrderedDictionary]) { + # Recursively search nested objects, preserving the top-level property name + $result = Find-OutputProperty -Object $prop.Value -Pattern $Pattern -TopLevelPropertyName $topLevelName + if ($result) { + return $result + } + } + } + + return $null +} + # First, find all size selectors in CreateUIDefinition. $sizeSelectors = $CreateUIDefinitionObject | Find-JsonContent -Key type -Value Microsoft.Compute.SizeSelector @@ -42,11 +80,9 @@ foreach ($selector in $sizeSelectors) { # Then walk each selector, } else { "*basics(*$($controlName)*" } - $theOutput = foreach ($out in $CreateUIDefinitionObject.parameters.outputs.psobject.properties) { - if ($out.Value -like $lookingFor) { - $out; break - } - } + + # Use the helper function to recursively search for the pattern in outputs + $theOutput = Find-OutputProperty -Object $CreateUIDefinitionObject.parameters.outputs -Pattern $lookingFor if (-not $theOutput) { Write-Error "Could not find VM SizeSelector '$($selector.Name)' in outputs" -TargetObject $selector diff --git a/unit-tests/VMSizes-Must-Match-Template/Pass/Multiple-Nested-VMSizes/azureDeploy.json b/unit-tests/VMSizes-Must-Match-Template/Pass/Multiple-Nested-VMSizes/azureDeploy.json new file mode 100644 index 00000000..4ff94a8d --- /dev/null +++ b/unit-tests/VMSizes-Must-Match-Template/Pass/Multiple-Nested-VMSizes/azureDeploy.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "parameters": { + "clusters": { + "type": "object" + } + }, + "resources": [] +} diff --git a/unit-tests/VMSizes-Must-Match-Template/Pass/Multiple-Nested-VMSizes/createUIDefinition.json b/unit-tests/VMSizes-Must-Match-Template/Pass/Multiple-Nested-VMSizes/createUIDefinition.json new file mode 100644 index 00000000..abb15d76 --- /dev/null +++ b/unit-tests/VMSizes-Must-Match-Template/Pass/Multiple-Nested-VMSizes/createUIDefinition.json @@ -0,0 +1,92 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/0.1.2-preview/CreateUIDefinition.MultiVm.json#", + "handler": "Microsoft.Azure.CreateUIDef", + "version": "0.1.2-preview", + "parameters": { + "basics": [], + "steps": [ + { + "label": "Scheduler", + "name": "scheduler", + "bladeTitle": "Scheduler", + "bladeSubtitle": "Configure Scheduler", + "elements": [ + { + "label": "Scheduler Section", + "name": "schedulerSection", + "type": "Microsoft.Common.Section", + "elements": [ + { + "label": "Scheduler VM Size", + "name": "vmsize", + "type": "Microsoft.Compute.SizeSelector", + "osPlatform": "Linux", + "count": 1, + "recommendedSizes": [ + "Standard_B1s" + ] + } + ] + }, + { + "label": "Login Nodes Section", + "name": "loginNodesSection", + "type": "Microsoft.Common.Section", + "elements": [ + { + "label": "Login Node VM Size", + "name": "vmsize", + "type": "Microsoft.Compute.SizeSelector", + "osPlatform": "Linux", + "count": 1, + "recommendedSizes": [ + "Standard_B1ms" + ] + } + ] + } + ] + }, + { + "label": "Slurm Settings", + "name": "slurmSettings", + "bladeTitle": "Slurm Settings", + "elements": [ + { + "label": "HTC Section", + "name": "HTCSection", + "type": "Microsoft.Common.Section", + "elements": [ + { + "label": "HTC VM Size", + "name": "vmsize", + "type": "Microsoft.Compute.SizeSelector", + "osPlatform": "Linux", + "count": 1, + "recommendedSizes": [ + "Standard_B2s" + ] + } + ] + } + ] + } + ], + "outputs": { + "location": "[location()]", + "clusters": { + "slurm": { + "schedulerNode": { + "sku": "[steps('scheduler').schedulerSection.vmsize]" + }, + "loginNodes": { + "sku": "[steps('scheduler').loginNodesSection.vmsize]" + }, + "htc": { + "sku": "[steps('slurmSettings').HTCSection.vmsize]" + } + } + } + } + } +} diff --git a/unit-tests/VMSizes-Must-Match-Template/Pass/Nested-Outputs-2-Levels/azureDeploy.json b/unit-tests/VMSizes-Must-Match-Template/Pass/Nested-Outputs-2-Levels/azureDeploy.json new file mode 100644 index 00000000..4ff94a8d --- /dev/null +++ b/unit-tests/VMSizes-Must-Match-Template/Pass/Nested-Outputs-2-Levels/azureDeploy.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "parameters": { + "clusters": { + "type": "object" + } + }, + "resources": [] +} diff --git a/unit-tests/VMSizes-Must-Match-Template/Pass/Nested-Outputs-2-Levels/createUIDefinition.json b/unit-tests/VMSizes-Must-Match-Template/Pass/Nested-Outputs-2-Levels/createUIDefinition.json new file mode 100644 index 00000000..4dcbc4b4 --- /dev/null +++ b/unit-tests/VMSizes-Must-Match-Template/Pass/Nested-Outputs-2-Levels/createUIDefinition.json @@ -0,0 +1,49 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/0.1.2-preview/CreateUIDefinition.MultiVm.json#", + "handler": "Microsoft.Azure.CreateUIDef", + "version": "0.1.2-preview", + "parameters": { + "basics": [], + "steps": [ + { + "label": "Scheduler", + "name": "scheduler", + "bladeTitle": "Scheduler", + "bladeSubtitle": "Configure Scheduler", + "subLabel": { + "preValidation": "Configure Scheduler", + "postValidation": "Done" + }, + "elements": [ + { + "label": "Scheduler Section", + "name": "schedulerSection", + "type": "Microsoft.Common.Section", + "elements": [ + { + "label": "VM Size", + "name": "vmsize", + "toolTip": "Scheduler VM size", + "type": "Microsoft.Compute.SizeSelector", + "osPlatform": "Linux", + "count": 1, + "recommendedSizes": [ + "Standard_B1s", + "Standard_B1ms" + ] + } + ] + } + ] + } + ], + "outputs": { + "location": "[location()]", + "clusters": { + "schedulerNode": { + "sku": "[steps('scheduler').schedulerSection.vmsize]" + } + } + } + } +} diff --git a/unit-tests/VMSizes-Must-Match-Template/Pass/Nested-Outputs-3-Levels/azureDeploy.json b/unit-tests/VMSizes-Must-Match-Template/Pass/Nested-Outputs-3-Levels/azureDeploy.json new file mode 100644 index 00000000..4ff94a8d --- /dev/null +++ b/unit-tests/VMSizes-Must-Match-Template/Pass/Nested-Outputs-3-Levels/azureDeploy.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "parameters": { + "clusters": { + "type": "object" + } + }, + "resources": [] +} diff --git a/unit-tests/VMSizes-Must-Match-Template/Pass/Nested-Outputs-3-Levels/createUIDefinition.json b/unit-tests/VMSizes-Must-Match-Template/Pass/Nested-Outputs-3-Levels/createUIDefinition.json new file mode 100644 index 00000000..b1fc5687 --- /dev/null +++ b/unit-tests/VMSizes-Must-Match-Template/Pass/Nested-Outputs-3-Levels/createUIDefinition.json @@ -0,0 +1,51 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/0.1.2-preview/CreateUIDefinition.MultiVm.json#", + "handler": "Microsoft.Azure.CreateUIDef", + "version": "0.1.2-preview", + "parameters": { + "basics": [], + "steps": [ + { + "label": "Scheduler", + "name": "scheduler", + "bladeTitle": "Scheduler", + "bladeSubtitle": "Configure Scheduler", + "subLabel": { + "preValidation": "Configure Scheduler", + "postValidation": "Done" + }, + "elements": [ + { + "label": "Scheduler Section", + "name": "schedulerSection", + "type": "Microsoft.Common.Section", + "elements": [ + { + "label": "VM Size", + "name": "vmsize", + "toolTip": "Scheduler VM size", + "type": "Microsoft.Compute.SizeSelector", + "osPlatform": "Linux", + "count": 1, + "recommendedSizes": [ + "Standard_B1s", + "Standard_B1ms" + ] + } + ] + } + ] + } + ], + "outputs": { + "location": "[location()]", + "clusters": { + "slurm": { + "schedulerNode": { + "sku": "[steps('scheduler').schedulerSection.vmsize]" + } + } + } + } + } +} diff --git a/unit-tests/VMSizes-Must-Match-Template/Pass/User-Scenario/azureDeploy.json b/unit-tests/VMSizes-Must-Match-Template/Pass/User-Scenario/azureDeploy.json new file mode 100644 index 00000000..4ff94a8d --- /dev/null +++ b/unit-tests/VMSizes-Must-Match-Template/Pass/User-Scenario/azureDeploy.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "parameters": { + "clusters": { + "type": "object" + } + }, + "resources": [] +} diff --git a/unit-tests/VMSizes-Must-Match-Template/Pass/User-Scenario/createUIDefinition.json b/unit-tests/VMSizes-Must-Match-Template/Pass/User-Scenario/createUIDefinition.json new file mode 100644 index 00000000..cae68439 --- /dev/null +++ b/unit-tests/VMSizes-Must-Match-Template/Pass/User-Scenario/createUIDefinition.json @@ -0,0 +1,121 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/0.1.2-preview/CreateUIDefinition.MultiVm.json#", + "handler": "Microsoft.Azure.CreateUIDef", + "version": "0.1.2-preview", + "parameters": { + "basics": [], + "steps": [ + { + "label": "Scheduler", + "name": "scheduler", + "bladeTitle": "Scheduler Configuration", + "elements": [ + { + "label": "Scheduler Section", + "name": "schedulerSection", + "type": "Microsoft.Common.Section", + "elements": [ + { + "label": "Scheduler VM Size", + "name": "vmsize", + "type": "Microsoft.Compute.SizeSelector", + "osPlatform": "Linux", + "count": 1, + "recommendedSizes": ["Standard_D2s_v3"] + } + ] + }, + { + "label": "Login Nodes Section", + "name": "loginNodesSection", + "type": "Microsoft.Common.Section", + "elements": [ + { + "label": "Login Node VM Size", + "name": "vmsize", + "type": "Microsoft.Compute.SizeSelector", + "osPlatform": "Linux", + "count": 1, + "recommendedSizes": ["Standard_D2s_v3"] + } + ] + } + ] + }, + { + "label": "Slurm Settings", + "name": "slurmSettings", + "bladeTitle": "Slurm Configuration", + "elements": [ + { + "label": "HTC Section", + "name": "HTCSection", + "type": "Microsoft.Common.Section", + "elements": [ + { + "label": "HTC VM Size", + "name": "vmsize", + "type": "Microsoft.Compute.SizeSelector", + "osPlatform": "Linux", + "count": 1, + "recommendedSizes": ["Standard_F2s_v2"] + } + ] + }, + { + "label": "HPC Section", + "name": "HPCSection", + "type": "Microsoft.Common.Section", + "elements": [ + { + "label": "HPC VM Size", + "name": "vmsize", + "type": "Microsoft.Compute.SizeSelector", + "osPlatform": "Linux", + "count": 1, + "recommendedSizes": ["Standard_HC44rs"] + } + ] + }, + { + "label": "GPU Section", + "name": "GPUSection", + "type": "Microsoft.Common.Section", + "elements": [ + { + "label": "GPU VM Size", + "name": "vmsize", + "type": "Microsoft.Compute.SizeSelector", + "osPlatform": "Linux", + "count": 1, + "recommendedSizes": ["Standard_NC6"] + } + ] + } + ] + } + ], + "outputs": { + "location": "[location()]", + "clusters": { + "slurm": { + "schedulerNode": { + "sku": "[steps('scheduler').schedulerSection.vmsize]" + }, + "loginNodes": { + "sku": "[steps('scheduler').loginNodesSection.vmsize]" + }, + "htc": { + "sku": "[steps('slurmSettings').HTCSection.vmsize]" + }, + "hpc": { + "sku": "[steps('slurmSettings').HPCSection.vmsize]" + }, + "gpu": { + "sku": "[steps('slurmSettings').GPUSection.vmsize]" + } + } + } + } + } +}