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