diff --git a/etc/mtree/BSD.tests.dist b/etc/mtree/BSD.tests.dist --- 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 --- a/usr.bin/tftp/Makefile +++ b/usr.bin/tftp/Makefile @@ -1,6 +1,8 @@ # @(#)Makefile 8.1 (Berkeley) 6/6/93 # $FreeBSD$ +.include + .PATH: ${SRCTOP}/libexec/tftpd PROG= tftp @@ -10,4 +12,7 @@ LIBADD= edit +HAS_TESTS= +SUBDIR.${MK_TESTS}= tests + .include diff --git a/usr.bin/tftp/tests/Makefile b/usr.bin/tftp/tests/Makefile new file mode 100644 --- /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 diff --git a/usr.bin/tftp/tests/tftp_test.sh b/usr.bin/tftp/tests/tftp_test.sh new file mode 100644 --- /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}" <&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 "${remote_file}" + local local_file="${remote_file##*/}" + echo "get localhost:${remote_file##*/}" >client-script + atf_check -o match:"Received [0-9]+ bytes" \ + tftp "${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 "${remote_file}" + local local_file="${remote_file##*/}" + echo "get [::1]:${remote_file##*/}" >client-script + atf_check -o match:"Received [0-9]+ bytes" \ + tftp "${remote_file}" + local local_file="${remote_file##*/}" + echo "get ${remote_file##*/}" >client-script + atf_check -o match:"Received [0-9]+ bytes" \ + tftp localhost "${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 + 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 "${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 + atf_check -o match:"Sent [0-9]+ bytes" \ + tftp localhost "${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 "${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 "${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 "${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 "${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 + 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 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