This patch adds a slack testing framework for earthquake and first test case.
The test case revealed the problem related to snapshot. Current sheepdog creates a snapshot of existing VDI with the two command: 1. let the existing VDI snapshot 2. create a new writable VDI 1 and 2 cannot be done atomically (if we want to do it, we need a transaction mechanism). If tgtd detects the working VDI became snapshot and tires reload a new writable one before 2, it hangs and iSCSI initiator cannot do nothing (just wait timeout). Signed-off-by: Hitoshi Mitake <[email protected]> --- .gitignore | 2 + tests/earthquake/001/dog_compile_command.json | 1 + tests/earthquake/001/dog_inspection.json | 3 + tests/earthquake/001/execCmd.sh | 3 + tests/earthquake/001/execution.json | 36 ++++++++ tests/earthquake/001/inspection.json | 4 + tests/earthquake/001/test.sh | 114 ++++++++++++++++++++++++++ tests/earthquake/001/tgt_compile_command.json | 1 + tests/earthquake/001/tgt_inspection.json | 3 + tests/earthquake/inspection.py | 90 ++++++++++++++++++++ 10 files changed, 257 insertions(+) create mode 100644 tests/earthquake/001/dog_compile_command.json create mode 100644 tests/earthquake/001/dog_inspection.json create mode 100755 tests/earthquake/001/execCmd.sh create mode 100644 tests/earthquake/001/execution.json create mode 100644 tests/earthquake/001/inspection.json create mode 100644 tests/earthquake/001/test.sh create mode 100644 tests/earthquake/001/tgt_compile_command.json create mode 100644 tests/earthquake/001/tgt_inspection.json create mode 100644 tests/earthquake/inspection.py diff --git a/.gitignore b/.gitignore index 0bbb94a..881b40a 100644 --- a/.gitignore +++ b/.gitignore @@ -81,3 +81,5 @@ man/dog.8 man/sheepfs.8 *.deb + +compile_commands.json diff --git a/tests/earthquake/001/dog_compile_command.json b/tests/earthquake/001/dog_compile_command.json new file mode 100644 index 0000000..d56760d --- /dev/null +++ b/tests/earthquake/001/dog_compile_command.json @@ -0,0 +1 @@ +{"directory": "/home/mitake/github/sheepdog.git/tests/earthquake/../../dog", "command": "/usr/local/bin/clang -I/home/mitake/github/sheepdog.git/tests/earthquake/../../dog -I/home/mitake/github/sheepdog.git/tests/earthquake/../../include -o /home/mitake/github/sheepdog.git/tests/earthquake/../../dog/vdi.o -c /home/mitake/github/sheepdog.git/tests/earthquake/../../dog/vdi.c", "file": "vdi.c"} \ No newline at end of file diff --git a/tests/earthquake/001/dog_inspection.json b/tests/earthquake/001/dog_inspection.json new file mode 100644 index 0000000..5aa9924 --- /dev/null +++ b/tests/earthquake/001/dog_inspection.json @@ -0,0 +1,3 @@ +[ + {"type": "funcCall", "param": {"name": "dog_exec_req"}} +] diff --git a/tests/earthquake/001/execCmd.sh b/tests/earthquake/001/execCmd.sh new file mode 100755 index 0000000..a0fc797 --- /dev/null +++ b/tests/earthquake/001/execCmd.sh @@ -0,0 +1,3 @@ +#! /bin/bash + +dd if=/dev/zero of=mnt/junk bs=$((1024 * 1024)) count=16 oflag=sync diff --git a/tests/earthquake/001/execution.json b/tests/earthquake/001/execution.json new file mode 100644 index 0000000..27244e3 --- /dev/null +++ b/tests/earthquake/001/execution.json @@ -0,0 +1,36 @@ +{ + "globalFlags" : { "direct": 1 }, + + "processes" : [ + { "id": "dog-snapshot" } + ], + + "executionSequence" : [ + { "states": [ + { "processId": "dog-snapshot", "event": {"eventType": "funcCall", "eventParam": {"name": "dog_exec_req"} } } + ], + "action": { "type": "nop", "param" : {} } + }, + { "states": [ + { "processId": "dog-snapshot", "event": {"eventType": "funcCall", "eventParam": {"name": "dog_exec_req"} } } + ], + "action": { "type": "nop", "param" : {} } + }, + { "states": [ + { "processId": "dog-snapshot", "event": {"eventType": "funcCall", "eventParam": {"name": "dog_exec_req"} } } + ], + "action": { "type": "nop", "param" : {} } + }, + { "states": [ + { "processId": "dog-snapshot", "event": {"eventType": "funcCall", "eventParam": {"name": "dog_exec_req"} } } + ], + "action": { "type": "nop", "param" : {} } + }, + { "states": [ + { "processId": "dog-snapshot", "event": {"eventType": "funcCall", "eventParam": {"name": "dog_exec_req"} } } + ], + "action": { "type": "execCommand", "param" : {"command": "execCmd.sh"} }, + "comment": "This 4th dog_exec_req() is called by do_vdi_create()" + } + ] +} diff --git a/tests/earthquake/001/inspection.json b/tests/earthquake/001/inspection.json new file mode 100644 index 0000000..84d1152 --- /dev/null +++ b/tests/earthquake/001/inspection.json @@ -0,0 +1,4 @@ +[ + { "component": "dog", "file": "vdi.c", "rule": "dog_inspection.json" }, + { "component": "tgt", "file": "usr/bs_sheepdog.c", "rule": "tgt_inspection.json" } +] diff --git a/tests/earthquake/001/test.sh b/tests/earthquake/001/test.sh new file mode 100644 index 0000000..62267da --- /dev/null +++ b/tests/earthquake/001/test.sh @@ -0,0 +1,114 @@ +#! /bin/bash + +PATH=$PATH:`pwd` # for executing execCmd.sh + +echo $PATH + +TOP_DIR=/tmp/sheepdog/earthquake +TEST_DIR=$TOP_DIR/001 + +EARTHQUAKE=../earthquake.git/earthquake/earthquake + +pkill -9 earthquake + +# check iSCSI stuff + +_notrun() +{ + echo "$seq not run: $*" + status=0 + exit +} + +TGTD=../tgt.git/usr/tgtd +TGTADM=../tgt.git/usr/tgtadm +ISCSID=${ISCSID_PROG:-iscsiadm} +ISCSIADM=${ISCSIADM_PROG:-iscsiadm} + +SHEEP=../../../sheep/sheep +DOG=../../../dog/dog + +which $TGTD > /dev/null || _notrun "Require tgtd but it's not installed" +which $TGTADM > /dev/null || _notrun "Require tgtadm but it's not installed" +which $ISCSID > /dev/null || _notrun "Require iscsid but it's not installed" +which $ISCSIADM > /dev/null || _notrun "Require iscsiadm but it's not installed" + +$ISCSIADM -m node --logout &> /dev/null +pkill -9 $ISCSID > /dev/null +pkill -9 $ISCSIADM > /dev/null +pkill -9 tgtd > /dev/null +pkill -9 tgtadm > /dev/null + +ORIG_DEVFILES=orig_devfiles +LOGIN_DEVFILES=login_devfiles +DIFF_DEVFILES=diff_devfiles + +/bin/ls /dev/sd* > $ORIG_DEVFILES + +_setup_tgtd() +# $1: iscsi portal +# $2: VDI name for backing store +{ + $TGTD --iscsi portal=$1 + $TGTADM --lld iscsi --mode target --op new --tid 1 --targetname iqn.2014-12.org.sheepdog-project + $TGTADM --mode logicalunit --op new --tid 1 --lun 1 --bstype sheepdog --backing-store $2 + $TGTADM --mode target --op bind --tid 1 --initiator-address ALL +} + +PORTAL1=127.0.0.1:3260 + +pkill -9 sheep +rm -rf $TEST_DIR +mkdir -p $TEST_DIR + +export EQ_DISABLE=1 # earthquake should be turned off during preparation phase + +for i in `seq 0 2`; do + $SHEEP -l level=debug -c local -p 700$i -z $i $TEST_DIR/$i +done +sleep 1 + +VDINAME=test + +$DOG cluster format +$DOG vdi create $VDINAME 64M -P + +$EARTHQUAKE --launch-orchestrator --daemonize --log-file-path=orchestrator.log --execution-file-path=execution.json + +_setup_tgtd $PORTAL1 unix:$TEST_DIR/0/sock:$VDINAME + +$ISCSID + +$ISCSIADM -m discovery -t sendtargets -p $PORTAL1 +$ISCSIADM -m node --login +sleep 15 + +/bin/ls /dev/sd* > $LOGIN_DEVFILES + +comm -3 $LOGIN_DEVFILES $ORIG_DEVFILES > $DIFF_DEVFILES + +if [[ "1 $DIFF_DEVFILES" != `wc -l $DIFF_DEVFILES` ]] +then + _notrun "Device files were not created correctly" +fi + +MNTPOINT=`pwd`/mnt +if [ ! -d $MNTPOINT ] +then + mkdir $MNTPOINT +else + umount $MNTPOINT +fi + +DEVFILE=`cat $DIFF_DEVFILES` + +mkfs.ext4 -F $DEVFILE +mount $DEVFILE $MNTPOINT + +unset EQ_DISABLE + +export EQ_ENV_PROCESS_ID="dog-snapshot" +$DOG vdi snapshot $VDINAME + +umount $MNTPOINT +$ISCSIADM -m node --logout diff --git a/tests/earthquake/001/tgt_compile_command.json b/tests/earthquake/001/tgt_compile_command.json new file mode 100644 index 0000000..72d7a88 --- /dev/null +++ b/tests/earthquake/001/tgt_compile_command.json @@ -0,0 +1 @@ +{"directory": "/home/mitake/github/sheepdog.git/tests/earthquake/tgt.git", "command": "/usr/local/bin/clang -I/home/mitake/github/sheepdog.git/tests/earthquake/tgt.git -o /home/mitake/github/sheepdog.git/tests/earthquake/tgt.git/usr/bs_sheepdog.o -c /home/mitake/github/sheepdog.git/tests/earthquake/tgt.git/usr/bs_sheepdog.c", "file": "usr/bs_sheepdog.c"} \ No newline at end of file diff --git a/tests/earthquake/001/tgt_inspection.json b/tests/earthquake/001/tgt_inspection.json new file mode 100644 index 0000000..a350191 --- /dev/null +++ b/tests/earthquake/001/tgt_inspection.json @@ -0,0 +1,3 @@ +[ + {"type": "funcCall", "param": {"name": "reload_inode"}} +] diff --git a/tests/earthquake/inspection.py b/tests/earthquake/inspection.py new file mode 100644 index 0000000..9120991 --- /dev/null +++ b/tests/earthquake/inspection.py @@ -0,0 +1,90 @@ +#! /usr/bin/env python + +# Copyright (C) 2014 Nippon Telegraph and Telephone Corporation. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version +# 2 as published by the Free Software Foundation. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +import os, sys, subprocess +import json, re +import tempfile + +cwd = os.getcwd() + +inspector_bin = cwd + "/earthquake.git/inspector/c/llvm/ninja_build/bin/eq_c_inspector" + +dog_src_dir = cwd + "/../../dog" +sheep_src_dir = cwd + "/../../sheep" +sheepdog_include_dir = cwd + "/../../include" +tgt_src_dir = cwd + "/tgt.git" + +# TODO: check there's no changes with git + +def exec_inspection(src_path, src_dir, inspection_file_path): + print "inspecting source file: %s" % (src_path) + print "source directory: %s" % (src_dir) + print "a path of inspection rule file: %s" % (inspection_file_path) + + subproc_args = [] + subproc_args.append(inspector_bin) + subproc_args.append("-p") + subproc_args.append(src_dir) + subproc_args.append("-inspection-list-path=%s" % (inspection_file_path)) + subproc_args.append(src_path) + ret = subprocess.call(subproc_args) + if ret != 0: + print "inspection failed" + exit(1) + +def do_single_case(path): + inspection_info_path = cwd + '/' + path + "/inspection.json" + f = open(inspection_info_path) + s = f.read() + inspection_schema = json.loads(s) + + for component in inspection_schema: + c_name = component["component"] + src_dir = "" + if c_name == "dog": + src_dir = dog_src_dir + elif c_name == "sheep": + src_dir = sheep_src_dir + elif c_name == "tgt": + src_dir = tgt_src_dir + + src_path = src_dir + '/' + component["file"] + rule_path = path + '/' + component["rule"] + + # construct compile command json for libtooling + compile_command = {} + compile_command["directory"] = src_dir + compile_command["command"] = "/usr/local/bin/clang -I%s" % (src_dir) + if c_name == "dog" or c_name == "sheep": + compile_command["command"] += " -I%s" % (sheepdog_include_dir) + compile_command["command"] += " -o " + re.sub(r'([a-zA-Z_0-9]+).c', r'\1.o', src_path) + compile_command["command"] += " -c " + src_dir + '/' + component["file"] + compile_command["file"] = component["file"] + compile_command = [compile_command] + + compile_command_file = open(src_dir + '/' + "compile_commands.json", "w+") + compile_command_file.write(json.JSONEncoder().encode(compile_command)) + compile_command_file.close() + + exec_inspection(src_path, src_dir, rule_path) + +if len(sys.argv) != 2: + print "usage: %s <a number of test case>" % (sys.argv[0]) + exit(1) + +try: + case = int(sys.argv[1]) +except: + print "invalid number of case: %s" % (sys.argv[1]) + exit(1) + +do_single_case("%03d" % case) + -- 1.8.3.2 -- sheepdog mailing list [email protected] https://lists.wpkg.org/mailman/listinfo/sheepdog
