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