Home | History | Annotate | Download | only in cros
      1 # Copyright (c) 2012 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 socket
      7 import time
      8 import urllib2
      9 
     10 import common
     11 
     12 from autotest_lib.client.common_lib import error
     13 from autotest_lib.client.cros import routing
     14 
     15 
     16 def CheckInterfaceForDestination(host, expected_interface):
     17     """
     18     Checks that routes for host go through a given interface.
     19 
     20     The concern here is that our network setup may have gone wrong
     21     and our test connections may go over some other network than
     22     the one we're trying to test.  So we take all the IP addresses
     23     for the supplied host and make sure they go through the given
     24     network interface.
     25 
     26     @param host: Destination host
     27     @param expected_interface: Expected interface name
     28     @raises: error.TestFail if the routes for the given host go through
     29             a different interface than the expected one.
     30 
     31     """
     32     # addrinfo records: (family, type, proto, canonname, (addr, port))
     33     server_addresses = [record[4][0]
     34                         for record in socket.getaddrinfo(host, 80)]
     35 
     36     route_found = False
     37     routes = routing.NetworkRoutes()
     38     for address in server_addresses:
     39         route = routes.getRouteFor(address)
     40         if not route:
     41             continue
     42 
     43         route_found = True
     44 
     45         interface = route.interface
     46         logging.info('interface for %s: %s', address, interface)
     47         if interface != expected_interface:
     48             raise error.TestFail('Target server %s uses interface %s'
     49                                  '(%s expected).' %
     50                                  (address, interface, expected_interface))
     51 
     52     if not route_found:
     53         raise error.TestFail('No route found for "%s".' % host)
     54 
     55 FETCH_URL_PATTERN_FOR_TEST = \
     56     'http://testing-chargen.appspot.com/download?size=%d'
     57 
     58 def FetchUrl(url_pattern, bytes_to_fetch=10, fetch_timeout=10):
     59     """
     60     Fetches a specified number of bytes from a URL.
     61 
     62     @param url_pattern: URL pattern for fetching a specified number of bytes.
     63             %d in the pattern is to be filled in with the number of bytes to
     64             fetch.
     65     @param bytes_to_fetch: Number of bytes to fetch.
     66     @param fetch_timeout: Number of seconds to wait for the fetch to complete
     67             before it times out.
     68     @return: The time in seconds spent for fetching the specified number of
     69             bytes.
     70     @raises: error.TestError if one of the following happens:
     71             - The fetch takes no time.
     72             - The number of bytes fetched differs from the specified
     73               number.
     74 
     75     """
     76     # Limit the amount of bytes to read at a time.
     77     _MAX_FETCH_READ_BYTES = 1024 * 1024
     78 
     79     url = url_pattern % bytes_to_fetch
     80     logging.info('FetchUrl %s', url)
     81     start_time = time.time()
     82     result = urllib2.urlopen(url, timeout=fetch_timeout)
     83     bytes_fetched = 0
     84     while bytes_fetched < bytes_to_fetch:
     85         bytes_left = bytes_to_fetch - bytes_fetched
     86         bytes_to_read = min(bytes_left, _MAX_FETCH_READ_BYTES)
     87         bytes_read = len(result.read(bytes_to_read))
     88         bytes_fetched += bytes_read
     89         if bytes_read != bytes_to_read:
     90             raise error.TestError('FetchUrl tried to read %d bytes, but got '
     91                                   '%d bytes instead.' %
     92                                   (bytes_to_read, bytes_read))
     93         fetch_time = time.time() - start_time
     94         if fetch_time > fetch_timeout:
     95             raise error.TestError('FetchUrl exceeded timeout.')
     96 
     97     return fetch_time
     98