Commit 045152b2 authored by Konrad Sztyber's avatar Konrad Sztyber Committed by Tomasz Zawadzki
Browse files

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: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Change-Id: Ic715483e888a7219fd27367d527201d75e8b69a2
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14270


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent 89b81dc2
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -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
}

test/sma/qos.sh

0 → 100755
+238 −0
Original line number Diff line number Diff line
#!/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
+1 −0
Original line number Diff line number Diff line
@@ -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