`cargo test` and `RUSTC_LOG` only tests, not dependencies

I'm modifying the Rust compiler for a project. I've built my own toolchain called stage1. To test my project, I'd like to run tests with cargo +stage1 test and observe the compiler's logging output using RUSTC_LOG.

Goal: Logging output from the Rust compiler compiling my tests

Attempt: RUSTC_LOG=rustc_mir::transform=info cargo +stage1 test (for example)

Result: ALL logging output from compiling my dependencies (libc, rand, etc.) as well as my tests.
I don't want to see the logs from libc, rand, etc.. I only want to see the logs from compiling my tests.

Is there a way to achieve this?

This would definitely be a workaround solution, but what about running cargo build first? That should build at least most of the dependencies so they don't have to be rebuilt... Or if you're willing to have just the info from external tests, you could run cargo test --lib first, to compile all dev dependencies & the library first, and then run cargo test with RUSTC_LOG set to get only the external tests' output.

A more exact solution would be to use cargo's json message format and write a tool which parses it to figure out when each package is being built. Specifically, if you run cargo test -j 1 --message-format json, it will output a json string for every build start/stop, and the -j 1 flag should ensure no two things build simultaneously. This would require writing a custom script, but I think it should be doable, and won't be that hacky.

1 Like

Another workaround is to run cargo +stage1 test -v to obtain the arguments with which cargo invoked rustc for your tests, then run RUSTC_LOG=... rustc <args>.

1 Like

Thanks for your responses :smiley: Here is my workflow now:

  1. cargo +stage1 build as @daboross recommended to build most of the tests' dependencies.
  2. RUSTC_LOG=... cargo +stage1 test to build any extra dependencies, but ignore the extra logs.
  3. Trivially touch/edit one of the test files (e.g. change a constant)
  4. RUSTC_LOG=... cargo +stage1 test -- this time, only the changed test file is rebuilt and I can read through the relevant logs by piping output to a file (RUSTC_LOG=... cargo +stage1 test &> out.log).

This isn't the cleanest, but it's sufficient for my work. I might put this in a Makefile eventually. Thank you @sinkuu as well; breaking down a cargo command with -v is a super useful tip!

Some further learnings:

Forcing rebuilds

cargo test caches the executable and any extra types of output you asked it to --emit in target/debug/deps/my_file_HASH, target/debug/deps/my_file_HASH.mir, etc. for some file my_test.rs. cargo adds a hash to the end of the file name.

cargo caches the compiler logs as well, so even if you build a new version of the compiler and run cargo +stage1 test again you see the same log output. I get around this in two ways:

  1. As I mentioned in the previous post, slightly modify the function whose build logs/MIR I'm interested in inspecting.
  2. Delete target/debug/deps/my_file_HASH*.

Building a specific test

cargo runs the test files in tests/ in alphabetical order and halts if a test file has a failing test. That means if tests/bar.rs has one failing test then cargo will not build tests/foo.rs (and therefore you will not see new compiler logs).

If I want to see test results from tests/foo.rs despite this, I just rename it to tests/a_foo.rs and delete target/debug/deps/foo_HASH*. :stuck_out_tongue:

1 Like