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