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

Unable to test Go program that involves "@org_golang_google_grpc" elsewhere in its source tree #684

Closed
seh opened this issue Dec 20, 2019 · 6 comments

Comments

@seh
Copy link
Contributor

seh commented Dec 20, 2019

What version of gazelle are you using?

0.19.1

What version of rules_go are you using?

0.20.3

What version of Bazel are you using?

2.0.0

Does this issue reproduce with the latest releases of all the above?

Yes, these are latest I have available today.

What operating system and processor architecture are you using?

macOS Mojave (10.14.6)
AMD64

What did you do?

Within a Bazel workspace with dependencies managed by Gazelle, and a program that depends upon the google.golang.org/grpc Go module at version "v1.23.0," first build the program with bazel build <main target path>. Confirm that the program builds without any problems.

Next, in order to run some unit tests written in Go, run bazel test <target path>/.... Observe that the attempt fails. Try to build all the targets under that path with bazel build <target path>/.... Observe that that attempt fails too.

What did you expect to see?

Bazel would build the unit test program, execute it, and fail if any of the unit tests failed, noting the path to the failure log, or exit successfully if all the unit tests passed. It would not try to build any Go packages using source files not intended for use on macOS.

What did you see instead?

Bazel builds and runs the unit test program (there's just one Go package with tests beneath this tree), but fails trying to compile a different package, due to missing dependencies that are related to Linux. Again, note that I'm running this on macOS.

% bazel test //my/redacted/project/...
INFO: Analyzed 9 targets (0 packages loaded, 0 targets configured).
INFO: Found 8 targets and 1 test target...
ERROR: /private/var/tmp/_bazel_seh/5f212e1971286a055146b31916a9b621/external/org_golang_google_grpc/internal/syscall/BUILD.bazel:3:1: GoCompilePkg external/org_golang_google_grpc/internal/syscall/linux_amd64_pure_stripped/go_default_library%/google.golang.org/grpc/internal/syscall.a failed (Exit 1) builder failed: error executing command bazel-out/host/bin/external/go_sdk/builder compilepkg -sdk external/go_sdk -installsuffix linux_amd64 -src external/org_golang_google_grpc/internal/syscall/syscall_linux.go -src ... (remaining 15 argument(s) skipped)

Use --sandbox_debug to see verbose messages from the sandbox
compilepkg: missing strict dependencies:
	/private/var/tmp/_bazel_seh/5f212e1971286a055146b31916a9b621/sandbox/darwin-sandbox/37/execroot/redacted_workspace/external/org_golang_google_grpc/internal/syscall/syscall_linux.go: import of "golang.org/x/sys/unix"
No dependencies were provided.
Check that imports in Go sources match importpath attributes in deps.
INFO: Elapsed time: 0.577s, Critical Path: 0.30s
INFO: 1 process: 1 darwin-sandbox.
FAILED: Build did NOT complete successfully
//my/redacted/project/internal/project:go_default_test              (cached) PASSED in 0.3s

Executed 0 out of 1 test: 1 test passes.
There were tests whose specified size is too big. Use the --test_verbose_timeout_warnings command line option to see which ones these are.
All tests passed but there were other errors during the build.
FAILED: Build did NOT complete successfully

It's not clear why Bazel is trying to build this internal/syscall package for @org_golang_google_grpc here, and why it's trying to build Go source files that are intended only for use on Linux.

I can cut testing out of the picture, and use bazel build to trigger this same problem, if I use not just the target path to my Go executable program, but to a whole tree recursively:

% bazel build //my/redacted/project/...
INFO: Analyzed 9 targets (0 packages loaded, 0 targets configured).
INFO: Found 9 targets...
ERROR: /private/var/tmp/_bazel_seh/5f212e1971286a055146b31916a9b621/external/org_golang_google_grpc/internal/syscall/BUILD.bazel:3:1: GoCompilePkg external/org_golang_google_grpc/internal/syscall/linux_amd64_pure_stripped/go_default_library%/google.golang.org/grpc/internal/syscall.a failed (Exit 1) builder failed: error executing command bazel-out/host/bin/external/go_sdk/builder compilepkg -sdk external/go_sdk -installsuffix linux_amd64 -src external/org_golang_google_grpc/internal/syscall/syscall_linux.go -src ... (remaining 15 argument(s) skipped)

Use --sandbox_debug to see verbose messages from the sandbox
compilepkg: missing strict dependencies:
	/private/var/tmp/_bazel_seh/5f212e1971286a055146b31916a9b621/sandbox/darwin-sandbox/44/execroot/redacted_workspace/external/org_golang_google_grpc/internal/syscall/syscall_linux.go: import of "golang.org/x/sys/unix"
No dependencies were provided.
Check that imports in Go sources match importpath attributes in deps.
INFO: Elapsed time: 0.729s, Critical Path: 0.36s
INFO: 1 process: 1 darwin-sandbox.
FAILED: Build did NOT complete successfully

I noted this problem originally in #293, by way of a comment (#293 (comment)) about what looked like an earlier fix this problem in bazel-contrib/rules_go#2009 that was since removed in bazel-contrib/rules_go#2126.

My questions:

  • Why is Bazel trying to build that failing file (internal/syscall/syscall_linux.go)?
  • Do I need to direct Gazelle to treat this dependency differently, if it's mistakenly concluding that this file is meant for use when building for execution on macOS?
@seh seh changed the title Unable to test Go program that involves "@org_golang_google_grpc" Unable to test Go program that involves "@org_golang_google_grpc" elsewhere in its source tree Dec 20, 2019
@seh
Copy link
Contributor Author

seh commented Dec 20, 2019

What's weird here is that this problem seems to arise only when using a recursive target path, presumably including something that shouldn't be included. I can run bazel test <target for package with test>, and bazel build <target for executable program>, but there's some other target in this package tree that aggravates this behavior.

[Time passes...]

Ah, I think I see a problem: By way of bazel query --output=build //my/redacted/project/..., I see that there are targets for building and pushing container images using the _app_layer and container_push rules. Those should only be run when targeting the @io_bazel_rules_go//go/toolchain:linux_amd64 platform, because they have to build the program for running on Linux, not macOS.

Given that, is there a way to exclude them from consideration when trying to "run all the tests in this project?"

@seh
Copy link
Contributor Author

seh commented Dec 20, 2019

I'm not sure if there's a better way to go about this, but I found that this worked:

bazel test $(bazel query 'kind(".*_test rule", //my/redacted/project/...)')

Alternately:

bazel test $(bazel query 'tests(//my/redacted/project/...)')

@jayconrod
Copy link
Contributor

I couldn't reproduce this. I was able to build a go_test that depends on google.golang.org/grpc without any problems.

Could you post a minimum example that demonstrates this issue, either as a repo or a gist? Please give the specific commands you're running. If you could run with -s and provide the command line for the failing action, that might also be helpful.

Based on the error, I'm speculating that you're cross-compiling something using the goos and goarch attributes on either go_test or go_binary. That doesn't work if there are conditional dependencies due to implementation limitations (bazel-contrib/rules_go#2219). gRPC had problems with that in the past.

@jayconrod
Copy link
Contributor

Given that, is there a way to exclude them from consideration when trying to "run all the tests in this project?"

Generally bazel test //... should build everything, including non-test targets. You can add tags = ["manual"] to targets that should not be matched by patterns like //....

@seh
Copy link
Contributor Author

seh commented Dec 20, 2019

Sorry for the confusion. That //... matches a few targets in my tree using the _app_layer and container_push rules does wind up involving cross-compilation, since those targets build for Linux rather than macOS. I think that lines up with what you said about conditional dependencies and cross-compilation.

@seh
Copy link
Contributor Author

seh commented Dec 21, 2019

My various targets using the go_image rule still had the "goos" and "goarch" attributes set, even though that's no longer recommended in the documentation, in favor of using the --platforms flag.

Once I removed the "goos" and "goarch" attributes from my go_image targets, the problem reported here went away. I can now run bazel build //my/redacted/project/... and bazel test //my/redacted/project/..., and have both succeed.

@seh seh closed this as completed Dec 21, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants