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

tests: fix potential races with t.Parallel and loops ➿ #3493

Merged
merged 1 commit into from
Nov 7, 2020

Conversation

vdemeester
Copy link
Member

Changes

Following the CommonMistake1 in Go, for loop and go routines can be
a big racey problem. This happens quite easily when using t.Parallel
in for loop with tests.

This fixes possible races by adding a "shadow" var that is evaluated
at each iteration and placed on the stack for the goroutine, so each
slice element is available to the goroutine when it is eventually
executed.

Signed-off-by: Vincent Demeester [email protected]

/kind bug
/area testing

Submitter Checklist

These are the criteria that every PR should meet, please check them off as you
review them:

  • Includes tests (if functionality changed/added)
  • Includes docs (if user facing)
  • Commit messages follow commit message best practices
  • Release notes block has been filled in or deleted (only if no user facing changes)

See the contribution guide for more details.

Double check this list of stuff that's easy to miss:

Reviewer Notes

If API changes are included, additive changes must be approved by at least two OWNERS and backwards incompatible changes must be approved by more than 50% of the OWNERS, and they must first be added in a backwards compatible way.

Release Notes

NONE

@tekton-robot tekton-robot added release-note-none Denotes a PR that doesnt merit a release note. kind/bug Categorizes issue or PR as related to a bug. area/testing Issues or PRs related to testing labels Nov 4, 2020
@tekton-robot tekton-robot added the size/S Denotes a PR that changes 10-29 lines, ignoring generated files. label Nov 4, 2020
@@ -218,6 +218,7 @@ func TestExamples(t *testing.T) {

t.Parallel()
for _, path := range getExamplePaths(t, baseDir) {
path := path // capture range variable
Copy link
Member Author

Choose a reason for hiding this comment

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

Thus is needed because exampleTest called later.. does use t.Parallel()

Following the CommonMistake[1] in Go, for loop and go routines can be
a big racey problem. This happens quite easily when using `t.Parallel`
in for loop with tests.

This fixes possible races by adding a "shadow" var that is evaluated
at each iteration and placed on the stack for the goroutine, so each
slice element is available to the goroutine when it is eventually
executed.

[1]: https://github.com/golang/go/wiki/CommonMistakes#using-goroutines-on-loop-iterator-variables

Signed-off-by: Vincent Demeester <[email protected]>
Comment on lines +210 to +211
i := i // capture range variable
td := td // capture range variable
Copy link
Member

Choose a reason for hiding this comment

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

I often use i, td := i, td to avoid the compounding pollution

Copy link
Member Author

Choose a reason for hiding this comment

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

😊

Copy link
Member

@mattmoor mattmoor left a comment

Choose a reason for hiding this comment

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

/lgtm

@tekton-robot tekton-robot added the lgtm Indicates that a PR is ready to be merged. label Nov 4, 2020
@vdemeester
Copy link
Member Author

(note that this might "fix" some flakey test — or might not 🧇)

Copy link
Member

@afrittoli afrittoli left a comment

Choose a reason for hiding this comment

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

Thanks!
/lgtm

I wonder if we should have a note about this in a comment or in the reviewing guide to avoid falling back into this issue?

@vdemeester
Copy link
Member Author

I wonder if we should have a note about this in a comment or in the reviewing guide to avoid falling back into this issue?

Yeah I am not sure where to put this 🙃

Copy link
Member

@pritidesai pritidesai left a comment

Choose a reason for hiding this comment

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

thanks @vdemeester, nice catch 👍

and one other advantage of table driven test is to have them run in parallel, just realizing, we have not been using t.Parallel() in our unit tests except one 😱

grep -r "t.Parallel()" ./pkg/
./pkg//reconciler/pipelinerun/resources/apply_test.go:			t.Parallel()

@tekton-robot
Copy link
Collaborator

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: pritidesai

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

The pull request process is described here

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

@tekton-robot tekton-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Nov 6, 2020
@tekton-robot tekton-robot merged commit 092a598 into tektoncd:master Nov 7, 2020
@vdemeester vdemeester deleted the test-parallel-and-closure branch November 7, 2020 10:27
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/testing Issues or PRs related to testing kind/bug Categorizes issue or PR as related to a bug. lgtm Indicates that a PR is ready to be merged. release-note-none Denotes a PR that doesnt merit a release note. size/S Denotes a PR that changes 10-29 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants