On Tue, Jul 21, 2009 at 12:29 PM, Michael Goldish<mgoldish@xxxxxxxxxx> wrote: > > ----- "Yolkfull Chow" <yzhou@xxxxxxxxxx> wrote: > >> On Mon, Jul 20, 2009 at 06:07:19PM +0300, Michael Goldish wrote: >> > 1) Log into a guest. >> > 2) Take a time reading from the guest and host. >> > 3) Run load on the guest and host. >> > 4) Take a second time reading. >> > 5) Stop the load and rest for a while. >> > 6) Take a third time reading. >> > 7) If the drift immediately after load is higher than a user- >> > specified value (in %), fail. >> > If the drift after the rest period is higher than a user-specified >> value, >> > fail. >> > >> > Signed-off-by: Michael Goldish <mgoldish@xxxxxxxxxx> >> > --- >> > client/tests/kvm/kvm.py | 1 + >> > client/tests/kvm/kvm_tests.py | 161 >> ++++++++++++++++++++++++++++++++++++++++- >> > 2 files changed, 160 insertions(+), 2 deletions(-) >> > >> > diff --git a/client/tests/kvm/kvm.py b/client/tests/kvm/kvm.py >> > index b18b643..070e463 100644 >> > --- a/client/tests/kvm/kvm.py >> > +++ b/client/tests/kvm/kvm.py >> > @@ -55,6 +55,7 @@ class kvm(test.test): >> > "kvm_install": test_routine("kvm_install", >> "run_kvm_install"), >> > "linux_s3": test_routine("kvm_tests", >> "run_linux_s3"), >> > "stress_boot": test_routine("kvm_tests", >> "run_stress_boot"), >> > + "timedrift": test_routine("kvm_tests", >> "run_timedrift"), >> > } >> > >> > # Make it possible to import modules from the test's >> bindir >> > diff --git a/client/tests/kvm/kvm_tests.py >> b/client/tests/kvm/kvm_tests.py >> > index 5991aed..ca0b8c0 100644 >> > --- a/client/tests/kvm/kvm_tests.py >> > +++ b/client/tests/kvm/kvm_tests.py >> > @@ -1,4 +1,4 @@ >> > -import time, os, logging >> > +import time, os, logging, re, commands >> > from autotest_lib.client.common_lib import utils, error >> > import kvm_utils, kvm_subprocess, ppm_utils, scan_results >> > >> > @@ -529,7 +529,6 @@ def run_stress_boot(tests, params, env): >> > """ >> > # boot the first vm >> > vm = kvm_utils.env_get_vm(env, params.get("main_vm")) >> > - >> > if not vm: >> > raise error.TestError("VM object not found in >> environment") >> > if not vm.is_alive(): >> > @@ -586,3 +585,161 @@ def run_stress_boot(tests, params, env): >> > for se in sessions: >> > se.close() >> > logging.info("Total number booted: %d" % (num -1)) >> > + >> > + >> > +def run_timedrift(test, params, env): >> > + """ >> > + Time drift test (mainly for Windows guests): >> > + >> > + 1) Log into a guest. >> > + 2) Take a time reading from the guest and host. >> > + 3) Run load on the guest and host. >> > + 4) Take a second time reading. >> > + 5) Stop the load and rest for a while. >> > + 6) Take a third time reading. >> > + 7) If the drift immediately after load is higher than a user- >> > + specified value (in %), fail. >> > + If the drift after the rest period is higher than a >> user-specified value, >> > + fail. >> > + >> > + @param test: KVM test object. >> > + @param params: Dictionary with test parameters. >> > + @param env: Dictionary with the test environment. >> > + """ >> > + vm = kvm_utils.env_get_vm(env, params.get("main_vm")) >> > + if not vm: >> > + raise error.TestError("VM object not found in >> environment") >> > + if not vm.is_alive(): >> > + raise error.TestError("VM seems to be dead; Test requires a >> living VM") >> > + >> > + logging.info("Waiting for guest to be up...") >> > + >> > + session = kvm_utils.wait_for(vm.ssh_login, 240, 0, 2) >> > + if not session: >> > + raise error.TestFail("Could not log into guest") >> > + >> > + logging.info("Logged in") >> > + >> > + # Collect test parameters: >> > + # Command to run to get the current time >> > + time_command = params.get("time_command") >> > + # Filter which should match a string to be passed to >> time.strptime() >> > + time_filter_re = params.get("time_filter_re") >> > + # Time format for time.strptime() >> > + time_format = params.get("time_format") >> > + guest_load_command = params.get("guest_load_command") >> > + guest_load_stop_command = >> params.get("guest_load_stop_command") >> > + host_load_command = params.get("host_load_command") >> > + guest_load_instances = int(params.get("guest_load_instances", >> "1")) >> > + host_load_instances = int(params.get("host_load_instances", >> "0")) >> > + # CPU affinity mask for taskset >> > + cpu_mask = params.get("cpu_mask", "0xFF") >> > + load_duration = float(params.get("load_duration", "30")) >> > + rest_duration = float(params.get("rest_duration", "10")) >> > + drift_threshold = float(params.get("drift_threshold", "200")) >> > + drift_threshold_after_rest = >> float(params.get("drift_threshold_after_rest", >> > + "200")) >> > + >> > + guest_load_sessions = [] >> > + host_load_sessions = [] >> > + >> > + # Remember the VM's previous CPU affinity >> > + prev_cpu_mask = commands.getoutput("taskset -p %s" % >> vm.get_pid()) >> > + prev_cpu_mask = prev_cpu_mask.split()[-1] >> > + # Set the VM's CPU affinity >> > + commands.getoutput("taskset -p %s %s" % (cpu_mask, >> vm.get_pid())) >> > + >> > + try: >> > + # Get time before load >> > + host_time_0 = time.time() >> > + session.sendline(time_command) >> > + (match, s) = session.read_up_to_prompt() >> > + s = re.findall(time_filter_re, s)[0] >> > + guest_time_0 = time.mktime(time.strptime(s, time_format)) >> >> Hi Machael, this test looks good for me, but I have a little >> suggestion: >> Why not write a common function to get guest time which really save >> many >> duplicate codes here? It could has four parameters and I would also >> help >> write it for you :-) >> >> def get_guest_time(session, time_command, filter_re, format): >> session.sendline(time_command) >> (match, s) = session.read_up_to_prompt() >> s = re.findall(filter_re, s)[0] >> curr_time = time.mktime(time.strptime(s, format)) >> return curr_time > > Thanks, makes perfect sense. The code seemed quite short already so I > didn't bother, but it should save quite a few lines. > > While we're at it, maybe the function should return the host time as well: > (host_time_0, guest_time_0) = get_current_time(...) > > Anyway, if it's OK with everyone, I think I'll do it in an additional > commit rather than re-post this one, because even a small change like > that needs to undergo some minimal testing. Yes, I am OK with it. I am currently trying the test here on my test box. Code looks good. -- 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