test/sma: quality of service test
The test verifies that bdev-based QoS settings are correctly applied on NVMe/TCP devices. Other device types supporting bdev-based QoS will share most of the code, so NVMe/TCP is a good test vehicle, as it's the easiest one to set up. Signed-off-by: Konrad Sztyber <konrad.sztyber@intel.com> Change-Id: Ic715483e888a7219fd27367d527201d75e8b69a2 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14270 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
89b81dc2ff
commit
045152b220
@ -35,3 +35,18 @@ uuid2nguid() {
|
||||
local uuid=${1^^}
|
||||
echo ${uuid//-/}
|
||||
}
|
||||
|
||||
get_qos_caps() {
|
||||
local rootdir
|
||||
|
||||
rootdir="$(dirname $BASH_SOURCE)/../.."
|
||||
|
||||
"$rootdir/scripts/sma-client.py" <<- EOF
|
||||
{
|
||||
"method": "GetQosCapabilities",
|
||||
"params": {
|
||||
"device_type": $1
|
||||
}
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
238
test/sma/qos.sh
Executable file
238
test/sma/qos.sh
Executable file
@ -0,0 +1,238 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
testdir=$(readlink -f "$(dirname "$0")")
|
||||
rootdir=$(readlink -f "$testdir/../..")
|
||||
|
||||
source "$rootdir/test/common/autotest_common.sh"
|
||||
source "$testdir/common.sh"
|
||||
|
||||
smac="$rootdir/scripts/sma-client.py"
|
||||
|
||||
device_nvmf_tcp=3
|
||||
limit_reserved=$(printf '%u' $((2 ** 64 - 1)))
|
||||
|
||||
cleanup() {
|
||||
killprocess $tgtpid
|
||||
killprocess $smapid
|
||||
}
|
||||
|
||||
create_device() {
|
||||
$smac <<- EOF
|
||||
{
|
||||
"method": "CreateDevice",
|
||||
"params": {
|
||||
"nvmf_tcp": {
|
||||
"subnqn": "nqn.2016-06.io.spdk:cnode0",
|
||||
"adrfam": "ipv4",
|
||||
"traddr": "127.0.0.1",
|
||||
"trsvcid": "4420"
|
||||
},
|
||||
"volume": {
|
||||
"volume_id": "$(uuid2base64 $1)"
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
trap "cleanup; exit 1" SIGINT SIGTERM EXIT
|
||||
|
||||
$rootdir/build/bin/spdk_tgt &
|
||||
tgtpid=$!
|
||||
|
||||
$rootdir/scripts/sma.py -c <(
|
||||
cat <<- EOF
|
||||
address: 127.0.0.1
|
||||
port: 8080
|
||||
devices:
|
||||
- name: 'nvmf_tcp'
|
||||
EOF
|
||||
) &
|
||||
smapid=$!
|
||||
|
||||
sma_waitforlisten
|
||||
|
||||
# Prepare a device with a volume
|
||||
rpc_cmd bdev_null_create null0 100 4096
|
||||
uuid=$(rpc_cmd bdev_get_bdevs -b null0 | jq -r '.[].uuid')
|
||||
device=$(create_device $uuid | jq -r '.handle')
|
||||
|
||||
# First check the capabilities
|
||||
diff <(get_qos_caps $device_nvmf_tcp | jq --sort-keys) <(
|
||||
jq --sort-keys <<- EOF
|
||||
{
|
||||
"max_volume_caps": {
|
||||
"rw_iops": true,
|
||||
"rd_bandwidth": true,
|
||||
"wr_bandwidth": true,
|
||||
"rw_bandwidth": true
|
||||
}
|
||||
}
|
||||
EOF
|
||||
)
|
||||
|
||||
# Make sure that invalid device type causes an error
|
||||
NOT get_qos_caps 1234
|
||||
|
||||
# Set a single limit and make sure it's changed (and nothing else was changed)
|
||||
$smac <<- EOF
|
||||
{
|
||||
"method": "SetQos",
|
||||
"params": {
|
||||
"device_handle": "$device",
|
||||
"volume_id": "$(uuid2base64 $uuid)",
|
||||
"maximum": {
|
||||
"rw_iops": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
diff <(rpc_cmd bdev_get_bdevs -b null0 | jq --sort-keys '.[].assigned_rate_limits') <(
|
||||
jq --sort-keys <<- EOF
|
||||
{
|
||||
"rw_ios_per_sec": 1000,
|
||||
"rw_mbytes_per_sec": 0,
|
||||
"r_mbytes_per_sec": 0,
|
||||
"w_mbytes_per_sec": 0
|
||||
}
|
||||
EOF
|
||||
)
|
||||
|
||||
# Change two limits at the same time
|
||||
$smac <<- EOF
|
||||
{
|
||||
"method": "SetQos",
|
||||
"params": {
|
||||
"device_handle": "$device",
|
||||
"volume_id": "$(uuid2base64 $uuid)",
|
||||
"maximum": {
|
||||
"rw_iops": 2,
|
||||
"rd_bandwidth": 8
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
diff <(rpc_cmd bdev_get_bdevs -b null0 | jq --sort-keys '.[].assigned_rate_limits') <(
|
||||
jq --sort-keys <<- EOF
|
||||
{
|
||||
"rw_ios_per_sec": 2000,
|
||||
"rw_mbytes_per_sec": 0,
|
||||
"r_mbytes_per_sec": 8,
|
||||
"w_mbytes_per_sec": 0
|
||||
}
|
||||
EOF
|
||||
)
|
||||
|
||||
# Check that it's possible to preserve existing values by specifying limit=UINT64_MAX
|
||||
$smac <<- EOF
|
||||
{
|
||||
"method": "SetQos",
|
||||
"params": {
|
||||
"device_handle": "$device",
|
||||
"volume_id": "$(uuid2base64 $uuid)",
|
||||
"maximum": {
|
||||
"rw_iops": $limit_reserved,
|
||||
"rd_bandwidth": $limit_reserved,
|
||||
"rw_bandwidth": 6
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
diff <(rpc_cmd bdev_get_bdevs -b null0 | jq --sort-keys '.[].assigned_rate_limits') <(
|
||||
jq --sort-keys <<- EOF
|
||||
{
|
||||
"rw_ios_per_sec": 2000,
|
||||
"rw_mbytes_per_sec": 6,
|
||||
"r_mbytes_per_sec": 8,
|
||||
"w_mbytes_per_sec": 0
|
||||
}
|
||||
EOF
|
||||
)
|
||||
|
||||
# Check that specyfing an unsupported limit results in an error
|
||||
unsupported_max_limits=(rd_iops wr_iops)
|
||||
|
||||
for limit in "${unsupported_max_limits[@]}"; do
|
||||
NOT $smac <<- EOF
|
||||
{
|
||||
"method": "SetQos",
|
||||
"params": {
|
||||
"device_handle": "$device",
|
||||
"volume_id": "$(uuid2base64 $uuid)",
|
||||
"maximum": {
|
||||
"rw_iops": $limit_reserved,
|
||||
"rd_bandwidth": $limit_reserved,
|
||||
"rw_bandwidth": $limit_reserved,
|
||||
"$limit": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
done
|
||||
|
||||
# Check non-existing device handle/volume_id
|
||||
NOT $smac <<- EOF
|
||||
{
|
||||
"method": "SetQos",
|
||||
"params": {
|
||||
"device_handle": "${device}-invalid",
|
||||
"volume_id": "$(uuid2base64 $uuid)",
|
||||
"maximum": {
|
||||
"rw_iops": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
NOT $smac <<- EOF
|
||||
{
|
||||
"method": "SetQos",
|
||||
"params": {
|
||||
"device_handle": "$device",
|
||||
"volume_id": "$(uuid2base64 $(uuidgen))",
|
||||
"maximum": {
|
||||
"rw_iops": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
# Check that it's not possible to set limits without specyfing a volume/device
|
||||
NOT $smac <<- EOF
|
||||
{
|
||||
"method": "SetQos",
|
||||
"params": {
|
||||
"device_handle": "$device",
|
||||
"maximum": {
|
||||
"rw_iops": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
NOT $smac <<- EOF
|
||||
{
|
||||
"method": "SetQos",
|
||||
"params": {
|
||||
"volume_id": "$(uuid2base64 $uuid)",
|
||||
"maximum": {
|
||||
"rw_iops": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
# Make sure that none of the limits were changed
|
||||
diff <(rpc_cmd bdev_get_bdevs -b null0 | jq --sort-keys '.[].assigned_rate_limits') <(
|
||||
jq --sort-keys <<- EOF
|
||||
{
|
||||
"rw_ios_per_sec": 2000,
|
||||
"rw_mbytes_per_sec": 6,
|
||||
"r_mbytes_per_sec": 8,
|
||||
"w_mbytes_per_sec": 0
|
||||
}
|
||||
EOF
|
||||
)
|
||||
|
||||
trap - SIGINT SIGTERM EXIT
|
||||
cleanup
|
@ -11,3 +11,4 @@ run_test "sma_plugins" $testdir/plugins.sh
|
||||
run_test "sma_discovery" $testdir/discovery.sh
|
||||
run_test "sma_vhost" $testdir/vhost_blk.sh
|
||||
run_test "sma_crypto" $testdir/crypto.sh
|
||||
run_test "sma_qos" $testdir/qos.sh
|
||||
|
Loading…
Reference in New Issue
Block a user