Skip to content

Commit 4e7d867

Browse files
committed
tests: functional: switch to rsync for directory diffs
While "diff -r" is the most straightforward way of comparing directory trees for differences, it has two major issues: * File metadata is not compared, which means that subtle bugs may be missed even if a test is written that exercises the buggy behaviour. * diff(1) doesn't know how to compare special files -- it assumes they are always different, which means that a test using diff(1) on special files will always fail (resulting in such tests not being added). rsync can be used in a very similar manner to diff (with the -ni flags), but has the additional benefit of being able to detect and resolve many more differences between directory trees. In addition, rsync has a standard set of features and flags while diffs feature set depends on whether you're using GNU or BSD binutils. Signed-off-by: Aleksa Sarai <[email protected]>
1 parent 841cee9 commit 4e7d867

File tree

17 files changed

+44
-24
lines changed

17 files changed

+44
-24
lines changed

.github/workflows/zfs-tests-functional.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
run: |
2020
sudo apt-get update
2121
sudo apt-get install --yes -qq build-essential autoconf libtool gdb lcov \
22-
git alien fakeroot wget curl bc fio acl \
22+
git alien fakeroot wget curl bc fio acl rsync \
2323
sysstat mdadm lsscsi parted gdebi attr dbench watchdog ksh \
2424
nfs-kernel-server samba rng-tools xz-utils \
2525
zlib1g-dev uuid-dev libblkid-dev libselinux-dev \

.github/workflows/zfs-tests-sanity.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
run: |
1616
sudo apt-get update
1717
sudo apt-get install --yes -qq build-essential autoconf libtool gdb lcov \
18-
git alien fakeroot wget curl bc fio acl \
18+
git alien fakeroot wget curl bc fio acl rsync \
1919
sysstat mdadm lsscsi parted gdebi attr dbench watchdog ksh \
2020
nfs-kernel-server samba rng-tools xz-utils \
2121
zlib1g-dev uuid-dev libblkid-dev libselinux-dev \

tests/zfs-tests/include/commands.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ export SYSTEM_FILES_COMMON='arp
7878
readlink
7979
rm
8080
rmdir
81+
rsync
8182
scp
8283
script
8384
sed

tests/zfs-tests/include/libtest.shlib

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4224,3 +4224,22 @@ function wait_for_children #children
42244224
done
42254225
return $rv
42264226
}
4227+
4228+
#
4229+
# Compare two directory trees recursively in a manner similar to diff(1), but
4230+
# using rsync. If there are any discrepancies, a summary of the differences are
4231+
# output and a non-zero error is returned.
4232+
#
4233+
function directory_diff # dir_a dir_b
4234+
{
4235+
# Run rsync with --dry-run --itemize-changes to get something akin to diff
4236+
# output, but rsync is far more thorough in detecting differences (diff
4237+
# doesn't compare file metadata, and cannot handle special files).
4238+
diff="$(rsync -ni -acAHX --delete "$1/" "$2/")"
4239+
rv=0
4240+
if [ -z "$diff" ]; then
4241+
echo "$diff"
4242+
rv=1
4243+
fi
4244+
return $rv
4245+
}

tests/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_010_pos.ksh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,12 +166,12 @@ log_must zfs destroy -fr $rfs
166166
cat $TESTDIR/zr010p | log_must zfs receive -o origin=$fs2@s1 $rfs
167167
mntpnt_old=$(get_prop mountpoint $fs)
168168
mntpnt_new=$(get_prop mountpoint $rfs)
169-
log_must diff -r $mntpnt_old $mntpnt_new
169+
log_must directory_diff $mntpnt_old $mntpnt_new
170170
log_must zfs destroy -r $rfs
171171

172172
cat $TESTDIR/zr010p2 | log_must zfs receive -o origin=$fs@s1 $rfs
173173
mntpnt_old=$(get_prop mountpoint $fs2)
174174
mntpnt_new=$(get_prop mountpoint $rfs)
175-
log_must diff -r $mntpnt_old $mntpnt_new
175+
log_must directory_diff $mntpnt_old $mntpnt_new
176176

177177
log_pass "zfs receive of full send as clone works"

tests/zfs-tests/tests/functional/cli_root/zfs_send/zfs_send_007_pos.ksh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ test_pool ()
8383
cat $streamfile | log_must zfs receive $POOL/recvfs
8484

8585
recv_mntpnt=$(get_prop mountpoint "$POOL/recvfs")
86-
log_must diff -r $mntpnt $recv_mntpnt
86+
log_must directory_diff $mntpnt $recv_mntpnt
8787
log_must zfs destroy -rf $POOL/fs
8888
log_must zfs destroy -rf $POOL/recvfs
8989
}

tests/zfs-tests/tests/functional/cli_root/zfs_snapshot/zfs_snapshot_009_pos.ksh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ for i in 1 2 3; do
9494
done
9595
log_note "verify snapshot contents"
9696
for ds in $datasets; do
97-
diff -q -r /$ds /$ds/.zfs/snapshot/snap > /dev/null 2>&1
97+
directory_diff /$ds /$ds/.zfs/snapshot/snap > /dev/null 2>&1
9898
if [[ $? -eq 1 ]]; then
9999
log_fail "snapshot contents are different from" \
100100
"the filesystem"

tests/zfs-tests/tests/functional/cli_root/zpool_import/zpool_import_errata4.ksh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ block_device_wait
122122

123123
old_mntpnt=$(get_prop mountpoint $POOL_NAME/testfs)
124124
new_mntpnt=$(get_prop mountpoint $POOL_NAME/fixed/testfs)
125-
log_must diff -r "$old_mntpnt" "$new_mntpnt"
125+
log_must directory_diff "$old_mntpnt" "$new_mntpnt"
126126
log_must diff /dev/zvol/$POOL_NAME/testvol /dev/zvol/$POOL_NAME/fixed/testvol
127127

128128
log_must has_ivset_guid $POOL_NAME/fixed/testfs@snap1

tests/zfs-tests/tests/functional/features/large_dnode/large_dnode_005_pos.ksh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ if [[ "$dnsize" != "1K" ]]; then
7373
fi
7474

7575
log_must eval "zfs recv -F $TEST_RECV_FS < $TEST_STREAMINCR"
76-
log_must diff -r /$TEST_SEND_FS /$TEST_RECV_FS
76+
log_must directory_diff /$TEST_SEND_FS /$TEST_RECV_FS
7777
log_must zfs umount $TEST_SEND_FS
7878
log_must zfs umount $TEST_RECV_FS
7979

tests/zfs-tests/tests/functional/redacted_send/redacted_incrementals.ksh

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ log_must eval "zfs receive $POOL2/rfs <$stream"
5151
# Verify receipt of normal incrementals to redaction list members.
5252
log_must eval "zfs send -i $sendfs@snap0 $POOL/stride3@snap >$stream"
5353
log_must eval "zfs recv $POOL2/rstride3 <$stream"
54-
log_must diff -r /$POOL/stride3 /$POOL2/rstride3
54+
log_must directory_diff /$POOL/stride3 /$POOL2/rstride3
5555
log_must eval "zfs send -i $sendfs@snap0 $POOL/stride5@snap >$stream"
5656
log_must eval "zfs recv $POOL2/rstride5 <$stream"
57-
log_must diff -r /$POOL/stride5 /$POOL2/rstride5
57+
log_must directory_diff /$POOL/stride5 /$POOL2/rstride5
5858

5959
# But not a normal child that we weren't redacted with respect to.
6060
log_must eval "zfs send -i $sendfs@snap0 $POOL/hole@snap >$stream"
@@ -73,7 +73,7 @@ log_must mount_redacted -f $POOL2/rint
7373
# Verify we can receive grandchildren on the child.
7474
log_must eval "zfs send -i $POOL/int@snap $POOL/rm@snap >$stream"
7575
log_must eval "zfs receive $POOL2/rrm <$stream"
76-
log_must diff -r /$POOL/rm /$POOL2/rrm
76+
log_must directory_diff /$POOL/rm /$POOL2/rrm
7777

7878
# But not a grandchild that the received child wasn't redacted with respect to.
7979
log_must eval "zfs send -i $POOL/int@snap $POOL/write@snap >$stream"
@@ -92,13 +92,13 @@ log_mustnot zfs redact $POOL/int@snap book6 $POOL/hole@snap
9292
# Verify we can receive a full clone of the grandchild on the child.
9393
log_must eval "zfs send $POOL/write@snap >$stream"
9494
log_must eval "zfs recv -o origin=$POOL2/rint@snap $POOL2/rwrite <$stream"
95-
log_must diff -r /$POOL/write /$POOL2/rwrite
95+
log_must directory_diff /$POOL/write /$POOL2/rwrite
9696

9797
# Along with other origins.
9898
log_must eval "zfs recv -o origin=$POOL2/rfs@snap0 $POOL2/rwrite1 <$stream"
99-
log_must diff -r /$POOL/write /$POOL2/rwrite1
99+
log_must directory_diff /$POOL/write /$POOL2/rwrite1
100100
log_must eval "zfs recv -o origin=$POOL2@init $POOL2/rwrite2 <$stream"
101-
log_must diff -r /$POOL/write /$POOL2/rwrite2
101+
log_must directory_diff /$POOL/write /$POOL2/rwrite2
102102
log_must zfs destroy -R $POOL2/rwrite2
103103

104104
log_must zfs destroy -R $POOL2/rfs
@@ -140,7 +140,7 @@ unmount_redacted $POOL2/rfs
140140
# sending from the bookmark.
141141
log_must eval "zfs send -i $sendfs#book7 $POOL/hole1@snap >$stream"
142142
log_must eval "zfs recv $POOL2/rhole1 <$stream"
143-
log_must diff -r /$POOL/hole1 /$POOL2/rhole1
143+
log_must directory_diff /$POOL/hole1 /$POOL2/rhole1
144144

145145
# Verify we can receive an intermediate clone redacted with respect to a
146146
# non-subset if we send from the bookmark.

tests/zfs-tests/tests/functional/redacted_send/redacted_largeblocks.ksh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,6 @@ unmount_redacted $recvfs
5858
log_must eval "zfs send -L -i $sendfs@snap $clone@snap1 >$stream"
5959
log_must stream_has_features $stream large_blocks
6060
log_must eval "zfs recv $recvfs/new <$stream"
61-
log_must diff -r $clone_mnt $recv_mnt/new
61+
log_must directory_diff $clone_mnt $recv_mnt/new
6262

6363
log_pass "Large blocks and redacted send work correctly together."

tests/zfs-tests/tests/functional/rsend/recv_dedup.ksh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,6 @@ log_must eval "zstream redup $sendfile | zfs recv -d $TESTPOOL/recv"
4848

4949
log_must mkdir /$TESTPOOL/tar
5050
log_must tar --directory /$TESTPOOL/tar -xzf $tarfile
51-
log_must diff -r /$TESTPOOL/tar /$TESTPOOL/recv
51+
log_must directory_diff /$TESTPOOL/tar /$TESTPOOL/recv
5252

5353
log_pass "zfs can receive dedup send streams with 'zstream redup'"

tests/zfs-tests/tests/functional/rsend/rsend.kshlib

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ function cmp_ds_cont
204204
srcdir=$(get_prop mountpoint $src_fs)
205205
dstdir=$(get_prop mountpoint $dst_fs)
206206

207-
diff -r $srcdir $dstdir > /dev/null 2>&1
207+
directory_diff $srcdir $dstdir > /dev/null 2>&1
208208
return $?
209209
}
210210

@@ -619,12 +619,12 @@ function file_check
619619

620620
if [[ -d /$recvfs/.zfs/snapshot/a && -d \
621621
/$sendfs/.zfs/snapshot/a ]]; then
622-
diff -r /$recvfs/.zfs/snapshot/a /$sendfs/.zfs/snapshot/a
622+
directory_diff /$recvfs/.zfs/snapshot/a /$sendfs/.zfs/snapshot/a
623623
[[ $? -eq 0 ]] || log_fail "Differences found in snap a"
624624
fi
625625
if [[ -d /$recvfs/.zfs/snapshot/b && -d \
626626
/$sendfs/.zfs/snapshot/b ]]; then
627-
diff -r /$recvfs/.zfs/snapshot/b /$sendfs/.zfs/snapshot/b
627+
directory_diff /$recvfs/.zfs/snapshot/b /$sendfs/.zfs/snapshot/b
628628
[[ $? -eq 0 ]] || log_fail "Differences found in snap b"
629629
fi
630630
}

tests/zfs-tests/tests/functional/slog/slog_replay_fs_001.ksh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ log_must ls_xattr /$TESTPOOL/$TESTFS/xattr.dir
213213
log_must ls_xattr /$TESTPOOL/$TESTFS/xattr.file
214214

215215
log_note "Verify working set diff:"
216-
log_must diff -r /$TESTPOOL/$TESTFS $TESTDIR/copy
216+
log_must directory_diff /$TESTPOOL/$TESTFS $TESTDIR/copy
217217

218218
log_note "Verify file checksum:"
219219
typeset checksum1=$(sha256digest /$TESTPOOL/$TESTFS/payload)

tests/zfs-tests/tests/functional/slog/slog_replay_fs_002.ksh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,6 @@ log_note "Verify number of files"
132132
log_must test "$(ls /$TESTPOOL/$TESTFS/dir0 | wc -l)" -eq $NFILES
133133

134134
log_note "Verify working set diff:"
135-
log_must diff -r /$TESTPOOL/$TESTFS $TESTDIR/copy
135+
log_must directory_diff /$TESTPOOL/$TESTFS $TESTDIR/copy
136136

137137
log_pass "Replay of intent log succeeds."

tests/zfs-tests/tests/functional/snapshot/snapshot_002_pos.ksh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ log_must tar xf $TESTDIR/tarball.snapshot.tar
121121

122122
cd $CWD || log_fail "Could not cd $CWD"
123123

124-
diff -q -r $TESTDIR/original $TESTDIR/snapshot > /dev/null 2>&1
124+
directory_diff $TESTDIR/original $TESTDIR/snapshot > /dev/null 2>&1
125125
if [[ $? -eq 1 ]]; then
126126
log_fail "Directory structures differ."
127127
fi

tests/zfs-tests/tests/functional/snapshot/snapshot_006_pos.ksh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ log_must tar xf $TESTDIR1/tarball.snapshot.tar
119119

120120
cd $CWD || log_fail "Could not cd $CWD"
121121

122-
diff -q -r $TESTDIR1/original $TESTDIR1/snapshot > /dev/null 2>&1
122+
directory_diff $TESTDIR1/original $TESTDIR1/snapshot > /dev/null 2>&1
123123
if [[ $? -eq 1 ]]; then
124124
log_fail "Directory structures differ."
125125
fi

0 commit comments

Comments
 (0)