MegaBites-AI/Windows-powershell
0372
1# Copyright (c) Microsoft Corporation.2# Licensed under the MIT License.3 4Import-Module HelpersCommon5 6function GetGatewayAddress7{8 return [System.Net.NetworkInformation.NetworkInterface]::GetAllNetworkInterfaces() |9 Where-Object { $_.OperationalStatus -eq 'Up' -and $_.NetworkInterfaceType -ne 'Loopback' } |10 ForEach-Object { $_.GetIPProperties().GatewayAddresses } |11 Select-Object -First 1 |12 ForEach-Object { $_.Address.IPAddressToString }13}14 15function GetExternalHostAddress([string]$HostName)16{17 if (-not $HostName)18 {19 return20 }21 22 try23 {24 return [System.Net.Dns]::GetHostEntry($HostName).AddressList |25 Where-Object { $_.AddressFamily -eq 'InterNetwork' } |26 Select-Object -First 1 |27 ForEach-Object { $_.IPAddressToString }28 }29 catch30 {31 return32 }33}34 35# Adding RequireSudoOnUnix due to an intentional breaking change.36# See https://github.com/dotnet/runtime/issues/6674637Describe "Test-Connection" -tags "CI", "RequireSudoOnUnix" {38 BeforeAll {39 $hostName = [System.Net.Dns]::GetHostName()40 $gatewayAddress = GetGatewayAddress41 $publicHostAddress = GetExternalHostAddress -HostName $hostName42 43 $testAddress = if ($publicHostAddress) { $publicHostAddress } else { $gatewayAddress }44 45 $targetName = "localhost"46 $targetAddress = "127.0.0.1"47 $targetAddressIPv6 = "::1"48 $UnreachableAddress = "10.11.12.13"49 50 # under some environments, we can't round trip this and retrieve the real name from the address51 # in this case we will simply use the hostname52 $jobContinues = Start-Job { Test-Connection $using:targetAddress -Repeat }53 }54 55 Context "Ping" {56 It "Default parameter set is 'Ping'" {57 $pingResults = Test-Connection $targetName58 $pingResults.Count | Should -Be 459 60 $result = $pingResults |61 Where-Object Status -EQ 'Success' |62 Select-Object -First 163 64 $result | Should -BeOfType Microsoft.PowerShell.Commands.TestConnectionCommand+PingStatus65 $result.Ping | Should -Be 166 $result.Source | Should -BeExactly $hostName67 $result.Destination | Should -BeExactly $targetName68 $result.Address | Should -BeIn @($targetAddress, $targetAddressIPv6)69 $result.Status | Should -BeExactly "Success"70 $result.Latency | Should -BeOfType long71 $result.Reply | Should -BeOfType System.Net.NetworkInformation.PingReply72 $result.BufferSize | Should -Be 3273 }74 75 It "Count parameter" {76 # Also we explicitly test '-Ping' parameter.77 $result1 = Test-Connection -Ping $targetName -Count 178 $result2 = Test-Connection $targetName -Count 279 80 $result1.Count | Should -Be 181 $result2.Count | Should -Be 282 }83 84 It "Quiet works" {85 $result1 = Test-Connection $targetName -Count 1 -Quiet86 # Ping unreachable address87 $result2 = Test-Connection $UnreachableAddress -Count 1 -Quiet88 89 $result1 | Should -BeTrue90 $result2 | Should -BeFalse91 }92 93 It 'returns false without errors for an unresolvable address when using -Quiet' {94 Test-Connection -Quiet -ErrorAction Stop -Count 1 -TargetName "fakeHost" | Should -BeFalse95 }96 97 It "Ping fake host" {98 { Test-Connection "fakeHost" -Count 1 -ErrorAction Stop } |99 Should -Throw -ErrorId "TestConnectionException,Microsoft.PowerShell.Commands.TestConnectionCommand"100 # Error code = 11001 - Host not found.101 # Error code = -131073 - Invalid address102 $error[0].Exception.InnerException.ErrorCode | Should -BeIn 11, -131073, 11001103 }104 105 It "Force IPv4 with implicit PingOptions" {106 $result = Test-Connection $testAddress -Count 1 -IPv4107 108 $resultStatus = $result.Reply.Status109 if ($resultStatus -eq "Success") {110 $result[0].Address | Should -BeExactly $testAddress111 $result[0].Reply.Options.Ttl | Should -BeLessOrEqual 128112 if ($IsWindows) {113 $result[0].Reply.Options.DontFragment | Should -BeFalse114 }115 }116 else {117 Set-ItResult -Skipped -Because "Ping reply not Success, was: '$resultStatus'"118 }119 }120 121 # In VSTS, address is 0.0.0.0122 # This test is marked as PENDING as .NET Core does not return correct PingOptions from ping request123 It "Force IPv4 with explicit PingOptions" -Pending {124 $result1 = Test-Connection $testAddress -Count 1 -IPv4 -MaxHops 10 -DontFragment125 126 # explicitly go to google dns. this test will pass even if the destination is unreachable127 # it's more about breaking out of the loop128 $result2 = Test-Connection 8.8.8.8 -Count 1 -IPv4 -MaxHops 1 -DontFragment129 130 $result1.Address | Should -BeExactly $testAddress131 $result1.Reply.Options.Ttl | Should -BeLessOrEqual 128132 133 if (!$IsWindows) {134 $result1.Reply.Options.DontFragment | Should -BeFalse135 # Depending on the network configuration any of the following should be returned136 $result2.Status | Should -BeIn "TtlExpired", "TimedOut", "Success"137 } else {138 # This assertion currently fails, see https://github.com/PowerShell/PowerShell/issues/12967139 #$result1.Reply.Options.DontFragment | Should -BeTrue140 141 # We expect 'TtlExpired' but if a router don't reply we get `TimedOut`142 # AzPipelines returns $null143 $result2.Status | Should -BeIn "TtlExpired", "TimedOut", $null144 }145 }146 147 Context 'IPv6 Tests' {148 # IPv6 tests are marked pending because while the functionality is present149 # and works in local testing, it is not functional in CI. There appears to150 # be a lack of or inconsistent support for IPv6 in CI environments.151 It "Allows us to Force IPv6" -Pending {152 $result = Test-Connection $targetName -IPv6 -Count 4 |153 Where-Object Status -EQ Success |154 Select-Object -First 1155 156 $result.Address | Should -BeExactly $targetAddressIPv6157 $result.Reply.Options | Should -Not -BeNullOrEmpty158 }159 160 It 'can convert IPv6 addresses to IPv4 with -IPv4 parameter' -Pending {161 $result = Test-Connection '2001:4860:4860::8888' -IPv4 -Count 4 |162 Where-Object Status -EQ Success |163 Select-Object -First 1164 # Google's DNS can resolve to either address.165 $result.Address.IPAddressToString | Should -BeIn @('8.8.8.8', '8.8.4.4')166 $result.Address.AddressFamily | Should -BeExactly 'InterNetwork'167 }168 169 It 'can convert IPv4 addresses to IPv6 with -IPv6 parameter' -Pending {170 $result = Test-Connection '8.8.8.8' -IPv6 -Count 4 |171 Where-Object Status -EQ Success |172 Select-Object -First 1173 # Google's DNS can resolve to either address.174 $result.Address.IPAddressToString | Should -BeIn @('2001:4860:4860::8888', '2001:4860:4860::8844')175 $result.Address.AddressFamily | Should -BeExactly 'InterNetworkV6'176 }177 }178 179 It "MaxHops Should -Be greater 0" {180 { Test-Connection $targetName -MaxHops 0 } |181 Should -Throw -ErrorId "ParameterArgumentValidationError,Microsoft.PowerShell.Commands.TestConnectionCommand"182 { Test-Connection $targetName -MaxHops -1 } |183 Should -Throw -ErrorId "ParameterArgumentValidationError,Microsoft.PowerShell.Commands.TestConnectionCommand"184 }185 186 It "Count Should -Be greater 0" {187 { Test-Connection $targetName -Count 0 } | Should -Throw -ErrorId "ParameterArgumentValidationError,Microsoft.PowerShell.Commands.TestConnectionCommand"188 { Test-Connection $targetName -Count -1 } | Should -Throw -ErrorId "ParameterArgumentValidationError,Microsoft.PowerShell.Commands.TestConnectionCommand"189 }190 191 It "Delay Should -Be greater 0" {192 { Test-Connection $targetName -Delay 0 } |193 Should -Throw -ErrorId "ParameterArgumentValidationError,Microsoft.PowerShell.Commands.TestConnectionCommand"194 { Test-Connection $targetName -Delay -1 } |195 Should -Throw -ErrorId "ParameterArgumentValidationError,Microsoft.PowerShell.Commands.TestConnectionCommand"196 }197 198 It "Delay works" {199 $result1 = Measure-Command { Test-Connection localhost -Count 2 }200 $result2 = Measure-Command { Test-Connection localhost -Delay 4 -Count 2 }201 202 $result1.TotalSeconds | Should -BeGreaterThan 1203 $result1.TotalSeconds | Should -BeLessThan 3204 $result2.TotalSeconds | Should -BeGreaterThan 4205 }206 207 It "BufferSize Should -Be between 0 and 65500" {208 { Test-Connection $targetName -BufferSize 0 } | Should -Not -Throw209 { Test-Connection $targetName -BufferSize -1 } |210 Should -Throw -ErrorId "ParameterArgumentValidationError,Microsoft.PowerShell.Commands.TestConnectionCommand"211 { Test-Connection $targetName -BufferSize 65501 } |212 Should -Throw -ErrorId "ParameterArgumentValidationError,Microsoft.PowerShell.Commands.TestConnectionCommand"213 }214 215 It "BufferSize works" {216 $result = Test-Connection $targetName -Count 1 -BufferSize 2217 218 $result.BufferSize | Should -Be 2219 }220 221 It "ResolveDestination for address" {222 $result = Test-Connection $targetAddress -ResolveDestination -Count 1223 $resolvedName = [System.Net.DNS]::GetHostEntry($targetAddress).HostName224 225 $result.Destination | Should -BeExactly $resolvedName226 $result.Address | Should -BeExactly $targetAddress227 }228 229 It "ResolveDestination for name" {230 $result = Test-Connection $targetName -ResolveDestination -Count 1231 $resolvedName = [System.Net.DNS]::GetHostByName($targetName).HostName232 233 # PingReply in CoreFX doesn't return ScopeId in IPAddress (Bug?)234 # but GetHostAddresses() returns so remove it.235 $resolvedAddress = ([System.Net.DNS]::GetHostAddresses($resolvedName)[0] -split "%")[0]236 237 $result.Destination | Should -BeExactly $resolvedName238 $result.Address | Should -BeExactly $resolvedAddress239 }240 241 It "TimeOut works" {242 (Measure-Command { Test-Connection $UnreachableAddress -Count 1 -TimeOut 1 }).TotalSeconds |243 Should -BeLessThan 3244 (Measure-Command { Test-Connection $UnreachableAddress -Count 1 -TimeOut 4 }).TotalSeconds |245 Should -BeGreaterThan 3246 }247 248 It "Repeat works" {249 # By default we do 4 ping so for '-Repeat' we expect to get >4 results.250 # Also we should wait >4 seconds before check results but previous tests already did the pause.251 $pingResults = Receive-Job $jobContinues252 Remove-Job $jobContinues -Force253 254 $pingResults.Count | Should -BeGreaterThan 4255 $pingResults[0].Address | Should -BeExactly $targetAddress256 $pingResults.Status | Should -Contain "Success"257 if ($IsWindows) {258 $pingResults.Where( { $_.Status -eq 'Success' }, 'Default', 1 ).BufferSize | Should -Be 32259 }260 }261 262 It "Repeat with explicit false should behave like default ping" {263 # -Repeat:$false should behave the same as not specifying -Repeat264 $pingResults = Test-Connection $targetAddress -Repeat:$false265 266 # Should get exactly 4 pings (the default Count value)267 $pingResults.Count | Should -Be 4268 $pingResults[0].Address | Should -BeExactly $targetAddress269 }270 }271 272 Context "MTUSizeDetect" {273 It "MTUSizeDetect works" {274 275 $platform = Get-PlatformInfo276 $platform | Out-String -Stream | Write-Verbose -Verbose277 278 if ($platform.platform -match 'sles' -and $platform.version -match '15') {279 Set-ItResult -Skipped -Because "MTUSizeDetect is not supported on OpenSUSE 15"280 return281 }282 283 # if we time out, that's a terminating exception, so set erroraction to continue284 $result = Test-Connection $testAddress -MtuSize -ErrorVariable eVar -ErrorAction Continue285 286 if ($eVar.TargetObject.Status -eq "TimedOut") {287 Set-ItResult -skipped -because "timed out"288 }289 else {290 $result | Should -BeOfType Microsoft.PowerShell.Commands.TestConnectionCommand+PingMtuStatus291 $result.Destination | Should -BeExactly $testAddress292 $result.Status | Should -BeExactly "Success"293 $result.MtuSize | Should -BeGreaterThan 0294 }295 }296 297 It "Quiet works" {298 $result = Test-Connection $gatewayAddress -MtuSize -Quiet299 300 $result | Should -BeOfType Int32301 $result | Should -BeGreaterThan 0302 }303 304 It "MtuSize with explicit false should behave like default ping" {305 # -MtuSize:$false should behave the same as not specifying -MtuSize (default ping)306 $pingResults = Test-Connection $targetAddress -MtuSize:$false307 308 # Should return PingStatus, not PingMtuStatus309 $pingResults[0] | Should -BeOfType Microsoft.PowerShell.Commands.TestConnectionCommand+PingStatus310 # Should get 4 pings (the default Count value)311 $pingResults.Count | Should -Be 4312 }313 }314 315 Context "TraceRoute" {316 It "TraceRoute works" -Pending {317 # real address is an ipv4 address, so force IPv4318 $result = Test-Connection $testAddress -TraceRoute -IPv4319 320 $result[0] | Should -BeOfType Microsoft.PowerShell.Commands.TestConnectionCommand+TraceStatus321 $result[0].Source | Should -BeExactly $testAddress322 $result[0].TargetAddress | Should -BeExactly $testAddress323 $result[0].Target | Should -BeExactly $testAddress324 $result[0].Hop | Should -Be 1325 $result[0].HopAddress.IPAddressToString | Should -BeExactly $testAddress326 $result[0].Status | Should -BeExactly "Success"327 if (!$IsWindows) {328 $result[0].Reply.Buffer.Count | Should -Match '^0$|^32$'329 } else {330 $result[0].Reply.Buffer.Count | Should -Be 32331 }332 }333 334 It "Quiet works" {335 $result = Test-Connection localhost -TraceRoute -Quiet336 337 $result | Should -BeTrue338 }339 340 It 'writes an error if MaxHops is exceeded during -Traceroute' {341 { Test-Connection 8.8.8.8 -Traceroute -MaxHops 2 -ErrorAction Stop } |342 Should -Throw -ErrorId 'TestConnectionException,Microsoft.PowerShell.Commands.TestConnectionCommand'343 }344 345 It 'returns false without error if MaxHops is exceeded during -Traceroute -Quiet' {346 Test-Connection 8.8.8.8 -Traceroute -MaxHops 2 -Quiet | Should -BeFalse347 }348 349 It 'has a non-null value for Destination for reachable hosts' {350 $results = Test-Connection 127.0.0.1 -Traceroute351 352 $results.Hostname | Should -Not -BeNullOrEmpty353 }354 355 It "Traceroute with explicit false should behave like default ping" {356 # -Traceroute:$false should behave the same as not specifying -Traceroute (default ping)357 $pingResults = Test-Connection $targetAddress -Traceroute:$false358 359 # Should return PingStatus, not TraceStatus360 $pingResults[0] | Should -BeOfType Microsoft.PowerShell.Commands.TestConnectionCommand+PingStatus361 # Should get 4 pings (the default Count value)362 $pingResults.Count | Should -Be 4363 }364 }365}366 367Describe "Connection" -Tag "CI", "RequireAdminOnWindows" {368 BeforeAll {369 # Ensure the local host listen on port 80370 $WebListener = Start-WebListener371 $UnreachableAddress = "10.11.12.13"372 }373 374 It "Test connection to local host on working port" {375 Test-Connection '127.0.0.1' -TcpPort $WebListener.HttpPort | Should -BeTrue376 }377 378 It "Test connection to unreachable host port 80" {379 Test-Connection $UnreachableAddress -TcpPort 80 -TimeOut 1 | Should -BeFalse380 }381 382 It "Test detailed connection to local host on working port" {383 $result = Test-Connection '127.0.0.1' -TcpPort $WebListener.HttpPort -Detailed384 385 $result.Count | Should -Be 1386 $result[0].Id | Should -BeExactly 1387 $result[0].TargetAddress | Should -BeExactly '127.0.0.1'388 $result[0].Port | Should -Be $WebListener.HttpPort389 $result[0].Latency | Should -BeGreaterOrEqual 0390 $result[0].Connected | Should -BeTrue391 $result[0].Status | Should -BeExactly 'Success'392 }393 394 It "Test detailed connection to local host on working port with modified count" {395 $result = Test-Connection '127.0.0.1' -TcpPort $WebListener.HttpPort -Detailed -Count 2396 397 $result.Count | Should -Be 2398 $result[0].Id | Should -BeExactly 1399 $result[0].TargetAddress | Should -BeExactly '127.0.0.1'400 $result[0].Port | Should -Be $WebListener.HttpPort401 $result[0].Latency | Should -BeGreaterOrEqual 0402 $result[0].Connected | Should -BeTrue403 $result[0].Status | Should -BeExactly 'Success'404 }405 406 It "Test detailed connection to unreachable host port 80" {407 $result = Test-Connection $UnreachableAddress -TcpPort 80 -Detailed -TimeOut 1408 409 $result.Count | Should -Be 1410 $result[0].Id | Should -BeExactly 1411 $result[0].TargetAddress | Should -BeExactly $UnreachableAddress412 $result[0].Port | Should -Be 80413 $result[0].Latency | Should -BeExactly 0414 $result[0].Connected | Should -BeFalse415 $result[0].Status | Should -Not -BeExactly 'Success'416 }417}418 419Describe "Test-Connection should run in the default synchronization context (threadpool)" -Tag "CI" {420 It "Test-Connection works after constructing a WindowsForm object" -Skip:(!$IsWindows) {421 $pwsh = Join-Path $PSHOME "pwsh"422 $pingResults = & $pwsh -NoProfile {423 Add-Type -AssemblyName System.Windows.Forms424 $null = New-Object System.Windows.Forms.Form425 Test-Connection localhost426 }427 428 $pingResults.Length | Should -Be 4429 $result = $pingResults | Select-Object -First 1430 431 $result.Ping | Should -Be 1432 $result.Source | Should -BeExactly ([System.Net.Dns]::GetHostName())433 $result.Destination | Should -BeExactly localhost434 $result.Latency | Should -BeOfType "long"435 $result.Reply.Status | Should -BeExactly "Success"436 $result.BufferSize | Should -Be 32437 }438}439 