• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
5import logging, json
6
7from autotest_lib.client.bin import test, utils
8from autotest_lib.client.common_lib import error
9from autotest_lib.client.cros import sys_power
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 collections import namedtuple
16
17NetworkInfo = namedtuple('NetworkInfo', ['name', 'guid', 'connectionState',
18                                         'networkType'])
19
20class 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