Commit e20a3629 authored by Robert Hensing's avatar Robert Hensing
Browse files

testers.testEqualContents: init

parent 44d0f378
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -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.
+38 −0
Original line number Diff line number Diff line
@@ -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",
+115 −1
Original line number Diff line number Diff line
@@ -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
      '';
  };
}