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 5import logging 6import socket 7import time 8import urllib2 9 10import common 11 12from autotest_lib.client.common_lib import error 13from autotest_lib.client.cros import routing 14 15 16def 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 55FETCH_URL_PATTERN_FOR_TEST = \ 56 'http://testing-chargen.appspot.com/download?size=%d' 57 58def 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