From 19b315db5935094db653b321393091bc89aab08f Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Thu, 30 May 2019 20:48:37 +0100 Subject: [PATCH 1/7] Add test that should fail on Linux first (TDD) --- Tests/Engine/InvokeScriptAnalyzer.tests.ps1 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Tests/Engine/InvokeScriptAnalyzer.tests.ps1 b/Tests/Engine/InvokeScriptAnalyzer.tests.ps1 index 158af4603..3cc9351af 100644 --- a/Tests/Engine/InvokeScriptAnalyzer.tests.ps1 +++ b/Tests/Engine/InvokeScriptAnalyzer.tests.ps1 @@ -72,6 +72,10 @@ Describe "Test available parameters" { It "is a switch parameter" { $params["SaveDscDependency"].ParameterType.FullName | Should -Be "System.Management.Automation.SwitchParameter" } + + It 'does not throw when being applied against a dummy script with no DSC code' { + Invoke-ScriptAnalyzer -ScriptDefinition 'foo' -SaveDscDependency + } } } From c34ff8f23b4d9c8cee4e4ac7c600517649de4973 Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Thu, 30 May 2019 21:10:42 +0100 Subject: [PATCH 2/7] Fix TDD test and make code more x-plat compliant to fix some ModuleDependency tests that are currently disabled on Linux --- Engine/Generic/ModuleDependencyHandler.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Engine/Generic/ModuleDependencyHandler.cs b/Engine/Generic/ModuleDependencyHandler.cs index 6023cd82c..347b9a9a1 100644 --- a/Engine/Generic/ModuleDependencyHandler.cs +++ b/Engine/Generic/ModuleDependencyHandler.cs @@ -4,12 +4,12 @@ #if !PSV3 using System; using System.Collections.Generic; -using System.Collections.ObjectModel; using System.IO; using System.Linq; using System.Management.Automation; using System.Management.Automation.Language; using System.Management.Automation.Runspaces; +using System.Runtime.InteropServices; namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic { @@ -75,7 +75,7 @@ private set #if CORECLR localAppdataPath = string.IsNullOrWhiteSpace(value) - ? Environment.GetEnvironmentVariable("LOCALAPPDATA") + ? Environment.GetEnvironmentVariable(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "LOCALAPPDATA" : "HOME") //Environment.GetEnvironmentVariable("LOCALAPPDATA") : value; #else localAppdataPath @@ -215,7 +215,7 @@ private string GetTempModulePath(string symLinkPath) private void SetupPSModulePath() { oldPSModulePath = Environment.GetEnvironmentVariable("PSModulePath"); - curPSModulePath = oldPSModulePath + ";" + tempModulePath; + curPSModulePath = oldPSModulePath + Path.PathSeparator + tempModulePath; #if CORECLR Environment.SetEnvironmentVariable("PSModulePath", curPSModulePath); #else From 2758de251b582eecab9244e92d2ede1273462d5b Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Thu, 30 May 2019 21:22:32 +0100 Subject: [PATCH 3/7] Enable ModuleDependencyHandler.tests.ps1 Pester tests on Linux (I expect up to 7 test failures here) whilst also making the tests a bit x-plat compliant (TDD) --- Tests/Engine/ModuleDependencyHandler.tests.ps1 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Tests/Engine/ModuleDependencyHandler.tests.ps1 b/Tests/Engine/ModuleDependencyHandler.tests.ps1 index 00de8a9ad..7a46efac5 100644 --- a/Tests/Engine/ModuleDependencyHandler.tests.ps1 +++ b/Tests/Engine/ModuleDependencyHandler.tests.ps1 @@ -3,7 +3,7 @@ $directory = Split-Path -Parent $MyInvocation.MyCommand.Path Describe "Resolve DSC Resource Dependency" { BeforeAll { $skipTest = $false - if ($IsLinux -or $IsMacOS -or $testingLibararyUsage -or ($PSversionTable.PSVersion -lt [Version]'5.0.0')) + if ($IsMacOS -or $testingLibararyUsage -or ($PSversionTable.PSVersion -lt [Version]'5.0.0')) { $skipTest = $true return @@ -46,6 +46,9 @@ Describe "Resolve DSC Resource Dependency" { $depHandler.TempPath | Should -Be $expectedPath $expectedLocalAppDataPath = $env:LOCALAPPDATA + if ($IsLinux -or $IsMacOS) { + $expectedLocalAppDataPath = $env:HOME + } $depHandler.LocalAppDataPath | Should -Be $expectedLocalAppDataPath $expectedModuleRepository = "PSGallery" From 9a2f49081d4e4ee9e4798fb81252a1cd1152d420 Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Fri, 31 May 2019 08:21:42 +0100 Subject: [PATCH 4/7] make some tests runnable in ModuleDependencyHandler.tests.ps1 and check for DSC installation --- .../Engine/ModuleDependencyHandler.tests.ps1 | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/Tests/Engine/ModuleDependencyHandler.tests.ps1 b/Tests/Engine/ModuleDependencyHandler.tests.ps1 index 7a46efac5..ad1420082 100644 --- a/Tests/Engine/ModuleDependencyHandler.tests.ps1 +++ b/Tests/Engine/ModuleDependencyHandler.tests.ps1 @@ -3,11 +3,21 @@ $directory = Split-Path -Parent $MyInvocation.MyCommand.Path Describe "Resolve DSC Resource Dependency" { BeforeAll { $skipTest = $false + $skipUnitTest = $false # Test that do not require DSC to be installed if ($IsMacOS -or $testingLibararyUsage -or ($PSversionTable.PSVersion -lt [Version]'5.0.0')) { $skipTest = $true + # $skipUnitTest = $true return } + if ($IsLinux) + { + $dscIsInstalled = Test-Path /etc/opt/omi/conf/dsc/configuration + if (-not $dscIsInstalled) + { + $skipTest = $true + } + } $SavedPSModulePath = $env:PSModulePath $violationFileName = 'MissingDSCResource.ps1' $violationFilePath = Join-Path $directory $violationFileName @@ -32,12 +42,12 @@ Describe "Resolve DSC Resource Dependency" { Context "Module handler class" { BeforeAll { - if ( $skipTest ) { return } + if ( $skipTest -and $skipUnitTest ) { return } $moduleHandlerType = [Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.ModuleDependencyHandler] $oldEnvVars = Get-Item Env:\* | Sort-Object -Property Key $oldPSModulePath = $env:PSModulePath } - It "Sets defaults correctly" -skip:$skipTest { + It "Sets defaults correctly" -skip:$skipUnitTest { $rsp = [runspacefactory]::CreateRunspace() $rsp.Open() $depHandler = $moduleHandlerType::new($rsp) @@ -64,15 +74,15 @@ Describe "Resolve DSC Resource Dependency" { $rsp.Dispose() } - It "Keeps the environment variables unchanged" -skip:$skipTest { + It "Keeps the environment variables unchanged" -skip:$skipUnitTest { Test-EnvironmentVariables($oldEnvVars) } - It "Throws if runspace is null" -skip:$skipTest { + It "Throws if runspace is null" -skip:$skipUnitTest { {$moduleHandlerType::new($null)} | Should -Throw } - It "Throws if runspace is not opened" -skip:$skipTest { + It "Throws if runspace is not opened" -skip:$skipUnitTest { $rsp = [runspacefactory]::CreateRunspace() {$moduleHandlerType::new($rsp)} | Should -Throw $rsp.Dispose() From 908cd3a898b0835c614b7ee31e689ffaa58f5a34 Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Fri, 31 May 2019 08:33:19 +0100 Subject: [PATCH 5/7] cleanup and do not run test in WMF4 --- .../Engine/ModuleDependencyHandler.tests.ps1 | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/Tests/Engine/ModuleDependencyHandler.tests.ps1 b/Tests/Engine/ModuleDependencyHandler.tests.ps1 index ad1420082..544d2a928 100644 --- a/Tests/Engine/ModuleDependencyHandler.tests.ps1 +++ b/Tests/Engine/ModuleDependencyHandler.tests.ps1 @@ -2,15 +2,13 @@ $directory = Split-Path -Parent $MyInvocation.MyCommand.Path Describe "Resolve DSC Resource Dependency" { BeforeAll { - $skipTest = $false - $skipUnitTest = $false # Test that do not require DSC to be installed - if ($IsMacOS -or $testingLibararyUsage -or ($PSversionTable.PSVersion -lt [Version]'5.0.0')) + $skipTest = $false # Test that require DSC to be installed + if ($testingLibararyUsage -or ($PSversionTable.PSVersion -lt [Version]'5.0.0')) { $skipTest = $true - # $skipUnitTest = $true return } - if ($IsLinux) + if ($IsLinux -or $IsMacOS) { $dscIsInstalled = Test-Path /etc/opt/omi/conf/dsc/configuration if (-not $dscIsInstalled) @@ -18,6 +16,7 @@ Describe "Resolve DSC Resource Dependency" { $skipTest = $true } } + $SavedPSModulePath = $env:PSModulePath $violationFileName = 'MissingDSCResource.ps1' $violationFilePath = Join-Path $directory $violationFileName @@ -42,12 +41,12 @@ Describe "Resolve DSC Resource Dependency" { Context "Module handler class" { BeforeAll { - if ( $skipTest -and $skipUnitTest ) { return } + if ( $skipTest ) { return } $moduleHandlerType = [Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.ModuleDependencyHandler] $oldEnvVars = Get-Item Env:\* | Sort-Object -Property Key $oldPSModulePath = $env:PSModulePath } - It "Sets defaults correctly" -skip:$skipUnitTest { + It "Sets defaults correctly" -Skip:($PSversionTable.PSVersion -lt [Version]'5.0.0') { $rsp = [runspacefactory]::CreateRunspace() $rsp.Open() $depHandler = $moduleHandlerType::new($rsp) @@ -74,15 +73,15 @@ Describe "Resolve DSC Resource Dependency" { $rsp.Dispose() } - It "Keeps the environment variables unchanged" -skip:$skipUnitTest { + It "Keeps the environment variables unchanged" -Skip:($PSversionTable.PSVersion -lt [Version]'5.0.0') { Test-EnvironmentVariables($oldEnvVars) } - It "Throws if runspace is null" -skip:$skipUnitTest { + It "Throws if runspace is null" -Skip:($PSversionTable.PSVersion -lt [Version]'5.0.0') { {$moduleHandlerType::new($null)} | Should -Throw } - It "Throws if runspace is not opened" -skip:$skipUnitTest { + It "Throws if runspace is not opened" -Skip:($PSversionTable.PSVersion -lt [Version]'5.0.0') { $rsp = [runspacefactory]::CreateRunspace() {$moduleHandlerType::new($rsp)} | Should -Throw $rsp.Dispose() From 1261df203574bea3adfc14f9d439939c56c52444 Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Fri, 31 May 2019 08:54:05 +0100 Subject: [PATCH 6/7] fix tests on Linux --- Tests/Engine/ModuleDependencyHandler.tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/Engine/ModuleDependencyHandler.tests.ps1 b/Tests/Engine/ModuleDependencyHandler.tests.ps1 index 544d2a928..d7df093c0 100644 --- a/Tests/Engine/ModuleDependencyHandler.tests.ps1 +++ b/Tests/Engine/ModuleDependencyHandler.tests.ps1 @@ -41,7 +41,7 @@ Describe "Resolve DSC Resource Dependency" { Context "Module handler class" { BeforeAll { - if ( $skipTest ) { return } + if ($PSversionTable.PSVersion -lt [Version]'5.0.0') { return } $moduleHandlerType = [Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.ModuleDependencyHandler] $oldEnvVars = Get-Item Env:\* | Sort-Object -Property Key $oldPSModulePath = $env:PSModulePath From 3c56ee142d7a6d6e37a7212dd1f458aa77512180 Mon Sep 17 00:00:00 2001 From: Christoph Bergmeister Date: Wed, 5 Jun 2019 19:25:02 +0100 Subject: [PATCH 7/7] Adapt tests so that they pass the first time when being run the first time. There is more cleanup needed in this class in general but this is the minimum viable change --- .../Engine/ModuleDependencyHandler.tests.ps1 | 37 ++++++++++++------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/Tests/Engine/ModuleDependencyHandler.tests.ps1 b/Tests/Engine/ModuleDependencyHandler.tests.ps1 index ff78ff760..a392150f5 100644 --- a/Tests/Engine/ModuleDependencyHandler.tests.ps1 +++ b/Tests/Engine/ModuleDependencyHandler.tests.ps1 @@ -33,6 +33,11 @@ Describe "Resolve DSC Resource Dependency" { $newEnv[$index].Value | Should -Be $oldEnv[$index].Value } } + + Function Get-LocalAppDataFolder + { + if ($IsLinux -or $IsMacOS) { $env:HOME } else { $env:LOCALAPPDATA } + } } AfterAll { if ( $skipTest ) { return } @@ -58,11 +63,7 @@ Describe "Resolve DSC Resource Dependency" { $expectedPath = [System.IO.Path]::GetTempPath() $depHandler.TempPath | Should -Be $expectedPath - $expectedLocalAppDataPath = $env:LOCALAPPDATA - if ($IsLinux -or $IsMacOS) { - $expectedLocalAppDataPath = $env:HOME - } - $depHandler.LocalAppDataPath | Should -Be $expectedLocalAppDataPath + $depHandler.LocalAppDataPath | Should -Be (Get-LocalAppDataFolder) $expectedModuleRepository = "PSGallery" $depHandler.ModuleRepository | Should -Be $expectedModuleRepository @@ -188,16 +189,19 @@ Describe "Resolve DSC Resource Dependency" { $modulePath = "$(Split-Path $directory)\Rules\DSCResourceModule\DSCResources\$moduleName" # Save the current environment variables - $oldLocalAppDataPath = $env:LOCALAPPDATA + $oldLocalAppDataPath = Get-LocalAppDataFolder $oldTempPath = $env:TEMP $savedPSModulePath = $env:PSModulePath # set the environment variables - $tempPath = Join-Path $oldTempPath ([guid]::NewGUID()).ToString() + $tempPath = Join-Path ([System.IO.Path]::GetTempPath()) ([guid]::NewGUID()).ToString() $newLocalAppDataPath = Join-Path $tempPath "LocalAppData" $newTempPath = Join-Path $tempPath "Temp" - $env:LOCALAPPDATA = $newLocalAppDataPath - $env:TEMP = $newTempPath + if (-not ($IsLinux -or $IsMacOS)) + { + $env:LOCALAPPDATA = $newLocalAppDataPath + $env:TEMP = $newTempPath + } # create the temporary directories New-Item -Type Directory -Path $newLocalAppDataPath -force @@ -224,7 +228,6 @@ Describe "Resolve DSC Resource Dependency" { } It "has a single parse error" -skip:$skipTest { - # invoke script analyzer $dr = Invoke-ScriptAnalyzer -Path $violationFilePath -ErrorVariable analyzerErrors -ErrorAction SilentlyContinue $analyzerErrors.Count | Should -Be 0 $dr | @@ -233,14 +236,22 @@ Describe "Resolve DSC Resource Dependency" { } It "Keeps PSModulePath unchanged before and after invocation" -skip:$skipTest { - $dr = Invoke-ScriptAnalyzer -Path $violationFilePath -ErrorVariable parseErrors -ErrorAction SilentlyContinue + Invoke-ScriptAnalyzer -Path $violationFilePath -ErrorVariable parseErrors -ErrorAction SilentlyContinue $env:PSModulePath | Should -Be $savedPSModulePath } if (!$skipTest) { - $env:LOCALAPPDATA = $oldLocalAppDataPath - $env:TEMP = $oldTempPath + if ($IsLinux -or $IsMacOS) + { + $env:HOME = $oldLocalAppDataPath + # On Linux [System.IO.Path]::GetTempPath() does not use the TEMP env variable unlike on Windows + } + else + { + $env:LOCALAPPDATA = $oldLocalAppDataPath + $env:TEMP = $oldTempPath + } Remove-Item -Recurse -Path $tempModulePath -Force Remove-Item -Recurse -Path $tempPath -Force }