From 2bf49272367cf92f8bee6b44f3f8fd42d7784484 Mon Sep 17 00:00:00 2001 From: Konrad Sztyber Date: Thu, 24 Feb 2022 13:17:31 +0100 Subject: [PATCH] test/sma: plugin test The test verifies that it's possible to register device managers from out-of-tree plugins. The test defines two plugins, each defining two device managers implementing the same two protocols and verifies that it's possible to register different combinations. Signed-off-by: Konrad Sztyber Change-Id: I2144b40db603fea95bf8b571777e6662b4de9bc7 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/11729 Community-CI: Broadcom CI Tested-by: SPDK CI Jenkins Reviewed-by: Jim Harris Reviewed-by: Tomasz Zawadzki --- test/common/skipped_tests.txt | 1 + test/sma/plugins.sh | 149 +++++++++++++++++++++++++++ test/sma/plugins/plugin1/__init__.py | 21 ++++ test/sma/plugins/plugin2/__init__.py | 21 ++++ test/sma/sma.sh | 1 + 5 files changed, 193 insertions(+) create mode 100755 test/sma/plugins.sh create mode 100644 test/sma/plugins/plugin1/__init__.py create mode 100644 test/sma/plugins/plugin2/__init__.py diff --git a/test/common/skipped_tests.txt b/test/common/skipped_tests.txt index 99f8440b8..1f4fda97f 100644 --- a/test/common/skipped_tests.txt +++ b/test/common/skipped_tests.txt @@ -92,3 +92,4 @@ zoned_fio # SMA tests - disabled in CI for now sma_nvmf_tcp +sma_plugins diff --git a/test/sma/plugins.sh b/test/sma/plugins.sh new file mode 100755 index 000000000..6d93074f1 --- /dev/null +++ b/test/sma/plugins.sh @@ -0,0 +1,149 @@ +#!/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 create_device() { + "$rootdir/scripts/sma-client.py" <<- EOF + { + "method": "CreateDevice", + "params": { + "$1": {} + } + } + EOF +} + +trap 'killprocess $smapid; exit 1' SIGINT SIGTERM EXIT + +# First check a single plugin with both its devices enabled in the config +PYTHONPATH=$testdir/plugins $rootdir/scripts/sma.py -c <( + cat <<- EOF + plugins: + - 'plugin1' + devices: + - name: 'plugin1-device1' + - name: 'plugin1-device2' + EOF +) & +smapid=$! +# Wait for a while to make sure SMA starts listening +sma_waitforlisten + +[[ $(create_device nvme | jq -r '.handle') == 'nvme:plugin1-device1' ]] +[[ $(create_device nvmf_tcp | jq -r '.handle') == 'nvmf_tcp:plugin1-device2' ]] + +killprocess $smapid + +# Check that it's possible to enable only a single device from a plugin +PYTHONPATH=$testdir/plugins $rootdir/scripts/sma.py -c <( + cat <<- EOF + plugins: + - 'plugin1' + devices: + - name: 'plugin1-device2' + EOF +) & +smapid=$! +sma_waitforlisten + +[[ $(create_device nvmf_tcp | jq -r '.handle') == 'nvmf_tcp:plugin1-device2' ]] +NOT create_device nvme + +killprocess $smapid + +# Load two different plugins, but only enable devices from one of them +PYTHONPATH=$testdir/plugins $rootdir/scripts/sma.py -c <( + cat <<- EOF + plugins: + - 'plugin1' + - 'plugin2' + devices: + - name: 'plugin1-device1' + - name: 'plugin1-device2' + EOF +) & +smapid=$! +sma_waitforlisten + +[[ $(create_device nvme | jq -r '.handle') == 'nvme:plugin1-device1' ]] +[[ $(create_device nvmf_tcp | jq -r '.handle') == 'nvmf_tcp:plugin1-device2' ]] + +killprocess $smapid + +# Check the same but take devices defined by the other plugin +PYTHONPATH=$testdir/plugins $rootdir/scripts/sma.py -c <( + cat <<- EOF + plugins: + - 'plugin1' + - 'plugin2' + devices: + - name: 'plugin2-device1' + - name: 'plugin2-device2' + EOF +) & +smapid=$! +sma_waitforlisten + +[[ $(create_device nvme | jq -r '.handle') == 'nvme:plugin2-device1' ]] +[[ $(create_device nvmf_tcp | jq -r '.handle') == 'nvmf_tcp:plugin2-device2' ]] + +killprocess $smapid + +# Now pick a device from each plugin +PYTHONPATH=$testdir/plugins $rootdir/scripts/sma.py -c <( + cat <<- EOF + plugins: + - 'plugin1' + - 'plugin2' + devices: + - name: 'plugin1-device1' + - name: 'plugin2-device2' + EOF +) & +smapid=$! +sma_waitforlisten + +[[ $(create_device nvme | jq -r '.handle') == 'nvme:plugin1-device1' ]] +[[ $(create_device nvmf_tcp | jq -r '.handle') == 'nvmf_tcp:plugin2-device2' ]] + +killprocess $smapid + +# Check the same, but register plugins via a env var +PYTHONPATH=$testdir/plugins SMA_PLUGINS=plugin1:plugin2 $rootdir/scripts/sma.py -c <( + cat <<- EOF + devices: + - name: 'plugin1-device1' + - name: 'plugin2-device2' + EOF +) & +smapid=$! +sma_waitforlisten + +[[ $(create_device nvme | jq -r '.handle') == 'nvme:plugin1-device1' ]] +[[ $(create_device nvmf_tcp | jq -r '.handle') == 'nvmf_tcp:plugin2-device2' ]] + +killprocess $smapid + +# Finally, register one plugin in a config and the other through env var +PYTHONPATH=$testdir/plugins SMA_PLUGINS=plugin1 $rootdir/scripts/sma.py -c <( + cat <<- EOF + plugins: + - 'plugin2' + devices: + - name: 'plugin1-device1' + - name: 'plugin2-device2' + EOF +) & +smapid=$! +sma_waitforlisten + +[[ $(create_device nvme | jq -r '.handle') == 'nvme:plugin1-device1' ]] +[[ $(create_device nvmf_tcp | jq -r '.handle') == 'nvmf_tcp:plugin2-device2' ]] + +killprocess $smapid + +trap - SIGINT SIGTERM EXIT diff --git a/test/sma/plugins/plugin1/__init__.py b/test/sma/plugins/plugin1/__init__.py new file mode 100644 index 000000000..d5daf5365 --- /dev/null +++ b/test/sma/plugins/plugin1/__init__.py @@ -0,0 +1,21 @@ +from spdk.sma import DeviceManager +from spdk.sma.proto import sma_pb2 + + +class TestDeviceManager1(DeviceManager): + def __init__(self, client): + super().__init__('plugin1-device1', 'nvme', client) + + def create_device(self, request): + return sma_pb2.CreateDeviceResponse(handle=f'{self.protocol}:{self.name}') + + +class TestDeviceManager2(DeviceManager): + def __init__(self, client): + super().__init__('plugin1-device2', 'nvmf_tcp', client) + + def create_device(self, request): + return sma_pb2.CreateDeviceResponse(handle=f'{self.protocol}:{self.name}') + + +devices = [TestDeviceManager1, TestDeviceManager2] diff --git a/test/sma/plugins/plugin2/__init__.py b/test/sma/plugins/plugin2/__init__.py new file mode 100644 index 000000000..8ff4165d5 --- /dev/null +++ b/test/sma/plugins/plugin2/__init__.py @@ -0,0 +1,21 @@ +from spdk.sma import DeviceManager +from spdk.sma.proto import sma_pb2 + + +class TestDeviceManager1(DeviceManager): + def __init__(self, client): + super().__init__('plugin2-device1', 'nvme', client) + + def create_device(self, request): + return sma_pb2.CreateDeviceResponse(handle=f'{self.protocol}:{self.name}') + + +class TestDeviceManager2(DeviceManager): + def __init__(self, client): + super().__init__('plugin2-device2', 'nvmf_tcp', client) + + def create_device(self, request): + return sma_pb2.CreateDeviceResponse(handle=f'{self.protocol}:{self.name}') + + +devices = [TestDeviceManager1, TestDeviceManager2] diff --git a/test/sma/sma.sh b/test/sma/sma.sh index a9a3ea56e..744edb656 100755 --- a/test/sma/sma.sh +++ b/test/sma/sma.sh @@ -6,3 +6,4 @@ rootdir=$(readlink -f "$testdir/../..") source "$rootdir/test/common/autotest_common.sh" run_test "sma_nvmf_tcp" $testdir/nvmf_tcp.sh +run_test "sma_plugins" $testdir/plugins.sh