From feae8e4b2d8fe94a9aa1bc6ea0b6eba0c142d163 Mon Sep 17 00:00:00 2001 From: James Truher Date: Tue, 23 Aug 2016 12:28:34 -0700 Subject: [PATCH 01/14] add read-host tests --- test/powershell/Common/TestHostCS.psm1 | 16 ++++++- .../Read-Host.Tests.ps1 | 42 +++++++++++++++++++ 2 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 test/powershell/Modules/Microsoft.PowerShell.Utility/Read-Host.Tests.ps1 diff --git a/test/powershell/Common/TestHostCS.psm1 b/test/powershell/Common/TestHostCS.psm1 index 081c48254c..c056fd7a9d 100755 --- a/test/powershell/Common/TestHostCS.psm1 +++ b/test/powershell/Common/TestHostCS.psm1 @@ -86,7 +86,6 @@ namespace TestHost public class Streams { public ArrayList ConsoleOutput = new ArrayList(); - public ArrayList Output = new ArrayList(); public ArrayList Input = new ArrayList(); public ArrayList Error = new ArrayList(); public ArrayList Verbose = new ArrayList(); @@ -95,6 +94,17 @@ namespace TestHost public ArrayList Information = new ArrayList(); public ArrayList Progress = new ArrayList(); public ArrayList Prompt = new ArrayList(); + public void Clear() { + ConsoleOutput.Clear() + Input.Clear() + Error.Clear() + Verbose.Clear() + Debug.Clear() + Warning.Clear() + Information.Clear() + Progress.Clear() + Prompt.Clear() + } } public class TestPSHostUserInterface : PSHostUserInterface { @@ -112,7 +122,9 @@ namespace TestHost public override Dictionary Prompt(string caption, string message, Collection descriptions) { - Streams.Prompt.Add(caption + ":" + message); + string s = String.Empty; + if ( descriptions[0] != null ) { s = descriptions[0].Name; } + Streams.Prompt.Add(caption + ":" + message + ":" + s); Dictionary d = new Dictionary(); d.Add(descriptions[0].ToString(), new PSObject(promptResponse)); return d; diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Read-Host.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Read-Host.Tests.ps1 new file mode 100644 index 0000000000..bf9e624efd --- /dev/null +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Read-Host.Tests.ps1 @@ -0,0 +1,42 @@ +if ( ! (get-module -ea silentlycontinue TestHostCS )) +{ + $root = git rev-parse --show-toplevel + $pestertestroot = join-path $root test/powershell + $common = join-path $pestertestroot Common + $hostmodule = join-path $common TestHostCS.psm1 + import-module $hostmodule +} +Describe "Read-Host Test" -tag "CI" { + BeforeAll { + $th = New-TestHost + $rs = [runspacefactory]::Createrunspace($th) + $rs.open() + $ps = [powershell]::Create() + $ps.Runspace = $rs + $ps.Commands.Clear() + } + AfterEach { + $ps.Commands.Clear() + } + AfterAll { + $rs.Close() + $rs.Dispose() + $ps.Dispose() + } + It "Read-Host returns expected string" { + $result = $ps.AddCommand("Read-Host").Invoke() + $result | Should Be $th.UI.ReadLineData + } + It "Read-Host sets the prompt correctly" { + $result = $ps.AddScript("Read-Host -prompt myprompt").Invoke() + $prompt = $th.ui.streams.prompt[0] + $prompt | should Not BeNullOrEmpty + $prompt.split(":")[-1] | should be myprompt + } + It "Read-Host returns a secure string when using -AsSecureString parameter" { + $result = $ps.AddScript("Read-Host -AsSecureString").Invoke() | select-object -first 1 + $result.GetType().Name | should be "SecureString" + [pscredential]::New("foo",$result).GetNEtworkCredential().Password | should BeExactly TEST + + } +} From e639240ecb476c7d4f674677401c7edb0cf5b5d6 Mon Sep 17 00:00:00 2001 From: James Truher Date: Tue, 23 Aug 2016 17:08:15 -0700 Subject: [PATCH 02/14] Add set-Date test this one is a bit tricky, unless you're elevated you can't set the date however, if you are not elevated you should get an error. This file does one or the other based on whether you're elevated --- .../Set-Date.Tests.ps1 | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 test/powershell/Modules/Microsoft.PowerShell.Utility/Set-Date.Tests.ps1 diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Set-Date.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Set-Date.Tests.ps1 new file mode 100644 index 0000000000..ec58428bf5 --- /dev/null +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Set-Date.Tests.ps1 @@ -0,0 +1,26 @@ +# first check to see which platform we're on. If we're on windows we should be able +# to be sure whether we're running elevated. If we're on Linux, we can use whoami to +# determine whether we're elevated +Describe "Set-Date" { + BeforeAll { + if ( $IsWindows ) { + $identity = [System.Security.Principal.WindowsIdentity]::GetCurrent() + $windowsPrincipal = new-object 'Security.Principal.WindowsPrincipal' $identity + if ($windowsPrincipal.IsInRole("Administrators") -eq 1) { $IsElevated = $true } else { $IsElevated = $false } + } + else { + if ( (whoami) -match "root" ) { + $IsElevated = $true + } + else { + $IsElevated = $false + } + } + } + It "Set-Date should be able to set the date in an elevated context" -Skip:(! $IsElevated) { + { get-date | set-date } | Should not throw + } + It "Set-Date should produce an error in a non-elevated context" -Skip:($IsElevated) { + { get-date |set-date} | should throw + } +} From c610ea794125f63ad4a3a8e8e38e85aea47dadaf Mon Sep 17 00:00:00 2001 From: James Truher Date: Wed, 24 Aug 2016 10:45:50 -0700 Subject: [PATCH 03/14] Add Set-Date test --- .../Modules/Microsoft.PowerShell.Utility/Set-Date.Tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Set-Date.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Set-Date.Tests.ps1 index ec58428bf5..47eccb785a 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/Set-Date.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Set-Date.Tests.ps1 @@ -1,7 +1,7 @@ # first check to see which platform we're on. If we're on windows we should be able # to be sure whether we're running elevated. If we're on Linux, we can use whoami to # determine whether we're elevated -Describe "Set-Date" { +Describe "Set-Date" -Tag "CI" { BeforeAll { if ( $IsWindows ) { $identity = [System.Security.Principal.WindowsIdentity]::GetCurrent() From 01c495b5e66969ea00bf2e38ef038b463260f590 Mon Sep 17 00:00:00 2001 From: James Truher Date: Wed, 24 Aug 2016 11:53:48 -0700 Subject: [PATCH 04/14] Change Import-PowerShellDataFile tag to CI and simplify tests --- .../PowerShellData.tests.ps1 | 46 ++++++------------- 1 file changed, 13 insertions(+), 33 deletions(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/PowerShellData.tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/PowerShellData.tests.ps1 index 5bdb795377..e2ececef47 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/PowerShellData.tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/PowerShellData.tests.ps1 @@ -1,83 +1,63 @@ -Describe "Tests for the Import-PowerShellDataFile cmdlet" -Tags "Feature" { +Describe "Tests for the Import-PowerShellDataFile cmdlet" -Tags "CI" { It "Validates error on a missing path" { - $foundError = "" try { Import-PowerShellDataFile -Path /SomeMissingDirectory -ErrorAction Stop + Throw "Execution OK" } catch { - $foundError = $_.FullyQualifiedErrorId + $_.FullyQualifiedErrorId | Should be "PathNotFound,Microsoft.PowerShell.Commands.ResolvePathCommand" } - - $foundError | Should be "PathNotFound,Microsoft.PowerShell.Commands.ResolvePathCommand" } It "Validates error on a directory" { - $foundError = "" try { Import-PowerShellDataFile ${TESTDRIVE} -ErrorAction Stop + Throw "Execution OK" } catch { - $foundError = $_.FullyQualifiedErrorId + $_.FullyQualifiedErrorId | Should be "CouldNotParseAsPowerShellDataFile,Import-PowerShellDataFile" } - $foundError | Should be "CouldNotParseAsPowerShellDataFile,Import-PowerShellDataFile" } It "Generates a good error on an insecure file" { - $path = New-TemporaryFile - Set-Content $path '@{ Foo = Get-Process }' - - $foundError = "" + $path = Setup -f insecure.psd1 -content '@{ Foo = Get-Process }' -pass try { Import-PowerShellDataFile $path -ErrorAction Stop + Throw "Execution OK" } catch { - $foundError = $_.FullyQualifiedErrorId + $_.FullyQualifiedErrorId | Should be "InvalidOperationException,Import-PowerShellDataFile" } - finally - { - Remove-Item $path - } - - $foundError | Should be "InvalidOperationException,Import-PowerShellDataFile" } It "Generates a good error on a file that isn't a PowerShell Data File (missing the hashtable root)" { - $path = New-TemporaryFile - Set-Content $path '"Hello World"' - - $foundError = "" + $path = setup -f NotAPSDataFile -content '"Hello World"' -Pass try { - Import-PowerShellDataFile $path -ErrorAction Stop + Import-PowerShellDataFile $path -ErrorAction Stop + Throw "Execution OK" } catch { - $foundError = $_.FullyQualifiedErrorId + $_.FullyQualifiedErrorId | Should be "CouldNotParseAsPowerShellDataFileNoHashtableRoot,Import-PowerShellDataFile" } - finally - { - Remove-Item $path - } - - $foundError | Should be "CouldNotParseAsPowerShellDataFileNoHashtableRoot,Import-PowerShellDataFile" } It "Can parse a PowerShell Data File (detailed tests are in AST.SafeGetValue tests)" { - $path = New-TemporaryFile - Set-Content $path '@{ "Hello" = "World" }' + $path = Setup -F gooddatafile -content '@{ "Hello" = "World" }' -pass $result = Import-PowerShellDataFile $path -ErrorAction Stop $result.Hello | Should be "World" From f6ae23864128aaf60d4f0bf4b385008480d700a0 Mon Sep 17 00:00:00 2001 From: James Truher Date: Wed, 24 Aug 2016 12:03:13 -0700 Subject: [PATCH 05/14] quiet the start-process tests by redirecting all output --- .../Start-Process.Tests.ps1 | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Start-Process.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Start-Process.Tests.ps1 index e00c5b6015..65d03c8308 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Start-Process.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Start-Process.Tests.ps1 @@ -14,7 +14,7 @@ Describe "Start-Process" -Tags @("CI","SLOW") { # This has been fixed on Linux, but not on OS X It "Should process arguments without error" { - $process = Start-Process ping -ArgumentList $pingParam -PassThru + $process = Start-Process ping -ArgumentList $pingParam -PassThru -RedirectStandardOutput "$TESTDRIVE/output" $process.Length | Should Be 1 $process.Id | Should BeGreaterThan 1 @@ -22,7 +22,7 @@ Describe "Start-Process" -Tags @("CI","SLOW") { } It "Should work correctly when used with full path name" { - $process = Start-Process $pingCommand -ArgumentList $pingParam -PassThru + $process = Start-Process $pingCommand -ArgumentList $pingParam -PassThru -RedirectStandardOutput "$TESTDRIVE/output" $process.Length | Should Be 1 $process.Id | Should BeGreaterThan 1 @@ -30,7 +30,7 @@ Describe "Start-Process" -Tags @("CI","SLOW") { } It "Should invoke correct path when used with FilePath argument" { - $process = Start-Process -FilePath $pingCommand -ArgumentList $pingParam -PassThru + $process = Start-Process -FilePath $pingCommand -ArgumentList $pingParam -PassThru -RedirectStandardOutput "$TESTDRIVE/output" $process.Length | Should Be 1 $process.Id | Should BeGreaterThan 1 @@ -38,11 +38,11 @@ Describe "Start-Process" -Tags @("CI","SLOW") { } It "Should wait for command completion if used with Wait argument" { - $process = Start-Process ping -ArgumentList $pingParam -Wait -PassThru + $process = Start-Process ping -ArgumentList $pingParam -Wait -PassThru -RedirectStandardOutput "$TESTDRIVE/output" } It "Should work correctly with WorkingDirectory argument" { - $process = Start-Process ping -WorkingDirectory $pingDirectory -ArgumentList $pingParam -PassThru + $process = Start-Process ping -WorkingDirectory $pingDirectory -ArgumentList $pingParam -PassThru -RedirectStandardOutput "$TESTDRIVE/output" $process.Length | Should Be 1 $process.Id | Should BeGreaterThan 1 @@ -50,7 +50,7 @@ Describe "Start-Process" -Tags @("CI","SLOW") { } It "Should should handle stderr redirection without error" { - $process = Start-Process ping -ArgumentList $pingParam -PassThru -RedirectStandardError $tempFile + $process = Start-Process ping -ArgumentList $pingParam -PassThru -RedirectStandardError $tempFile -RedirectStandardOutput "$TESTDRIVE/output" $process.Length | Should Be 1 $process.Id | Should BeGreaterThan 1 @@ -59,13 +59,13 @@ Describe "Start-Process" -Tags @("CI","SLOW") { It "Should should handle stdout redirection without error" { $process = Start-Process ping -ArgumentList $pingParam -Wait -RedirectStandardOutput $tempFile - $dirEntry = dir $tempFile + $dirEntry = get-childitem $tempFile $dirEntry.Length | Should BeGreaterThan 0 } It "Should should handle stdin redirection without error" { $process = Start-Process sort -Wait -RedirectStandardOutput $tempFile -RedirectStandardInput $assetsFile - $dirEntry = dir $tempFile + $dirEntry = get-childitem $tempFile $dirEntry.Length | Should BeGreaterThan 0 } From 763fe2bdbf91935d6296a933a001b089530bd74d Mon Sep 17 00:00:00 2001 From: James Truher Date: Wed, 24 Aug 2016 12:14:39 -0700 Subject: [PATCH 06/14] fix missing ";" in Streams.Clear --- test/powershell/Common/TestHostCS.psm1 | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/test/powershell/Common/TestHostCS.psm1 b/test/powershell/Common/TestHostCS.psm1 index c056fd7a9d..1496999c1d 100755 --- a/test/powershell/Common/TestHostCS.psm1 +++ b/test/powershell/Common/TestHostCS.psm1 @@ -95,15 +95,15 @@ namespace TestHost public ArrayList Progress = new ArrayList(); public ArrayList Prompt = new ArrayList(); public void Clear() { - ConsoleOutput.Clear() - Input.Clear() - Error.Clear() - Verbose.Clear() - Debug.Clear() - Warning.Clear() - Information.Clear() - Progress.Clear() - Prompt.Clear() + ConsoleOutput.Clear(); + Input.Clear(); + Error.Clear(); + Verbose.Clear(); + Debug.Clear(); + Warning.Clear(); + Information.Clear(); + Progress.Clear(); + Prompt.Clear(); } } public class TestPSHostUserInterface : PSHostUserInterface From 52ba25be691876f54e5a0a8d78a43bb5286b867d Mon Sep 17 00:00:00 2001 From: James Truher Date: Wed, 24 Aug 2016 12:43:18 -0700 Subject: [PATCH 07/14] Add simple Enable-PSBreakpoint and Disable-PSBreakpoint cmdlet tests --- .../EnableDisablePSBreakpoint.Tests.ps1 | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 test/powershell/Modules/Microsoft.PowerShell.Utility/EnableDisablePSBreakpoint.Tests.ps1 diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/EnableDisablePSBreakpoint.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/EnableDisablePSBreakpoint.Tests.ps1 new file mode 100644 index 0000000000..cb8e693737 --- /dev/null +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/EnableDisablePSBreakpoint.Tests.ps1 @@ -0,0 +1,21 @@ +Describe "Enable and Disable PSBreakpoints" -Tag "CI" { + BeforeAll { + $path = Setup -F testbp.ps1 -content "get-command`nget-date`nget-location" -pass + $bp = set-psbreakpoint -script $path -line 2 + disable-psbreakpoint $bp + } + AfterAll { + $bp | remove-psbreakpoint + } + It "Enable-PSBreakpoint should enable the breakpoint" { + $bp.Enabled | should be $false + Enable-PSBreakpoint $bp + $bp.Enabled | Should be $true + } + It "Disable-PSBreakpoint should disable the breakpoint" { + Enable-PSBreakpoint $bp + $bp.Enabled | Should be $true + Disable-PSBreakpoint $bp + $bp.Enabled | Should be $false + } +} From d3a177d6aee8438fd8e650bf7dd8ca4e3eab3dec Mon Sep 17 00:00:00 2001 From: James Truher Date: Wed, 24 Aug 2016 14:20:07 -0700 Subject: [PATCH 08/14] Add simple securestring conversion cmdlet tests --- .../SecureString.Tests.ps1 | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 test/powershell/Modules/Microsoft.PowerShell.Security/SecureString.Tests.ps1 diff --git a/test/powershell/Modules/Microsoft.PowerShell.Security/SecureString.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Security/SecureString.Tests.ps1 new file mode 100644 index 0000000000..ac0f16d137 --- /dev/null +++ b/test/powershell/Modules/Microsoft.PowerShell.Security/SecureString.Tests.ps1 @@ -0,0 +1,45 @@ +Describe "SecureString conversion tests" -Tags "CI" { + BeforeAll { + $string = "ABCD" + $secureString = [System.Security.SecureString]::New() + $string.ToCharArray() | foreach-object { $securestring.AppendChar($_) } + $defaultParamValues = $PSdefaultParameterValues.Clone() + $PSdefaultParameterValues = @{} + if ( ! $IsWindows ) { $PSdefaultParameterValues["it:pending"] = $true } + } + AfterAll { + $PSdefaultParameterValues = $defaultParamValues + } + + It "using null arguments to ConvertFrom-SecureString produces an exception" { + try { + ConvertFrom-SecureString -secureString $null -key $null + } + catch { + $_.FullyQualifiedErrorId | should be "ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.ConvertFromSecureStringCommand" + } + + } + + It "using a bad key produces an exception" { + try { + $badkey = [byte[]]@(1,2) + ConvertFrom-SecureString -securestring $secureString -key $badkey + throw "Execution OK" + } + catch { + $_.FullyQualifiedErrorId | should be "Argument,Microsoft.PowerShell.Commands.ConvertFromSecureStringCommand" + } + } + + It "Can convert to a secure string" { + $ss = ConvertTo-SecureString -AsPlainText -Force abcd + $ss.GetType().Name | should be "SecureString" + } + It "can convert back from a secure string" { + $secret = "abcd" + $ss1 = ConvertTo-SecureString -AsPlainText -Force $secret + $ss2 = convertfrom-securestring $ss1 | convertto-securestring + [pscredential]::New("user",$ss2).GetNetworkCredential().Password | should be $secret + } +} From 9c99bdbef92386a2ec0c5a1b013f5e6579f90c86 Mon Sep 17 00:00:00 2001 From: James Truher Date: Wed, 24 Aug 2016 15:58:05 -0700 Subject: [PATCH 09/14] Add new debugging tests which are based on existing earlier non-Pester tests --- test/powershell/Common/Test.Helpers.psm1 | 25 +++++ .../Scripting/Debugging/Debugging.Tests.ps1 | 96 +++++++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 test/powershell/Common/Test.Helpers.psm1 create mode 100644 test/powershell/Language/Scripting/Debugging/Debugging.Tests.ps1 diff --git a/test/powershell/Common/Test.Helpers.psm1 b/test/powershell/Common/Test.Helpers.psm1 new file mode 100644 index 0000000000..b168c97911 --- /dev/null +++ b/test/powershell/Common/Test.Helpers.psm1 @@ -0,0 +1,25 @@ +function Wait-CompleteExecution +{ + [CmdletBinding()] + param ( + [ScriptBlock]$sb, + [int]$TimeoutInMilliseconds = 10000, + [int]$IntervalInMilliseconds = 1000 + ) + # Get the current time + $startTime = [DateTime]::Now + + # Loop until the script block evaluates to true + while (-not ($sb.Invoke())) { + # Sleep for the specified interval + start-sleep -mil $intervalInMilliseconds + + # If the timeout period has passed, throw an exception + if (([DateTime]::Now - $startTime).TotalMilliseconds -gt $timeoutInMilliseconds) + { + return $false + } + } + return $true +} +export-modulemember -function Wait-CompleteExecution diff --git a/test/powershell/Language/Scripting/Debugging/Debugging.Tests.ps1 b/test/powershell/Language/Scripting/Debugging/Debugging.Tests.ps1 new file mode 100644 index 0000000000..402d43b578 --- /dev/null +++ b/test/powershell/Language/Scripting/Debugging/Debugging.Tests.ps1 @@ -0,0 +1,96 @@ +$script1 = @' +'aaa'.ToString() > $null +'aa' > $null +"a" 2> $null | % { $_ } +'bb' > $null +'bb'.ToSTring() > $null +'bbb' +'@ +$script2 = @' +"line 1" +"line 2" +"line 3" +'@ + +$root = git rev-parse --show-toplevel +$pestertestroot = join-path $root test/powershell +$common = join-path $pestertestroot Common +$helperModule = join-path $common Test.Helpers.psm1 + +Describe "Breakpoints when set should be hit" -tag "CI" { + BeforeAll { + $path = setup -pass -f TestScript_1.ps1 -content $script1 + $bps = 1..6 | %{ set-psbreakpoint -script $path -line $_ -Action { continue } } + } + AfterAll { + $bps | Remove-PSBreakPoint + } + It "A redirected breakpoint is hit" { + & $path + foreach ( $bp in $bps ) { + $bp.HitCount | should be 1 + } + } +} + +Describe "It should be possible to reset runspace debugging" { + BeforeAll { + import-module $helperModule -force + $path = setup -pass -f TestScript_2.ps1 -content $script2 + $scriptPath = "$testdrive/TestScript_2.ps1" + $iss = [initialsessionstate]::CreateDefault2(); + $rs = [runspacefactory]::CreateRunspace($iss) + $rs.Name = "TestRunspaceDebuggerReset" + $rs.Open() + $rs | Enable-RunspaceDebug + + $debuggerBeforeReset = $rs.Debugger + + # Create PowerShell to run script. + $ps = [powershell]::Create() + $ps.Runspace = $rs + + # Set breakpoints in runspace. + $result = $ps.AddScript("Set-PSBreakpoint -Script '$scriptPath' -line 1").Invoke() + $ps.Commands.Clear() + $result = $ps.AddScript("Set-PSBreakpoint -Script '$scriptPath' -line 3").Invoke() + $ps.Commands.Clear() + $breakpoints = $ps.AddScript("Get-PSBreakpoint").Invoke() + + # Run script file until breakpoint hit. + $ar = $ps.AddScript("$scriptPath").BeginInvoke() + $completed = Wait-CompleteExecution { $rs.Debugger.InBreakPoint -eq $true } -timeout 10000 -interval 200 + $ps.Stop() + $rs.ResetRunspaceState() + } + AfterAll { + if ( $ps -ne $null ) { $ps.Dispose() } + if ( $ss -ne $null ) { $rs.Dispose() } + } + It "2 breakpoints should have been set" { + $breakpoints.Count | Should be 2 + } + It "The breakpoint Should have been hit" { + $completed | should be $true + } + It "The reset debugger should not be in a breakpoint" { + $rs.Debugger.InBreakPoint | should be $false + } + It "The reset debugger should not be active" { + $rs.Debugger.IsActive | should be $false + } + It "The reset debugger mode should be set to 'Default'" { + $rs.Debugger.DebugMode | should be "Default" + } + It "The debugger should be the same before and after the reset" { + $rs.Debugger | Should be $debuggerBeforeReset + } + It "The breakpoints should be gone after reset" { + $ps.Commands.clear() + $ps.AddCommand("Get-PSBreakpoint").Invoke() | Should BeNullOrEmpty + } + It "The script should run without a break" { + $ps.Commands.Clear() + $ps.addscript("$testdrive/TestScript_2.ps1").Invoke().Count | should be 3 + } +} From 6aac4976fbb54a86ea31ce44ef4aef77e93c0287 Mon Sep 17 00:00:00 2001 From: James Truher Date: Wed, 24 Aug 2016 16:58:21 -0700 Subject: [PATCH 10/14] Add simple runspace debugging tests --- .../Scripting/Debugging/Debugging.Tests.ps1 | 2 +- .../Debug-Runspace.Tests.ps1 | 59 +++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 test/powershell/Modules/Microsoft.PowerShell.Utility/Debug-Runspace.Tests.ps1 diff --git a/test/powershell/Language/Scripting/Debugging/Debugging.Tests.ps1 b/test/powershell/Language/Scripting/Debugging/Debugging.Tests.ps1 index 402d43b578..88c55cee33 100644 --- a/test/powershell/Language/Scripting/Debugging/Debugging.Tests.ps1 +++ b/test/powershell/Language/Scripting/Debugging/Debugging.Tests.ps1 @@ -33,7 +33,7 @@ Describe "Breakpoints when set should be hit" -tag "CI" { } } -Describe "It should be possible to reset runspace debugging" { +Describe "It should be possible to reset runspace debugging" -tag "Feature" { BeforeAll { import-module $helperModule -force $path = setup -pass -f TestScript_2.ps1 -content $script2 diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Debug-Runspace.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Debug-Runspace.Tests.ps1 new file mode 100644 index 0000000000..8b41fe1aa4 --- /dev/null +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Debug-Runspace.Tests.ps1 @@ -0,0 +1,59 @@ +Describe "Debug-Runspace" -tag "CI" { + BeforeAll { + $rs1 = [runspacefactory]::CreateRunspace() + $rs1.Open() + $rs1.Name = "MyRunspace1" + $rs2 = [runspacefactory]::CreateRunspace() + $rs2.Open() + $rs2.Name = "MyRunspace2" + } + AfterAll { + if ( $rs1 ) { $rs1.Dispose() } + if ( $rs2 ) { $rs1.Dispose() } + } + + It "Debugging a runspace should fail is the name is ambiguous" { + try { + Debug-Runspace -Name "My*" -ea stop + throw "Execution OK" + } + catch { + $_.FullyQualifiedErrorId | should be "DebugRunspaceTooManyRunspaceFound,Microsoft.PowerShell.Commands.DebugRunspaceCommand" + } + } + + It "Debugging a runspace should fail is the name is not found" { + try { + Debug-Runspace -Name "dflkjsdkfjldkjssldfj" -ea stop + throw "Execution OK" + } + catch { + $_.FullyQualifiedErrorId | should be "DebugRunspaceNoRunspaceFound,Microsoft.PowerShell.Commands.DebugRunspaceCommand" + } + } + + It "Debugging a runspace should fail is the runspace is not open" { + try { + $rs2.Close() + Debug-Runspace -runspace $rs2 -ea stop + throw "Execution OK" + } + catch { + $_.FullyQualifiedErrorId | should be "InvalidOperation,Microsoft.PowerShell.Commands.DebugRunspaceCommand" + } + } + + It "Debugging a runspace should fail is the runspace has no debugger" { + try { + $rs1.Debugger.SetDebugMode("None") + Debug-Runspace -runspace $rs1 -ea stop + throw "Execution OK" + } + catch { + $_.FullyQualifiedErrorId | should be "InvalidOperation,Microsoft.PowerShell.Commands.DebugRunspaceCommand" + } + } + +} + + From f4ed351f86589359afa1daf43a41b5116d67bebe Mon Sep 17 00:00:00 2001 From: James Truher Date: Thu, 25 Aug 2016 17:00:18 -0700 Subject: [PATCH 11/14] fix typos in test descriptions --- .../Microsoft.PowerShell.Utility/Debug-Runspace.Tests.ps1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Debug-Runspace.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Debug-Runspace.Tests.ps1 index 8b41fe1aa4..7f5c00ab5c 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/Debug-Runspace.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Debug-Runspace.Tests.ps1 @@ -12,7 +12,7 @@ Describe "Debug-Runspace" -tag "CI" { if ( $rs2 ) { $rs1.Dispose() } } - It "Debugging a runspace should fail is the name is ambiguous" { + It "Debugging a runspace should fail if the name is ambiguous" { try { Debug-Runspace -Name "My*" -ea stop throw "Execution OK" @@ -22,7 +22,7 @@ Describe "Debug-Runspace" -tag "CI" { } } - It "Debugging a runspace should fail is the name is not found" { + It "Debugging a runspace should fail if the name is not found" { try { Debug-Runspace -Name "dflkjsdkfjldkjssldfj" -ea stop throw "Execution OK" @@ -32,7 +32,7 @@ Describe "Debug-Runspace" -tag "CI" { } } - It "Debugging a runspace should fail is the runspace is not open" { + It "Debugging a runspace should fail if the runspace is not open" { try { $rs2.Close() Debug-Runspace -runspace $rs2 -ea stop @@ -43,7 +43,7 @@ Describe "Debug-Runspace" -tag "CI" { } } - It "Debugging a runspace should fail is the runspace has no debugger" { + It "Debugging a runspace should fail if the runspace has no debugger" { try { $rs1.Debugger.SetDebugMode("None") Debug-Runspace -runspace $rs1 -ea stop From 3ceca01b648ffc61192fabe9f6164cf4e246dba1 Mon Sep 17 00:00:00 2001 From: James Truher Date: Mon, 29 Aug 2016 15:00:26 -0700 Subject: [PATCH 12/14] address some review feedback --- test/powershell/Common/Test.Helpers.psm1 | 26 ++++++++++++++++++- .../Scripting/Debugging/Debugging.Tests.ps1 | 5 ++-- .../Set-Date.Tests.ps1 | 15 ++--------- 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/test/powershell/Common/Test.Helpers.psm1 b/test/powershell/Common/Test.Helpers.psm1 index b168c97911..a83bae4ef1 100644 --- a/test/powershell/Common/Test.Helpers.psm1 +++ b/test/powershell/Common/Test.Helpers.psm1 @@ -22,4 +22,28 @@ function Wait-CompleteExecution } return $true } -export-modulemember -function Wait-CompleteExecution + +function Test-IsElevated +{ + $IsElevated = $False + if ( $IsWindows ) { + # on Windows we can determine whether we're executing in an + # elevated context + $identity = [System.Security.Principal.WindowsIdentity]::GetCurrent() + $windowsPrincipal = new-object 'Security.Principal.WindowsPrincipal' $identity + if ($windowsPrincipal.IsInRole("Administrators") -eq 1) + { + $IsElevated = $true + } + } + else { + # on Linux, tests run via sudo will generally report "root" for whoami + if ( (whoami) -match "root" ) { + $IsElevated = $true + } + } + return $IsElevated +} + +export-modulemember -function Wait-CompleteExecution,Test-IsElevated + diff --git a/test/powershell/Language/Scripting/Debugging/Debugging.Tests.ps1 b/test/powershell/Language/Scripting/Debugging/Debugging.Tests.ps1 index 88c55cee33..90ed527648 100644 --- a/test/powershell/Language/Scripting/Debugging/Debugging.Tests.ps1 +++ b/test/powershell/Language/Scripting/Debugging/Debugging.Tests.ps1 @@ -12,9 +12,8 @@ $script2 = @' "line 3" '@ -$root = git rev-parse --show-toplevel -$pestertestroot = join-path $root test/powershell -$common = join-path $pestertestroot Common +$testroot = resolve-path (join-path $psscriptroot ../../..) +$common = join-path $testroot Common $helperModule = join-path $common Test.Helpers.psm1 Describe "Breakpoints when set should be hit" -tag "CI" { diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Set-Date.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Set-Date.Tests.ps1 index 47eccb785a..d523146dda 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/Set-Date.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Set-Date.Tests.ps1 @@ -3,19 +3,8 @@ # determine whether we're elevated Describe "Set-Date" -Tag "CI" { BeforeAll { - if ( $IsWindows ) { - $identity = [System.Security.Principal.WindowsIdentity]::GetCurrent() - $windowsPrincipal = new-object 'Security.Principal.WindowsPrincipal' $identity - if ($windowsPrincipal.IsInRole("Administrators") -eq 1) { $IsElevated = $true } else { $IsElevated = $false } - } - else { - if ( (whoami) -match "root" ) { - $IsElevated = $true - } - else { - $IsElevated = $false - } - } + Import-Module (join-path $psscriptroot "../../Common/Test.Helpers.psm1") + $IsElevated = Test-IsElevated } It "Set-Date should be able to set the date in an elevated context" -Skip:(! $IsElevated) { { get-date | set-date } | Should not throw From 2824e136cbc5953bd857ef67987a707b51d33e6b Mon Sep 17 00:00:00 2001 From: James Truher Date: Tue, 30 Aug 2016 16:14:20 -0700 Subject: [PATCH 13/14] update exception messages --- .../Microsoft.PowerShell.Security/SecureString.Tests.ps1 | 2 +- .../Microsoft.PowerShell.Utility/Debug-Runspace.Tests.ps1 | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Security/SecureString.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Security/SecureString.Tests.ps1 index ac0f16d137..9fc6cfe9f8 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Security/SecureString.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Security/SecureString.Tests.ps1 @@ -25,7 +25,7 @@ Describe "SecureString conversion tests" -Tags "CI" { try { $badkey = [byte[]]@(1,2) ConvertFrom-SecureString -securestring $secureString -key $badkey - throw "Execution OK" + throw "Command did not throw exception" } catch { $_.FullyQualifiedErrorId | should be "Argument,Microsoft.PowerShell.Commands.ConvertFromSecureStringCommand" diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Debug-Runspace.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Debug-Runspace.Tests.ps1 index 7f5c00ab5c..4c5b13fccb 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/Debug-Runspace.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Debug-Runspace.Tests.ps1 @@ -15,7 +15,7 @@ Describe "Debug-Runspace" -tag "CI" { It "Debugging a runspace should fail if the name is ambiguous" { try { Debug-Runspace -Name "My*" -ea stop - throw "Execution OK" + throw "Command did not throw exception" } catch { $_.FullyQualifiedErrorId | should be "DebugRunspaceTooManyRunspaceFound,Microsoft.PowerShell.Commands.DebugRunspaceCommand" @@ -25,7 +25,7 @@ Describe "Debug-Runspace" -tag "CI" { It "Debugging a runspace should fail if the name is not found" { try { Debug-Runspace -Name "dflkjsdkfjldkjssldfj" -ea stop - throw "Execution OK" + throw "Command did not throw exception" } catch { $_.FullyQualifiedErrorId | should be "DebugRunspaceNoRunspaceFound,Microsoft.PowerShell.Commands.DebugRunspaceCommand" @@ -36,7 +36,7 @@ Describe "Debug-Runspace" -tag "CI" { try { $rs2.Close() Debug-Runspace -runspace $rs2 -ea stop - throw "Execution OK" + throw "Command did not throw exception" } catch { $_.FullyQualifiedErrorId | should be "InvalidOperation,Microsoft.PowerShell.Commands.DebugRunspaceCommand" @@ -47,7 +47,7 @@ Describe "Debug-Runspace" -tag "CI" { try { $rs1.Debugger.SetDebugMode("None") Debug-Runspace -runspace $rs1 -ea stop - throw "Execution OK" + throw "Command did not throw exception" } catch { $_.FullyQualifiedErrorId | should be "InvalidOperation,Microsoft.PowerShell.Commands.DebugRunspaceCommand" From 4dc09f504cdd64bafdc8314f84c315627c56228b Mon Sep 17 00:00:00 2001 From: James Truher Date: Tue, 30 Aug 2016 16:52:00 -0700 Subject: [PATCH 14/14] change throw message --- .../Microsoft.PowerShell.Utility/PowerShellData.tests.ps1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/PowerShellData.tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/PowerShellData.tests.ps1 index e2ececef47..0b07ad2940 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/PowerShellData.tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/PowerShellData.tests.ps1 @@ -5,7 +5,7 @@ try { Import-PowerShellDataFile -Path /SomeMissingDirectory -ErrorAction Stop - Throw "Execution OK" + Throw "Command did not throw exception" } catch { @@ -18,7 +18,7 @@ try { Import-PowerShellDataFile ${TESTDRIVE} -ErrorAction Stop - Throw "Execution OK" + Throw "Command did not throw exception" } catch { @@ -33,7 +33,7 @@ try { Import-PowerShellDataFile $path -ErrorAction Stop - Throw "Execution OK" + Throw "Command did not throw exception" } catch { @@ -47,7 +47,7 @@ try { Import-PowerShellDataFile $path -ErrorAction Stop - Throw "Execution OK" + Throw "Command did not throw exception" } catch {