Skip to content
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

[QUIC] Add ShutdownCompleted method and fix receive and shutdown behavior in tests #50930

Merged
merged 17 commits into from
Apr 19, 2021

Conversation

CarnaViire
Copy link
Member

Related to microsoft/msquic#1384

  • SHUTDOWN_WRITE_COMPLETED event means we've only sent the shutdown to peer, SHUTDOWN_COMPLETED means peer has received and acked it
  • after msquic fix mentioned above, SHUTDOWN_COMPLETED respects pending RECEIVE events so it only appear after we've read all the data. However, client and server should communicate on application level on when connection is safe to close. That's because there is no way to say when peer is done processing the data after acking SHUTDOWN_COMPLETED on transport level -- and unexpected connection closing may result in data loss.
  • it seems that if we write, then read, we should send shutdown, wait for SHUTDOWN_WRITE_COMPLETED, and only after that start reading
  • msquic can aggregate received data, so we cannot depend on receiving the same set of buffers we've sent, but only on receiving the same total aggregated data.
  • stream that is opened by client but left unaccepted by server may cause AccessViolationException in its Finalizer. Explicitly closing the connections seems to help, but the problem should still be investigated, we should have a meaningful exception instead of AccessViolationException (for code example see QuicStreamTests.GetStreamIdWithoutStartWorks)
  • we never changed Connected property of MsQuicConnection to false after shutting down, so I've done that inside HandleEventShutdownComplete

This PR fixed QuicStreamTests.BasicTest and QuicStreamTests.MultipleReadsAndWrites.

QuicConnectionTests.AcceptStream_ConnectionAborted_ByClient_Throws started to fail after updating msquic from microsoft/msquic@cc104e8 to microsoft/msquic@8e21db7. I haven't investigated it yet, will add to #49157.

QuicStreamTests.LargeDataSentAndReceived and QuicStreamTests.ReadWrite_Random_Success still have issues with bytes mixing in the middle of data -- if run together with all the tests. They won't fail if executed alone or all test executed sequentially. The minimal repro for the issue to show should be to combine QuicStreamTests.LargeDataSentAndReceived and MsQuicTests.CallDifferentWriteMethodsWorks in a single test as two concurrent tasks. I haven't investigated it further yet.

Contributes to #49157

@ghost
Copy link

ghost commented Apr 8, 2021

Tagging subscribers to this area: @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

Issue Details

Related to microsoft/msquic#1384

  • SHUTDOWN_WRITE_COMPLETED event means we've only sent the shutdown to peer, SHUTDOWN_COMPLETED means peer has received and acked it
  • after msquic fix mentioned above, SHUTDOWN_COMPLETED respects pending RECEIVE events so it only appear after we've read all the data. However, client and server should communicate on application level on when connection is safe to close. That's because there is no way to say when peer is done processing the data after acking SHUTDOWN_COMPLETED on transport level -- and unexpected connection closing may result in data loss.
  • it seems that if we write, then read, we should send shutdown, wait for SHUTDOWN_WRITE_COMPLETED, and only after that start reading
  • msquic can aggregate received data, so we cannot depend on receiving the same set of buffers we've sent, but only on receiving the same total aggregated data.
  • stream that is opened by client but left unaccepted by server may cause AccessViolationException in its Finalizer. Explicitly closing the connections seems to help, but the problem should still be investigated, we should have a meaningful exception instead of AccessViolationException (for code example see QuicStreamTests.GetStreamIdWithoutStartWorks)
  • we never changed Connected property of MsQuicConnection to false after shutting down, so I've done that inside HandleEventShutdownComplete

This PR fixed QuicStreamTests.BasicTest and QuicStreamTests.MultipleReadsAndWrites.

QuicConnectionTests.AcceptStream_ConnectionAborted_ByClient_Throws started to fail after updating msquic from microsoft/msquic@cc104e8 to microsoft/msquic@8e21db7. I haven't investigated it yet, will add to #49157.

QuicStreamTests.LargeDataSentAndReceived and QuicStreamTests.ReadWrite_Random_Success still have issues with bytes mixing in the middle of data -- if run together with all the tests. They won't fail if executed alone or all test executed sequentially. The minimal repro for the issue to show should be to combine QuicStreamTests.LargeDataSentAndReceived and MsQuicTests.CallDifferentWriteMethodsWorks in a single test as two concurrent tasks. I haven't investigated it further yet.

Contributes to #49157

Author: CarnaViire
Assignees: -
Labels:

area-System.Net.Quic

Milestone: -

@dotnet-issue-labeler
Copy link

Note regarding the new-api-needs-documentation label:

This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, to please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change.

@geoffkizer
Copy link
Contributor

We are still discussing the API design here, right? #756

I'm fine to get this in if it unblocks tests, but we may end up reworking the API here later.

@CarnaViire
Copy link
Member Author

@geoffkizer It's totally fine to rework APIs later, I understand that. My goal is to make tests working correctly as even basic ones didn't work before. Without green tests it will be harder to rework stuff 😄

Copy link
Member

@ManickaP ManickaP left a comment

Choose a reason for hiding this comment

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

Looks good, thanks!
I give it one more go once the questions are solved.

@@ -228,84 +174,60 @@ public async Task GetStreamIdWithoutStartWorks()

using QuicStream clientStream = clientConnection.OpenBidirectionalStream();
Assert.Equal(0, clientStream.StreamId);

// TODO: stream that is opened by client but left unaccepted by server may cause AccessViolationException in its Finalizer
Copy link
Member

Choose a reason for hiding this comment

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

AccessViolationException is always wrong (memory corruption), we should not be causing that in any case.
By any chance do you have details of this exception? Dump maybe?

continue;
}

Console.WriteLine($"Wrong data starting from pos={i}");
Copy link
Member

Choose a reason for hiding this comment

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

If you need to log in test, you should rather use ITestOutputHelper, console output gets suppressed by xUnit.

public HttpClientHandlerTestBase(ITestOutputHelper output)

Copy link
Member Author

Choose a reason for hiding this comment

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

ITestOutputHelper doesn't output to console if the tests are run from the command line... as the method I've added is more an extended assert than just some test logging, I guess it will be more useful then to use an Assert method that has a message parameter.

Copy link
Member

@ManickaP ManickaP left a comment

Choose a reason for hiding this comment

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

LGTM, thanks.

@CarnaViire CarnaViire merged commit 01d4dca into dotnet:main Apr 19, 2021
@ghost ghost locked as resolved and limited conversation to collaborators May 19, 2021
@karelz karelz added this to the 6.0.0 milestone May 20, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants