Skip to content

Mark integration / e2e test files with a build tag#4565

Closed
SgtCoDFish wants to merge 1 commit intocert-manager:masterfrom
SgtCoDFish:testsplit
Closed

Mark integration / e2e test files with a build tag#4565
SgtCoDFish wants to merge 1 commit intocert-manager:masterfrom
SgtCoDFish:testsplit

Conversation

@SgtCoDFish
Copy link
Copy Markdown
Member

@SgtCoDFish SgtCoDFish commented Oct 28, 2021

Notes for Reviewer

See my comments below about prow's reporting of tests.

This PR should be a no-op for all of our bazel-based tests. They should still be run in exactly the same way. Verifying that they do run the same way is IMO the most important part of reviewing this PR.

Overview

This PR adds go:build tags to every test I can find which has an external dependency - i.e. one which breaks or fails on a clean checkout of the repo when running go test ./..., or else everything under test/integration and test/e2e. The e2e tests are tagged differently.

This will enable us to use go test for all types of tests. Currently go test will panic due to missing dependencies if run without bazel magic happening.

This is part of the migration to make.


Unrelated notes, might be of interest but not needed for reviewing this PR Mostly for interest, the following is useful analysing runtimes of tests, the following will list in `tests.txt` all tests ordered by time taken in seconds:
go test -count=1 -json ./pkg/...  > tests.json
jq -r '. | select(.Action == "pass") | [(.Elapsed|tostring), .Package] | join(" ")' < tests.json | sort -rn | uniq > tests.txt

Note that the output varies based on how the tests are specified:

# testing a specific file ignores the build tag, but build tags in dependencies are respected leading to a failure to build
$ go test -count=1 ./test/integration/webhook/dynamic_authority_test.go
# command-line-arguments
package command-line-arguments (test)
        imports github.com/jetstack/cert-manager/test/integration/framework: build constraints exclude all Go files in ...
FAIL    command-line-arguments [setup failed]
FAIL
exit code 1
# testing using ... respects build tags and therefore acts as though there aren't any go files here at all
$ go test -count=1 ./test/integration/webhook/...
go: warning: "./test/integration/webhook/..." matched no packages
no packages to test
exit code 1

/kind cleanup

Adds go:build tags to integration and e2e tests

@jetstack-bot jetstack-bot added kind/cleanup Categorizes issue or PR as related to cleaning up code, process, or technical debt. release-note-none Denotes a PR that doesn't merit a release note. do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. dco-signoff: yes Indicates that all commits in the pull request have the valid DCO sign-off message. size/M Denotes a PR that changes 30-99 lines, ignoring generated files. area/acme Indicates a PR directly modifies the ACME Issuer code labels Oct 28, 2021
@jetstack-bot
Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: SgtCoDFish

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@jetstack-bot jetstack-bot added area/acme/dns01 Indicates a PR modifies ACME DNS01 provider code area/testing Issues relating to testing approved Indicates a PR has been approved by an approver from all required OWNERS files. labels Oct 28, 2021
@jetstack-bot jetstack-bot added the area/acme/http01 Indicates a PR modifies ACME HTTP01 provider code label Nov 18, 2021
@SgtCoDFish SgtCoDFish force-pushed the testsplit branch 2 times, most recently from 09f2815 to 1314a70 Compare January 4, 2022 17:41
@SgtCoDFish SgtCoDFish mentioned this pull request Jan 5, 2022
30 tasks
@SgtCoDFish SgtCoDFish marked this pull request as ready for review January 6, 2022 13:51
@jetstack-bot jetstack-bot added release-note Denotes a PR that will be considered when it comes time to generate release notes. and removed do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. release-note-none Denotes a PR that doesn't merit a release note. labels Jan 6, 2022
@cert-manager cert-manager deleted a comment from jetstack-bot Jan 6, 2022
@SgtCoDFish SgtCoDFish marked this pull request as draft January 6, 2022 15:00
@jetstack-bot jetstack-bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jan 6, 2022
@SgtCoDFish SgtCoDFish force-pushed the testsplit branch 2 times, most recently from 57f3082 to d7d6240 Compare January 6, 2022 16:09
@SgtCoDFish SgtCoDFish marked this pull request as ready for review January 6, 2022 16:09
@jetstack-bot jetstack-bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jan 6, 2022
@SgtCoDFish
Copy link
Copy Markdown
Member Author

I think prow makes the test output confusing here. Taking an example:

internal/apis/acme/install/pruning_test.go is marked as an integration_test in this PR. This tag is specified in the relevant BUILD.bazel, so bazel should run the test.

Bazel does run the test locally with bazel test //internal/apis/acme/install/..., bazel test //internal... and bazel test //....

Yet in the prow overview of the cert-manager-bazel test this test isn't shown. It is shown for a different overview for a different PR entirely.

In the logs for this PR, the test is shown as running.

So the test is run, but isn't reported in the JUnit section on the prow UI.

I'm going to push to this PR with the following patch to confirm that the pull-cert-manager-bazel test fails as expected.

diff --git a/internal/apis/acme/install/pruning_test.go b/internal/apis/acme/install/pruning_test.go
index 32d1a1984..b0c493857 100644
--- a/internal/apis/acme/install/pruning_test.go
+++ b/internal/apis/acme/install/pruning_test.go
@@ -31,4 +31,5 @@ import (
 func TestPruneTypes(t *testing.T) {
 	crdfuzz.SchemaFuzzTestForCRDWithPath(t, api.Scheme, apitesting.PathForCRD(t, "orders"), acmefuzzer.Funcs)
 	crdfuzz.SchemaFuzzTestForCRDWithPath(t, api.Scheme, apitesting.PathForCRD(t, "challenges"), acmefuzzer.Funcs)
+	panic("blork")
 }

If the bazel tests are run but not reported by prow, that seems acceptable to me given the bazel tests are on their deathbed. Alternatively it might be an easy fix to make them appear in the prow overview.

@SgtCoDFish SgtCoDFish added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jan 6, 2022
@SgtCoDFish
Copy link
Copy Markdown
Member Author

As expected, the test failure isn't shown in the prow overview (which reports 91/91 tests passed) but the test was run, which is visible at the bottom of the logs:

//internal/apis/acme/install:go_default_test                             FAILED in 0.1s

I'm fine with this, personally. I'll remove the test commit and remove the hold.

@SgtCoDFish SgtCoDFish removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jan 6, 2022
@SgtCoDFish
Copy link
Copy Markdown
Member Author

/test all

integration and e2e tests are broadly defined as being tests which
require some kind of _external_ setup before they can successfully
execute, differentiated by the amount of setup required.

Signed-off-by: Ashley Davis <ashley.davis@jetstack.io>
@irbekrm
Copy link
Copy Markdown
Contributor

irbekrm commented Jan 12, 2022

Thanks for all the great work on the make migration! Also, awesome PR description & comments ❤️

This PR adds go:build tags to every test I can find which has an external dependency - i.e. one which breaks or fails on a clean checkout of the repo when running go test ./..., or else everything under test/integration and test/e2e. The e2e tests are tagged differently.
This will enable us to use go test for all types of tests. Currently go test will panic due to missing dependencies if run without bazel magic happening.

I am not sure what is the general preferred approach in Go community about whether go test should run all tests in a repo or not, but from a more abstract point of view, I think it would be preferable if it would fall back on running all tests as opposed to running just some, to avoid cases where tests are not run due to forgetting to pass/misspelling a tag etc. I think that in general it is preferable to make engineers put in effort to skip a test (i.e figure out what tag to pass when running locally) as opposed to put in effort to ensure that the test they wrote actually runs because if they fail to do the latter, the effect is worse.

In this case, the obvious risk seems to be forgetting to add a tag to a Bazel rule and this will go away once we remove Bazel. But I would argue that it may be preferable to have the same approach and fall back to running all tests unless explicitly specified otherwise. At the moment we already have a mix of approaches where, for example, Venafi tests are skipped in most CI tests by passing a flag from test config, but there is also some code within the tests themselves to skip if a certain env var is not found (which introduces a risk as we could change the test pod config and accidentally remove the env var + it is not obvious that they won't be run for a person running them locally).

I had a brief look at alternative approaches and saw that it is possible to negate the build tag (i.e // +build !short and then skip with go test ./... --tags=short - I have not tested this). Also found this short article that talks about the same issue and introduces a less elegant, but imo still preferable approach using env vars.

Apologies, if some of this was already discussed earlier!

@SgtCoDFish
Copy link
Copy Markdown
Member Author

I agree with what you're saying, broadly speaking. I'd love to be in a place where go test just runs everything [1] and I want to clean up all tests so it's really obvious what's being run or skipped

My main concern ATM is that running go test on a fresh clone of the cert-manager repo will panic and it just doesn't feel good... if I switch to using t.Skip that's gonna touch so much more code.

Plus as far as I know, build tags are the only approach that works everywhere because of pkg/util/versionchecker/versionchecker_test.go. Without prior setup it won't even compile properly. Admittedly though, that's the only test with that issue.

My view is pretty much:

  1. Before this PR, go test ./... is broken and to run all tests you need an external tool (bazel)
  2. After this PR, go test ./... works but isn't ideal, and to run all tests you need an external tool (bazel, plus make will be an option soon)

[1] probably except the e2e tests

@SgtCoDFish
Copy link
Copy Markdown
Member Author

Discussed this in standup; consensus was to move all integration tests into test/integration, treat the versionchecker test as a special case (which might include a build tag), leave go test ./... broken but by moving all tests into test/, we'll allow go test ./pkg/... and go test ./internal/... to work as expected.

@SgtCoDFish SgtCoDFish closed this Jan 12, 2022
@munnerz
Copy link
Copy Markdown
Member

munnerz commented Jan 14, 2022

Ah, I missed this conversation previously! 😄

to avoid cases where tests are not run due to forgetting to pass/misspelling a tag etc.

I think this is an issue with both approaches though - moving into test/integration as well as marking things with a build tag. No matter what, you have to execute at least 2 commands to get all tests to run: 1) go test ./... and 2) make integration. The only difference is what that make integration runs (i.e. go build -tag ... vs go test ./test/integration/....

The drawback of not using tags is that go test ./... doesn't work (you have to explicitly say go test ./pkg/... ./cmd/... etc). For that reason, I think having a build tag means that we keep with our original goal of making go test ./... work whilst also allowing us to move forward with the make migration.

It also means that we are able to store our test files wherever we want/alongside the source code they are testing like normal too... (which plays nicer with hierarchical OWNERS files too)

SgtCoDFish added a commit to SgtCoDFish/cert-manager that referenced this pull request Jan 17, 2022
This was initially part of cert-manager#4565 which was closed in favour of moving
integration tests, but the consensus was that the e2e test is a special
case.

The e2e test requires so much more ahead-of-time setup that our bazel
build flow special cases it by marking it manual. This is a `go test`
equivalent to that, which enables the e2e test to remain under the test/
directory while still allowing `go test ./test/...` to work generally
for all other tests.

We'll add make targets for the e2e tests down the road. For now, we add
it and define it in bazel so this commit should be a no-op in effect.

Signed-off-by: Ashley Davis <ashley.davis@jetstack.io>
SgtCoDFish added a commit to SgtCoDFish/cert-manager that referenced this pull request Jan 17, 2022
This was initially part of cert-manager#4565 which was closed in favour of moving
integration tests, but the consensus was that the e2e test is a special
case.

The e2e test requires so much more ahead-of-time setup that our bazel
build flow special cases it by marking it manual. This is a `go test`
equivalent to that, which enables the e2e test to remain under the test/
directory while still allowing `go test ./test/...` to work generally
for all other tests.

We'll add make targets for the e2e tests down the road. For now, we add
the build tag and define it in bazel so this commit should be a no-op
in effect.

Signed-off-by: Ashley Davis <ashley.davis@jetstack.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. area/acme/dns01 Indicates a PR modifies ACME DNS01 provider code area/acme/http01 Indicates a PR modifies ACME HTTP01 provider code area/acme Indicates a PR directly modifies the ACME Issuer code area/testing Issues relating to testing dco-signoff: yes Indicates that all commits in the pull request have the valid DCO sign-off message. kind/cleanup Categorizes issue or PR as related to cleaning up code, process, or technical debt. release-note Denotes a PR that will be considered when it comes time to generate release notes. size/M Denotes a PR that changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants