Re: [Autotest] [PATCH] [NEW] cgroup test * general smoke_test + module dependend subtests (memory test included) * library for future use in other tests (kvm)

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

 



On Tue, Aug 2, 2011 at 11:50 AM, Lukas Doktor <ldoktor@xxxxxxxxxx> wrote:
> From: root <root@xxxxxxxxxxxxxxxxxxxxxxxxxx>

Ok Lukas, give me some time to go through this, I have started this
but will probably take a while to finish.

Cheers!

> cgroup.py:
> * structure for different cgroup subtests
> * contains basic "cgroup-memory" test
>
> cgroup_common.py:
> * library for cgroup handling (intended to be used from kvm test in the future)
> * universal smoke_test for every module
>
> cgroup_client.py:
> * application which is executed and controled using cgroups
> * contains smoke, memory, cpu and devices tests which were manually tested to break cgroup rules and will be used in the cgroup.py subtests
>
> Signed-off-by: Lukas Doktor <ldoktor@xxxxxxxxxx>
> ---
>  client/tests/cgroup/cgroup.py        |  236 ++++++++++++++++++++++++++++++++++
>  client/tests/cgroup/cgroup_client.py |  116 +++++++++++++++++
>  client/tests/cgroup/control          |   12 ++
>  3 files changed, 364 insertions(+), 0 deletions(-)
>  create mode 100755 client/tests/cgroup/cgroup.py
>  create mode 100755 client/tests/cgroup/cgroup_client.py
>  create mode 100644 client/tests/cgroup/control
>
> diff --git a/client/tests/cgroup/cgroup.py b/client/tests/cgroup/cgroup.py
> new file mode 100755
> index 0000000..d043d65
> --- /dev/null
> +++ b/client/tests/cgroup/cgroup.py
> @@ -0,0 +1,236 @@
> +from autotest_lib.client.bin import test
> +from autotest_lib.client.common_lib import error
> +import os, logging
> +import time
> +from cgroup_common import Cgroup as CG
> +from cgroup_common import CgroupModules
> +
> +class cgroup(test.test):
> +    """
> +    Tests the cgroup functionalities
> +    """
> +    version = 1
> +    _client = ""
> +    modules = CgroupModules()
> +
> +
> +    def run_once(self):
> +        """
> +           Try to access different resources which are restricted by cgroup.
> +        """
> +        logging.info('Start')
> +
> +        err = ""
> +        # Run available tests
> +        for i in ['memory']:
> +            try:
> +                if self.modules.get_pwd(i):
> +                    if (eval ("self.test_%s()" % i)):
> +                        err += "%s, " % i
> +                else:
> +                    logging.error("CGROUP: Skipping test_%s, module not "
> +                                  "available/mounted", i)
> +                    err += "%s, " % i
> +            except Exception, inst:
> +                logging.error("CGROUP: test_%s fatal failure: %s", i, inst)
> +                err += "%s, " % i
> +
> +        if err:
> +            raise error.TestFail('CGROUP: Some subtests failed (%s)' % err[:-2])
> +
> +
> +    def setup(self):
> +        """
> +        Setup
> +        """
> +        logging.info('Setup')
> +
> +        self._client = os.path.join(self.bindir, "cgroup_client.py")
> +
> +        _modules = ['cpuset', 'ns', 'cpu', 'cpuacct', 'memory', 'devices',
> +                    'freezer', 'net_cls', 'blkio']
> +        if (self.modules.init(_modules) <= 0):
> +            raise error.TestFail('Can\'t mount any cgroup modules')
> +
> +
> +    def cleanup(self):
> +        """
> +        Unmount all cgroups and remove directories
> +        """
> +        logging.info('Cleanup')
> +        self.modules.cleanup()
> +
> +
> +    #############################
> +    # TESTS
> +    #############################
> +    def test_memory(self):
> +        """
> +        Memory test
> +        """
> +        # Preparation
> +        logging.info("Entering 'test_memory'")
> +        item = CG('memory', self._client)
> +        if item.initialize(self.modules):
> +            logging.error("test_memory: cgroup init failed")
> +            return -1
> +
> +        if item.smoke_test():
> +            logging.error("test_memory: smoke_test failed")
> +            return -1
> +
> +        pwd = item.mk_cgroup()
> +        if pwd == None:
> +            logging.error("test_memory: Can't create cgroup")
> +            return -1
> +
> +        logging.debug("test_memory: Memory filling test")
> +
> +        f = open('/proc/meminfo','r')
> +        mem = f.readline()
> +        while not mem.startswith("MemFree"):
> +            mem = f.readline()
> +        # Use only 1G or max of the free memory
> +        mem = min(int(mem.split()[1])/1024, 1024)
> +        mem = max(mem, 100) # at least 100M
> +        if (item.get_property("memory.memsw.limit_in_bytes", supress=True)
> +                                                                    != None):
> +            memsw = True
> +            # Clear swap
> +            os.system("swapoff -a")
> +            os.system("swapon -a")
> +            f.seek(0)
> +            swap = f.readline()
> +            while not swap.startswith("SwapTotal"):
> +                swap = f.readline()
> +            swap = int(swap.split()[1])/1024
> +            if swap < mem / 2:
> +                logging.error("Not enough swap memory to test 'memsw'")
> +                memsw = False
> +        else:
> +            # Doesn't support swap+memory limitation, disable swap
> +            logging.info("'memsw' not supported")
> +            os.system("swapoff -a")
> +            memsw = False
> +        logging.debug("test_memory: Initializition passed")
> +
> +        ################################################
> +        # Fill the memory without cgroup limitation
> +        # Should pass
> +        ################################################
> +        ps = item.test("memfill %d" % mem)
> +        ps.stdin.write('\n')
> +        i = 0
> +        while ps.poll() == None:
> +            if i > 60:
> +                break
> +            i += 1
> +            time.sleep(1)
> +        if i > 60:
> +            logging.error("test_memory: Memory filling failed (WO cgroup)")
> +            ps.terminate()
> +            return -1
> +        if not ps.stdout.readlines()[-1].startswith("PASS"):
> +            logging.error("test_memory: Unsuccessful memory filling "
> +                          "(WO cgroup)")
> +            return -1
> +        logging.debug("test_memory: Memfill WO cgroup passed")
> +
> +        ################################################
> +        # Fill the memory with 1/2 memory limit
> +        # memsw: should swap out part of the process and pass
> +        # WO memsw: should fail (SIGKILL)
> +        ################################################
> +        ps = item.test("memfill %d" % mem)
> +        if item.set_cgroup(ps.pid, pwd):
> +            logging.error("test_memory: Could not set cgroup")
> +            return -1
> +        if item.set_property("memory.limit_in_bytes", (1024*1024*mem/2), pwd):
> +            logging.error("test_memory: Could not set mem limit (mem)")
> +            return -1
> +        ps.stdin.write('\n')
> +        i = 0
> +        while ps.poll() == None:
> +            if i > 60:
> +                break
> +            i += 1
> +            time.sleep(1)
> +        if i > 60:
> +            logging.error("test_memory: Memory filling failed (mem)")
> +            ps.terminate()
> +            return -1
> +        out = ps.stdout.readlines()
> +        if len(out) < 2:
> +            logging.error("test_memory: Process failed; output:\n%s", out)
> +            return -1
> +        if memsw:
> +            if not out[-1].startswith("PASS"):
> +                logging.error("test_memory: Unsuccessful memory filling (mem)")
> +                logging.error("test_memory: cgroup_client.py returned %d; "
> +                              "output:\n%s", ps.poll(), out)
> +                return -1
> +        else:
> +            if out[-1].startswith("PASS"):
> +                logging.error("test_memory: Unexpected memory filling (mem)")
> +                return -1
> +            else:
> +                filled = int(out[-2].split()[1][:-1])
> +                if mem/2 > 1.5*filled:
> +                    logging.error("test_memory: Limit = %dM, Filled = %dM (+ "
> +                               "python overhead upto 1/3 (mem)", mem/2, filled)
> +                else:
> +                    logging.debug("test_memory: Limit = %dM, Filled = %dM (+ "
> +                               "python overhead upto 1/3 (mem)", mem/2, filled)
> +        logging.debug("test_memory: Memfill mem only cgroup passed")
> +
> +        ################################################
> +        # Fill the memory with 1/2 memory+swap limit
> +        # Should fail
> +        ################################################
> +        if memsw:
> +            ps = item.test("memfill %d" % mem)
> +            if item.set_cgroup(ps.pid, pwd):
> +                logging.error("test_memory: Could not set cgroup (memsw)")
> +                return -1
> +            if item.set_property("memory.memsw.limit_in_bytes",
> +                                 (1024*1024*mem/2), pwd):
> +                logging.error("test_memory: Could not set mem limit (memsw)")
> +                return -1
> +            ps.stdin.write('\n')
> +            i = 0
> +            while ps.poll() == None:
> +                if i > 60:
> +                    break
> +                i += 1
> +                time.sleep(1)
> +            if i > 60:
> +                logging.error("test_memory: Memory filling failed (mem)")
> +                ps.terminate()
> +                return -1
> +            out = ps.stdout.readlines()
> +            if len(out) < 2:
> +                logging.error("test_memory: Process failed; output:\n%s", out)
> +                return -1
> +            if out[-1].startswith("PASS"):
> +                logging.error("test_memory: Unexpected memory filling (memsw)",
> +                              mem)
> +                return -1
> +            else:
> +                filled = int(out[-2].split()[1][:-1])
> +                if mem/2 > 1.5*filled:
> +                    logging.error("test_memory: Limit = %dM, Filled = %dM (+ "
> +                              "python overhead upto 1/3 (memsw)", mem/2, filled)
> +                else:
> +                    logging.debug("test_memory: Limit = %dM, Filled = %dM (+ "
> +                              "python overhead upto 1/3 (memsw)", mem/2, filled)
> +            logging.debug("test_memory: Memfill mem+swap cgroup passed")
> +
> +        # cleanup
> +        if item.rm_cgroup(pwd):
> +            logging.error("test_memory: Can't remove cgroup directory")
> +            return -1
> +        os.system("swapon -a")
> +        logging.debug("test_memory: Cleanup passed")
> +
> +        logging.info("Leaving 'test_memory': PASSED")
> +        return 0
> diff --git a/client/tests/cgroup/cgroup_client.py b/client/tests/cgroup/cgroup_client.py
> new file mode 100755
> index 0000000..ff098ef
> --- /dev/null
> +++ b/client/tests/cgroup/cgroup_client.py
> @@ -0,0 +1,116 @@
> +#!/usr/bin/python
> +# -*- coding: utf-8 -*-
> +"""
> +Interactive python script for testing cgroups
> +
> +@copyright: 2011 Red Hat Inc.
> +@author: Lukas Doktor <ldoktor@xxxxxxxxxx>
> +"""
> +import array, sys, time, math
> +
> +def test_smoke():
> +    """
> +    SIGSTOP the process and after SIGCONT exits.
> +    """
> +    print "TEST: smoke"
> +    print "TEST: wait for input"
> +    raw_input()
> +    print "PASS: smoke"
> +
> +
> +def test_memfill(size=1024):
> +    """
> +    SIGSTOP and after SIGCONT fills the memory up to size size.
> +    """
> +    print "TEST: memfill (%dM)" % size
> +    print "TEST: wait for input"
> +    raw_input()
> +    mem = array.array('B')
> +    buf = ""
> +    for i in range(1024*1024):
> +        buf += '\x00'
> +    for i in range(size):
> +        mem.fromstring(buf)
> +        #for j in range(1024*1024):
> +        #    mem.append(0)
> +        print "TEST: %dM" % i
> +    print "PASS: memfill (%dM)" % size
> +
> +
> +def test_cpu():
> +    """
> +    Stress the CPU
> +    """
> +    print "TEST: cpu"
> +    print "TEST: wait for input"
> +    raw_input()
> +    while True:
> +        for i in range (1000, 10000):
> +            math.factorial(i)
> +
> +
> +def test_devices_read():
> +    """
> +    Inf read from /dev/zero
> +    """
> +    print "TEST: devices read"
> +    print "TEST: wait for input"
> +    raw_input()
> +
> +    dev = open("/dev/zero", 'r')
> +    while True:
> +        print "TEST: tick"
> +        dev.flush()
> +        dev.read(1024*1024)
> +        time.sleep(1)
> +
> +
> +def test_devices_write():
> +    """
> +    Inf write into /dev/null device
> +    """
> +    print "TEST: devices write"
> +    print "TEST: wait for input"
> +    raw_input()
> +
> +    dev = open("/dev/null", 'w')
> +    buf = ""
> +    for _ in range(1024*1024):
> +        buf += '\x00'
> +    while True:
> +        print "TEST: tick"
> +        dev.write(buf)
> +        dev.flush()
> +        time.sleep(1)
> +
> +
> +def main():
> +    """
> +    Main (infinite) loop.
> +    """
> +    if len(sys.argv) < 2:
> +        print "FAIL: Incorrect usage"
> +        return -1
> +    if sys.argv[1] == "smoke":
> +        test_smoke()
> +    elif sys.argv[1] == "memfill":
> +        if len(sys.argv) > 2:
> +            test_memfill(int(sys.argv[2]))
> +        else:
> +            test_memfill()
> +    elif sys.argv[1] == "cpu":
> +        test_cpu()
> +    elif sys.argv[1] == "devices":
> +        if len(sys.argv) > 2:
> +            if (sys.argv[2] == "write"):
> +                test_devices_write()
> +            else:
> +                test_devices_read()
> +        else:
> +            test_devices_read()
> +    else:
> +        print "FAIL: No test specified"
> +
> +if __name__ == "__main__":
> +    main()
> +
> diff --git a/client/tests/cgroup/control b/client/tests/cgroup/control
> new file mode 100644
> index 0000000..86aec06
> --- /dev/null
> +++ b/client/tests/cgroup/control
> @@ -0,0 +1,12 @@
> +AUTHOR = "Lukas Doktor <ldoktor@xxxxxxxxxx>"
> +NAME = "Cgroup"
> +TIME = "SHORT"
> +TEST_CATEGORY = "Functional"
> +TEST_CLASS = "General"
> +TEST_TYPE = "client"
> +
> +DOC = """
> +This test checks basic functionality of cgroups
> +"""
> +
> +job.run_test('cgroup')
> --
> 1.7.6
>
> _______________________________________________
> Autotest mailing list
> Autotest@xxxxxxxxxxxxxxx
> http://test.kernel.org/cgi-bin/mailman/listinfo/autotest
>



-- 
Lucas
--
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