Loading doc/builders/testers.chapter.md +24 −0 Original line number Diff line number Diff line Loading @@ -75,6 +75,30 @@ environment to a minimum, some small changes are inevitable. `buildPackages.coreutils` and possibly more. These are not added to `PATH` or any other environment variable, so they should be hard to observe. ## `testEqualContents` {#tester-equalContents} Check that two paths have the same contents. Example: ```nix testers.testEqualContents { assertion = "sed -e performs replacement"; expected = writeText "expected" '' foo baz baz ''; actual = runCommand "actual" { # not really necessary for a package that's in stdenv nativeBuildInputs = [ gnused ]; base = writeText "base" '' foo bar baz ''; } '' sed -e 's/bar/baz/g' $base >$out ''; } ``` ## `testEqualDerivation` {#tester-testEqualDerivation} Checks that two packages produce the exact same build instructions. Loading pkgs/build-support/testers/default.nix +38 −0 Original line number Diff line number Diff line Loading @@ -13,6 +13,44 @@ testEqualDerivation = callPackage ./test-equal-derivation.nix { }; # See https://nixos.org/manual/nixpkgs/unstable/#tester-testEqualContents # or doc/builders/testers.chapter.md testEqualContents = { assertion, actual, expected, }: runCommand "equal-contents-${lib.strings.toLower assertion}" { inherit assertion actual expected; } '' echo "Checking:" echo "$assertion" if ! diff -U5 -r "$actual" "$expected" --color=always 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 else echo "expected $expected and actual $actual match." echo 'OK' touch $out fi fi ''; testVersion = { package, command ? "${package.meta.mainProgram or package.pname or package.name} --version", Loading pkgs/build-support/testers/test/default.nix +115 −1 Original line number Diff line number Diff line Loading @@ -68,9 +68,123 @@ lib.recurseIntoAttrs { # Checking our note that dev is the default output echo $failed/_ | grep -- '-dev/_' >/dev/null echo 'All good.' touch $out ''; }; testEqualContents = lib.recurseIntoAttrs { happy = 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 ''; actual = runCommand "actual" {} '' mkdir -p $out/c echo a >$out/a echo b >$out/b echo d >$out/c/d ''; }; unequalExe = runCommand "testEqualContents-unequalExe" { log = testers.testBuildFailure (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 chmod a+x $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 ''; }); } '' ( 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 ''; fileDiff = runCommand "testEqualContents-fileDiff" { log = testers.testBuildFailure (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 ''; actual = runCommand "actual" {} '' mkdir -p $out/c echo a >$out/a echo B >$out/b echo d >$out/c/d ''; }); } '' ( 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 ''; fileMissing = runCommand "testEqualContents-fileMissing" { log = testers.testBuildFailure (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 ''; actual = runCommand "actual" {} '' mkdir -p $out/c echo a >$out/a echo d >$out/c/d ''; }); } '' ( set -x grep -F -- "Contents must be equal but were not" $log/testBuildFailure.log grep -E -- 'Only in .*-expected: b' $log/testBuildFailure.log ) || { echo "Test failed: could not find pattern in build log $log" exit 1 } echo 'All good.' touch $out ''; }; } Loading
doc/builders/testers.chapter.md +24 −0 Original line number Diff line number Diff line Loading @@ -75,6 +75,30 @@ environment to a minimum, some small changes are inevitable. `buildPackages.coreutils` and possibly more. These are not added to `PATH` or any other environment variable, so they should be hard to observe. ## `testEqualContents` {#tester-equalContents} Check that two paths have the same contents. Example: ```nix testers.testEqualContents { assertion = "sed -e performs replacement"; expected = writeText "expected" '' foo baz baz ''; actual = runCommand "actual" { # not really necessary for a package that's in stdenv nativeBuildInputs = [ gnused ]; base = writeText "base" '' foo bar baz ''; } '' sed -e 's/bar/baz/g' $base >$out ''; } ``` ## `testEqualDerivation` {#tester-testEqualDerivation} Checks that two packages produce the exact same build instructions. Loading
pkgs/build-support/testers/default.nix +38 −0 Original line number Diff line number Diff line Loading @@ -13,6 +13,44 @@ testEqualDerivation = callPackage ./test-equal-derivation.nix { }; # See https://nixos.org/manual/nixpkgs/unstable/#tester-testEqualContents # or doc/builders/testers.chapter.md testEqualContents = { assertion, actual, expected, }: runCommand "equal-contents-${lib.strings.toLower assertion}" { inherit assertion actual expected; } '' echo "Checking:" echo "$assertion" if ! diff -U5 -r "$actual" "$expected" --color=always 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 else echo "expected $expected and actual $actual match." echo 'OK' touch $out fi fi ''; testVersion = { package, command ? "${package.meta.mainProgram or package.pname or package.name} --version", Loading
pkgs/build-support/testers/test/default.nix +115 −1 Original line number Diff line number Diff line Loading @@ -68,9 +68,123 @@ lib.recurseIntoAttrs { # Checking our note that dev is the default output echo $failed/_ | grep -- '-dev/_' >/dev/null echo 'All good.' touch $out ''; }; testEqualContents = lib.recurseIntoAttrs { happy = 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 ''; actual = runCommand "actual" {} '' mkdir -p $out/c echo a >$out/a echo b >$out/b echo d >$out/c/d ''; }; unequalExe = runCommand "testEqualContents-unequalExe" { log = testers.testBuildFailure (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 chmod a+x $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 ''; }); } '' ( 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 ''; fileDiff = runCommand "testEqualContents-fileDiff" { log = testers.testBuildFailure (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 ''; actual = runCommand "actual" {} '' mkdir -p $out/c echo a >$out/a echo B >$out/b echo d >$out/c/d ''; }); } '' ( 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 ''; fileMissing = runCommand "testEqualContents-fileMissing" { log = testers.testBuildFailure (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 ''; actual = runCommand "actual" {} '' mkdir -p $out/c echo a >$out/a echo d >$out/c/d ''; }); } '' ( set -x grep -F -- "Contents must be equal but were not" $log/testBuildFailure.log grep -E -- 'Only in .*-expected: b' $log/testBuildFailure.log ) || { echo "Test failed: could not find pattern in build log $log" exit 1 } echo 'All good.' touch $out ''; }; }