testers.testEqualContents: add postFailureMessage parameter

Add an optional postFailureMessage parameter to testEqualContents that allows
users to provide additional context when tests fail. This is particularly useful
for providing instructions on how to update expected results when they change
intentionally.

The message is displayed after the standard failure output, helping maintainers
understand what to do next when a test fails.
This commit is contained in:
Robert Hensing
2025-08-24 19:40:04 +02:00
parent 175ac336c4
commit 8d128a4138
3 changed files with 66 additions and 15 deletions

View File

@@ -405,6 +405,22 @@ The tester produces an empty output and only succeeds when the checks using `exp
Check that two paths have the same contents. Check that two paths have the same contents.
`assertion` (string)
: A message that is printed before the comparison, after `Checking:`.
`expected` (path or value coercible to store path)
: The path to the expected [file system object] content
`actual` (value coercible to store path) <!-- path value is possible, but wrong in practice, but let's not bother readers with our predictions -->
: The path to the actual file system object content to check
`postFailureMessage` (string)
: A message that is printed last if the file system object contents at the two paths don't match exactly.
:::{.example #ex-testEqualContents-toyexample} :::{.example #ex-testEqualContents-toyexample}
# Check that two paths have the same contents # Check that two paths have the same contents
@@ -427,6 +443,11 @@ testers.testEqualContents {
'' ''
sed -e 's/bar/baz/g' $base >$out sed -e 's/bar/baz/g' $base >$out
''; '';
# if applicable
postFailureMessage = ''
The bar-baz replacer produced an unexpected result.
If the new behavior is acceptable and validated against the bar-baz specification, run ./adopt-new-bar-baz-result.sh to adjust this test and require the new behavior.
'';
} }
``` ```
@@ -695,3 +716,5 @@ Notable attributes:
* `nodes`: the evaluated NixOS configurations. Useful for debugging and exploring the configuration. * `nodes`: the evaluated NixOS configurations. Useful for debugging and exploring the configuration.
* `driverInteractive`: a script that launches an interactive Python session in the context of the `testScript`. * `driverInteractive`: a script that launches an interactive Python session in the context of the `testScript`.
[file system object]: https://nix.dev/manual/nix/latest/store/file-system-object

View File

@@ -56,10 +56,16 @@
assertion, assertion,
actual, actual,
expected, expected,
postFailureMessage ? null,
}: }:
runCommand "equal-contents-${lib.strings.toLower assertion}" runCommand "equal-contents-${lib.strings.toLower assertion}"
{ {
inherit assertion actual expected; inherit
assertion
actual
expected
postFailureMessage
;
nativeBuildInputs = [ diffoscopeMinimal ]; nativeBuildInputs = [ diffoscopeMinimal ];
} }
'' ''
@@ -69,6 +75,10 @@
then then
echo echo
echo 'Contents must be equal, but were not!' echo 'Contents must be equal, but were not!'
if [[ -n "''${postFailureMessage:-}" ]]; then
echo
echo "$postFailureMessage"
fi
echo echo
echo "+: expected, at $expected" echo "+: expected, at $expected"
echo "-: unexpected, at $actual" echo "-: unexpected, at $actual"

View File

@@ -270,22 +270,40 @@ lib.recurseIntoAttrs {
''; '';
}; };
fileMissing = testers.testBuildFailure ( # - Test whether a missing file triggers a failure as expected
testers.testEqualContents { # - Test the postFailureMessage
assertion = "Directories with different file list are not recognized as equal"; fileMissing =
expected = runCommand "expected" { } '' let
mkdir -p -- "$out/c" log = testers.testBuildFailure (
echo a >"$out/a" testers.testEqualContents {
echo b >"$out/b" assertion = "Directories with different file list are not recognized as equal";
echo d >"$out/c/d" 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"
'';
inherit postFailureMessage;
}
);
postFailureMessage = ''
If after careful review, you find that the changes are acceptable, run `suchandsuch` to adopt the new behavior.
''; '';
actual = runCommand "actual" { } '' in
mkdir -p -- "$out/c" runCommand "fileMissing-failure-and-log-check"
echo a >"$out/a" {
echo d >"$out/c/d" inherit log;
inherit postFailureMessage;
}
''
grep -F "$postFailureMessage" "$log/testBuildFailure.log"
touch $out
''; '';
}
);
equalExe = testers.testEqualContents { equalExe = testers.testEqualContents {
assertion = "The same executable file contents at different paths are recognized as equal"; assertion = "The same executable file contents at different paths are recognized as equal";