1# Copyright (c) 2012 The Chromium 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 copy 6import dbus 7import logging 8import os 9import time 10 11from chromeos.power_strip import PowerStrip 12import pyauto 13import pyauto_errors 14 15class PyNetworkUITest(pyauto.PyUITest): 16 """A subclass of PyUITest for Chrome OS network tests. 17 18 A subclass of PyUITest that automatically sets the flimflam 19 priorities to put wifi connections first before starting tests. 20 This is for convenience when writing wifi tests. 21 """ 22 _ROUTER_CONFIG_FILE = os.path.join(pyauto.PyUITest.DataDir(), 23 'pyauto_private', 'chromeos', 'network', 24 'wifi_testbed_config') 25 _FLIMFLAM_PATH = 'org.chromium.flimflam' 26 27 def setUp(self): 28 self.CleanupFlimflamDirsOnChromeOS() 29 # Move ethernet to the end of the flimflam priority list, 30 # effectively hiding any ssh connections that the 31 # test harness might be using and putting wifi ahead. 32 self._PushServiceOrder('wifi,ethernet') 33 self._ParseDefaultRoutingTable() 34 pyauto.PyUITest.setUp(self) 35 36 def tearDown(self): 37 pyauto.PyUITest.tearDown(self) 38 self._PopServiceOrder() 39 # Remove the route entry for the power strip. 40 if hasattr(self, 'ps_route_entry'): 41 os.system('route del -net %(ipaddress)s gateway %(gateway)s netmask ' 42 '%(netmask)s dev %(iface)s' % self.ps_route_entry) 43 44 def _GetFlimflamManager(self): 45 _proxy = dbus.SystemBus().get_object(self._FLIMFLAM_PATH, '/') 46 return dbus.Interface(_proxy, self._FLIMFLAM_PATH + '.Manager') 47 48 def _ParseDefaultRoutingTable(self): 49 """Creates and stores a dictionary of the default routing paths.""" 50 route_table_headers = ['destination', 'gateway', 'genmask', 'flags', 51 'metric', 'ref', 'use', 'iface'] 52 routes = os.popen('route -n | egrep "^0.0.0.0"').read() 53 routes = [interface.split() for interface in routes.split('\n')][:-1] 54 self.default_routes = {} 55 for iface in routes: 56 self.default_routes[iface[-1]] = dict(zip(route_table_headers, iface)) 57 58 def _SetServiceOrder(self, service_order): 59 self._GetFlimflamManager().SetServiceOrder(service_order) 60 # Flimflam throws a dbus exception if device is already disabled. This 61 # is not an error. 62 try: 63 self._GetFlimflamManager().DisableTechnology('wifi') 64 except dbus.DBusException as e: 65 if 'org.chromium.flimflam.Error.AlreadyDisabled' not in str(e): 66 raise e 67 self._GetFlimflamManager().EnableTechnology('wifi') 68 69 def _PushServiceOrder(self, service_order): 70 self._old_service_order = self._GetFlimflamManager().GetServiceOrder() 71 self._SetServiceOrder(service_order) 72 service_order = service_order.split(',') 73 74 # Verify services that are present in both the service_order 75 # we set and the one retrieved from device are in the correct order. 76 set_service_order = self._GetFlimflamManager().GetServiceOrder().split(',') 77 common_service = set(service_order) & set(set_service_order) 78 79 service_order = [s for s in service_order if s in common_service] 80 set_service_order = [s for s in set_service_order if s in common_service] 81 82 assert service_order == set_service_order, \ 83 'Flimflam service order not set properly. %s != %s' % \ 84 (service_order, set_service_order) 85 86 def _PopServiceOrder(self): 87 self._SetServiceOrder(self._old_service_order) 88 89 # Verify services that are present in both the service_order 90 # we set and the one retrieved from device are in the correct order. 91 old_service_order = self._old_service_order.split(',') 92 set_service_order = self._GetFlimflamManager().GetServiceOrder().split(',') 93 common_service = set(old_service_order) & set(set_service_order) 94 95 old_service_order = [s for s in old_service_order if s in common_service] 96 set_service_order = [s for s in set_service_order if s in common_service] 97 98 assert old_service_order == set_service_order, \ 99 'Flimflam service order not set properly. %s != %s' % \ 100 (old_service_order, set_service_order) 101