diff --git a/pkgs/build-support/rust/build-rust-crate/lib.sh b/pkgs/build-support/rust/build-rust-crate/lib.sh
index 5fa9b2f21154..09731f29f0c3 100644
--- a/pkgs/build-support/rust/build-rust-crate/lib.sh
+++ b/pkgs/build-support/rust/build-rust-crate/lib.sh
@@ -87,6 +87,12 @@ build_bin_test_file() {
# above.
derived_crate_name=${derived_crate_name#"tests_"}
derived_crate_name="${derived_crate_name%.rs}"
+ # Cargo names tests/
/main.rs as , not _main — strip the
+ # trailing _main that the `/`→`_` substitution produced. Guarded so
+ # a flat-style tests/_main.rs keeps its _main suffix.
+ if [[ "$file" == */main.rs ]]; then
+ derived_crate_name="${derived_crate_name%_main}"
+ fi
build_bin_test "$derived_crate_name" "$file"
}
diff --git a/pkgs/build-support/rust/build-rust-crate/test/default.nix b/pkgs/build-support/rust/build-rust-crate/test/default.nix
index dafb3ce631d7..854aec414466 100644
--- a/pkgs/build-support/rust/build-rust-crate/test/default.nix
+++ b/pkgs/build-support/rust/build-rust-crate/test/default.nix
@@ -91,9 +91,15 @@ let
mkTest =
crateArgs:
let
- crate = mkHostCrate (removeAttrs crateArgs [ "expectedTestOutput" ]);
+ crate = mkHostCrate (
+ removeAttrs crateArgs [
+ "expectedTestOutputs"
+ "expectedTestBinaries"
+ ]
+ );
hasTests = crateArgs.buildTests or false;
expectedTestOutputs = crateArgs.expectedTestOutputs or null;
+ expectedTestBinaries = crateArgs.expectedTestBinaries or [ ];
binaries = map (v: lib.escapeShellArg v.name) (crateArgs.crateBin or [ ]);
isLib = crateArgs ? libName || crateArgs ? libPath;
crateName = crateArgs.crateName or "nixtestcrate";
@@ -134,6 +140,10 @@ let
''
else if stdenv.hostPlatform == stdenv.buildPlatform then
''
+ ${lib.concatMapStringsSep "\n" (
+ b:
+ "test -x ${crate}/tests/${lib.escapeShellArg b} || { echo 'expected test binary \"${b}\" not found in:'; ls ${crate}/tests; exit 23; }"
+ ) expectedTestBinaries}
for file in ${crate}/tests/*; do
$file 2>&1 >> $out
done
@@ -419,12 +429,34 @@ rec {
];
};
buildTests = true;
+ # Cargo names tests//main.rs as , not _main.
+ expectedTestBinaries = [
+ "foo"
+ "bar"
+ ];
expectedTestOutputs = [
"test src_main ... ok"
"test tests_foo ... ok"
"test tests_bar ... ok"
];
};
+ rustBinTestsFlatMainSuffix = {
+ # A flat-style test whose name happens to end in _main must keep
+ # its suffix — only tests//main.rs gets the _main stripped.
+ src = symlinkJoin {
+ name = "rust-bin-tests-flat-main-suffix";
+ paths = [
+ (mkTestFileWithMain "src/main.rs" "src_main")
+ (mkTestFile "tests/foo_main.rs" "flat_test")
+ ];
+ };
+ buildTests = true;
+ expectedTestBinaries = [ "foo_main" ];
+ expectedTestOutputs = [
+ "test src_main ... ok"
+ "test flat_test ... ok"
+ ];
+ };
linkAgainstRlibCrate = {
crateName = "foo";
src = mkFile "src/main.rs" ''