# 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 logging, json from autotest_lib.client.bin import test, utils from autotest_lib.client.common_lib import error from autotest_lib.client.cros.networking.chrome_testing \ import chrome_networking_test_context as cntc from autotest_lib.client.cros.networking.chrome_testing \ import chrome_networking_test_api as cnta from autotest_lib.client.cros.networking.chrome_testing import test_utils from autotest_lib.client.cros.power import sys_power from collections import namedtuple NetworkInfo = namedtuple('NetworkInfo', ['name', 'guid', 'connectionState', 'networkType']) class network_ChromeCellularEndToEnd(test.test): """ Tests the following UI functionality with chrome.networkingPrivate APIs: 1. Tests that the device auto connects to cellular network. 3. Tests that the device prefers ethernet over cellular network. 4. Tests that the enabling and disabling of cellular modem works. """ version = 1 def _extract_network_info(self, networks_found): """Extract the needed information from the list of networks. @param networks_found: Networks found via api. @return Formatted list of available cellular networks. """ formatted_network_list = [] for network in networks_found: network = NetworkInfo(name=network['Name'], guid=network['GUID'], connectionState=network.get('ConnectionState', 'none'), networkType=network['Type']) formatted_network_list.append(network) return formatted_network_list def _set_autoconnect(self, service, value=True): """Turn on autoconnect for cellular network. @param service: Cellular service dictionary @value: Set / unset autoconnect """ logging.debug('_set_autoconnect') properties = json.dumps({'Cellular': {'AutoConnect': value}}) set_properties = test_utils.call_test_function_check_success( self._chrome_testing, 'setProperties', ('"' + service['GUID'] + '"', properties)) self.chrome_net.scan_for_networks() def _is_cellular_network_connected(self, service): """Check if device is connected to cellular network. @param service: Cellular service dict @return True if connected to cellular, else False """ network_properties = self.chrome_net._chrome_testing.call_test_function( test_utils.LONG_TIMEOUT, 'getNetworkInfo', ('"' + service['GUID'] + '"')) logging.debug('Network properties: %s', network_properties) if network_properties['status'] == 'chrome-test-call-status-failure': raise error.TestFail('getNetworkInfo did not return with status ' 'SUCCESS: %s' % network_properties['error']) if network_properties['result']['ConnectionState'] == 'Connected': return True return False def _cellular_service(self): """Find cellular service. @return Cellular service dict """ cell_networks = self.chrome_net._chrome_testing.find_cellular_networks() for service in cell_networks: if service['GUID']: return service return None def _find_cellular_service(self): """Find and return cellular service if available. @return Cellular service """ utils.poll_for_condition(lambda: self._cellular_service() is not None, exception=error.TestFail('No cell service.'), sleep_interval=1, timeout=60) return self._cellular_service() def _connect_to_cellular_network(self, service): """Connect to cellular network. @param service: Cellular service dict """ logging.debug('_connect_to_cellular_network') if service is None: raise error.TestFail('GUID not available for cellular network.') self.chrome_net.connect_to_network(service) self.chrome_net.scan_for_networks() def _autoconnect_cellular(self): """Verify that the DUT is able to autoconnect to cellular network.""" logging.debug('_autoconnect_cellular') service = self._find_cellular_service() logging.debug('Cellular service: %s', service) if service['ConnectionState'] == 'NotConnected': self._connect_to_cellular_network(service) self._set_autoconnect(service) logging.debug('Suspend and resume device') sys_power.do_suspend(20) service = self._find_cellular_service() utils.poll_for_condition( lambda: self._is_cellular_network_connected(service), exception=error.TestFail('Network not connected after suspend ' 'and resume.'), sleep_interval=1, timeout=60) logging.debug('Autoconnect works after suspend/resume.') def _get_networks(self, network_type='All'): """Get available networks with getNetworks api. @param network_type: Type of network, defaults to All @return List of networks found """ logging.debug('_get_networks') properties = json.dumps({'networkType': network_type, 'visible': True, 'limit': 2}) network_list = self.chrome_net._chrome_testing.call_test_function( test_utils.LONG_TIMEOUT, 'getNetworks', (properties)) return network_list def _ethernet_preferred_over_cellular(self): """Verify that the DUT prefers ethernet over cellular connection.""" logging.debug('_ethernet_preferred_over_cellular') self.chrome_net.disable_network_device(self.chrome_net.WIFI_DEVICE) network_list = self._get_networks() if not len(network_list['result']) > 1: logging.debug('Available networks: %s', network_list) raise error.TestFail('Not enough networks available to check ' 'network preference. Need minimum 2 networks ' 'to do a successfull comparision.') formatted_network_list = self._extract_network_info( network_list['result']) logging.debug('Available network list: %s', formatted_network_list) if not formatted_network_list[0].networkType == 'Ethernet': raise error.TestFail('Ethernet is not preferred.') if not formatted_network_list[1].networkType == 'Cellular': raise error.TestFail('Cellular is not available to determine ' 'network preference.') if (not formatted_network_list[0].connectionState == 'Connected' or not formatted_network_list[1].connectionState == 'Connected'): raise error.TestFail('Ethernet and Cellular should both be ' 'connected to successfully determine ' 'network preference.') logging.debug('Ethernet is preferred over cellular.') def _enable_disable_network_check( self, original_enabled_networks, new_enabled_networks): """Tests enabling and disabling of Cellular. @param original_enabled_networks: Original list of network devices that were enabled when the test started. @param new_enabled_networks: New list of network devices that are enabled now. @raises error.TestFail if Cellular state is not toggled. """ # Make sure we leave the Cellular modem in enabled state before # ending the test. logging.debug('_enable_disable_network_check') self.chrome_net.enable_network_device(self.chrome_net.CELLULAR) if self.chrome_net.CELLULAR in original_enabled_networks: if self.chrome_net.CELLULAR in new_enabled_networks: raise error.TestFail('Cellular was not disabled.') elif self.chrome_net.CELLULAR not in new_enabled_networks: logging.info('Cellular was successfully disabled.') if self.chrome_net.CELLULAR not in original_enabled_networks: if self.chrome_net.CELLULAR not in new_enabled_networks: raise error.TestFail('Cellular was not enabled.') elif self.chrome_net.CELLULAR in new_enabled_networks: logging.info('Cellular was successfully enabled.') def _enable_disable_cellular(self): """Verify that the test is able to enable and disable Cellular.""" logging.debug('_enable_disable_cellular') original_enabled_networks = self.chrome_net.get_enabled_devices() if self.chrome_net.CELLULAR in original_enabled_networks: self.chrome_net.disable_network_device(self.chrome_net.CELLULAR) else: self.chrome_net.enable_network_device(self.chrome_net.CELLULAR) new_enabled_networks = self.chrome_net.get_enabled_devices() self._enable_disable_network_check( original_enabled_networks, new_enabled_networks) def run_once(self, test): """Runs the test. @param test: Set by the server test control file depending on the test that is being run. """ with cntc.ChromeNetworkingTestContext() as testing_context: self._chrome_testing = testing_context self.chrome_net = cnta.ChromeNetworkProvider(testing_context) enabled_devices = self.chrome_net.get_enabled_devices() logging.debug('Enabled devices: %s', enabled_devices) if (self.chrome_net.CELLULAR not in enabled_devices): self.chrome_net.enable_network_device( self.chrome_net.CELLULAR) self.chrome_net.scan_for_networks() if test == 'autoconnectCellular': self._autoconnect_cellular() elif test == 'ethernetPreferred': self._ethernet_preferred_over_cellular() elif test == 'enableDisableCellular': self._enable_disable_cellular()