All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jason Wang <jasowang@redhat.com>
To: autotest@test.kernel.org, lmr@redhat.com, kvm@vger.kernel.org
Subject: [PATCH] KVM test: Add a subtest iofuzz
Date: Wed, 07 Apr 2010 19:55:09 +0800	[thread overview]
Message-ID: <20100407115509.14877.87055.stgit@localhost.localdomain> (raw)

The design of iofuzz is simple: it just generate random I/O port
activity inside the virtual machine. The correctness of the device
emulation may be verified through this test.

As the instrcutions are randomly generated, guest may enter the wrong
state. The test solve this issue by detect the hang and restart the
virtual machine.

The test duration could also be adjusted through the "fuzz_count". And
the parameter "skip_devices" is used to specified the devices which
should not be used to do the fuzzing.

For current version, every activity were logged and the commnad was
sent through a seesion between host and guest. Through this method may
slow down the whole test but it works well. The enumeration was done
through /proc/ioports and the scenario of avtivity is not aggressive.

Suggestions are welcomed.

Signed-off-by: Jason Wang <jasowang@redhat.com>
---
 client/tests/kvm/tests/iofuzz.py       |   97 ++++++++++++++++++++++++++++++++
 client/tests/kvm/tests_base.cfg.sample |    2 +
 2 files changed, 99 insertions(+), 0 deletions(-)
 create mode 100644 client/tests/kvm/tests/iofuzz.py

diff --git a/client/tests/kvm/tests/iofuzz.py b/client/tests/kvm/tests/iofuzz.py
new file mode 100644
index 0000000..c2f22af
--- /dev/null
+++ b/client/tests/kvm/tests/iofuzz.py
@@ -0,0 +1,97 @@
+import logging, time, re, random
+from autotest_lib.client.common_lib import error
+import kvm_subprocess, kvm_test_utils, kvm_utils
+
+
+def run_iofuzz(test, params, env):
+    """
+    KVM iofuzz test:
+    1) Log into a guest
+
+    @param test: kvm test object
+    @param params: Dictionary with the test parameters
+    @param env: Dictionary with test environment.
+    """
+    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
+    session = kvm_test_utils.wait_for_login(vm, 0,
+                                         float(params.get("boot_timeout", 240)),
+                                         0, 2)
+
+    def outb(session, port, data):
+        logging.debug("outb(0x%x,0x%x)" % (port, data))
+        outb_cmd = "echo -e '\\%s' | dd of=/dev/port seek=%d bs=1 count=1" % \
+                   (oct(data), port)
+        s, o = session.get_command_status_output(outb_cmd)
+        if s != 0:
+            logging.debug("None zero value returned")
+
+    def inb(session, port):
+        logging.debug("inb(0x%x)" % port)
+        inb_cmd = "dd if=/dev/port seek=%d of=/dev/null bs=1 count=1" % port
+        s, o = session.get_command_status_output(inb_cmd)
+        if s != 0:
+            logging.debug("None zero value returned")
+
+    def fuzz(session, inst_list):
+        for (op, operand) in inst_list:
+            if op == "read":
+                inb(session, operand[0])
+            elif op =="write":
+                outb(session, operand[0], operand[1])
+            else:
+                raise error.TestError("Unknown command %s" % op)
+
+            if not session.is_responsive():
+                logging.debug("Session is not responsive")
+                if vm.process.is_alive():
+                    logging.debug("VM is alive, try to re-login")
+                    try:
+                        session = kvm_test_utils.wait_for_login(vm, 0, 10, 0, 2)
+                    except:
+                        logging.debug("Could not re-login, reboot the guest")
+                        session = kvm_test_utils.reboot(vm, session,
+                                                        method = "system_reset")
+                else:
+                    raise error.TestFail("VM have quit abnormally")
+    try:
+        ports = {}
+        ran = random.SystemRandom()
+        
+        logging.info("Enumerate the device through /proc/ioports")
+        ioports = session.get_command_output("cat /proc/ioports")
+        logging.debug(ioports)
+        devices = re.findall("(\w+)-(\w+)\ : (.*)", ioports)
+
+        skip_devices = params.get("skip_devices","")
+        fuzz_count = int(params.get("fuzz_count", 10))
+        
+        for (beg, end, name) in devices:
+            ports[(int(beg, base=16), int(end, base=16))] = name.strip()
+
+        for (beg, end) in ports.keys():
+
+            name = ports[(beg, end)]
+            if name in skip_devices:
+                logging.info("Skipping %s" % name)
+                continue
+            
+            logging.info("Fuzzing %s at 0x%x-0x%x" % (name, beg, end))
+            inst = []
+                     
+            # Read all ports
+            for port in range(beg, end+1):
+                inst.append(("read", [port]))
+                
+            # Outb with zero
+            for port in range(beg, end+1):
+                inst.append(("write", [port, 0]))
+                pass
+
+            # Random fuzzing 
+            for seq in range(fuzz_count * (end-beg+1)):
+                inst.append(("write", [ran.randint(beg, end), ran.randint(0,255)]))
+
+            fuzz(session, inst)
+                        
+    finally:
+        session.close()
diff --git a/client/tests/kvm/tests_base.cfg.sample b/client/tests/kvm/tests_base.cfg.sample
index d162cf8..01080bb 100644
--- a/client/tests/kvm/tests_base.cfg.sample
+++ b/client/tests/kvm/tests_base.cfg.sample
@@ -294,6 +294,8 @@ variants:
                 ksm_mode = "serial"
             - ksm_parallel:
                 ksm_mode = "parallel"
+    - iofuzz:
+        type = iofuzz
 
     # system_powerdown, system_reset and shutdown *must* be the last ones
     # defined (in this order), since the effect of such tests can leave


             reply	other threads:[~2010-04-07 11:50 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-04-07 11:55 Jason Wang [this message]
2010-05-06 23:18 ` [Autotest] [PATCH] KVM test: Add a subtest iofuzz Lucas Meneghel Rodrigues
2010-05-06 23:13 Lucas Meneghel Rodrigues

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20100407115509.14877.87055.stgit@localhost.localdomain \
    --to=jasowang@redhat.com \
    --cc=autotest@test.kernel.org \
    --cc=kvm@vger.kernel.org \
    --cc=lmr@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.