#!/usr/bin/env bash

# COVERAGE CURRENTLY ACHIEVED BY THIS SCRIPT:
# THIS WAS RUN ON FEDORA 35

# Results on Fedora 35 (5/3/2022) nvme-stas v1.1
#Name                  Stmts   Miss  Cover
#-----------------------------------------
#stacctl                  55      3    95%
#stacd                   160      6    96%
#stafctl                  77      3    96%
#stafd                   241     39    84%
#staslib/avahi.py        185     28    85%
#staslib/defs.py          21      0   100%
#staslib/glibudev.py      32      3    91%
#staslib/stas.py         791     76    90%
#staslib/version.py       34      0   100%
#-----------------------------------------
#TOTAL                  1596    158    90%

# Results on SLES 15 SP4 (6/10/2022) nvme-stas v1.1.3
# nvme-stas connected to real CDC.
#Name                 Stmts   Miss  Cover
#----------------------------------------
#stacctl                 55      3    95%
#stacd                  192      6    97%
#stafctl                 77      3    96%
#stafd                  246     25    90%
#staslib/avahi.py       186     23    88%
#staslib/defs.py         22      0   100%
#staslib/stas.py        864     64    93%
#staslib/version.py      32      0   100%
#----------------------------------------
#TOTAL                 1674    124    93%


PRIMARY_GRP=$( id -ng )
PRIMARY_USR=$( id -nu )
PYTHON_PATH=.:./subprojects/libnvme

sd_stop() {
    unit="$1"-cov.service
    sudo systemctl stop "${unit}" >/dev/null 2>&1
    sudo systemctl reset-failed "${unit}" >/dev/null 2>&1
}

sd_restart() {
    unit="$1"-cov.service
    sudo systemctl restart "${unit}" >/dev/null 2>&1
}

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

    printf "\n%b[1;36m%s%b[0m\n" "\0033" "Start ${app}" "\0033"

    RUNTIME_DIRECTORY=/tmp/${app}
    rm -rf ${RUNTIME_DIRECTORY}
    mkdir ${RUNTIME_DIRECTORY}

    sd_stop "${app}" # make sure it's not running already
    sudo systemd-run --unit="${unit}" --working-directory=. --property=Type=dbus --property=BusName="${dbus}" --setenv=PYTHONPATH=${PYTHON_PATH} --setenv=RUNTIME_DIRECTORY=${RUNTIME_DIRECTORY} coverage run --rcfile=.coveragerc ${cmd}
}

reload_cfg() {
    app="$1"
    unit="${app}"-cov.service
    pid=$( systemctl show --property MainPID --value "${unit}" )
    printf "%b[1;36m%s%b[0m\n" "\0033" "Reload config ${app}" "\0033"
    sudo kill -HUP "${pid}"
}

if [ ! -d coverage ]; then
    mkdir coverage
fi

################################################################################
# Load nvme kernel module
sudo /usr/sbin/modprobe nvme-tcp

sudo nvme disconnect-all

################################################################################
# Create a dummy config file for @STAFD_PROCNAME@
stafd_conf_fname=$(mktemp /tmp/@STAFD_PROCNAME@.conf.XXXXXX)
cat > "${stafd_conf_fname}" <<'EOF'
[Global]
tron=true
kato=10
persistent-connections=false
ip-family=ipv6
EOF

################################################################################
# Create a dummy config file for @STACD_PROCNAME@
stacd_conf_fname=$(mktemp /tmp/@STACD_PROCNAME@.conf.XXXXXX)
cat > "${stacd_conf_fname}" <<'EOF'
[Global]
tron=true
kato=10
udev-rule=disabled
sticky-connections=enabled
EOF

sudo systemctl stop avahi-daemon.service
sudo systemctl stop avahi-daemon.socket
sudo systemctl mask avahi-daemon.service
sudo systemctl mask avahi-daemon.socket
sleep 1


printf "%b[1;36m%s%b[0m\n" "\0033" "Invoking @STAFD_CTLNAME@ status while @STAFD_PROCNAME@ is not running" "\0033"
coverage run --rcfile=.coveragerc @STAFD_CTLNAME@ ls >/dev/null 2>&1
coverage run --rcfile=.coveragerc @STAFD_CTLNAME@ invalid-command >/dev/null 2>&1

printf "%b[1;36m%s%b[0m\n" "\0033" "Invoking @STACD_CTLNAME@ status while @STACD_PROCNAME@ is not running" "\0033"
coverage run --rcfile=.coveragerc @STACD_CTLNAME@ ls >/dev/null 2>&1
coverage run --rcfile=.coveragerc @STACD_CTLNAME@ invalid-command >/dev/null 2>&1

################################################################################
# Start @STAFD_PROCNAME@ and @STACD_PROCNAME@
sd_start "@STAFD_PROCNAME@" "@STAFD_DBUS_NAME@" "${stafd_conf_fname}"
sd_start "@STACD_PROCNAME@" "@STACD_DBUS_NAME@" "${stacd_conf_fname}"
sleep 3

printf "%b[1;36m%s%b[0m\n" "\0033" "Invoking @STAFD_CTLNAME@ status" "\0033"
coverage run --rcfile=.coveragerc @STAFD_CTLNAME@ status  >/dev/null 2>&1

reload_cfg "@STAFD_PROCNAME@"
sleep 1

sudo systemctl unmask avahi-daemon.socket
sudo systemctl unmask avahi-daemon.service
sudo systemctl start avahi-daemon.socket
sudo systemctl start avahi-daemon.service
sleep 2

cat > "${stafd_conf_fname}" <<'EOF'
[Global]
tron=true
persistent-connections=false

[Service Discovery]
zeroconf=disabled
EOF
reload_cfg "@STAFD_PROCNAME@"

sleep 1

cat > "${stafd_conf_fname}" <<'EOF'
[Global]
tron=true
persistent-connections=false
ip-family=ipv4
kato=10

[Controllers]
controller=transport=tcp;traddr=localhost
controller=transport=tcp;traddr=1.1.1.1
controller=transport=tcp;traddr=2.2.2.2
controller=transport=tcp;traddr=555.555.555.555
controller=transport=tcp;traddr=abracadabra
controller=
controller=trsvcid
controller=transport=rdma;traddr=!@#$
blacklist=transport=tcp;traddr=1.1.1.1
blacklist=transport=tcp;traddr=1000.1000.1000.1000
EOF
reload_cfg "@STAFD_PROCNAME@"

cat > "${stacd_conf_fname}" <<'EOF'
[Global]
tron=true
udev-rule=disabled
sticky-connections=disabled
EOF
reload_cfg "@STACD_PROCNAME@"
sleep 3

printf "%b[1;36m%s%b[0m\n" "\0033" "Invoking @STAFD_CTLNAME@ status" "\0033"
coverage run --rcfile=.coveragerc @STAFD_CTLNAME@ status  >/dev/null 2>&1

################################################################################
# Fake mDNS packets from a CDC
printf "\n%b[1;36m%s%b[0m\n" "\0033" "Start Avahi publisher" "\0033"
AVAHI_PUBLISHER=mdns_publisher.service
sudo systemctl stop ${AVAHI_PUBLISHER} >/dev/null 2>&1
sudo systemctl reset-failed ${AVAHI_PUBLISHER} >/dev/null 2>&1
sudo systemd-run --unit=${AVAHI_PUBLISHER} --working-directory=. avahi-publish -s SFSS _nvme-disc._tcp 8009 "p=tcp"
sleep 1

################################################################################
# Start nvme target simulator
printf "\n%b[1;36m%s%b[0m\n" "\0033" "Start nvmet" "\0033"
sudo ../utils/nvmet/nvmet.py clean
sudo ../utils/nvmet/nvmet.py create -f ../utils/nvmet/nvmet.conf
sleep 2

reload_cfg "@STAFD_PROCNAME@"
reload_cfg "@STACD_PROCNAME@"
sleep 3

################################################################################
printf "\n%b[1;36m%s%b[0m\n" "\0033" "Invoking @STAFD_PROCNAME@ --version" "\0033"
coverage run --rcfile=.coveragerc @STAFD_PROCNAME@ --version
printf "%b[1;36m%s%b[0m\n" "\0033" "Invoking @STAFD_PROCNAME@ --idl" "\0033"
coverage run --rcfile=.coveragerc @STAFD_PROCNAME@ --idl /tmp/@STAFD_PROCNAME@.idl

printf "\n%b[1;36m%s%b[0m\n" "\0033" "Invoking @STACD_PROCNAME@ --version" "\0033"
coverage run --rcfile=.coveragerc @STACD_PROCNAME@ --version
printf "%b[1;36m%s%b[0m\n" "\0033" "Invoking @STACD_PROCNAME@ --idl" "\0033"
coverage run --rcfile=.coveragerc @STACD_PROCNAME@ --idl /tmp/@STACD_PROCNAME@.idl

################################################################################
# Stimulate D-Bus activity
printf "\n%b[1;36m%s%b[0m\n" "\0033" "Invoking @STAFD_CTLNAME@ --version" "\0033"
sudo coverage run --rcfile=.coveragerc @STAFD_CTLNAME@ --version
printf "%b[1;36m%s%b[0m\n" "\0033" "Invoking @STAFD_CTLNAME@ with a bad command" "\0033"
sudo coverage run --rcfile=.coveragerc @STAFD_CTLNAME@ blah
printf "%b[1;36m%s%b[0m\n" "\0033" "Invoking @STAFD_CTLNAME@ troff" "\0033"
sudo coverage run --rcfile=.coveragerc @STAFD_CTLNAME@ troff
printf "%b[1;36m%s%b[0m\n" "\0033" "Invoking @STAFD_CTLNAME@ status" "\0033"
coverage run --rcfile=.coveragerc @STAFD_CTLNAME@ status  >/dev/null 2>&1
printf "%b[1;36m%s%b[0m\n" "\0033" "Invoking @STAFD_CTLNAME@ tron" "\0033"
sudo coverage run --rcfile=.coveragerc @STAFD_CTLNAME@ tron
printf "%b[1;36m%s%b[0m\n" "\0033" "Invoking @STAFD_CTLNAME@ ls" "\0033"
coverage run --rcfile=.coveragerc @STAFD_CTLNAME@ ls -d   >/dev/null 2>&1
printf "%b[1;36m%s%b[0m\n" "\0033" "Invoking @STAFD_CTLNAME@ adlp" "\0033"
coverage run --rcfile=.coveragerc @STAFD_CTLNAME@ adlp -d >/dev/null 2>&1
printf "%b[1;36m%s%b[0m\n" "\0033" "Invoking @STAFD_CTLNAME@ dlp" "\0033"
coverage run --rcfile=.coveragerc @STAFD_CTLNAME@ dlp -t tcp -a ::1 -s 8009 >/dev/null 2>&1

printf "\n%b[1;36m%s%b[0m\n" "\0033" "Invoking @STACD_CTLNAME@ --version" "\0033"
sudo coverage run --rcfile=.coveragerc @STACD_CTLNAME@ --version
printf "%b[1;36m%s%b[0m\n" "\0033" "Invoking @STACD_CTLNAME@ with a bad command" "\0033"
sudo coverage run --rcfile=.coveragerc @STACD_CTLNAME@ blah
printf "%b[1;36m%s%b[0m\n" "\0033" "Invoking @STACD_CTLNAME@ troff" "\0033"
sudo coverage run --rcfile=.coveragerc @STACD_CTLNAME@ troff
printf "%b[1;36m%s%b[0m\n" "\0033" "Invoking @STACD_CTLNAME@ status" "\0033"
coverage run --rcfile=.coveragerc @STACD_CTLNAME@ status >/dev/null 2>&1
printf "%b[1;36m%s%b[0m\n" "\0033" "Invoking @STACD_CTLNAME@ tron" "\0033"
sudo coverage run --rcfile=.coveragerc @STACD_CTLNAME@ tron
printf "%b[1;36m%s%b[0m\n" "\0033" "Invoking @STACD_CTLNAME@ ls" "\0033"
coverage run --rcfile=.coveragerc @STACD_CTLNAME@ ls -d >/dev/null 2>&1

################################################################################
# Stimulate AENs activity by removing/restoring namespaces
printf "\n%b[1;36m%s%b[0m\n" "\0033" "Remove namespace: klingons" "\0033"
sudo ../utils/nvmet/nvmet.py unlink -p 1 -s klingons
sleep 2
printf "\n%b[1;36m%s%b[0m\n" "\0033" "Invoking @STACD_CTLNAME@ ls" "\0033"
coverage run --rcfile=.coveragerc @STACD_CTLNAME@ ls -d >/dev/null 2>&1

printf "\n%b[1;36m%s%b[0m\n" "\0033" "Restore namespace: klingons" "\0033"
sudo ../utils/nvmet/nvmet.py link -p 1 -s klingons
sleep 2
printf "\n%b[1;36m%s%b[0m\n" "\0033" "Invoking @STACD_CTLNAME@ ls" "\0033"
coverage run --rcfile=.coveragerc @STACD_CTLNAME@ ls -d >/dev/null 2>&1

################################################################################
# Stop Avahi Publisher
printf "\n%b[1;36m%s%b[0m\n" "\0033" "Stop Avahi publisher" "\0033"
sudo systemctl stop ${AVAHI_PUBLISHER}
sleep 1

################################################################################
printf "\n%b[1;36m%s%b[0m\n" "\0033" "Restart Avahi publisher" "\0033"
sudo systemd-run --unit=${AVAHI_PUBLISHER} --working-directory=. avahi-publish -s SFSS _nvme-disc._tcp 8009 "p=tcp"
sleep 2

################################################################################
# Make config changes for @STAFD_PROCNAME@
printf "\n%b[1;36m%s%b[0m\n" "\0033" "Empty configuration and disable zeroconf for @STAFD_PROCNAME@" "\0033"
cat > "${stafd_conf_fname}" <<'EOF'
[Global]
tron=true
persistent-connections=false

[Service Discovery]
zeroconf=disabled
EOF
reload_cfg "@STAFD_PROCNAME@"
sleep 1

################################################################################
# Make more config changes for @STAFD_PROCNAME@
printf "\n%b[1;36m%s%b[0m\n" "\0033" "Add single controller (::1) and re-enable zeroconf for @STAFD_PROCNAME@" "\0033"
cat > "${stafd_conf_fname}" <<'EOF'
[Global]
tron=true
persistent-connections=false

[Controllers]
controller=transport=tcp;traddr=::1;trsvcid=8009
EOF
reload_cfg "@STAFD_PROCNAME@"
sleep 2

################################################################################
# Stop Avahi Publisher
printf "\n%b[1;36m%s%b[0m\n" "\0033" "Stop Avahi publisher" "\0033"
sudo systemctl stop ${AVAHI_PUBLISHER}
sleep 2

################################################################################
# Remove one of the NVMe device's
printf "\n%b[1;36m%s%b[0m\n" "\0033" "Remove (disconnect) nvme1" "\0033"
sudo nvme disconnect -d nvme1
sleep 2


################################################################################
printf "%b[1;36m%s%b[0m\n" "\0033" "Restart @STAFD_PROCNAME@ and @STACD_PROCNAME@" "\0033"
sd_restart "@STAFD_PROCNAME@"
sd_restart "@STACD_PROCNAME@"
sleep 1

printf "%b[1;36m%s%b[0m\n" "\0033" "Create invalid conditions for saving/loading @STAFD_PROCNAME@'s last known config" "\0033"
rm -rf "/tmp/@STAFD_PROCNAME@"
sd_stop "@STAFD_PROCNAME@"
sd_restart "@STACD_PROCNAME@"
mkdir -p "/tmp/@STAFD_PROCNAME@"
sd_start "@STAFD_PROCNAME@" "@STAFD_DBUS_NAME@" "${stafd_conf_fname}"
sleep 2

################################################################################
# Stop everything and collect coverage stats
printf "\n%b[1;36m%s%b[0m\n" "\0033" "Stop @STAFD_PROCNAME@ and @STACD_PROCNAME@" "\0033"
sd_stop "@STAFD_PROCNAME@"
sd_stop "@STACD_PROCNAME@"
sleep 1

################################################################################
# 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

sudo nvme disconnect-all

rm "${stafd_conf_fname}"
rm "${stacd_conf_fname}"

PYTHONPATH=${PYTHON_PATH} coverage run --rcfile=.coveragerc ../test/test-udev.py
PYTHONPATH=${PYTHON_PATH} coverage run --rcfile=.coveragerc ../test/test-avahi.py
PYTHONPATH=${PYTHON_PATH} coverage run --rcfile=.coveragerc ../test/test-gtimer.py
PYTHONPATH=${PYTHON_PATH} coverage run --rcfile=.coveragerc ../test/test-version.py
PYTHONPATH=${PYTHON_PATH} coverage run --rcfile=.coveragerc ../test/test-transport_id.py
PYTHONPATH=${PYTHON_PATH} coverage run --rcfile=.coveragerc ../test/test-config.py
PYTHONPATH=${PYTHON_PATH} coverage run --rcfile=.coveragerc ../test/test-controller.py
PYTHONPATH=${PYTHON_PATH} coverage run --rcfile=.coveragerc ../test/test-service.py
PYTHONPATH=${PYTHON_PATH} coverage run --rcfile=.coveragerc ../test/test-log.py
sudo PYTHONPATH=${PYTHON_PATH} coverage run --rcfile=.coveragerc ../test/test-nvme_options.py

################################################################################
# Stop nvme target simulator
printf "\n%b[1;36m%s%b[0m\n" "\0033" "Stop nvmet" "\0033"
sudo ../utils/nvmet/nvmet.py clean

printf "\n%b[1;36m%s%b[0m\n" "\0033" "Collect all coverage data" "\0033"
coverage combine --rcfile=.coveragerc

printf "\n%b[1;36m%s%b[0m\n" "\0033" "Generating coverage report" "\0033"
coverage report -i --rcfile=.coveragerc

printf "\n%b[1;36m%s%b[0m\n" "\0033" "Generating coverage report (HTML)" "\0033"
coverage html -i --rcfile=.coveragerc

