From b41183835da40467023ba7e537d1bc91a20564d8 Mon Sep 17 00:00:00 2001 From: Konrad Sztyber Date: Thu, 24 Feb 2022 09:55:39 +0100 Subject: [PATCH] test/sma: add tests for nvmf-tcp The test uses `scripts/sma-client.py` to send a series of gRPC methods that are serviced by the SMA and then uses the regular SPDK RPC interface to verify its effects on the application. Signed-off-by: Konrad Sztyber Change-Id: I2b61c61cb475ec906bb6a594cda3082c0bd8ab44 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/11728 Community-CI: Broadcom CI Tested-by: SPDK CI Jenkins Reviewed-by: Jim Harris Reviewed-by: Tomasz Zawadzki --- test/common/skipped_tests.txt | 3 + test/sma/common.sh | 12 +++ test/sma/nvmf_tcp.sh | 159 ++++++++++++++++++++++++++++++++++ test/sma/sma.sh | 8 ++ 4 files changed, 182 insertions(+) create mode 100644 test/sma/common.sh create mode 100755 test/sma/nvmf_tcp.sh create mode 100755 test/sma/sma.sh diff --git a/test/common/skipped_tests.txt b/test/common/skipped_tests.txt index 8f7c6cd7d..99f8440b8 100644 --- a/test/common/skipped_tests.txt +++ b/test/common/skipped_tests.txt @@ -89,3 +89,6 @@ busy balanced core_load zoned_fio + +# SMA tests - disabled in CI for now +sma_nvmf_tcp diff --git a/test/sma/common.sh b/test/sma/common.sh new file mode 100644 index 000000000..667acd39e --- /dev/null +++ b/test/sma/common.sh @@ -0,0 +1,12 @@ +function sma_waitforlisten() { + local sma_addr=${1:-127.0.0.1} + local sma_port=${2:-8080} + + for ((i = 0; i < 5; i++)); do + if nc -z $sma_addr $sma_port; then + return 0 + fi + sleep 1s + done + return 1 +} diff --git a/test/sma/nvmf_tcp.sh b/test/sma/nvmf_tcp.sh new file mode 100755 index 000000000..941d345ea --- /dev/null +++ b/test/sma/nvmf_tcp.sh @@ -0,0 +1,159 @@ +#!/usr/bin/env bash + +testdir=$(readlink -f "$(dirname "$0")") +rootdir=$(readlink -f "$testdir/../..") + +source "$rootdir/test/common/autotest_common.sh" +source "$testdir/common.sh" + +function cleanup() { + killprocess $tgtpid + killprocess $smapid +} + +function uuid2base64() { + python <<- EOF + import base64, uuid + print(base64.b64encode(uuid.UUID("$1").bytes).decode()) + EOF +} + +function create_device() { + "$rootdir/scripts/sma-client.py" <<- EOF + { + "method": "CreateDevice", + "params": { + "nvmf_tcp": { + "subnqn": "$1", + "adrfam": "ipv4", + "traddr": "127.0.0.1", + "trsvcid": "4420" + } + } + } + EOF +} + +function delete_device() { + "$rootdir/scripts/sma-client.py" <<- EOF + { + "method": "DeleteDevice", + "params": { + "handle": "$1" + } + } + EOF +} + +function attach_volume() { + "$rootdir/scripts/sma-client.py" <<- EOF + { + "method": "AttachVolume", + "params": { + "device_handle": "$1", + "volume": { + "volume_id": "$(uuid2base64 $2)" + } + } + } + EOF +} + +function detach_volume() { + "$rootdir/scripts/sma-client.py" <<- EOF + { + "method": "DetachVolume", + "params": { + "device_handle": "$1", + "volume_id": "$(uuid2base64 $2)" + } + } + EOF +} + +trap "cleanup; exit 1" SIGINT SIGTERM EXIT + +$rootdir/build/bin/spdk_tgt & +tgtpid=$! +waitforlisten $tgtpid + +# Prepare the target +rpc_cmd bdev_null_create null0 100 4096 + +$rootdir/scripts/sma.py -c <( + cat <<- EOF + address: 127.0.0.1 + port: 8080 + devices: + - name: 'nvmf_tcp' + EOF +) & +smapid=$! + +# Wait until the SMA starts listening +sma_waitforlisten + +# Make sure a TCP transport has been created +rpc_cmd nvmf_get_transports --trtype tcp + +# Create a couple of devices and verify them via RPC +devid0=$(create_device nqn.2016-06.io.spdk:cnode0 | jq -r '.handle') +rpc_cmd nvmf_get_subsystems nqn.2016-06.io.spdk:cnode0 + +devid1=$(create_device nqn.2016-06.io.spdk:cnode1 | jq -r '.handle') +rpc_cmd nvmf_get_subsystems nqn.2016-06.io.spdk:cnode0 +rpc_cmd nvmf_get_subsystems nqn.2016-06.io.spdk:cnode1 +[[ "$devid0" != "$devid1" ]] + +# Check that there are three subsystems (2 created above + discovery) +[[ $(rpc_cmd nvmf_get_subsystems | jq -r '. | length') -eq 3 ]] + +# Verify the method is idempotent and sending the same gRPCs won't create new +# devices and will return the same handles +tmp0=$(create_device nqn.2016-06.io.spdk:cnode0 | jq -r '.handle') +tmp1=$(create_device nqn.2016-06.io.spdk:cnode1 | jq -r '.handle') + +[[ $(rpc_cmd nvmf_get_subsystems | jq -r '. | length') -eq 3 ]] +[[ "$tmp0" == "$devid0" ]] +[[ "$tmp1" == "$devid1" ]] + +# Now delete both of them verifying via RPC +delete_device "$devid0" +NOT rpc_cmd nvmf_get_subsystems nqn.2016-06.io.spdk:cnode0 +[[ $(rpc_cmd nvmf_get_subsystems | jq -r '. | length') -eq 2 ]] + +delete_device "$devid1" +NOT rpc_cmd nvmf_get_subsystems nqn.2016-06.io.spdk:cnode1 +[[ $(rpc_cmd nvmf_get_subsystems | jq -r '. | length') -eq 1 ]] + +# Finally check that removing a non-existing device is also sucessful +delete_device "$devid0" +delete_device "$devid1" + +# Check volume attach/detach +devid0=$(create_device nqn.2016-06.io.spdk:cnode0 | jq -r '.handle') +devid1=$(create_device nqn.2016-06.io.spdk:cnode1 | jq -r '.handle') +uuid=$(rpc_cmd bdev_get_bdevs -b null0 | jq -r '.[].uuid') + +# Attach the volume to a first device +attach_volume "$devid0" "$uuid" +[[ $(rpc_cmd nvmf_get_subsystems nqn.2016-06.io.spdk:cnode0 | jq -r '.[0].namespaces | length') -eq 1 ]] +[[ $(rpc_cmd nvmf_get_subsystems nqn.2016-06.io.spdk:cnode1 | jq -r '.[0].namespaces | length') -eq 0 ]] +[[ $(rpc_cmd nvmf_get_subsystems nqn.2016-06.io.spdk:cnode0 | jq -r '.[0].namespaces[0].uuid') == "$uuid" ]] + +# Attach the same device again and see that it won't fail +attach_volume "$devid0" "$uuid" +[[ $(rpc_cmd nvmf_get_subsystems nqn.2016-06.io.spdk:cnode0 | jq -r '.[0].namespaces | length') -eq 1 ]] +[[ $(rpc_cmd nvmf_get_subsystems nqn.2016-06.io.spdk:cnode1 | jq -r '.[0].namespaces | length') -eq 0 ]] +[[ $(rpc_cmd nvmf_get_subsystems nqn.2016-06.io.spdk:cnode0 | jq -r '.[0].namespaces[0].uuid') == "$uuid" ]] + +# Detach it and verify it's removed from the subsystem +detach_volume "$devid0" "$uuid" +[[ $(rpc_cmd nvmf_get_subsystems nqn.2016-06.io.spdk:cnode0 | jq -r '.[0].namespaces | length') -eq 0 ]] +[[ $(rpc_cmd nvmf_get_subsystems nqn.2016-06.io.spdk:cnode1 | jq -r '.[0].namespaces | length') -eq 0 ]] + +# Detach it again and verify it suceeds +detach_volume "$devid0" "$uuid" + +cleanup +trap - SIGINT SIGTERM EXIT diff --git a/test/sma/sma.sh b/test/sma/sma.sh new file mode 100755 index 000000000..a9a3ea56e --- /dev/null +++ b/test/sma/sma.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +testdir=$(readlink -f "$(dirname "$0")") +rootdir=$(readlink -f "$testdir/../..") + +source "$rootdir/test/common/autotest_common.sh" + +run_test "sma_nvmf_tcp" $testdir/nvmf_tcp.sh