All of lore.kernel.org
 help / color / mirror / Atom feed
From: Lukas Doktor <ldoktor@redhat.com>
To: autotest@test.kernel.org, kvm@vger.kernel.org,
	kvm-autotest@redhat.com, akong@redhat.com, lmr@redhat.com,
	ldoktor@redhat.com, jzupka@redhat.com
Subject: [PATCH] [kvm-autotest] tests.cgroup: Add TestFreezer
Date: Mon, 31 Oct 2011 10:30:33 +0100	[thread overview]
Message-ID: <1320053433-5190-2-git-send-email-ldoktor@redhat.com> (raw)
In-Reply-To: <1320053433-5190-1-git-send-email-ldoktor@redhat.com>

This subtest tests the 'freezer.state' cgroup functionality. It assignes the
virtual machine into freezer cgroup, schedule cpu-intensive work and verifies
the correct function in both states (frozen/thawed) during long and short
period of time.

 * Adds TestFreezer (freezer) test
 * Adds assign_vm_into_cgroup() function
 * Code cleanup

Signed-off-by: Lukas Doktor <ldoktor@redhat.com>
---
 client/tests/cgroup/cgroup_common.py |   16 +---
 client/tests/kvm/tests/cgroup.py     |  159 +++++++++++++++++++++++++++++++---
 2 files changed, 146 insertions(+), 29 deletions(-)

diff --git a/client/tests/cgroup/cgroup_common.py b/client/tests/cgroup/cgroup_common.py
index 0c86398..7d5daf2 100755
--- a/client/tests/cgroup/cgroup_common.py
+++ b/client/tests/cgroup/cgroup_common.py
@@ -6,25 +6,11 @@ Helpers for cgroup testing.
 @copyright: 2011 Red Hat Inc.
 @author: Lukas Doktor <ldoktor@redhat.com>
 """
-import logging, os, shutil, subprocess, time, traceback
+import logging, os, shutil, subprocess, time
 from tempfile import mkdtemp
 from autotest_lib.client.bin import utils
 from autotest_lib.client.common_lib import error
 
-def _traceback(name, exc_info):
-    """
-    Formats traceback into lines "name: line\nname: line"
-    @param name: desired line preposition
-    @param exc_info: sys.exc_info of the exception
-    @return: string which contains beautifully formatted exception
-    """
-    out = "\n"
-    for line in traceback.format_exception(exc_info[0], exc_info[1],
-                                           exc_info[2]):
-        out += "%s: %s" % (name, line)
-    return out
-
-
 class Cgroup(object):
     """
     Cgroup handling class.
diff --git a/client/tests/kvm/tests/cgroup.py b/client/tests/kvm/tests/cgroup.py
index f31ef0c..b482bce 100644
--- a/client/tests/kvm/tests/cgroup.py
+++ b/client/tests/kvm/tests/cgroup.py
@@ -40,6 +40,20 @@ def run_cgroup(test, params, env):
             raise error.TestFail("WM [%s] had to be recreated" % err[:-2])
 
 
+    def assign_vm_into_cgroup(vm, cgroup, pwd=None):
+        """
+        Assigns all threads of VM into cgroup
+        @param vm: desired VM
+        @param cgroup: cgroup handler
+        @param pwd: desired cgroup's pwd, cgroup index or None for root cgroup
+        """
+        if isinstance(pwd, int):
+            pwd = cgroup.cgroups[pwd]
+        cgroup.set_cgroup(vm.get_shell_pid(),pwd)
+        for pid in utils.get_children_pids(vm.get_shell_pid()):
+            cgroup.set_cgroup(int(pid), pwd)
+
+
     def distance(actual, reference):
         """
         Absolute value of relative distance of two numbers
@@ -118,10 +132,12 @@ def run_cgroup(test, params, env):
             utils.system("dd if=/dev/zero of=%s bs=1M count=8 &>/dev/null"
                          % (host_file.name))
             ret_file = host_file
-            logging.debug("add_file_drive: new file %s as drive", host_file.name)
+            logging.debug("add_file_drive: new file %s as drive",
+                          host_file.name)
         else:
             ret_file = None
-            logging.debug("add_file_drive: using file %s as drive", host_file.name)
+            logging.debug("add_file_drive: using file %s as drive",
+                          host_file.name)
 
         out = vm.monitor.cmd("pci_add auto storage file=%s,if=%s,snapshot=off,"
                              "cache=off" % (host_file.name, driver))
@@ -277,10 +293,7 @@ def run_cgroup(test, params, env):
             blkio.initialize(self.modules)
             for i in range(2):
                 pwd.append(blkio.mk_cgroup())
-                blkio.set_cgroup(self.vms[i].get_shell_pid(), pwd[i])
-                # Move all existing threads into cgroup
-                for tmp in utils.get_children_pids(self.vms[i].get_shell_pid()):
-                    blkio.set_cgroup(int(tmp), pwd[i])
+                assign_vm_into_cgroup(self.vms[i], blkio, pwd[i])
             self.blkio.set_property("blkio.weight", 100, pwd[0])
             self.blkio.set_property("blkio.weight", 1000, pwd[1])
 
@@ -475,9 +488,7 @@ def run_cgroup(test, params, env):
             for i in range(len(self.cgroups)):
                 logging.info("Limiting speed to: %s", (self.speeds[i]))
                 # Assign all threads of vm
-                self.cgroup.set_cgroup(self.vm.get_shell_pid(), self.cgroups[i])
-                for pid in utils.get_children_pids(self.vm.get_shell_pid()):
-                    self.cgroup.set_cgroup(int(pid), self.cgroups[i])
+                assign_vm_into_cgroup(self.vm, self.cgroup, self.cgroups[i])
 
                 # Standard test-time is 60s. If the slice time is less than 30s,
                 # test-time is prolonged to 30s per slice.
@@ -668,10 +679,7 @@ def run_cgroup(test, params, env):
 
             self.cgroup.initialize(self.modules)
             self.cgroup.mk_cgroup()
-            self.cgroup.set_cgroup(self.vm.get_shell_pid(),
-                                   self.cgroup.cgroups[0])
-            for pid in utils.get_children_pids(self.vm.get_shell_pid()):
-                self.cgroup.set_cgroup(int(pid), self.cgroup.cgroups[0])
+            assign_vm_into_cgroup(self.vm, self.cgroup, 0)
 
             # Test dictionary
             # Beware of persistence of some setting to another round!!!
@@ -765,6 +773,128 @@ def run_cgroup(test, params, env):
 
             return ("All restrictions enforced successfully.")
 
+
+    class TestFreezer:
+        """
+        Tests the freezer.state cgroup functionality. (it freezes the guest
+        and unfreeze it again)
+        """
+        def __init__(self, vms, modules):
+            """
+            Initialization
+            @param vms: list of vms
+            @param modules: initialized cgroup module class
+            """
+            self.vm = vms[0]      # Virt machines
+            self.modules = modules          # cgroup module handler
+            self.cgroup = Cgroup('freezer', '')   # cgroup blkio handler
+            self.files = None   # Temporary files (files of virt disks)
+            self.devices = None # Temporary virt devices
+
+
+        def cleanup(self):
+            err = ""
+            try:
+                self.cgroup.set_property('freezer.state', 'THAWED',
+                                         self.cgroup.cgroups[0])
+            except Exception, failure_detail:
+                err += "\nCan't unfreeze vm: %s" % failure_detail
+
+            try:
+                _ = self.vm.wait_for_login(timeout=30)
+                _.cmd('rm -f /tmp/freeze-lock')
+                _.close()
+            except Exception, failure_detail:
+                err += "\nCan't stop the stresses."
+
+            try:
+                del(self.cgroup)
+            except Exception, failure_detail:
+                err += "\nCan't remove Cgroup: %s" % failure_detail
+
+            if err:
+                logging.error("Some cleanup operations failed: %s", err)
+                raise error.TestFail("Some cleanup operations failed: %s" %
+                                      err)
+
+
+        def init(self):
+            """
+            Initialization
+             * prepares one cgroup and assign vm to it
+            """
+            self.cgroup.initialize(self.modules)
+            self.cgroup.mk_cgroup()
+            assign_vm_into_cgroup(self.vm, self.cgroup, 0)
+
+
+        def run(self):
+            """
+            Actual test:
+             * Freezes the guest and thaws it again couple of times
+             * verifies that guest is frozen and runs when expected
+            """
+            def get_stat(pid):
+                """
+                Gather statistics of pid+1st level subprocesses cpu usage
+                @param pid: PID of the desired process
+                @return: sum of all cpu-related values of 1st level subprocesses
+                """
+                out = None
+                for i in range(10):
+                    try:
+                        out = utils.system_output("cat /proc/%s/task/*/stat" %
+                                                   pid)
+                    except error.CmdError:
+                        out = None
+                    else:
+                        break
+                out = out.split('\n')
+                ret = 0
+                for i in out:
+                    ret += sum([int(_) for _ in i.split(' ')[13:17]])
+                return ret
+
+
+            session = self.vm.wait_for_serial_login(timeout=30)
+            session.cmd('touch /tmp/freeze-lock')
+            session.sendline('while [ -e /tmp/freeze-lock ]; do :; done')
+            cgroup = self.cgroup
+            pid = self.vm.get_pid()
+
+            for tsttime in [0.5,3,20]:
+                # Let it work for short, mid and long period of time
+                logging.info("FREEZING (%ss)", tsttime)
+                # Death line for freezing is 1s
+                cgroup.set_property('freezer.state', 'FROZEN',
+                                    cgroup.cgroups[0], check=False)
+                time.sleep(1)
+                _ = cgroup.get_property('freezer.state', cgroup.cgroups[0])
+                if 'FROZEN' not in _:
+                    raise error.TestFail("Couldn't freeze the VM: state %s" % _)
+                stat_ = get_stat(pid)
+                time.sleep(tsttime)
+                stat = get_stat(pid)
+                if stat != stat_:
+                    raise error.TestFail('Process was running in FROZEN state; '
+                                         'iteration %s, stat=%s, stat_=%s, '
+                                         'diff=%s' %
+                                          (i, stat, stat_, stat-stat_))
+                logging.info("THAWING (%ss)", tsttime)
+                self.cgroup.set_property('freezer.state', 'THAWED',
+                                         self.cgroup.cgroups[0])
+                stat_ = get_stat(pid)
+                time.sleep(tsttime)
+                stat = get_stat(pid)
+                if (stat - stat_) < (90*tsttime):
+                    raise error.TestFail('Process was not active in FROZEN'
+                                         'state; iteration %s, stat=%s, '
+                                         'stat_=%s, diff=%s' %
+                                          (i, stat, stat_, stat-stat_))
+
+            return ("Freezer works fine")
+
+
     # Setup
     # TODO: Add all new tests here
     tests = {"blkio_bandwidth_weigth_read"  : TestBlkioBandwidthWeigthRead,
@@ -774,9 +904,10 @@ def run_cgroup(test, params, env):
              "blkio_throttle_multiple_read" : TestBlkioThrottleMultipleRead,
              "blkio_throttle_multiple_write" : TestBlkioThrottleMultipleWrite,
              "devices_access"               : TestDevicesAccess,
+             "freezer"                      : TestFreezer,
             }
     modules = CgroupModules()
-    if (modules.init(['blkio', 'devices']) <= 0):
+    if (modules.init(['blkio', 'devices', 'freezer']) <= 0):
         raise error.TestFail('Can\'t mount any cgroup modules')
     # Add all vms
     vms = []
-- 
1.7.6.4

      reply	other threads:[~2011-10-31  9:30 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-10-31  9:30 [kvm-autotest] tests.cgroup: Add TestFreezer Lukas Doktor
2011-10-31  9:30 ` Lukas Doktor [this message]

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=1320053433-5190-2-git-send-email-ldoktor@redhat.com \
    --to=ldoktor@redhat.com \
    --cc=akong@redhat.com \
    --cc=autotest@test.kernel.org \
    --cc=jzupka@redhat.com \
    --cc=kvm-autotest@redhat.com \
    --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.