timerdevice_boot.py 8.4 KB
Newer Older
L
Lucas Meneghel Rodrigues 已提交
1 2
import logging
import time
3
import re
4

5
from avocado.utils import process
6
from virttest import utils_test
7
from virttest import utils_time
Y
yama 已提交
8
from virttest import env_process
9
from virttest import funcatexit
10
from virttest import error_context
11

L
Lucas Meneghel Rodrigues 已提交
12

13 14 15
def _system(*args, **kwargs):
    kwargs["shell"] = True
    return process.system(*args, **kwargs)
16 17


18
@error_context.context_aware
19
def run(test, params, env):
20 21 22
    """
    Timer device boot guest:

23
    1) Check host clock's sync status with chronyd
24 25 26 27 28
    2) Add some load on host (Optional)
    3) Boot the guest with specific clock source
    4) Check the clock source currently used on guest
    5) Do some file operation on guest (Optional)
    6) Check the system time on guest and host (Optional)
29
    7) Check the hardware time on guest (linux only)
30 31 32
    8) Sleep period of time before reboot (Optional)
    9) Reboot guest (Optional)
    10) Check the system time on guest and host (Optional)
33 34
    11) Check the hardware time on guest (Optional)
    12) Restore guest's clock source
35

L
Lucas Meneghel Rodrigues 已提交
36 37 38
    :param test: QEMU test object.
    :param params: Dictionary with test parameters.
    :param env: Dictionary with the test environment.
39
    """
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62

    def get_hwtime(session):
        """
        Get guest's hardware clock.

        :param session: VM session.
        """
        hwclock_time_command = params.get("hwclock_time_command",
                                          "hwclock -u")
        hwclock_time_filter_re = params.get("hwclock_time_filter_re",
                                            r"(\d+-\d+-\d+ \d+:\d+:\d+)")
        hwclock_time_format = params.get("hwclock_time_format",
                                         "%Y-%m-%d %H:%M:%S")
        output = session.cmd_output_safe(hwclock_time_command)
        try:
            str_time = re.findall(hwclock_time_filter_re, output)[0]
            guest_time = time.mktime(time.strptime(str_time, hwclock_time_format))
        except Exception as err:
            logging.debug(
                "(time_format, time_string): (%s, %s)", hwclock_time_format, str_time)
            raise err
        return guest_time

S
Sitong Liu 已提交
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
    def verify_timedrift(session, is_hardware=False):
        """
        Verify timedrift between host and guest.

        :param session: VM session.
        :param is_hardware: if need to verify guest's hardware time.
        """
        # Command to run to get the current time
        time_command = params["time_command"]
        # Filter which should match a string to be passed to time.strptime()
        time_filter_re = params["time_filter_re"]
        # Time format for time.strptime()
        time_format = params["time_format"]
        timerdevice_drift_threshold = float(params.get(
            "timerdevice_drift_threshold", 3))

        time_type = "system" if not is_hardware else "harware"
        error_context.context("Check the %s time on guest" % time_type,
                              logging.info)
        host_time, guest_time = utils_test.get_time(session, time_command,
                                                    time_filter_re,
                                                    time_format)
        if is_hardware:
            guest_time = get_hwtime(session)
        drift = abs(float(host_time) - float(guest_time))
        if drift > timerdevice_drift_threshold:
            test.fail("The guest's %s time is different with"
                      " host's system time. Host time: '%s', guest time:"
                      " '%s'" % (time_type, host_time, guest_time))

93
    def get_current_clksrc(session):
94 95
        cmd = "cat /sys/devices/system/clocksource/"
        cmd += "clocksource0/current_clocksource"
S
Sitong Liu 已提交
96
        current_clksrc = session.cmd_output_safe(cmd)
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
        if "kvm-clock" in current_clksrc:
            return "kvm-clock"
        elif "tsc" in current_clksrc:
            return "tsc"
        elif "timebase" in current_clksrc:
            return "timebase"
        elif "acpi_pm" in current_clksrc:
            return "acpi_pm"
        return current_clksrc

    def update_clksrc(session, clksrc):
        """
        Update guest's clocksource, this func can work when not login
        into guest with ssh.

        :param session: VM session.
        :param clksrc: expected guest's clocksource.
        """
        avail_cmd = "cat /sys/devices/system/clocksource/clocksource0/"
        avail_cmd += "available_clocksource"
S
Sitong Liu 已提交
117
        avail_clksrc = session.cmd_output_safe(avail_cmd)
118 119 120 121 122 123 124 125 126 127 128 129 130
        if clksrc in avail_clksrc:
            clksrc_cmd = "echo %s > /sys/devices/system/clocksource/" % clksrc
            clksrc_cmd += "clocksource0/current_clocksource"
            status, output = session.cmd_status_output(clksrc_cmd)
            if status:
                test.fail("fail to update guest's clocksource to %s,"
                          "details: %s" % clksrc, output)
        else:
            test.error("please check the clocksource you want to set, "
                       "it's not supported by current guest, current "
                       "available clocksources: %s" % avail_clksrc)

    error_context.context("sync host time with NTP server",
131
                          logging.info)
S
Sitong Liu 已提交
132 133
    clock_sync_command = params["clock_sync_command"]
    process.system(clock_sync_command, shell=True)
134

135 136
    timerdevice_host_load_cmd = params.get("timerdevice_host_load_cmd")
    if timerdevice_host_load_cmd:
137
        error_context.context("Add some load on host", logging.info)
Y
yama 已提交
138 139 140 141 142 143 144 145 146 147 148
        host_cpu_cnt_cmd = params["host_cpu_cnt_cmd"]
        host_cpu_cnt = int(process.system_output(host_cpu_cnt_cmd, shell=True).strip())
        if params["os_type"] == "linux":
            timerdevice_host_load_cmd = timerdevice_host_load_cmd % host_cpu_cnt
            process.system(timerdevice_host_load_cmd, shell=True,
                           ignore_bg_processes=True)
        else:
            timerdevice_host_load_cmd = timerdevice_host_load_cmd % int(host_cpu_cnt/2)
            stress_bg = utils_test.HostStress("stress", params,
                                              stress_args=timerdevice_host_load_cmd)
            stress_bg.load_stress_tool()
149 150
        host_load_stop_cmd = params.get("timerdevice_host_load_stop_cmd",
                                        "pkill -f 'do X=1'")
151
        funcatexit.register(env, params["type"], _system,
152 153
                            host_load_stop_cmd)

Y
yama 已提交
154 155 156
    params["start_vm"] = "yes"
    env_process.preprocess_vm(test, params, env, params.get("main_vm"))

157 158 159
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()

160 161 162 163 164 165
    error_context.context("Sync guest timezone before test", logging.info)
    if params["os_type"] == 'linux':
        utils_time.sync_timezone_linux(vm)
    else:
        utils_time.sync_timezone_win(vm)

166
    timeout = int(params.get("login_timeout", 360))
167
    session = vm.wait_for_serial_login(timeout=timeout)
168 169

    timerdevice_clksource = params.get("timerdevice_clksource")
170
    need_restore_clksrc = False
171
    if timerdevice_clksource:
172 173
        origin_clksrc = get_current_clksrc(session)
        logging.info("guest is booted with %s" % origin_clksrc)
174

175 176 177
        if timerdevice_clksource != origin_clksrc:
            update_clksrc(session, timerdevice_clksource)
            need_restore_clksrc = True
178

S
Sitong Liu 已提交
179
    error_context.context("check timedrift between guest and host.",
180
                          logging.info)
S
Sitong Liu 已提交
181
    verify_timedrift(session)
182
    if params["os_type"] == "linux":
S
Sitong Liu 已提交
183
        verify_timedrift(session, is_hardware=True)
184

Y
yama 已提交
185 186 187 188 189 190 191 192 193
    repeat_nums = params.get_numeric("repeat_nums")
    if repeat_nums:
        sleep_time = params["sleep_time"]
        for index in range(repeat_nums):
            time.sleep(int(sleep_time))
            verify_timedrift(session)
            if params["os_type"] == "linux":
                verify_timedrift(session, is_hardware=True)

194 195 196
    if params.get("timerdevice_reboot_test") == "yes":
        sleep_time = params.get("timerdevice_sleep_time")
        if sleep_time:
197 198
            error_context.context("Sleep '%s' secs before reboot" % sleep_time,
                                  logging.info)
199 200 201
            sleep_time = int(sleep_time)
            time.sleep(sleep_time)

S
Sitong Liu 已提交
202 203 204 205
        error_context.context("Check timedrift between guest and host "
                              "after reboot.", logging.info)
        vm.reboot(timeout=timeout, serial=True)
        verify_timedrift(session)
206
        if params["os_type"] == "linux":
S
Sitong Liu 已提交
207
            verify_timedrift(session, is_hardware=True)
208 209
    if need_restore_clksrc:
        update_clksrc(session, origin_clksrc)
210
    session.close()