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

change(tests): use OS-assigned unallocated ports for getting random known ports #5607

Merged
merged 20 commits into from
Nov 10, 2022

Conversation

arya2
Copy link
Contributor

@arya2 arya2 commented Nov 10, 2022

Motivation

The random_known_port may return an allocated port, causing a test error.

This PR reduces the likelihood of those errors by having the OS find a port that is unallocated at the time that random_known_port is called, and by broadening the range of possible ports.

Solution

  • Create a TcpListener with port 0 to find an unallocated port.
  • Read the port number of new socket and drop the listener to close it.

Review

Reviewer Checklist

  • Will the PR name make sense to users?
    • Does it need extra CHANGELOG info? (new features, breaking changes, large changes)
  • Are the PR labels correct?
  • Does the code do what the ticket and PR says?
  • How do you know it works? Does it have tests?

@arya2 arya2 added A-rust Area: Updates to Rust code P-Optional ✨ C-testing Category: These are tests C-trivial Category: A trivial change that is not worth mentioning in the CHANGELOG labels Nov 10, 2022
@arya2 arya2 requested a review from teor2345 November 10, 2022 00:02
@arya2 arya2 self-assigned this Nov 10, 2022
@github-actions github-actions bot added the C-enhancement Category: This is an improvement label Nov 10, 2022
Copy link
Contributor

@teor2345 teor2345 left a comment

Choose a reason for hiding this comment

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

I'm happy to try this, and if it ends up not working on Windows, or in some tests, we can go back to using a numerically random port selection.

But every test it does work for is one less test that will randomly fail.

It's impossible to do this check in a reliable, cross-platform way.

Here's some background for that comment:

Windows sometimes waits a few minutes before allowing port reuse:
https://serverfault.com/questions/541070/linux-tcp-source-port-reuse-and-delay/609829#609829

On Linux and macOS, it would be easier if we set the SO_REUSEADDR option on Zebra's ports, but that's impossible for tokio and std Rust ports, because they don't expose that option. (Maybe they've improved the API since?)

https://programmer.group/so_reuseaddr-and-so_reuseport-socket-options-for-tcp-ip-programming.html

zebra-test/src/net.rs Show resolved Hide resolved
@arya2
Copy link
Contributor Author

arya2 commented Nov 10, 2022

Windows sometimes waits a few minutes before allowing port reuse

It's a 2-minute default TcpTimedWaitDelay. That makes sense.

Tokio seems to support SO_REUSEADDR (https://docs.rs/tokio/latest/tokio/net/struct.TcpListener.html#implementations) but that's not cross-platform or supported by Rust std.

We can close this now or put it under #[cfg(any(target_os = "macos", target_os = "linux"))] if the tests pass on MacOS.

@codecov
Copy link

codecov bot commented Nov 10, 2022

Codecov Report

Merging #5607 (6dd307e) into main (c447b03) will increase coverage by 0.11%.
The diff coverage is 81.74%.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5607      +/-   ##
==========================================
+ Coverage   78.67%   78.79%   +0.11%     
==========================================
  Files         305      305              
  Lines       38211    38320     +109     
==========================================
+ Hits        30064    30195     +131     
+ Misses       8147     8125      -22     

@teor2345
Copy link
Contributor

Tokio seems to support SO_REUSEADDR (https://docs.rs/tokio/latest/tokio/net/struct.TcpListener.html#implementations) but that's not cross-platform or supported by Rust std.

I think Rust std added it recently as well?

https://github.com/rust-lang/rust/blob/1b225414f325593f974c6b41e671a0a0dc5d7d5e/library/std/src/sys_common/net.rs#L402-L403

@teor2345
Copy link
Contributor

We can close this now or put it under #[cfg(any(target_os = "macos", target_os = "linux"))] if the tests pass on MacOS.

It seems to work, so let's use the same #[cfg(not(windows))] logic as Rust std?

Then we can keep the old code and use it for Windows.

@arya2
Copy link
Contributor Author

arya2 commented Nov 10, 2022

I think Rust std added it recently as well?

That explains why this worked.

@arya2 arya2 marked this pull request as ready for review November 10, 2022 02:32
@arya2 arya2 requested a review from a team as a code owner November 10, 2022 02:32
Copy link
Contributor

@teor2345 teor2345 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, but let's merge it separately from #5589, in case we need to revert?

Base automatically changed from update-ci-and-long-running-tests to main November 10, 2022 03:40
@mergify mergify bot requested a review from a team as a code owner November 10, 2022 03:40
@teor2345
Copy link
Contributor

@Mergifyio update

@mergify
Copy link
Contributor

mergify bot commented Nov 10, 2022

update

✅ Branch has been successfully updated

@dconnolly dconnolly changed the title change(tests) use OS-assigned unallocated ports for getting random known ports change(tests): use OS-assigned unallocated ports for getting random known ports Nov 10, 2022
@mergify mergify bot merged commit beb45fc into main Nov 10, 2022
@mergify mergify bot deleted the use-os-assigned-random-known-port branch November 10, 2022 23:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-rust Area: Updates to Rust code C-enhancement Category: This is an improvement C-testing Category: These are tests C-trivial Category: A trivial change that is not worth mentioning in the CHANGELOG
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants