blob: 5bee072537d01ef545168d4f58272d3ef040a75d [file] [log] [blame]
# Copyright 2014 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import logging, re, time
from autotest_lib.client.common_lib import error
from autotest_lib.server.cros.faft.firmware_test import FirmwareTest
class firmware_EventLog(FirmwareTest):
"""
Test to ensure eventlog is written on boot and suspend/resume.
"""
version = 1
_TIME_FORMAT = '%Y-%m-%d %H:%M:%S'
def initialize(self, host, cmdline_args):
super(firmware_EventLog, self).initialize(host, cmdline_args)
self.setup_dev_mode(dev_mode=False)
def _has_event(self, pattern):
return bool(filter(re.compile(pattern).search, self._events))
def _gather_events(self):
entries = self.faft_client.system.run_shell_command_get_output(
'mosys eventlog list')
now = self._now()
self._events = []
for line in reversed(entries):
_, time_string, event = line.split(' | ', 2)
timestamp = time.strptime(time_string, self._TIME_FORMAT)
if timestamp > now:
logging.error('Found prophecy: "%s"', line)
raise error.TestFail('Event timestamp lies in the future')
if timestamp < self._cutoff_time:
logging.debug('Event "%s" too early, stopping search', line)
break
logging.info('Found event: "%s"', line)
self._events.append(event)
# This assumes that Linux and the firmware use the same RTC. mosys converts
# timestamps to localtime, and so do we (by calling date without --utc).
def _now(self):
time_string = self.faft_client.system.run_shell_command_get_output(
'date +"%s"' % self._TIME_FORMAT)[0]
logging.debug('Current local system time on DUT is "%s"', time_string)
return time.strptime(time_string, self._TIME_FORMAT)
def run_once(self):
if not self.faft_config.has_eventlog:
raise error.TestNAError('This board has no eventlog support.')
logging.info('Verifying eventlog behavior on normal mode boot')
self._cutoff_time = self._now()
self.reboot_warm()
self.check_state((self.checkers.crossystem_checker, {
'devsw_boot': '0',
'mainfw_type': 'normal',
}))
self._gather_events()
if not self._has_event(r'System boot'):
raise error.TestError('No "System boot" event on normal boot.')
# ' Wake' to match 'FW Wake' and 'ACPI Wake' but not 'Wake Source'
if self._has_event(r'Developer Mode|Recovery Mode|Sleep| Wake'):
raise error.TestError('Incorrect event logged on normal boot.')
logging.debug('Transitioning to dev mode for next test')
self.enable_dev_mode_and_reboot()
self.wait_dev_screen_and_ctrl_d()
self.wait_for_client()
logging.info('Verifying eventlog behavior on developer mode boot')
self._cutoff_time = self._now()
self.reboot_warm(ctrl_d=True)
self.check_state((self.checkers.crossystem_checker, {
'devsw_boot': '1',
'mainfw_type': 'developer',
}))
self._gather_events()
if (not self._has_event(r'System boot') or
not self._has_event(r'Chrome OS Developer Mode')):
raise error.TestError('Missing required event on dev mode boot.')
if self._has_event(r'Recovery Mode|Sleep| Wake'):
raise error.TestError('Incorrect event logged on dev mode boot.')
logging.debug('Transitioning back to normal mode for final tests')
self.enable_normal_mode_and_reboot()
self.wait_for_client()
logging.info('Verifying eventlog behavior in recovery mode')
self._cutoff_time = self._now()
self.enable_rec_mode_and_reboot()
self.wait_for_client_offline()
time.sleep(self.faft_config.firmware_screen)
self.reboot_warm(sync_before_boot=False)
self.check_state((self.checkers.crossystem_checker, {
'devsw_boot': '0',
'mainfw_type': 'normal',
}))
self._gather_events()
if (not self._has_event(r'System boot') or
not self._has_event(r'Chrome OS Recovery Mode \| Recovery Button')):
raise error.TestError('Missing required event in recovery mode.')
if self._has_event(r'Developer Mode|Sleep| Wake'):
raise error.TestError('Incorrect event logged in recovery mode.')
logging.info('Verifying eventlog behavior on suspend/resume')
self._cutoff_time = self._now()
self.faft_client.system.run_shell_command(
'powerd_dbus_suspend -wakeup_timeout=10')
time.sleep(5) # a little slack time for powerd to write the 'Wake'
self._gather_events()
if ((not self._has_event(r'^Wake') or not self._has_event(r'Sleep')) and
(not self._has_event(r'ACPI Enter \| S3') or
not self._has_event(r'ACPI Wake \| S3'))):
raise error.TestError('Missing required event on suspend/resume.')
if self._has_event(r'System |Developer Mode|Recovery Mode'):
raise error.TestError('Incorrect event logged on suspend/resume.')