Home | History | Annotate | Download | only in p2p_ShareFiles
      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 sys
      8 
      9 from autotest_lib.client.bin import test
     10 from autotest_lib.client.common_lib import error
     11 from autotest_lib.client.cros import p2p_utils
     12 from autotest_lib.client.cros.netprotos import cros_p2p, zeroconf
     13 
     14 
     15 class p2p_ShareFiles(test.test):
     16     """The P2P Server class tester.
     17 
     18     This class runs the p2p service (p2p-server and p2p-http-server) and checks
     19     that the DUT is sharing the files on the network.
     20     """
     21     version = 1
     22 
     23     def setup(self):
     24         self.job.setup_dep(['lansim'])
     25 
     26 
     27     def initialize(self):
     28         dep = 'lansim'
     29         dep_dir = os.path.join(self.autodir, 'deps', dep)
     30         logging.info('lansim is at %s', dep_dir)
     31         self.job.install_pkg(dep, 'dep', dep_dir)
     32 
     33         # Import the lansim modules installed on lansim/build/
     34         sys.path.append(os.path.join(dep_dir, 'build'))
     35 
     36         self._p2p = p2p_utils.P2PServerOverTap()
     37 
     38 
     39     def cleanup(self):
     40         self._p2p.cleanup()
     41 
     42 
     43     def _run_lansim_loop(self, timeout=None, until=None):
     44         """Run the Simulator main loop for a given time."""
     45         try:
     46             self._sim.run(timeout=timeout, until=until)
     47         except Exception, e:
     48             logging.exception('Simulator ended with an exception:')
     49             raise error.TestError('Simulator ended with an exception: %r' % e)
     50 
     51 
     52     def run_once(self):
     53         from lansim import simulator, host
     54 
     55         # Setup the environment where avahi-daemon runs during the test.
     56         try:
     57             self._p2p.setup()
     58         except:
     59             logging.exception('Failed to start tested services.')
     60             raise
     61 
     62         self._sim = simulator.Simulator(self._p2p.tap)
     63         # Create a single fake peer that will be sending the multicast requests.
     64         peer = host.SimpleHost(self._sim, '94:EB:2C:00:00:61', '169.254.10.97')
     65 
     66         # Run a userspace implementation of avahi + p2p-client on the fake
     67         # host. This will use the P2P services exported by the DUT.
     68         zero = zeroconf.ZeroconfDaemon(peer, 'a-peer')
     69         p2pcli = cros_p2p.CrosP2PClient(zero)
     70 
     71         # On p2p-server startup, it should announce the service even if we
     72         # aren't sharing any file. Usually it doesn't take more than 2 seconds
     73         # to start announcing the service, repeated a few times.
     74         self._run_lansim_loop(timeout=20, until=p2pcli.get_peers())
     75         # Check that we see the DUT on the list of peers.
     76         peers = p2pcli.get_peers()
     77         if len(peers) != 1:
     78             logging.info('Found peers: %r', peers)
     79             raise error.TestFail('Expected one peer (the DUT) but %d found.' %
     80                                  len(peers))
     81 
     82         # Check that the announced information is correct.
     83         peer_name, _hostname, ips, port = peers[0]
     84         if len(ips) != 1 or ips[0] != self._p2p.tap.addr:
     85             logging.info('Peer ips: %r', ips)
     86             raise error.TestFail('Found wrong peer IP address on the DUT.')
     87         if port != cros_p2p.CROS_P2P_PORT:
     88             logging.info('Peer p2p port is: %r', port)
     89             raise error.TestFail('Found wrong p2p port exported on the DUT.')
     90 
     91         files = p2pcli.get_peer_files(peer_name)
     92         if files:
     93             logging.info('Peer files: %r', files)
     94             raise error.TestFail('Found exported files on the DUT.')
     95 
     96         num_connections = p2pcli.get_peer_connections(peer_name)
     97         if num_connections:
     98             logging.info('Peer connections: %r', num_connections)
     99             raise error.TestFail('DUT already has p2p connections.')
    100 
    101         # Share a small file and check that it is broadcasted.
    102         with open(os.path.join(p2p_utils.P2P_SHARE_PATH, 'my_file=HASH==.p2p'),
    103                   'w') as f:
    104             f.write('0123456789')
    105 
    106         # Run the loop until the file is shared. Normally, the p2p-server takes
    107         # up to 1 second to detect a change on the shared directory and
    108         # announces it right away a few times. Wait until the file is announced,
    109         # what should not take more than a few seconds. If after 30 seconds the
    110         # files isn't announced, that is an error.
    111         self._run_lansim_loop(timeout=30,
    112                               until=lambda: p2pcli.get_peer_files(peer_name))
    113 
    114         files = p2pcli.get_peer_files(peer_name)
    115         if files != [('my_file=HASH==', 10)]:
    116             logging.info('Peer files: %r', files)
    117             raise error.TestFail('Expected exported file on the DUT.')
    118 
    119         # Test that the DUT replies to active requests.
    120         zero.clear_cache()
    121         p2pcli.start_query()
    122         # A query can be replied by several peers after it is send, but there's
    123         # no one-to-one mapping between these two. A query simply forces other
    124         # peers to send the requested information shortly after. Thus, here we
    125         # just wait a few seconds until we decide that the query timeouted.
    126         self._run_lansim_loop(timeout=3)
    127         p2pcli.stop_query()
    128 
    129         files = p2pcli.get_peer_files(peer_name)
    130         if files != [('my_file=HASH==', 10)]:
    131             logging.info('Peer files: %r', files)
    132             raise error.TestFail('Expected exported file on the DUT.')
    133