blob: f1c5130e4b924d19acf2440cf4a032618cb85069 [file] [log] [blame]
# Copyright 2015 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 contextlib
import logging
import time
from autotest_lib.client.common_lib.cros.network import xmlrpc_datatypes
from autotest_lib.client.common_lib import error
from autotest_lib.server.cros import dark_resume_utils
from autotest_lib.server.cros.network import hostap_config
from autotest_lib.server.cros.network import wifi_cell_test_base
from autotest_lib.server.cros.network import wifi_client
class network_WiFi_ReconnectInDarkResume(wifi_cell_test_base.WiFiCellTestBase):
"""Test that known WiFi access points wake up the system."""
version = 1
def initialize(self, host):
"""Set up for dark resume."""
self._dr_utils = dark_resume_utils.DarkResumeUtils(host)
def check_connected_on_last_resume(self):
"""Checks whether the DUT was connected on its last resume.
Checks that the DUT was connected after waking from suspend by parsing
the last instance shill log message that reports shill's connection
status on resume. Fails the test if this log message reports that
the DUT woke up disconnected.
"""
# As of build R43 6913.0.0, the shill log message from the function
# OnAfterResume is called as soon as shill resumes from suspend, and
# will report whether or not shill is connected. The log message will
# take one of the following two forms:
#
# [...] [INFO:wifi.cc($PID)] OnAfterResume: connected
# [...] [INFO:wifi.cc($PID)] OnAfterResume: not connected
#
# where $PID is an arbitrary PID number. By checking if the last
# instance of this message contains the substring "not connected", we
# can determine whether or not shill was connected on its last resume.
connection_status_msg_regex_str = 'INFO:wifi\.cc.*OnAfterResume'
not_connected_substr = 'not connected'
connected_substr = 'connected'
cmd = ('grep -E %s /var/log/net.log | tail -1' %
connection_status_msg_regex_str)
cmdresult = self.context.client.host.run(cmd).stdout
if not cmdresult:
raise error.TestFail(
'Could not find resume connection status log message.')
if not_connected_substr in cmdresult:
raise error.TestFail(
'Client was not connected upon waking from suspend.')
if not connected_substr in cmdresult:
raise error.TestFail(
'Resume log message did not contain connection status.')
logging.info('Client was connected upon waking from suspend.')
def run_once(self):
"""Body of the test."""
self.context.configure(hostap_config.HostapConfig(channel=1))
assoc_params = xmlrpc_datatypes.AssociationParameters(
ssid=self.context.router.get_ssid())
self.context.assert_connect_wifi(assoc_params)
client = self.context.client
router = self.context.router
ap_ssid = router.get_ssid()
# Enable the wake on SSID feature in shill, and set the scan period.
with contextlib.nested(
client.wake_on_wifi_features(wifi_client.WAKE_ON_WIFI_SSID),
client.net_detect_scan_period_seconds(
wifi_client.NET_DETECT_SCAN_WAIT_TIME_SECONDS)):
logging.info('Set up WoWLAN')
with self._dr_utils.suspend():
# Wait for suspend actions to finish.
time.sleep(wifi_client.SUSPEND_WAIT_TIME_SECONDS)
# Bring the AP down so that DUT is disconnected.
router.deconfig_aps()
# Wait for the DUT to wake on disconnect in dark resume, then
# suspend again.
time.sleep(wifi_client.DARK_RESUME_WAIT_TIME_SECONDS)
# Bring the AP back up to wake up the DUT.
logging.info('Bringing AP back online.')
self.context.configure(hostap_config.HostapConfig(
ssid=ap_ssid, channel=1))
# Wait long enough for the NIC on the DUT to perform a net
# detect scan, discover the AP with the white-listed SSID, wake
# up in dark resume, connect, then suspend again.
time.sleep(wifi_client.NET_DETECT_SCAN_WAIT_TIME_SECONDS +
wifi_client.DARK_RESUME_WAIT_TIME_SECONDS)
self.check_connected_on_last_resume()
def cleanup(self):
self._dr_utils.teardown()
# Make sure we clean up everything
super(network_WiFi_ReconnectInDarkResume, self).cleanup()