using namespace System.Diagnostics using namespace System.Collections using namespace System.Collections.Generic using namespace System.IO.Compression param ( [switch]$NoRun ) function Assert( [bool]$condition, [string]$message = "Assertion failed" ){ if( -not $condition ) { Get-PSCallStack | ForEach-Object { Write-Host $_.FunctionName $_.Location $_.Arguments } throw $message } } function CreateExampleConfigs { Write-Warning "Creating test files ExampleConfigs\Web.config and Web.UnitTest.config..." Write-Host "Creating test files ExampleConfigs\Web.config and Web.UnitTest.config..." mkdir ExampleConfigs -ErrorAction SilentlyContinue @' <?xml version="1.0" encoding="utf-8"?> <configuration> <someSetting name="someSetting" from="Web.config" to="OriginalValueHere" subject="Test variable substitution" /> <appSettings> <add key="TestKey" value="TestValue" /> </appSettings> </configuration> '@ | Out-File .\ExampleConfigs\Web.config @' <?xml version="1.0" encoding="utf-8"?> <configuration> <someSetting name="someSetting" from="Web.UnitTest.config" to="$(SomeSetting.EmailTo)" subject="Test variable substitution" /> <appSettings> <add key="TestKey" value="TestValue" /> </appSettings> </configuration> '@ | Out-File .\ExampleConfigs\Web.UnitTest.config } function Setup { $env:SomeSetting_EmailTo = "ParametersEmailTo@replaced.com" $env:RELEASE_ENVIRONMENTNAME = "UnitTest" if (-not (Test-Path ExampleConfigs\Web.config) -or -not (Test-Path ExampleConfigs\Web.UnitTest.config)) { CreateExampleConfigs } Remove-Item TempExpanded -Recurse -ErrorAction SilentlyContinue $primaryArtifactSourceAlias = "TestArtifactSourceAlias" function Release.PrimaryArtifactSourceAlias { $primaryArtifactSourceAlias } if (Test-Path $primaryArtifactSourceAlias\Drop.bak.zip) { Remove-Item $primaryArtifactSourceAlias\Drop.zip -ErrorAction SilentlyContinue Rename-Item $primaryArtifactSourceAlias\Drop.bak.zip Drop.zip } else { mkdir $primaryArtifactSourceAlias -ErrorAction SilentlyContinue Compress-Archive ExampleConfigs $primaryArtifactSourceAlias\drop.zip -Force } } function TestTextTransform { $content = " to=""`$(SomeSetting.EmailTo)"" subject=""ELMAH [TEST]""" $replacements = @( @{"SomeSetting_EmailTo"="Replaced"}.GetEnumerator() ) $expected = " to=""Replaced"" subject=""ELMAH [TEST]""" $actual = TextTransform $content $replacements "[TestTextTransform]" Assert ($actual -eq $expected) "Failed matching case Replace: Expected: $expected, Actual: $actual" "TestTextTransform:With Exact Case Match:Passed" $replacementsUpperCase = @( @{"SomeSetting_EmailTo"="Replaced"}.GetEnumerator() ) $actual2 = TextTransform $content $replacementsUpperCase "[TestTextTransform Case Insensitive]" Assert ($actual2 -eq $expected) "Failed Case Insensitive Replace: Expected: $expected, Actual: $actual2" "TestTextTransform:Case Insensitive:Passed" } function TestTransformFile { #Arrange mkdir ExampleConfigsCopy -ErrorAction SilentlyContinue try{ #Arrange Copy-Item ExampleConfigs\Web.config , .\ExampleConfigs\Web.UnitTest.config ExampleConfigsCopy $files= Get-ChildItem ExampleConfigsCopy\* $original0 = Get-Content ExampleConfigsCopy\Web.UnitTest.config -Raw # Act TransformFiles $files # Assert $actual0 = Get-Content ExampleConfigsCopy\Web.UnitTest.config -Raw Assert ($original0 -ne $actual0) "Original: $original0, Actual: $actual0" Assert ($actual0 -match $env:SomeSetting_EmailTo) "$files should contain `$env:SomeSetting_EmailTo = $env:SomeSetting_EmailTo but doesn't" $appSettingsNode= (Select-Xml -Path $files[0] -XPath "/configuration/appSettings"). Node Assert ($null -ne $appSettingsNode) "Failed to parse appSettings note in $files[0] after transform, got null for /configuration/appSettings" "TestTranformFiles: Passed" } finally { Remove-Item .\ExampleConfigsCopy -Recurse -ErrorAction SilentlyContinue } } function TestExpandAndRecreateArtifactZipFile { $artifactZipPath = "$primaryArtifactSourceAlias\drop.zip" $backupfileName = $artifactZipPath -replace ".zip$",".bak.zip" ExpandArtifactZipToTempExpandedFolder $artifactZipPath Push-Location TempExpanded try { BackupAndReCreateArtifactZipFile $zipfile } finally { Pop-Location } Assert (Test-Path $artifactZipPath) "Expected replacement zip file $artifactZipPath not found" Assert (Test-Path $backupfileName) "Expected Backup file $backupfileName not found" "TestExpandAndRecreateArtifactZipFile:Zip file and bak.zip file exist:Passed" "TestExpandAndRecreateArtifactZipFile:Compare: $artifactZipPath, $backupfileName" # Resolve-Path $artifactZipPath # Resolve-Path $backupfileName # Get-Location $zip1 = [ZipFile]::OpenRead( (Resolve-Path $artifactZipPath) ) $zip2 = [ZipFile]::OpenRead( (Resolve-Path $backupfileName) ) $toTuple = [Func[ZipArchiveEntry, ZipArchiveEntry, [Tuple[ZipArchiveEntry,ZipArchiveEntry]]]]{ param ($entry1, $entry2) return [tuple]::Create( $entry1, $entry2 ) } $dirEntries= [System.Linq.Enumerable]::Zip($zip1.Entries, $zip2.Entries, $toTuple ) $zip1.Dispose() $zip2.Dispose() $dirEntries | ForEach-Object { $entry1 = [ZipArchiveEntry]$_.Item1 $entry2 = [ZipArchiveEntry]$_.Item2 Assert ($entry1.FullName -eq $entry2.FullName) "Files in $artifactZipPath and $primaryArtifactSourceAlias\drop.bak.zip do not match" Assert ($entry1.Length -eq $entry2.Length) "Files in $artifactZipPath and $primaryArtifactSourceAlias\drop.bak.zip do not match" } "TestExpandAndRecreateArtifactZipFile:Zip file and bak.zip file have same directory entries:Passed" } function TestGetConfigFilesToEdit { "Expected:" Get-ChildItem TempExpanded -Recurse -Include "Web.config","Web.$env:RELEASE_ENVIRONMENTNAME.config" $actual = Get-ConfigFilesInExpandedFolder Assert ($null -ne $actual) "Expected `$actual to be set, but found null" Assert ($actual.Count -eq 2) "Expected to transform exactly 2 config files, but found:`n----------`n$($actual)`n---------" $configFilesToTransformIncludesWebConfig = $actual -match "TempExpanded(\\|/).+(\\|/)Web.config$" Assert $configFilesToTransformIncludesWebConfig.Count "Expected to transform web.config file but found:`n----------`n$($actual)`n---------" $configFilesToTransformIncludesWebTestConfig = $actual -match "TempExpanded(\\|/).+(\\|/)Web.$env:RELEASE_ENVIRONMENTNAME.config$" Assert $configFilesToTransformIncludesWebTestConfig.Count "Expected to transform web.$env:RELEASE_ENVIRONMENTNAME.config file but found:`n----------`n$($actual)`n---------" "TestGetConfigFilesToEdit: Passed" } # ----------------------------------------------------- # if($NoRun){ return } # ----------------------------------------------------- $DebugPreferenceWas = $DebugPreference $DebugPreference = "Continue" try{ . Setup $noRun=$true ; . .\DevAzureReleaseVariableTransform.ps1 ShowDebuggingInformation TestTextTransform TestTransformFile TestExpandAndRecreateArtifactZipFile TestGetConfigFilesToEdit } finally { $DebugPreference = $DebugPreferenceWas }