python312Packages.powerfox: init at 1.1.0 (#371207)
[NixPkgs.git] / pkgs / build-support / rust / build-rust-crate / test / default.nix
blobfdfc8fdef01effb02726343cb35d670c29007e5a
2   lib,
3   buildPackages,
4   buildRustCrate,
5   callPackage,
6   releaseTools,
7   runCommand,
8   runCommandCC,
9   stdenv,
10   symlinkJoin,
11   writeTextFile,
12   pkgsCross,
15 let
16   mkCrate =
17     buildRustCrate: args:
18     let
19       p = {
20         crateName = "nixtestcrate";
21         version = "0.1.0";
22         authors = [ "Test <test@example.com>" ];
23       } // args;
24     in
25     buildRustCrate p;
26   mkHostCrate = mkCrate buildRustCrate;
28   mkCargoToml =
29     {
30       name,
31       crateVersion ? "0.1.0",
32       path ? "Cargo.toml",
33     }:
34     mkFile path ''
35       [package]
36       name = ${builtins.toJSON name}
37       version = ${builtins.toJSON crateVersion}
38     '';
40   mkFile =
41     destination: text:
42     writeTextFile {
43       name = "src";
44       destination = "/${destination}";
45       inherit text;
46     };
48   mkBin =
49     name:
50     mkFile name ''
51       use std::env;
52       fn main() {
53         let name: String = env::args().nth(0).unwrap();
54         println!("executed {}", name);
55       }
56     '';
58   mkBinExtern =
59     name: extern:
60     mkFile name ''
61       extern crate ${extern};
62       fn main() {
63         assert_eq!(${extern}::test(), 23);
64       }
65     '';
67   mkTestFile =
68     name: functionName:
69     mkFile name ''
70       #[cfg(test)]
71       #[test]
72       fn ${functionName}() {
73         assert!(true);
74       }
75     '';
76   mkTestFileWithMain =
77     name: functionName:
78     mkFile name ''
79       #[cfg(test)]
80       #[test]
81       fn ${functionName}() {
82         assert!(true);
83       }
85       fn main() {}
86     '';
88   mkLib = name: mkFile name "pub fn test() -> i32 { return 23; }";
90   mkTest =
91     crateArgs:
92     let
93       crate = mkHostCrate (builtins.removeAttrs crateArgs [ "expectedTestOutput" ]);
94       hasTests = crateArgs.buildTests or false;
95       expectedTestOutputs = crateArgs.expectedTestOutputs or null;
96       binaries = map (v: lib.escapeShellArg v.name) (crateArgs.crateBin or [ ]);
97       isLib = crateArgs ? libName || crateArgs ? libPath;
98       crateName = crateArgs.crateName or "nixtestcrate";
99       libName = crateArgs.libName or crateName;
101       libTestBinary =
102         if !isLib then
103           null
104         else
105           mkHostCrate {
106             crateName = "run-test-${crateName}";
107             dependencies = [ crate ];
108             src = mkBinExtern "src/main.rs" libName;
109           };
111     in
112     assert expectedTestOutputs != null -> hasTests;
113     assert hasTests -> expectedTestOutputs != null;
115     runCommand "run-buildRustCrate-${crateName}-test"
116       {
117         nativeBuildInputs = [ crate ];
118       }
119       (
120         if !hasTests then
121           ''
122             ${lib.concatMapStringsSep "\n" (
123               binary:
124               # Can't actually run the binary when cross-compiling
125               (lib.optionalString (stdenv.hostPlatform != stdenv.buildPlatform) "type ") + binary
126             ) binaries}
127             ${lib.optionalString isLib ''
128               test -e ${crate}/lib/*.rlib || exit 1
129               ${lib.optionalString (stdenv.hostPlatform != stdenv.buildPlatform) "test -x "} \
130                 ${libTestBinary}/bin/run-test-${crateName}
131             ''}
132             touch $out
133           ''
134         else if stdenv.hostPlatform == stdenv.buildPlatform then
135           ''
136             for file in ${crate}/tests/*; do
137               $file 2>&1 >> $out
138             done
139             set -e
140             ${lib.concatMapStringsSep "\n" (
141               o: "grep '${o}' $out || {  echo 'output \"${o}\" not found in:'; cat $out; exit 23; }"
142             ) expectedTestOutputs}
143           ''
144         else
145           ''
146             for file in ${crate}/tests/*; do
147               test -x "$file"
148             done
149             touch "$out"
150           ''
151       );
153   /*
154     Returns a derivation that asserts that the crate specified by `crateArgs`
155     has the specified files as output.
157     `name` is used as part of the derivation name that performs the checking.
159     `mkCrate` can be used to override the `mkCrate` call/implementation to use to
160     override the `buildRustCrate`, useful for cross compilation. Uses `mkHostCrate` by default.
162     `crateArgs` is passed to `mkCrate` to build the crate with `buildRustCrate`
164     `expectedFiles` contains a list of expected file paths in the output. E.g.
165     `[ "./bin/my_binary" ]`.
167     `output` specifies the name of the output to use. By default, the default
168     output is used but e.g. `output = "lib";` will cause the lib output
169     to be checked instead. You do not need to specify any directories.
170   */
171   assertOutputs =
172     {
173       name,
174       mkCrate ? mkHostCrate,
175       crateArgs,
176       expectedFiles,
177       output ? null,
178     }:
179     assert (builtins.isString name);
180     assert (builtins.isAttrs crateArgs);
181     assert (builtins.isList expectedFiles);
183     let
184       crate = mkCrate (builtins.removeAttrs crateArgs [ "expectedTestOutput" ]);
185       crateOutput = if output == null then crate else crate."${output}";
186       expectedFilesFile = writeTextFile {
187         name = "expected-files-${name}";
188         text =
189           let
190             sorted = builtins.sort (a: b: a < b) expectedFiles;
191             concatenated = builtins.concatStringsSep "\n" sorted;
192           in
193           "${concatenated}\n";
194       };
195     in
196     runCommand "assert-outputs-${name}"
197       {
198       }
199       (
200         ''
201           local actualFiles=$(mktemp)
203           cd "${crateOutput}"
204           find . -type f \
205             | sort \
206         ''
207         # sed out the hash because it differs per platform
208         + ''
209             | sed 's/-${crate.metadata}//g' \
210             > "$actualFiles"
211           diff -q ${expectedFilesFile} "$actualFiles" > /dev/null || {
212             echo -e "\033[0;1;31mERROR: Difference in expected output files in ${crateOutput} \033[0m" >&2
213             echo === Got:
214             sed -e 's/^/  /' $actualFiles
215             echo === Expected:
216             sed -e 's/^/  /' ${expectedFilesFile}
217             echo === Diff:
218             diff -u ${expectedFilesFile} $actualFiles |\
219               tail -n +3 |\
220               sed -e 's/^/  /'
221             exit 1
222           }
223           touch $out
224         ''
225       );
228 rec {
230   tests =
231     let
232       cases = rec {
233         libPath = {
234           libPath = "src/my_lib.rs";
235           src = mkLib "src/my_lib.rs";
236         };
237         srcLib = {
238           src = mkLib "src/lib.rs";
239         };
241         # This used to be supported by cargo but as of 1.40.0 I can't make it work like that with just cargo anymore.
242         # This might be a regression or deprecated thing they finally removed…
243         # customLibName =  { libName = "test_lib"; src = mkLib "src/test_lib.rs"; };
244         # rustLibTestsCustomLibName = {
245         #   libName = "test_lib";
246         #   src = mkTestFile "src/test_lib.rs" "foo";
247         #   buildTests = true;
248         #   expectedTestOutputs = [ "test foo ... ok" ];
249         # };
251         customLibNameAndLibPath = {
252           libName = "test_lib";
253           libPath = "src/best-lib.rs";
254           src = mkLib "src/best-lib.rs";
255         };
256         crateBinWithPath = {
257           crateBin = [
258             {
259               name = "test_binary1";
260               path = "src/foobar.rs";
261             }
262           ];
263           src = mkBin "src/foobar.rs";
264         };
265         crateBinNoPath1 = {
266           crateBin = [ { name = "my-binary2"; } ];
267           src = mkBin "src/my_binary2.rs";
268         };
269         crateBinNoPath2 = {
270           crateBin = [
271             { name = "my-binary3"; }
272             { name = "my-binary4"; }
273           ];
274           src = symlinkJoin {
275             name = "buildRustCrateMultipleBinariesCase";
276             paths = [
277               (mkBin "src/bin/my_binary3.rs")
278               (mkBin "src/bin/my_binary4.rs")
279             ];
280           };
281         };
282         crateBinNoPath3 = {
283           crateBin = [ { name = "my-binary5"; } ];
284           src = mkBin "src/bin/main.rs";
285         };
286         crateBinNoPath4 = {
287           crateBin = [ { name = "my-binary6"; } ];
288           src = mkBin "src/main.rs";
289         };
290         crateBinRename1 = {
291           crateBin = [ { name = "my-binary-rename1"; } ];
292           src = mkBinExtern "src/main.rs" "foo_renamed";
293           dependencies = [
294             (mkHostCrate {
295               crateName = "foo";
296               src = mkLib "src/lib.rs";
297             })
298           ];
299           crateRenames = {
300             "foo" = "foo_renamed";
301           };
302         };
303         crateBinRename2 = {
304           crateBin = [ { name = "my-binary-rename2"; } ];
305           src = mkBinExtern "src/main.rs" "foo_renamed";
306           dependencies = [
307             (mkHostCrate {
308               crateName = "foo";
309               libName = "foolib";
310               src = mkLib "src/lib.rs";
311             })
312           ];
313           crateRenames = {
314             "foo" = "foo_renamed";
315           };
316         };
317         crateBinRenameMultiVersion =
318           let
319             crateWithVersion =
320               version:
321               mkHostCrate {
322                 crateName = "my_lib";
323                 inherit version;
324                 src = mkFile "src/lib.rs" ''
325                   pub const version: &str = "${version}";
326                 '';
327               };
328             depCrate01 = crateWithVersion "0.1.2";
329             depCrate02 = crateWithVersion "0.2.1";
330           in
331           {
332             crateName = "my_bin";
333             src = symlinkJoin {
334               name = "my_bin_src";
335               paths = [
336                 (mkFile "src/main.rs" ''
337                   #[test]
338                   fn my_lib_01() { assert_eq!(lib01::version, "0.1.2"); }
340                   #[test]
341                   fn my_lib_02() { assert_eq!(lib02::version, "0.2.1"); }
343                   fn main() { }
344                 '')
345               ];
346             };
347             dependencies = [
348               depCrate01
349               depCrate02
350             ];
351             crateRenames = {
352               "my_lib" = [
353                 {
354                   version = "0.1.2";
355                   rename = "lib01";
356                 }
357                 {
358                   version = "0.2.1";
359                   rename = "lib02";
360                 }
361               ];
362             };
363             buildTests = true;
364             expectedTestOutputs = [
365               "test my_lib_01 ... ok"
366               "test my_lib_02 ... ok"
367             ];
368           };
369         rustLibTestsDefault = {
370           src = mkTestFile "src/lib.rs" "baz";
371           buildTests = true;
372           expectedTestOutputs = [ "test baz ... ok" ];
373         };
374         rustLibTestsCustomLibPath = {
375           libPath = "src/test_path.rs";
376           src = mkTestFile "src/test_path.rs" "bar";
377           buildTests = true;
378           expectedTestOutputs = [ "test bar ... ok" ];
379         };
380         rustLibTestsCustomLibPathWithTests = {
381           libPath = "src/test_path.rs";
382           src = symlinkJoin {
383             name = "rust-lib-tests-custom-lib-path-with-tests-dir";
384             paths = [
385               (mkTestFile "src/test_path.rs" "bar")
386               (mkTestFile "tests/something.rs" "something")
387             ];
388           };
389           buildTests = true;
390           expectedTestOutputs = [
391             "test bar ... ok"
392             "test something ... ok"
393           ];
394         };
395         rustBinTestsCombined = {
396           src = symlinkJoin {
397             name = "rust-bin-tests-combined";
398             paths = [
399               (mkTestFileWithMain "src/main.rs" "src_main")
400               (mkTestFile "tests/foo.rs" "tests_foo")
401               (mkTestFile "tests/bar.rs" "tests_bar")
402             ];
403           };
404           buildTests = true;
405           expectedTestOutputs = [
406             "test src_main ... ok"
407             "test tests_foo ... ok"
408             "test tests_bar ... ok"
409           ];
410         };
411         rustBinTestsSubdirCombined = {
412           src = symlinkJoin {
413             name = "rust-bin-tests-subdir-combined";
414             paths = [
415               (mkTestFileWithMain "src/main.rs" "src_main")
416               (mkTestFile "tests/foo/main.rs" "tests_foo")
417               (mkTestFile "tests/bar/main.rs" "tests_bar")
418             ];
419           };
420           buildTests = true;
421           expectedTestOutputs = [
422             "test src_main ... ok"
423             "test tests_foo ... ok"
424             "test tests_bar ... ok"
425           ];
426         };
427         linkAgainstRlibCrate = {
428           crateName = "foo";
429           src = mkFile "src/main.rs" ''
430             extern crate somerlib;
431             fn main() {}
432           '';
433           dependencies = [
434             (mkHostCrate {
435               crateName = "somerlib";
436               type = [ "rlib" ];
437               src = mkLib "src/lib.rs";
438             })
439           ];
440         };
441         buildScriptDeps =
442           let
443             depCrate =
444               buildRustCrate: boolVal:
445               mkCrate buildRustCrate {
446                 crateName = "bar";
447                 src = mkFile "src/lib.rs" ''
448                   pub const baz: bool = ${boolVal};
449                 '';
450               };
451           in
452           {
453             crateName = "foo";
454             src = symlinkJoin {
455               name = "build-script-and-main";
456               paths = [
457                 (mkFile "src/main.rs" ''
458                   extern crate bar;
459                   #[cfg(test)]
460                   #[test]
461                   fn baz_false() { assert!(!bar::baz); }
462                   fn main() { }
463                 '')
464                 (mkFile "build.rs" ''
465                   extern crate bar;
466                   fn main() { assert!(bar::baz); }
467                 '')
468               ];
469             };
470             buildDependencies = [ (depCrate buildPackages.buildRustCrate "true") ];
471             dependencies = [ (depCrate buildRustCrate "false") ];
472             buildTests = true;
473             expectedTestOutputs = [ "test baz_false ... ok" ];
474           };
475         buildScriptFeatureEnv = {
476           crateName = "build-script-feature-env";
477           features = [
478             "some-feature"
479             "crate/another_feature"
480           ];
481           src = symlinkJoin {
482             name = "build-script-feature-env";
483             paths = [
484               (mkFile "src/main.rs" ''
485                 #[cfg(test)]
486                 #[test]
487                 fn feature_not_visible() {
488                   assert!(std::env::var("CARGO_FEATURE_SOME_FEATURE").is_err());
489                   assert!(option_env!("CARGO_FEATURE_SOME_FEATURE").is_none());
490                 }
491                 fn main() {}
492               '')
493               (mkFile "build.rs" ''
494                 fn main() {
495                   assert!(std::env::var("CARGO_FEATURE_SOME_FEATURE").is_ok());
496                   assert!(option_env!("CARGO_FEATURE_SOME_FEATURE").is_none());
497                 }
498               '')
499             ];
500           };
501           buildTests = true;
502           expectedTestOutputs = [ "test feature_not_visible ... ok" ];
503         };
504         # Regression test for https://github.com/NixOS/nixpkgs/pull/88054
505         # Build script output should be rewritten as valid env vars.
506         buildScriptIncludeDirDeps =
507           let
508             depCrate = mkHostCrate {
509               crateName = "bar";
510               src = symlinkJoin {
511                 name = "build-script-and-include-dir-bar";
512                 paths = [
513                   (mkFile "src/lib.rs" ''
514                     fn main() { }
515                   '')
516                   (mkFile "build.rs" ''
517                     use std::path::PathBuf;
518                     fn main() { println!("cargo:include-dir={}/src", std::env::current_dir().unwrap_or(PathBuf::from(".")).to_str().unwrap()); }
519                   '')
520                 ];
521               };
522             };
523           in
524           {
525             crateName = "foo";
526             src = symlinkJoin {
527               name = "build-script-and-include-dir-foo";
528               paths = [
529                 (mkFile "src/main.rs" ''
530                   fn main() { }
531                 '')
532                 (mkFile "build.rs" ''
533                   fn main() { assert!(std::env::var_os("DEP_BAR_INCLUDE_DIR").is_some()); }
534                 '')
535               ];
536             };
537             buildDependencies = [ depCrate ];
538             dependencies = [ depCrate ];
539           };
540         # Support new invocation prefix for build scripts `cargo::`
541         # https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script
542         buildScriptInvocationPrefix =
543           let
544             depCrate =
545               buildRustCrate:
546               mkCrate buildRustCrate {
547                 crateName = "bar";
548                 src = mkFile "build.rs" ''
549                   fn main() {
550                     // Old invocation prefix
551                     // We likely won't see be mixing these syntaxes in the same build script in the wild.
552                     println!("cargo:key_old=value_old");
554                     // New invocation prefix
555                     println!("cargo::metadata=key=value");
556                     println!("cargo::metadata=key_complex=complex(value)");
557                   }
558                 '';
559               };
560           in
561           {
562             crateName = "foo";
563             src = symlinkJoin {
564               name = "build-script-and-main-invocation-prefix";
565               paths = [
566                 (mkFile "src/main.rs" ''
567                   const BUILDFOO: &'static str = env!("BUILDFOO");
569                   #[test]
570                   fn build_foo_check() { assert!(BUILDFOO == "yes(check)"); }
572                   fn main() { }
573                 '')
574                 (mkFile "build.rs" ''
575                   use std::env;
576                   fn main() {
577                     assert!(env::var_os("DEP_BAR_KEY_OLD").expect("metadata key 'key_old' not set in dependency") == "value_old");
578                     assert!(env::var_os("DEP_BAR_KEY").expect("metadata key 'key' not set in dependency") == "value");
579                     assert!(env::var_os("DEP_BAR_KEY_COMPLEX").expect("metadata key 'key_complex' not set in dependency") == "complex(value)");
581                     println!("cargo::rustc-env=BUILDFOO=yes(check)");
582                   }
583                 '')
584               ];
585             };
586             buildDependencies = [ (depCrate buildPackages.buildRustCrate) ];
587             dependencies = [ (depCrate buildRustCrate) ];
588             buildTests = true;
589             expectedTestOutputs = [ "test build_foo_check ... ok" ];
590           };
591         # Regression test for https://github.com/NixOS/nixpkgs/issues/74071
592         # Whenevever a build.rs file is generating files those should not be overlayed onto the actual source dir
593         buildRsOutDirOverlay = {
594           src = symlinkJoin {
595             name = "buildrs-out-dir-overlay";
596             paths = [
597               (mkLib "src/lib.rs")
598               (mkFile "build.rs" ''
599                 use std::env;
600                 use std::ffi::OsString;
601                 use std::fs;
602                 use std::path::Path;
603                 fn main() {
604                   let out_dir = env::var_os("OUT_DIR").expect("OUT_DIR not set");
605                   let out_file = Path::new(&out_dir).join("lib.rs");
606                   fs::write(out_file, "invalid rust code!").expect("failed to write lib.rs");
607                 }
608               '')
609             ];
610           };
611         };
612         # Regression test for https://github.com/NixOS/nixpkgs/pull/83379
613         # link flag order should be preserved
614         linkOrder = {
615           src = symlinkJoin {
616             name = "buildrs-out-dir-overlay";
617             paths = [
618               (mkFile "build.rs" ''
619                 fn main() {
620                   // in the other order, linkage will fail
621                   println!("cargo:rustc-link-lib=b");
622                   println!("cargo:rustc-link-lib=a");
623                 }
624               '')
625               (mkFile "src/main.rs" ''
626                 extern "C" {
627                   fn hello_world();
628                 }
629                 fn main() {
630                   unsafe {
631                     hello_world();
632                   }
633                 }
634               '')
635             ];
636           };
637           buildInputs =
638             let
639               compile =
640                 name: text:
641                 let
642                   src = writeTextFile {
643                     name = "${name}-src.c";
644                     inherit text;
645                   };
646                 in
647                 runCommandCC name { } ''
648                   mkdir -p $out/lib
649                   # Note: On darwin (which defaults to clang) we have to add
650                   # `-undefined dynamic_lookup` as otherwise the compilation fails.
651                   $CC -shared \
652                     ${lib.optionalString stdenv.hostPlatform.isDarwin "-undefined dynamic_lookup"} \
653                     -o $out/lib/${name}${stdenv.hostPlatform.extensions.library} ${src}
654                 '';
655               b = compile "libb" ''
656                 #include <stdio.h>
658                 void hello();
660                 void hello_world() {
661                   hello();
662                   printf(" world!\n");
663                 }
664               '';
665               a = compile "liba" ''
666                 #include <stdio.h>
668                 void hello() {
669                   printf("hello");
670                 }
671               '';
672             in
673             [
674               a
675               b
676             ];
677         };
678         rustCargoTomlInSubDir = {
679           # The "workspace_member" can be set to the sub directory with the crate to build.
680           # By default ".", meaning the top level directory is assumed.
681           # Using null will trigger a search.
682           workspace_member = null;
683           src = symlinkJoin rec {
684             name = "find-cargo-toml";
685             paths = [
686               (mkCargoToml { name = "ignoreMe"; })
687               (mkTestFileWithMain "src/main.rs" "ignore_main")
689               (mkCargoToml {
690                 name = "rustCargoTomlInSubDir";
691                 path = "subdir/Cargo.toml";
692               })
693               (mkTestFileWithMain "subdir/src/main.rs" "src_main")
694               (mkTestFile "subdir/tests/foo/main.rs" "tests_foo")
695               (mkTestFile "subdir/tests/bar/main.rs" "tests_bar")
696             ];
697           };
698           buildTests = true;
699           expectedTestOutputs = [
700             "test src_main ... ok"
701             "test tests_foo ... ok"
702             "test tests_bar ... ok"
703           ];
704         };
706         rustCargoTomlInTopDir =
707           let
708             withoutCargoTomlSearch = builtins.removeAttrs rustCargoTomlInSubDir [ "workspace_member" ];
709           in
710           withoutCargoTomlSearch
711           // {
712             expectedTestOutputs = [
713               "test ignore_main ... ok"
714             ];
715           };
716         procMacroInPrelude = {
717           procMacro = true;
718           edition = "2018";
719           src = symlinkJoin {
720             name = "proc-macro-in-prelude";
721             paths = [
722               (mkFile "src/lib.rs" ''
723                 use proc_macro::TokenTree;
724               '')
725             ];
726           };
727         };
728       };
729       brotliCrates = (callPackage ./brotli-crates.nix { });
730       rcgenCrates = callPackage ./rcgen-crates.nix {
731         # Suppress deprecation warning
732         buildRustCrate = null;
733       };
734       tests = lib.mapAttrs (
735         key: value: mkTest (value // lib.optionalAttrs (!value ? crateName) { crateName = key; })
736       ) cases;
737     in
738     tests
739     // rec {
741       crateBinWithPathOutputs = assertOutputs {
742         name = "crateBinWithPath";
743         crateArgs = {
744           crateBin = [
745             {
746               name = "test_binary1";
747               path = "src/foobar.rs";
748             }
749           ];
750           src = mkBin "src/foobar.rs";
751         };
752         expectedFiles = [
753           "./bin/test_binary1"
754         ];
755       };
757       crateBinWithPathOutputsDebug = assertOutputs {
758         name = "crateBinWithPath";
759         crateArgs = {
760           release = false;
761           crateBin = [
762             {
763               name = "test_binary1";
764               path = "src/foobar.rs";
765             }
766           ];
767           src = mkBin "src/foobar.rs";
768         };
769         expectedFiles =
770           [
771             "./bin/test_binary1"
772           ]
773           ++ lib.optionals stdenv.hostPlatform.isDarwin [
774             # On Darwin, the debug symbols are in a separate directory.
775             "./bin/test_binary1.dSYM/Contents/Info.plist"
776             "./bin/test_binary1.dSYM/Contents/Resources/DWARF/test_binary1"
777           ];
778       };
780       crateBinNoPath1Outputs = assertOutputs {
781         name = "crateBinNoPath1";
782         crateArgs = {
783           crateBin = [ { name = "my-binary2"; } ];
784           src = mkBin "src/my_binary2.rs";
785         };
786         expectedFiles = [
787           "./bin/my-binary2"
788         ];
789       };
791       crateLibOutputs = assertOutputs {
792         name = "crateLib";
793         output = "lib";
794         crateArgs = {
795           libName = "test_lib";
796           type = [ "rlib" ];
797           libPath = "src/lib.rs";
798           src = mkLib "src/lib.rs";
799         };
800         expectedFiles = [
801           "./nix-support/propagated-build-inputs"
802           "./lib/libtest_lib.rlib"
803           "./lib/link"
804         ];
805       };
807       crateLibOutputsDebug = assertOutputs {
808         name = "crateLib";
809         output = "lib";
810         crateArgs = {
811           release = false;
812           libName = "test_lib";
813           type = [ "rlib" ];
814           libPath = "src/lib.rs";
815           src = mkLib "src/lib.rs";
816         };
817         expectedFiles = [
818           "./nix-support/propagated-build-inputs"
819           "./lib/libtest_lib.rlib"
820           "./lib/link"
821         ];
822       };
824       crateLibOutputsWasm32 = assertOutputs {
825         name = "wasm32-crate-lib";
826         output = "lib";
827         mkCrate = mkCrate pkgsCross.wasm32-unknown-none.buildRustCrate;
828         crateArgs = {
829           libName = "test_lib";
830           type = [ "cdylib" ];
831           libPath = "src/lib.rs";
832           src = mkLib "src/lib.rs";
833         };
834         expectedFiles = [
835           "./nix-support/propagated-build-inputs"
836           "./lib/test_lib.wasm"
837           "./lib/link"
838         ];
839       };
841       brotliTest =
842         let
843           pkg = brotliCrates.brotli_2_5_0 { };
844         in
845         runCommand "run-brotli-test-cmd"
846           {
847             nativeBuildInputs = [ pkg ];
848           }
849           (
850             if stdenv.hostPlatform == stdenv.buildPlatform then
851               ''
852                 ${pkg}/bin/brotli -c ${pkg}/bin/brotli > /dev/null && touch $out
853               ''
854             else
855               ''
856                 test -x '${pkg}/bin/brotli' && touch $out
857               ''
858           );
859       allocNoStdLibTest =
860         let
861           pkg = brotliCrates.alloc_no_stdlib_1_3_0 { };
862         in
863         runCommand "run-alloc-no-stdlib-test-cmd"
864           {
865             nativeBuildInputs = [ pkg ];
866           }
867           ''
868             test -e ${pkg}/bin/example && touch $out
869           '';
870       brotliDecompressorTest =
871         let
872           pkg = brotliCrates.brotli_decompressor_1_3_1 { };
873         in
874         runCommand "run-brotli-decompressor-test-cmd"
875           {
876             nativeBuildInputs = [ pkg ];
877           }
878           ''
879             test -e ${pkg}/bin/brotli-decompressor && touch $out
880           '';
882       rcgenTest =
883         let
884           pkg = rcgenCrates.rootCrate.build;
885         in
886         runCommand "run-rcgen-test-cmd"
887           {
888             nativeBuildInputs = [ pkg ];
889           }
890           (
891             if stdenv.hostPlatform == stdenv.buildPlatform then
892               ''
893                 ${pkg}/bin/rcgen && touch $out
894               ''
895             else
896               ''
897                 test -x '${pkg}/bin/rcgen' && touch $out
898               ''
899           );
900     };
901   test = releaseTools.aggregate {
902     name = "buildRustCrate-tests";
903     meta = {
904       description = "Test cases for buildRustCrate";
905       maintainers = [ ];
906     };
907     constituents = builtins.attrValues tests;
908   };