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