test: Add idle migration test for iscsi target.
Change-Id: I971b7b61f09902d12c63b160e8b0dd9a7eb9ef51 Signed-off-by: Cunyin Chang <cunyin.chang@intel.com>
This commit is contained in:
parent
b7a5c653e7
commit
3e83ccce9f
@ -97,7 +97,7 @@ if [ $(uname -s) = Linux ]; then
|
||||
time ./test/iscsi_tgt/fio/fio.sh
|
||||
time ./test/iscsi_tgt/reset/reset.sh
|
||||
time ./test/iscsi_tgt/rpc_config/rpc_config.sh
|
||||
|
||||
time ./test/iscsi_tgt/idle_migration/idle_migration.sh
|
||||
timing_exit iscsi_tgt
|
||||
fi
|
||||
|
||||
|
14
test/iscsi_tgt/idle_migration/build_configuration.sh
Executable file
14
test/iscsi_tgt/idle_migration/build_configuration.sh
Executable file
@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -xe
|
||||
rootdir=$(readlink -f $(dirname $0))/../../..
|
||||
|
||||
rpc_py=$rootdir/scripts/rpc.py
|
||||
|
||||
"$rpc_py" add_initiator_group 1 "ALL" "127.0.0.1/32"
|
||||
"$rpc_py" add_portal_group 1 '127.0.0.1:3260'
|
||||
|
||||
for i in $(seq 0 15); do
|
||||
"$rpc_py" construct_malloc_lun 32 512
|
||||
"$rpc_py" construct_target_node "Target$i" "Target_alias$i" "Malloc$i:0" "1:1" 64 1 0 0 0
|
||||
done
|
74
test/iscsi_tgt/idle_migration/connection_status.py
Executable file
74
test/iscsi_tgt/idle_migration/connection_status.py
Executable file
@ -0,0 +1,74 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from time import sleep
|
||||
from subprocess import check_output
|
||||
|
||||
rpc_py = os.path.dirname(os.path.realpath(__file__)) + '/../../../scripts/rpc.py'
|
||||
|
||||
class spdk_rpc(object):
|
||||
|
||||
def __init__(self, rpc_py):
|
||||
self.rpc_py = rpc_py
|
||||
|
||||
def __getattr__(self, name):
|
||||
def call(*args):
|
||||
cmd = "python {} {}".format(self.rpc_py, name)
|
||||
for arg in args:
|
||||
cmd += " {}".format(arg)
|
||||
return check_output(cmd, shell=True)
|
||||
return call
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
if (len(sys.argv) < 2) or (sys.argv[1] != "idle" and sys.argv[1] != "active"):
|
||||
print "must specify \"idle\" or \"active\""
|
||||
sys.exit(1)
|
||||
|
||||
rpc = spdk_rpc(rpc_py)
|
||||
|
||||
idle = 0
|
||||
active = 0
|
||||
|
||||
# capture connection state 10 times, 10 ms apart and keep a
|
||||
# a running count of how many connections were found idle
|
||||
# and active
|
||||
for i in range(10):
|
||||
|
||||
conns = json.loads(rpc.get_iscsi_connections())
|
||||
num_conns = len(conns)
|
||||
|
||||
for conn in conns:
|
||||
if conn['is_idle'] == 1:
|
||||
idle += 1
|
||||
else:
|
||||
active += 1
|
||||
|
||||
# sleep 10ms
|
||||
sleep(0.01)
|
||||
|
||||
active_pct = float(active) / (idle + active)
|
||||
|
||||
# even when there is no active I/O on a connection, there could be
|
||||
# a nopin/nopout being processed which causes a connection to
|
||||
# temporarily go active; also even when fio is actively running
|
||||
# there could be a brief period of time where the initiator has
|
||||
# no active I/O to some connection
|
||||
#
|
||||
# so do not enforce that *all* connections must be idle or active;
|
||||
# allow for some percentage of anomalies
|
||||
anomaly_pct_allowed = 0.10
|
||||
|
||||
print "active = {}".format(active)
|
||||
print "idle = {}".format(idle)
|
||||
print "active_pct = {}".format(active_pct)
|
||||
|
||||
if sys.argv[1] == "idle" and active_pct > anomaly_pct_allowed:
|
||||
sys.exit(1)
|
||||
|
||||
if sys.argv[1] == "active" and active_pct < (1.00 - anomaly_pct_allowed):
|
||||
sys.exit(1)
|
||||
|
||||
sys.exit(0)
|
64
test/iscsi_tgt/idle_migration/idle_migration.sh
Executable file
64
test/iscsi_tgt/idle_migration/idle_migration.sh
Executable file
@ -0,0 +1,64 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
testdir=$(readlink -f $(dirname $0))
|
||||
rootdir=$testdir/../../..
|
||||
source $rootdir/scripts/autotest_common.sh
|
||||
|
||||
if [ -z "$TARGET_IP" ]; then
|
||||
echo "TARGET_IP not defined in environment"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$INITIATOR_IP" ]; then
|
||||
echo "INITIATOR_IP not defined in environment"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
timing_enter idle_migration
|
||||
|
||||
# iSCSI target configuration
|
||||
PORT=3260
|
||||
RPC_PORT=5260
|
||||
|
||||
fio_py="python $rootdir/scripts/fio.py"
|
||||
|
||||
./app/iscsi_tgt/iscsi_tgt -c $testdir/iscsi.conf &
|
||||
pid=$!
|
||||
echo "Process pid: $pid"
|
||||
|
||||
trap "process_core; killprocess $pid; exit 1" SIGINT SIGTERM EXIT
|
||||
|
||||
waitforlisten $pid ${RPC_PORT}
|
||||
echo "iscsi_tgt is listening. Running tests..."
|
||||
|
||||
$testdir/build_configuration.sh
|
||||
|
||||
sleep 1
|
||||
|
||||
iscsiadm -m discovery -t sendtargets -p $TARGET_IP:$PORT
|
||||
iscsiadm -m node --login -p $TARGET_IP:$PORT
|
||||
|
||||
trap "iscsicleanup; process_core; killprocess $pid; exit 1" SIGINT SIGTERM EXIT
|
||||
|
||||
sleep 5
|
||||
|
||||
# verify that ids has connections in idle state
|
||||
python $testdir/connection_status.py idle
|
||||
|
||||
# start fio in background - while it is running, verify that connections are active
|
||||
$fio_py 4096 16 randrw 15 &
|
||||
fiopid=$!
|
||||
sleep 5
|
||||
python $testdir/connection_status.py active
|
||||
kill $fiopid
|
||||
wait $fiopid || true
|
||||
sleep 1
|
||||
|
||||
# verify again that ids has connections in idle state
|
||||
python $testdir/connection_status.py idle
|
||||
|
||||
trap - SIGINT SIGTERM EXIT
|
||||
|
||||
iscsicleanup
|
||||
killprocess $pid
|
||||
timing_exit idle_migration
|
14
test/iscsi_tgt/idle_migration/iscsi.conf
Normal file
14
test/iscsi_tgt/idle_migration/iscsi.conf
Normal file
@ -0,0 +1,14 @@
|
||||
[Global]
|
||||
ReactorMask 0xFFFF
|
||||
LogFacility "local7"
|
||||
|
||||
[iSCSI]
|
||||
NodeBase "iqn.2016-06.io.spdk"
|
||||
AuthFile /usr/local/etc/spdk/auth.conf
|
||||
Timeout 30
|
||||
DiscoveryAuthMethod Auto
|
||||
MaxSessions 64
|
||||
ImmediateData Yes
|
||||
ErrorRecoveryLevel 0
|
||||
[Rpc]
|
||||
Enable Yes
|
Loading…
Reference in New Issue
Block a user