diff --git a/Makefile.am b/Makefile.am index 9a739b6..5df4bd1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -101,6 +101,7 @@ tests/Transfer_-_--rate-limit.test \ tests/Transfer_-_--remote.test \ tests/Transfer_-_--stop-at-size.test \ tests/Transfer_-_--stop-at-size_reads.test \ +tests/Watchfd_-_Multiple_arguments.test \ tests/Watchfd_-_Multiple_descriptors.test \ tests/Watchfd_-_Single_descriptor.test diff --git a/tests/Memory_safety_-_Watchfd.test b/tests/Memory_safety_-_Watchfd.test index 54c7f1f..6791397 100755 --- a/tests/Memory_safety_-_Watchfd.test +++ b/tests/Memory_safety_-_Watchfd.test @@ -65,4 +65,43 @@ pid=$! sleep 0.1 { runWithValgrind -P "${workFile3}" -d "${pid}" -f -i 0.5 >/dev/null 2>&1; } 4>&1 || exit 1 +# Check "--watchfd PID1 PID2". +seq 1 100 > "${workFile1}" +seq 1 300 > "${workFile2}" +true > "${workFile3}" +# shellcheck disable=SC2030 +( +while test -e "${workFile3}" && ! test -s "${workFile3}"; do sleep 0.1; done +sleep 1 +read -r line +exec 9<"${workFile2}" +sleep 1 +exec 8<"${workFile1}" +exec 7/dev/null 2>&1; } 4>&1 || exit 1 + exit 0 diff --git a/tests/Watchfd_-_Multiple_arguments.test b/tests/Watchfd_-_Multiple_arguments.test new file mode 100755 index 0000000..7428967 --- /dev/null +++ b/tests/Watchfd_-_Multiple_arguments.test @@ -0,0 +1,101 @@ +#!/bin/sh +# +# Check that watching a process's file descriptors works as expected when +# given multiple arguments. + +# 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'}" +true "${workFile4:?not set - call this from 'make check'}" + +# Skip the test if "-d" is not available. +if ! "${testSubject}" -h | grep -Fq ' -d'; then + echo "no \`--watchfd' / \`-d' option on this platform" + exit 77 +fi + +seq 1 100 > "${workFile1}" +seq 1 300 > "${workFile2}" + +# Run two background processes to perform a few reads from a file. +# +# Each one only starts doing anything once the PV process below has started +# (the workFile3 check). +true > "${workFile3}" +( +while test -e "${workFile3}" && ! test -s "${workFile3}"; do sleep 0.1; done +sleep 1 +# shellcheck disable=SC2034 # line is deliberately unused +read -r line <&8 +sleep 1 +) <&- 8<"${workFile1}" & +pid1=$! + +( +while test -e "${workFile3}" && ! test -s "${workFile3}"; do sleep 0.1; done +sleep 1 +# shellcheck disable=SC2034 # line is deliberately unused +read -r line <&9 +sleep 1 +) <&- 9<"${workFile2}" & +pid2=$! + +sleep 0.1 +"${testSubject}" -P "${workFile3}" -f -i 0.5 -d "${pid1}" "${pid2}" >/dev/null 2>"${workFile4}" + +# Skip the test if "-d" does not work. +if grep -Fq ' -d: not available' "${workFile4}"; then + echo "no \`--watchfd' / \`-d' option on this platform" + exit 77 +fi + +# Process the output to make it easier to handle. +# NB "ESC [ A" is "cursor up", we turn that into "-" and a newline. +tr '\r' '\n' < "${workFile4}" | sed 's/.\[A/-!/g' | tr '!' '\n' > "${workFile1}" + +# We should see at least 2 file positions for fd 8. +positionsReported="$(awk '/^[0-9 ]+: *8:/ {print $3}' < "${workFile1}" | sort -n | uniq)" +differentNumbers="$(printf "%s\n" "${positionsReported}" | grep -Ec .)" +if ! test "${differentNumbers}" -gt 1; then + printf "%s\n" "Expected at least 2 different numbers to be output for fd 8" + printf "%s:\n%s\n" "Positions reported" "${positionsReported}" + printf "%s: %s\n" "Number of different values seen" "${differentNumbers}" + printf "%s\n" "Raw output:" + cat "${workFile1}" + exit 1 +fi + +# We should see at least 2 file positions for fd 9. +positionsReported="$(awk '/^[0-9 ]+: *9:/ {print $3}' < "${workFile1}" | sort -n | uniq)" +differentNumbers="$(printf "%s\n" "${positionsReported}" | grep -Ec .)" +if ! test "${differentNumbers}" -gt 1; then + printf "%s\n" "Expected at least 2 different numbers to be output for fd 9" + printf "%s:\n%s\n" "Positions reported" "${positionsReported}" + printf "%s: %s\n" "Number of different values seen" "${differentNumbers}" + printf "%s\n" "Raw output:" + cat "${workFile1}" + exit 1 +fi + +# We should see the last 6 characters of fd 8's filename appear. +lastChars="$(printf "%s\n" "${workFile1}" | rev | cut -b1-6 | rev)" +if ! grep -Fq "${lastChars}:" < "${workFile1}"; then + printf "%s\n" "Expected to see a filename for fd 8" + printf "%s\n" "Raw output:" + cat "${workFile1}" + exit 1 +fi +# We should see the last 6 characters of fd 9's filename appear. +lastChars="$(printf "%s\n" "${workFile2}" | rev | cut -b1-6 | rev)" +if ! grep -Fq "${lastChars}:" < "${workFile1}"; then + printf "%s\n" "Expected to see a filename for fd 9" + printf "%s\n" "Raw output:" + cat "${workFile1}" + exit 1 +fi + +exit 0