| # Copyright (c) 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 collections |
| import logging |
| |
| from autotest_lib.client.common_lib import error |
| from autotest_lib.client.common_lib import global_config |
| from autotest_lib.client.common_lib import utils |
| from autotest_lib.client.common_lib.cros import dev_server |
| from autotest_lib.client.common_lib.cros.network import ping_runner |
| from autotest_lib.server import hosts |
| from autotest_lib.server import site_linux_router |
| from autotest_lib.server import test |
| from autotest_lib.server.cros import dnsname_mangler |
| from autotest_lib.server.cros import provisioner |
| from autotest_lib.server.cros.network import wifi_test_context_manager |
| |
| |
| # Stable versions come from the builders. |
| # The builder version is used to build the URL of the corresponding image |
| # in Google Storage. |
| # The image version is a line from /etc/lsb-release in the corresponding image. |
| StableVersion = collections.namedtuple('StableVersion', |
| ['builder_version', 'release_version']) |
| |
| class network_WiFi_UpdateRouter(test.test): |
| """Updates a router to the most recent stable version. |
| |
| This is not a test per se, since it does not test client behavior. However |
| it is advantageous to write this as a test so that we can schedule it to |
| run periodically via the same infrastructure we use to run tests. |
| |
| Note that this test is very much patterned on provision_QuickProvision. |
| |
| """ |
| version = 1 |
| |
| STABLE_VERSIONS = { |
| ## crbug.com/1098024: these are left here as documentation of what the |
| # last stable version is, but the current updater code does not support |
| # them. |
| 'whirlwind': StableVersion('whirlwind-test-ap-tryjob/R85-13310.60.0-b4641849', |
| '13310.60.2020_08_25_0212'), |
| 'gale': StableVersion('gale-test-ap-tryjob/R85-13310.54.0-b4637444', |
| '13310.54.2020_08_19_1536'), |
| } |
| |
| # List of files to remove. |
| FILES_TO_REMOVE = ['/var/spool/crash/*', '/tmp/*', |
| '/var/lib/metrics/uma-events'] |
| |
| |
| def get_release_version(self, host): |
| result = host.run('cat /etc/lsb-release') |
| for line in result.stdout.splitlines(): |
| if line.startswith('CHROMEOS_RELEASE_VERSION='): |
| return line.split('=', 1)[1] |
| |
| |
| def get_update_url(self, ds_url, image): |
| CONFIG = global_config.global_config |
| IMAGE_URL_PATTERN = CONFIG.get_config_value( |
| 'CROS', 'image_url_pattern', type=str) |
| return IMAGE_URL_PATTERN % (ds_url, image) |
| |
| |
| def warmup(self, raw_cmdline_args): |
| """Possibly parse the router hostname from the commandline. |
| |
| @param raw_cmdline_args raw input from autotest. |
| |
| """ |
| cmdline_args = utils.args_to_dict(raw_cmdline_args) |
| logging.info('Running wifi test with commandline arguments: %r', |
| cmdline_args) |
| self._router_hostname_from_cmdline = cmdline_args.get( |
| wifi_test_context_manager.WiFiTestContextManager. \ |
| CMDLINE_ROUTER_ADDR) |
| |
| |
| def freeup_disk_space(self, device_host): |
| """Remove files to free up disk space. |
| |
| @param device_host: router / pcap host object |
| |
| """ |
| for path in self.FILES_TO_REMOVE: |
| device_host.run('rm -rf %s' % path, ignore_status=True) |
| |
| |
| def run_once(self, host, is_pcap=False): |
| """Update router / packet capture associated with host. |
| |
| @param host DUT connected to AP/Pcap that needs update |
| |
| """ |
| if is_pcap: |
| device_hostname = dnsname_mangler.get_pcap_addr( |
| client_hostname=host.hostname) |
| else: |
| device_hostname = site_linux_router.build_router_hostname( |
| client_hostname=host.hostname, |
| router_hostname=self._router_hostname_from_cmdline) |
| |
| ping_helper = ping_runner.PingRunner() |
| if not ping_helper.simple_ping(device_hostname): |
| # Pcap devices aren't always present. Just claim Not Applicable if |
| # we couldn't find it. |
| e = error.TestNAError if is_pcap else error.TestError |
| raise e('%s not found / is down.' % device_hostname) |
| |
| # Use CrosHost for all router/pcap hosts and avoid host detection. |
| # Host detection would use JetstreamHost for Whirlwind routers. |
| # JetstreamHost assumes ap-daemons are running. |
| # Testbed routers run the testbed-ap profile with no ap-daemons. |
| # TODO(ecgh): crbug.com/757075 Fix testbed-ap JetstreamHost detection. |
| device_host = hosts.create_host(device_hostname, |
| host_class=hosts.CrosHost, |
| allow_failure=True) |
| # Remove un-wanted files to freeup diskspace before starting update. |
| self.freeup_disk_space(device_host) |
| self.update_device(device_host) |
| |
| |
| def update_device(self, device_host): |
| """Update router and pcap associated with host. |
| |
| @param device_host: router / pcap host object |
| @param device_board: router / pcap board name |
| |
| """ |
| device_board = device_host.get_board().split(':', 1)[1] |
| desired = self.STABLE_VERSIONS.get(device_board, None) |
| if desired is None: |
| raise error.TestFail('No stable version found for %s with board=%s.' |
| % (device_host.hostname, device_board)) |
| |
| logging.info('Checking whether %s is at the latest stable version: %s', |
| device_host.hostname, desired.release_version) |
| current_release_version = self.get_release_version(device_host) |
| if desired.release_version == current_release_version: |
| raise error.TestNAError('%s is already at latest version %s.' % |
| (device_host.hostname, |
| desired.release_version)) |
| |
| logging.info('Updating %s to image %s from %s', |
| device_host.hostname, desired.release_version, |
| current_release_version) |
| try: |
| ds = dev_server.ImageServer.resolve(desired.builder_version, |
| device_host.hostname) |
| except dev_server.DevServerException as e: |
| logging.error(e) |
| raise error.TestFail(str(e)) |
| |
| url = self.get_update_url(ds.url(), desired.builder_version) |
| provisioner.ChromiumOSProvisioner(url, |
| host=device_host).run_provision() |