system_stub.py revision 23730a6e56a168d1879203e4b3819bb36e3d8f1f
1# Copyright (c) 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. 4 5"""Provides stubs for os, sys and subprocess for testing 6 7This test allows one to test code that itself uses os, sys, and subprocess. 8""" 9 10import os 11import re 12import shlex 13import sys 14 15 16class Override(object): 17 def __init__(self, base_module, module_list): 18 stubs = {'adb_commands': AdbCommandsModuleStub, 19 'cloud_storage': CloudStorageModuleStub, 20 'open': OpenFunctionStub, 21 'os': OsModuleStub, 22 'perf_control': PerfControlModuleStub, 23 'raw_input': RawInputFunctionStub, 24 'subprocess': SubprocessModuleStub, 25 'sys': SysModuleStub, 26 'thermal_throttle': ThermalThrottleModuleStub, 27 } 28 self.adb_commands = None 29 self.os = None 30 self.subprocess = None 31 self.sys = None 32 33 self._base_module = base_module 34 self._overrides = {} 35 36 for module_name in module_list: 37 self._overrides[module_name] = getattr(base_module, module_name, None) 38 setattr(self, module_name, stubs[module_name]()) 39 setattr(base_module, module_name, getattr(self, module_name)) 40 41 if self.os and self.sys: 42 self.os.path.sys = self.sys 43 44 def __del__(self): 45 assert not len(self._overrides) 46 47 def Restore(self): 48 for module_name, original_module in self._overrides.iteritems(): 49 setattr(self._base_module, module_name, original_module) 50 self._overrides = {} 51 52 53class AdbCommandsModuleStub(object): 54# adb not even found 55# android_browser_finder not returning 56 class AdbCommandsStub(object): 57 def __init__(self, module, device): 58 self._module = module 59 self._device = device 60 self.is_root_enabled = True 61 62 def RunShellCommand(self, args): 63 if isinstance(args, basestring): 64 args = shlex.split(args) 65 handler = self._module.shell_command_handlers[args[0]] 66 return handler(args) 67 68 def IsRootEnabled(self): 69 return self.is_root_enabled 70 71 def RestartAdbdOnDevice(self): 72 pass 73 74 def IsUserBuild(self): 75 return False 76 77 def __init__(self): 78 self.attached_devices = [] 79 self.shell_command_handlers = {} 80 81 def AdbCommandsStubConstructor(device=None): 82 return AdbCommandsModuleStub.AdbCommandsStub(self, device) 83 self.AdbCommands = AdbCommandsStubConstructor 84 85 @staticmethod 86 def IsAndroidSupported(): 87 return True 88 89 def GetAttachedDevices(self): 90 return self.attached_devices 91 92 def SetupPrebuiltTools(self, _): 93 return True 94 95 def CleanupLeftoverProcesses(self): 96 pass 97 98 99class CloudStorageModuleStub(object): 100 INTERNAL_BUCKET = None 101 PUBLIC_BUCKET = None 102 103 class CloudStorageError(Exception): 104 pass 105 106 def __init__(self): 107 self.remote_paths = [] 108 self.local_file_hashes = {} 109 self.local_hash_files = {} 110 111 def List(self, _): 112 return self.remote_paths 113 114 def Insert(self, bucket, remote_path, local_path): 115 pass 116 117 def CalculateHash(self, file_path): 118 return self.local_file_hashes[file_path] 119 120 def ReadHash(self, hash_path): 121 return self.local_hash_files[hash_path] 122 123 124class OpenFunctionStub(object): 125 class FileStub(object): 126 def __init__(self, data): 127 self._data = data 128 129 def __enter__(self): 130 return self 131 132 def __exit__(self, *args): 133 pass 134 135 def read(self, size=None): 136 if size: 137 return self._data[:size] 138 else: 139 return self._data 140 141 def __init__(self): 142 self.files = {} 143 144 def __call__(self, name, *args, **kwargs): 145 return OpenFunctionStub.FileStub(self.files[name]) 146 147 148class OsModuleStub(object): 149 class OsPathModuleStub(object): 150 def __init__(self, sys_module): 151 self.sys = sys_module 152 self.files = [] 153 154 def exists(self, path): 155 return path in self.files 156 157 def isfile(self, path): 158 return path in self.files 159 160 def join(self, *paths): 161 def IsAbsolutePath(path): 162 if self.sys.platform.startswith('win'): 163 return re.match('[a-zA-Z]:\\\\', path) 164 else: 165 return path.startswith('/') 166 167 # Per Python specification, if any component is an absolute path, 168 # discard previous components. 169 for index, path in reversed(list(enumerate(paths))): 170 if IsAbsolutePath(path): 171 paths = paths[index:] 172 break 173 174 if self.sys.platform.startswith('win'): 175 tmp = os.path.join(*paths) 176 return tmp.replace('/', '\\') 177 else: 178 tmp = os.path.join(*paths) 179 return tmp.replace('\\', '/') 180 181 @staticmethod 182 def expanduser(path): 183 return os.path.expanduser(path) 184 185 @staticmethod 186 def dirname(path): 187 return os.path.dirname(path) 188 189 @staticmethod 190 def splitext(path): 191 return os.path.splitext(path) 192 193 X_OK = os.X_OK 194 195 def __init__(self, sys_module=sys): 196 self.path = OsModuleStub.OsPathModuleStub(sys_module) 197 self.display = ':0' 198 self.local_app_data = None 199 self.program_files = None 200 self.program_files_x86 = None 201 self.devnull = os.devnull 202 203 def access(self, path, _): 204 return path in self.path.files 205 206 def getenv(self, name): 207 if name == 'DISPLAY': 208 return self.display 209 elif name == 'LOCALAPPDATA': 210 return self.local_app_data 211 elif name == 'PROGRAMFILES': 212 return self.program_files 213 elif name == 'PROGRAMFILES(X86)': 214 return self.program_files_x86 215 raise Exception('Unsupported getenv') 216 217 218class PerfControlModuleStub(object): 219 class PerfControlStub(object): 220 def __init__(self, adb): 221 pass 222 223 def __init__(self): 224 self.PerfControl = PerfControlModuleStub.PerfControlStub 225 226 227class RawInputFunctionStub(object): 228 def __init__(self): 229 self.input = '' 230 231 def __call__(self, name, *args, **kwargs): 232 return self.input 233 234 235class SubprocessModuleStub(object): 236 class PopenStub(object): 237 def __init__(self): 238 self.communicate_result = ('', '') 239 240 def __call__(self, args, **kwargs): 241 return self 242 243 def communicate(self): 244 return self.communicate_result 245 246 def __init__(self): 247 self.Popen = SubprocessModuleStub.PopenStub() 248 self.PIPE = None 249 250 def call(self, *args, **kwargs): 251 pass 252 253 254class SysModuleStub(object): 255 def __init__(self): 256 self.platform = '' 257 258 259class ThermalThrottleModuleStub(object): 260 class ThermalThrottleStub(object): 261 def __init__(self, adb): 262 pass 263 264 def __init__(self): 265 self.ThermalThrottle = ThermalThrottleModuleStub.ThermalThrottleStub 266