[PATCH] KVM-test: Add a ENOSPC subtest

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Amos Kong <akong@xxxxxxxxxx>

KVM guest always pauses on NOSPACE error, this test
just repeatedly extend guest disk space and resume guest
from paused status.

Changes from v1:
- Use the most current KVM test API
- Use the autotest API for external commands execution
- Instead of chaining multiple shell commands as pre and
post commands, create proper pre and post scripts for the
test, as it is easier to figure out problems
- Instead of setting up /dev/loop0 hardcoded by default,
find the first available loop device before and use it.

Signed-off-by: Amos Kong <akong@xxxxxxxxxx>
---
 client/tests/kvm/scripts/enospc-post.py   |   74 +++++++++++++++++++++++++++++
 client/tests/kvm/scripts/enospc-pre.py    |   71 +++++++++++++++++++++++++++
 client/tests/kvm/tests/enospc.py          |   68 ++++++++++++++++++++++++++
 client/tests/kvm/tests_base.cfg.sample    |   14 +++++
 4 files changed, 227 insertions(+), 0 deletions(-)
 mode change 100644 => 100755 client/tests/kvm/scripts/bonding_setup.py
 mode change 100644 => 100755 client/tests/kvm/scripts/check_image.py
 create mode 100755 client/tests/kvm/scripts/enospc-post.py
 create mode 100755 client/tests/kvm/scripts/enospc-pre.py
 create mode 100644 client/tests/kvm/tests/enospc.py

diff --git a/client/tests/kvm/scripts/bonding_setup.py b/client/tests/kvm/scripts/bonding_setup.py
old mode 100644
new mode 100755
diff --git a/client/tests/kvm/scripts/check_image.py b/client/tests/kvm/scripts/check_image.py
old mode 100644
new mode 100755
diff --git a/client/tests/kvm/scripts/enospc-post.py b/client/tests/kvm/scripts/enospc-post.py
new file mode 100755
index 0000000..71cc383
--- /dev/null
+++ b/client/tests/kvm/scripts/enospc-post.py
@@ -0,0 +1,74 @@
+#!/usr/bin/python
+"""
+Simple script to setup enospc test environment
+"""
+import os, commands
+
+class SetupError(Exception):
+    """
+    Simple wrapper for the builtin Exception class.
+    """
+    pass
+
+
+def find_command(cmd):
+    """
+    Searches for a command on common paths, error if it can't find it.
+
+    @param cmd: Command to be found.
+    """
+    if os.path.exists(cmd):
+        return cmd
+    for dir in ["/usr/local/sbin", "/usr/local/bin",
+                "/usr/sbin", "/usr/bin", "/sbin", "/bin"]:
+        file = os.path.join(dir, cmd)
+        if os.path.exists(file):
+            return file
+    raise ValueError('Missing command: %s' % cmd)
+
+
+def run(cmd, info=None):
+    """
+    Run a command and throw an exception if it fails.
+    Optionally, you can provide additional contextual info.
+
+    @param cmd: Command string.
+    @param reason: Optional string that explains the context of the failure.
+
+    @raise: SetupError if command fails.
+    """
+    print "Running '%s'" % cmd
+    cmd_name = cmd.split(' ')[0]
+    find_command(cmd_name)
+    status, output = commands.getstatusoutput(cmd)
+    if status:
+        e_msg = ('Command %s failed.\nStatus:%s\nOutput:%s' %
+                 (cmd, status, output))
+        if info is not None:
+            e_msg += '\nAdditional Info:%s' % info
+        raise SetupError(e_msg)
+
+    return (status, output)
+
+
+if __name__ == "__main__":
+    qemu_img_binary = os.environ['KVM_TEST_qemu_img_binary']
+    if not os.path.isabs(qemu_img_binary):
+        qemu_img_binary = os.path.join(KVM_TEST_DIR, qemu_img_binary)
+    if not os.path.exists(qemu_img_binary):
+        raise SetupError('The qemu-img binary that is supposed to be used '
+                         '(%s) does not exist. Please verify your '
+                         'configuration' % qemu_img_binary)
+
+    run("lvremove -f vgtest")
+    status, output = run("losetup -a")
+    loopback_device = None
+    if output:
+        for line in output.splitlines():
+            device = line.split(":")[0]
+            if "/tmp/enospc.raw" in line:
+                loopback_device = device
+                break
+    if loopback_device is not None:
+        run("losetup -d %s" % loopback_device)
+    run("rm -rf /tmp/enospc.raw /tmp/kvm_autotest_root/images/enospc.qcow2")
diff --git a/client/tests/kvm/scripts/enospc-pre.py b/client/tests/kvm/scripts/enospc-pre.py
new file mode 100755
index 0000000..e56bdc0
--- /dev/null
+++ b/client/tests/kvm/scripts/enospc-pre.py
@@ -0,0 +1,71 @@
+#!/usr/bin/python
+"""
+Simple script to setup enospc test environment
+"""
+import os, commands
+
+class SetupError(Exception):
+    """
+    Simple wrapper for the builtin Exception class.
+    """
+    pass
+
+
+def find_command(cmd):
+    """
+    Searches for a command on common paths, error if it can't find it.
+
+    @param cmd: Command to be found.
+    """
+    if os.path.exists(cmd):
+        return cmd
+    for dir in ["/usr/local/sbin", "/usr/local/bin",
+                "/usr/sbin", "/usr/bin", "/sbin", "/bin"]:
+        file = os.path.join(dir, cmd)
+        if os.path.exists(file):
+            return file
+    raise ValueError('Missing command: %s' % cmd)
+
+
+def run(cmd, info=None):
+    """
+    Run a command and throw an exception if it fails.
+    Optionally, you can provide additional contextual info.
+
+    @param cmd: Command string.
+    @param reason: Optional string that explains the context of the failure.
+
+    @raise: SetupError if command fails.
+    """
+    print "Running '%s'" % cmd
+    cmd_name = cmd.split(' ')[0]
+    find_command(cmd_name)
+    status, output = commands.getstatusoutput(cmd)
+    if status:
+        e_msg = ('Command %s failed.\nStatus:%s\nOutput:%s' %
+                 (cmd, status, output))
+        if info is not None:
+            e_msg += '\nAdditional Info:%s' % info
+        raise SetupError(e_msg)
+
+    return (status, output.strip())
+
+
+if __name__ == "__main__":
+    qemu_img_binary = os.environ['KVM_TEST_qemu_img_binary']
+    if not os.path.isabs(qemu_img_binary):
+        qemu_img_binary = os.path.join(KVM_TEST_DIR, qemu_img_binary)
+    if not os.path.exists(qemu_img_binary):
+        raise SetupError('The qemu-img binary that is supposed to be used '
+                         '(%s) does not exist. Please verify your '
+                         'configuration' % qemu_img_binary)
+
+    run("%s create -f raw /tmp/enospc.raw 10G" % qemu_img_binary)
+    status, loopback_device = run("losetup -f")
+    run("losetup -f /tmp/enospc.raw")
+    run("pvcreate %s" % loopback_device)
+    run("vgcreate vgtest %s" % loopback_device)
+    run("lvcreate -L200M -n lvtest vgtest")
+    run("%s create -f qcow2 /dev/vgtest/lvtest 10G" % qemu_img_binary)
+    run("ln -s /dev/vgtest/lvtest /tmp/kvm_autotest_root/images/enospc.qcow2")
+
diff --git a/client/tests/kvm/tests/enospc.py b/client/tests/kvm/tests/enospc.py
new file mode 100644
index 0000000..21ea24e
--- /dev/null
+++ b/client/tests/kvm/tests/enospc.py
@@ -0,0 +1,68 @@
+import logging, commands, time, os
+from autotest_lib.client.common_lib import error
+from autotest_lib.client.bin import utils
+import kvm_test_utils
+
+
+def run_enospc(test, params, env):
+    """
+    ENOSPC test
+
+    1) Create a virtual disk on lvm
+    2) Boot up guest with two disks
+    3) Continually write data to second disk
+    4) Check images and extend second disk when no space
+    5) Continue paused guest
+    6) Repeat step 3~5 several times
+
+    @param test: KVM test object.
+    @param params: Dictionary with the test parameters.
+    @param env: Dictionary with test environment.
+    """
+    vm = env.get_vm(params["main_vm"])
+    vm.verify_alive()
+    login_timeout = int(params.get("login_timeout", 360))
+    session_serial = vm.wait_for_serial_login(timeout=login_timeout)
+
+    drive_format = params.get("drive_format")
+    if drive_format == "virtio":
+        devname = "/dev/vdb"
+    elif drive_format == "ide":
+        devname = "/dev/hdb"
+    elif drive_format == "scsi":
+        devname = "/dev/sdb"
+    cmd = params.get("background_cmd")
+    cmd %= devname
+    logging.info("Sending background cmd '%s'", cmd)
+    session_serial.sendline(cmd)
+
+    iterations = int(params.get("repeat_time", 40))
+    i = 0
+    pause_n = 0
+    while i < iterations:
+        status = vm.monitor.cmd("info status")
+        logging.debug(status)
+        if "paused" in status:
+            pause_n += 1
+            logging.info("Checking all images in use by the VM")
+            script_path = os.path.join(test.bindir, "scripts/check_image.py")
+            try:
+                cmd_result = utils.run('python %s' % script_path)
+            except error.CmdError, e:
+                logging.debug(e.result_obj.stdout)
+            logging.info("Guest paused, extending Logical Volume size")
+            try:
+                cmd_result = utils.run("lvextend -L +200M /dev/vgtest/lvtest")
+            except error.CmdError, e:
+                logging.debug(e.result_obj.stdout)
+            vm.monitor.cmd("cont")
+        time.sleep(10)
+        i += 1
+
+    if pause_n == 0:
+        raise error.TestFail("Guest didn't pause during loop")
+    else:
+        logging.info("Guest paused %s times from %s iterations",
+                     pause_n, iterations)
+
+    logging.info("Final %s" % vm.monitor.cmd("info status"))
diff --git a/client/tests/kvm/tests_base.cfg.sample b/client/tests/kvm/tests_base.cfg.sample
index 97db3e7..2157a15 100644
--- a/client/tests/kvm/tests_base.cfg.sample
+++ b/client/tests/kvm/tests_base.cfg.sample
@@ -591,6 +591,20 @@ variants:
             - fmt_raw:
                 image_format_stg = raw
 
+    - enospc:
+        type = enospc
+        images += " stg"
+        drive_werror = stop
+        drive_cache = none
+        image_name_stg = enospc
+        image_format_stg = qcow2
+        image_boot_stg = no
+        image_snapshot_stg = no
+        background_cmd = "nohup dd if=/dev/zero of=%s bs=1024 &"
+        pre_command += "qemu-img create -f raw /tmp/enospc.raw 10G && losetup /dev/loop0 /tmp/enospc.raw && pvcreate /dev/loop0 && vgcreate vgtest /dev/loop0 && lvcreate -L200M -n lvtest vgtest && qemu-img create -f qcow2 /dev/vgtest/lvtest 10G && ln -s /dev/vgtest/lvtest /tmp/kvm_autotest_root/images/enospc.qcow2;"
+        post_command += "lvremove -f vgtest; losetup -d /dev/loop0; rm -rf /tmp/enospc.raw /tmp/kvm_autotest_root/images/enospc.qcow2;"
+        kill_vm = yes
+
     - qmp_basic: install setup unattended_install.cdrom
         type = qmp_basic
 
-- 
1.7.3.4

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux