[PATCH] KVM test: Add a subtest iofuzz

2010-05-06 Thread Lucas Meneghel Rodrigues
From: Jason Wang jasow...@redhat.com

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 welcome.

Signed-off-by: Jason Wang jasow...@redhat.com
---
 client/tests/kvm/tests/iofuzz.py   |  138 
 client/tests/kvm/tests_base.cfg.sample |2 +
 2 files changed, 140 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 000..5bd1b8e
--- /dev/null
+++ b/client/tests/kvm/tests/iofuzz.py
@@ -0,0 +1,138 @@
+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
+2) Enumerate all IO port ranges through /proc/ioports
+3) On each port of the range:
+* Read it
+* Write 0 to it
+* Write a random value to a random port on a random order
+
+If the guest SSH session hangs, the test detects the hang and the guest
+is then rebooted. The test fails if we detect the qemu process to terminate
+while executing the process.
+
+@param test: kvm test object
+@param params: Dictionary with the test parameters
+@param env: Dictionary with test environment.
+
+def outb(session, port, data):
+
+Write data to a given port.
+
+@param session: SSH session stablished to a VM
+@param port: Port where we'll write the data
+@param data: Integer value that will be written on the port. This
+value will be converted to octal before its written.
+
+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 is None:
+logging.debug(Command did not return)
+if s != 0:
+logging.debug(Command returned status %s, s)
+
+
+def inb(session, port):
+
+Read from a given port.
+
+@param session: SSH session stablished to a VM
+@param port: Port where we'll read data
+
+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 is None:
+logging.debug(Command did not return)
+if s != 0:
+logging.debug(Command returned status %s, s)
+
+
+def fuzz(session, inst_list):
+
+Executes a series of read/write/randwrite instructions.
+
+If the guest SSH session hangs, an attempt to relogin will be made.
+If it fails, the guest will be reset. If during the process the VM
+process abnormally ends, the test fails.
+
+@param inst_list: List of instructions that will be executed.
+@raise error.TestFail: If the VM process dies in the middle of the
+fuzzing procedure.
+
+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 has quit abnormally during %s,
+ (op, operand))
+
+
+boot_timeout = float(params.get(boot_timeout, 240))
+vm = kvm_test_utils.get_living_vm(env, 

Re: [Autotest] [PATCH] KVM test: Add a subtest iofuzz

2010-05-06 Thread Lucas Meneghel Rodrigues
On Wed, Apr 7, 2010 at 8:55 AM, Jason Wang jasow...@redhat.com wrote:
 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.

Hi Jason, nice test! I have made some little changes, re-submitted and
will commit. Thanks!

 Signed-off-by: Jason Wang jasow...@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 000..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)):
 +            

[PATCH] KVM test: Add a subtest iofuzz

2010-04-07 Thread Jason Wang
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 jasow...@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 000..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