summaryrefslogtreecommitdiffstats
path: root/coverage.sh.in
diff options
context:
space:
mode:
Diffstat (limited to 'coverage.sh.in')
-rwxr-xr-xcoverage.sh.in653
1 files changed, 653 insertions, 0 deletions
diff --git a/coverage.sh.in b/coverage.sh.in
new file mode 100755
index 0000000..b75ae5c
--- /dev/null
+++ b/coverage.sh.in
@@ -0,0 +1,653 @@
+#!/usr/bin/env bash
+
+PRIMARY_GRP=$( id -ng )
+PRIMARY_USR=$( id -nu )
+PYTHON_PATH=.:./subprojects/libnvme
+AVAHI_PUBLISHER=mdns_publisher.service
+
+file=/tmp/stafd.conf.XXXXXX
+stafd_conf_fname=$(mktemp $file)
+
+file=/tmp/stacd.conf.XXXXXX
+stacd_conf_fname=$(mktemp $file)
+
+CYAN="[1;36m"
+RED="[1;31m"
+YELLOW="[1;33m"
+NORMAL="[0m"
+
+log() {
+ msg="$1"
+ printf "%b%s%s%b[0m\n" "\0033" ${CYAN} "${msg}" "\0033"
+ sudo logger -t COVERAGE -i "@@@@@ " -p warning -- "${msg}"
+}
+
+log_file_contents() {
+ rc=$1
+ file=$2
+
+ if [ $rc -eq 0 ]; then
+ color=${NORMAL}
+ level="info"
+ else
+ color=${YELLOW}
+ level="error"
+ fi
+
+ while IFS= read -r line; do
+ msg=" ${line}"
+ printf "%b%s%s%b[0m\n" "\0033" ${color} "${msg}" "\0033"
+ sudo logger -t COVERAGE -i "@@@@@ " -p ${level} -- "${msg}"
+ done < ${file}
+}
+
+systemctl-exists() {
+ unit="$1"
+ [ $(systemctl list-unit-files "${unit}" | wc -l) -gt 3 ]
+}
+
+sd_stop() {
+ app="$1"
+ unit="${app}"-cov.service
+ if systemctl-exists "${unit}" >/dev/null 2>&1; then
+ log "Stop ${app}"
+ sudo systemctl stop "${unit}" >/tmp/output.txt 2>&1
+ if [ -s /tmp/output.txt ]; then
+ log_file_contents $? /tmp/output.txt
+ else
+ printf " sudo systemctl stop %s\n" "${unit}"
+ fi
+ sudo systemctl reset-failed "${unit}" >/dev/null 2>&1
+ printf "\n"
+ sleep 1
+ fi
+}
+
+sd_start() {
+ app="$1"
+ dbus="$2"
+ conf="$3"
+ unit="${app}"-cov.service
+
+ if [ -z "${conf}" ]; then
+ cmd="${app} --syslog"
+ else
+ cmd="${app} --syslog -f ${conf}"
+ fi
+
+ RUNTIME_DIRECTORY=/tmp/${app}
+ rm -rf ${RUNTIME_DIRECTORY}
+ mkdir ${RUNTIME_DIRECTORY}
+
+ # Clear previous failure status (if any)
+ sudo systemctl reset-failed "${unit}" >/dev/null 2>&1
+
+ log "Start ${app}"
+ sudo systemd-run --unit="${unit}" --working-directory=. --property=Type=dbus --property=BusName="${dbus}" --property="SyslogIdentifier=${app}" --property="ExecReload=/bin/kill -HUP \$MAINPID" --setenv=PYTHONPATH=${PYTHON_PATH} --setenv=RUNTIME_DIRECTORY=${RUNTIME_DIRECTORY} coverage run --rcfile=.coveragerc ${cmd} >/tmp/output.txt 2>&1
+ log_file_contents $? /tmp/output.txt
+ printf "\n"
+ sleep 1
+}
+
+sd_restart() {
+ app="$1"
+ unit="${app}"-cov.service
+
+ if systemctl is-active "${unit}" >/dev/null 2>&1; then
+ log "Restart ${app}"
+ sudo systemctl restart "${unit}" && printf "systemctl restart %s\n" "${unit}" >/tmp/output.txt 2>&1
+ log_file_contents $? /tmp/output.txt
+ sleep 1
+ else
+ msg="Cannot restart ${app}, which is not currently running."
+ printf "%b%s%s%b[0m\n\n" "\0033" ${RED} "${msg}" "\0033"
+ fi
+ printf "\n"
+}
+
+reload_cfg() {
+ app="$1"
+ unit="${app}"-cov.service
+ log "Reload config ${app}"
+ sudo systemctl reload "${unit}" && printf "systemctl reload %s\n" "${unit}" >/tmp/output.txt 2>&1
+ #pid=$( systemctl show --property MainPID --value "${unit}" )
+ #sudo kill -HUP "${pid}" >/tmp/output.txt 2>&1
+ log_file_contents $? /tmp/output.txt
+ printf "\n"
+ sleep 1
+}
+
+run_unit_test() {
+ input=$@
+ if [ "$1" == "sudo" ]; then
+ shift
+ COVERAGE="sudo coverage"
+ else
+ COVERAGE="coverage"
+ fi
+ test=$@
+ log "Run unit test: ${input}"
+ PYTHONPATH=${PYTHON_PATH} ${COVERAGE} run --rcfile=.coveragerc ../test/${test} >/dev/null 2>&1
+}
+
+run_cmd_coverage() {
+ input=$@
+ if [ "$1" == "sudo" ]; then
+ shift
+ COVERAGE="sudo coverage"
+ else
+ COVERAGE="coverage"
+ fi
+ cmd="$@"
+ log "Invoke: ${input}"
+ ${COVERAGE} run --rcfile=.coveragerc ${cmd} >/tmp/output.txt 2>&1
+ log_file_contents $? /tmp/output.txt
+ printf "\n"
+}
+
+run_cmd() {
+ cmd="$@"
+ ${cmd} >/tmp/output.txt 2>&1
+ if [ -s /tmp/output.txt ]; then
+ log_file_contents $? /tmp/output.txt
+ else
+ printf " %s\n" "${cmd}"
+ fi
+}
+
+prerun_setup() {
+ if [ ! -d coverage ]; then
+ mkdir coverage
+ fi
+
+ for file in staf stac; do
+ if [ ! -f "/usr/share/dbus-1/system.d/org.nvmexpress.${file}.conf" -a \
+ ! -f "/etc/dbus-1/system.d/org.nvmexpress.${file}.conf" ]; then
+ log "hardlink /etc/dbus-1/system.d/org.nvmexpress.${file}.conf -> @BUILD_DIR@/etc/dbus-1/system.d/org.nvmexpress.${file}.conf"
+ sudo ln @BUILD_DIR@/etc/dbus-1/system.d/org.nvmexpress.${file}.conf /etc/dbus-1/system.d/org.nvmexpress.${file}.conf
+ if [ $? -ne 0 ]; then
+ log "hardlink failed"
+ exit 1
+ fi
+ fi
+ done
+ sudo systemctl reload dbus.service
+}
+
+postrun_cleanup() {
+ sd_stop "stafd"
+ sd_stop "stacd"
+
+ log "Stop nvmet"
+ sudo ../utils/nvmet/nvmet.py clean >/tmp/output.txt 2>&1
+ log_file_contents $? /tmp/output.txt
+ printf "\n"
+
+ log "nvme disconnect-all"
+ run_cmd sudo nvme disconnect-all
+ printf "\n"
+
+ log "Remove ${stafd_conf_fname} and ${stacd_conf_fname}"
+ rm "${stafd_conf_fname}"
+ rm "${stacd_conf_fname}"
+ printf "\n"
+
+ for file in staf stac; do
+ if [ -f "/etc/dbus-1/system.d/org.nvmexpress.${file}.conf" ]; then
+ if [ "$(stat -c %h -- "/etc/dbus-1/system.d/org.nvmexpress.${file}.conf")" -gt 1 ]; then
+ log "Remove hardlink /etc/dbus-1/system.d/org.nvmexpress.${file}.conf"
+ sudo rm "/etc/dbus-1/system.d/org.nvmexpress.${file}.conf"
+ fi
+ fi
+ done
+ sudo systemctl reload dbus.service
+
+ sudo systemctl unmask avahi-daemon.service
+ sudo systemctl unmask avahi-daemon.socket
+ sudo systemctl start avahi-daemon.service
+ sudo systemctl start avahi-daemon.socket
+
+ sudo systemctl stop ${AVAHI_PUBLISHER} >/dev/null 2>&1
+ sudo systemctl reset-failed ${AVAHI_PUBLISHER} >/dev/null 2>&1
+
+ log "All done!!!"
+ log "FINISHED-FINISHED-FINISHED-FINISHED-FINISHED-FINISHED-FINISHED-FINISHED"
+}
+
+trap postrun_cleanup EXIT
+trap postrun_cleanup SIGINT
+
+################################################################################
+################################################################################
+################################################################################
+
+log "START-START-START-START-START-START-START-START-START-START-START-START"
+
+if systemctl is-active stafd.service >/dev/null 2>&1 || systemctl is-active stacd.service >/dev/null 2>&1; then
+ msg="Stopping because stafd and/or stacd is/are currently running."
+ printf "%b%s%s%b[0m\n" "\0033" ${RED} "${msg}" "\0033"
+ exit 1
+fi
+
+prerun_setup
+
+#*******************************************************************************
+# Load nvme kernel module
+log "modprobe nvme_tcp"
+run_cmd sudo /usr/sbin/modprobe nvme_tcp
+
+log "nvme disconnect-all"
+run_cmd sudo nvme disconnect-all
+printf "\n"
+
+sd_stop stafd # make sure it's not running already
+sd_stop stacd # make sure it's not running already
+
+#*******************************************************************************
+# Create a dummy config file for stafd
+log "Create dummy config file ${stafd_conf_fname}"
+cat > "${stafd_conf_fname}" <<'EOF'
+[Global]
+tron = true
+ip-family = ipv6
+johnny = be-good
+queue-size = 2000000
+reconnect-delay = NaN
+ctrl-loss-tmo = 10
+disable-sqflow = true
+
+[Discovery controller connection management]
+persistent-connections = false
+zeroconf-connections-persistence = -1
+
+[Hello]
+hello = bye
+EOF
+log_file_contents 0 "${stafd_conf_fname}"
+printf "\n"
+
+#*******************************************************************************
+# Create a dummy config file for stacd
+log "Create dummy config file ${stacd_conf_fname}"
+cat > "${stacd_conf_fname}" <<'EOF'
+[Global]
+tron = true
+kato = 10
+nr-io-queues = 4
+nr-write-queues = NaN
+nr-poll-queues = NaN
+queue-size = 2000000
+reconnect-delay = 1
+ctrl-loss-tmo = 1
+disable-sqflow = true
+
+[I/O controller connection management]
+disconnect-scope = blah-blah
+disconnect-trtypes = boing-boing
+EOF
+log_file_contents 0 "${stacd_conf_fname}"
+printf "\n"
+
+log "Stop & Mask Avahi daemon"
+run_cmd sudo systemctl stop avahi-daemon.service
+run_cmd sudo systemctl stop avahi-daemon.socket
+run_cmd sudo systemctl mask avahi-daemon.service
+run_cmd sudo systemctl mask avahi-daemon.socket
+printf "\n"
+sleep 1
+
+log ">>>>>>>>>>>>>>>>>>>>> Marker [1] <<<<<<<<<<<<<<<<<<<<<"
+printf "\n"
+
+run_cmd_coverage stafctl ls
+run_cmd_coverage stafctl invalid-command
+run_cmd_coverage stacctl ls
+run_cmd_coverage stacctl invalid-command
+
+#*******************************************************************************
+# Start nvme target simulator
+log "Start nvmet"
+sudo ../utils/nvmet/nvmet.py clean >/dev/null 2>&1
+sudo ../utils/nvmet/nvmet.py create -f ../utils/nvmet/nvmet.conf >/tmp/output.txt 2>&1
+log_file_contents $? /tmp/output.txt
+printf "\n"
+
+sleep 2
+
+log ">>>>>>>>>>>>>>>>>>>>> Marker [2] <<<<<<<<<<<<<<<<<<<<<"
+printf "\n"
+
+#*******************************************************************************
+# Start stafd and stacd
+sd_start "stafd" "@STAFD_DBUS_NAME@" "${stafd_conf_fname}"
+sd_start "stacd" "@STACD_DBUS_NAME@" "${stacd_conf_fname}"
+sleep 2
+
+run_cmd_coverage stafctl status
+
+reload_cfg "stafd"
+sleep 1
+
+log "Restart Avahi daemon"
+run_cmd sudo systemctl unmask avahi-daemon.socket
+run_cmd sudo systemctl unmask avahi-daemon.service
+run_cmd sudo systemctl start avahi-daemon.socket
+run_cmd sudo systemctl start avahi-daemon.service
+printf "\n"
+sleep 2
+
+log ">>>>>>>>>>>>>>>>>>>>> Marker [3] <<<<<<<<<<<<<<<<<<<<<"
+printf "\n"
+
+log "Change stafd config [1]:"
+cat > "${stafd_conf_fname}" <<'EOF'
+[Global]
+tron = true
+
+[Discovery controller connection management]
+persistent-connections = false
+zeroconf-connections-persistence = 0.5
+
+[Service Discovery]
+zeroconf = enabled
+EOF
+log_file_contents 0 "${stafd_conf_fname}"
+printf "\n"
+
+reload_cfg "stafd"
+sleep 1
+
+log "Change stafd config [2]:"
+cat > "${stafd_conf_fname}" <<'EOF'
+[Global]
+tron = true
+ip-family = ipv4
+queue-size = 2000000
+reconnect-delay = 1
+ctrl-loss-tmo = 1
+disable-sqflow = true
+pleo = disable
+
+[Discovery controller connection management]
+persistent-connections = false
+zeroconf-connections-persistence = 1:01
+
+[Controllers]
+controller = transport = tcp ; traddr = localhost ; ; ; kato=31; dhchap-ctrl-secret=not-so-secret
+controller=transport=tcp;traddr=1.1.1.1
+controller=transport=tcp;traddr=100.100.100.100
+controller=transport=tcp;traddr=2607:f8b0:4002:c2c::71
+
+exclude=transport=tcp;traddr=1.1.1.1
+EOF
+log_file_contents 0 "${stafd_conf_fname}"
+printf "\n"
+
+reload_cfg "stafd"
+sleep 5
+
+
+log "Change stacd config [1]:"
+cat > "${stacd_conf_fname}" <<'EOF'
+[Global]
+tron=true
+nr-io-queues=4
+nr-write-queues=4
+queue-size=2000000
+reconnect-delay=1
+ctrl-loss-tmo=1
+disable-sqflow=true
+
+[I/O controller connection management]
+disconnect-scope=all-connections-matching-disconnect-trtypes
+disconnect-trtypes=tcp+rdma
+EOF
+log_file_contents 0 "${stacd_conf_fname}"
+printf "\n"
+
+reload_cfg "stacd"
+sleep 5
+
+log ">>>>>>>>>>>>>>>>>>>>> Marker [4] <<<<<<<<<<<<<<<<<<<<<"
+printf "\n"
+
+run_cmd_coverage stafctl status
+
+#*******************************************************************************
+# Fake mDNS packets from a CDC
+log "Start Avahi publisher"
+run_cmd sudo systemctl stop ${AVAHI_PUBLISHER}
+run_cmd sudo systemctl reset-failed ${AVAHI_PUBLISHER}
+run_cmd sudo systemd-run --unit=${AVAHI_PUBLISHER} --working-directory=. avahi-publish -s SFSS _nvme-disc._tcp 8009 "p=tcp"
+printf "\n"
+sleep 1
+
+#*******************************************************************************
+run_cmd_coverage stafd --version
+run_cmd_coverage stacd --version
+
+#*******************************************************************************
+# Stimulate D-Bus activity
+run_cmd_coverage sudo stafctl --version
+run_cmd_coverage sudo stafctl blah
+run_cmd_coverage sudo stafctl troff
+run_cmd_coverage stafctl status
+run_cmd_coverage sudo stafctl tron
+run_cmd_coverage stafctl ls -d
+run_cmd_coverage stafctl adlp -d
+run_cmd_coverage stafctl dlp -t tcp -a ::1 -s 8009
+
+run_cmd_coverage sudo stacctl --version
+run_cmd_coverage sudo stacctl blah
+run_cmd_coverage sudo stacctl troff
+run_cmd_coverage stacctl status
+run_cmd_coverage sudo stacctl tron
+run_cmd_coverage stacctl ls -d
+
+log ">>>>>>>>>>>>>>>>>>>>> Marker [5] <<<<<<<<<<<<<<<<<<<<<"
+printf "\n"
+
+#*******************************************************************************
+# Stimulate AENs activity by removing/restoring namespaces
+log "Remove namespace: klingons"
+run_cmd sudo ../utils/nvmet/nvmet.py unlink -p 1 -s klingons
+printf "\n"
+sleep 2
+run_cmd_coverage stacctl ls
+
+log "Restore namespace: klingons"
+run_cmd sudo ../utils/nvmet/nvmet.py link -p 1 -s klingons
+printf "\n"
+sleep 2
+run_cmd_coverage stacctl ls
+
+log ">>>>>>>>>>>>>>>>>>>>> Marker [6] <<<<<<<<<<<<<<<<<<<<<"
+printf "\n"
+
+#*******************************************************************************
+# Stop Avahi Publisher
+log "Stop Avahi publisher"
+run_cmd sudo systemctl stop ${AVAHI_PUBLISHER}
+printf "\n"
+sleep 1
+
+#*******************************************************************************
+log "Restart Avahi publisher"
+run_cmd sudo systemd-run --unit=${AVAHI_PUBLISHER} --working-directory=. avahi-publish -s SFSS _nvme-disc._tcp 8009 "p=tcp"
+printf "\n"
+sleep 2
+
+log ">>>>>>>>>>>>>>>>>>>>> Marker [7] <<<<<<<<<<<<<<<<<<<<<"
+printf "\n"
+
+#*******************************************************************************
+# Make config changes for stafd
+log "Change stafd config [3]:"
+cat > "${stafd_conf_fname}" <<'EOF'
+[Global]
+tron = true
+queue-size = 2000000
+reconnect-delay = 1
+ctrl-loss-tmo = 1
+disable-sqflow = true
+
+[Discovery controller connection management]
+persistent-connections=false
+zeroconf-connections-persistence=0.5
+
+[Service Discovery]
+zeroconf=disabled
+EOF
+log_file_contents 0 "${stafd_conf_fname}"
+printf "\n"
+
+reload_cfg "stafd"
+sleep 3
+
+#*******************************************************************************
+# Make more config changes for stafd
+log "Change stafd config [4]:"
+cat > "${stafd_conf_fname}" <<'EOF'
+[Global]
+tron=true
+queue-size=2000000
+reconnect-delay=1
+ctrl-loss-tmo=0
+disable-sqflow=true
+ip-family=ipv6
+
+[Discovery controller connection management]
+persistent-connections=false
+zeroconf-connections-persistence=0
+
+[Controllers]
+controller=transport=tcp;traddr=localhost;trsvcid=8009
+controller=transport=tcp;traddr=abracadabra
+controller=transport=tcp;traddr=google.com
+controller=
+controller=trsvcid
+controller=transport=rdma;traddr=!@#$
+controller=transport=fc;traddr=21:00:00:00:00:00:00:00;host-traddr=20:00:00:00:00:00:00:00
+controller=transport=XM;traddr=2.2.2.2
+controller=transport=tcp;traddr=555.555.555.555
+EOF
+log_file_contents 0 "${stafd_conf_fname}"
+printf "\n"
+
+log ">>>>>>>>>>>>>>>>>>>>> Marker [8] <<<<<<<<<<<<<<<<<<<<<"
+printf "\n"
+
+reload_cfg "stafd"
+sleep 2
+
+#*******************************************************************************
+# Stop Avahi Publisher
+log "Stop Avahi publisher"
+run_cmd sudo systemctl stop ${AVAHI_PUBLISHER}
+printf "\n"
+sleep 2
+
+log ">>>>>>>>>>>>>>>>>>>>> Marker [9] <<<<<<<<<<<<<<<<<<<<<"
+printf "\n"
+
+#*******************************************************************************
+# Remove one of the NVMe device's
+file=/tmp/getdev-XXX.py
+getdev=$(mktemp $file)
+cat > "${getdev}" <<'EOF'
+import sys
+from dasbus.connection import SystemMessageBus
+
+bus = SystemMessageBus()
+iface = bus.get_proxy(sys.argv[1], sys.argv[2])
+controllers = iface.list_controllers(False)
+if len(controllers) > 0:
+ controller = controllers[0]
+ print(controller['device'])
+ sys.exit(0)
+sys.exit(1)
+EOF
+
+# Find a Discovery Controller and issue a "nvme disconnect"
+if dev=$(python3 ${getdev} @STAFD_DBUS_NAME@ @STAFD_DBUS_PATH@); then
+ log "Remove connection (disconnect) to Discovery Controller ${dev}"
+ run_cmd sudo nvme disconnect -d ${dev}
+ printf "\n"
+else
+ msg="Failed to find a connection to a Discovery Controller"
+ printf "%b%s%s%b[0m\n" "\0033" ${RED} "${msg}" "\0033"
+ sudo logger -t COVERAGE -i "@@@@@ " -p warning -- "${msg}"
+fi
+
+# Find an I/O Controller and issue a "nvme disconnect"
+if dev=$(python3 ${getdev} @STACD_DBUS_NAME@ @STACD_DBUS_PATH@); then
+ log "Remove connection (disconnect) to I/O Controller ${dev}"
+ run_cmd sudo nvme disconnect -d ${dev}
+ printf "\n"
+else
+ msg="Failed to find a connection to an I/O Controller"
+ printf "%b%s%s%b[0m\n" "\0033" ${RED} "${msg}" "\0033"
+ sudo logger -t COVERAGE -i "@@@@@ " -p warning -- "${msg}"
+fi
+
+sleep 3
+
+rm "${getdev}"
+
+
+#*******************************************************************************
+log ">>>>>>>>>>>>>>>>>>>>> Marker [10] <<<<<<<<<<<<<<<<<<<<<"
+printf "\n"
+
+sd_restart "stafd"
+sd_restart "stacd"
+sleep 4
+
+log "Create invalid conditions for saving/loading stafd's last known config"
+rm -rf "/tmp/stafd"
+sd_restart "stafd"
+sleep 2
+
+log "Remove invalid conditions for saving/loading stafd's last known config"
+mkdir -p "/tmp/stafd"
+sd_restart "stafd"
+sleep 2
+
+#*******************************************************************************
+# Change ownership of files that were created as root
+sudo chown -R "${PRIMARY_USR}":"${PRIMARY_GRP}" coverage >/dev/null 2>&1
+sudo chown -R "${PRIMARY_USR}":"${PRIMARY_GRP}" staslib/__pycache__ >/dev/null 2>&1
+sudo chown -R "${PRIMARY_USR}":"${PRIMARY_GRP}" subprojects/libnvme/libnvme/__pycache__ >/dev/null 2>&1
+
+#*******************************************************************************
+# Run unit tests
+run_unit_test test-avahi.py
+run_unit_test test-avahi.py
+run_unit_test test-config.py
+run_unit_test test-controller.py
+run_unit_test test-gtimer.py
+run_unit_test test-iputil.py
+run_unit_test test-log.py
+run_unit_test sudo test-nvme_options.py # Test both with super user...
+run_unit_test test-nvme_options.py # ... and with regular user
+run_unit_test test-service.py
+run_unit_test test-timeparse.py
+run_unit_test test-transport_id.py
+run_unit_test test-udev.py
+run_unit_test test-version.py
+
+#*******************************************************************************
+# Stop nvme target simulator
+
+log "Collect all coverage data"
+coverage combine --rcfile=.coveragerc
+printf "\n"
+
+log "Generating coverage report"
+coverage report -i --rcfile=.coveragerc
+printf "\n"
+
+log "Generating coverage report (HTML)"
+coverage html -i --rcfile=.coveragerc
+printf "\n"
+