Loading pkgs/build-support/testers/default.nix +8 −19 Original line number Diff line number Diff line { pkgs, pkgsLinux, buildPackages, lib, callPackage, runCommand, stdenv, substituteAll, testers }: { pkgs, pkgsLinux, buildPackages, diffoscopeMinimal, lib, callPackage, runCommand, stdenv, substituteAll, testers }: # Documentation is in doc/build-helpers/testers.chapter.md { # See https://nixos.org/manual/nixpkgs/unstable/#tester-lycheeLinkCheck Loading Loading @@ -27,33 +27,22 @@ expected, }: runCommand "equal-contents-${lib.strings.toLower assertion}" { inherit assertion actual expected; nativeBuildInputs = [ diffoscopeMinimal ]; } '' echo "Checking:" echo "$assertion" if ! diff -U5 -r "$actual" "$expected" --color=always printf '%s\n' "$assertion" if ! diffoscope --no-progress --text-color=always --exclude-directory-metadata=no -- "$actual" "$expected" then echo echo 'Contents must be equal, but were not!' echo echo "+: expected, at $expected" echo "-: unexpected, at $actual" exit 1 else find "$expected" -type f -executable > expected-executables | sort find "$actual" -type f -executable > actual-executables | sort if ! diff -U0 actual-executables expected-executables --color=always then echo echo "Contents must be equal, but some files' executable bits don't match" echo echo "+: make this file executable in the actual contents" echo "-: make this file non-executable in the actual contents" exit 1 false else echo "expected $expected and actual $actual match." echo 'OK' touch $out fi echo OK touch -- "$out" fi ''; Loading pkgs/build-support/testers/test/default.nix +116 −98 Original line number Diff line number Diff line { testers, lib, pkgs, hello, runCommand, ... }: { testers, lib, pkgs, hello, runCommand, emptyFile, emptyDirectory, ... }: let pkgs-with-overlay = pkgs.extend(final: prev: { proof-of-overlay-hello = prev.hello; Loading Loading @@ -99,117 +99,135 @@ lib.recurseIntoAttrs { }; testEqualContents = lib.recurseIntoAttrs { happy = testers.testEqualContents { equalDir = testers.testEqualContents { assertion = "The same directory contents at different paths are recognized as equal"; expected = runCommand "expected" { } '' mkdir -p $out/c echo a >$out/a echo b >$out/b echo d >$out/c/d mkdir -p -- "$out/c" echo a >"$out/a" echo b >"$out/b" echo d >"$out/c/d" echo e >"$out/e" chmod a+x -- "$out/e" ''; actual = runCommand "actual" { } '' mkdir -p $out/c echo a >$out/a echo b >$out/b echo d >$out/c/d mkdir -p -- "$out/c" echo a >"$out/a" echo b >"$out/b" echo d >"$out/c/d" echo e >"$out/e" chmod a+x -- "$out/e" ''; }; unequalExe = runCommand "testEqualContents-unequalExe" { log = testers.testBuildFailure (testers.testEqualContents { assertion = "The same directory contents at different paths are recognized as equal"; fileMissing = testers.testBuildFailure ( testers.testEqualContents { assertion = "Directories with different file list are not recognized as equal"; expected = runCommand "expected" { } '' mkdir -p $out/c echo a >$out/a chmod a+x $out/a echo b >$out/b echo d >$out/c/d mkdir -p -- "$out/c" echo a >"$out/a" echo b >"$out/b" echo d >"$out/c/d" ''; actual = runCommand "actual" { } '' mkdir -p $out/c echo a >$out/a echo b >$out/b chmod a+x $out/b echo d >$out/c/d mkdir -p -- "$out/c" echo a >"$out/a" echo d >"$out/c/d" ''; }); } '' ( set -x grep -F -- "executable bits don't match" $log/testBuildFailure.log grep -E -- '+.*-actual/a' $log/testBuildFailure.log grep -E -- '-.*-actual/b' $log/testBuildFailure.log grep -F -- "--- actual-executables" $log/testBuildFailure.log grep -F -- "+++ expected-executables" $log/testBuildFailure.log ) || { echo "Test failed: could not find pattern in build log $log" exit 1 } echo 'All good.' touch $out ); equalExe = testers.testEqualContents { assertion = "The same executable file contents at different paths are recognized as equal"; expected = runCommand "expected" { } '' echo test >"$out" chmod a+x -- "$out" ''; actual = runCommand "actual" { } '' echo test >"$out" chmod a+x -- "$out" ''; }; fileDiff = runCommand "testEqualContents-fileDiff" { log = testers.testBuildFailure (testers.testEqualContents { assertion = "The same directory contents at different paths are recognized as equal"; unequalExe = testers.testBuildFailure ( testers.testEqualContents { assertion = "Different file mode bits are not recognized as equal"; expected = runCommand "expected" { } '' mkdir -p $out/c echo a >$out/a echo b >$out/b echo d >$out/c/d touch -- "$out" chmod a+x -- "$out" ''; actual = runCommand "actual" { } '' mkdir -p $out/c echo a >$out/a echo B >$out/b echo d >$out/c/d touch -- "$out" ''; }); } '' ( set -x grep -F -- "Contents must be equal but were not" $log/testBuildFailure.log grep -E -- '+++ .*-actual/b' $log/testBuildFailure.log grep -E -- '--- .*-actual/b' $log/testBuildFailure.log grep -F -- "-B" $log/testBuildFailure.log grep -F -- "+b" $log/testBuildFailure.log ) || { echo "Test failed: could not find pattern in build log $log" exit 1 } echo 'All good.' touch $out ); unequalExeInDir = testers.testBuildFailure ( testers.testEqualContents { assertion = "Different file mode bits are not recognized as equal in directory"; expected = runCommand "expected" { } '' mkdir -p -- "$out/a" echo b >"$out/b" chmod a+x -- "$out/b" ''; actual = runCommand "actual" { } '' mkdir -p -- "$out/a" echo b >"$out/b" ''; } ); fileMissing = runCommand "testEqualContents-fileMissing" { log = testers.testBuildFailure (testers.testEqualContents { assertion = "The same directory contents at different paths are recognized as equal"; nonExistentPath = testers.testBuildFailure ( testers.testEqualContents { assertion = "Non existent paths are not recognized as equal"; expected = "${emptyDirectory}/foo"; actual = "${emptyDirectory}/bar"; } ); emptyFileAndDir = testers.testBuildFailure ( testers.testEqualContents { assertion = "Empty file and directory are not recognized as equal"; expected = emptyFile; actual = emptyDirectory; } ); fileDiff = let log = testers.testBuildFailure ( testers.testEqualContents { assertion = "Different files are not recognized as equal in subdirectories"; expected = runCommand "expected" { } '' mkdir -p $out/c echo a >$out/a echo b >$out/b echo d >$out/c/d mkdir -p -- "$out/b" echo a >"$out/a" echo EXPECTED >"$out/b/c" ''; actual = runCommand "actual" { } '' mkdir -p $out/c echo a >$out/a echo d >$out/c/d mkdir -p "$out/b" echo a >"$out/a" echo ACTUAL >"$out/b/c" ''; }); } '' } ); in runCommand "testEqualContents-fileDiff" { inherit log; } '' ( set -x grep -F -- "Contents must be equal but were not" $log/testBuildFailure.log grep -E -- 'Only in .*-expected: b' $log/testBuildFailure.log # Note: use `&&` operator to chain commands because errexit (set -e) # does not work in this context (even when set explicitly and with # inherit_errexit), otherwise the subshell exits with the status of # the last run command and ignores preceding failures. grep -F -- 'Contents must be equal, but were not!' "$log/testBuildFailure.log" && grep -E -- '\+\+\+ .*-expected/b/c' "$log/testBuildFailure.log" && grep -E -- '--- .*-actual/b/c' "$log/testBuildFailure.log" && grep -F -- -ACTUAL "$log/testBuildFailure.log" && grep -F -- +EXPECTED "$log/testBuildFailure.log" ) || { echo "Test failed: could not find pattern in build log $log" exit 1 false } echo 'All good.' touch $out touch -- "$out" ''; }; } Loading
pkgs/build-support/testers/default.nix +8 −19 Original line number Diff line number Diff line { pkgs, pkgsLinux, buildPackages, lib, callPackage, runCommand, stdenv, substituteAll, testers }: { pkgs, pkgsLinux, buildPackages, diffoscopeMinimal, lib, callPackage, runCommand, stdenv, substituteAll, testers }: # Documentation is in doc/build-helpers/testers.chapter.md { # See https://nixos.org/manual/nixpkgs/unstable/#tester-lycheeLinkCheck Loading Loading @@ -27,33 +27,22 @@ expected, }: runCommand "equal-contents-${lib.strings.toLower assertion}" { inherit assertion actual expected; nativeBuildInputs = [ diffoscopeMinimal ]; } '' echo "Checking:" echo "$assertion" if ! diff -U5 -r "$actual" "$expected" --color=always printf '%s\n' "$assertion" if ! diffoscope --no-progress --text-color=always --exclude-directory-metadata=no -- "$actual" "$expected" then echo echo 'Contents must be equal, but were not!' echo echo "+: expected, at $expected" echo "-: unexpected, at $actual" exit 1 else find "$expected" -type f -executable > expected-executables | sort find "$actual" -type f -executable > actual-executables | sort if ! diff -U0 actual-executables expected-executables --color=always then echo echo "Contents must be equal, but some files' executable bits don't match" echo echo "+: make this file executable in the actual contents" echo "-: make this file non-executable in the actual contents" exit 1 false else echo "expected $expected and actual $actual match." echo 'OK' touch $out fi echo OK touch -- "$out" fi ''; Loading
pkgs/build-support/testers/test/default.nix +116 −98 Original line number Diff line number Diff line { testers, lib, pkgs, hello, runCommand, ... }: { testers, lib, pkgs, hello, runCommand, emptyFile, emptyDirectory, ... }: let pkgs-with-overlay = pkgs.extend(final: prev: { proof-of-overlay-hello = prev.hello; Loading Loading @@ -99,117 +99,135 @@ lib.recurseIntoAttrs { }; testEqualContents = lib.recurseIntoAttrs { happy = testers.testEqualContents { equalDir = testers.testEqualContents { assertion = "The same directory contents at different paths are recognized as equal"; expected = runCommand "expected" { } '' mkdir -p $out/c echo a >$out/a echo b >$out/b echo d >$out/c/d mkdir -p -- "$out/c" echo a >"$out/a" echo b >"$out/b" echo d >"$out/c/d" echo e >"$out/e" chmod a+x -- "$out/e" ''; actual = runCommand "actual" { } '' mkdir -p $out/c echo a >$out/a echo b >$out/b echo d >$out/c/d mkdir -p -- "$out/c" echo a >"$out/a" echo b >"$out/b" echo d >"$out/c/d" echo e >"$out/e" chmod a+x -- "$out/e" ''; }; unequalExe = runCommand "testEqualContents-unequalExe" { log = testers.testBuildFailure (testers.testEqualContents { assertion = "The same directory contents at different paths are recognized as equal"; fileMissing = testers.testBuildFailure ( testers.testEqualContents { assertion = "Directories with different file list are not recognized as equal"; expected = runCommand "expected" { } '' mkdir -p $out/c echo a >$out/a chmod a+x $out/a echo b >$out/b echo d >$out/c/d mkdir -p -- "$out/c" echo a >"$out/a" echo b >"$out/b" echo d >"$out/c/d" ''; actual = runCommand "actual" { } '' mkdir -p $out/c echo a >$out/a echo b >$out/b chmod a+x $out/b echo d >$out/c/d mkdir -p -- "$out/c" echo a >"$out/a" echo d >"$out/c/d" ''; }); } '' ( set -x grep -F -- "executable bits don't match" $log/testBuildFailure.log grep -E -- '+.*-actual/a' $log/testBuildFailure.log grep -E -- '-.*-actual/b' $log/testBuildFailure.log grep -F -- "--- actual-executables" $log/testBuildFailure.log grep -F -- "+++ expected-executables" $log/testBuildFailure.log ) || { echo "Test failed: could not find pattern in build log $log" exit 1 } echo 'All good.' touch $out ); equalExe = testers.testEqualContents { assertion = "The same executable file contents at different paths are recognized as equal"; expected = runCommand "expected" { } '' echo test >"$out" chmod a+x -- "$out" ''; actual = runCommand "actual" { } '' echo test >"$out" chmod a+x -- "$out" ''; }; fileDiff = runCommand "testEqualContents-fileDiff" { log = testers.testBuildFailure (testers.testEqualContents { assertion = "The same directory contents at different paths are recognized as equal"; unequalExe = testers.testBuildFailure ( testers.testEqualContents { assertion = "Different file mode bits are not recognized as equal"; expected = runCommand "expected" { } '' mkdir -p $out/c echo a >$out/a echo b >$out/b echo d >$out/c/d touch -- "$out" chmod a+x -- "$out" ''; actual = runCommand "actual" { } '' mkdir -p $out/c echo a >$out/a echo B >$out/b echo d >$out/c/d touch -- "$out" ''; }); } '' ( set -x grep -F -- "Contents must be equal but were not" $log/testBuildFailure.log grep -E -- '+++ .*-actual/b' $log/testBuildFailure.log grep -E -- '--- .*-actual/b' $log/testBuildFailure.log grep -F -- "-B" $log/testBuildFailure.log grep -F -- "+b" $log/testBuildFailure.log ) || { echo "Test failed: could not find pattern in build log $log" exit 1 } echo 'All good.' touch $out ); unequalExeInDir = testers.testBuildFailure ( testers.testEqualContents { assertion = "Different file mode bits are not recognized as equal in directory"; expected = runCommand "expected" { } '' mkdir -p -- "$out/a" echo b >"$out/b" chmod a+x -- "$out/b" ''; actual = runCommand "actual" { } '' mkdir -p -- "$out/a" echo b >"$out/b" ''; } ); fileMissing = runCommand "testEqualContents-fileMissing" { log = testers.testBuildFailure (testers.testEqualContents { assertion = "The same directory contents at different paths are recognized as equal"; nonExistentPath = testers.testBuildFailure ( testers.testEqualContents { assertion = "Non existent paths are not recognized as equal"; expected = "${emptyDirectory}/foo"; actual = "${emptyDirectory}/bar"; } ); emptyFileAndDir = testers.testBuildFailure ( testers.testEqualContents { assertion = "Empty file and directory are not recognized as equal"; expected = emptyFile; actual = emptyDirectory; } ); fileDiff = let log = testers.testBuildFailure ( testers.testEqualContents { assertion = "Different files are not recognized as equal in subdirectories"; expected = runCommand "expected" { } '' mkdir -p $out/c echo a >$out/a echo b >$out/b echo d >$out/c/d mkdir -p -- "$out/b" echo a >"$out/a" echo EXPECTED >"$out/b/c" ''; actual = runCommand "actual" { } '' mkdir -p $out/c echo a >$out/a echo d >$out/c/d mkdir -p "$out/b" echo a >"$out/a" echo ACTUAL >"$out/b/c" ''; }); } '' } ); in runCommand "testEqualContents-fileDiff" { inherit log; } '' ( set -x grep -F -- "Contents must be equal but were not" $log/testBuildFailure.log grep -E -- 'Only in .*-expected: b' $log/testBuildFailure.log # Note: use `&&` operator to chain commands because errexit (set -e) # does not work in this context (even when set explicitly and with # inherit_errexit), otherwise the subshell exits with the status of # the last run command and ignores preceding failures. grep -F -- 'Contents must be equal, but were not!' "$log/testBuildFailure.log" && grep -E -- '\+\+\+ .*-expected/b/c' "$log/testBuildFailure.log" && grep -E -- '--- .*-actual/b/c' "$log/testBuildFailure.log" && grep -F -- -ACTUAL "$log/testBuildFailure.log" && grep -F -- +EXPECTED "$log/testBuildFailure.log" ) || { echo "Test failed: could not find pattern in build log $log" exit 1 false } echo 'All good.' touch $out touch -- "$out" ''; }; }