Example #1
0
 def initialize(self):
     # Make sure these are initiallized to None in case we throw
     # during self.initialize().
     self._chrooted_avahi = None
     self._peerd = None
     self._host = None
     self._zc_listener = None
     self._chrooted_avahi = chrooted_avahi.ChrootedAvahi()
     self._chrooted_avahi.start()
     # Start up a fresh copy of peerd with really verbose logging.
     self._peerd = peerd_dbus_helper.make_helper(
             peerd_config.PeerdConfig(verbosity_level=3))
     # Listen on our half of the interface pair for mDNS advertisements.
     self._host = interface_host.InterfaceHost(
             self._chrooted_avahi.unchrooted_interface_name)
     self._zc_listener = zeroconf.ZeroconfDaemon(self._host,
                                                 self.FAKE_HOST_HOSTNAME)
     # The queries for hostname/dns_domain are IPCs and therefore relatively
     # expensive.  Do them just once.
     hostname = self._chrooted_avahi.hostname
     dns_domain = self._chrooted_avahi.dns_domain
     if not hostname or not dns_domain:
         raise error.TestFail('Failed to get hostname/domain from avahi.')
     self._dns_domain = dns_domain
     self._hostname = '%s.%s' % (hostname, dns_domain)
Example #2
0
 def initialize(self):
     # Make sure these are initiallized to None in case we throw
     # during self.initialize().
     self._chrooted_avahi = None
     self._peerd = None
     self._host = None
     self._zc_listener = None
     self._chrooted_avahi = chrooted_avahi.ChrootedAvahi()
     self._chrooted_avahi.start()
     self.reset_peerd()
     # Listen on our half of the interface pair for mDNS advertisements.
     self._host = interface_host.InterfaceHost(
             self._chrooted_avahi.unchrooted_interface_name)
     self._zc_listener = zeroconf.ZeroconfDaemon(self._host,
                                                 self.FAKE_HOST_HOSTNAME)
     # The queries for hostname/dns_domain are IPCs and therefor relatively
     # expensive.  Do them just once.
     hostname = self._chrooted_avahi.hostname
     dns_domain = self._chrooted_avahi.dns_domain
     if not hostname or not dns_domain:
         raise error.TestFail('Failed to get hostname/domain from avahi.')
     self._dns_domain = dns_domain
     self._hostname = '%s.%s' % (hostname, dns_domain)
     self._last_cache_refresh_seconds = 0
    def run_once(self):
        from lansim import simulator, host

        # Setup the environment where avahi-daemon runs during the test.
        try:
            self._p2p.setup()
        except:
            logging.exception('Failed to start tested services.')
            raise

        self._sim = simulator.Simulator(self._p2p.tap)
        # Create a single fake peer that will be sending the multicast requests.
        peer = host.SimpleHost(self._sim, '94:EB:2C:00:00:61', '169.254.10.97')

        # Run a userspace implementation of avahi + p2p-client on the fake
        # host. This will use the P2P services exported by the DUT.
        zero = zeroconf.ZeroconfDaemon(peer, 'a-peer')
        p2pcli = cros_p2p.CrosP2PClient(zero)

        # On p2p-server startup, it should announce the service even if we
        # aren't sharing any file. Usually it doesn't take more than 2 seconds
        # to start announcing the service, repeated a few times.
        self._run_lansim_loop(timeout=20, until=p2pcli.get_peers())
        # Check that we see the DUT on the list of peers.
        peers = p2pcli.get_peers()
        if len(peers) != 1:
            logging.info('Found peers: %r', peers)
            raise error.TestFail('Expected one peer (the DUT) but %d found.' %
                                 len(peers))

        # Check that the announced information is correct.
        peer_name, _hostname, ips, port = peers[0]
        if len(ips) != 1 or ips[0] != self._p2p.tap.addr:
            logging.info('Peer ips: %r', ips)
            raise error.TestFail('Found wrong peer IP address on the DUT.')
        if port != cros_p2p.CROS_P2P_PORT:
            logging.info('Peer p2p port is: %r', port)
            raise error.TestFail('Found wrong p2p port exported on the DUT.')

        files = p2pcli.get_peer_files(peer_name)
        if files:
            logging.info('Peer files: %r', files)
            raise error.TestFail('Found exported files on the DUT.')

        num_connections = p2pcli.get_peer_connections(peer_name)
        if num_connections:
            logging.info('Peer connections: %r', num_connections)
            raise error.TestFail('DUT already has p2p connections.')

        # Share a small file and check that it is broadcasted.
        with open(os.path.join(p2p_utils.P2P_SHARE_PATH, 'my_file=HASH==.p2p'),
                  'w') as f:
            f.write('0123456789')

        # Run the loop until the file is shared. Normally, the p2p-server takes
        # up to 1 second to detect a change on the shared directory and
        # announces it right away a few times. Wait until the file is announced,
        # what should not take more than a few seconds. If after 30 seconds the
        # files isn't announced, that is an error.
        self._run_lansim_loop(timeout=30,
                              until=lambda: p2pcli.get_peer_files(peer_name))

        files = p2pcli.get_peer_files(peer_name)
        if files != [('my_file=HASH==', 10)]:
            logging.info('Peer files: %r', files)
            raise error.TestFail('Expected exported file on the DUT.')

        # Test that the DUT replies to active requests.
        zero.clear_cache()
        p2pcli.start_query()
        # A query can be replied by several peers after it is send, but there's
        # no one-to-one mapping between these two. A query simply forces other
        # peers to send the requested information shortly after. Thus, here we
        # just wait a few seconds until we decide that the query timeouted.
        self._run_lansim_loop(timeout=3)
        p2pcli.stop_query()

        files = p2pcli.get_peer_files(peer_name)
        if files != [('my_file=HASH==', 10)]:
            logging.info('Peer files: %r', files)
            raise error.TestFail('Expected exported file on the DUT.')
Example #4
0
    def run_once(self):
        from lansim import simulator, host

        # Setup the environment where avahi-daemon runs during the test.
        self._setup_avahi()

        self._sim = simulator.SimulatorThread(self._tap)
        # Create three peers host-a, host-b and host-c sharing a set of files.
        # This first block creates the fake host on the simulator. For clarity
        # and easier debug, note that the last octect on the IPv4 address is the
        # ASCII for a, b and c respectively.
        peer_a = host.SimpleHost(self._sim, '94:EB:2C:00:00:61',
                                 '169.254.10.97')
        peer_b = host.SimpleHost(self._sim, '94:EB:2C:00:00:62',
                                 '169.254.10.98')
        peer_c = host.SimpleHost(self._sim, '94:EB:2C:00:00:63',
                                 '169.254.10.99')

        # Run a userspace implementation of avahi + p2p-server on the fake
        # hosts. This announces the P2P service on each fake host.
        zero_a = zeroconf.ZeroconfDaemon(peer_a, 'host-a')
        zero_b = zeroconf.ZeroconfDaemon(peer_b, 'host-b')
        zero_c = zeroconf.ZeroconfDaemon(peer_c, 'host-c')

        cros_a = cros_p2p.CrosP2PDaemon(zero_a)
        cros_b = cros_p2p.CrosP2PDaemon(zero_b)
        cros_c = cros_p2p.CrosP2PDaemon(zero_c)

        # Add files to each host. All the three hosts share the file "everyone"
        # with different size, used to test the minimum-size argument.
        # host-a and host-b share another file only-a and only-b respectively,
        # used to check that the p2p-client picks the right peer.
        cros_a.add_file('everyone', 1000)
        cros_b.add_file('everyone', 10000)
        cros_c.add_file('everyone', 20000)

        cros_a.add_file('only-a', 5000)

        cros_b.add_file('only-b', 8000)

        # Initially set the number of connections on the network to a low number
        # (two) that later will be increased to test if p2p-client hangs when
        # there are too many connections.
        cros_a.set_num_connections(1)
        cros_c.set_num_connections(1)

        self._sim.start()

        ### Request a file shared from only one peer.
        _ret, url = self._run_p2p_client(args=('--get-url=only-a', ),
                                         timeout=10.)

        if url.strip() != 'http://169.254.10.97:16725/only-a':
            self._join_simulator()
            raise error.TestFail('Received unknown url: "%s"' % url)

        ### Check that the num_connections is reported properly.
        _ret, conns = self._run_p2p_client(args=('--num-connections', ),
                                           timeout=10.)
        if conns.strip() != '2':
            self._join_simulator()
            raise error.TestFail('Wrong number of connections reported: %s' %
                                 conns)

        ### Request a file shared from a peer with enough of the file.
        _ret, url = self._run_p2p_client(args=('--get-url=everyone',
                                               '--minimum-size=15000'),
                                         timeout=10.)

        if url.strip() != 'http://169.254.10.99:16725/everyone':
            self._join_simulator()
            raise error.TestFail('Received unknown url: "%s"' % url)

        ### Request too much bytes of an existing file.
        ret, url = self._run_p2p_client(args=('--get-url=only-b',
                                              '--minimum-size=10000'),
                                        timeout=10.,
                                        ignore_status=True)

        if url:
            self._join_simulator()
            raise error.TestFail('Received url but expected none: "%s"' % url)
        if ret == 0:
            raise error.TestFail('p2p-client returned no URL, but without an '
                                 'error.')

        ### Check that p2p-client hangs while waiting for a peer when there are
        ### too many connections.
        self._sim.run_on_simulator(
            lambda: cros_a.set_num_connections(99, announce=True))

        # For a query on the DUT to check that the new information is received.
        for attempt in range(5):
            _ret, conns = self._run_p2p_client(args=('--num-connections', ),
                                               timeout=10.)
            conns = conns.strip()
            if conns == '100':
                break
        if conns != '100':
            self._join_simulator()
            raise error.TestFail(
                "p2p-client --num-connections doesn't reflect "
                "the current number of connections on the "
                "network, returned %s" % conns)

        ret, url = self._run_p2p_client(args=('--get-url=only-b', ),
                                        timeout=5.,
                                        ignore_status=True)
        if not ret is None:
            self._join_simulator()
            raise error.TestFail('p2p-client finished but should have waited '
                                 'for num_connections to drop.')

        self._sim.stop()
        self._sim.join()

        if self._sim.error:
            raise error.TestError(
                'SimulatorThread ended with an exception: %r' %
                self._sim.error)
    def run_once(self):
        from lansim import simulator, host

        # Setup the environment where avahi-daemon runs during the test.
        try:
            self._p2p.setup(dumpdir=self.job.resultdir)
        except:
            logging.exception('Failed to start tested services.')
            raise

        # Share a file on the DUT.
        content = open('/dev/urandom').read(16 * 1024)
        with open(os.path.join(p2p_utils.P2P_SHARE_PATH, 'file.p2p'),
                  'w') as f:
            f.write(content)

        self._sim = simulator.SimulatorThread(self._p2p.tap)
        # Create a single fake peer that will be sending the multicast requests.
        peer = host.SimpleHost(self._sim, '94:EB:2C:00:00:61', '169.254.10.55')

        # Run a userspace implementation of avahi + p2p-client on the fake
        # host. This will use the P2P services exported by the DUT.
        zero = zeroconf.ZeroconfDaemon(peer, 'peer')
        p2pcli = cros_p2p.CrosP2PClient(zero)

        self._sim.start()

        # Force a request from the client before waiting for the DUT's response.
        self._sim.run_on_simulator(lambda: p2pcli.start_query())

        # Wait up to 30 seconds until the DUT is ready sharing the files.
        res = self._sim.wait_for_condition(lambda: self._dut_ready(p2pcli),
                                           timeout=30.)
        self._sim.run_on_simulator(lambda: p2pcli.stop_query())

        if not res:
            raise error.TestFail('The DUT failed to announce the shared files '
                                 'after 30 seconds.')

        # DUT's p2p-http-server is running on hostname:port.
        peer_name, hostname, ips, port, files = res

        if len(files) != 1 or files[0] != ('file', len(content)) or (
                len(ips) != 1) or ips[0] != self._p2p.tap.addr:
            logging.error('peer_name = %r', peer_name)
            logging.error('hostname = %r', hostname)
            logging.error('ips = %r', ips)
            logging.error('port = %r', port)
            logging.error('files = %r', files)
            raise error.TestFail('The DUT announced an erroneous file.')

        # Check we can't download directly from localhost.
        for host_ip in (ips[0], '127.0.0.1'):
            ret = self._p2p_fetch(host_ip, port, 'file')
            if ret != 7:  # curl's exit code 7 is "Failed to connect to host."
                logging.error('curl returned: %s', repr(ret)[:100])
                raise error.TestFail(
                    "The DUT didn't block a request from localhost using "
                    "the address %s." % host_ip)

        # Check we can download if the connection comes from a peer on the
        # network. To achieve this, we forward the tester's TCP traffic through
        # a fake host on lansim.
        self._sim.run_on_simulator(
            lambda: peer.tcp_forward(1234, ips[0], port))

        ret = self._p2p_fetch(peer.ip_addr, 1234, 'file')
        if ret != content:
            logging.error('curl returned: %s', repr(ret)[:100])
            raise error.TestFail(
                "The DUT didn't serve the file request from %s " %
                peer.id_addr)