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)
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.')
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)