From patchwork Sat Jan 22 02:03:46 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lucas Meneghel Rodrigues X-Patchwork-Id: 497551 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p0M23uXe006740 for ; Sat, 22 Jan 2011 02:04:15 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754571Ab1AVCD7 (ORCPT ); Fri, 21 Jan 2011 21:03:59 -0500 Received: from mx1.redhat.com ([209.132.183.28]:9130 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754399Ab1AVCD6 (ORCPT ); Fri, 21 Jan 2011 21:03:58 -0500 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id p0M23vAu007294 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 21 Jan 2011 21:03:57 -0500 Received: from freedom.redhat.com (vpn-11-112.rdu.redhat.com [10.11.11.112]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p0M23nto030188; Fri, 21 Jan 2011 21:03:55 -0500 From: Lucas Meneghel Rodrigues To: autotest@test.kernel.org Cc: kvm@vger.kernel.org, Lucas Meneghel Rodrigues Subject: [PATCH 3/4] KVM test: renaming allocator.py to ksm_overcommit_guest.py Date: Sat, 22 Jan 2011 00:03:46 -0200 Message-Id: <1295661827-30803-4-git-send-email-lmr@redhat.com> In-Reply-To: <1295661827-30803-1-git-send-email-lmr@redhat.com> References: <1295661827-30803-1-git-send-email-lmr@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Sat, 22 Jan 2011 02:04:15 +0000 (UTC) diff --git a/client/tests/kvm/scripts/allocator.py b/client/tests/kvm/scripts/allocator.py deleted file mode 100755 index 09dc004..0000000 --- a/client/tests/kvm/scripts/allocator.py +++ /dev/null @@ -1,237 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -""" -Auxiliary script used to allocate memory on guests. - -@copyright: 2008-2009 Red Hat Inc. -@author: Jiri Zupka (jzupka@redhat.com) -""" - - -import os, array, sys, struct, random, copy, inspect, tempfile, datetime, math - -PAGE_SIZE = 4096 # machine page size - -TMPFS_OVERHEAD = 0.0022 # overhead on 1MB of write data - - -class MemFill(object): - """ - Fills guest memory according to certain patterns. - """ - def __init__(self, mem, static_value, random_key): - """ - Constructor of MemFill class. - - @param mem: Amount of test memory in MB. - @param random_key: Seed of random series used for fill up memory. - @param static_value: Value used to fill all memory. - """ - if (static_value < 0 or static_value > 255): - print ("FAIL: Initialization static value" - "can be only in range (0..255)") - return - - self.tmpdp = tempfile.mkdtemp() - ret_code = os.system("mount -o size=%dM tmpfs %s -t tmpfs" % - ((mem+math.ceil(mem*TMPFS_OVERHEAD)), - self.tmpdp)) - if ret_code != 0: - if os.getuid() != 0: - print ("FAIL: Unable to mount tmpfs " - "(likely cause: you are not root)") - else: - print "FAIL: Unable to mount tmpfs" - else: - self.f = tempfile.TemporaryFile(prefix='mem', dir=self.tmpdp) - self.allocate_by = 'L' - self.npages = ((mem * 1024 * 1024) / PAGE_SIZE) - self.random_key = random_key - self.static_value = static_value - print "PASS: Initialization" - - - def __del__(self): - if os.path.ismount(self.tmpdp): - self.f.close() - os.system("umount %s" % (self.tmpdp)) - - - def compare_page(self, original, inmem): - """ - Compare pages of memory and print the differences found. - - @param original: Data that was expected to be in memory. - @param inmem: Data in memory. - """ - for ip in range(PAGE_SIZE / original.itemsize): - if (not original[ip] == inmem[ip]): # find which item is wrong - originalp = array.array("B") - inmemp = array.array("B") - originalp.fromstring(original[ip:ip+1].tostring()) - inmemp.fromstring(inmem[ip:ip+1].tostring()) - for ib in range(len(originalp)): # find wrong byte in item - if not (originalp[ib] == inmemp[ib]): - position = (self.f.tell() - PAGE_SIZE + ip * - original.itemsize + ib) - print ("Mem error on position %d wanted 0x%Lx and is " - "0x%Lx" % (position, originalp[ib], inmemp[ib])) - - - def value_page(self, value): - """ - Create page filled by value. - - @param value: String we want to fill the page with. - @return: return array of bytes size PAGE_SIZE. - """ - a = array.array("B") - for i in range((PAGE_SIZE / a.itemsize)): - try: - a.append(value) - except: - print "FAIL: Value can be only in range (0..255)" - return a - - - def random_page(self, seed): - """ - Create page filled by static random series. - - @param seed: Seed of random series. - @return: Static random array series. - """ - random.seed(seed) - a = array.array(self.allocate_by) - for i in range(PAGE_SIZE / a.itemsize): - a.append(random.randrange(0, sys.maxint)) - return a - - - def value_fill(self, value=None): - """ - Fill memory page by page, with value generated with value_page. - - @param value: Parameter to be passed to value_page. None to just use - what's on the attribute static_value. - """ - self.f.seek(0) - if value is None: - value = self.static_value - page = self.value_page(value) - for pages in range(self.npages): - page.tofile(self.f) - print "PASS: Mem value fill" - - - def value_check(self, value=None): - """ - Check memory to see if data is correct. - - @param value: Parameter to be passed to value_page. None to just use - what's on the attribute static_value. - @return: if data in memory is correct return PASS - else print some wrong data and return FAIL - """ - self.f.seek(0) - e = 2 - failure = False - if value is None: - value = self.static_value - page = self.value_page(value) - for pages in range(self.npages): - pf = array.array("B") - pf.fromfile(self.f, PAGE_SIZE / pf.itemsize) - if not (page == pf): - failure = True - self.compare_page(page, pf) - e = e - 1 - if e == 0: - break - if failure: - print "FAIL: value verification" - else: - print "PASS: value verification" - - - def static_random_fill(self, n_bytes_on_end=PAGE_SIZE): - """ - Fill memory by page with static random series with added special value - on random place in pages. - - @param n_bytes_on_end: how many bytes on the end of page can be changed. - @return: PASS. - """ - self.f.seek(0) - page = self.random_page(self.random_key) - random.seed(self.random_key) - p = copy.copy(page) - - t_start = datetime.datetime.now() - for pages in range(self.npages): - rand = random.randint(((PAGE_SIZE / page.itemsize) - 1) - - (n_bytes_on_end / page.itemsize), - (PAGE_SIZE/page.itemsize) - 1) - p[rand] = pages - p.tofile(self.f) - p[rand] = page[rand] - - t_end = datetime.datetime.now() - delta = t_end - t_start - milisec = delta.microseconds / 1e3 + delta.seconds * 1e3 - print "PASS: filling duration = %Ld ms" % milisec - - - def static_random_verify(self, n_bytes_on_end=PAGE_SIZE): - """ - Check memory to see if it contains correct contents. - - @return: if data in memory is correct return PASS - else print some wrong data and return FAIL. - """ - self.f.seek(0) - e = 2 - page = self.random_page(self.random_key) - random.seed(self.random_key) - p = copy.copy(page) - failure = False - for pages in range(self.npages): - rand = random.randint(((PAGE_SIZE/page.itemsize) - 1) - - (n_bytes_on_end/page.itemsize), - (PAGE_SIZE/page.itemsize) - 1) - p[rand] = pages - pf = array.array(self.allocate_by) - pf.fromfile(self.f, PAGE_SIZE / pf.itemsize) - if not (p == pf): - failure = True - self.compare_page(p, pf) - e = e - 1 - if e == 0: - break - p[rand] = page[rand] - if failure: - print "FAIL: Random series verification" - else: - print "PASS: Random series verification" - - -def die(): - """ - Quit allocator. - """ - exit(0) - - -def main(): - """ - Main (infinite) loop of allocator. - """ - print "PASS: Start" - end = False - while not end: - str = raw_input() - exec str - - -if __name__ == "__main__": - main() diff --git a/client/tests/kvm/scripts/ksm_overcommit_guest.py b/client/tests/kvm/scripts/ksm_overcommit_guest.py new file mode 100755 index 0000000..09dc004 --- /dev/null +++ b/client/tests/kvm/scripts/ksm_overcommit_guest.py @@ -0,0 +1,237 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +""" +Auxiliary script used to allocate memory on guests. + +@copyright: 2008-2009 Red Hat Inc. +@author: Jiri Zupka (jzupka@redhat.com) +""" + + +import os, array, sys, struct, random, copy, inspect, tempfile, datetime, math + +PAGE_SIZE = 4096 # machine page size + +TMPFS_OVERHEAD = 0.0022 # overhead on 1MB of write data + + +class MemFill(object): + """ + Fills guest memory according to certain patterns. + """ + def __init__(self, mem, static_value, random_key): + """ + Constructor of MemFill class. + + @param mem: Amount of test memory in MB. + @param random_key: Seed of random series used for fill up memory. + @param static_value: Value used to fill all memory. + """ + if (static_value < 0 or static_value > 255): + print ("FAIL: Initialization static value" + "can be only in range (0..255)") + return + + self.tmpdp = tempfile.mkdtemp() + ret_code = os.system("mount -o size=%dM tmpfs %s -t tmpfs" % + ((mem+math.ceil(mem*TMPFS_OVERHEAD)), + self.tmpdp)) + if ret_code != 0: + if os.getuid() != 0: + print ("FAIL: Unable to mount tmpfs " + "(likely cause: you are not root)") + else: + print "FAIL: Unable to mount tmpfs" + else: + self.f = tempfile.TemporaryFile(prefix='mem', dir=self.tmpdp) + self.allocate_by = 'L' + self.npages = ((mem * 1024 * 1024) / PAGE_SIZE) + self.random_key = random_key + self.static_value = static_value + print "PASS: Initialization" + + + def __del__(self): + if os.path.ismount(self.tmpdp): + self.f.close() + os.system("umount %s" % (self.tmpdp)) + + + def compare_page(self, original, inmem): + """ + Compare pages of memory and print the differences found. + + @param original: Data that was expected to be in memory. + @param inmem: Data in memory. + """ + for ip in range(PAGE_SIZE / original.itemsize): + if (not original[ip] == inmem[ip]): # find which item is wrong + originalp = array.array("B") + inmemp = array.array("B") + originalp.fromstring(original[ip:ip+1].tostring()) + inmemp.fromstring(inmem[ip:ip+1].tostring()) + for ib in range(len(originalp)): # find wrong byte in item + if not (originalp[ib] == inmemp[ib]): + position = (self.f.tell() - PAGE_SIZE + ip * + original.itemsize + ib) + print ("Mem error on position %d wanted 0x%Lx and is " + "0x%Lx" % (position, originalp[ib], inmemp[ib])) + + + def value_page(self, value): + """ + Create page filled by value. + + @param value: String we want to fill the page with. + @return: return array of bytes size PAGE_SIZE. + """ + a = array.array("B") + for i in range((PAGE_SIZE / a.itemsize)): + try: + a.append(value) + except: + print "FAIL: Value can be only in range (0..255)" + return a + + + def random_page(self, seed): + """ + Create page filled by static random series. + + @param seed: Seed of random series. + @return: Static random array series. + """ + random.seed(seed) + a = array.array(self.allocate_by) + for i in range(PAGE_SIZE / a.itemsize): + a.append(random.randrange(0, sys.maxint)) + return a + + + def value_fill(self, value=None): + """ + Fill memory page by page, with value generated with value_page. + + @param value: Parameter to be passed to value_page. None to just use + what's on the attribute static_value. + """ + self.f.seek(0) + if value is None: + value = self.static_value + page = self.value_page(value) + for pages in range(self.npages): + page.tofile(self.f) + print "PASS: Mem value fill" + + + def value_check(self, value=None): + """ + Check memory to see if data is correct. + + @param value: Parameter to be passed to value_page. None to just use + what's on the attribute static_value. + @return: if data in memory is correct return PASS + else print some wrong data and return FAIL + """ + self.f.seek(0) + e = 2 + failure = False + if value is None: + value = self.static_value + page = self.value_page(value) + for pages in range(self.npages): + pf = array.array("B") + pf.fromfile(self.f, PAGE_SIZE / pf.itemsize) + if not (page == pf): + failure = True + self.compare_page(page, pf) + e = e - 1 + if e == 0: + break + if failure: + print "FAIL: value verification" + else: + print "PASS: value verification" + + + def static_random_fill(self, n_bytes_on_end=PAGE_SIZE): + """ + Fill memory by page with static random series with added special value + on random place in pages. + + @param n_bytes_on_end: how many bytes on the end of page can be changed. + @return: PASS. + """ + self.f.seek(0) + page = self.random_page(self.random_key) + random.seed(self.random_key) + p = copy.copy(page) + + t_start = datetime.datetime.now() + for pages in range(self.npages): + rand = random.randint(((PAGE_SIZE / page.itemsize) - 1) - + (n_bytes_on_end / page.itemsize), + (PAGE_SIZE/page.itemsize) - 1) + p[rand] = pages + p.tofile(self.f) + p[rand] = page[rand] + + t_end = datetime.datetime.now() + delta = t_end - t_start + milisec = delta.microseconds / 1e3 + delta.seconds * 1e3 + print "PASS: filling duration = %Ld ms" % milisec + + + def static_random_verify(self, n_bytes_on_end=PAGE_SIZE): + """ + Check memory to see if it contains correct contents. + + @return: if data in memory is correct return PASS + else print some wrong data and return FAIL. + """ + self.f.seek(0) + e = 2 + page = self.random_page(self.random_key) + random.seed(self.random_key) + p = copy.copy(page) + failure = False + for pages in range(self.npages): + rand = random.randint(((PAGE_SIZE/page.itemsize) - 1) - + (n_bytes_on_end/page.itemsize), + (PAGE_SIZE/page.itemsize) - 1) + p[rand] = pages + pf = array.array(self.allocate_by) + pf.fromfile(self.f, PAGE_SIZE / pf.itemsize) + if not (p == pf): + failure = True + self.compare_page(p, pf) + e = e - 1 + if e == 0: + break + p[rand] = page[rand] + if failure: + print "FAIL: Random series verification" + else: + print "PASS: Random series verification" + + +def die(): + """ + Quit allocator. + """ + exit(0) + + +def main(): + """ + Main (infinite) loop of allocator. + """ + print "PASS: Start" + end = False + while not end: + str = raw_input() + exec str + + +if __name__ == "__main__": + main() diff --git a/client/tests/kvm/tests/ksm_overcommit.py b/client/tests/kvm/tests/ksm_overcommit.py index a3c52ef..76ad3b0 100644 --- a/client/tests/kvm/tests/ksm_overcommit.py +++ b/client/tests/kvm/tests/ksm_overcommit.py @@ -18,28 +18,29 @@ def run_ksm_overcommit(test, params, env): def _start_allocator(vm, session, timeout): """ - Execute allocator.py on a guest, wait until it is initialized. + Execute ksm_overcommit_guest.py on a guest, wait until it is initialized. @param vm: VM object. @param session: Remote session to a VM object. - @param timeout: Timeout that will be used to verify if allocator.py - started properly. + @param timeout: Timeout that will be used to verify if + ksm_overcommit_guest.py started properly. """ - logging.debug("Starting allocator.py on guest %s", vm.name) - session.sendline("python /tmp/allocator.py") + logging.debug("Starting ksm_overcommit_guest.py on guest %s", vm.name) + session.sendline("python /tmp/ksm_overcommit_guest.py") try: (match, data) = session.read_until_last_line_matches( ["PASS:", "FAIL:"], timeout) except kvm_subprocess.ExpectProcessTerminatedError, e: - raise error.TestFail("Command allocator.py on vm '%s' failed: %s" % - (vm.name, str(e))) + e_msg = ("Command ksm_overcommit_guest.py on vm '%s' failed: %s" % + (vm.name, str(e))) + raise error.TestFail(e_msg) def _execute_allocator(command, vm, session, timeout): """ - Execute a given command on allocator.py main loop, indicating the vm - the command was executed on. + Execute a given command on ksm_overcommit_guest.py main loop, + indicating the vm the command was executed on. @param command: Command that will be executed. @param vm: VM object. @@ -48,17 +49,18 @@ def run_ksm_overcommit(test, params, env): @return: Tuple (match index, data) """ - logging.debug("Executing '%s' on allocator.py loop, vm: %s, timeout: %s", - command, vm.name, timeout) + logging.debug("Executing '%s' on ksm_overcommit_guest.py loop, " + "vm: %s, timeout: %s", command, vm.name, timeout) session.sendline(command) try: (match, data) = session.read_until_last_line_matches( ["PASS:","FAIL:"], timeout) except kvm_subprocess.ExpectProcessTerminatedError, e: - e_str = ("Failed to execute command '%s' on allocator.py, " - "vm '%s': %s" % (command, vm.name, str(e))) - raise error.TestFail(e_str) + e_msg = ("Failed to execute command '%s' on " + "ksm_overcommit_guest.py, vm '%s': %s" % + (command, vm.name, str(e))) + raise error.TestFail(e_msg) return (match, data) @@ -98,7 +100,7 @@ def run_ksm_overcommit(test, params, env): a_cmd = "mem.value_fill(%d)" % skeys[0] _execute_allocator(a_cmd, vm, lsessions[i], 120 * perf_ratio) - # Let allocator.py do its job + # Let ksm_overcommit_guest.py do its job # (until shared mem reaches expected value) shm = 0 j = 0 @@ -168,7 +170,7 @@ def run_ksm_overcommit(test, params, env): vm = lvms[i] session = lsessions[i] a_cmd = "mem.static_random_fill()" - logging.debug("Executing %s on allocator.py loop, vm: %s", + logging.debug("Executing %s on ksm_overcommit_guest.py loop, vm: %s", a_cmd, vm.name) session.sendline(a_cmd) @@ -271,7 +273,7 @@ def run_ksm_overcommit(test, params, env): a_cmd = "mem.value_fill(%d)" % (skeys[0]) _execute_allocator(a_cmd, vm, lsessions[i], 90 * perf_ratio) - # Wait until allocator.py merges the pages (3 * ksm_size / 3) + # Wait until ksm_overcommit_guest.py merges the pages (3 * ksm_size / 3) shm = 0 i = 0 logging.debug("Target shared memory size: %s", ksm_size) @@ -592,9 +594,9 @@ def run_ksm_overcommit(test, params, env): time.sleep(vmsc * 2 * perf_ratio) logging.debug(kvm_test_utils.get_memory_info(lvms)) - # Copy allocator.py into guests + # Copy ksm_overcommit_guest.py into guests pwd = os.path.join(os.environ['AUTODIR'],'tests/kvm') - vksmd_src = os.path.join(pwd, "scripts/allocator.py") + vksmd_src = os.path.join(pwd, "scripts/ksm_overcommit_guest.py") dst_dir = "/tmp" for vm in lvms: vm.copy_files_to(vksmd_src, dst_dir)