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