OLD | NEW |
| (Empty) |
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 """Provides stubs for os, sys and subprocess for testing | |
5 | |
6 This test allows one to test code that itself uses os, sys, and subprocess. | |
7 """ | |
8 | |
9 import os | |
10 import re | |
11 import shlex | |
12 import sys as real_sys | |
13 | |
14 class Override(object): | |
15 def __init__(self, base_module, module_list): | |
16 stubs = {'adb_commands': AdbCommandsModuleStub, | |
17 'os': OsModuleStub, | |
18 'subprocess': SubprocessModuleStub, | |
19 'sys': SysModuleStub, | |
20 } | |
21 self.adb_commands = None | |
22 self.os = None | |
23 self.subprocess = None | |
24 self.sys = None | |
25 | |
26 self._base_module = base_module | |
27 self._overrides = {} | |
28 | |
29 for module_name in module_list: | |
30 self._overrides[module_name] = getattr(base_module, module_name) | |
31 setattr(self, module_name, stubs[module_name]()) | |
32 setattr(base_module, module_name, getattr(self, module_name)) | |
33 | |
34 if self.os and self.sys: | |
35 self.os.path.sys = self.sys | |
36 | |
37 def __del__(self): | |
38 assert not len(self._overrides) | |
39 | |
40 def Restore(self): | |
41 for module_name, original_module in self._overrides.iteritems(): | |
42 setattr(self._base_module, module_name, original_module) | |
43 self._overrides = {} | |
44 | |
45 class AdbCommandsModuleStub(object): | |
46 # adb not even found | |
47 # android_browser_finder not returning | |
48 class AdbCommandsStub(object): | |
49 def __init__(self, module, device): | |
50 self._module = module | |
51 self._device = device | |
52 self.is_root_enabled = True | |
53 | |
54 def RunShellCommand(self, args): | |
55 if isinstance(args, basestring): | |
56 args = shlex.split(args) | |
57 handler = self._module.shell_command_handlers[args[0]] | |
58 return handler(args) | |
59 | |
60 def IsRootEnabled(self): | |
61 return self.is_root_enabled | |
62 | |
63 def __init__(self): | |
64 self.attached_devices = [] | |
65 self.shell_command_handlers = {} | |
66 | |
67 def AdbCommandsStubConstructor(device=None): | |
68 return AdbCommandsModuleStub.AdbCommandsStub(self, device) | |
69 self.AdbCommands = AdbCommandsStubConstructor | |
70 | |
71 @staticmethod | |
72 def IsAndroidSupported(): | |
73 return True | |
74 | |
75 def GetAttachedDevices(self): | |
76 return self.attached_devices | |
77 | |
78 @staticmethod | |
79 def HasForwarder(_=None): | |
80 return True | |
81 | |
82 class OsModuleStub(object): | |
83 class OsPathModuleStub(object): | |
84 def __init__(self, sys_module): | |
85 self.sys = sys_module | |
86 self.files = [] | |
87 | |
88 def exists(self, path): | |
89 return path in self.files | |
90 | |
91 def join(self, *paths): | |
92 def IsAbsolutePath(path): | |
93 if self.sys.platform.startswith('win'): | |
94 return re.match('[a-zA-Z]:\\\\', path) | |
95 else: | |
96 return path.startswith('/') | |
97 | |
98 # Per Python specification, if any component is an absolute path, | |
99 # discard previous components. | |
100 for index, path in reversed(list(enumerate(paths))): | |
101 if IsAbsolutePath(path): | |
102 paths = paths[index:] | |
103 break | |
104 | |
105 if self.sys.platform.startswith('win'): | |
106 tmp = os.path.join(*paths) | |
107 return tmp.replace('/', '\\') | |
108 else: | |
109 tmp = os.path.join(*paths) | |
110 return tmp.replace('\\', '/') | |
111 | |
112 def expanduser(self, filename): | |
113 return os.path.expanduser(filename) | |
114 | |
115 def dirname(self, filename): # pylint: disable=R0201 | |
116 return os.path.dirname(filename) | |
117 | |
118 def __init__(self, sys_module=real_sys): | |
119 self.path = OsModuleStub.OsPathModuleStub(sys_module) | |
120 self.display = ':0' | |
121 self.local_app_data = None | |
122 self.program_files = None | |
123 self.program_files_x86 = None | |
124 self.devnull = os.devnull | |
125 | |
126 def getenv(self, name): | |
127 if name == 'DISPLAY': | |
128 return self.display | |
129 elif name == 'LOCALAPPDATA': | |
130 return self.local_app_data | |
131 elif name == 'PROGRAMFILES': | |
132 return self.program_files | |
133 elif name == 'PROGRAMFILES(X86)': | |
134 return self.program_files_x86 | |
135 raise Exception('Unsupported getenv') | |
136 | |
137 class SubprocessModuleStub(object): | |
138 class PopenStub(object): | |
139 def __init__(self): | |
140 self.communicate_result = ('', '') | |
141 | |
142 def __call__(self, args, **kwargs): | |
143 return self | |
144 | |
145 def communicate(self): | |
146 return self.communicate_result | |
147 | |
148 def __init__(self): | |
149 self.Popen = SubprocessModuleStub.PopenStub() | |
150 self.PIPE = None | |
151 | |
152 def call(self, *args, **kwargs): | |
153 raise NotImplementedError() | |
154 | |
155 class SysModuleStub(object): | |
156 def __init__(self): | |
157 self.platform = '' | |
OLD | NEW |