hostname/Sanity/basic/runtest.sh
2025-06-12 16:22:04 +02:00

369 lines
16 KiB
Bash
Executable file

#!/bin/bash
# vim: dict+=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# runtest.sh of /CoreOS/hostname/Sanity/basic
# Description: sanity + basic white-box testing of hostname
# Author: Patrik Mosko <pmosko@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2019 Red Hat, Inc.
#
# This program is free software: you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see http://www.gnu.org/licenses/.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Include Beaker environment
. /usr/share/beakerlib/beakerlib.sh || exit 1
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PACKAGE="hostname"
TEST_hostname="myhostname"
TEST_domain="sanitytesting.com"
TEST_FQDN="$TEST_hostname.$TEST_domain"
TEST_hostname2="myhostname2"
TEST_domain2="sanitytesting2.com"
TEST_FQDN2="$TEST_hostname2.$TEST_domain2"
HOSTNAMED="/usr/lib/systemd/system/systemd-hostnamed.service"
DUMMIES_NUM=5 #number of dummy interfaces we are gonna operate with
TIMEOUT=15
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
backup_files() {
rlFileBackup --clean --missing-ok "/etc/hosts"
rlFileBackup --clean --missing-ok "/etc/hostname"
rlFileBackup --clean --missing-ok "/etc/host.conf"
rlFileBackup --clean --missing-ok "/etc/resolv.conf"
}
hostname_backup() {
rlLog "Backing up actual \`hostname\` value"
rlRun 'hostname_bak="$(hostname)"'
}
hostname_reset() {
rlLog "Reseting hostname to the last backed up value"
rlRun "hostname $hostname_bak"
}
set_hostname_by_length() {
local length="$1"
rlLog "Prepare hostname string of specified length ($length)"
test_hostname="$(printf 'h%.0s' $(seq 1 $length))"
rlRun "echo $test_hostname | wc -c"
rlAssertEquals "assert size of created string" $length ${#test_hostname}
}
etc-hosts_reset() {
rlLog "Reseting /etc/hosts to localhost mappings only"
rlRun ": >/etc/hosts"
rlRun "echo '127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4' > /etc/hosts"
rlRun "echo '::1 localhost localhost.localdomain localhost6 localhost6.localdomain6' >> /etc/hosts"
}
etc-hosts_add() {
local ip_addr="$1"
local domain="$2"
local alias="$3"
rlLog "Adding new entry into /etc/hosts"
echo "$ip_addr $domain $alias" >> /etc/hosts
}
resolv-conf_add() {
local str="$1"
rlLog "Adding new entry into /etc/resolv.conf"
echo "$str" >> /etc/resolv.conf
}
create_dummy_ifc() {
local dummies_num="$1"
rlLog "Create '$1' dummy interfaces and assign them static IPs"
rlRun "modprobe dummy numdummies=$dummies_num"
for ifc in `seq 0 $(( ${dummies_num}-1 ))`; do
rlRun "ip address add 9.8.7.${ifc}/32 dev dummy${ifc}"
rlRun "ip link set dev dummy${ifc} up"
done
ip address
}
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rlJournalStart
########## SETUP PHASE ##########
rlPhaseStartSetup
rlIsRHEL '<=6' && rlAssertRpm "net-tools"
rlIsRHEL '>6' && rlAssertRpm "hostname"
backup_files
rlRun "HOSTNAME_backup=$(hostname)"
rlRun "TmpDir=\$(mktemp -d)" 0 "Creating tmp directory"
rlRun "pushd $TmpDir"
rlFileBackup $HOSTNAMED
rlRun "sed -i 's|WatchdogSec.*||g' $HOSTNAMED" 0 "Remove watchdog from systemd-hostnamed.service"
rlRun "systemctl daemon-reload"
rlRun "systemctl mask --now systemd-hostnamed.service" 0 "Disable trigger for systemd-hostnamed.service and stop the service"
rlPhaseEnd
##################### TEST PHASE ####################
rlPhaseStartTest "hostname - basic GET/SET/FQDN - localhost - options alternatives- /etc/hosts"
# set FQDN in /etc/hosts
rlRun "hostname $TEST_hostname"
rlRun "etc-hosts_add '5.5.4.4' $TEST_FQDN $TEST_hostname" 0 "insert random 'ip fqdn alias' into /etc/hosts"
sleep $TIMEOUT
rlRun "systemctl status systemd-hostnamed" 0-255
# -s, --short
#_______________________________________________________________
rlRun '_s=$(hostname -s)' 0 "GET short name (-s)"
rlRun '_short=$(hostname --short)' 0 "GET short name (--short)"
rlAssertEquals "Check if hostname returned expected shortname" "$_s" "$TEST_hostname"
rlAssertEquals "compare output of '-s' and '--short'" "$_s" "$_short"
# -d, --domain
#_______________________________________________________________
rlRun '_d=$(hostname -d)' 0 "GET short name (-d)"
rlRun '_domain=$(hostname --domain)' 0 "GET short name (--domain)"
rlAssertEquals "Check if hostname returned expected domain" "$_d" "$TEST_domain"
rlAssertEquals "compare output of '-d' and '--domain'" "$_d" "$_domain"
# -f, --long, --fqdn
#_______________________________________________________________
rlRun '_f=$(hostname -f)' 0 "GET fqdn (-f)"
rlRun '_fqdn=$(hostname --fqdn)' 0 "GET fqdn (--fqdn)"
rlRun '_long=$(hostname --long)' 0 "GET fqdn (--long)"
rlAssertEquals "Check if hostname returned expected FQDN" "$_fqdn" "$TEST_FQDN"
rlAssertEquals "compare output of '--fqdn' and '--long'" "$_fqdn" "$_long"
rlAssertEquals "compare output of '--fqdn' and '-f'" "$_fqdn" "$_f"
rlRun "systemctl status systemd-hostnamed" 0-255
rlPhaseEnd
##################### TEST PHASE ####################
rlPhaseStartTest "hostname - advanced GET/SET"
rlRun "HFile=$(mktemp)"
rlRun "echo $TEST_hostname2 > $HFile"
> file_empty
# try to set hostname with unsupported characters
if rlIsRHEL '>6'; then #rhel-6 permits disallowed hostnames syntax
rlRun "hostname invalid+hostname" 1
rlRun "hostname invalid/host/name" 1
rlRun "hostname _invalidhostname" 1
rlRun "hostname ~invalidhostname" 1
fi
# -f, --file no-exists
#_______________________________________________________________
rlRun "_F=\$(hostname -F nonexist_file)" 1 "SET hostname from (non-existing) file (-F)"
rlRun "_file=\$(hostname --file nonexist_file)" 1 "SET hostname from (non-existing) file (--file)"
# -f, --file exists_empty
rlRun "_F=\$(hostname -F $HFile)" 0 "SET hostname from (existing/empty) file (-F)"
rlRun "_file=\$(hostname --file $HFile)" 0 "SET hostname from (existing/empty) file (--file)"
if rlIsRHEL '>6'; then
# --boot && --file no-exists
#_______________________________________________________________
rlRun '_F=$(hostname -F nonexist_file --boot)' 0 "SET hostname from (non-existing) file (-F, --boot)"
rlRun '_file=$(hostname --file nonexist_file -b)' 0 "SET hostname from (non-existing) file (--file)"
# --boot && --file exists_empty
rlRun "_F=\$(hostname -F $HFile --boot)" 0 "SET hostname from (existing/empty) file (-F, --boot)"
rlRun "_file=\$(hostname --file $HFile -b)" 0 "SET hostname from (existing/empty) file (--file)"
fi
rlPhaseEnd
##################### TEST PHASE ####################
rlPhaseStartTest "hostname - multiple IP addresses"
etc-hosts_reset
# -i, --ip-address
# -I, --all-ip-addresses
# whitebox: foreach getaddrinfo() => getnameinfo(NI_NUMERICHOST)
#_______________________________________________________________
# a) hostname has DNS record(s) - check all A|AAAA IP addresses
#rlRun "hostname example.com" 0 "set hostname to example.com - ugly workaround to test getaddrinfo being run internally"
if rlIsRHEL; then
if rpm -q --quiet bind-utils; then
if host $(hostname); then
hostname_backup
rlRun "hostname example.com"
sleep 10
# --ip-address
for addr in $(hostname -i); do
rlAssertGrep "$addr" <(dig $(hostname) any |sed -nre "s|^$(hostname)\\..*IN\\s+A+\\s+||gp")
rlAssertNotGrep "$addr" <(ip a sh up)
done
# --all-ip-addresses: example.com addresses shouldn't be returned
for addr in $(hostname -I); do
rlAssertNotGrep "$addr" <(dig $(hostname) any |sed -nre "s|^$(hostname)\\..*IN\\s+A+\\s+||gp")
rlAssertGrep "$addr" <(ip a sh up)
done
hostname_reset
fi
fi
fi
# b) Set hostname in /etc/hosts
hostname_backup
rlRun "hostname $TEST_hostname2" 0 "set random hostname - shouldn't have entry in DNS server/zone"
rlRun "etc-hosts_add 8.1.2.3 $TEST_hostname2"
rlRun "etc-hosts_add 8.1.2.4 $TEST_hostname2"
rlRun "etc-hosts_add 8.1.2.5 $TEST_hostname2"
rlRun "etc-hosts_add abcd:ef00::1 $TEST_hostname2"
rlRun "etc-hosts_add abcd:ef00::2 $TEST_hostname2"
sleep $TIMEOUT
rlRun "hostname -i | xargs -I % -d' ' grep % /etc/hosts" 0 'hostname --ip-address: IPs inserted into /etc/hosts should be recognized'
rlRun "hostname -I | xargs -I % -d' ' grep % /etc/hosts" 123 'hostname --all-ip-addresses: IPs inserted into /etc/hosts should NOT be recognized'
hostname_reset
etc-hosts_reset
# c) no DNS record for hostname, print IPs of some (up) interfaces
create_dummy_ifc $DUMMIES_NUM
hostname_backup
rlRun "hostname random-hostname"
sleep $TIMEOUT
if rlIsRHEL '<=6'; then
rlRun "hostname -i" 1
else
rlRun -l "hostname"
rlRun -l "hostname -i"
# --ip-address
rlLog "Check if IPs returned by 'hostname -i' are present in 'ip addr show up'"
for ip in $(hostname -i | tr ' ' '\n' | awk -F'%' '{print $1}'); do
rlLog "Checking IP '${ip}' returned by 'hostname -i'"
rlAssertGrep "${ip}" <(ip a sh up)
done
# TODO:
#failing part needs update:
# LOG: http://beaker-archive.host.prod.eng.bos.redhat.com/beaker-logs/2019/11/39117/3911716/7601680/102569594/taskout.log
# rlRun "[ \$(hostname -i | wc -w) -gt \$(hostname -I | wc -w) ]" 0 "hostname -i gives lesser number of IPs - it omits IPv6's link local IPs"
fi
# --all-ip-addresses
rlLog "Check if IPs returned by 'hostname -I' are present in 'ip addr show up'"
for ip in $(hostname -I | tr ' ' '\n' | awk -F'%' '{print $1}'); do
rlLog "Checking IP '${ip}' returned by \`hostname -I\`"
rlAssertGrep "${ip}" <(ip a sh up)
done
rlPhaseEnd
##################### TEST PHASE ####################
rlPhaseStartTest "hostname - advanced FQDN"
etc-hosts_reset
hostname_backup
# -A, --all-fqdns
# whitebox: foreach getaddrinfo() => getnameinfo(NI_NAMEREQD)
# tries to get FQDN from all system's IPs with getnameinfo() - ignore downed interfaces, loopback and link-local
#_______________________________________________________________
rlRun -l "hostname -I | tr ' ' '\\n'"
rlRun -l "hostname -A"
# each dummy interfaces shall return the same hostname
if rlIsRHEL '>6'; then #bug not fixed (yet) on rhel-6 net-tools version of hostname (length is INET6_ADDRSTRLEN, should be 255)
rlRun "hostname $TEST_hostname"
sleep $TIMEOUT
rlRun "[ \$(hostname -A | tr ' ' '\\n' | grep $TEST_hostname | wc -w) -ge $DUMMIES_NUM ]"
rlRun "[ \$(hostname --all-fqdns | tr ' ' '\\n' | grep $TEST_hostname | wc -w) -ge $DUMMIES_NUM ]"
fi
# hostname -A should be able to find PTR DNS records for our initial hostname
if rpm -q --quiet bind-utils; then
if host $HOSTNAME_backup; then
rlRun "hostname example.com"
sleep $TIMEOUT
# simply assume that our initial hostnames have always an IPv4 addr
for addr in $(dig $HOSTNAME_backup any |sed -nre "s|^$(hostname)\\..*IN\\s+A+\\s+||gp"); do
rlAssertNotGrep "$addr" <(hostname --all-fqdns)
rlAssertNotGrep "$addr" <(hostname -A)
done
fi
fi
hostname_reset
rlRun "rmmod dummy"
rlPhaseEnd
##################### TEST PHASE ####################
rlPhaseStartTest "Check other options"
# -V, --version
#_______________________________________________________________
rlIsRHEL '<=6' && ret=5 || ret=0
rlRun '_V="$(hostname -V 2>&1)"' $ret "GET version (-V)"
rlRun '_version="$(hostname --version 2>&1)"' $ret "GET version (--version)"
if rlIsRHEL '<=6'; then
rlAssertGrep "$(rpm -q --qf %{V} net-tools)" <(echo $_V | grep net-tools)
else
rlAssertGrep "$(rpm -q --qf %{V} hostname)" <(echo $_V)
fi
rlAssertEquals "compare output of '-V' and '--version'" "$_V" "$_version"
#-h, --help
#_______________________________________________________________
rlIsRHEL '<=6' && ret=4 || ret=255
rlRun "hostname -h" $ret "basic CLI help page (-h)"
rlRun "hostname --help" $ret "basic CLI help page (--help)"
rlPhaseEnd
##################### TEST PHASE ####################
rlPhaseStartTest "hostname - SET - length boundaries"
# lower limits
if rlIsRHEL '>6'; then # probably should be considered as bug in rhel-6 net-tools version of hostname
rlRun "hostname ''" 1 "hostname shoudln't accept string of size 0"
rlRun "[ \"$(hostname | wc -c)\" -gt 0 -a \"$(hostname | wc -c)\" -lt $(($(getconf HOST_NAME_MAX)+2)) ]"
fi
rlRun "set_hostname_by_length 1"
rlRun "hostname $test_hostname"
sleep $TIMEOUT
rlRun "[ \"$(hostname | wc -c)\" -gt 0 -a \"$(hostname | wc -c)\" -lt $(($(getconf HOST_NAME_MAX)+2)) ]"
# upper limits
rlRun "set_hostname_by_length 47" 0 "testing old buffer length (INET6_ADDRSTRLEN (46)) bug "
rlRun "hostname $test_hostname"
sleep $TIMEOUT
rlRun "[ \"\$(hostname)\" = \"$test_hostname\" ]"
rlRun "[ \"$(hostname | wc -c)\" -gt 0 -a \"$(hostname | wc -c)\" -lt $(($(getconf HOST_NAME_MAX)+2)) ]"
rlRun "set_hostname_by_length \$(getconf HOST_NAME_MAX)"
rlRun "hostname $test_hostname"
sleep $TIMEOUT
rlRun "[ \"\$(hostname)\" = \"$test_hostname\" ]"
rlRun "[ \"$(hostname | wc -c)\" -gt 0 -a \"$(hostname | wc -c)\" -lt $(($(getconf HOST_NAME_MAX)+2)) ]"
rlRun "set_hostname_by_length \$(( \$(getconf HOST_NAME_MAX)+1 ))"
rlRun "hostname $test_hostname" 1 "OS should prevent setting hostname bigger than default MAX length"
rlPhaseEnd
#TODO: NIS-related magic + options (-y, --yp, --nis)
##################### TEST PHASE ####################
#rlPhaseStartTest "Check other options"
#rlPhaseEnd
########## CLEANUP PHASE ##########
rlPhaseStartCleanup
rlRun "hostname $HOSTNAME_backup"
rlRun "systemctl unmask systemd-hostnamed"
rlFileRestore
rlRun "systemctl daemon-reload"
rlRun "popd"
rlRun "rm -r $TmpDir" 0 "Removing tmp directory"
rlPhaseEnd
rlJournalPrintText
rlJournalEnd