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

Fix incorrect use of loop variables in parallel tests. #44013

Closed
wants to merge 1 commit into from

Conversation

renatolabs
Copy link

- What I did
This commit fixes occurrences of loop variables being captured by
reference in parallel tests. With very high probability, only the last
test case will actually be exercised. To work around this problem, we
create a local copy of the range variable before the parallel test, as
advised by the Go documentation at:

https://pkg.go.dev/testing#hdr-Subtests_and_Sub_benchmarks

- How I did it
Issues were found automatically using the loopvarcapture linter.

- How to verify it
Running the tests changed here and verifying that they now actually run each test declared.

This commit fixes occurrences of loop variables being captured by
reference in parallel tests. With very high probability, only the last
test case will actually be exercised. To work around this problem, we
create a local copy of the range variable before the parallel test, as
advised by the Go documentation at:

https://pkg.go.dev/testing#hdr-Subtests_and_Sub_benchmarks

Issues were found automatically using the `loopvarcapture` linter.

Signed-off-by: Renato Costa <renato@cockroachlabs.com>
Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

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

thanks! I know if fixed a couple of these in the past, but I'm sure there's more that may have this issue, so thanks for catching these 👍

LGTM

@thaJeztah thaJeztah added this to the v-next milestone Aug 23, 2022
tailFiles(files, watcher, dec, tailReader, config.Tail, fwd)
close(started)
Copy link
Member

Choose a reason for hiding this comment

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

?

Copy link
Author

Choose a reason for hiding this comment

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

The synchronization attempted in this loop was incorrect (closing the channel in the Go routine and reading it back, supposedly to wait for the Go routine to finish). Since close was called before the actual reference to the range variable, the code was not safe.

Maybe this snippet makes it clearer: https://go.dev/play/p/mo3FA7_D8sI

Copy link
Contributor

Choose a reason for hiding this comment

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

I think it was meant to wait for the goroutine to start, not finish (hence the name started).
Not sure if it makes any difference though.

Copy link
Member

Choose a reason for hiding this comment

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

I must admit that I didn't look closely at this part. Is there something to dereference / capture in this case as well then? The playground example above (https://go.dev/play/p/mo3FA7_D8sI) shows;

`close` called at the beginning, tc = 3
`close` called at the beginning, tc = 3
`close` called at the beginning, tc = 3

`close` called at the end, tc = 1
`close` called at the end, tc = 2
`close` called at the end, tc = 3

Which, likely isn't intended.

Changing the example to capture tc https://go.dev/play/p/aZ7YsyPFxMN shows;

`close` called at the beginning, tc = 3
`close` called at the beginning, tc = 2
`close` called at the beginning, tc = 1

`close` called at the end, tc = 1
`close` called at the end, tc = 2
`close` called at the end, tc = 3

Copy link
Author

Choose a reason for hiding this comment

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

I think it was meant to wait for the goroutine to start, not finish (hence the name started).

Good point. I admit I just made the minimal change here to make the loop variable access safe.

To your point, @thaJeztah, I could just create a copy of config, as that would also fix the issue. On the other hand, it seems like this is dead code, as the iteration happens over an empty map.

@corhere
Copy link
Contributor

corhere commented Mar 31, 2023

Superseded by #45005

@corhere corhere closed this Mar 31, 2023
@thaJeztah thaJeztah removed this from the 24.0.0 milestone Apr 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants