diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/GetTracerCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/GetTracerCommand.cs index b9ad3e7d4..55f4e78bf 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/GetTracerCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/GetTracerCommand.cs @@ -1,4 +1,3 @@ -#if !CORECLR /********************************************************************++ Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ @@ -59,6 +58,3 @@ namespace Microsoft.PowerShell.Commands #endregion Cmdlet code } } - - -#endif diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/MshHostTraceListener.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/MshHostTraceListener.cs index 30b6050e9..1ddda4afa 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/MshHostTraceListener.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/MshHostTraceListener.cs @@ -1,15 +1,19 @@ -#if !CORECLR /********************************************************************++ Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ using System; using System.IO; -using System.Security.Permissions; using System.Text; using System.Management.Automation; using System.Management.Automation.Host; using System.Management.Automation.Internal.Host; +#if CORECLR +using Microsoft.PowerShell.CoreClr.Stubs; +#else +using System.Security.Permissions; +#endif + namespace Microsoft.PowerShell.Commands { /// @@ -64,6 +68,9 @@ namespace Microsoft.PowerShell.Commands [SecurityPermission(SecurityAction.LinkDemand)] protected override void Dispose(bool disposing) { +#if CORECLR + base.Dispose(disposing); +#else try { if (disposing) @@ -75,8 +82,10 @@ namespace Microsoft.PowerShell.Commands { base.Dispose(disposing); } +#endif } +#if !CORECLR /// /// Closes the dialog and then calls the base class Close /// @@ -87,6 +96,7 @@ namespace Microsoft.PowerShell.Commands base.Close(); } +#endif #endregion TraceListener constructors and disposer @@ -144,6 +154,3 @@ namespace Microsoft.PowerShell.Commands } // class PSHostTraceListener } // namespace System.Management.Automation - - -#endif diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/SetTracerCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/SetTracerCommand.cs index 6f6a04450..561d12a44 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/SetTracerCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/SetTracerCommand.cs @@ -1,4 +1,3 @@ -#if !CORECLR /********************************************************************++ Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ @@ -186,6 +185,3 @@ namespace Microsoft.PowerShell.Commands #endregion Cmdlet code } } - - -#endif diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/TraceCommandBase.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/TraceCommandBase.cs index e9b13f9a0..2322303a7 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/TraceCommandBase.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/TraceCommandBase.cs @@ -1,4 +1,3 @@ -#if !CORECLR /********************************************************************++ Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ @@ -134,6 +133,3 @@ namespace Microsoft.PowerShell.Commands } } } - - -#endif diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/TraceExpressionCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/TraceExpressionCommand.cs index 3f48f6796..c303bddfd 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/TraceExpressionCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/TraceExpressionCommand.cs @@ -1,4 +1,3 @@ -#if !CORECLR /********************************************************************++ Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ @@ -334,7 +333,7 @@ namespace Microsoft.PowerShell.Commands foreach (FileStream fileStream in this.FileStreams) { fileStream.Flush(); - fileStream.Close(); + fileStream.Dispose(); } } GC.SuppressFinalize(this); @@ -573,6 +572,3 @@ namespace Microsoft.PowerShell.Commands private Collection matchingSources = new Collection(); } } - - -#endif diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/TraceListenerCommandBase.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/TraceListenerCommandBase.cs index 6af1f02b6..7615b910b 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/TraceListenerCommandBase.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/trace/TraceListenerCommandBase.cs @@ -1,4 +1,3 @@ -#if !CORECLR /********************************************************************++ Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ @@ -461,7 +460,7 @@ namespace Microsoft.PowerShell.Commands true)) { listenerToRemove.Flush(); - listenerToRemove.Close(); + listenerToRemove.Dispose(); source.Listeners.RemoveAt(index); } } @@ -620,7 +619,7 @@ namespace Microsoft.PowerShell.Commands foreach (TraceListener listener in pair.Value) { listener.Flush(); - listener.Close(); + listener.Dispose(); } } storedTraceSourceState.Clear (); @@ -632,6 +631,3 @@ namespace Microsoft.PowerShell.Commands #endregion stored state } } - - -#endif diff --git a/src/Microsoft.PowerShell.Commands.Utility/project.json b/src/Microsoft.PowerShell.Commands.Utility/project.json index 77e6525e1..bcdf61b06 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/project.json +++ b/src/Microsoft.PowerShell.Commands.Utility/project.json @@ -28,7 +28,8 @@ "imports": [ "dnxcore50", "portable-net45+win8" ], "dependencies": { "Microsoft.CodeAnalysis.CSharp": "1.1.1", - "Newtonsoft.Json": "8.0.2" + "Newtonsoft.Json": "8.0.2", + "System.Diagnostics.TextWriterTraceListener": "4.0.0-rc2-24103" } }, "net451": { diff --git a/src/powershell/Modules/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 b/src/powershell/Modules/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 index e30c63d02..3564ea3e1 100644 --- a/src/powershell/Modules/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 +++ b/src/powershell/Modules/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 @@ -19,6 +19,7 @@ CmdletsToExport= "Format-List", "Format-Custom", "Format-Table", "Format-Wide", "Clear-Variable", "Export-Clixml", "Import-Clixml", "ConvertTo-Xml", "Select-Xml", "Write-Debug", "Write-Verbose", "Write-Warning", "Write-Error", "Write-Information", "Write-Output", "Set-PSBreakpoint", "Get-PSBreakpoint", "Remove-PSBreakpoint", "Enable-PSBreakpoint", "Disable-PSBreakpoint", "Get-PSCallStack", + "Get-TraceSource", "Set-TraceSource", "Trace-Command", "Unblock-File", "Get-Runspace", "Debug-Runspace", "Enable-RunspaceDebug", "Disable-RunspaceDebug", "Get-RunspaceDebug", "Wait-Debugger" FunctionsToExport= "Get-FileHash", "New-TemporaryFile", "New-Guid", "Format-Hex", "Import-PowerShellDataFile", diff --git a/test/powershell/Get-TraceSource.Tests.ps1 b/test/powershell/Get-TraceSource.Tests.ps1 new file mode 100644 index 000000000..bd777d7cf --- /dev/null +++ b/test/powershell/Get-TraceSource.Tests.ps1 @@ -0,0 +1,6 @@ +Describe "Get-TraceSource" -tags "P1" { + It "Should output data sorted by name" { + $expected = (Get-TraceSource | Sort-Object Name) + Get-TraceSource | Should be $expected + } +} diff --git a/test/powershell/Trace-Command.Tests.ps1 b/test/powershell/Trace-Command.Tests.ps1 new file mode 100644 index 000000000..61c62edac --- /dev/null +++ b/test/powershell/Trace-Command.Tests.ps1 @@ -0,0 +1,83 @@ +# This came from monad/tests/ci/PowerShell/tests/Commands/Cmdlets/pester.utility.command.tests.ps1 +Describe "Trace-Command" -tags "P1", "RI" { + + Context "Listner options" { + BeforeAll { + $logFile = New-Item "TestDrive:/traceCommandLog.txt" -Force + $actualLogFile = New-Item "TestDrive:/actualTraceCommandLog.txt" -Force + } + + AfterEach { + Remove-Item "TestDrive:/traceCommandLog.txt" -Force -ErrorAction SilentlyContinue + Remove-Item "TestDrive:/actualTraceCommandLog.txt" -Force -ErrorAction SilentlyContinue + } + + # LogicalOperationStack is not in .NET Core + It "LogicalOperationStack works" -Skip:$IsCore { + $keyword = "Trace_Command_ListenerOption_LogicalOperationStack_Foo" + $stack = [System.Diagnostics.Trace]::CorrelationManager.LogicalOperationStack + $stack.Push($keyword) + + Trace-Command -Name * -Expression {echo Foo} -ListenerOption LogicalOperationStack -FilePath $logfile + + $log = Get-Content $logfile | Where-Object {$_ -like "*LogicalOperationStack=$keyword*"} + $log.Count | Should BeGreaterThan 0 + } + + # GetStackTrace is not in .NET Core + It "Callstack works" -Skip:$IsCore { + Trace-Command -Name * -Expression {echo Foo} -ListenerOption Callstack -FilePath $logfile + $log = Get-Content $logfile | Where-Object {$_ -like "*Callstack= * System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)*"} + $log.Count | Should BeGreaterThan 0 + } + + It "Datetime works" { + $expectedDate = Trace-Command -Name * -Expression {Get-Date} -ListenerOption DateTime -FilePath $logfile + $log = Get-Content $logfile | Where-Object {$_ -like "*DateTime=*"} + $results = $log | ForEach-Object {[DateTime]::Parse($_.Split("=")[1])} + + ## allow a gap of 6 seconds. All traces should be finished within 6 seconds. + $allowedGap = [timespan](60 * 1000 * 1000) + $results | ForEach-Object { + $actualGap = $_ - $expectedDate; + if ($expectedDate -gt $_) + { + $actualGap = $expectedDate - $_; + } + + $allowedGap | Should BeGreaterThan $actualGap + } + } + + It "None options has no effect" { + Trace-Command -Name * -Expression {echo Foo} -ListenerOption None -FilePath $actualLogfile + Trace-Command -name * -Expression {echo Foo} -FilePath $logfile + + Compare-Object (Get-Content $actualLogfile) (Get-Content $logfile) | Should BeNullOrEmpty + } + + It "ThreadID works" { + Trace-Command -Name * -Expression {echo Foo} -ListenerOption ThreadId -FilePath $logfile + $log = Get-Content $logfile | Where-Object {$_ -like "*ThreadID=*"} + $results = $log | ForEach-Object {$_.Split("=")[1]} + + $results | % { $_ | Should Be ([threading.thread]::CurrentThread.ManagedThreadId) } + } + + It "Timestamp creates logs in ascending order" { + Trace-Command -Name * -Expression {echo Foo} -ListenerOption Timestamp -FilePath $logfile + $log = Get-Content $logfile | Where-Object {$_ -like "*Timestamp=*"} + $results = $log | ForEach-Object {$_.Split("=")[1]} + $sortedResults = $results | Sort-Object + $sortedResults | Should Be $results + } + + It "ProcessId logs current process Id" { + Trace-Command -Name * -Expression {echo Foo} -ListenerOption ProcessId -FilePath $logfile + $log = Get-Content $logfile | Where-Object {$_ -like "*ProcessID=*"} + $results = $log | ForEach-Object {$_.Split("=")[1]} + + $results | ForEach-Object { $_ | Should Be $pid } + } + } +}