Does `bazel run` use sandboxing? If not, why not? - bazel

From my tests, it doesn't appear that bazel run runs in a sandbox. For example, I ran bazel run //:some_target --spawn_strategy=darwin-sandbox --sandbox_debug, and it didn't generate a new directory in <outputBase>/sandbox/darwin-sandbox.
Am I correct that bazel run doesn't use sandboxing? If so, why not?

bazel run will build the target you pass with sandboxing and caching the same way as bazel build, and then it will run it outside the sandbox. That's the whole point of bazel run.
If you want to run a command inside the sandbox, write a genrule and then bazel build the genrule target.

Related

Run action/script AFTER the binary executed by "bazel run" returns

I'm wondering if there's a way to run an action or script or program after a bazel run command finishes. Running such a script/program before the bazel run is (in a way) possible via --run_under.
Here's an example use-case:
bazel run //path/to/my:target
Running target generates an output file out in it's cwd (somewhere in the bazel .cache directory)
Run a script that uses the output file out
If it's not possible to get run that script afterwards, is there a way to get the cwd of the binary that was just run? Then it would also be possible to access out from "outside" without bazel.
--run_under is the correct approach to this. You can simply run the command in the script after running what is passed as args to your script that you pass to --run_under e.g.
#!/bin/bash
set -euo pipefail
./prefix_command
bash "$#"
./postfix_command

Is there a way to build tests with bazel without running them?

Every time I run bazel test <targets...> it builds all target test binaries and runs them. Is there a way to only compile them or build them without running them?
You can use bazel build <targets...> to just build those targets without running the tests.

How to avoid deleting cached files after build in Bazel

I have a genrule in Bazel that is supposed to manipulate some files. I think I'm not accessing these files by the correct path, so I want to look at the directory structure that Bazel is creating so I can debug.
I added some echo statements to my genrule and I can see that Bazel is working in the directory /home/lyft/.cache/bazel/_bazel_lyft/8de0a1069de8d166c668173ca21c04ae/sandbox/linux-sandbox/1/execroot/. However, after Bazel finishes running, this directory is gone, so I can't look at the directory structure.
How can I prevent Bazel from deleting its temporary files so that I can debug what's happening?
Since this question is a top result for "keep sandbox files after build bazel" Google search and it wasn't obvious for me from the accepted answer, I feel the need to write this answer.
Short answer
Use --sandbox_debug. If this flag is passed, Bazel will not delete the files inside the sandbox folder after the build finishes.
Longer answer
Run bazel build with --sandbox_debug option:
$ bazel build mypackage:mytarget --sandbox_debug
Then you can inspect the contents of the sandbox folder for the project.
To get the location of the sandbox folder for current project, navigate to project and then run:
$ bazel info output_base
/home/johnsmith/.cache/bazel/_bazel_johnsmith/d949417420413f64a0b619cb69f1db69 # output will be something like this
Inside that directory there will be sandbox folder.
Possible caveat: (I'm NOT sure about this but) It's possible that some of the files are missing in sandbox folder, if you previously ran a build without --sandbox_debug flag and it partially succeeded. The reason is Bazel won't rerun parts of the build that already succeeded, and consequently the files corresponding to the successful build parts might not end up in the sandbox.
If you want to make sure all the sandbox files are there, clean the project first using either bazel clean or bazel clean --expunge.
You can use --spawn_strategy=standalone.
You can also use --sandbox_debug to see which directories are mounted to the sandbox.
You can also set the genrule's cmd to find . > $# to debug what's available to the genrule.
Important: declare all srcs/outs/tools that the genrule will read/write/use, and use $(location //label/of:target) to look up their path. Example:
genrule(
name = "x1",
srcs = ["//foo:input1.txt", "//bar:generated_file"],
outs = ["x1out.txt", "x1err.txt"],
tools = ["//util:bin1"],
cmd = "$(location //util:bin1) --input1=$(location //foo:input1.txt) --input2=$(location //bar:generated_file) --some_flag --other_flag >$(location x1out.txt) 2>$(location x1err.txt)",
)

How to specify "default" target labels when running bazel test

We're considering migrating to Bazel from Make. To make the transition easier I would like to have bazel test (no flags / options) run the current directory's tests, if any.
So instead of bazel test my_tests bazel test would find the current directory's BUILD file, find any *_test rules and run those.
If you want to do exactly as you said then you can use your own script.
When you run “bazel” it actually looks to see if there is a script named “bazel” under tools directory of the current workspace. So if you have an executable under “$workspace/tools/bazel” bazel will run that instead of the bazel binary itself.
This means you can write a script that checks if the only argument is “test” and if so calls “bazel-real test :all”
It can also check the exit code to see if there were no tests (it’s a specific error code) and return 0 instead
You can use the all target pattern to match all targets in the current package: bazel test :all
You can read more about it here: https://docs.bazel.build/versions/master/user-manual.html#target-patterns
Note however that if there are no test targets in the current package, bazel will give an error: "ERROR: No test targets were found, yet testing was requested.". In this case bazel will give an exit code of 4: https://docs.bazel.build/versions/master/user-manual.html#what-exit-code-will-i-get
I recommend creating a alias called bazel-test to bazel test :all.

Running bazel build with an aspect on test targets does not yield test output jars

running bazel build //... \
--aspects some-aspect.bzl%some_aspect \
--output_groups=some_new_output,default
does not create test jars outputs.
on the other hand running bazel test does create the test jar outputs:
bazel test //... \
--aspects some-aspect.bzl%some_aspect \
--output_groups=some_new_output,default
How come?
This question was updated to reflect use of aspects:
The original question:
running bazel build //... does not add test code to output jar.
on the other hand bazel test //... builds the test code but also
runs it.
Is there a way in bazel to build the test code without running the
tests?
I had a mistake in the values I gave the --output_groups flag.
It should have been --output_groups=+some_new_output,+default
The default can even be omitted:
--output_groups=+some_new_output
This flag is not documented at all. There is an open issue on this in bazel github repo.
You may be looking for --build_tests_only.

Resources