Skip to content

Commit

Permalink
Canonify outputs when updating baselines via btest-diff
Browse files Browse the repository at this point in the history
This leverages the same canonicalization btest-diff already applies
during test output comparison against baselines also when updating
those baselines (usually via btest -U/-u). This removes a bunch of
noise from the baselines, including personal home directories,
timestamps, etc.

Since btest-diff doesn't know whether the baseline has undergone this
canonicalization, it continues to canonicalize the basline prior to
diffing. To track whether it has canonicalized a baseline when
updating, btest-diff now also prepends a header to the generated
baseline that warns users about the fact that it is
auto-generated. The presence of this header doubles as a marker for
canonicalization.

Includes a test-case.
  • Loading branch information
ckreibich committed Oct 7, 2020
1 parent 01cffdd commit 1b3d01b
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 18 deletions.
85 changes: 67 additions & 18 deletions btest-diff
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,41 @@
# Maximum number of lines to show from mismatching input file by default.
MAX_LINES=100

# Header line we tuck onto new baselines generated by
# btest-diff. Serves both as a warning and as an indicator that the
# baseline has been run through the TEST_DIFF_CANONIFIER (if any).
HEADER="### btest baseline data generated by btest-diff. Do not edit. Use btest -U/-u to update."

# Predicate, succeeds if the given baseline is canonicalized.
function is_canon_baseline {
local input="$1"

if head -1 "$input" | grep -q -F "$HEADER" 2>/dev/null; then
return 0
fi

return 1
}

# Prints the requested baseline to standard out if it is
# canonicalized. Otherwise, fails.
function get_canon_baseline {
local input="$1"

! is_canon_baseline "$input" && return 1
tail -n +2 "$input"
}

# Updates the given baseline to the given destination, prepending our
# header.
function update_canon_baseline {
local input="$1"
local output="$2"

echo "$HEADER" >"$output"
cat "$input" >>"$output"
}

if [ -n "$TEST_DIFF_FILE_MAX_LINES" ]; then
MAX_LINES=$TEST_DIFF_FILE_MAX_LINES
fi
Expand Down Expand Up @@ -67,34 +102,43 @@ fi
if [ -e $TEST_BASELINE/$canon ]; then
error=0

if [ "$TEST_DIFF_CANONIFIER" != "" ]; then
diff1=/tmp/test-diff.$$.$canon.baseline.tmp
diff2=/tmp/test-diff.$$.$canon.tmp
tmpfiles="$tmpfiles $diff1 $diff2"
# If no canonifier is defined, make it a runnable
# no-op. Simplifies code layout.
if [ -z "$TEST_DIFF_CANONIFIER" ]; then
TEST_DIFF_CANONIFIER=cat
fi

eval $TEST_DIFF_CANONIFIER $TEST_BASELINE/$canon <$TEST_BASELINE/$canon >$diff1
canon_baseline=/tmp/test-diff.$$.$canon.baseline.tmp
canon_output=/tmp/test-diff.$$.$canon.tmp
tmpfiles="$tmpfiles $canon_baseline $canon_output"

# Prepare the baseline. When created by a recent btest-diff, we
# don't need to re-canonicalize, otherwise we do.
if ! get_canon_baseline $TEST_BASELINE/$canon >$canon_baseline; then
# It's an older uncanonicalized baseline, so canonicalize
# it now prior to comparison. Future updates via btest
# -U/-u will then store it canonicalized.
eval $TEST_DIFF_CANONIFIER <$TEST_BASELINE/$canon >$canon_baseline
if [ $? -ne 0 ]; then
error=1
echo "== Error ==============================" >>$TEST_DIAGNOSTICS
echo "btest-diff: TEST_DIFF_CANONIFIER failed on file '$TEST_BASELINE/$canon'" >>$TEST_DIAGNOSTICS
result=1
fi
fi

eval $TEST_DIFF_CANONIFIER $input <$input >$diff2
if [ $? -ne 0 ]; then
error=1
echo "== Error ==============================" >>$TEST_DIAGNOSTICS
echo "btest-diff: TEST_DIFF_CANONIFIER failed on file '$input'" >>$TEST_DIAGNOSTICS
result=1
fi
else
diff1=$TEST_BASELINE/$canon
diff2=$input
# Canonicalize the new test output
eval $TEST_DIFF_CANONIFIER $input <$input >$canon_output
if [ $? -ne 0 ]; then
error=1
echo "== Error ==============================" >>$TEST_DIAGNOSTICS
echo "btest-diff: TEST_DIFF_CANONIFIER failed on file '$input'" >>$TEST_DIAGNOSTICS
result=1
fi

if [ $error -eq 0 ]; then
echo "== Diff ===============================" >>$TEST_DIAGNOSTICS
diff -au $@ $diff1 $diff2 >>$TEST_DIAGNOSTICS
diff -au $@ $canon_baseline $canon_output >>$TEST_DIAGNOSTICS
result=$?
fi
else
Expand All @@ -119,15 +163,20 @@ elif [ "$TEST_MODE" == "UPDATE_INTERACTIVE" ]; then

echo -n "$TEST_NAME ..." >/dev/tty

# If we have a canonified version of the input file, use it as the
# new baseline. Otherwise, just use the input.
update="${canon_output:-$input}"

if [ $rc == 0 ]; then
cp $input $TEST_BASELINE/$canon
update_canon_baseline $update $TEST_BASELINE/$canon
exit 0
fi

exit $rc

elif [ "$TEST_MODE" == "UPDATE" ]; then
cp $input $TEST_BASELINE/$canon
update="${canon_output:-$input}"
update_canon_baseline $update $TEST_BASELINE/$canon
exit 0
fi

Expand Down
47 changes: 47 additions & 0 deletions testing/tests/canonifier-conversion.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# This test verifies that we only canonicalize baselines once, namely
# when canonicalizing new test output, and that baselines get
# converted over to our header-tagged format.
#
# Test prep: make our canonifier executable
# %TEST-EXEC: chmod 755 ./diff-double-x
#
# Test prep: create a "dated" baseline.
# %TEST-EXEC: mkdir -p Baseline/canonifier-conversion
# %TEST-EXEC: echo x >Baseline/canonifier-conversion/output
#
# Verify that it succeeds:
# %TEST-EXEC: btest %INPUT
#
# Update the baseline. This should prefix btest-diff's header and canonify:
# %TEST-EXEC: btest -U %INPUT
#
# Verify that these have happened and preserve baseline:
# %TEST-EXEC: head -1 Baseline/canonifier-conversion/output | grep -q 'Do not edit'
# %TEST-EXEC: tail -1 Baseline/canonifier-conversion/output | grep xx
# %TEST-EXEC: cp Baseline/canonifier-conversion/output base.1
#
# Verify that it still succeeds:
# %TEST-EXEC: btest %INPUT
#
# Update the baseline again.
# %TEST-EXEC: btest -U %INPUT
# %TEST-EXEC: cp Baseline/canonifier-conversion/output base.2
#
# Verify the updated baselines remained identical.
# %TEST-EXEC: test "$(cat base.1)" = "$(cat base.2)"

@TEST-EXEC: echo x >output
@TEST-EXEC: btest-diff output

%TEST-START-FILE btest.cfg
[btest]
TmpDir = .tmp

[environment]
TEST_DIFF_CANONIFIER=%(testbase)s/diff-double-x
%TEST-END-FILE

%TEST-START-FILE diff-double-x
#! /usr/bin/env bash
sed 's/x/xx/g'
%TEST-END-FILE

0 comments on commit 1b3d01b

Please sign in to comment.