. "$BST_LIB" # BST-TIMEOUT: 600 # GNU inetutils 2.5 -- first half: the standalone tools (hostname, ping, ping6, # ifconfig, traceroute, logger) and the three clients' identity. The servers and # the loopback round trips are in 88-inetutils-net.test, which is a SEPARATE FILE # so each half gets its own guest: seventeen ~4 MB binaries in one boot ran the # first version of this suite past the 600 s bound with two cases still to go, # and this guest does not return memory on process exit. # # EVERY BINARY IS NAMED BY ITS ABSOLUTE .inetutils PATH, never by the bare name # on $PATH. Nine of these tools are update-alternatives entries and inetutils # bids 79 for them against net-tools' 100 and busybox's -- so `hostname` and # `ifconfig` on this image are NOT inetutils', and a suite that ran them would be # reporting on a different package. The concrete file the alternative points at # is always .inetutils, and that is what this port is accountable for. require /bin/hostname.inetutils inetutils/present H=/bin/hostname.inetutils PING=/bin/ping.inetutils PING6=/bin/ping6.inetutils TELNET=/usr/bin/telnet.inetutils TFTP=/usr/bin/tftp.inetutils FTP=/usr/bin/ftp.inetutils TRACE=/usr/bin/traceroute.inetutils LOGGER=/usr/bin/logger.inetutils D=${TMPDIR:-/tmp}/bst-inetutils.$$ rm -rf "$D"; mkdir -p "$D" || { bst_notok inetutils/workdir "cannot create $D"; exit 0; } # gap -- the red for a failure this port has already traced to a # platform gap, named at the case rather than left for a reader to re-derive. An # unrecognised failure falls through to a plain red on purpose: that is what a # regression in inetutils itself should look like, and it must not be absorbed by # an attribution written for a different cause. gap() { case "$2" in *"setuid: Function not implemented"*) bst_notok "$1" "brintos/linux#19 (credential setters ENOSYS): the raw ICMP socket WAS created -- ping_init() runs first and printed nothing -- and ping then died on setuid(getuid()), which is a no-op at uid 0 -- $(_bst_1line "$2")" ;; *"family not supported"*|*"Address family"*) bst_notok "$1" "brintos/linux#54 (kernel built CONFIG_IPV6=n): socket(AF_INET6,...) is refused with EAFNOSUPPORT -- $(_bst_1line "$2")" ;; *) bst_notok "$1" "$(_bst_1line "$2")" ;; esac } # --- inventory ---------------------------------------------------------------- # The package splits into fourteen debs and the image installs fourteen minus # one: inetutils-syslogd is deliberately absent, because it RCONFLICTS sysklogd, # which this image already ships. inetutils-rsh/-rshd are built empty (the # recipe passes --disable-rsh and friends) and are not installed either. A file # missing here means a package was dropped from IMAGE_INSTALL, which no # functional case below would localise. inv="" for f in "$H" "$PING" "$PING6" "$TELNET" "$TFTP" "$FTP" "$TRACE" "$LOGGER" \ /usr/bin/inetd.inetutils /sbin/ifconfig.inetutils \ /usr/sbin/in.telnetd /usr/sbin/in.tftpd /usr/bin/ftpd.inetutils \ /bin/dnsdomainname.inetutils /usr/bin/whois.inetutils; do [ -x "$f" ] || inv="$inv $f" done check_eq inetutils/inventory "" "$inv" # inetutils-syslogd must NOT be here: it and sysklogd both claim /sbin/syslogd, # and shipping both is what RCONFLICTS exists to prevent. Asserted rather than # assumed, because an accidental re-add would be silent until something started # the wrong daemon. check_eq inetutils/syslogd-not-installed "" "$(ls /usr/sbin/syslogd.inetutils /sbin/syslogd.inetutils 2>/dev/null)" # --- hostname: the ticket's first named criterion ----------------------------- # "the configured name" is what the kernel holds, so compare against the kernel's # own copy rather than a literal -- the name is set by the image, not by this # suite. /proc/sys is readable exactly once per path per boot on this image # (brintos/linux#36), so it is read ONCE here and reused. sysname=$(cat /proc/sys/kernel/hostname 2>/dev/null) check_eq inetutils/hostname-reports-configured "$sysname" "$("$H" 2>/dev/null)" check_eq inetutils/hostname-short "${sysname%%.*}" "$("$H" -s 2>/dev/null)" # --- ping: the ticket's second named criterion -------------------------------- # Both halves of the verdict in one case: a reply count AND no loss. "0% packet # loss" alone would pass a run that sent nothing. pout=$("$PING" -c 2 -w 5 127.0.0.1 2>&1); prc=$? case "$pout" in *"2 packets received"*) case "$pout" in *"0% packet loss"*) if [ "$prc" -eq 0 ]; then bst_ok inetutils/ping-loopback else gap inetutils/ping-loopback "rc=$prc $pout"; fi ;; *) gap inetutils/ping-loopback "replies but loss reported: $pout" ;; esac ;; *) if bst_execfail "$pout"; then bst_unrun inetutils/ping-loopback "$pout" else gap inetutils/ping-loopback "rc=$prc $pout"; fi ;; esac # ping6 exits 1 having printed NOTHING AT ALL, so the cause has to come from the # kernel rather than from the tool's own diagnostic. /proc/net/if_inet6 is the # witness: absent means the kernel carries no IPv6 stack, so ping_init()'s # socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6) cannot succeed. Checked here rather # than asserted from the empty output, because "no output" on its own would # equally fit a trap or a silent early exit. p6=$("$PING6" -c 2 -w 5 ::1 2>&1); p6rc=$? case "$p6" in *"0% packet loss"*) if [ "$p6rc" -eq 0 ]; then bst_ok inetutils/ping6-loopback else gap inetutils/ping6-loopback "rc=$p6rc $p6"; fi ;; *) if bst_execfail "$p6"; then bst_unrun inetutils/ping6-loopback "$p6" elif [ ! -e /proc/net/if_inet6 ]; then bst_notok inetutils/ping6-loopback "brintos/linux#54 (kernel built CONFIG_IPV6=n; /proc/net/if_inet6 absent): there is no AF_INET6 to open a raw socket on, so ping6 exits before it can print -- rc=$p6rc out='${p6:-}'" else gap inetutils/ping6-loopback "rc=$p6rc ${p6:-}"; fi ;; esac # --- ifconfig and traceroute -------------------------------------------------- # inetutils' ifconfig is NOT the one `ifconfig` resolves to here (net-tools bids # 100 to its 79); this runs the concrete file, so it reports on this port. check_out inetutils/ifconfig-loopback "127.0.0.1" /sbin/ifconfig.inetutils lo # traceroute is numeric by default -- resolution is opt-in via # --resolve-hostnames -- and unlike ping it drops no privilege, so it exercises # the same raw-ICMP receive path with the credential setters out of the picture. check_out inetutils/traceroute-loopback "127.0.0.1" "$TRACE" 127.0.0.1 # --- logger ------------------------------------------------------------------- # logger's default target is /dev/log, and this image starts no syslogd, so # nothing is listening there -- that is the image's state, not a logger defect, # and a case asserting against it would be testing the wrong thing. `-u` is # exactly the option for naming another socket, so the suite provides one: # AF_UNIX SOCK_DGRAM, which is what logger.c:274 opens. socat is the receiver # (already on this image, covered by 88-socat); if it is absent this is a skip, # because the missing piece is then the harness, not the subject. if command -v socat >/dev/null 2>&1; then socat -u UNIX-RECV:"$D/log.sock" - >"$D/log.out" 2>"$D/log.err" & spid=$! n=0; while [ $n -lt 40 ]; do [ -S "$D/log.sock" ] && break; n=$((n+1)); sleep 1; done "$LOGGER" -u "$D/log.sock" -t bst-inetutils -p user.notice "BST-INETUTILS-LOG" \ >"$D/log.cli" 2>&1 n=0; while [ $n -lt 40 ]; do [ -s "$D/log.out" ] && break; n=$((n+1)); sleep 1; done kill "$spid" 2>/dev/null got=$(cat "$D/log.out" 2>/dev/null) case "$got" in *bst-inetutils*BST-INETUTILS-LOG*) bst_ok inetutils/logger-unix-socket ;; *) bst_notok inetutils/logger-unix-socket "want tag+message on the socket, got:'$(_bst_1line "$got")' logger said:'$(_bst_1line "$(cat "$D/log.cli" 2>/dev/null)")'" ;; esac else bst_skip inetutils/logger-unix-socket "socat not installed; it is this case's UNIX-datagram receiver" fi # --- the clients answer for themselves ---------------------------------------- # Cheap, but not redundant with the round trips in the other half: these run the # client binaries in THIS guest, so a client that cannot even start is localised # here rather than showing up as a server-side failure over there. check_out inetutils/telnet-version "inetutils" "$TELNET" --version check_out inetutils/tftp-version "inetutils" "$TFTP" --version check_out inetutils/ftp-version "inetutils" "$FTP" --version rm -rf "$D"