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

Test refactor proposal #909

Merged
merged 22 commits into from
Mar 22, 2024
Merged

Test refactor proposal #909

merged 22 commits into from
Mar 22, 2024

Conversation

Jake-Shadle
Copy link
Collaborator

This is a first pass at showing a different way to write integration tests, ie, tests that use multiple components together.

  1. An incremental step at changing APIs and tests either binding sockets ahead of time that are then passed to the APIs, or for the proxy case, not binding and using the port returned from run_server in most cases. While the available_addr function is still used, this is first step at completely removing it. While it works in most cases, it's actually not guaranteed to be 100% reliable as there is nothing stopping the OS of assigning the port to another call causing a bind failure for the second test to use it, so eventually removing this will entirely remove bind-related flakiness.
  2. Moves the logic of spinning up the various components into separate pieces from the CLI interface to them. The goal of this change is to start to tease apart the user interface (CLI) portions from the actual code that is run, to make writing tests easier. This also completely removes the notion of unwrapping the RuntimeConfig from the Admin inside various places in favor of passing in the actual config for the component in a type safe manner. For instance previously running the manage command with a relay server set would panic as .unwrap_agent() was used inside MdsClient
  3. Move tests out to a separate crate. This is done so that common test code can be placed in the library and new dependencies can be used etc so that (eventually) test helper code in test.rs can be removed from quilkin itself
  4. Make "unit" tests integration tests. While iterating on quilkin I've noticed that the there is a lot of test code in the library that shouldn't be there, as it means changing unit tests needs to compile quilkin (including all the test code) instead of just being able to recompile and relink the single test binary. I'm not sure why it was done this way but I suspect it might be due to...
  5. Add helper for test tracing. Currently the tracing-test dev dependency can be used to add a proc macro to a test function to get trace output to be outputted on test failure. Unfortunately this macro has no way to filter messages other than allowing only message from teh current crate, which makes integration tests useless as then no trace messages from quilkin itself will be captured, or else no filtering either by crate nor level (the level used in the tracing-test is trace!) which results in massive spam from eg hyper/h2 that makes test tracing from integration tests utterly useless. So I just made a simple trace_test! macro that makes it trivial to capture only the output we care about in tests to make debugging slightly more tolerable
  6. The qt (quilkin-test) crate also introduces a proposed API to make writing integration tests easier, removing a lot of boilerplate by creating various components with minimal necessary configuration that can then be hooked together with dependencies. An example of this is shown in the refactored relay_routing test in mesh.rs

This is a temporary change, but just makes a change to config where it internally has a datacenter or icao enum as the agent config is completely different from all other components :p
A partial step at changing APIs and tests either binding sockets ahead of time that are then passed to the APIs, or for the proxy case, not binding and using the port returned from run_server in most cases. While the available_addr function is still used, this is partial step at completely removing it. While it works in most cases, it's actually not guaranteed to be 100% reliable as there is nothing stopping the OS of assigning the port to another call causing a bind failure for the second test to use it
This moves the rest of the CLI commands into components the same as proxy in the previous commit.

The goal of this change is to start to tease apart the user interface (CLI) portions from the actual code that is run, to make writing tests easier

This also completely removes the notion of unwrapping the `RuntimeConfig` from the `Admin` inside various places in favor of passing in the actual config for the component in a type safe manner. For instance previously running the manage command with a relay server set would panic as .unwrap_agent() was used inside MdsClient
Trace output is incredibly spammy at debug level, this just moves some offenders to trace level
This is a first pass at showing a different way to write integration tests, ie, tests that use multiple components together.

1. Move tests out to a separate crate. This is done so that common test code can be placed in the library and new dependencies can be used etc so that (eventually) test helper code in test.rs can be removed from quilkin itself
2. Make "unit" tests integration tests. While iterating on quilkin I've noticed that the there is a lot of test code in the library that shouldn't be there, as it means changing unit tests needs to compile quilkin (including all the test code) instead of just being able to recompile and relink the single test binary. I'm not sure why it was done this way but I suspect it might be due to...
3. Add helper for test tracing. Currently the tracing-test dev dependency can be used to add a proc macro to a test function to get trace output to be outputted on test failure. Unfortunately this macro has no way to filter messages other than allowing only message from teh current crate, which makes integration tests useless as then no trace messages from quilkin itself will be captured, or else _no filtering_ either by crate nor level (the level used in the tracing-test is trace!) which results in _massive_ spam from eg hyper/h2 that makes test tracing from integration tests utterly useless. So I just made a simple trace_test! macro that makes it trivial to capture only the output we care about in tests to make debugging slightly more tolerable
4. The qt (quilkin-test) crate also introduces a proposed API to make writing integration tests easier, removing a _lot_ of boilerplate by creating various components with minimal necessary configuration that can then be hooked together with dependencies. An example of this is shown in the refactored relay_routing test in mesh.rs
Copy link

This PR exceeds the recommended size of 1000 lines. Please make sure you are NOT addressing multiple issues with one PR. Note this PR might be rejected due to its size.

Copy link

This PR exceeds the recommended size of 1000 lines. Please make sure you are NOT addressing multiple issues with one PR. Note this PR might be rejected due to its size.

@markmandel
Copy link
Contributor

Having a quick look before getting on a plane for GDC - but this is an interesting approach! All of this seems like an improvement.

Make "unit" tests integration tests. While iterating on quilkin I've noticed that the there is a lot of test code in the library that shouldn't be there, as it means changing unit tests needs to compile quilkin (including all the test code) instead of just being able to recompile and relink the single test binary. I'm not sure why it was done this way but I suspect it might be due to...

Blame me, and my relative lack of experience with Rust vs y'all's at Embarks 😃

While it works in most cases, it's actually not guaranteed to be 100% reliable as there is nothing stopping the OS of assigning the port to another call causing a bind failure for the second test to use it, so eventually removing this will entirely remove bind-related flakiness.

Binding to 0 will result in a conflict? In theory, that shouldn't be possible - or am I missing something here?

Move tests out to a separate crate. This is done so that common test code can be placed in the library and new dependencies can be used etc so that (eventually) test helper code in test.rs can be removed from quilkin itself

Sounds good to me - I always struggled with the best way to do this.

So I just made a simple trace_test! macro that makes it trivial to capture only the output we care about in tests to make debugging slightly more tolerable

Sounds excellent. Right now having to step into a test and rerun it locally after CI failure to get at deeper logs is not pleasant.

Only other note in case this gets reviewed and potentially merged while I'm at GDC - Apache headers on everything please 👍🏻 (just in case).

Copy link

This PR exceeds the recommended size of 1000 lines. Please make sure you are NOT addressing multiple issues with one PR. Note this PR might be rejected due to its size.

Copy link

This PR exceeds the recommended size of 1000 lines. Please make sure you are NOT addressing multiple issues with one PR. Note this PR might be rejected due to its size.

Copy link

This PR exceeds the recommended size of 1000 lines. Please make sure you are NOT addressing multiple issues with one PR. Note this PR might be rejected due to its size.

Copy link

This PR exceeds the recommended size of 1000 lines. Please make sure you are NOT addressing multiple issues with one PR. Note this PR might be rejected due to its size.

Copy link

This PR exceeds the recommended size of 1000 lines. Please make sure you are NOT addressing multiple issues with one PR. Note this PR might be rejected due to its size.

Copy link

This PR exceeds the recommended size of 1000 lines. Please make sure you are NOT addressing multiple issues with one PR. Note this PR might be rejected due to its size.

src/net/xds/client.rs Show resolved Hide resolved
test/src/lib.rs Show resolved Hide resolved
Copy link

This PR exceeds the recommended size of 1000 lines. Please make sure you are NOT addressing multiple issues with one PR. Note this PR might be rejected due to its size.

@Jake-Shadle Jake-Shadle marked this pull request as ready for review March 22, 2024 08:40
@XAMPPRocky XAMPPRocky enabled auto-merge (squash) March 22, 2024 08:43
Copy link

This PR exceeds the recommended size of 1000 lines. Please make sure you are NOT addressing multiple issues with one PR. Note this PR might be rejected due to its size.

@XAMPPRocky
Copy link
Collaborator

For @markmandel talked with Jake and we're going to merge this now, and do a followup PR for the one agones test, just to reduce merge conflicts and divergences.

Copy link

This PR exceeds the recommended size of 1000 lines. Please make sure you are NOT addressing multiple issues with one PR. Note this PR might be rejected due to its size.

@XAMPPRocky XAMPPRocky merged commit 2a46b36 into main Mar 22, 2024
10 checks passed
@quilkin-bot
Copy link
Collaborator

Build Succeeded 🥳

Build Id: e8ce28a7-bc2e-44bd-baf4-26fe921c8465

The following development images have been built, and will exist for the next 30 days:

To build this version:

git fetch [email protected]:googleforgames/quilkin.git pull/909/head:pr_909 && git checkout pr_909
cargo build

@Jake-Shadle Jake-Shadle deleted the test-refactor branch March 22, 2024 09:34
@markmandel markmandel added area/tests Unit tests, integration tests, anything to make sure things don't break kind/cleanup Refactoring code, fixing up documentation, etc labels Aug 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/tests Unit tests, integration tests, anything to make sure things don't break kind/cleanup Refactoring code, fixing up documentation, etc size/xl
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants