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

Improve errors and testing using NIOTS #588

Merged
merged 9 commits into from
Jun 1, 2022
Merged

Conversation

Lukasa
Copy link
Collaborator

@Lukasa Lukasa commented May 31, 2022

Motivation

Currently error reporting with NIO Transport Services is often sub-par.
This occurs because the Network.framework connections may enter the
waiting state until the network connectivity state changes. We were not
watching for the user event that contains the error in that state, so if
we timed out in that state we'd just give a generic timeout error,
instead of telling the user anything more detailed.

Additionally, several of our tests assume that failure will be fast, but
in NIO Transport Services we will enter that .waiting state. This is
reasonable, as changed network connections may make a connection that
was not succeeding suddenly viable. However, it's inconvenient for
testing, where we're mostly interested in confirming that the error path
works as expected.

Modifications

  • Add an observer of the WaitingForConnectivity event that records it
    into our state machine for later reporting.
  • Add support for disabling waiting for connectivity for testing
    purposes.
  • Add annotations to several tests to stop them waiting for
    connectivity.

Results

Faster tests, better coverage, better errors for our users.

@Lukasa Lukasa added the semver/minor For PRs that when merged cause a bump of the minor version, ie. 1.x.0 -> 1.(x+1).0 label May 31, 2022
@Lukasa Lukasa requested review from dnadoba and fabianfett May 31, 2022 16:49
Motivation

Currently error reporting with NIO Transport Services is often sub-par.
This occurs because the Network.framework connections may enter the
waiting state until the network connectivity state changes. We were not
watching for the user event that contains the error in that state, so if
we timed out in that state we'd just give a generic timeout error,
instead of telling the user anything more detailed.

Additionally, several of our tests assume that failure will be fast, but
in NIO Transport Services we will enter that .waiting state. This is
reasonable, as changed network connections may make a connection that
was not succeeding suddenly viable. However, it's inconvenient for
testing, where we're mostly interested in confirming that the error path
works as expected.

Modifications

- Add an observer of the WaitingForConnectivity event that records it
  into our state machine for later reporting.
- Add support for disabling waiting for connectivity for testing
  purposes.
- Add annotations to several tests to stop them waiting for
  connectivity.

Results

Faster tests, better coverage, better errors for our users.
Copy link
Collaborator

@dnadoba dnadoba left a comment

Choose a reason for hiding this comment

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

Great patch, only two minor suggestions

Tests/AsyncHTTPClientTests/HTTPClientTests.swift Outdated Show resolved Hide resolved
Copy link
Member

@fabianfett fabianfett left a comment

Choose a reason for hiding this comment

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

This looks great. And I'm sure that the new code path is hit plenty in more complex scenarios. However I would love to see two more test cases:

  1. Unit style: the new NWWaitingHandler in an EmbeddedChannel. Is the callout triggered.
  2. An explicit test: NWError is reported if networkFrameworkWaitForConnectivity is turned on. Currently this is implicit in testAvoidLeakingTLSHandshakeCompletionPromise.

Doing those in a follow up is totally fine with me.

}

func handlerRemoved(context: ChannelHandlerContext) {
self.requester = nil
Copy link
Member

Choose a reason for hiding this comment

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

just out of interest, why do we release the requester here explicitly? Could there be a race that we get an inbound event after we have been removed from the pipeline?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

No, this was initially defensive to prevent requesters living an excessively long time. However, now that I think about it I suspect this is unnecessarily defensive, as nothing else is holding onto this handler.

@Lukasa
Copy link
Collaborator Author

Lukasa commented Jun 1, 2022

I've addressed (2), I'm going to tackle (1) in the future because it requires me to make an enhancement to NIOTS.

@Lukasa
Copy link
Collaborator Author

Lukasa commented Jun 1, 2022

5.7/nightly failures are Sendable related, merging over them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
semver/minor For PRs that when merged cause a bump of the minor version, ie. 1.x.0 -> 1.(x+1).0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants