bazel test vs direct execution

Viewed 568

I'm using GoogleTest with bazel and when I run bazel test :tokens_test (rule defined below) I have a failing test, but when I run the compiled tests I see the expected result. It is failing because the test can not open the test data file. The directory layout and the BUILD rule for the test I'm running look like this:

tokens/
  BUILD
  tokens_test.cpp
  test_data/
    test_input1.txt
cc_test(
  name = "tokens_test",
  srcs = ["tokens_test.cpp"],
  deps = [
    '@gtest//:gtest'
    '@gtest//:gtest_main',
  ],
  data = ["//tokens/test_data:test_input1.txt"]
)

At this point the test is just a wrapper to open the file and read in the test data which is the bit thats failing.

TEST(Tokenizer, OpenFileTest) {
  auto fin = std::ifstream("test_data/test_input1.txt");
  std::cout << a.get();  // Outputs -1.
}

When I navigate to the bazel-out location and find my way to the tokens runfiles directory I can see the compiled test excutable.

[jibberish]/__main__/tokens>ls
test_data/
  test_input1.txt
tokens_test

And when I run the executable:

[jibberish]/__main__/tokens>./tokens_test

...normal test output...
The correct output!
...more test output...

I'm lost as to where to start looking for the problem. I've tried including a BUILD in the test_data directory with an exports_files rule, using a variety of relatives paths in the BUILD files and my source code and a lot of permutations of those relative paths.

1 Answers

Define your data as

 data = ["test_data/test_input1.txt"]

Use absolute path: ./tokens/test_data/test_input1.txt

To find it run your test with a bazel test --sandbox_debug -s. The last command will looks like that one:

SUBCOMMAND: # //:hello_test [action 'Testing //:hello_test', configuration: faff19e6fd939f490ac11578d94024c6b7a032836cde039fd5edd28b838194e8, execution platform: @local_config_platform//:host]

(cd /home/s/.cache/bazel/_bazel_s/fa4c7c7c7db2888182e4f15990b55d58/execroot/com_google_absl_hello_world && \
  exec env - \
    EXPERIMENTAL_SPLIT_XML_GENERATION=1 \
    RUNFILES_DIR=bazel-out/k8-fastbuild/bin/hello_test.runfiles \
    RUN_UNDER_RUNFILES=1 \
    TEST_BINARY=./hello_test \
    TEST_INFRASTRUCTURE_FAILURE_FILE=bazel-out/k8-fastbuild/testlogs/hello_test/test.infrastructure_failure \
    TEST_LOGSPLITTER_OUTPUT_FILE=bazel-out/k8-fastbuild/testlogs/hello_test/test.raw_splitlogs/test.splitlogs \
    TEST_PREMATURE_EXIT_FILE=bazel-out/k8-fastbuild/testlogs/hello_test/test.exited_prematurely \
    TEST_SIZE=medium \
    TEST_SRCDIR=bazel-out/k8-fastbuild/bin/hello_test.runfiles \
    TZ=UTC \
    XML_OUTPUT_FILE=bazel-out/k8-fastbuild/testlogs/hello_test/test.xml \
  external/bazel_tools/tools/test/test-setup.sh ./hello_test)

Then you can paste the whole (cd ...) one-liner to reproduce the exact sandbox environment as during the bazel test run. For example you can substitute the last line in that way:

(cd /home/s/.cache/bazel/_bazel_s/fa4c7c7c7db2888182e4f15990b55d58/execroot/com_google_absl_hello_world && \
  exec env - \
    EXPERIMENTAL_SPLIT_XML_GENERATION=1 \
    RUNFILES_DIR=bazel-out/k8-fastbuild/bin/hello_test.runfiles \
    RUN_UNDER_RUNFILES=1 \
    TEST_BINARY=./hello_test \
    TEST_INFRASTRUCTURE_FAILURE_FILE=bazel-out/k8-fastbuild/testlogs/hello_test/test.infrastructure_failure \
    TEST_LOGSPLITTER_OUTPUT_FILE=bazel-out/k8-fastbuild/testlogs/hello_test/test.raw_splitlogs/test.splitlogs \
    TEST_PREMATURE_EXIT_FILE=bazel-out/k8-fastbuild/testlogs/hello_test/test.exited_prematurely \
    TEST_SIZE=medium \
    TEST_SRCDIR=bazel-out/k8-fastbuild/bin/hello_test.runfiles \
    TZ=UTC \
    XML_OUTPUT_FILE=bazel-out/k8-fastbuild/testlogs/hello_test/test.xml \
  bash -c 'pwd && ls')

So bash -c 'pwd && ls' will show the current directory path and content.

Related