blob: 2bd382afea4c3f14842d71d08657c3261bac8451 [file] [log] [blame]
# Copyright 2017 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
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib import utils
from autotest_lib.server.cros.network import hostap_config
from autotest_lib.server.cros.network import wifi_cell_test_base
class network_WiFi_Reset(wifi_cell_test_base.WiFiCellTestBase):
"""Test that the WiFi interface can be reset successfully, and that WiFi
comes back up properly. Also run a few suspend/resume cycles along the way.
Supports only Marvell (mwifiex) Wifi drivers.
"""
version = 1
_MWIFIEX_RESET_PATH = "/sys/kernel/debug/mwifiex/%s/reset"
_MWIFIEX_RESET_TIMEOUT = 20
_MWIFIEX_RESET_INTERVAL = 0.5
_NUM_RESETS = 15
_NUM_SUSPENDS = 5
_SUSPEND_DELAY = 10
@property
def mwifiex_reset_path(self):
"""Get path to the Wifi interface's reset file."""
return self._MWIFIEX_RESET_PATH % self.context.client.wifi_if
def mwifiex_reset_exists(self):
"""Check if the mwifiex reset file is present (i.e., a mwifiex
interface is present).
"""
return self.context.client.host.run('test -e "%s"' %
self.mwifiex_reset_path, ignore_status=True).exit_status == 0
def mwifiex_reset(self):
"""Perform mwifiex reset and wait for the interface to come back up."""
ssid = self.context.router.get_ssid()
# Adapter will asynchronously reset.
self.context.client.host.run('echo 1 > ' + self.mwifiex_reset_path)
# Wait for disconnect. We aren't guaranteed to receive a disconnect
# event, but shill will at least notice the adapter went away.
self.context.client.wait_for_service_states(ssid, ['idle'],
timeout_seconds=20)
# Now wait for the reset interface file to come back.
utils.poll_for_condition(
condition=self.mwifiex_reset_exists,
exception=error.TestFail(
'Failed to reset device %s' %
self.context.client.wifi_if),
timeout=self._MWIFIEX_RESET_TIMEOUT,
sleep_interval=self._MWIFIEX_RESET_INTERVAL)
def run_once(self):
"""Body of the test."""
if not self.mwifiex_reset_exists():
self._supports_reset = False
raise error.TestNAError('DUT does not support device reset')
else:
self._supports_reset = True
client = self.context.client
ap_config = hostap_config.HostapConfig(channel=1)
ssid = self.configure_and_connect_to_ap(ap_config)
self.context.assert_ping_from_dut()
router = self.context.router
ssid = router.get_ssid()
boot_id = client.host.get_boot_id()
logging.info("Running %d suspends", self._NUM_SUSPENDS)
for _ in range(self._NUM_SUSPENDS):
logging.info("Running %d resets", self._NUM_RESETS)
for __ in range(self._NUM_RESETS):
self.mwifiex_reset()
client.wait_for_connection(ssid)
self.context.assert_ping_from_dut()
client.do_suspend(self._SUSPEND_DELAY)
client.host.test_wait_for_resume(boot_id)
client.wait_for_connection(ssid)
def cleanup(self):
"""Performs cleanup at exit. May reboot the DUT, to keep the system
functioning for the next test.
"""
if self._supports_reset and not self.mwifiex_reset_exists():
logging.info("Test exited, but interface is missing; rebooting")
self.context.client.reboot(timeout=60)