Cargo run in an integration test, and unnecessary rebuilds

I have integration tests that invoke cargo run --bin=xyz. They do this (rather than running the binaries from target/) for a number of reasons:

  • To ensure that the binary target is up to date
  • Because something just doesn't feel kosher about peeking into target/
  • When I call things directly from target, sometimes they are missing runtime link paths for dynamic libraries

Unfortunately, sometimes problems arise where the test harness apparently runs in an environment that is sufficiently modified from the original build environment that it triggers a rebuild of a somewhere down the dependency tree. (example: if the test cds into a temporary directory, it won't see a project-local .cargo/config anymore, which might cause it to lose some build flags)

This can turn a quick test into a 20 minute endeavor (ten minutes for the unit test, and then another 10 minutes the next time I build the harness as the environment will be back to normal!). It is a royal pain to debug, and I don't know of any reliable way to tell what exactly caused it to rebuild.

Any tips?

1 Like

Cargo guarantees that binaries are built before integration tests are run.

You may not like it, but that's how the official way to do this looks like :slight_smile: Cargo itself does this itself :slight_smile: It would be awesome to wrap this path shenanigans into a reusable library.

That is problematic, yeah. I am not familiar enough with this bit, so no advice here :frowning:

Playing around with it, it looks like cargo does this by modifying LD_LIBRARY_PATH to add cargo:rustc-link-search direcctories. By comparing the output of env!("LD_LIBRARY_PATH") and std::env::var("LD_LIBRARY_PATH") in an integration test, I see the following entries get added:


Those first four seem highly problematic! There are often unused directories for a crate in build that are leftover from previous builds, and so when there is more than one pair of directories, I see no easy way to tell which one is the correct one!

Wait a second.

I am a dummy.

I just stated that the integration tests see these paths in std::env::var("LD_LIBRARY_PATH"). This means that they should be able to call the binaries in target/ without running into problems....and indeed they can!

Crisis averted, at least for now.

1 Like