rules_go icon indicating copy to clipboard operation
rules_go copied to clipboard

go_test with data doesn't work on Windows?

Open ukai opened this issue 4 years ago • 2 comments

What version of rules_go are you using?

v0.22.4

What version of gazelle are you using?

v0.19.0

What version of Bazel are you using?

3.1.0

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

yes

What operating system and processor architecture are you using?

Windows x64

Any other potentially useful information about your toolchain?

What did you do?

https://github.com/ukai/bazel-go-test

What did you expect to see?

test pass

What did you see instead?

test failed as it couldn't find testdata file.

--- FAIL: TestLoad (0.00s)
    sample_test.go:8: Load open testdata/foo: The system cannot find the path specified.; want nil err
FAIL

ukai avatar May 13 '20 06:05 ukai

Bazel normally runs tests in a temporary sandbox directory. It creates symbolic links to runfiles.

Windows forbids creation of symbolic links unless you have administrative privileges, so Bazel doesn't run tests with runfiles the same way. Instead, it writes a manifest file and passes the location of the manifest to the test using an environment variable.

You can use the github.com/bazelbuild/rules_go/go/tools/bazel package to decode this manifest and access runfiles. You may also need to set rundir = "." on the go_test rule so the test doesn't change to its package subdirectory when starting; that can make it difficult to find runfiles.

jayconrod avatar May 13 '20 14:05 jayconrod

I've also hit this, and as someone learning bazel it was super confusing. I was trying to understand "data" dependencies and couldn't reproduce what the test, and the documentation, says should happen, which is that you should just be able to access the data file fairly naturally using a relative path. I finally cloned the repo and run the actual test in here and it fails on Windows.

The documentation doesn't encourage you to enable symlinks on Windows due to potential performance issues (creating symlinks is expensive and a lot would be created for runfiles).

It seems like the intended thing to do is to use the bazel golang package to access any files, as that will read the manifest and read the correct file. For me though that's polluting my code with logic that depends on the build system being used, which feels wrong. The code under test might be production code that is supposed to read files, you clearly don't want to pollute that with bazel code. Also, it doesn't seem to support listing the contents in a natural way (an io.fs implementation would fix that).

tomqwpl avatar Jul 03 '22 06:07 tomqwpl