133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# Copyright 2012 The Chromium Authors. All rights reserved.
233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# Use of this source code is governed by a BSD-style license that can be
333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# found in the LICENSE file.
433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck"""Provides stubs for os, sys and subprocess for testing
633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John ReckThis test allows one to test code that itself uses os, sys, and subprocess.
833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck"""
933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
1033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckimport ntpath
1133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckimport os
1233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckimport posixpath
1333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckimport re
1433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckimport shlex
1533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckimport sys
1633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
1733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
1833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckclass Override(object):
1933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
2033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  _overidden_modules = set()
2133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
2233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def __init__(self, base_module, module_list):
2333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.cloud_storage = None
2433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.open = None
2533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.os = None
2633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.perf_control = None
2733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.raw_input = None
2833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.subprocess = None
2933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.sys = None
3033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.thermal_throttle = None
3133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.logging = None
3233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    stubs = {'cloud_storage': CloudStorageModuleStub,
3333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck             'open': OpenFunctionStub,
3433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck             'os': OsModuleStub,
3533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck             'perf_control': PerfControlModuleStub,
3633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck             'raw_input': RawInputFunctionStub,
3733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck             'subprocess': SubprocessModuleStub,
3833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck             'sys': SysModuleStub,
3933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck             'thermal_throttle': ThermalThrottleModuleStub,
4033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck             'logging': LoggingStub,
4133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    }
4233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.adb_commands = None
4333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.os = None
4433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.subprocess = None
4533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.sys = None
4633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
4733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    assert base_module not in self._overidden_modules, (
4833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        '%s is already overridden' % base_module.__name__)
4933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self._overidden_modules.add(base_module)
5033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self._base_module = base_module
5133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self._overrides = {}
5233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
5333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    for module_name in module_list:
5433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      self._overrides[module_name] = getattr(base_module, module_name, None)
5533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      setattr(self, module_name, stubs[module_name]())
5633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      setattr(base_module, module_name, getattr(self, module_name))
5733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
5833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    if self.os and self.sys:
5933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      self.os.path.sys = self.sys
6033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
6133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def __del__(self):
6233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    assert not len(self._overrides)
6333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
6433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def Restore(self):
6533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    for module_name, original_module in self._overrides.iteritems():
6633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      if original_module is None:
6733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        # This will happen when we override built-in functions, like open.
6833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        # If we don't delete the attribute, we will shadow the built-in
6933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        # function with an attribute set to None.
7033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        delattr(self._base_module, module_name)
7133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      else:
7233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        setattr(self._base_module, module_name, original_module)
7333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self._overrides = {}
7433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self._overidden_modules.remove(self._base_module)
7533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self._base_module = None
7633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
7733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
7833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckclass AdbDevice(object):
7933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
8033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def __init__(self):
8133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.has_root = False
8233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.needs_su = False
8333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.shell_command_handlers = {}
8433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.mock_content = []
8533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.system_properties = {}
8633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    if self.system_properties.get('ro.product.cpu.abi') == None:
8733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      self.system_properties['ro.product.cpu.abi'] = 'armeabi-v7a'
8833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
8933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def HasRoot(self):
9033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    return self.has_root
9133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
9233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def NeedsSU(self):
9333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    return self.needs_su
9433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
9533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def RunShellCommand(self, args, **kwargs):
9633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    del kwargs  # unused
9733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    if isinstance(args, basestring):
9833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      args = shlex.split(args)
9933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    handler = self.shell_command_handlers[args[0]]
10033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    return handler(args)
10133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
10233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def FileExists(self, _):
10333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    return False
10433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
10533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def ReadFile(self, device_path, as_root=False):
10633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    del device_path, as_root  # unused
10733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    return self.mock_content
10833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
10933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def GetProp(self, property_name):
11033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    return self.system_properties[property_name]
11133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
11233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def SetProp(self, property_name, property_value):
11333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.system_properties[property_name] = property_value
11433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
11533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
11633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckclass CloudStorageModuleStub(object):
11733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  PUBLIC_BUCKET = 'chromium-telemetry'
11833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  PARTNER_BUCKET = 'chrome-partner-telemetry'
11933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  INTERNAL_BUCKET = 'chrome-telemetry'
12033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  BUCKET_ALIASES = {
12133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    'public': PUBLIC_BUCKET,
12233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    'partner': PARTNER_BUCKET,
12333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    'internal': INTERNAL_BUCKET,
12433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  }
12533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
12633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  # These are used to test for CloudStorage errors.
12733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  INTERNAL_PERMISSION = 2
12833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  PARTNER_PERMISSION = 1
12933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  PUBLIC_PERMISSION = 0
13033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  # Not logged in.
13133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  CREDENTIALS_ERROR_PERMISSION = -1
13233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
13333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  class NotFoundError(Exception):
13433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    pass
13533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
13633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  class CloudStorageError(Exception):
13733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    pass
13833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
13933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  class PermissionError(CloudStorageError):
14033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    pass
14133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
14233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  class CredentialsError(CloudStorageError):
14333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    pass
14433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
14533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def __init__(self):
14633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.default_remote_paths = {CloudStorageModuleStub.INTERNAL_BUCKET:{},
14733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck                                 CloudStorageModuleStub.PARTNER_BUCKET:{},
14833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck                                 CloudStorageModuleStub.PUBLIC_BUCKET:{}}
14933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.remote_paths = self.default_remote_paths
15033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.local_file_hashes = {}
15133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.local_hash_files = {}
15233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.permission_level = CloudStorageModuleStub.INTERNAL_PERMISSION
15333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.downloaded_files = []
15433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
15533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def SetPermissionLevelForTesting(self, permission_level):
15633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.permission_level = permission_level
15733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
15833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def CheckPermissionLevelForBucket(self, bucket):
15933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    if bucket == CloudStorageModuleStub.PUBLIC_BUCKET:
16033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      return
16133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    elif (self.permission_level ==
16233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck          CloudStorageModuleStub.CREDENTIALS_ERROR_PERMISSION):
16333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      raise CloudStorageModuleStub.CredentialsError()
16433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    elif bucket == CloudStorageModuleStub.PARTNER_BUCKET:
16533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      if self.permission_level < CloudStorageModuleStub.PARTNER_PERMISSION:
16633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        raise CloudStorageModuleStub.PermissionError()
16733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    elif bucket == CloudStorageModuleStub.INTERNAL_BUCKET:
16833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      if self.permission_level < CloudStorageModuleStub.INTERNAL_PERMISSION:
16933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        raise CloudStorageModuleStub.PermissionError()
17033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    elif bucket not in self.remote_paths:
17133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      raise CloudStorageModuleStub.NotFoundError()
17233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
17333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def SetRemotePathsForTesting(self, remote_path_dict=None):
17433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    if not remote_path_dict:
17533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      self.remote_paths = self.default_remote_paths
17633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      return
17733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.remote_paths = remote_path_dict
17833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
17933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def GetRemotePathsForTesting(self):
18033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    if not self.remote_paths:
18133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      self.remote_paths = self.default_remote_paths
18233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    return self.remote_paths
18333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
18433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  # Set a dictionary of data files and their "calculated" hashes.
18533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def SetCalculatedHashesForTesting(self, calculated_hash_dictionary):
18633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.local_file_hashes = calculated_hash_dictionary
18733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
18833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def GetLocalDataFiles(self):
18933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    return self.local_file_hashes.keys()
19033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
19133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  # Set a dictionary of hash files and the hashes they should contain.
19233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def SetHashFileContentsForTesting(self, hash_file_dictionary):
19333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.local_hash_files = hash_file_dictionary
19433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
19533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def GetLocalHashFiles(self):
19633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    return self.local_hash_files.keys()
19733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
19833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def ChangeRemoteHashForTesting(self, bucket, remote_path, new_hash):
19933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.remote_paths[bucket][remote_path] = new_hash
20033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
20133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def List(self, bucket):
20233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    if not bucket or not bucket in self.remote_paths:
20333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      bucket_error = ('Incorrect bucket specified, correct buckets:' +
20433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck                      str(self.remote_paths))
20533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      raise CloudStorageModuleStub.CloudStorageError(bucket_error)
20633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    CloudStorageModuleStub.CheckPermissionLevelForBucket(self, bucket)
20733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    return list(self.remote_paths[bucket].keys())
20833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
20933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def Exists(self, bucket, remote_path):
21033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    CloudStorageModuleStub.CheckPermissionLevelForBucket(self, bucket)
21133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    return remote_path in self.remote_paths[bucket]
21233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
21333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def Insert(self, bucket, remote_path, local_path):
21433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    CloudStorageModuleStub.CheckPermissionLevelForBucket(self, bucket)
21533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    if not local_path in self.GetLocalDataFiles():
21633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      file_path_error = 'Local file path does not exist'
21733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      raise CloudStorageModuleStub.CloudStorageError(file_path_error)
21833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.remote_paths[bucket][remote_path] = (
21933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      CloudStorageModuleStub.CalculateHash(self, local_path))
22033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    return remote_path
22133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
22233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def GetHelper(self, bucket, remote_path, local_path, only_if_changed):
22333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    CloudStorageModuleStub.CheckPermissionLevelForBucket(self, bucket)
22433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    if not remote_path in self.remote_paths[bucket]:
22533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      if only_if_changed:
22633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        return False
22733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      raise CloudStorageModuleStub.NotFoundError('Remote file does not exist.')
22833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    remote_hash = self.remote_paths[bucket][remote_path]
22933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    local_hash = self.local_file_hashes[local_path]
23033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    if only_if_changed and remote_hash == local_hash:
23133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      return False
23233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.downloaded_files.append(remote_path)
23333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.local_file_hashes[local_path] = remote_hash
23433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.local_hash_files[local_path + '.sha1'] = remote_hash
23533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    return remote_hash
23633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
23733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def Get(self, bucket, remote_path, local_path):
23833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    return CloudStorageModuleStub.GetHelper(self, bucket, remote_path,
23933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck                                            local_path, False)
24033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
24133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def GetIfChanged(self, local_path, bucket=None):
24233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    remote_path = os.path.basename(local_path)
24333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    if bucket:
24433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      return CloudStorageModuleStub.GetHelper(self, bucket, remote_path,
24533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck                                              local_path, True)
24633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    result = CloudStorageModuleStub.GetHelper(
24733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        self, self.PUBLIC_BUCKET, remote_path, local_path, True)
24833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    if not result:
24933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      result = CloudStorageModuleStub.GetHelper(
25033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck          self, self.PARTNER_BUCKET, remote_path, local_path, True)
25133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    if not result:
25233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      result = CloudStorageModuleStub.GetHelper(
25333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck          self, self.INTERNAL_BUCKET, remote_path, local_path, True)
25433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    return result
25533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
25633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def GetFilesInDirectoryIfChanged(self, directory, bucket):
25733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    if os.path.dirname(directory) == directory: # If in the root dir.
25833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      raise ValueError('Trying to serve root directory from HTTP server.')
25933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    for dirpath, _, filenames in os.walk(directory):
26033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      for filename in filenames:
26133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        path, extension = os.path.splitext(
26233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck            os.path.join(dirpath, filename))
26333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        if extension != '.sha1':
26433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck          continue
26533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        self.GetIfChanged(path, bucket)
26633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
26733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def CalculateHash(self, file_path):
26833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    return self.local_file_hashes[file_path]
26933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
27033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def ReadHash(self, hash_path):
27133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    return self.local_hash_files[hash_path]
27233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
27333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
27433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckclass LoggingStub(object):
27533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def __init__(self):
27633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.warnings = []
27733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.errors = []
27833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
27933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def info(self, msg, *args):
28033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    pass
28133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
28233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def error(self, msg, *args):
28333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.errors.append(msg % args)
28433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
28533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def warning(self, msg, *args):
28633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.warnings.append(msg % args)
28733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
28833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def warn(self, msg, *args):
28933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.warning(msg, *args)
29033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
29133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
29233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckclass OpenFunctionStub(object):
29333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  class FileStub(object):
29433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def __init__(self, data):
29533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      self._data = data
29633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
29733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def __enter__(self):
29833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      return self
29933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
30033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def __exit__(self, *args):
30133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      pass
30233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
30333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def read(self, size=None):
30433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      if size:
30533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        return self._data[:size]
30633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      else:
30733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        return self._data
30833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
30933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def write(self, data):
31033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      self._data.write(data)
31133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
31233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def close(self):
31333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      pass
31433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
31533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def __init__(self):
31633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.files = {}
31733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
31833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def __call__(self, name, *args, **kwargs):
31933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    return OpenFunctionStub.FileStub(self.files[name])
32033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
32133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
32233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckclass OsModuleStub(object):
32333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  class OsEnvironModuleStub(object):
32433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def get(self, _):
32533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      return None
32633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
32733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  class OsPathModuleStub(object):
32833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def __init__(self, sys_module):
32933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      self.sys = sys_module
33033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      self.files = []
33133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      self.dirs = []
33233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
33333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def exists(self, path):
33433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      return path in self.files
33533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
33633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def isfile(self, path):
33733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      return path in self.files
33833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
33933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def isdir(self, path):
34033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      return path in self.dirs
34133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
34233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def join(self, *paths):
34333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      def IsAbsolutePath(path):
34433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        if self.sys.platform.startswith('win'):
34533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck          return re.match('[a-zA-Z]:\\\\', path)
34633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        else:
34733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck          return path.startswith('/')
34833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
34933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      # Per Python specification, if any component is an absolute path,
35033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      # discard previous components.
35133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      for index, path in reversed(list(enumerate(paths))):
35233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        if IsAbsolutePath(path):
35333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck          paths = paths[index:]
35433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck          break
35533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
35633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      if self.sys.platform.startswith('win'):
35733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        tmp = os.path.join(*paths)
35833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        return tmp.replace('/', '\\')
35933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      else:
36033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        tmp = os.path.join(*paths)
36133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        return tmp.replace('\\', '/')
36233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
36333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def basename(self, path):
36433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      if self.sys.platform.startswith('win'):
36533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        return ntpath.basename(path)
36633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      else:
36733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck        return posixpath.basename(path)
36833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
36933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    @staticmethod
37033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def abspath(path):
37133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      return os.path.abspath(path)
37233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
37333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    @staticmethod
37433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def expanduser(path):
37533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      return os.path.expanduser(path)
37633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
37733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    @staticmethod
37833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def dirname(path):
37933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      return os.path.dirname(path)
38033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
38133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    @staticmethod
38233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def realpath(path):
38333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      return os.path.realpath(path)
38433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
38533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    @staticmethod
38633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def split(path):
38733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      return os.path.split(path)
38833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
38933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    @staticmethod
39033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def splitext(path):
39133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      return os.path.splitext(path)
39233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
39333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    @staticmethod
39433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def splitdrive(path):
39533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      return os.path.splitdrive(path)
39633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
39733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  X_OK = os.X_OK
39833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
39933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  sep = os.sep
40033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  pathsep = os.pathsep
40133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
40233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def __init__(self, sys_module=sys):
40333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.path = OsModuleStub.OsPathModuleStub(sys_module)
40433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.environ = OsModuleStub.OsEnvironModuleStub()
40533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.display = ':0'
40633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.local_app_data = None
40733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.sys_path = None
40833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.program_files = None
40933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.program_files_x86 = None
41033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.devnull = os.devnull
41133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self._directory = {}
41233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
41333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def access(self, path, _):
41433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    return path in self.path.files
41533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
41633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def getenv(self, name, value=None):
41733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    if name == 'DISPLAY':
41833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      env = self.display
41933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    elif name == 'LOCALAPPDATA':
42033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      env = self.local_app_data
42133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    elif name == 'PATH':
42233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      env = self.sys_path
42333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    elif name == 'PROGRAMFILES':
42433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      env = self.program_files
42533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    elif name == 'PROGRAMFILES(X86)':
42633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      env = self.program_files_x86
42733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    else:
42833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      raise NotImplementedError('Unsupported getenv')
42933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    return env if env else value
43033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
43133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def chdir(self, path):
43233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    pass
43333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
43433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def walk(self, top):
43533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    for dir_name in self._directory:
43633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      yield top, dir_name, self._directory[dir_name]
43733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
43833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
43933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckclass PerfControlModuleStub(object):
44033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  class PerfControlStub(object):
44133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def __init__(self, adb):
44233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      pass
44333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
44433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def __init__(self):
44533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.PerfControl = PerfControlModuleStub.PerfControlStub
44633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
44733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
44833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckclass RawInputFunctionStub(object):
44933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def __init__(self):
45033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.input = ''
45133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
45233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def __call__(self, name, *args, **kwargs):
45333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    return self.input
45433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
45533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
45633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckclass SubprocessModuleStub(object):
45733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  class PopenStub(object):
45833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def __init__(self):
45933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      self.communicate_result = ('', '')
46033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      self.returncode_result = 0
46133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
46233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def __call__(self, args, **kwargs):
46333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      return self
46433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
46533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def communicate(self):
46633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      return self.communicate_result
46733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
46833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    @property
46933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def returncode(self):
47033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      return self.returncode_result
47133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
47233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def __init__(self):
47333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.Popen = SubprocessModuleStub.PopenStub()
47433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.PIPE = None
47533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
47633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def call(self, *args, **kwargs):
47733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    pass
47833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
47933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
48033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckclass SysModuleStub(object):
48133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def __init__(self):
48233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.platform = ''
48333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
48433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
48533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckclass ThermalThrottleModuleStub(object):
48633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  class ThermalThrottleStub(object):
48733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    def __init__(self, adb):
48833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      pass
48933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
49033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  def __init__(self):
49133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck    self.ThermalThrottle = ThermalThrottleModuleStub.ThermalThrottleStub
492