Message ID | 1312296653-7814-2-git-send-email-ldoktor@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Tue, Aug 2, 2011 at 11:50 AM, Lukas Doktor <ldoktor@redhat.com> wrote: > From: root <root@dhcp-26-193.brq.redhat.com> 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@redhat.com> > --- > 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@redhat.com> > +""" > +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@redhat.com>" > +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@test.kernel.org > http://test.kernel.org/cgi-bin/mailman/listinfo/autotest >
I go through this and let you know. ----- Original Message ----- > From: root <root@dhcp-26-193.brq.redhat.com> > > 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@redhat.com> > --- > 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@redhat.com> > +""" > +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@redhat.com>" > +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 > > -- > To unsubscribe from this list: send the line "unsubscribe kvm" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
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@redhat.com> +""" +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@redhat.com>" +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')