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

Update Go & JS tests to conform to the multidim interop test spec. #121

Merged
merged 11 commits into from
Feb 11, 2023

Conversation

MarcoPolo
Copy link
Contributor

@MarcoPolo MarcoPolo commented Jan 31, 2023

Addresses #120.

Closes #113, closes #120, closes #115, closes #112.

@jxs could you update the Rust test please?

After this PR the tests in the implementation repos will be broken until we update them as well. @jxs can you take updating the rust-libp2p repo? I'll update go-libp2p.

We could do something fancier where we maintain two versions of this test runner and update the implementation repos only once. I think it's okay to break CI for a little bit to make these changes simpler (The time can be minimized if we don't merge this until {rust,go}-libp2p are ready). If folks feel differently let me know.

@jxs
Copy link
Member

jxs commented Jan 31, 2023

Hi Marco, yeah no worries I'll start on it Tomorrow :)

@thomaseizinger
Copy link
Contributor

If we pin the action to a hash in the repo, we should be able to update in steps, right?

@thomaseizinger
Copy link
Contributor

If we pin the action to a hash in the repo, we should be able to update in steps, right?

We might need to also change the action to not just checkout latest test-plans master but the hash it was pinned to.

I have an idea that could work ..

@thomaseizinger
Copy link
Contributor

If we pin the action to a hash in the repo, we should be able to update in steps, right?

We might need to also change the action to not just checkout latest test-plans master but the hash it was pinned to.

I just saw that we already have test-plans-ref:

Specifying that + pinning the action to a hash should allow us a graceful upgrade without having to do things in lock step.

@thomaseizinger
Copy link
Contributor

thomaseizinger commented Feb 1, 2023

Can we merge my composite action before we do this? #123

That would allow us to migrate each repository individually without breaking any CI.

@jxs
Copy link
Member

jxs commented Feb 2, 2023

there's also #114. If you prefer you can cherry-pick 07a7eeb here Marco

@@ -0,0 +1,18 @@
image_name := rust-v0.50
commitSha = 53e477d4423106bb9f9e744a4b275dfb6213ca0a
Copy link
Contributor Author

@MarcoPolo MarcoPolo Feb 2, 2023

Choose a reason for hiding this comment

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

@thomaseizinger / @jxs

This is how I imagine defining future released versions. (As an alternative to publishing to a registry).

Also a note, from testing this manually. The Rust listener I don't think is listening for a sigint. The listener doesn't exit when compose tries to stop it after the dialer finishes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

also this isn't for the released version 0.50, it's for master I believe. That needs to be fixed, but the test-to-spec update isn't backported yet. Easy to do, I just haven't done it yet.

Copy link
Contributor

Choose a reason for hiding this comment

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

So if I understand correctly, we download the archive and build the container from the source of the tag?

Or do you expect the test to be defined here and we just reference the downloaded source-code?

Copy link
Contributor

Choose a reason for hiding this comment

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

If the test is still co-located with the source-code, I don't really see the benefit of doing this. Can you lay it out please?

If the test is not co-located but defined in here, then we can just use the package manager to point the released version.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The test is colocated with the implementation (in rust-libp2p).

The code here should be minimal, fetch the repo at the specified hash/tag and then build the container.

The dockerfile here is simply because I couldn't use the one in the rust-libp2p repo since im on a Mac and haven't setup cross builds.

This way you can run these tests locally without having access to the registry.

CI will cache this as well so it shouldn't add much time relative to a registry either.

Copy link
Contributor

@thomaseizinger thomaseizinger Feb 2, 2023

Choose a reason for hiding this comment

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

Following from that, once you've run the test-suite once locally, it will work without a network connection. There shouldn't be a case where you need to build those containers yourself IMO.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

❯ docker run --rm -it ghcr.io/libp2p/rust-libp2p/ping-interop-test:v0.50.0                                                                                            
Unable to find image 'ghcr.io/libp2p/rust-libp2p/ping-interop-test:v0.50.0' locally
docker: Error response from daemon: Head "https://ghcr.io/v2/libp2p/rust-libp2p/ping-interop-test/manifests/v0.50.0": denied.

I assume I need to authenticate with the registry somehow?

There are two problems I have with just relying on the tag.

  1. I can't checkout this repo and run the test. Now I need to setup a registry to get this working.
  2. It makes changes to the test implementation harder. Do I have to have a GH action publish a new container for that change? I can't do what the action does here because I would need to cross compile to linux to create the binary.

My requirements:

  1. It should be reproducible from a given test-plans commit. If a commit passes, it should always pass in the future.
  2. I should be able to run the tests locally, and be able to tweak tests locally.

I'm happy to cache things all day long. And if we could use the registry as a cache, I'm fine with doing that as well. That's what I thought you meant when you said "Because you can also do that if you just build the container locally and give it the right tag". But now I understand you meant that I could manually build it and tag it myself so it doesn't try to fetch from the registry. This breaks the reproducibility.

Copy link
Contributor

Choose a reason for hiding this comment

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

❯ docker run --rm -it ghcr.io/libp2p/rust-libp2p/ping-interop-test:v0.50.0                                                                                            
Unable to find image 'ghcr.io/libp2p/rust-libp2p/ping-interop-test:v0.50.0' locally
docker: Error response from daemon: Head "https://ghcr.io/v2/libp2p/rust-libp2p/ping-interop-test/manifests/v0.50.0": denied.

I assume I need to authenticate with the registry somehow?

Nothing is published yet as I wanted to await the final spec of the tests! :)
The branches are ready in rust-libp2p. Just need to click the publish button in the workflow.

There are two problems I have with just relying on the tag.

  1. I can't checkout this repo and run the test. Now I need to setup a registry to get this working.

Nothing needs to be set up once the images are published. The images will be publicly accessible.

  1. It makes changes to the test implementation harder. Do I have to have a GH action publish a new container for that change? I can't do what the action does here because I would need to cross compile to linux to create the binary.

The fact that we build the binary outside the container is a simplification (and performance optimisation) that us rust-libp2p maintainers accepted because we all run linux. If necessary, we can switch to building inside a container. It has at the end of the day nothing to do with pulling images from a registry or building them locally.

My requirements:

  1. It should be reproducible from a given test-plans commit. If a commit passes, it should always pass in the future.

We can (and should) pin the container hash in the versions.ts file. That will fetch the right container even if the tag gets overwritten. IMO this is a super strong commitment to reproducibility because we are running bit-for-bit the same binary on every test.

  1. I should be able to run the tests locally, and be able to tweak tests locally.

Changing the test is tricky because it lives in another source-code repository anyway. For local dev, I'd suggest to build the container locally and add it via --extra-version. I don't think we should "cheat" the local setup by overwriting an existing test or container.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Let's chat sync. I think that'll be faster than all this back and forth :)

Copy link
Contributor

Choose a reason for hiding this comment

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

@MarcoPolo and I agreed in a sync-chat that using these caches is basically equivalent to a registry, just slightly leaner.

Building a docker container will reuse local / cached layers if they are present. Running an image will pull it unless it is present. If we have a central cache in S3, building and pulling from a registry are essentially equivalent, we are just downloading layers.

The benefit of building and caching over pulling is that we only need to define how to build a container in the implementation repository. Then, any commit (or tag for that matter) can be referenced within the test-plans repo here and used to run the tests.

Copy link
Contributor

@thomaseizinger thomaseizinger left a comment

Choose a reason for hiding this comment

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

Thanks for pushing this forward, left a few comments. It would be nice if we could split this into smaller PRs. There are a lot of different changes going on here.

.github/workflows/multidim-interop.yml Outdated Show resolved Hide resolved
multidim-interop/Makefile Show resolved Hide resolved
multidim-interop/dockerBuildWrapper.sh Show resolved Hide resolved
multidim-interop/src/generator.ts Show resolved Hide resolved
multidim-interop/src/generator.ts Show resolved Hide resolved
mergify bot pushed a commit to libp2p/rust-libp2p that referenced this pull request Feb 8, 2023
@MarcoPolo MarcoPolo marked this pull request as draft February 8, 2023 19:35
@MarcoPolo MarcoPolo marked this pull request as ready for review February 9, 2023 01:08
@MarcoPolo
Copy link
Contributor Author

This is ready for a review. It can be reviewed commit by commit. That's easier for me than the overhead of dealing with 6 PRs.

Copy link
Contributor

@thomaseizinger thomaseizinger left a comment

Choose a reason for hiding this comment

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

LGTM!

Some non-blocking questions.

I guess we should prepare the commits in rust-libp2p properly (i.e. finish the backport) before we merge this?

.github/actions/run-interop-ping-test/action.yml Outdated Show resolved Hide resolved
multidim-interop/Makefile Show resolved Hide resolved
@MarcoPolo
Copy link
Contributor Author

I guess we should prepare the commits in rust-libp2p properly (i.e. finish the backport) before we merge this?

I have the preference of merging this, and then a PR later that updates the commit with the backport. I don't expect that backport to break anything and it would be good to unblock other work here (like rolling out the s3 caching).

@thomaseizinger
Copy link
Contributor

I guess we should prepare the commits in rust-libp2p properly (i.e. finish the backport) before we merge this?

I have the preference of merging this, and then a PR later that updates the commit with the backport. I don't expect that backport to break anything and it would be good to unblock other work here (like rolling out the s3 caching).

Sounds good to me!

Comment on lines 36 to 42
- name: Configure AWS credentials for S3 build cache
if: ${{ inputs.s3-access-key-id }} != "" && ${{ inputs.s3-secret-access-key }} != ""
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ inputs.s3-access-key-id }}
aws-secret-access-key: ${{ inputs.s3-secret-access-key}}
aws-region: ${{ env.AWS_REGION }}
Copy link
Member

Choose a reason for hiding this comment

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

rust-libp2p executes this step on each pull request. Some pull requests originate from forks. Those pull requests don't have access to the above secrets. Thus this step fails.

See https://github.com/libp2p/rust-libp2p/actions/runs/4142906998/jobs/7164133938 on libp2p/rust-libp2p#3344 as an example.

I don't yet have the full picture on the caching approach via an S3 bucket. Would mounting the bucket as read-only from forks be an option? Worst case, we don't mount the bucket on forks at all, thus building all images from scratch.

Copy link
Contributor Author

@MarcoPolo MarcoPolo Feb 10, 2023

Choose a reason for hiding this comment

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

Thus this step fails.

The original plan was that the if should have skipped this step. I'll check why that isn't happening.

Would mounting the bucket as read-only from forks be an option?

Unfortunately no. The s3 cache needs rw access. Maybe there's a hidden option I'm not seeing, but when I tried a read only key it failed.

My original plan was to have forks build from scratch.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I had the if statement wrong. #131 fixes it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Did you try omitting the --cache-to option when you tried with a read-only key?

According to https://docs.docker.com/build/cache/backends/, those two options operate separately and I am surprised that --cache-from by itself would need write permissions.

If we conditionally define --cache-to, we should be set our bucket to be publicly readable and have forks use our cache.

Alternatively, I see that this also has a registry cache option which might be interesting to explore.

I really want our CI to always be fast, not just for our own PRs. (I also don't like wasting compute power.)

Copy link
Contributor

Choose a reason for hiding this comment

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

Happy to help with this but it would earliest be in ~5 days as I am off the grid for the next few.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Did you try omitting the --cache-to option when you tried with a read-only key?

I hadn't, that's probably it!

Probably worth figuring out how to make this bucket public and then defaulting to that public bucket if no keys are passed. I'll open an issue.

MarcoPolo and others added 3 commits February 10, 2023 15:21
* Test if it works without s3 cache keys

* Fix if statement

* Fix if statement

* Always use buildkit

* Undo debug change

* Add no cache workflow

* Skip test in no-cache workflow

* Update .github/workflows/no-cache-multidim-interop.yml

* Same workflow; use CACHING_OPTIONS
* Add webrtc to JS test

* Add onlyDial to all queries

* Update versions.ts
@MarcoPolo MarcoPolo merged commit 3b6d87b into master Feb 11, 2023
mxinden added a commit to mxinden/rust-libp2p that referenced this pull request Feb 13, 2023
With libp2p/test-plans#121 merged, we should be able to use @master
directly.

This includes
libp2p/test-plans@6d1aed2, thus
allowing interop tests to run from fork pull requests.
mxinden added a commit to libp2p/rust-libp2p that referenced this pull request Feb 14, 2023
With libp2p/test-plans#121 merged, we should be able to use @master
directly. Still pointing to a concrete git hash.

This includes
libp2p/test-plans@6d1aed2, thus
allowing interop tests to run from fork pull requests.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants