diff --git a/Makefile.am b/Makefile.am index a5a0c35..ae3803e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -95,6 +95,7 @@ tests/Modifiers_-_--line-mode.test \ tests/Modifiers_-_--size_from_file_size.test \ tests/Modifiers_-_--size.test \ tests/Modifiers_-_--sync.test \ +tests/Sparse_-_Basic.test \ tests/Terminal_-_Detect_width.test \ tests/Transfer_-_--rate-limit.test \ tests/Transfer_-_--remote.test \ diff --git a/tests/Sparse_-_Basic.test b/tests/Sparse_-_Basic.test new file mode 100755 index 0000000..1fefc87 --- /dev/null +++ b/tests/Sparse_-_Basic.test @@ -0,0 +1,89 @@ +#!/bin/sh +# +# Transfer a large chunk of data through pv using pipes, sending it in a +# bursty fashion, and make sure some of it consists of blocks of null bytes. +# Check data correctness afterwards, and if dd can produce a sparse file, +# check that pv's output is also sparse. + +# Allow all tests to be skipped, e.g. during a release build +test "${SKIP_ALL_TESTS}" = "1" && exit 77 + +true "${testSubject:?not set - call this from 'make check'}" +true "${workFile1:?not set - call this from 'make check'}" +true "${workFile2:?not set - call this from 'make check'}" +true "${workFile3:?not set - call this from 'make check'}" + +# generate some data, with a hole in the middle. +dd if=/dev/urandom of="${workFile1}" bs=4096 count=640 2>/dev/null +dd if=/dev/null of="${workFile1}" bs=4096 count=0 seek=1280 2>/dev/null +dd if=/dev/urandom of="${workFile1}" bs=4096 count=1280 seek=1280 2>/dev/null + +# check that sparse files are supported. +cat < "${workFile1}" > "${workFile3}" +inputBlocks="$(ls -1s "${workFile1}" | awk '{print $1}')" +nonSparseBlocks="$(ls -1s "${workFile3}" | awk '{print $1}')" +if test "${inputBlocks}" -eq "${nonSparseBlocks}"; then + echo 'sparse files not supported' + exit 77 +fi + +inputChecksum=$(cksum "${workFile1}" | awk '{print $1}') + +# read through pv and test afterwards +( +dd if="${workFile1}" bs=1 count=9000 +sleep 1 +dd if="${workFile1}" bs=1 skip=9000 count=1240 +sleep 1 +dd if="${workFile1}" bs=1024 skip=10 count=1014 +sleep 1 +dd if="${workFile1}" bs=1024 skip=1024 count=1024 +sleep 1 +dd if="${workFile1}" bs=1024 skip=2048 +) 2>/dev/null | "${testSubject}" -q -O -L 2M | cat > "${workFile2}" + +outputChecksum=$(cksum "${workFile2}" | awk '{print $1}') + +if ! test "${inputChecksum}" = "${outputChecksum}"; then + echo "checksum mismatch with dd | pv | cat" + exit 1 +fi + +# same again but with one less pipe +( +dd if="${workFile1}" bs=1 count=9000 +sleep 1 +dd if="${workFile1}" bs=1 skip=9000 count=1240 +sleep 1 +dd if="${workFile1}" bs=1024 skip=10 count=1014 +sleep 1 +dd if="${workFile1}" bs=1024 skip=1024 count=1024 +sleep 1 +dd if="${workFile1}" bs=1024 skip=2048 +) 2>/dev/null | "${testSubject}" -q -O -L 2M > "${workFile2}" + +outputChecksum=$(cksum "${workFile2}" | awk '{print $1}') + +if ! test "${inputChecksum}" = "${outputChecksum}"; then + echo "checksum mismatch with dd | pv > file" + exit 1 +fi + +outputBlocks="$(ls -1s "${workFile2}" | awk '{print $1}')" + +# Note that we only check that the output has any holes at all (and that the +# input had holes). We don't compare pv's output with dd's output directly, +# because the exact number of holes might differ intermittently. + +if test "${nonSparseBlocks}" -gt "${inputBlocks}" && ! test "${outputBlocks}" -lt "${nonSparseBlocks}"; then + echo "output is not sparse" + echo "input file:" + ls -ls "${workFile1}" + echo "output file:" + ls -ls "${workFile2}" + echo "input file without holes:" + ls -ls "${workFile3}" + exit 1 +fi + +exit 0