This patch has not been tested since rebasing onto upstream vmtest.sh.
It is probably very broken, but here to show the direction the testing
is going in...

vsock_test uses tcp for the control socket. TCP itself responds to
namespaces. In order to test vsock but not break TCP, vmtest.sh sets up
a bridge with socat (perhaps ip tables would be better, because it can
reduce an out-of-tree tool dependency). Another option is to not use
vsock_test for the NS tests, but it seems more robust to test all of
vsock instead of just (for example) connectibility...

Signed-off-by: Bobby Eshleman <bobbyeshle...@gmail.com>
---
 tools/testing/selftests/vsock/vmtest.sh | 555 +++++++++++++++++++++++++++++---
 1 file changed, 510 insertions(+), 45 deletions(-)

diff --git a/tools/testing/selftests/vsock/vmtest.sh 
b/tools/testing/selftests/vsock/vmtest.sh
index edacebfc1632..8f627f60cc11 100755
--- a/tools/testing/selftests/vsock/vmtest.sh
+++ b/tools/testing/selftests/vsock/vmtest.sh
@@ -7,6 +7,48 @@
 #              * virtme-ng
 #              * busybox-static (used by virtme-ng)
 #              * qemu  (used by virtme-ng)
+#
+# Namespace tests require to test the functionality of VSOCK under different
+# namespace configurations. Ideally, we can use vsock_test and friends under
+# the different configurations to ensure that all functionality works
+# regardless of namespace setup. vsock_test also requires TCP for its control
+# plane, which is also impacted by namespacing. For this reason, these tests
+# build a bridge between the namespaces so that the TCP control traffic can
+# flow between namespaces. The bridge setup looks as follows:
+#
+#
+#                                  |
+#     +------------------+         |
+#     | VM               |         |
+#     |                  |     NS0 | NS1
+#     |  +------------+  |         |
+#     |  |            |  | --------+--------------------+
+#     |  | vsock_test |  |         |                    |
+#     |  |            |  | <-------+-----------------+  |
+#     |  +------------+  |         |  VSOCK_TEST_PORT|  |
+#     |                  |         |                 |  | VSOCK
+#     +------------------+         |                 |  |
+#              ^  |                |                 |  |
+#  CONTROL_PORT|  |                |                 |  |
+#              |  |                |                 |  |
+#              |  |                |                 |  v
+#              |  |                |             +------------+
+#              |  | TCP            |             |            |
+#              |  |                |             | vsock_test |
+#              |  |                |             |            |
+#              |  |                |             +------------+
+# CONTROL_PORT |  |                |   CONTROL_PORT  ^  |
+#              |  |                |                 |  |
+#              |  v                |   CONTROL_PORT  |  v
+#           +-------+              |              +-------+
+#           |       |veth0         |         veth1|       |
+#           | socat |<-------------+------------- | socat |
+#           |       | -------------+------------> |       |
+#           +-------+              |              +-------+
+#              NS_BRIDGE_PORT      |       NS_BRIDGE_PORT
+#                                  |
+
+set -u
 
 readonly SCRIPT_DIR="$(cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
 readonly KERNEL_CHECKOUT=$(realpath "${SCRIPT_DIR}"/../../../../)
@@ -19,11 +61,11 @@ readonly TEST_HOST_PORT=50000
 readonly TEST_HOST_PORT_LISTENER=50001
 readonly SSH_GUEST_PORT=22
 readonly SSH_HOST_PORT=2222
-readonly VSOCK_CID=1234
+readonly BRIDGE_PORT=5678
+readonly DEFAULT_CID=1234
 readonly WAIT_PERIOD=3
 readonly WAIT_PERIOD_MAX=60
-readonly WAIT_TOTAL=$(( WAIT_PERIOD * WAIT_PERIOD_MAX ))
-readonly QEMU_PIDFILE=$(mktemp /tmp/qemu_vsock_vmtest_XXXX.pid)
+WAIT_TOTAL=$(( WAIT_PERIOD * WAIT_PERIOD_MAX ))
 
 # virtme-ng offers a netdev for ssh when using "--ssh", but we also need a
 # control port forwarded for vsock_test.  Because virtme-ng doesn't support
@@ -33,23 +75,48 @@ readonly QEMU_PIDFILE=$(mktemp 
/tmp/qemu_vsock_vmtest_XXXX.pid)
 # add the kernel cmdline options that virtme-init uses to setup the interface.
 readonly 
QEMU_TEST_PORT_FWD="hostfwd=tcp::${TEST_HOST_PORT}-:${TEST_GUEST_PORT}"
 readonly QEMU_SSH_PORT_FWD="hostfwd=tcp::${SSH_HOST_PORT}-:${SSH_GUEST_PORT}"
-readonly QEMU_OPTS="\
+readonly LOG=$(mktemp /tmp/vsock_vmtest_XXXX.log)
+readonly TEST_NAMES=(vm_server_host_client vm_client_host_server vm_loopback)
+QEMU_OPTS="\
         -netdev user,id=n0,${QEMU_TEST_PORT_FWD},${QEMU_SSH_PORT_FWD} \
         -device virtio-net-pci,netdev=n0 \
-        -device vhost-vsock-pci,guest-cid=${VSOCK_CID} \
-        --pidfile ${QEMU_PIDFILE} \
 "
 readonly KERNEL_CMDLINE="\
        virtme.dhcp net.ifnames=0 biosdevname=0 \
        virtme.ssh virtme_ssh_channel=tcp virtme_ssh_user=$USER \
 "
 readonly LOG=$(mktemp /tmp/vsock_vmtest_XXXX.log)
-readonly TEST_NAMES=(vm_server_host_client vm_client_host_server vm_loopback)
+readonly TEST_NAMES=(
+       vm_server_host_client
+       vm_client_host_server
+       vm_loopback
+       host_vsock_ns_mode
+       host_vsock_ns_mode_write_once
+       global_same_cid
+       local_same_cid
+       global_local_same_cid
+       local_global_same_cid
+       global_host_connect_global_vm
+       global_vm_connect_global_host
+       global_vm_connect_mixed_host
+)
+
 readonly TEST_DESCS=(
        "Run vsock_test in server mode on the VM and in client mode on the 
host."
        "Run vsock_test in client mode on the VM and in server mode on the 
host."
        "Run vsock_test using the loopback transport in the VM."
+       "Check /proc/net/vsock_ns_mode strings on the host."
+       "Check /proc/net/vsock_ns_mode is write-once on the host."
+       "Test that CID allocation fails with the same CID, one global NS and 
another global NS."
+       "Test that CID allocation succeeds with the same CID, one local NS and 
another local NS."
+       "Test that CID allocation succeeds with the same CID, one global NS and 
one local NS, global allocates first."
+       "Test that CID allocation succeeds with the same CID, one global NS and 
one local NS, local allocates first."
 )
+readonly NEEDS_SETUP=(vm_server_host_client vm_client_host_server vm_loopback)
+readonly MODES=("local" "global" "mixed")
+readonly PIDFILE_TEMPLATE="/tmp/qemu_vsock_vmtest_XXXX.pid"
+
+declare -a PIDFILES
 
 VERBOSE=0
 
@@ -84,21 +151,40 @@ die() {
        exit "${KSFT_FAIL}"
 }
 
+cleanup() {
+       terminate_pidfiles ${PIDFILES[@]}
+       del_namespaces
+}
+
 vm_ssh() {
        ssh -q -o UserKnownHostsFile=/dev/null -p ${SSH_HOST_PORT} localhost 
"$@"
        return $?
 }
 
-cleanup() {
-       if [[ -s "${QEMU_PIDFILE}" ]]; then
-               pkill -SIGTERM -F "${QEMU_PIDFILE}" > /dev/null 2>&1
-       fi
+vm_ssh_ns() {
+       local ns="${1}"
+       local NS_EXEC="ip netns exec ${ns}"
+       shift
 
-       # If failure occurred during or before qemu start up, then we need
-       # to clean this up ourselves.
-       if [[ -e "${QEMU_PIDFILE}" ]]; then
-               rm "${QEMU_PIDFILE}"
-       fi
+       ${NS_EXEC} ssh -q -o UserKnownHostsFile=/dev/null -p ${SSH_HOST_PORT} 
localhost $*
+
+       return $?
+}
+
+terminate_pidfiles() {
+       local pidfile
+
+       for pidfile in $@; do
+               if [[ -s "${pidfile}" ]]; then
+                       pkill -SIGTERM -F ${pidfile} 2>&1 > /dev/null
+               fi
+
+               # If failure occurred during or before qemu start up, then we 
need
+               # to clean this up ourselves.
+               if [[ -e "${pidfile}" ]]; then
+                       rm "${pidfile}"
+               fi
+       done
 }
 
 check_args() {
@@ -189,7 +275,13 @@ handle_build() {
 }
 
 vm_start() {
+       local cid=$1
+       local ns=$2
+       local verify_boot=${3:-1}
+       local pidfile=${4:-}
+
        local logfile=/dev/null
+       local qemu_opts=""
        local verbose_opt=""
        local kernel_opt=""
        local qemu
@@ -201,35 +293,53 @@ vm_start() {
                logfile=/dev/stdout
        fi
 
+       qemu_opts="\
+               ${QEMU_OPTS} -device vhost-vsock-pci,guest-cid=${cid} \
+               --pidfile ${pidfile}
+       "
+
        if [[ "${BUILD}" -eq 1 ]]; then
                kernel_opt="${KERNEL_CHECKOUT}"
        fi
 
-       vng \
+       if [[ ! -z "${ns}" ]]; then
+               NS_EXEC="ip netns exec ${ns}"
+       fi
+
+       if [[ -z "${pidfile}" ]]; then
+               pidfile=$(mktemp $PIDFILE_TEMPLATE)
+               PIDFILES+=("${pidfile}")
+       fi
+
+       ${NS_EXEC} vng \
                --run \
                ${kernel_opt} \
                ${verbose_opt} \
-               --qemu-opts="${QEMU_OPTS}" \
+               --qemu-opts="${qemu_opts}" \
                --qemu="${qemu}" \
                --user root \
                --append "${KERNEL_CMDLINE}" \
                --rw  &> ${logfile} &
 
-       if ! timeout ${WAIT_TOTAL} \
-               bash -c 'while [[ ! -s '"${QEMU_PIDFILE}"' ]]; do sleep 1; 
done; exit 0'; then
-               die "failed to boot VM"
-       fi
+       timeout ${WAIT_TOTAL} \
+               bash -c 'while [[ ! -s '"${pidfile}"' ]]; do sleep 1; done; 
exit 0'
 }
 
 vm_wait_for_ssh() {
+       local ns="${1}"
        local i
 
        i=0
-       while true; do
+       while [[ true ]]; do
                if [[ ${i} -gt ${WAIT_PERIOD_MAX} ]]; then
                        die "Timed out waiting for guest ssh"
                fi
-               if vm_ssh -- true; then
+               if [[ ! -z "${ns}" ]]; then
+                       vm_ssh_ns "${ns}" -- true
+               else
+                       vm_ssh -- true
+               fi
+               if [[ $? -eq 0 ]]; then
                        break
                fi
                i=$(( i + 1 ))
@@ -262,8 +372,9 @@ wait_for_listener()
 
 vm_wait_for_listener() {
        local port=$1
+       local host_ns=$2
 
-       vm_ssh <<EOF
+       vm_ssh_ns "${host_ns}" <<EOF
 $(declare -f wait_for_listener)
 wait_for_listener ${port} ${WAIT_PERIOD} ${WAIT_PERIOD_MAX}
 EOF
@@ -271,6 +382,17 @@ EOF
 
 host_wait_for_listener() {
        wait_for_listener "${TEST_HOST_PORT_LISTENER}" "${WAIT_PERIOD}" 
"${WAIT_PERIOD_MAX}"
+       wait_for_listener ${TEST_HOST_PORT_LISTENER} ${WAIT_PERIOD} 
${WAIT_PERIOD_MAX}
+}
+
+host_ns_wait_for_listener() {
+       local ns="${1}"
+       local port="${2}"
+
+       ip netns exec "${ns}" bash <<-EOF
+               $(declare -f wait_for_listener)
+               wait_for_listener ${port} ${WAIT_PERIOD} ${WAIT_PERIOD_MAX}
+       EOF
 }
 
 __log_stdin() {
@@ -331,7 +453,7 @@ test_vm_server_host_client() {
        ${VSOCK_TEST} \
                --mode=client \
                --control-host=127.0.0.1 \
-               --peer-cid="${VSOCK_CID}" \
+               --peer-cid="${DEFAULT_CID}" \
                --control-port="${TEST_HOST_PORT}" 2>&1 | log_host "${testname}"
 
        return $?
@@ -343,7 +465,7 @@ test_vm_client_host_server() {
        ${VSOCK_TEST} \
                --mode "server" \
                --control-port "${TEST_HOST_PORT_LISTENER}" \
-               --peer-cid "${VSOCK_CID}" 2>&1 | log_host "${testname}" &
+               --peer-cid "${DEFAULT_CID}" 2>&1 | log_host "${testname}" &
 
        host_wait_for_listener
 
@@ -376,6 +498,309 @@ test_vm_loopback() {
        return $?
 }
 
+add_namespaces() {
+       local init=${1:-0}
+
+       for mode in "${MODES[@]}"; do
+               if ! ip netns add "${mode}"; then
+                       return ${KSFT_FAIL}
+               fi
+
+               # e.g., global-2, local-2, mixed-2
+               if ! ip netns add "${mode}-2"; then
+                       return ${KSFT_FAIL}
+               fi
+
+               if [[ ${init} -eq 1 ]]; then
+                       ns_set_mode "${mode}" "${mode}"
+                       ns_set_mode "${mode}-2" "${mode}"
+
+                       # we need lo for qemu port forwarding
+                       ip netns exec "${mode}" ip link set dev lo up
+                       ip netns exec "${mode}-2" ip link set dev lo up
+               fi
+       done
+       return 0
+}
+
+del_namespaces() {
+       for mode in "${MODES[@]}"; do
+               ip netns del "${mode}"
+               ip netns del "${mode}-2"
+       done &>/dev/null
+}
+
+ns_set_mode() {
+       local ns=$1
+       local mode=$2
+
+       echo "${mode}" \
+               | ip netns exec "${ns}" \
+                       tee /proc/net/vsock_ns_mode &>/dev/null
+}
+
+setup_bridge() {
+       local ns0
+       local ns1
+       local addr1
+
+       ns0=$1
+       ns1=$2
+
+       ip link add veth0 type veth peer name veth1
+       ip link set veth0 netns "${ns0}"
+       ip link set veth1 netns "${ns1}"
+       ip netns exec "${ns0}" ip addr add 10.0.0.1/24 dev veth0
+       ip netns exec "${ns1}" ip addr add 10.0.0.2/24 dev veth1
+       ip netns exec "${ns0}" ip link set veth0 up
+       ip netns exec "${ns1}" ip link set veth1 up
+}
+
+teardown_bridge() {
+       local ns0="${1}"
+
+       # veth1 is implicitly destroyed with veth0
+       ip netns exec "${ns0}" ip link delete veth0
+}
+
+test_host_vsock_ns_mode() {
+       if ! add_namespaces; then
+               return ${KSFT_FAIL}
+       fi
+
+       for mode in "${MODES[@]}"; do
+               if ! ns_set_mode "${mode}" "${mode}"; then
+                       del_namespaces
+                       return ${KSFT_FAIL}
+               fi
+       done
+
+       if ! del_namespaces; then
+               return ${KSFT_FAIL}
+       fi
+}
+
+test_host_vsock_ns_mode_write_once() {
+       if ! add_namespaces; then
+               return ${KSFT_FAIL}
+       fi
+
+       for mode in "${MODES[@]}"; do
+               if ! ns_set_mode "${mode}" "${mode}"; then
+                       del_namespaces
+                       return ${KSFT_FAIL}
+               fi
+
+               # try setting back to global, should fail
+               if ns_set_mode "${mode}" "global"; then
+                       del_namespaces
+                       return ${KSFT_FAIL}
+               fi
+       done
+
+       if ! del_namespaces; then
+               return ${KSFT_FAIL}
+       fi
+}
+
+namespaces_can_boot_same_cid() {
+       local ns1=$1
+       local ns2=$2
+       local cid=20
+       local pidfile1
+       local pidfile2
+       local msg
+
+       if ! add_namespaces 1; then
+               return 1
+       fi
+
+       if [[ ${VERBOSE} -gt 0 ]]; then
+               echo "booting vm 1" | tap_prefix
+       fi
+
+       pidfile1=$(mktemp $PIDFILE_TEMPLATE)
+       PIDFILES+=("${pidfile1}")
+       vm_start ${cid} ${ns1} ${pidfile1}
+
+       if [[ ${VERBOSE} -gt 0 ]]; then
+               echo "booting vm 2" | tap_prefix
+       fi
+
+       pidfile2=$(mktemp $PIDFILE_TEMPLATE)
+       PIDFILES+=("${pidfile2}")
+       WAIT_TOTAL=30 vm_start ${cid} ${ns2} ${pidfile2}
+
+       rc=$?
+       if [[ $rc -eq 0 ]]; then
+               msg="successfully booted"
+               rc=0
+       else
+               msg="failed to boot"
+               rc=1
+       fi
+
+       if [[ ${VERBOSE} -gt 0 ]]; then
+               echo "vm 2 ${msg}" | tap_prefix
+       fi
+       if ! del_namespaces; then
+               echo "failed to delete namespaces" | tap_prefix
+       fi
+
+       terminate_pidfiles ${pidfile1} ${pidfile2}
+       return $rc
+}
+
+test_global_same_cid() {
+       if namespaces_can_boot_same_cid "global" "global-2"; then
+               return $KSFT_FAIL
+       fi
+
+       return $KSFT_PASS
+}
+
+test_local_global_same_cid() {
+       if namespaces_can_boot_same_cid "local" "global"; then
+               return $KSFT_PASS
+       fi
+
+       return $KSFT_FAIL
+}
+
+test_global_local_same_cid() {
+       if namespaces_can_boot_same_cid "global" "local"; then
+               return $KSFT_PASS
+       fi
+
+       return $KSFT_FAIL
+}
+
+test_local_same_cid() {
+       if namespaces_can_boot_same_cid "local" "local"; then
+               return $KSFT_FAIL
+       fi
+
+       return $KSFT_PASS
+}
+
+test_global_host_connect_global_vm() {
+       local testname="${FUNCNAME[0]#test_}"
+       local cid=${DEFAULT_CID}
+       local port=1234
+       local host_ns="global"
+       local host_ns2="global-2"
+
+       add_namespaces 1
+       setup_bridge "${host_ns}" "${host_ns2}"
+
+       # Start server in VM in namespace
+       if ! vm_start ${cid} "${host_ns}"; then
+               teardown_bridge "${host_ns}"
+               return $KSFT_FAIL
+       fi
+
+       vm_ssh_ns "${host_ns}" \
+               -- "${VSOCK_TEST}" \
+               --mode=server \
+               --control-port="${TEST_GUEST_PORT}" \
+               --peer-cid=2 \
+               2>&1 | log_guest "${testname}" &
+       vm_wait_for_listener ${TEST_GUEST_PORT} "${host_ns}"
+
+       # Setup NS-to-NS "bridge" 
+       ip netns exec "${host_ns}" socat TCP-LISTEN:${BRIDGE_PORT},fork \
+               TCP-CONNECT:localhost:${TEST_HOST_PORT} &
+       host_ns_wait_for_listener "${host_ns}" "${BRIDGE_PORT}"
+
+       ip netns exec "${host_ns2}" \
+               socat TCP:10.0.0.1:${BRIDGE_PORT} 
TCP-LISTEN:${TEST_HOST_PORT},fork &
+       host_ns_wait_for_listener "${host_ns2}" "${TEST_HOST_PORT}"
+
+       # Start client in other namespace
+       ip netns exec "${host_ns2}" ${VSOCK_TEST} \
+               --mode=client \
+               --control-host=127.0.0.1 \
+               --peer-cid="${cid}" \
+               --control-port="${TEST_HOST_PORT}" 2>&1 | log_host "${testname}"
+       rc=$?
+
+       if [[ ! $rc -eq 0 ]]; then
+               return $KSFT_FAIL
+       fi
+
+       del_namespaces
+
+       return $KSFT_PASS
+}
+
+do_ns_vm_client_host_server_test() {
+       local testname="$1"
+       local host_ns="$2"
+       local host_ns2="$3"
+       local cid=${DEFAULT_CID}
+
+       # must not be same as qemu hostfwd port
+       local port=12345
+
+       add_namespaces 1
+       setup_bridge "${host_ns}" "${host_ns2}"
+
+       if ! vm_start ${cid} "${host_ns}"; then
+               teardown_bridge "${host_ns}"
+               return $KSFT_FAIL
+       fi
+
+       ip netns exec "${host_ns2}" ${VSOCK_TEST} \
+               --mode=server \
+               --peer-cid="${cid}" \
+               --control-port="${port}" 2>&1 | log_host "${testname}" &
+
+       host_ns_wait_for_listener "${host_ns2}" "${port}"
+
+       ip netns exec "${host_ns2}" \
+               socat TCP-LISTEN:${BRIDGE_PORT},bind=10.0.0.2,fork \
+                       TCP:localhost:${port} &
+
+       host_ns_wait_for_listener "${host_ns2}" "${BRIDGE_PORT}"
+
+       ip netns exec "${host_ns}" socat TCP-LISTEN:${port},fork \
+               TCP-CONNECT:10.0.0.2:${BRIDGE_PORT} &
+
+       host_ns_wait_for_listener "${host_ns}" "${port}"
+
+       vm_ssh_ns "${host_ns}" \
+               -- "${VSOCK_TEST}" \
+               --mode=client \
+               --control-host=10.0.2.2 \
+               --control-port="${port}" \
+               --peer-cid=2 \
+               2>&1 | log_guest "${testname}"
+
+       if [[ ! $? -eq 0 ]]; then
+               return $KSFT_FAIL
+       fi
+
+       del_namespaces
+
+       return $KSFT_PASS
+}
+
+test_global_vm_connect_global_host() {
+       local testname="${FUNCNAME[0]#test_}"
+       local host_ns="global"
+       local host_ns2="global-2"
+
+       do_ns_vm_client_host_server_test ${testname} ${host_ns} ${host_ns2}
+}
+
+test_global_vm_connect_mixed_host() {
+       local testname="${FUNCNAME[0]#test_}"
+       local host_ns="global"
+       local host_ns2="mixed"
+
+       do_ns_vm_client_host_server_test ${testname} ${host_ns} ${host_ns2}
+}
+
 run_test() {
        local host_oops_cnt_before
        local host_warn_cnt_before
@@ -421,7 +846,40 @@ run_test() {
                rc=$KSFT_FAIL
        fi
 
-       return "${rc}"
+       check_result "${rc}"
+}
+
+needs_setup() {
+       local tname
+
+       tname="$1"
+
+       for testname in ${NEEDS_SETUP[@]}; do
+               if [[ "${tname}" == "${testname}" ]]; then
+                       return 1
+               fi
+       done
+
+       return 0
+}
+
+check_result() {
+       local rc
+
+       rc=$1
+
+       if [[ ${rc} -eq $KSFT_PASS ]]; then
+               cnt_pass=$(( cnt_pass + 1 ))
+               echo "ok ${cnt_total} ${arg}"
+       elif [[ ${rc} -eq $KSFT_SKIP ]]; then
+               cnt_skip=$(( cnt_skip + 1 ))
+               echo "ok ${cnt_total} ${arg} # SKIP"
+       elif [[ ${rc} -eq $KSFT_FAIL ]]; then
+               cnt_fail=$(( cnt_fail + 1 ))
+               echo "not ok ${cnt_total} ${arg} # exit=$rc"
+       fi
+
+       cnt_total=$(( cnt_total + 1 ))
 }
 
 QEMU="qemu-system-$(uname -m)"
@@ -452,29 +910,36 @@ handle_build
 
 echo "1..${#ARGS[@]}"
 
-log_setup "Booting up VM"
-vm_start
-vm_wait_for_ssh
-log_setup "VM booted up"
-
 cnt_pass=0
 cnt_fail=0
 cnt_skip=0
 cnt_total=0
+setup_done=0
+
+pidfile=""
+for arg in ${ARGS[@]}; do
+       if needs_setup "${arg}"; then
+               if [[ -z "${pidfile}" ]]; then
+                       pidfile=$(mktemp $PIDFILE_TEMPLATE)
+                       log_setup "Booting up VM"
+                       vm_start "${DEFAULT_CID}" "" "${pidfile}"
+                       vm_wait_for_ssh
+                       log_setup "VM booted up"
+               fi
+
+               run_test "${arg}"
+       fi
+done
+
+if [[ ! -z "${pidfile}" ]]; then
+       log_setup "VM terminate"
+       terminate_pidfiles "${pidfile}"
+fi
+
 for arg in "${ARGS[@]}"; do
-       run_test "${arg}"
-       rc=$?
-       if [[ ${rc} -eq $KSFT_PASS ]]; then
-               cnt_pass=$(( cnt_pass + 1 ))
-               echo "ok ${cnt_total} ${arg}"
-       elif [[ ${rc} -eq $KSFT_SKIP ]]; then
-               cnt_skip=$(( cnt_skip + 1 ))
-               echo "ok ${cnt_total} ${arg} # SKIP"
-       elif [[ ${rc} -eq $KSFT_FAIL ]]; then
-               cnt_fail=$(( cnt_fail + 1 ))
-               echo "not ok ${cnt_total} ${arg} # exit=$rc"
+       if ! needs_setup "${arg}"; then
+               run_test "${arg}"
        fi
-       cnt_total=$(( cnt_total + 1 ))
 done
 
 echo "SUMMARY: PASS=${cnt_pass} SKIP=${cnt_skip} FAIL=${cnt_fail}"

-- 
2.47.1


Reply via email to