• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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