Skip to content

globally unique port allocation for unittests #5865

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

Conversation

alexpyattaev
Copy link

Problem

We can not rely on port ranges not intersecting during test runs, and we need bindings with fixed offsets for QUIC ports.
This PR ensures all bindings use non-overlapping port ranges.

Summary of Changes

  • Added "port range allocator" logic that works with nextest

@alexpyattaev alexpyattaev changed the title globally unique port allocation for unittests and such globally unique port allocation for unittests Apr 17, 2025
@alexpyattaev alexpyattaev marked this pull request as ready for review April 17, 2025 14:31
let bind_ip_addr = IpAddr::V4(Ipv4Addr::UNSPECIFIED);
let port_range = (MIN_PORT_RANGE, MAX_PORT_RANGE);

let bind_ip_addr = IpAddr::V4(Ipv4Addr::LOCALHOST);

Choose a reason for hiding this comment

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

do we only use TestValidator locally? never across machines?

Copy link
Author

Choose a reason for hiding this comment

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

It can run remotely but was never intended to. We use it in tests for SVM programs in CI (which run locally). I believe some devs use it for testing too, but also in a local context. Finally, this is just the default config for it anyway, one can override it with CLA if needed.

Choose a reason for hiding this comment

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

looks like solana-test-validator cli defauls bind_address to 0.0.0.0. See:

agave/validator/src/cli.rs

Lines 860 to 868 in f0032eb

.arg(
Arg::with_name("bind_address")
.long("bind-address")
.value_name("HOST")
.takes_value(true)
.validator(solana_net_utils::is_host)
.default_value("0.0.0.0")
.help("IP address to bind the validator ports [default: 0.0.0.0]"),
)
. and then used here:
let bind_address = matches.value_of("bind_address").map(|bind_address| {
solana_net_utils::parse_host(bind_address).unwrap_or_else(|err| {
eprintln!("Failed to parse --bind-address: {err}");
exit(1);
})
});

and set again here:

if let Some(bind_address) = bind_address {
genesis.bind_ip_addr(bind_address);
}

Would it make sense to make the default cli bind to localhost since bindip_addr in TestValidatorNodeConfig::Default() gets overwritten?

Copy link
Author

Choose a reason for hiding this comment

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

Yes, you are on point there, already PR'd that one #5862

Comment on lines +98 to +101
#[cfg(not(debug_assertions))]
let port_range = solana_net_utils::VALIDATOR_PORT_RANGE;
#[cfg(debug_assertions)]
let port_range = localhost_port_range_for_tests();

Choose a reason for hiding this comment

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

maybe a dumbn question, but when we run tests in CI, are they compiled with --release or --debug?

Copy link
Author

Choose a reason for hiding this comment

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

CI runs with debug assertions. That is kinda the point:) This is unrelated to whether optimizer is enabled or not. I guess we could gate it on dev-context-only-utils as well, I am honestly not sure what the best way here is.

Choose a reason for hiding this comment

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

ya tbh I think gating on dev-context-only-utils would be preferable. That way you have to explicitly set the feature to get the desired, limited port range. not 100% sure though, maybe @bw-solana has a better insight here?

Copy link
Author

Choose a reason for hiding this comment

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

Yeah that is possible but will be more invasive as we would need to manually activate the feature in all crates that pull test-validator for their unittests. It would also be mighty unobvious as to why the feature is enabled if it does not gate any functions.

Choose a reason for hiding this comment

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

ahh good point. ok i am fine leaving it as is then

@codecov-commenter
Copy link

Codecov Report

Attention: Patch coverage is 76.92308% with 21 lines in your changes missing coverage. Please review.

Project coverage is 83.0%. Comparing base (36b3586) to head (d239292).
Report is 6 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff            @@
##           master    #5865     +/-   ##
=========================================
- Coverage    83.0%    83.0%   -0.1%     
=========================================
  Files         828      829      +1     
  Lines      375858   375910     +52     
=========================================
+ Hits       312113   312153     +40     
- Misses      63745    63757     +12     
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@gregcusack gregcusack self-requested a review April 18, 2025 17:16
Copy link

@gregcusack gregcusack left a comment

Choose a reason for hiding this comment

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

lgtm!

@alexpyattaev alexpyattaev merged commit a0d37d5 into anza-xyz:master Apr 18, 2025
30 checks passed
@alexpyattaev alexpyattaev deleted the global_port_allocation_for_tests branch April 19, 2025 10:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants