1# Copyright 2012 The Chromium 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. 4import glob 5import imp 6import inspect 7import logging 8import os 9import socket 10import sys 11import time 12 13 14class TimeoutException(Exception): 15 pass 16 17 18def GetBaseDir(): 19 main_module = sys.modules['__main__'] 20 if hasattr(main_module, '__file__'): 21 return os.path.dirname(os.path.abspath(main_module.__file__)) 22 else: 23 return os.getcwd() 24 25 26def GetTelemetryDir(): 27 return os.path.normpath(os.path.join( 28 __file__, os.pardir, os.pardir, os.pardir)) 29 30 31def GetUnittestDataDir(): 32 return os.path.join(GetTelemetryDir(), 'unittest_data') 33 34 35def GetChromiumSrcDir(): 36 return os.path.normpath(os.path.join(GetTelemetryDir(), os.pardir, os.pardir)) 37 38 39def AddDirToPythonPath(*path_parts): 40 path = os.path.abspath(os.path.join(*path_parts)) 41 if os.path.isdir(path) and path not in sys.path: 42 sys.path.insert(0, path) 43 44_counter = [0] 45def _GetUniqueModuleName(): 46 _counter[0] += 1 47 return "page_set_module_" + str(_counter[0]) 48 49def GetPythonPageSetModule(file_path): 50 return imp.load_source(_GetUniqueModuleName(), file_path) 51 52 53def WaitFor(condition, timeout): 54 """Waits for up to |timeout| secs for the function |condition| to return True. 55 56 Polling frequency is (elapsed_time / 10), with a min of .1s and max of 5s. 57 58 Returns: 59 Result of |condition| function (if present). 60 """ 61 min_poll_interval = 0.1 62 max_poll_interval = 5 63 output_interval = 300 64 65 def GetConditionString(): 66 if condition.__name__ == '<lambda>': 67 try: 68 return inspect.getsource(condition).strip() 69 except IOError: 70 pass 71 return condition.__name__ 72 73 start_time = time.time() 74 last_output_time = start_time 75 while True: 76 res = condition() 77 if res: 78 return res 79 now = time.time() 80 elapsed_time = now - start_time 81 last_output_elapsed_time = now - last_output_time 82 if elapsed_time > timeout: 83 raise TimeoutException('Timed out while waiting %ds for %s.' % 84 (timeout, GetConditionString())) 85 if last_output_elapsed_time > output_interval: 86 logging.info('Continuing to wait %ds for %s. Elapsed: %ds.', 87 timeout, GetConditionString(), elapsed_time) 88 last_output_time = time.time() 89 poll_interval = min(max(elapsed_time / 10., min_poll_interval), 90 max_poll_interval) 91 time.sleep(poll_interval) 92 93 94def GetUnreservedAvailableLocalPort(): 95 """Returns an available port on the system. 96 97 WARNING: This method does not reserve the port it returns, so it may be used 98 by something else before you get to use it. This can lead to flake. 99 """ 100 tmp = socket.socket() 101 tmp.bind(('', 0)) 102 port = tmp.getsockname()[1] 103 tmp.close() 104 105 return port 106 107 108def CloseConnections(tab): 109 """Closes all TCP sockets held open by the browser.""" 110 try: 111 tab.ExecuteJavaScript("""window.chrome && chrome.benchmarking && 112 chrome.benchmarking.closeConnections()""") 113 except Exception: 114 pass 115 116 117def GetBuildDirectories(): 118 """Yields all combination of Chromium build output directories.""" 119 build_dirs = ['build', 120 os.path.basename(os.environ.get('CHROMIUM_OUT_DIR', 'out')), 121 'xcodebuild'] 122 123 build_types = ['Debug', 'Debug_x64', 'Release', 'Release_x64'] 124 125 for build_dir in build_dirs: 126 for build_type in build_types: 127 yield build_dir, build_type 128 129def GetSequentialFileName(base_name): 130 """Returns the next sequential file name based on |base_name| and the 131 existing files. base_name should not contain extension. 132 e.g: if base_name is /tmp/test, and /tmp/test_000.json, 133 /tmp/test_001.mp3 exist, this returns /tmp/test_002. In case no 134 other sequential file name exist, this will return /tmp/test_000 135 """ 136 name, ext = os.path.splitext(base_name) 137 assert ext == '', 'base_name cannot contain file extension.' 138 index = 0 139 while True: 140 output_name = '%s_%03d' % (name, index) 141 if not glob.glob(output_name + '.*'): 142 break 143 index = index + 1 144 return output_name 145