Documentation ¶
Overview ¶
Package chdir provides an init function that changes the current working directory to RunDir when the test executable is started by Bazel (when TEST_SRCDIR and TEST_WORKSPACE are set).
This hides a difference between Bazel and 'go test': 'go test' starts test executables in the package source directory, while Bazel starts test executables in a directory made to look like the repository root directory. Tests frequently refer to testdata files using paths relative to their package directory, so open source tests frequently break unless they're written with Bazel specifically in mind (using go/runfiles).
For this init function to work, it must be called before init functions in all user packages.
In Go 1.20 and earlier, the package initialization order was underspecified, other than a requirement that each package is initialized after all its transitively imported packages. We relied on the linker initializing packages in the order their imports appeared in source, so we import bzltestutil (and transitively, this package) from the generated test main before other packages.
In Go 1.21, the package initialization order was clarified, and the linker implementation was changed. See https://go.dev/ref/spec#Program_initialization or https://go.dev/doc/go1.21#language.
> Given the list of all packages, sorted by import path, in each step the > first uninitialized package in the list for which all imported packages > (if any) are already initialized is initialized. This step is repeated > until all packages are initialized.
To ensure this package is initialized before user code without injecting edges into the dependency graph, we implement the following hack:
- Add the prefix '+initfirst/' to this package's path with the 'importmap' attribute. '+' is the first allowed character that sorts higher than letters. Because we're using 'importmap' and not 'importpath', this package may be imported in .go files without the prefix.
- Put this init function in a separate package that only imports "os". Previously, this function was in bzltestutil, but bzltest util imports several other std packages may be get initialized later. For example, the "sync" package is initialized after a user package named "github.com/a/b" that only imports "os", and because bzltestutil imports "sync", it would get initialized even later. A user package that imports nothing may still be initialized before "os", but we assume "os" is needed to observe the current directory.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ( // Initialized by linker. RunDir string // Initial working directory. TestExecDir string )
Functions ¶
This section is empty.
Types ¶
This section is empty.