#!/bin/bash -ue
test_checkrestart(){
		echo "** Testing: 'checkrestart $*'"
		local d

		for d in /tmp /usr/lib; do
				if [ -e "$d/_checkrestart_test" ]; then
						echo "$0: ERROR: Should not exist: $d/_checkrestart_test" >&2
						exit 1
				fi
		done

		# Create temp files and then unlink them - now this script will be
		# detetected as using deleted files
		exec 3> /tmp/_checkrestart_test
		unlink /tmp/_checkrestart_test

		exec 4> /usr/lib/_checkrestart_test
		unlink /usr/lib/_checkrestart_test

		for d in /tmp /usr/lib; do
				if [ -e "$d/_checkrestart_test" ]; then
						echo "$0: ERROR: Should not exist: $d/_checkrestart_test" >&2
						exit 1
				fi
		done
		(
				# subprocesses inherit all open fd's so we need to run the
				# test from a subshell or all of checkrestart, tee and grep
				# would also be detected as 'using' the deleted files
				exec 3>&-
				exec 4>&-
				echo "*** Running: 'checkrestart $*'"
				: > output
				checkrestart "$@" | tee output
				local exit_status=${PIPESTATUS[0]}
				echo "*** Looking for: '$EXPECTED'"
				if grep -E --text "$EXPECTED" output; then
						echo "** PASS: 'checkrestart $*' (exit: $exit_status)"
				else
						echo >&2 "** FAIL: 'checkrestart $*' failed (checkrestart exit=$exit_status; grep code=$?)"
				fi

		)
		# clean up: close fds
		exec 3>&-
		exec 4>&-
		echo
}

echo "* Starting $0"
echo "** (Info on environment follows)"
export ME="$0"
export PID="$$"
env

echo "Unfortunately, testing has shown that sometimes the debian salsa.debian.org infrastructure does
actually have processes using deleted files. And this also affects testing autopkgtests inside a schroot.

So we can't simply run checkrestart and expect to find
nothing.

So we have to mock the results of lsof to only report info on the current process, and ignore
everything else that happens to be running."

lsof=/usr/local/sbin/lsof

if [ -f "$lsof" ]; then
		echo "ERROR: $lsof should not exist" >&2
		exit 9
fi

cat > "$lsof" <<EOF
#!/bin/sh
exec /usr/bin/lsof -p $PID "\$@"
EOF
cat "$lsof"
chmod +x "$lsof"
echo
echo "Checking it works:"
type -p lsof
lsof


echo "** Starting test: checkrestart"
echo "This first test assumes that there is nothing using deleted files"
echo "If this assumption is wrong, likely all following tests will fail too"
echo "so if this test fails, either something is very wrong with checkrestart"
echo "or the tests (or system they run on) may be at fault."
: > output
checkrestart | tee output
if grep -q "0 non-ignored" output; then
		 echo "*** PASS"
else
	 echo >&2 "*** FAIL: test 'checkrestart' failed"
fi


EXPECTED="1 non-ignored " test_checkrestart
EXPECTED="RESTART_NEEDED: 1" test_checkrestart --machine
EXPECTED="1 non-ignored " test_checkrestart --terse

# -f - list deleted files
EXPECTED="/usr/lib/_checkrestart_test" test_checkrestart --show-files
TAB=$(printf '\t')
EXE="(/usr)?/bin/bash" # path could be /bin/bash or /usr/bin/bash depending on usrmerge
CMDLINE="\['/bin/bash', '-ue', '$ME'\]"

EXPECTED="^file${TAB}/usr/lib/_checkrestart_test${TAB}[0-9]+${TAB}${ME}${TAB}${EXE}${TAB}${CMDLINE}${TAB}${TAB}Script\$" test_checkrestart --machine --show-files

# --terse gives one line
# -v implies -f
# -t overides -f
# -v does work with -t
EXPECTED="1 non-ignored" test_checkrestart --terse --show-files
EXPECTED="1 non-ignored" test_checkrestart --show-files -t
EXPECTED="1 non-ignored" test_checkrestart --terse --all
# -a means nothing is ignored, so -v doesnt show much more
EXPECTED="not part of any package" test_checkrestart --terse --all -v
# without -a we see why things were ignored
EXPECTED="/tmp/_checkrestart_test" test_checkrestart --terse -v

# -i - ignore package ('Unpackaged' counts as a package)
EXPECTED="0 non-ignored" test_checkrestart -i Unpackaged -d

# -b
ignore_list=$(dirname "$(realpath "$0")")/files-to-ignore.list

EXPECTED="0 non-ignored " test_checkrestart -b "$ignore_list"
EXPECTED="Ignoring deleted file" test_checkrestart -b "$ignore_list" --verbose
# -v
EXPECTED="ignored_file" test_checkrestart -b "$ignore_list" --verbose --machine

# --packages means only deleted files and programs from packages are reported
EXPECTED="0 non-ignored" test_checkrestart -p
EXPECTED="Ignoring program" test_checkrestart -pv
EXPECTED="0 non-ignored" test_checkrestart -pv


# --all should also find the file in /tmp as well as the one in /usr
EXPECTED="1 non-ignored " test_checkrestart --all
EXPECTED="/tmp/_checkrestart_test" test_checkrestart --all -f
EXPECTED="^OTHER${TAB}Unpackaged: test-checkrestart${TAB}[0-9]+${TAB}$ME${TAB}${EXE}${TAB}${CMDLINE}${TAB}${TAB}Script\$" test_checkrestart --all --machine

EXPECTED="PROCESSES_ALL: 1" test_checkrestart --all --verbose --machine
EXPECTED="^file${TAB}/tmp/_checkrestart_test${TAB}[0-9]+${TAB}${ME}${TAB}${EXE}${TAB}${CMDLINE}${TAB}${TAB}Script\$" test_checkrestart --all --machine -f

# -x (and -a)
EXPECTED="0 non-ignored " test_checkrestart -a -x 'package:^Unpackaged' -d -x unit: -x suggested:. -x initscript:.
EXPECTED="0 non-ignored " test_checkrestart -a -x "program:^$ME\$" -d
EXPECTED="0 non-ignored " test_checkrestart -a -x 'file:^/(tmp|usr/lib)/_checkrestart_test$' -d
EXPECTED="0 non-ignored " test_checkrestart -a -x "pid:^$PID\$" -d




# -a can be combined with -b or -p - order matters
EXPECTED="0 non-ignored " test_checkrestart --all -p

# all files, but only from package
EXPECTED="0 non-ignored " test_checkrestart -p -a
EXPECTED="1 non-ignored " test_checkrestart -b "$ignore_list" --all
EXPECTED="/tmp/_checkrestart_test" test_checkrestart  --all -b "$ignore_list" -v
# -a before -b does not ignore
EXPECTED="^file${TAB}/usr/lib/_checkrestart_test${TAB}[0-9]+${TAB}${ME}${TAB}${EXE}${TAB}${CMDLINE}${TAB}${TAB}Script\$" test_checkrestart --machine --verbose  -b "$ignore_list" -a


# reboot-required (no pkgs)
for f in  /run/reboot-required /run/reboot-required.pkgs; do
		if [ -e "$f" ]; then
				echo "ERROR: $f should not exist" >&2
				exit 2
		fi
done

touch /run/reboot-required
EXPECTED="needs rebooting"
test_checkrestart
# still shows progs needing restart
EXPECTED="^1 non-ignored"
test_checkrestart

EXPECTED="needs rebooting"
test_checkrestart -t
EXPECTED="; 1 non-ignored"
test_checkrestart -t

EXPECTED="REBOOT_NEEDED: Yes; MISSING"
test_checkrestart -m
EXPECTED="RESTART_NEEDED: 1"
test_checkrestart -m

EXPECTED="REBOOT_NEEDED: Yes; MISSING"
test_checkrestart -tm
EXPECTED="RESTART_NEEDED: 1"
test_checkrestart -m

# with pkgs as well
echo -e "aaaa\nbbbb" >> /run/reboot-required.pkgs
EXPECTED="REQUESTED_REBOOT: bbbb"
test_checkrestart -m
EXPECTED="^${TAB}aaaa$"
test_checkrestart


echo "* Testsuite ended ($0)"
echo "Cleaning up"
rm -f /run/reboot-required /run/reboot-required.pkgs "$lsof" && echo "DONE."
exit 0
