Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
Trace-Command.Tests.ps1300 linesDownload Raw Back to Microsoft.PowerShell.Utility
1# Copyright (c) Microsoft Corporation.2# Licensed under the MIT License.3 4# This came from monad/tests/ci/PowerShell/tests/Commands/Cmdlets/pester.utility.command.tests.ps15Describe "Trace-Command" -tags "CI" {6 7    Context "Listener options" {8        BeforeAll {9            $logFile = New-Item "TestDrive:/traceCommandLog.txt" -Force10            $actualLogFile = New-Item "TestDrive:/actualTraceCommandLog.txt" -Force11        }12 13        AfterEach {14            Remove-Item "TestDrive:/traceCommandLog.txt" -Force -ErrorAction SilentlyContinue15            Remove-Item "TestDrive:/actualTraceCommandLog.txt" -Force -ErrorAction SilentlyContinue16        }17 18        # LogicalOperationStack is not in .NET Core19        It "LogicalOperationStack works" -Skip:$IsCoreCLR {20            $keyword = "Trace_Command_ListenerOption_LogicalOperationStack_Foo"21            $stack = [System.Diagnostics.Trace]::CorrelationManager.LogicalOperationStack22            $stack.Push($keyword)23 24            Trace-Command -Name * -Expression {Write-Output Foo} -ListenerOption LogicalOperationStack -FilePath $logfile25 26            $log = Get-Content $logfile | Where-Object {$_ -like "*LogicalOperationStack=$keyword*"}27            $log.Count | Should -BeGreaterThan 028        }29 30        # GetStackTrace is not in .NET Core31        It "Callstack works" -Skip:$IsCoreCLR {32            Trace-Command -Name * -Expression {Write-Output Foo} -ListenerOption Callstack -FilePath $logfile33            $log = Get-Content $logfile | Where-Object {$_ -like "*Callstack=   * System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)*"}34            $log.Count | Should -BeGreaterThan 035        }36 37        It "Datetime works" {38            $expectedDate = Trace-Command -Name * -Expression {Get-Date} -ListenerOption DateTime -FilePath $logfile39            $log = Get-Content $logfile | Where-Object {$_ -like "*DateTime=*"}40            $results = $log | ForEach-Object {[DateTime]::Parse($_.Split("=")[1])}41 42            ## allow a gap of 6 seconds. All traces should be finished within 6 seconds.43            $allowedGap = [timespan](60 * 1000 * 1000)44            $results | ForEach-Object {45                    $actualGap = $_ - $expectedDate;46                    if ($expectedDate -gt $_)47                    {48                        $actualGap = $expectedDate - $_;49                    }50 51                    $allowedGap | Should -BeGreaterThan $actualGap52                }53        }54 55        It "None options has no effect" {56            Trace-Command -Name * -Expression {Write-Output Foo} -ListenerOption None -FilePath $actualLogfile57            Trace-Command -Name * -Expression {Write-Output Foo} -FilePath $logfile58 59            Compare-Object (Get-Content $actualLogfile) (Get-Content $logfile) | Should -BeNullOrEmpty60        }61 62        It "ThreadID works" {63            Trace-Command -Name * -Expression {Write-Output Foo} -ListenerOption ThreadId -FilePath $logfile64            $log = Get-Content $logfile | Where-Object {$_ -like "*ThreadID=*"}65            $results = $log | ForEach-Object {$_.Split("=")[1]}66 67            $results | ForEach-Object { $_ | Should -Be ([threading.thread]::CurrentThread.ManagedThreadId) }68        }69 70        It "Timestamp creates logs in ascending order" {71            Trace-Command -Name * -Expression {Write-Output Foo} -ListenerOption Timestamp -FilePath $logfile72            $log = Get-Content $logfile | Where-Object {$_ -like "*Timestamp=*"}73            $results = $log | ForEach-Object {$_.Split("=")[1]}74            $sortedResults = $results | Sort-Object75            $sortedResults | Should -Be $results76        }77 78        It "ProcessId logs current process Id" {79            Trace-Command -Name * -Expression {Write-Output Foo} -ListenerOption ProcessId -FilePath $logfile80            $log = Get-Content $logfile | Where-Object {$_ -like "*ProcessID=*"}81            $results = $log | ForEach-Object {$_.Split("=")[1]}82 83            $results | ForEach-Object { $_ | Should -Be $PID }84        }85    }86 87    Context "MethodInvocation traces" {88 89        BeforeAll {90            $filePath = Join-Path $TestDrive 'testtracefile.txt'91 92            class MyClass {93                MyClass() {}94                MyClass([int]$arg) {}95 96                [void]Method() { return }97                [void]Method([string]$arg) { return }98                [void]Method([int]$arg) { return }99 100                [string]ReturnMethod() { return "foo" }101 102                static [void]StaticMethod() { return }103                static [void]StaticMethod([string]$arg) { return }104            }105 106            # C# classes support more features than pwsh classes107            Add-Type -TypeDefinition @'108namespace TraceCommandTests;109 110public sealed class OverloadTests111{112    public int PropertySetter { get; set; }113 114    public OverloadTests() {}115    public OverloadTests(int value)116    {117        PropertySetter = value;118    }119 120    public void GenericMethod<T>()121    {}122 123    public T GenericMethodWithArg<T>(T obj) => obj;124 125    public void MethodWithDefault(string arg1, int optional = 1)126    {}127 128    public void MethodWithOut(out int val)129    {130        val = 1;131    }132 133    public void MethodWithRef(ref int val)134    {135        val = 1;136    }137}138'@139        }140 141        AfterEach {142            Remove-Item $filePath -Force -ErrorAction SilentlyContinue143        }144 145        It "Traces instance method" {146            $myClass = [MyClass]::new()147            Trace-Command -Name MethodInvocation -Expression {148                $myClass.Method(1)149            } -FilePath $filePath150            Get-Content $filePath | Should -BeLike "*Invoking method: void Method(int arg)"151        }152 153        It "Traces static method" {154            Trace-Command -Name MethodInvocation -Expression {155                [MyClass]::StaticMethod(1)156            } -FilePath $filePath157            Get-Content $filePath | Should -BeLike "*Invoking method: static void StaticMethod(string arg)"158        }159 160        It "Traces method with return type" {161            $myClass = [MyClass]::new()162            Trace-Command -Name MethodInvocation -Expression {163                $myClass.ReturnMethod()164            } -FilePath $filePath165            Get-Content $filePath | Should -BeLike "*Invoking method: string ReturnMethod()"166        }167 168        It "Traces constructor" {169            Trace-Command -Name MethodInvocation -Expression {170                [TraceCommandTests.OverloadTests]::new("1234")171            } -FilePath $filePath172            Get-Content $filePath | Should -BeLike "*Invoking method: TraceCommandTests.OverloadTests new(int value)"173        }174 175        It "Traces Property setter invoked as a method" {176            $obj = [TraceCommandTests.OverloadTests]::new()177            Trace-Command -Name MethodInvocation -Expression {178                $obj.set_PropertySetter(1234)179            } -FilePath $filePath180            Get-Content $filePath | Should -BeLike "*Invoking method: void set_PropertySetter(int value)"181        }182 183        It "Traces generic method" {184            $obj = [TraceCommandTests.OverloadTests]::new()185            Trace-Command -Name MethodInvocation -Expression {186                $obj.GenericMethod[int]()187            } -FilePath $filePath188            Get-Content $filePath | Should -BeLike "*Invoking method: void GenericMethod``[int``]()"189        }190 191        It "Traces generic method with argument" {192            $obj = [TraceCommandTests.OverloadTests]::new()193            Trace-Command -Name MethodInvocation -Expression {194                $obj.GenericMethodWithArg("foo")195            } -FilePath $filePath196            Get-Content $filePath | Should -BeLike "*Invoking method: string GenericMethodWithArg``[string``](string obj)"197        }198 199        It "Traces .NET call with default value" {200            $obj = [TraceCommandTests.OverloadTests]::new()201            Trace-Command -Name MethodInvocation -Expression {202                $obj.MethodWithDefault("foo")203            } -FilePath $filePath204            Get-Content $filePath | Should -BeLike "*Invoking method: void MethodWithDefault(string arg1, int optional = 1)"205        }206 207        It "Traces method with ref argument" {208            $obj = [TraceCommandTests.OverloadTests]::new()209            $v = 1210 211            Trace-Command -Name MethodInvocation -Expression {212                $obj.MethodWithRef([ref]$v)213            } -FilePath $filePath214            # [ref] goes through the binder so will trigger the first trace215            Get-Content $filePath | Select-Object -Skip 1 | Should -BeLike "*Invoking method: void MethodWithRef(``[ref``] int val)"216        }217 218        It "Traces method with out argument" {219            $obj = [TraceCommandTests.OverloadTests]::new()220            $v = 1221 222            Trace-Command -Name MethodInvocation -Expression {223                $obj.MethodWithOut([ref]$v)224            } -FilePath $filePath225            # [ref] goes through the binder so will trigger the first trace226            Get-Content $filePath | Select-Object -Skip 1 | Should -BeLike "*Invoking method: void MethodWithOut(``[ref``] int val)"227        }228 229        It "Traces a binding error" {230            Trace-Command -Name MethodInvocation -Expression {231                # try/catch is used as error formatter will hit the trace as well232                try {233                    [System.Runtime.InteropServices.Marshal]::SizeOf([int])234                }235                catch {236                    # Satisfy codefactor237                    $_ | Out-Null238                }239            } -FilePath $filePath240            # type fqn is used, the wildcard avoids hardcoding that241            Get-Content $filePath | Should -BeLike "*Invoking method: static int SizeOf``[System.RuntimeType, *``](System.RuntimeType, * structure)"242        }243 244        It "Traces LINQ call" {245            Trace-Command -Name MethodInvocation -Expression {246                [System.Linq.Enumerable]::Union([int[]]@(1, 2), [int[]]@(3, 4))247            } -FilePath $filePath248            Get-Content $filePath | Should -BeLike "*Invoking method: static System.Collections.Generic.IEnumerable``[int``] Union``[int``](System.Collections.Generic.IEnumerable``[int``] first, System.Collections.Generic.IEnumerable``[int``] second)"249        }250    }251 252    Context "Trace-Command tests for code coverage" {253 254        BeforeAll {255            $filePath = Join-Path $TestDrive 'testtracefile.txt'256        }257 258        AfterEach {259            Remove-Item $filePath -Force -ErrorAction SilentlyContinue260        }261 262        It "Get non-existing trace source" {263            { '34E7F9FA-EBFB-4D21-A7D2-D7D102E2CC2F' | Get-TraceSource -ErrorAction Stop} | Should -Throw -ErrorId 'TraceSourceNotFound,Microsoft.PowerShell.Commands.GetTraceSourceCommand'264        }265 266        It "Set-TraceSource to file and RemoveFileListener wildcard" {267            $null = Set-TraceSource -Name "ParameterBinding" -Option ExecutionFlow -FilePath $filePath -Force -ListenerOption "ProcessId,TimeStamp" -PassThru268            Set-TraceSource -Name "ParameterBinding" -RemoveFileListener *269            Get-Content $filePath -Raw | Should -Match 'ParameterBinding Information'270        }271 272        It "Trace-Command -Command with error" {273            { Trace-Command -Name ParameterBinding -Command 'Get-PSDrive' -ArgumentList 'NonExistingDrive' -Option ExecutionFlow -FilePath $filePath -Force -ListenerOption "ProcessId,TimeStamp" -ErrorAction Stop } |274                Should -Throw -ErrorId 'GetLocationNoMatchingDrive,Microsoft.PowerShell.Commands.TraceCommandCommand'275        }276 277        It "Trace-Command fails for non-filesystem paths" {278            { Trace-Command -Name ParameterBinding -Expression {$null} -FilePath "Env:\Test" -ErrorAction Stop } | Should -Throw -ErrorId 'FileListenerPathResolutionFailed,Microsoft.PowerShell.Commands.TraceCommandCommand'279        }280 281        It "Trace-Command to readonly file" {282            $null = New-Item $filePath -Force283            Set-ItemProperty $filePath -Name IsReadOnly -Value $true284            Trace-Command -Name ParameterBinding -Command 'Get-PSDrive' -FilePath $filePath -Force285            Get-Content $filePath -Raw | Should -Match 'ParameterBinding Information'286        }287 288        It "Trace-Command using Path parameter alias" {289            $null = New-Item $filePath -Force290            Trace-Command -Name ParameterBinding -Command 'Get-PSDrive' -Path $filePath -Force291            Get-Content $filePath -Raw | Should -Match 'ParameterBinding Information'292        }293 294        It "Trace-Command contains wildcard characters" {295            $a = Trace-Command -Name ParameterB* -Command 'get-alias'296            $a.count | Should -BeGreaterThan 0297        }298    }299}300