diff mbox

[5/6] KVM test: Turn enospc test pre/post actions into infrastructure

Message ID 1295659850-29609-5-git-send-email-lmr@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Lucas Meneghel Rodrigues Jan. 22, 2011, 1:30 a.m. UTC
None
diff mbox

Patch

diff --git a/client/tests/kvm/kvm_preprocessing.py b/client/tests/kvm/kvm_preprocessing.py
index 081a13f..2713805 100644
--- a/client/tests/kvm/kvm_preprocessing.py
+++ b/client/tests/kvm/kvm_preprocessing.py
@@ -262,6 +262,10 @@  def preprocess(test, params, env):
         u = test_setup.UnattendedInstallConfig(test, params)
         u.setup()
 
+    if params.get("type") == "enospc":
+        e = test_setup.EnospcConfig(test, params)
+        e.setup()
+
     # Execute any pre_commands
     if params.get("pre_command"):
         process_command(test, params, env, params.get("pre_command"),
@@ -362,6 +366,10 @@  def postprocess(test, params, env):
         h = kvm_utils.HugePageConfig(params)
         h.cleanup()
 
+    if params.get("type") == "enospc":
+        e = test_setup.EnospcConfig(test, params)
+        e.cleanup()
+
     # Execute any post_commands
     if params.get("post_command"):
         process_command(test, params, env, params.get("post_command"),
diff --git a/client/tests/kvm/test_setup.py b/client/tests/kvm/test_setup.py
index b17c473..e906e18 100644
--- a/client/tests/kvm/test_setup.py
+++ b/client/tests/kvm/test_setup.py
@@ -2,7 +2,7 @@ 
 Library to perform pre/post test setup for KVM autotest.
 """
 import os, sys, shutil, tempfile, re, ConfigParser, glob, inspect, commands
-import logging
+import logging, time
 from autotest_lib.client.common_lib import error
 from autotest_lib.client.bin import utils
 
@@ -42,6 +42,19 @@  def clean_old_image(image):
         os.remove(image)
 
 
+def display_attributes(instance):
+    """
+    Inspects a given class instance attributes and displays them, convenient
+    for debugging.
+    """
+    logging.debug("Attributes set:")
+    for member in inspect.getmembers(instance):
+        name, value = member
+        attribute = getattr(instance, name)
+        if not (name.startswith("__") or callable(attribute) or not value):
+            logging.debug("    %s: %s", name, value)
+
+
 class Disk(object):
     """
     Abstract class for Disk objects, with the common methods implemented.
@@ -472,13 +485,7 @@  class UnattendedInstallConfig(object):
         Uses an appropriate strategy according to each install model.
         """
         logging.info("Starting unattended install setup")
-
-        logging.debug("Variables set:")
-        for member in inspect.getmembers(self):
-            name, value = member
-            attribute = getattr(self, name)
-            if not (name.startswith("__") or callable(attribute) or not value):
-                logging.debug("    %s: %s", name, value)
+        display_attributes(self)
 
         if self.unattended_file and (self.floppy or self.cdrom_unattended):
             self.setup_boot_disk()
@@ -593,3 +600,96 @@  class HugePageConfig(object):
             return
         utils.system("echo 0 > %s" % self.kernel_hp_file)
         logging.debug("Hugepage memory successfuly dealocated")
+
+
+class EnospcConfig(object):
+    """
+    Performs setup for the test enospc. This is a borg class, similar to a
+    singleton. The idea is to keep state in memory for when we call cleanup()
+    on postprocessing.
+    """
+    __shared_state = {}
+    def __init__(self, test, params):
+        self.__dict__ = self.__shared_state
+        root_dir = test.bindir
+        self.tmpdir = test.tmpdir
+        self.qemu_img_binary = params.get('qemu_img_binary')
+        if not os.path.isfile(self.qemu_img_binary):
+            self.qemu_img_binary = os.path.join(root_dir,
+                                                self.qemu_img_binary)
+        self.raw_file_path = os.path.join(self.tmpdir, 'enospc.raw')
+        # Here we're trying to choose fairly explanatory names so it's less
+        # likely that we run in conflict with other devices in the system
+        self.vgtest_name = params.get("vgtest_name")
+        self.lvtest_name = params.get("lvtest_name")
+        self.lvtest_device = "/dev/%s/%s" % (self.vgtest_name, self.lvtest_name)
+        image_dir = os.path.dirname(params.get("image_name"))
+        self.qcow_file_path = os.path.join(image_dir, 'enospc.qcow2')
+        try:
+            getattr(self, 'loopback')
+        except AttributeError:
+            self.loopback = ''
+
+
+    @error.context_aware
+    def setup(self):
+        logging.debug("Starting enospc setup")
+        error.context("performing enospc setup")
+        display_attributes(self)
+        # Double check if there aren't any leftovers
+        self.cleanup()
+        try:
+            utils.run("%s create -f raw %s 10G" %
+                      (self.qemu_img_binary, self.raw_file_path))
+            # Associate a loopback device with the raw file.
+            # Subject to race conditions, that's why try here to associate
+            # it with the raw file as quickly as possible
+            l_result = utils.run("losetup -f")
+            utils.run("losetup -f %s" % self.raw_file_path)
+            self.loopback = l_result.stdout.strip()
+            # Add the loopback device configured to the list of pvs
+            # recognized by LVM
+            utils.run("pvcreate %s" % self.loopback)
+            utils.run("vgcreate %s %s" % (self.vgtest_name, self.loopback))
+            # Create an lv inside the vg with starting size of 200M
+            utils.run("lvcreate -L 200M -n %s %s" %
+                      (self.lvtest_name, self.vgtest_name))
+            # Create a 10GB qcow2 image in the logical volume
+            utils.run("%s create -f qcow2 %s 10G" %
+                      (self.qemu_img_binary, self.lvtest_device))
+            # Let's symlink the logical volume with the image name that autotest
+            # expects this device to have
+            os.symlink(self.lvtest_device, self.qcow_file_path)
+        except Exception, e:
+            self.cleanup()
+            raise
+
+    @error.context_aware
+    def cleanup(self):
+        error.context("performing enospc cleanup")
+        if os.path.isfile(self.lvtest_device):
+            utils.run("fuser -k %s" % self.lvtest_device)
+            time.sleep(2)
+        l_result = utils.run("lvdisplay")
+        # Let's remove all volumes inside the volume group created
+        if self.lvtest_name in l_result.stdout:
+            utils.run("lvremove -f %s" % self.lvtest_device)
+        # Now, removing the volume group itself
+        v_result = utils.run("vgdisplay")
+        if self.vgtest_name in v_result.stdout:
+            utils.run("vgremove -f %s" % self.vgtest_name)
+        # Now, if we can, let's remove the physical volume from lvm list
+        if self.loopback:
+            p_result = utils.run("pvdisplay")
+            if self.loopback in p_result.stdout:
+                utils.run("pvremove -f %s" % self.loopback)
+        l_result = utils.run('losetup -a')
+        if self.loopback and (self.loopback in l_result.stdout):
+            try:
+                utils.run("losetup -d %s" % self.loopback)
+            except error.CmdError:
+                logging.error("Failed to liberate loopback %s", self.loopback)
+        if os.path.islink(self.qcow_file_path):
+            os.remove(self.qcow_file_path)
+        if os.path.isfile(self.raw_file_path):
+            os.remove(self.raw_file_path)
diff --git a/client/tests/kvm/tests/enospc.py b/client/tests/kvm/tests/enospc.py
index 6a149f9..3868cc4 100644
--- a/client/tests/kvm/tests/enospc.py
+++ b/client/tests/kvm/tests/enospc.py
@@ -24,6 +24,10 @@  def run_enospc(test, params, env):
     login_timeout = int(params.get("login_timeout", 360))
     session_serial = vm.wait_for_serial_login(timeout=login_timeout)
 
+    vgtest_name = params.get("vgtest_name")
+    lvtest_name = params.get("lvtest_name")
+    logical_volume = "/dev/%s/%s" % (vgtest_name, lvtest_name)
+
     drive_format = params.get("drive_format")
     if drive_format == "virtio":
         devname = "/dev/vdb"
@@ -54,7 +58,7 @@  def run_enospc(test, params, env):
                     logging.error(e)
             logging.info("Guest paused, extending Logical Volume size")
             try:
-                cmd_result = utils.run("lvextend -L +200M /dev/vgtest/lvtest")
+                cmd_result = utils.run("lvextend -L +200M %s" % logical_volume)
             except error.CmdError, e:
                 logging.debug(e.result_obj.stdout)
             vm.monitor.cmd("cont")
diff --git a/client/tests/kvm/tests_base.cfg.sample b/client/tests/kvm/tests_base.cfg.sample
index f90d551..bd2f720 100644
--- a/client/tests/kvm/tests_base.cfg.sample
+++ b/client/tests/kvm/tests_base.cfg.sample
@@ -601,9 +601,10 @@  variants:
         image_format_stg = qcow2
         image_boot_stg = no
         image_snapshot_stg = no
+        check_image_stg = no
+        vgtest_name = vg_kvm_test_enospc
+        lvtest_name = lv_kvm_test_enospc
         background_cmd = "nohup dd if=/dev/zero of=%s bs=1024 &"
-        pre_command += " scripts/enospc-pre.py;"
-        post_command += " scripts/enospc-post.py;"
         kill_vm = yes
 
     - qmp_basic: install setup unattended_install.cdrom