1# Lint as: python2, python3 2# Copyright 2015 The Chromium OS Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6import logging, json 7 8from autotest_lib.client.bin import test, utils 9from autotest_lib.client.common_lib import error 10from autotest_lib.client.cros.networking.chrome_testing \ 11 import chrome_networking_test_context as cntc 12from autotest_lib.client.cros.networking.chrome_testing \ 13 import chrome_networking_test_api as cnta 14from autotest_lib.client.cros.networking.chrome_testing import test_utils 15from autotest_lib.client.cros.power import sys_power 16from collections import namedtuple 17 18NetworkInfo = namedtuple('NetworkInfo', ['name', 'guid', 'connectionState', 19 'networkType']) 20 21class network_ChromeCellularEndToEnd(test.test): 22 """ 23 Tests the following UI functionality with chrome.networkingPrivate APIs: 24 1. Tests that the device auto connects to cellular network. 25 3. Tests that the device prefers ethernet over cellular network. 26 4. Tests that the enabling and disabling of cellular modem works. 27 28 """ 29 version = 1 30 31 32 def _extract_network_info(self, networks_found): 33 """Extract the needed information from the list of networks. 34 35 @param networks_found: Networks found via api. 36 @return Formatted list of available cellular networks. 37 38 """ 39 formatted_network_list = [] 40 41 for network in networks_found: 42 network = NetworkInfo(name=network['Name'], 43 guid=network['GUID'], 44 connectionState=network.get('ConnectionState', 'none'), 45 networkType=network['Type']) 46 formatted_network_list.append(network) 47 48 return formatted_network_list 49 50 51 def _set_autoconnect(self, service, value=True): 52 """Turn on autoconnect for cellular network. 53 54 @param service: Cellular service dictionary 55 @value: Set / unset autoconnect 56 57 """ 58 logging.debug('_set_autoconnect') 59 properties = json.dumps({'Cellular': {'AutoConnect': value}}) 60 set_properties = test_utils.call_test_function_check_success( 61 self._chrome_testing, 62 'setProperties', 63 ('"' + service['GUID'] + '"', properties)) 64 self.chrome_net.scan_for_networks() 65 66 67 def _is_cellular_network_connected(self, service): 68 """Check if device is connected to cellular network. 69 70 @param service: Cellular service dict 71 @return True if connected to cellular, else False 72 73 """ 74 network_properties = self.chrome_net._chrome_testing.call_test_function( 75 test_utils.LONG_TIMEOUT, 76 'getNetworkInfo', 77 ('"' + service['GUID'] + '"')) 78 79 logging.debug('Network properties: %s', network_properties) 80 81 if network_properties['status'] == 'chrome-test-call-status-failure': 82 raise error.TestFail('getNetworkInfo did not return with status ' 83 'SUCCESS: %s' % network_properties['error']) 84 85 if network_properties['result']['ConnectionState'] == 'Connected': 86 return True 87 88 return False 89 90 91 def _cellular_service(self): 92 """Find cellular service. 93 94 @return Cellular service dict 95 96 """ 97 cell_networks = self.chrome_net._chrome_testing.find_cellular_networks() 98 for service in cell_networks: 99 if service['GUID']: 100 return service 101 102 return None 103 104 105 def _find_cellular_service(self): 106 """Find and return cellular service if available. 107 108 @return Cellular service 109 110 """ 111 utils.poll_for_condition(lambda: self._cellular_service() is not None, 112 exception=error.TestFail('No cell service.'), 113 sleep_interval=1, 114 timeout=60) 115 return self._cellular_service() 116 117 118 def _connect_to_cellular_network(self, service): 119 """Connect to cellular network. 120 121 @param service: Cellular service dict 122 123 """ 124 logging.debug('_connect_to_cellular_network') 125 if service is None: 126 raise error.TestFail('GUID not available for cellular network.') 127 self.chrome_net.connect_to_network(service) 128 self.chrome_net.scan_for_networks() 129 130 131 def _autoconnect_cellular(self): 132 """Verify that the DUT is able to autoconnect to cellular network.""" 133 logging.debug('_autoconnect_cellular') 134 service = self._find_cellular_service() 135 logging.debug('Cellular service: %s', service) 136 137 if service['ConnectionState'] == 'NotConnected': 138 self._connect_to_cellular_network(service) 139 140 self._set_autoconnect(service) 141 142 logging.debug('Suspend and resume device') 143 sys_power.do_suspend(20) 144 service = self._find_cellular_service() 145 146 utils.poll_for_condition( 147 lambda: self._is_cellular_network_connected(service), 148 exception=error.TestFail('Network not connected after suspend ' 149 'and resume.'), 150 sleep_interval=1, 151 timeout=60) 152 logging.debug('Autoconnect works after suspend/resume.') 153 154 155 def _get_networks(self, network_type='All'): 156 """Get available networks with getNetworks api. 157 158 @param network_type: Type of network, defaults to All 159 @return List of networks found 160 161 """ 162 logging.debug('_get_networks') 163 properties = json.dumps({'networkType': network_type, 164 'visible': True, 165 'limit': 2}) 166 network_list = self.chrome_net._chrome_testing.call_test_function( 167 test_utils.LONG_TIMEOUT, 168 'getNetworks', 169 (properties)) 170 return network_list 171 172 173 def _ethernet_preferred_over_cellular(self): 174 """Verify that the DUT prefers ethernet over cellular connection.""" 175 logging.debug('_ethernet_preferred_over_cellular') 176 self.chrome_net.disable_network_device(self.chrome_net.WIFI_DEVICE) 177 network_list = self._get_networks() 178 179 if not len(network_list['result']) > 1: 180 logging.debug('Available networks: %s', network_list) 181 raise error.TestFail('Not enough networks available to check ' 182 'network preference. Need minimum 2 networks ' 183 'to do a successfull comparision.') 184 185 formatted_network_list = self._extract_network_info( 186 network_list['result']) 187 188 logging.debug('Available network list: %s', formatted_network_list) 189 190 if not formatted_network_list[0].networkType == 'Ethernet': 191 raise error.TestFail('Ethernet is not preferred.') 192 193 if not formatted_network_list[1].networkType == 'Cellular': 194 raise error.TestFail('Cellular is not available to determine ' 195 'network preference.') 196 197 if (not formatted_network_list[0].connectionState == 'Connected' or 198 not formatted_network_list[1].connectionState == 'Connected'): 199 raise error.TestFail('Ethernet and Cellular should both be ' 200 'connected to successfully determine ' 201 'network preference.') 202 203 logging.debug('Ethernet is preferred over cellular.') 204 205 206 def _enable_disable_network_check( 207 self, original_enabled_networks, new_enabled_networks): 208 """Tests enabling and disabling of Cellular. 209 210 @param original_enabled_networks: Original list of network devices that 211 were enabled when the test started. 212 @param new_enabled_networks: New list of network devices that are 213 enabled now. 214 @raises error.TestFail if Cellular state is not toggled. 215 216 """ 217 # Make sure we leave the Cellular modem in enabled state before 218 # ending the test. 219 logging.debug('_enable_disable_network_check') 220 self.chrome_net.enable_network_device(self.chrome_net.CELLULAR) 221 222 if self.chrome_net.CELLULAR in original_enabled_networks: 223 if self.chrome_net.CELLULAR in new_enabled_networks: 224 raise error.TestFail('Cellular was not disabled.') 225 elif self.chrome_net.CELLULAR not in new_enabled_networks: 226 logging.info('Cellular was successfully disabled.') 227 228 if self.chrome_net.CELLULAR not in original_enabled_networks: 229 if self.chrome_net.CELLULAR not in new_enabled_networks: 230 raise error.TestFail('Cellular was not enabled.') 231 elif self.chrome_net.CELLULAR in new_enabled_networks: 232 logging.info('Cellular was successfully enabled.') 233 234 235 def _enable_disable_cellular(self): 236 """Verify that the test is able to enable and disable Cellular.""" 237 logging.debug('_enable_disable_cellular') 238 original_enabled_networks = self.chrome_net.get_enabled_devices() 239 if self.chrome_net.CELLULAR in original_enabled_networks: 240 self.chrome_net.disable_network_device(self.chrome_net.CELLULAR) 241 else: 242 self.chrome_net.enable_network_device(self.chrome_net.CELLULAR) 243 new_enabled_networks = self.chrome_net.get_enabled_devices() 244 self._enable_disable_network_check( 245 original_enabled_networks, new_enabled_networks) 246 247 248 def run_once(self, test): 249 """Runs the test. 250 251 @param test: Set by the server test control file depending on the test 252 that is being run. 253 254 """ 255 with cntc.ChromeNetworkingTestContext() as testing_context: 256 self._chrome_testing = testing_context 257 self.chrome_net = cnta.ChromeNetworkProvider(testing_context) 258 enabled_devices = self.chrome_net.get_enabled_devices() 259 260 logging.debug('Enabled devices: %s', enabled_devices) 261 if (self.chrome_net.CELLULAR not in enabled_devices): 262 self.chrome_net.enable_network_device( 263 self.chrome_net.CELLULAR) 264 self.chrome_net.scan_for_networks() 265 266 if test == 'autoconnectCellular': 267 self._autoconnect_cellular() 268 elif test == 'ethernetPreferred': 269 self._ethernet_preferred_over_cellular() 270 elif test == 'enableDisableCellular': 271 self._enable_disable_cellular() 272