system_stub.py revision 5f1c94371a64b3196d4be9466099bb892df9b88e
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. 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 class AdbCommandsStub(object): 55 def __init__(self, module, device): 56 self._module = module 57 self._device = device 58 self.is_root_enabled = True 59 60 def RunShellCommand(self, args): 61 if isinstance(args, basestring): 62 args = shlex.split(args) 63 handler = self._module.shell_command_handlers[args[0]] 64 return handler(args) 65 66 def IsRootEnabled(self): 67 return self.is_root_enabled 68 69 def RestartAdbdOnDevice(self): 70 pass 71 72 def IsUserBuild(self): 73 return False 74 75 def WaitForDevicePm(self): 76 pass 77 78 def __init__(self): 79 self.attached_devices = [] 80 self.shell_command_handlers = {} 81 82 def AdbCommandsStubConstructor(device=None): 83 return AdbCommandsModuleStub.AdbCommandsStub(self, device) 84 self.AdbCommands = AdbCommandsStubConstructor 85 86 @staticmethod 87 def IsAndroidSupported(): 88 return True 89 90 def GetAttachedDevices(self): 91 return self.attached_devices 92 93 def SetupPrebuiltTools(self, _): 94 return True 95 96 def CleanupLeftoverProcesses(self): 97 pass 98 99 100class CloudStorageModuleStub(object): 101 INTERNAL_BUCKET = None 102 PUBLIC_BUCKET = None 103 104 class CloudStorageError(Exception): 105 pass 106 107 def __init__(self): 108 self.remote_paths = [] 109 self.local_file_hashes = {} 110 self.local_hash_files = {} 111 112 def List(self, _): 113 return self.remote_paths 114 115 def Insert(self, bucket, remote_path, local_path): 116 pass 117 118 def CalculateHash(self, file_path): 119 return self.local_file_hashes[file_path] 120 121 def ReadHash(self, hash_path): 122 return self.local_hash_files[hash_path] 123 124 125class OpenFunctionStub(object): 126 class FileStub(object): 127 def __init__(self, data): 128 self._data = data 129 130 def __enter__(self): 131 return self 132 133 def __exit__(self, *args): 134 pass 135 136 def read(self, size=None): 137 if size: 138 return self._data[:size] 139 else: 140 return self._data 141 142 def __init__(self): 143 self.files = {} 144 145 def __call__(self, name, *args, **kwargs): 146 return OpenFunctionStub.FileStub(self.files[name]) 147 148 149class OsModuleStub(object): 150 class OsEnvironModuleStub(object): 151 def get(self, _): 152 return None 153 154 class OsPathModuleStub(object): 155 def __init__(self, sys_module): 156 self.sys = sys_module 157 self.files = [] 158 159 def exists(self, path): 160 return path in self.files 161 162 def isfile(self, path): 163 return path in self.files 164 165 def join(self, *paths): 166 def IsAbsolutePath(path): 167 if self.sys.platform.startswith('win'): 168 return re.match('[a-zA-Z]:\\\\', path) 169 else: 170 return path.startswith('/') 171 172 # Per Python specification, if any component is an absolute path, 173 # discard previous components. 174 for index, path in reversed(list(enumerate(paths))): 175 if IsAbsolutePath(path): 176 paths = paths[index:] 177 break 178 179 if self.sys.platform.startswith('win'): 180 tmp = os.path.join(*paths) 181 return tmp.replace('/', '\\') 182 else: 183 tmp = os.path.join(*paths) 184 return tmp.replace('\\', '/') 185 186 @staticmethod 187 def expanduser(path): 188 return os.path.expanduser(path) 189 190 @staticmethod 191 def dirname(path): 192 return os.path.dirname(path) 193 194 @staticmethod 195 def splitext(path): 196 return os.path.splitext(path) 197 198 X_OK = os.X_OK 199 200 pathsep = os.pathsep 201 202 def __init__(self, sys_module=sys): 203 self.path = OsModuleStub.OsPathModuleStub(sys_module) 204 self.environ = OsModuleStub.OsEnvironModuleStub() 205 self.display = ':0' 206 self.local_app_data = None 207 self.sys_path = None 208 self.program_files = None 209 self.program_files_x86 = None 210 self.devnull = os.devnull 211 212 def access(self, path, _): 213 return path in self.path.files 214 215 def getenv(self, name, value=None): 216 if name == 'DISPLAY': 217 env = self.display 218 elif name == 'LOCALAPPDATA': 219 env = self.local_app_data 220 elif name == 'PATH': 221 env = self.sys_path 222 elif name == 'PROGRAMFILES': 223 env = self.program_files 224 elif name == 'PROGRAMFILES(X86)': 225 env = self.program_files_x86 226 else: 227 raise NotImplementedError('Unsupported getenv') 228 return env if env else value 229 230 231class PerfControlModuleStub(object): 232 class PerfControlStub(object): 233 def __init__(self, adb): 234 pass 235 236 def __init__(self): 237 self.PerfControl = PerfControlModuleStub.PerfControlStub 238 239 240class RawInputFunctionStub(object): 241 def __init__(self): 242 self.input = '' 243 244 def __call__(self, name, *args, **kwargs): 245 return self.input 246 247 248class SubprocessModuleStub(object): 249 class PopenStub(object): 250 def __init__(self): 251 self.communicate_result = ('', '') 252 253 def __call__(self, args, **kwargs): 254 return self 255 256 def communicate(self): 257 return self.communicate_result 258 259 def __init__(self): 260 self.Popen = SubprocessModuleStub.PopenStub() 261 self.PIPE = None 262 263 def call(self, *args, **kwargs): 264 pass 265 266 267class SysModuleStub(object): 268 def __init__(self): 269 self.platform = '' 270 271 272class ThermalThrottleModuleStub(object): 273 class ThermalThrottleStub(object): 274 def __init__(self, adb): 275 pass 276 277 def __init__(self): 278 self.ThermalThrottle = ThermalThrottleModuleStub.ThermalThrottleStub 279