system_stub.py revision 4e180b6a0b4720a9b8e9e959a882386f690f08ff
14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)# Copyright (c) 2012 The Chromium Authors. All rights reserved.
24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)# found in the LICENSE file.
44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)"""Provides stubs for os, sys and subprocess for testing
54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)This test allows one to test code that itself uses os, sys, and subprocess.
74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)"""
8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)import os
10116680a4aac90f2aa7413d9095a592090648e557Ben Murdochimport re
114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)import shlex
12import sys as real_sys
13
14class Override(object):
15  def __init__(self, base_module, module_list):
16    stubs = {'adb_commands': AdbCommandsModuleStub,
17             'perf_control': PerfControlModuleStub,
18             'thermal_throttle': ThermalThrottleModuleStub,
19             'os': OsModuleStub,
20             'subprocess': SubprocessModuleStub,
21             'sys': SysModuleStub,
22    }
23    self.adb_commands = None
24    self.os = None
25    self.subprocess = None
26    self.sys = None
27
28    self._base_module = base_module
29    self._overrides = {}
30
31    for module_name in module_list:
32      self._overrides[module_name] = getattr(base_module, module_name)
33      setattr(self, module_name, stubs[module_name]())
34      setattr(base_module, module_name, getattr(self, module_name))
35
36    if self.os and self.sys:
37      self.os.path.sys = self.sys
38
39  def __del__(self):
40    assert not len(self._overrides)
41
42  def Restore(self):
43    for module_name, original_module in self._overrides.iteritems():
44      setattr(self._base_module, module_name, original_module)
45    self._overrides = {}
46
47class AdbCommandsModuleStub(object):
48# adb not even found
49# android_browser_finder not returning
50  class AdbCommandsStub(object):
51    def __init__(self, module, device):
52      self._module = module
53      self._device = device
54      self.is_root_enabled = True
55
56    def RunShellCommand(self, args):
57      if isinstance(args, basestring):
58        args = shlex.split(args)
59      handler = self._module.shell_command_handlers[args[0]]
60      return handler(args)
61
62    def IsRootEnabled(self):
63      return self.is_root_enabled
64
65  def __init__(self):
66    self.attached_devices = []
67    self.shell_command_handlers = {}
68
69    def AdbCommandsStubConstructor(device=None):
70      return AdbCommandsModuleStub.AdbCommandsStub(self, device)
71    self.AdbCommands = AdbCommandsStubConstructor
72
73  @staticmethod
74  def IsAndroidSupported():
75    return True
76
77  def GetAttachedDevices(self):
78    return self.attached_devices
79
80  @staticmethod
81  def HasForwarder(_=None):
82    return True
83
84class PerfControlModuleStub(object):
85  class PerfControlStub(object):
86    def __init__(self, adb):
87      pass
88
89  def __init__(self):
90    self.PerfControl = PerfControlModuleStub.PerfControlStub
91
92
93class ThermalThrottleModuleStub(object):
94  class ThermalThrottleStub(object):
95    def __init__(self, adb):
96      pass
97
98  def __init__(self):
99    self.ThermalThrottle = ThermalThrottleModuleStub.ThermalThrottleStub
100
101
102class OsModuleStub(object):
103  class OsPathModuleStub(object):
104    def __init__(self, sys_module):
105      self.sys = sys_module
106      self.files = []
107
108    def exists(self, path):
109      return path in self.files
110
111    def isfile(self, path):
112      return path in self.files
113
114    def join(self, *paths):
115      def IsAbsolutePath(path):
116        if self.sys.platform.startswith('win'):
117          return re.match('[a-zA-Z]:\\\\', path)
118        else:
119          return path.startswith('/')
120
121      # Per Python specification, if any component is an absolute path,
122      # discard previous components.
123      for index, path in reversed(list(enumerate(paths))):
124        if IsAbsolutePath(path):
125          paths = paths[index:]
126          break
127
128      if self.sys.platform.startswith('win'):
129        tmp = os.path.join(*paths)
130        return tmp.replace('/', '\\')
131      else:
132        tmp = os.path.join(*paths)
133        return tmp.replace('\\', '/')
134
135    def expanduser(self, filename):
136      return os.path.expanduser(filename)
137
138    def dirname(self, filename): # pylint: disable=R0201
139      return os.path.dirname(filename)
140
141  X_OK = os.X_OK
142
143  def __init__(self, sys_module=real_sys):
144    self.path = OsModuleStub.OsPathModuleStub(sys_module)
145    self.display = ':0'
146    self.local_app_data = None
147    self.program_files = None
148    self.program_files_x86 = None
149    self.devnull = os.devnull
150
151  def access(self, path, _):
152    return path in self.path.files
153
154  def getenv(self, name):
155    if name == 'DISPLAY':
156      return self.display
157    elif name == 'LOCALAPPDATA':
158      return self.local_app_data
159    elif name == 'PROGRAMFILES':
160      return self.program_files
161    elif name == 'PROGRAMFILES(X86)':
162      return self.program_files_x86
163    raise Exception('Unsupported getenv')
164
165class SubprocessModuleStub(object):
166  class PopenStub(object):
167    def __init__(self):
168      self.communicate_result = ('', '')
169
170    def __call__(self, args, **kwargs):
171      return self
172
173    def communicate(self):
174      return self.communicate_result
175
176  def __init__(self):
177    self.Popen = SubprocessModuleStub.PopenStub()
178    self.PIPE = None
179
180  def call(self, *args, **kwargs):
181    raise NotImplementedError()
182
183class SysModuleStub(object):
184  def __init__(self):
185    self.platform = ''
186