+ raise error.TestError("Could not set blkio.weight")
+ if self.blkio.set_property("blkio.weight", 1000, pwd[1]):
+ raise error.TestError("Could not set blkio.weight")
+
+ # Add dumm drives
+ for i in range(2):
+ self.files.append(tempfile.NamedTemporaryFile(
+ prefix="cgroup-disk-",
+ suffix=".iso"))
+ utils.system("dd if=/dev/zero of=%s bs=1M
count=10&>/dev/null"
+ % (self.files[i].name))
+ out = vms[i].monitor.cmd("pci_add auto storage
file=%s,"
+ "if=virtio,snapshot=off,cache=off"
+ % (self.files[i].name))
+ out = re.search(r'OK domain (\d+), bus (\d+), slot
(\d+), '
+ 'function \d+', out).groups()
+ self.devices.append("%s:%s:%s" % out)
+
+
+ def run(self):
+ """
+ Actual test:
+ * executes self.dd_cmd simultanously on both vms.
+ """
+ sessions = []
+ out = []
+ sessions.append(vms[0].wait_for_login(timeout=30))
+ sessions.append(vms[1].wait_for_login(timeout=30))
+ sessions.append(vms[0].wait_for_login(timeout=30))
+ sessions.append(vms[1].wait_for_login(timeout=30))
+ sessions[0].sendline(self.dd_cmd)
+ sessions[1].sendline(self.dd_cmd)
+ time.sleep(60)
+
+ cmd = "rm -f /tmp/cgroup_lock; killall -9 dd"
+ sessions[2].sendline(cmd)
+ sessions[3].sendline(cmd)
+ re_dd = (r'(\d+) bytes \(\d+\.*\d* \w*\) copied,
(\d+\.*\d*) s, '
+ '\d+\.*\d* \w./s')
+ out = []
+ for i in range(2):
+ out.append(sessions[i].read_up_to_prompt())
+ out[i] = [int(_[0])/float(_[1])
+ for _ in re.findall(re_dd, out[i])[1:-1]]
+ logging.debug("dd(%d) output: %s", i, out[i])
+ out[i] = [min(out[i]), sum(out[i])/len(out[i]),
max(out[i]),
+ len(out[i])]
+
+ for session in sessions:
+ session.close()
+
+ logging.debug("dd values (min,avg,max,ddloops):\nout1:
%s\nout2: %s"
+ ,out[0], out[1])
+
+ out1 = out[0][1]
+ out2 = out[1][1]
+ # In theory out1 should be 10times smaller, than out2.
+ if out1*3> out2:
+ raise error.TestFail("dd values: %s:%s (1:%f), limit
1:2.5"
+ ", theoretical: 1:10"
+ % (out1, out2, out2/out1))
+ else:
+ logging.info("dd values: %s:%s (1:%s)", out1, out2,
out2/out1)
+
+
+
+ class TestBlkioBandwidthWeigthRead(_TestBlkioBandwidth):
+ """
+ Tests the blkio.weight capability using simultanious read on
2 vms
+ """
+ def __init__(self, vms, modules):
+ """
+ Initialization
+ @param vms: list of vms
+ @param modules: initialized cgroup module class
+ """
+ _TestBlkioBandwidth.__init__(self, vms, modules)
+ self.dd_cmd = ("export FILE=$(ls /dev/vd* | tail -n 1);
touch "
+ "/tmp/cgroup_lock ; while [ -e
/tmp/cgroup_lock ];"
+ "do dd if=$FILE of=/dev/null iflag=direct
bs=100K;"
+ "done")
+
+
+ class TestBlkioBandwidthWeigthWrite(_TestBlkioBandwidth):
+ """
+ Tests the blkio.weight capability using simultanious write
on 2 vms
+ """
+ def __init__(self, vms, modules):
+ """
+ Initialization
+ @param vms: list of vms
+ @param modules: initialized cgroup module class
+ """
+ _TestBlkioBandwidth.__init__(self, vms, modules)
+ self.dd_cmd = ('export FILE=$(ls /dev/vd* | tail -n 1);
touch '
+ '/tmp/cgroup_lock ; while [ -e
/tmp/cgroup_lock ];'
+ 'do dd if=/dev/zero of=$FILE oflag=direct
bs=100K;'
+ 'done')
+
+
+ def _check_vms(vms):
+ """
+ Checks the vitality of VM
+ @param vms: list of vm's
+ """
+ for i in range(len(vms)):
+ vms[i].verify_alive()
+ _ = vms[i].wait_for_login(timeout=60)
+ out = _.cmd_output("dmesg -c")
+ _.close()
+ del(_)
+ if out.find("BUG") != -1:
+ logging.error("BUG occured in dmesg:\n%s", out)
+ logging.warn("recreate VM(%s)", i)
+ # The vm have to be recreate to reset the qemu PCI
state
+ vms[i].create()
+
+
+ # Setup
+ # TODO: Add all new tests here
+ tests = {"blkio_bandwidth_weigth_read" :
TestBlkioBandwidthWeigthRead,
+ "blkio_bandwidth_weigth_write" :
TestBlkioBandwidthWeigthWrite,
+ }
+ modules = CgroupModules()
+ if (modules.init(['cpuset', 'cpu', 'cpuacct', 'memory', 'devices',
+ 'freezer', 'net_cls', 'blkio'])<= 0):
+ raise error.TestFail('Can\'t mount any cgroup modules')
+ # Add all vms
+ vms = []
+ for vm in params.get("vms", "main_vm").split():
+ vm = env.get_vm(vm)
+ vm.verify_alive()
+ timeout = int(params.get("login_timeout", 360))
+ _ = vm.wait_for_login(timeout=timeout)
+ _.close()
+ del(_)
+ vms.append(vm)
+
+
+ # Execute tests
+ results = ""
+ # cgroup_tests = "re1[:loops] re2[:loops] ... ... ..."
+ for j in params.get("cgroup_tests").split():
+ try:
+ loops = int(j[j.rfind(':')+1:])
+ j = j[:j.rfind(':')]
+ except:
+ loops = 1
+ for _loop in range(loops):
+ for i in [_ for _ in tests.keys() if re.match(j, _)]:
+ logging.info("%s: Entering the test", i)
+ try:
+ _check_vms(vms)
+ tst = tests[i](vms, modules)
+ tst.init()
+ tst.run()
+ except error.TestFail, inst:
+ logging.error("%s: Leaving, test FAILED
(TestFail): %s",
+ i, inst)
+ results += "\n * %s: Test FAILED (TestFail): %s"
% (i, inst)
+ try:
+ tst.cleanup()
+ except Exception, inst:
+ tmps = ""
+ for tmp in traceback.format_exception(
+ sys.exc_info()[0],
+ sys.exc_info()[1],
+ sys.exc_info()[2]):
+ tmps += "%s cleanup: %s" % (i, tmp)
+ logging.info("%s: cleanup also failed\n%s",
i, tmps)
+ except error.TestError, inst:
+ tmps = ""
+ for tmp in traceback.format_exception(
+ sys.exc_info()[0],
+ sys.exc_info()[1],
+ sys.exc_info()[2]):
+ tmps += "%s: %s" % (i, tmp)
+ logging.error("%s: Leaving, test FAILED
(TestError): %s",
+ i, tmps)
+ results += "\n * %s: Test FAILED (TestError):
%s"% (i, inst)
+ try:
+ tst.cleanup()
+ except Exception, inst:
+ logging.warn("%s: cleanup also failed:
%s\n", i, inst)
+ except Exception, inst:
+ tmps = ""
+ for tmp in traceback.format_exception(
+ sys.exc_info()[0],
+ sys.exc_info()[1],
+ sys.exc_info()[2]):
+ tmps += "%s: %s" % (i, tmp)
+ logging.error("%s: Leaving, test FAILED
(Exception): %s",
+ i, tmps)
+ results += "\n * %s: Test FAILED (Exception):
%s"% (i, inst)
+ try:
+ tst.cleanup()
+ except Exception, inst:
+ logging.warn("%s: cleanup also failed:
%s\n", i, inst)
+ else:
+ try:
+ tst.cleanup()
+ except Exception, inst:
+ tmps = ""
+ for tmp in traceback.format_exception(
+ sys.exc_info()[0],
+ sys.exc_info()[1],
+ sys.exc_info()[2]):
+ tmps += "%s cleanup: %s" % (i, tmp)
+ logging.info("%s: Leaving, test passed but
cleanup "
+ "FAILED\n%s", i, tmps)
+ results += ("\n * %s: Test passed but
cleanup FAILED"
+ % (i))
+ else:
+ logging.info("%s: Leaving, test PASSED", i)
+ results += "\n * %s: Test PASSED" % (i)
+
+ logging.info("SUM: All tests finished (%d PASS / %d FAIL = %d
TOTAL)%s",
+ results.count("PASSED"), results.count("FAILED"),
+ (results.count("PASSED")+results.count("FAILED")),
results)
+ if results.count("FAILED"):
+ raise error.TestFail("Some subtests failed")
+