Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 10 Mar 2023 13:29:24 GMT
From:      =?utf-8?Q?Dag-Erling=20Sm=C3=B8rgrav?= <des@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 64c2a712d661 - main - tftp: Add tests.
Message-ID:  <202303101329.32ADTOLJ090207@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by des:

URL: https://cgit.FreeBSD.org/src/commit/?id=64c2a712d661db9be31f02fe97c3b59710290ae3

commit 64c2a712d661db9be31f02fe97c3b59710290ae3
Author:     Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2023-03-10 13:24:56 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2023-03-10 13:25:16 +0000

    tftp: Add tests.
    
    Sponsored by:   Klara, Inc.
    Reviewed by:    asomers
    Differential Revision:  https://reviews.freebsd.org/D38969
---
 etc/mtree/BSD.tests.dist        |   2 +
 usr.bin/tftp/Makefile           |   5 +
 usr.bin/tftp/tests/Makefile     |  10 +
 usr.bin/tftp/tests/tftp_test.sh | 406 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 423 insertions(+)

diff --git a/etc/mtree/BSD.tests.dist b/etc/mtree/BSD.tests.dist
index f3420369ad80..c9a13cec193e 100644
--- a/etc/mtree/BSD.tests.dist
+++ b/etc/mtree/BSD.tests.dist
@@ -1110,6 +1110,8 @@
         ..
         tar
         ..
+        tftp
+        ..
         tr
         ..
         truncate
diff --git a/usr.bin/tftp/Makefile b/usr.bin/tftp/Makefile
index b6ad018e03ac..91df4847c629 100644
--- a/usr.bin/tftp/Makefile
+++ b/usr.bin/tftp/Makefile
@@ -1,6 +1,8 @@
 #	@(#)Makefile	8.1 (Berkeley) 6/6/93
 # $FreeBSD$
 
+.include <src.opts.mk>
+
 .PATH: ${SRCTOP}/libexec/tftpd
 
 PROG=	tftp
@@ -10,4 +12,7 @@ CFLAGS+=-I${SRCTOP}/libexec/tftpd
 
 LIBADD=	edit
 
+HAS_TESTS=
+SUBDIR.${MK_TESTS}=	tests
+
 .include <bsd.prog.mk>
diff --git a/usr.bin/tftp/tests/Makefile b/usr.bin/tftp/tests/Makefile
new file mode 100644
index 000000000000..ca5d89f92af3
--- /dev/null
+++ b/usr.bin/tftp/tests/Makefile
@@ -0,0 +1,10 @@
+# $FreeBSD$
+
+PACKAGE=	tests
+
+ATF_TESTS_SH=	tftp_test
+BINDIR=		${TESTSDIR}
+
+TESTS_METADATA.tftp_test+= is_exclusive="true"
+
+.include <bsd.test.mk>
diff --git a/usr.bin/tftp/tests/tftp_test.sh b/usr.bin/tftp/tests/tftp_test.sh
new file mode 100644
index 000000000000..96e375f51aeb
--- /dev/null
+++ b/usr.bin/tftp/tests/tftp_test.sh
@@ -0,0 +1,406 @@
+#
+# Copyright (c) 2023 Klara, Inc.
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+tftp_dir="${TMPDIR:-/tmp}/tftp.dir"
+inetd_conf="${TMPDIR:-/tmp}/inetd.conf"
+inetd_pid="${TMPDIR:-/tmp}/inetd.pid"
+
+start_tftpd() {
+	if ! [ -z "$(sockstat -PUDP -p69 -q)" ] ; then
+		atf_skip "the tftp port is in use"
+	fi
+	echo "starting inetd for $(atf_get ident)" >&2
+	rm -rf "${tftp_dir}"
+	mkdir "${tftp_dir}"
+	cat >"${inetd_conf}" <<EOF
+tftp	dgram	udp	wait	root	/usr/libexec/tftpd	tftpd -d15 -l ${tftp_dir}
+tftp	dgram	udp6	wait	root	/usr/libexec/tftpd	tftpd -d15 -l ${tftp_dir}
+EOF
+	/usr/sbin/inetd -a localhost -p "${inetd_pid}" "${inetd_conf}"
+}
+
+stop_tftpd() {
+	echo "stopping inetd for $(atf_get ident)" >&2
+	# Send SIGTERM to inetd, then SIGKILL until it's gone
+	local sig=TERM
+	while pkill -$sig -LF "${inetd_pid}" inetd ; do
+		echo "waiting for inetd to stop" >&2
+		sleep 1
+		sig=KILL
+	done
+	rm -rf "${tftp_dir}" "${inetd_conf}" "${inetd_pid}"
+}
+
+atf_test_case tftp_get_big cleanup
+tftp_get_big_head() {
+	atf_set "descr" "get command with big file"
+	atf_set "require.user" "root"
+}
+tftp_get_big_body() {
+	start_tftpd
+	local remote_file="${tftp_dir}/remote.bin"
+	dd if=/dev/urandom of="${remote_file}" bs=1m count=16 status=none
+	local local_file="local.bin"
+	echo "get ${remote_file##*/} ${local_file}" >client-script
+	atf_check -o match:"Received [0-9]+ bytes" \
+	    tftp localhost <client-script
+	atf_check cmp -s "${local_file}" "${remote_file}"
+}
+tftp_get_big_cleanup() {
+	stop_tftpd
+}
+
+atf_test_case tftp_get_host cleanup
+tftp_get_host_head() {
+	atf_set "descr" "get command with host name"
+	atf_set "require.user" "root"
+}
+tftp_get_host_body() {
+	start_tftpd
+	local remote_file="${tftp_dir}/hello.txt"
+	echo "Hello, $$!" >"${remote_file}"
+	local local_file="${remote_file##*/}"
+	echo "get localhost:${remote_file##*/}" >client-script
+	atf_check -o match:"Received [0-9]+ bytes" \
+	    tftp <client-script
+	atf_check cmp -s "${local_file}" "${remote_file}"
+}
+tftp_get_host_cleanup() {
+	stop_tftpd
+}
+
+atf_test_case tftp_get_ipv4 cleanup
+tftp_get_ipv4_head() {
+	atf_set "descr" "get command with ipv4 address"
+	atf_set "require.user" "root"
+}
+tftp_get_ipv4_body() {
+	start_tftpd
+	local remote_file="${tftp_dir}/hello.txt"
+	echo "Hello, $$!" >"${remote_file}"
+	local local_file="${remote_file##*/}"
+	echo "get 127.0.0.1:${remote_file##*/}" >client-script
+	atf_check -o match:"Received [0-9]+ bytes" \
+	    tftp <client-script
+	atf_check cmp -s "${local_file}" "${remote_file}"
+}
+tftp_get_ipv4_cleanup() {
+	stop_tftpd
+}
+
+atf_test_case tftp_get_ipv6 cleanup
+tftp_get_ipv6_head() {
+	atf_set "descr" "get command with ipv6 address"
+	atf_set "require.user" "root"
+}
+tftp_get_ipv6_body() {
+	sysctl -q kern.features.inet6 || atf_skip "This test requires IPv6 support"
+	start_tftpd
+	local remote_file="${tftp_dir}/hello.txt"
+	echo "Hello, $$!" >"${remote_file}"
+	local local_file="${remote_file##*/}"
+	echo "get [::1]:${remote_file##*/}" >client-script
+	atf_check -o match:"Received [0-9]+ bytes" \
+	    tftp <client-script
+	atf_check cmp -s "${local_file}" "${remote_file}"
+}
+tftp_get_ipv6_cleanup() {
+	stop_tftpd
+}
+
+atf_test_case tftp_get_one cleanup
+tftp_get_one_head() {
+	atf_set "descr" "get command with one argument"
+	atf_set "require.user" "root"
+}
+tftp_get_one_body() {
+	start_tftpd
+	local remote_file="${tftp_dir}/hello.txt"
+	echo "Hello, $$!" >"${remote_file}"
+	local local_file="${remote_file##*/}"
+	echo "get ${remote_file##*/}" >client-script
+	atf_check -o match:"Received [0-9]+ bytes" \
+	    tftp localhost <client-script
+	atf_check cmp -s "${local_file}" "${remote_file}"
+}
+tftp_get_one_cleanup() {
+	stop_tftpd
+}
+
+atf_test_case tftp_get_two cleanup
+tftp_get_two_head() {
+	atf_set "descr" "get command with two arguments"
+	atf_set "require.user" "root"
+}
+tftp_get_two_body() {
+	start_tftpd
+	local remote_file="${tftp_dir}/hello.txt"
+	echo "Hello, $$!" >"${remote_file}"
+	local local_file="world.txt"
+	echo "get ${remote_file##*/} ${local_file}" >client-script
+	atf_check -o match:"Received [0-9]+ bytes" \
+	    tftp localhost <client-script
+	atf_check cmp -s "${local_file}" "${remote_file}"
+}
+tftp_get_two_cleanup() {
+	stop_tftpd
+}
+
+atf_test_case tftp_get_more cleanup
+tftp_get_more_head() {
+	atf_set "descr" "get command with three or more arguments"
+	atf_set "require.user" "root"
+}
+tftp_get_more_body() {
+	start_tftpd
+	for n in 3 4 5 6 7 ; do
+		echo -n "get" >client-script
+		for f in $(jot -c $n 97) ; do
+			echo "test file $$/$f/$n" >"${tftp_dir}/${f}.txt"
+			echo -n " ${f}.txt" >>client-script
+			rm -f "${f}.txt"
+		done
+		echo >>client-script
+		atf_check -o match:"Received [0-9]+ bytes" \
+		    tftp localhost <client-script
+		for f in $(jot -c $n 97) ; do
+			atf_check cmp -s "${f}.txt" "${tftp_dir}/${f}.txt"
+		done
+	done
+}
+tftp_get_more_cleanup() {
+	stop_tftpd
+}
+
+atf_test_case tftp_get_multi_host cleanup
+tftp_get_multi_host_head() {
+	atf_set "descr" "get command with multiple files and host name"
+	atf_set "require.user" "root"
+}
+tftp_get_multi_host_body() {
+	start_tftpd
+	for f in a b c ; do
+		echo "test file $$/$f/$n" >"${tftp_dir}/${f}.txt"
+		rm -f "${f}.txt"
+	done
+	echo "get localhost:a.txt b.txt c.txt" >client-script
+	atf_check -o match:"Received [0-9]+ bytes" \
+	    tftp localhost <client-script
+	for f in a b c ; do
+		atf_check cmp -s "${f}.txt" "${tftp_dir}/${f}.txt"
+	done
+}
+tftp_get_multi_host_cleanup() {
+	stop_tftpd
+}
+
+atf_test_case tftp_put_big cleanup
+tftp_put_big_head() {
+	atf_set "descr" "put command with big file"
+	atf_set "require.user" "root"
+}
+tftp_put_big_body() {
+	start_tftpd
+	local local_file="local.bin"
+	dd if=/dev/urandom of="${local_file}" bs=1m count=16 status=none
+	local remote_file="${tftp_dir}/random.bin"
+	truncate -s 0 "${remote_file}"
+	chown nobody:nogroup "${remote_file}"
+	chmod 0666 "${remote_file}"
+	echo "put ${local_file} ${remote_file##*/}" >client-script
+	atf_check -o match:"Sent [0-9]+ bytes" \
+	    tftp localhost <client-script
+	atf_check cmp -s "${remote_file}" "${local_file}"
+}
+tftp_put_big_cleanup() {
+	stop_tftpd
+}
+
+atf_test_case tftp_put_host cleanup
+tftp_put_host_head() {
+	atf_set "descr" "put command with host name"
+	atf_set "require.user" "root"
+}
+tftp_put_host_body() {
+	start_tftpd
+	local local_file="local.txt"
+	echo "test file $$" >"${local_file}"
+	local remote_file="${tftp_dir}/remote.txt"
+	truncate -s 0 "${remote_file}"
+	chown nobody:nogroup "${remote_file}"
+	chmod 0666 "${remote_file}"
+	echo "put ${local_file} localhost:${remote_file##*/}" >client-script
+	atf_check -o match:"Sent [0-9]+ bytes" \
+	    tftp <client-script
+	atf_check cmp -s "${remote_file}" "${local_file}"
+}
+tftp_put_host_cleanup() {
+	stop_tftpd
+}
+
+atf_test_case tftp_put_ipv4 cleanup
+tftp_put_ipv4_head() {
+	atf_set "descr" "put command with ipv4 address"
+	atf_set "require.user" "root"
+}
+tftp_put_ipv4_body() {
+	start_tftpd
+	local local_file="local.txt"
+	echo "test file $$" >"${local_file}"
+	local remote_file="${tftp_dir}/remote.txt"
+	truncate -s 0 "${remote_file}"
+	chown nobody:nogroup "${remote_file}"
+	chmod 0666 "${remote_file}"
+	echo "put ${local_file} 127.0.0.1:${remote_file##*/}" >client-script
+	atf_check -o match:"Sent [0-9]+ bytes" \
+	    tftp <client-script
+	atf_check cmp -s "${remote_file}" "${local_file}"
+}
+tftp_put_ipv4_cleanup() {
+	stop_tftpd
+}
+
+atf_test_case tftp_put_ipv6 cleanup
+tftp_put_ipv6_head() {
+	atf_set "descr" "put command with ipv6 address"
+	atf_set "require.user" "root"
+}
+tftp_put_ipv6_body() {
+	sysctl -q kern.features.inet6 || atf_skip "This test requires IPv6 support"
+	start_tftpd
+	local local_file="local.txt"
+	echo "test file $$" >"${local_file}"
+	local remote_file="${tftp_dir}/remote.txt"
+	truncate -s 0 "${remote_file}"
+	chown nobody:nogroup "${remote_file}"
+	chmod 0666 "${remote_file}"
+	echo "put ${local_file} [::1]:${remote_file##*/}" >client-script
+	atf_check -o match:"Sent [0-9]+ bytes" \
+	    tftp <client-script
+	atf_check cmp -s "${remote_file}" "${local_file}"
+}
+tftp_put_ipv6_cleanup() {
+	stop_tftpd
+}
+
+atf_test_case tftp_put_one cleanup
+tftp_put_one_head() {
+	atf_set "descr" "put command with one argument"
+	atf_set "require.user" "root"
+}
+tftp_put_one_body() {
+	start_tftpd
+	local local_file="file.txt"
+	echo "test file $$" >"${local_file}"
+	local remote_file="${tftp_dir}/${local_file}"
+	truncate -s 0 "${remote_file}"
+	chown nobody:nogroup "${remote_file}"
+	chmod 0666 "${remote_file}"
+	echo "put ${local_file}" >client-script
+	atf_check -o match:"Sent [0-9]+ bytes" \
+	    tftp localhost <client-script
+	atf_check cmp -s "${remote_file}" "${local_file}"
+}
+tftp_put_one_cleanup() {
+	stop_tftpd
+}
+
+atf_test_case tftp_put_two cleanup
+tftp_put_two_head() {
+	atf_set "descr" "put command with two arguments"
+	atf_set "require.user" "root"
+}
+tftp_put_two_body() {
+	start_tftpd
+	local local_file="local.txt"
+	echo "test file $$" >"${local_file}"
+	local remote_file="${tftp_dir}/remote.txt"
+	truncate -s 0 "${remote_file}"
+	chown nobody:nogroup "${remote_file}"
+	chmod 0666 "${remote_file}"
+	echo "put ${local_file} ${remote_file##*/}" >client-script
+	atf_check -o match:"Sent [0-9]+ bytes" \
+	    tftp localhost <client-script
+	atf_check cmp -s "${remote_file}" "${local_file}"
+}
+tftp_put_two_cleanup() {
+	stop_tftpd
+}
+
+atf_test_case tftp_put_more cleanup
+tftp_put_more_head() {
+	atf_set "descr" "put command with three or more arguments"
+	atf_set "require.user" "root"
+}
+tftp_put_more_body() {
+	start_tftpd
+	mkdir "${tftp_dir}/subdir"
+	for n in 2 3 4 5 6 ; do
+		echo -n "put" >client-script
+		for f in $(jot -c $n 97) ; do
+			echo "test file $$/$f/$n" >"${f}.txt"
+			truncate -s 0 "${tftp_dir}/subdir/${f}.txt"
+			chown nobody:nogroup "${tftp_dir}/subdir/${f}.txt"
+			chmod 0666 "${tftp_dir}/subdir/${f}.txt"
+			echo -n " ${f}.txt" >>client-script
+		done
+		echo " subdir" >>client-script
+		atf_check -o match:"Sent [0-9]+ bytes" \
+		    tftp localhost <client-script
+		for f in $(jot -c $n 97) ; do
+			atf_check cmp -s "${tftp_dir}/subdir/${f}.txt" "${f}.txt"
+		done
+	done
+}
+tftp_put_more_cleanup() {
+	stop_tftpd
+}
+
+atf_test_case tftp_put_multi_host cleanup
+tftp_put_multi_host_head() {
+	atf_set "descr" "put command with multiple files and host name"
+	atf_set "require.user" "root"
+}
+tftp_put_multi_host_body() {
+	start_tftpd
+	mkdir "${tftp_dir}/subdir"
+	echo -n "put" >client-script
+	for f in a b c ; do
+		echo "test file $$/$f" >"${f}.txt"
+		truncate -s 0 "${tftp_dir}/subdir/${f}.txt"
+		chown nobody:nogroup "${tftp_dir}/subdir/${f}.txt"
+		chmod 0666 "${tftp_dir}/subdir/${f}.txt"
+		echo -n " ${f}.txt" >>client-script
+	done
+	echo " localhost:subdir" >>client-script
+	atf_check -o match:"Sent [0-9]+ bytes" \
+	    tftp <client-script
+	for f in a b c ; do
+		atf_check cmp -s "${tftp_dir}/subdir/${f}.txt" "${f}.txt"
+	done
+}
+tftp_put_multi_host_cleanup() {
+	stop_tftpd
+}
+
+atf_init_test_cases() {
+	atf_add_test_case tftp_get_big
+	atf_add_test_case tftp_get_host
+	atf_add_test_case tftp_get_ipv4
+	atf_add_test_case tftp_get_ipv6
+	atf_add_test_case tftp_get_one
+	atf_add_test_case tftp_get_two
+	atf_add_test_case tftp_get_more
+	atf_add_test_case tftp_get_multi_host
+	atf_add_test_case tftp_put_big
+	atf_add_test_case tftp_put_host
+	atf_add_test_case tftp_put_ipv4
+	atf_add_test_case tftp_put_ipv6
+	atf_add_test_case tftp_put_one
+	atf_add_test_case tftp_put_two
+	atf_add_test_case tftp_put_more
+	atf_add_test_case tftp_put_multi_host
+}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202303101329.32ADTOLJ090207>