1#!/usr/bin/env python 2 3# Copyright (c) 2016 The Chromium Authors. All rights reserved. 4# Use of this source code is governed by a BSD-style license that can be 5# found in the LICENSE file. 6 7import functools 8import os 9import sys 10 11 12def GetCatapultDir(): 13 return os.path.normpath( 14 os.path.join(os.path.dirname(__file__), '..', '..', '..')) 15 16 17def IsRunningOnCrosDevice(): 18 """Returns True if we're on a ChromeOS device.""" 19 lsb_release = '/etc/lsb-release' 20 if sys.platform.startswith('linux') and os.path.exists(lsb_release): 21 with open(lsb_release, 'r') as f: 22 res = f.read() 23 if res.count('CHROMEOS_RELEASE_NAME'): 24 return True 25 return False 26 27 28def _ExecutableExtensions(): 29 # pathext is, e.g. '.com;.exe;.bat;.cmd' 30 exts = os.getenv('PATHEXT').split(';') #e.g. ['.com','.exe','.bat','.cmd'] 31 return [x[1:].upper() for x in exts] #e.g. ['COM','EXE','BAT','CMD'] 32 33 34def IsExecutable(path): 35 if os.path.isfile(path): 36 if hasattr(os, 'name') and os.name == 'nt': 37 return path.split('.')[-1].upper() in _ExecutableExtensions() 38 else: 39 return os.access(path, os.X_OK) 40 else: 41 return False 42 43 44def _AddDirToPythonPath(*path_parts): 45 path = os.path.abspath(os.path.join(*path_parts)) 46 if os.path.isdir(path) and path not in sys.path: 47 # Some callsite that use telemetry assumes that sys.path[0] is the directory 48 # containing the script, so we add these extra paths to right after it. 49 sys.path.insert(1, path) 50 51_AddDirToPythonPath(os.path.join(GetCatapultDir(), 'devil')) 52_AddDirToPythonPath(os.path.join(GetCatapultDir(), 'dependency_manager')) 53_AddDirToPythonPath(os.path.join(GetCatapultDir(), 'third_party', 'mock')) 54# mox3 is needed for pyfakefs usage, but not for pylint. 55_AddDirToPythonPath(os.path.join(GetCatapultDir(), 'third_party', 'mox3')) 56_AddDirToPythonPath( 57 os.path.join(GetCatapultDir(), 'third_party', 'pyfakefs')) 58 59from devil.utils import timeout_retry 60from devil.utils import reraiser_thread 61 62 63# Decorator that adds timeout functionality to a function. 64def Timeout(default_timeout): 65 return lambda func: TimeoutDeco(func, default_timeout) 66 67# Note: Even though the "timeout" keyword argument is the only 68# keyword argument that will need to be given to the decorated function, 69# we still have to use the **kwargs syntax, because we have to use 70# the *args syntax here before (since the decorator decorates functions 71# with different numbers of positional arguments) and Python doesn't allow 72# a single named keyword argument after *args. 73# (e.g., 'def foo(*args, bar=42):' is a syntax error) 74 75def TimeoutDeco(func, default_timeout): 76 @functools.wraps(func) 77 def RunWithTimeout(*args, **kwargs): 78 if 'timeout' in kwargs: 79 timeout = kwargs['timeout'] 80 else: 81 timeout = default_timeout 82 try: 83 return timeout_retry.Run(func, timeout, 0, args=args) 84 except reraiser_thread.TimeoutError: 85 print '%s timed out.' % func.__name__ 86 return False 87 return RunWithTimeout 88