[sheepdog] [PATCH 4/5] tests/earthquake: testing framework and first test case

Hitoshi Mitake mitake.hitoshi at lab.ntt.co.jp
Thu Dec 25 10:51:24 CET 2014


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 <mitake.hitoshi at lab.ntt.co.jp>
---
 .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




More information about the sheepdog mailing list