Skip to content

Test-Connection - Improve Logic and Output #10697

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 65 commits into from
Nov 18, 2019

Conversation

vexx32
Copy link
Collaborator

@vexx32 vexx32 commented Oct 3, 2019

PR Summary

Refactor Test-Connection to provide unit-based output with clearer formatting and more useful traceroute timing information.

  • Uses SendAsync() to send pings and adds event handler to permit Ctrl+C to cancel the cmdlet operation mid-ping (great for giving up on a long timeout).
  • Refactor output; both regular -Ping and -TraceRoute actions output one object per received ping, formatted to accommodate as much information as possible.
  • Refactor -Traceroute methodology to use 4 pings instead of 3:
    • 1-3 initial "discovery" pings with low TTL to the final destination to find the router at that hop point (not displayed in output). First ping to come back with TtlExpired is used to target the rest of the pings.
      • On Unix, TtlExpired is never reported, so we skip this step completely and just target all pings at the final destination.
    • 3 followup pings to that router directly so we get proper latency and status information from the router (all rendered in output).
    • This fixes an outstanding issue where traceroutes could not provide latency information on intermediate hops.
  • Slight refactor for MtuSize detection to allow it to work correctly on Unix.
  • Use new class types for all output in order to better provide easy access to displayed information.
  • Update ValidateSet attribute on -MaxHops to reflect underlying API limitations (0 is not a valid argument for PingOptions' TTL)
  • Fix long-standing issue with -Traceroute where -MaxHops is a valid input parameter, but is completely ignored. New behaviour is to write an error if the destination cannot be reached within the set value for -MaxHops, or return $false if also specifying -Quiet.
  • Fixed an issue where -IPv4 and -IPv6 were completely ignored if you supplied a valid address from the other family. Resolution is to check the AddressFamily, and if it doesn't match the provided switch, pull the host entry and find an address matching the requested family to use.
    • Added some additional IPv6 tests. After running all the IPv6 tests in CI (including those originally marked -Pending) I think it best we leave them disabled. I've verified the features work in Windows 10 and Ubuntu under WSL, but Azures CI apparently doesn't have great IPv6 support, so it's a very mixed bag on what comes back for those tests. We can reenable them in future if there are improvements or alterations to CI config that might improve their reliability there.
  • Renamed switches:
    • -Continues => -Repeat (Alias applied to maintain compatibility)
    • -MtuSizeDetect => -MtuSize (Alias applied here also)

PR Context

RFC: PowerShell/PowerShell-RFC#172

Resolves #9235

Resolves #7685

PR Checklist

vexx32 added 22 commits August 24, 2019 00:48
Rather than instantiate a new Ping() every time,
we can store it in a readonly field and just call Send() as needed.
This uses the SendAsync() method with a manual reset shim,
allowing us to cancel the ping if needed.
For example, in the case of StopProcessing() being called,
the cmdlet can properly process the request and halt processing,
throwing the correct errors as needed.
All output is provided as soon as the PingReply is received,
using a new class to format the output (PingStatus).
Also added a FormatView for PingStatus.
🎨 Update formatview definitions to include traceroutes
♻️ move formatviewdefintions to proper location in file
♻️ Small amount of cleanup
@vexx32 vexx32 added the WG-Cmdlets-Management cmdlets in the Microsoft.PowerShell.Management module label Oct 3, 2019
Errors out when trying to SendPingAsync() too quickly in succession
@vexx32
Copy link
Collaborator Author

vexx32 commented Oct 4, 2019

@SteveL-MSFT Samples of output:

Default -Ping Output

image

-Traceroute Output

image

-Traceroute -ResolveDestination Output

image

-MtuSize Output

image

-IPv6 (with IPv4 address)

image

-IPv4 (with IPv6 address)

image

@vexx32 vexx32 force-pushed the TestConnection/BetterOutput branch from 6fbafa7 to cf7d523 Compare October 4, 2019 03:39
@vexx32
Copy link
Collaborator Author

vexx32 commented Nov 11, 2019

@SteveL-MSFT @iSazonov @TravisEz13 I checked https://github.com/dotnet/corefx/issues/28934 recently and saw they pushed it back to 5.0 for now.

Can we make a judgement call on the way forward here? This implementation, while doing more work than it should need to, is at least (in my opinion) more usable and functional on every platform than the existing implementation, and makes use of the most effective parts of the API surface currently available.

In my opinion, having this in PS7 to have a more user-friendly cmdlet would be better than waiting until .NET 5 for the API to be fixed. 🙂

I'm more than happy to do the later rewrite when the .NET Core team (finally) fix their Ping APIs. 😁

@SteveL-MSFT
Copy link
Member

@vexx32 I don't think we should hold this waiting on .NET (should open a new issue linked to corefx, I can tag it for vNext). I'll spend some time reviewing this today.

@vexx32
Copy link
Collaborator Author

vexx32 commented Nov 11, 2019

Went back through ping / test-connection issues and found this one:

#7576

I think this PR addresses that as well 🤔

@vexx32
Copy link
Collaborator Author

vexx32 commented Nov 11, 2019

@SteveL-MSFT looks like we've been tracking this in #4240; I think we can continue to track this there. 🙂

Comment on lines +1649 to +1650
.AddHeader(Alignment.Right, label: "Latency(ms)", width: 7)
.AddHeader(Alignment.Right, label: "BufferSize(B)", width: 10)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is formatting, we can make changes in the future based on user feedback

@ghost ghost added Waiting on Author The PR was reviewed and requires changes or comments from the author before being accept and removed Waiting on Author The PR was reviewed and requires changes or comments from the author before being accept labels Nov 11, 2019
@vexx32
Copy link
Collaborator Author

vexx32 commented Nov 15, 2019

@PoshChan please retry windows

@PoshChan
Copy link
Collaborator

@vexx32, successfully started retry of PowerShell-CI-Windows

/// <summary>
/// Gets the target address of the ping.
/// </summary>
public IPAddress? Address { get => Reply.Status == IPStatus.Success ? Reply.Address : null; }
Copy link
Collaborator Author

@vexx32 vexx32 Nov 15, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting. Querying the Reply.Address in the latest build I got from CI appears to be... broken.

 PS>  $a.Reply.Address

OverloadDefinitions
-------------------
System.Object&, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e Address(int )

I'll have to make sure I rebase this PR and see if this is resolved in a later .NET core preview. Querying the address in different ways does work, but something is a bit screwy with the auto-property. Gonna look into this probably this evening, should hopefully not be a complex fix. 🤞

(This is a bit of an oddity because this actually causes it to be hidden in the formatter, which is just super odd.)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FIgured it out. Pushing a fix.

@@ -1,8 +1,12 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vexx32, your last commit had 1 failures in PowerShell-CI-windows
Test-Connection.Ping.Force IPv4 with explicit PingOptions

Expected $true, but got $false.
at <ScriptBlock>, D:\a\1\s\test\powershell\Modules\Microsoft.PowerShell.Management\Test-Connection.Tests.ps1: line 103
103:                 $result1.Reply.Options.DontFragment | Should -BeTrue

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SteveL-MSFT I have confirmed with a manual test that this regression comes from .NET Core itself -- a manual use of the Ping.Send() or SendAsync() exhibits this behaviour where a DontFragment setting is ignored (or at least not returned as set from the ping reply).

This appears to be a new regression since the 3.0 release.

This API is... getting more fragile. 😕

Marking this test as pending until this gets fixed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did someone file an issue?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a note on the existing tracking issue in coreFX for the Ping APIs.

One of the coreFX folx asked if I could set breakpoints and check what's going on. I may give it a stab, but I'm not really sure what I'm doing there tbh. CoreFX is a very large project, and I'm not familiar with how to work with it in a debugging context, or even build it at all.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I create an additional tracking issue here as well? We already have a tracking issue for the APIs used by this cmdlet in general I think I can add a note to.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm good as long as it's tracked somehow.

PingOptions are not returned from .NET Core api as expected.

Test marked as pending for now.
@TravisEz13 TravisEz13 changed the title Test-Connection - Improve Logic and Output Test-Connection - Improve Logic and Output Nov 18, 2019
@TravisEz13 TravisEz13 merged commit 4408379 into PowerShell:master Nov 18, 2019
@vexx32 vexx32 deleted the TestConnection/BetterOutput branch November 18, 2019 19:39
@iSazonov
Copy link
Collaborator

Should we document anything (the check box is set)?

@vexx32
Copy link
Collaborator Author

vexx32 commented Nov 19, 2019

Yeah, we changed quite a bit in terms of the shape of the output in pretty much all the cases here.

Doc issue is MicrosoftDocs/PowerShell-Docs#4987 - I'll link it in the PR description as well. Thanks for the reminder! 💖

@ghost
Copy link

ghost commented Nov 21, 2019

🎉v7.0.0-preview.6 has been released which incorporates this pull request.:tada:

Handy links:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Breaking-Change breaking change that may affect users CL-BreakingChange Indicates that a PR should be marked as a breaking change in the Change Log CL-General Indicates that a PR should be marked as a general cmdlet change in the Change Log
Projects
None yet
6 participants