diff mbox

KVM test: Memory ballooning test for KVM guest v4

Message ID 1271362106-22663-1-git-send-email-lmr@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Lucas Meneghel Rodrigues April 15, 2010, 8:08 p.m. UTC
None
diff mbox

Patch

diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
index 047505a..3c643fd 100755
--- a/client/tests/kvm/kvm_vm.py
+++ b/client/tests/kvm/kvm_vm.py
@@ -916,15 +916,19 @@  class VM:
             session.close()
 
 
-    def get_memory_size(self):
+    def get_memory_size(self, cmd=None):
         """
-        Get memory size of the VM.
+        Get bootup memory size of the VM.
+
+        @param check_cmd: Command used to check memory. If not provided,
+                self.params.get("mem_chk_cmd") will be used.
         """
         session = self.remote_login()
         if not session:
             return None
         try:
-            cmd = self.params.get("mem_chk_cmd")
+            if not cmd:
+                cmd = self.params.get("mem_chk_cmd")
             s, mem_str = session.get_command_status_output(cmd)
             if s != 0:
                 return None
@@ -941,3 +945,11 @@  class VM:
             return int(mem_size)
         finally:
             session.close()
+
+
+    def get_current_memory_size(self):
+        """
+        Get current memory size of the VM, rather than bootup memory.
+        """
+        cmd = self.params.get("mem_chk_cur_cmd")
+        return self.get_memory_size(cmd)
diff --git a/client/tests/kvm/tests/balloon_check.py b/client/tests/kvm/tests/balloon_check.py
new file mode 100644
index 0000000..2496785
--- /dev/null
+++ b/client/tests/kvm/tests/balloon_check.py
@@ -0,0 +1,102 @@ 
+import re, string, logging, random, time
+from autotest_lib.client.common_lib import error
+import kvm_test_utils, kvm_utils
+
+def run_balloon_check(test, params, env):
+    """
+    Check Memory ballooning:
+    1) Boot a guest
+    2) Change the memory between 60% to 95% of memory of guest using ballooning
+    3) check memory info
+
+    @param test: kvm test object
+    @param params: Dictionary with the test parameters
+    @param env: Dictionary with test environment.
+    """
+    def check_ballooned_memory():
+        """
+        Verify the actual memory reported by monitor command info balloon. If
+        the operation failed, increase the failure counter.
+
+        @return: Number of failures occurred during operation.
+        """
+        fail = 0
+        status, output = vm.send_monitor_cmd("info balloon")
+        if status != 0:
+            logging.error("qemu monitor command failed: info balloon")
+            fail += 1
+            return 0
+        return int(re.findall("\d+", output)[0]), fail
+
+
+    def balloon_memory(new_mem):
+        """
+        Baloon memory to new_mem and verifies on both qemu monitor and
+        guest OS if change worked.
+
+        @param new_mem: New desired memory.
+        @return: Number of failures occurred during operation.
+        """
+        fail = 0
+        logging.info("Changing VM memory to %s", new_mem)
+        vm.send_monitor_cmd("balloon %s" % new_mem)
+        time.sleep(20)
+
+        ballooned_mem, cfail = check_ballooned_memory()
+        fail += cfail
+        # Verify whether the VM machine reports the correct new memory
+        if ballooned_mem != new_mem:
+            logging.error("Memory ballooning failed while changing memory "
+                          "from %s to %s", actual_mem, new_mem)
+            fail += 1
+
+        # Verify whether the guest OS reports the correct new memory
+        current_mem_guest = vm.get_current_memory_size()
+
+        # Current memory figures will allways be a little smaller than new
+        # memory. If they are higher, ballooning failed on guest perspective
+        if current_mem_guest > new_mem:
+            logging.error("Guest OS reports %s of RAM, but new ballooned RAM "
+                          "is %s", current_mem_guest, new_mem)
+            fail += 1
+        return fail
+
+
+    fail = 0
+    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
+    session = kvm_test_utils.wait_for_login(vm)
+
+    # Upper limit that we can raise the memory
+    vm_assigned_mem = int(params.get("mem"))
+
+    # Check memory size
+    logging.info("Memory check")
+    boot_mem = vm.get_memory_size()
+    if boot_mem != vm_assigned_mem:
+        logging.error("Memory size mismatch:")
+        logging.error("    Assigned to VM: %s" % expected_mem)
+        logging.error("    Reported by guest OS at boot: %s" % actual_mem)
+        fail += 1
+
+    # Check if info balloon works or not
+    current_vm_mem, cfail = check_ballooned_memory()
+    if cfail:
+        fail += cfail
+    if current_vm_mem:
+        logging.info("Current VM memory according to ballooner: %s",
+                     current_vm_mem)
+
+    # Reduce memory to random size between 60% to 95% of max memory size
+    percent = random.uniform(0.6, 0.95)
+    new_mem = int(percent * vm_assigned_mem)
+    fail += balloon_memory(new_mem)
+
+    # Reset memory value to original memory assigned on qemu. This will ensure
+    # we won't trigger guest OOM killer while running multiple iterations
+    fail += balloon_memory(vm_assigned_mem)
+
+    # Close stablished session
+    session.close()
+    # Check if any failures happen during the whole test
+    if fail != 0:
+        raise error.TestFail("Memory ballooning test failed")
diff --git a/client/tests/kvm/tests_base.cfg.sample b/client/tests/kvm/tests_base.cfg.sample
index 4baa1dc..e77201b 100644
--- a/client/tests/kvm/tests_base.cfg.sample
+++ b/client/tests/kvm/tests_base.cfg.sample
@@ -171,6 +171,11 @@  variants:
                 drift_threshold = 10
                 drift_threshold_single = 3
 
+    - balloon_check:  install setup unattended_install
+        type = balloon_check
+        extra_params += "-balloon virtio"
+        iterations = 5
+
     - stress_boot:  install setup unattended_install
         type = stress_boot
         max_vms = 5    
@@ -381,6 +386,7 @@  variants:
         file_transfer_client = scp
         file_transfer_port = 22
         mem_chk_cmd = dmidecode -t 17 | awk -F: '/Size/ {print $2}'
+        mem_chk_cur_cmd = grep MemTotal /proc/meminfo
         cpu_chk_cmd = grep -c processor /proc/cpuinfo
         timedrift:
             extra_params += " -no-kvm-pit-reinjection"
@@ -777,6 +783,7 @@  variants:
 
         cpu_chk_cmd = echo %NUMBER_OF_PROCESSORS%
         mem_chk_cmd = wmic memphysical
+        mem_chk_cur_cmd = wmic memphysical
 
         unattended_install:
             timeout = 7200
@@ -1179,7 +1186,7 @@  variants:
         image_boot=yes
 
 
-virtio|virtio_blk|e1000:
+virtio|virtio_blk|e1000|balloon_check:
     only Fedora.11 Fedora.12 Win2008 WinVista Win7 openSUSE-11 Ubuntu-8.10-server