blob: 0a751b1199be68daab09c13fe27ca1614d1263e7 [file] [log] [blame]
Alex Deymoa7b7c2b2013-11-06 11:58:55 -08001# Copyright (c) 2013 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
6import os
7import shutil
8
9from autotest_lib.client.common_lib import error, utils
Christopher Wileyb1a5bdb2015-02-02 14:56:18 -080010from autotest_lib.client.common_lib.cros import avahi_utils
11from autotest_lib.client.cros import service_stopper, tcpdump
Alex Deymoa7b7c2b2013-11-06 11:58:55 -080012
13
14P2P_SHARE_PATH = '/var/cache/p2p'
15
16# A path used to store the existing p2p files during the test and restore them
17# once the test finishes.
18P2P_SHARE_BACKUP_PATH = '/var/cache/p2p-backup'
19
20
21def p2p_backup_files(backup_path=P2P_SHARE_BACKUP_PATH):
22 """Backup the P2P shared files and create an empty shared directory.
23
24 p2p-server shall not be running during backup or restore.
25
26 @param backup_path: The path where the files will be moved to.
27 @raise error.TestError
28 """
29 try:
30 if os.path.exists(backup_path):
31 shutil.rmtree(backup_path)
32 if os.path.exists(P2P_SHARE_PATH):
33 os.rename(P2P_SHARE_PATH, backup_path)
34 except OSError, e:
35 raise error.TestError("Error on P2P files backup: %s" % (e.message))
36
37
38def p2p_restore_files(backup_path=P2P_SHARE_BACKUP_PATH):
39 """Restore the P2P shared files from a backup and *delete* the backup.
40
41 p2p-server shall not be running during backup or restore.
42
43 @param backup_path: The path where the files will be moved from.
44 """
45 if os.path.exists(P2P_SHARE_PATH):
46 shutil.rmtree(P2P_SHARE_PATH, ignore_errors=True)
47 if os.path.exists(backup_path):
48 os.rename(backup_path, P2P_SHARE_PATH)
49
50
51class P2PServerOverTap(object):
52 """Manage a p2p-server instance running over a TAP interface.
53
54 This class manages a p2p-server instance configured to run over a TAP
55 interface, useful for any test that needs to interact with the p2p-server
56 (and its p2p-http-server instance) on a controled network environment.
57 """
58 def __init__(self, tap_ip='169.254.10.1', tap_mask=24, tap_name='faketap'):
59 """Initialize the configuration.
60
61 @param tap_ip: IPv4 address for the TAP interface on the DUT's end.
62 @param tap_mask: Network mask fot the tap_ip address.
63 @param tap_name: The name prefix for the TAP interface.
64 """
65 # The network 169.254/16 shouldn't clash with other real services and we
66 # use a /24 subnet of it as the default safe value here.
67 self._tap_ip = tap_ip
68 self._tap_mask = tap_mask
69 self._tap_name = tap_name
70 self._services = None
71 self.tap = None
Alex Deymoa25ea0d2013-12-27 12:42:34 -080072 self._tcpdump = None
Alex Deymoa7b7c2b2013-11-06 11:58:55 -080073
74
Alex Deymoa25ea0d2013-12-27 12:42:34 -080075 def setup(self, dumpdir=None):
76 """Initializes avahi daemon on a new tap interface.
77
78 @param dumpdir: Directory where the traffic on the new tap interface
79 is recorded. A value of None disables traffic dumping.
80 """
Alex Deymoa7b7c2b2013-11-06 11:58:55 -080081 try:
82 from lansim import tuntap
83 except ImportError:
84 logging.exception('Failed to import lansim.')
85 raise error.TestError('Error importing lansim. Did you setup_dep '
86 'and install_pkg lansim on your test?')
87
88 # Ensure p2p and avahi aren't running.
89 self._services = service_stopper.ServiceStopper(['p2p', 'avahi'])
90 self._services.stop_services()
91
92 # Backup p2p files.
93 p2p_backup_files()
94
95 # Initialize the TAP interface.
96 self.tap = tuntap.TunTap(tuntap.IFF_TAP, name=self._tap_name)
97 self.tap.set_addr(self._tap_ip, self._tap_mask)
98 self.tap.up()
99
Alex Deymoa25ea0d2013-12-27 12:42:34 -0800100 # Enable traffic dump.
101 if not dumpdir is None:
102 dumpfile = os.path.join(dumpdir, 'dump-%s.pcap' % self.tap.name)
103 self._tcpdump = tcpdump.Tcpdump(self.tap.name, dumpfile)
104
Alex Deymoa7b7c2b2013-11-06 11:58:55 -0800105 # Re-launch avahi-daemon on the TAP interface only.
106 avahi_utils.avahi_start_on_iface(self.tap.name)
107 utils.system("start p2p")
108
109
110 def cleanup(self):
111 """Restore the original environment as before the call to setup().
112
113 This method makes a best-effort attempt to restore the environment and
114 logs all the errors encountered but doesn't fail.
115 """
116 try:
117 utils.system('stop p2p')
118 avahi_utils.avahi_stop()
119 except:
120 logging.exception('Failed to stop tested services.')
121
Alex Deymoa25ea0d2013-12-27 12:42:34 -0800122 if self._tcpdump:
123 self._tcpdump.stop()
124
Alex Deymoa7b7c2b2013-11-06 11:58:55 -0800125 if self.tap:
126 self.tap.down()
127
128 # Restore p2p files.
129 try:
130 p2p_restore_files()
131 except OSError:
132 logging.exception('Failed to restore the P2P backup.')
133
134 if self._services:
135 self._services.restore_services()