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" ''