# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# pylint: disable=unused-argument

import os
import unittest

from py_utils import cloud_storage
import mock
from pyfakefs import fake_filesystem_unittest
from pyfakefs import fake_filesystem
from pyfakefs import fake_filesystem_glob

import dependency_manager
from dependency_manager import uploader


class BaseConfigCreationAndUpdateUnittests(fake_filesystem_unittest.TestCase):
  def setUp(self):
    self.addTypeEqualityFunc(uploader.CloudStorageUploader,
                             uploader.CloudStorageUploader.__eq__)
    self.setUpPyfakefs()
    self.dependencies = {
        'dep1': {'cloud_storage_bucket': 'bucket1',
                 'cloud_storage_base_folder': 'dependencies_folder',
                 'file_info': {
                     'plat1': {
                         'cloud_storage_hash': 'hash11',
                         'download_path': '../../relative/dep1/path1'},
                     'plat2': {
                         'cloud_storage_hash': 'hash12',
                         'download_path': '../../relative/dep1/path2'}}},
        'dep2': {'cloud_storage_bucket': 'bucket2',
                 'file_info': {
                     'plat1': {
                         'cloud_storage_hash': 'hash21',
                         'download_path': '../../relative/dep2/path1'},
                     'plat2': {
                         'cloud_storage_hash': 'hash22',
                         'download_path': '../../relative/dep2/path2'}}}}

    self.expected_file_lines = [
      # pylint: disable=bad-continuation
      '{', '"config_type": "BaseConfig",', '"dependencies": {',
        '"dep1": {', '"cloud_storage_base_folder": "dependencies_folder",',
          '"cloud_storage_bucket": "bucket1",', '"file_info": {',
            '"plat1": {', '"cloud_storage_hash": "hash11",',
              '"download_path": "../../relative/dep1/path1"', '},',
            '"plat2": {', '"cloud_storage_hash": "hash12",',
              '"download_path": "../../relative/dep1/path2"', '}', '}', '},',
        '"dep2": {', '"cloud_storage_bucket": "bucket2",', '"file_info": {',
            '"plat1": {', '"cloud_storage_hash": "hash21",',
              '"download_path": "../../relative/dep2/path1"', '},',
            '"plat2": {', '"cloud_storage_hash": "hash22",',
              '"download_path": "../../relative/dep2/path2"', '}', '}', '}',
      '}', '}']

    self.file_path = os.path.abspath(os.path.join(
        'path', 'to', 'config', 'file'))

    self.new_dep_path = 'path/to/new/dep'
    self.fs.CreateFile(self.new_dep_path)
    self.new_dep_hash = 'A23B56B7F23E798601F'
    self.new_dependencies = {
        'dep1': {'cloud_storage_bucket': 'bucket1',
                 'cloud_storage_base_folder': 'dependencies_folder',
                 'file_info': {
                     'plat1': {
                         'cloud_storage_hash': 'hash11',
                         'download_path': '../../relative/dep1/path1'},
                     'plat2': {
                         'cloud_storage_hash': self.new_dep_hash,
                         'download_path': '../../relative/dep1/path2'}}},
        'dep2': {'cloud_storage_bucket': 'bucket2',
                 'file_info': {
                     'plat1': {
                         'cloud_storage_hash': 'hash21',
                         'download_path': '../../relative/dep2/path1'},
                     'plat2': {
                         'cloud_storage_hash': 'hash22',
                         'download_path': '../../relative/dep2/path2'}}}}
    self.new_bucket = 'bucket1'
    self.new_remote_path = 'dependencies_folder/dep1_%s' % self.new_dep_hash
    self.new_pending_upload = uploader.CloudStorageUploader(
        self.new_bucket, self.new_remote_path, self.new_dep_path)
    self.expected_new_backup_path = '.'.join([self.new_remote_path, 'old'])
    self.new_expected_file_lines = [
      # pylint: disable=bad-continuation
      '{', '"config_type": "BaseConfig",', '"dependencies": {',
        '"dep1": {', '"cloud_storage_base_folder": "dependencies_folder",',
          '"cloud_storage_bucket": "bucket1",', '"file_info": {',
            '"plat1": {', '"cloud_storage_hash": "hash11",',
              '"download_path": "../../relative/dep1/path1"', '},',
            '"plat2": {', '"cloud_storage_hash": "%s",' % self.new_dep_hash,
              '"download_path": "../../relative/dep1/path2"', '}', '}', '},',
        '"dep2": {', '"cloud_storage_bucket": "bucket2",', '"file_info": {',
            '"plat1": {', '"cloud_storage_hash": "hash21",',
              '"download_path": "../../relative/dep2/path1"', '},',
            '"plat2": {', '"cloud_storage_hash": "hash22",',
              '"download_path": "../../relative/dep2/path2"', '}', '}', '}',
      '}', '}']

    self.final_dep_path = 'path/to/final/dep'
    self.fs.CreateFile(self.final_dep_path)
    self.final_dep_hash = 'B34662F23B56B7F98601F'
    self.final_bucket = 'bucket2'
    self.final_remote_path = 'dep1_%s' % self.final_dep_hash
    self.final_pending_upload = uploader.CloudStorageUploader(
        self.final_bucket, self.final_remote_path, self.final_dep_path)
    self.expected_final_backup_path = '.'.join([self.final_remote_path,
                                                'old'])
    self.final_dependencies = {
        'dep1': {'cloud_storage_bucket': 'bucket1',
                 'cloud_storage_base_folder': 'dependencies_folder',
                 'file_info': {
                     'plat1': {
                         'cloud_storage_hash': 'hash11',
                         'download_path': '../../relative/dep1/path1'},
                     'plat2': {
                         'cloud_storage_hash': self.new_dep_hash,
                         'download_path': '../../relative/dep1/path2'}}},
        'dep2': {'cloud_storage_bucket': 'bucket2',
                 'file_info': {
                     'plat1': {
                         'cloud_storage_hash': self.final_dep_hash,
                         'download_path': '../../relative/dep2/path1'},
                     'plat2': {
                         'cloud_storage_hash': 'hash22',
                         'download_path': '../../relative/dep2/path2'}}}}
    self.final_expected_file_lines = [
      # pylint: disable=bad-continuation
      '{', '"config_type": "BaseConfig",', '"dependencies": {',
        '"dep1": {', '"cloud_storage_base_folder": "dependencies_folder",',
          '"cloud_storage_bucket": "bucket1",', '"file_info": {',
            '"plat1": {', '"cloud_storage_hash": "hash11",',
              '"download_path": "../../relative/dep1/path1"', '},',
            '"plat2": {', '"cloud_storage_hash": "%s",' % self.new_dep_hash,
              '"download_path": "../../relative/dep1/path2"', '}', '}', '},',
        '"dep2": {', '"cloud_storage_bucket": "bucket2",', '"file_info": {',
            '"plat1": {', '"cloud_storage_hash": "%s",' % self.final_dep_hash,
              '"download_path": "../../relative/dep2/path1"', '},',
            '"plat2": {', '"cloud_storage_hash": "hash22",',
              '"download_path": "../../relative/dep2/path2"', '}', '}', '}',
      '}', '}']


  def tearDown(self):
    self.tearDownPyfakefs()

  # Init is not meant to be overridden, so we should be mocking the
  # base_config's json module, even in subclasses.
  def testCreateEmptyConfig(self):
    expected_file_lines = ['{',
                           '"config_type": "BaseConfig",',
                           '"dependencies": {}',
                           '}']
    config = dependency_manager.BaseConfig(self.file_path, writable=True)

    file_module = fake_filesystem.FakeFileOpen(self.fs)
    for line in file_module(self.file_path):
      self.assertEqual(expected_file_lines.pop(0), line.strip())
    self.fs.CloseOpenFile(file_module(self.file_path))
    self.assertEqual({}, config._config_data)
    self.assertEqual(self.file_path, config._config_path)

  def testCreateEmptyConfigError(self):
    self.assertRaises(dependency_manager.EmptyConfigError,
                      dependency_manager.BaseConfig, self.file_path)

  def testCloudStorageRemotePath(self):
    dependency = 'dep_name'
    cs_hash = self.new_dep_hash
    cs_base_folder = 'dependency_remote_folder'
    expected_remote_path = '%s/%s_%s' % (cs_base_folder, dependency, cs_hash)
    remote_path = dependency_manager.BaseConfig._CloudStorageRemotePath(
        dependency, cs_hash, cs_base_folder)
    self.assertEqual(expected_remote_path, remote_path)

    cs_base_folder = 'dependency_remote_folder'
    expected_remote_path = '%s_%s' % (dependency, cs_hash)
    remote_path = dependency_manager.BaseConfig._CloudStorageRemotePath(
        dependency, cs_hash, cs_base_folder)

  def testGetEmptyJsonDict(self):
    expected_json_dict = {'config_type': 'BaseConfig',
                          'dependencies': {}}
    json_dict = dependency_manager.BaseConfig._GetJsonDict()
    self.assertEqual(expected_json_dict, json_dict)

  def testGetNonEmptyJsonDict(self):
    expected_json_dict = {"config_type": "BaseConfig",
                          "dependencies": self.dependencies}
    json_dict = dependency_manager.BaseConfig._GetJsonDict(self.dependencies)
    self.assertEqual(expected_json_dict, json_dict)

  def testWriteEmptyConfigToFile(self):
    expected_file_lines = ['{', '"config_type": "BaseConfig",',
                           '"dependencies": {}', '}']
    self.assertFalse(os.path.exists(self.file_path))
    dependency_manager.BaseConfig._WriteConfigToFile(self.file_path)
    self.assertTrue(os.path.exists(self.file_path))
    file_module = fake_filesystem.FakeFileOpen(self.fs)
    for line in file_module(self.file_path):
      self.assertEqual(expected_file_lines.pop(0), line.strip())
    self.fs.CloseOpenFile(file_module(self.file_path))

  def testWriteNonEmptyConfigToFile(self):
    self.assertFalse(os.path.exists(self.file_path))
    dependency_manager.BaseConfig._WriteConfigToFile(self.file_path,
                                                     self.dependencies)
    self.assertTrue(os.path.exists(self.file_path))
    expected_file_lines = list(self.expected_file_lines)
    file_module = fake_filesystem.FakeFileOpen(self.fs)
    for line in file_module(self.file_path):
      self.assertEqual(expected_file_lines.pop(0), line.strip())
    self.fs.CloseOpenFile(file_module(self.file_path))

  @mock.patch('dependency_manager.uploader.cloud_storage')
  def testExecuteUpdateJobsNoOp(self, uploader_cs_mock):
    self.fs.CreateFile(self.file_path,
                       contents='\n'.join(self.expected_file_lines))
    config = dependency_manager.BaseConfig(self.file_path, writable=True)

    self.assertFalse(config.ExecuteUpdateJobs())
    self.assertFalse(config._IsDirty())
    self.assertFalse(config._pending_uploads)
    self.assertEqual(self.dependencies, config._config_data)
    file_module = fake_filesystem.FakeFileOpen(self.fs)
    expected_file_lines = list(self.expected_file_lines)
    for line in file_module(self.file_path):
      self.assertEqual(expected_file_lines.pop(0), line.strip())
    self.fs.CloseOpenFile(file_module(self.file_path))

  @mock.patch('dependency_manager.uploader.cloud_storage')
  def testExecuteUpdateJobsFailureOnInsertNoCSCollision(
      self, uploader_cs_mock):
    uploader_cs_mock.Exists.return_value = False
    uploader_cs_mock.Insert.side_effect = cloud_storage.CloudStorageError
    self.fs.CreateFile(self.file_path,
                       contents='\n'.join(self.expected_file_lines))
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    config._config_data = self.new_dependencies.copy()
    config._is_dirty = True
    config._pending_uploads = [self.new_pending_upload]
    self.assertEqual(self.new_dependencies, config._config_data)
    self.assertTrue(config._is_dirty)
    self.assertEqual(1, len(config._pending_uploads))
    self.assertEqual(self.new_pending_upload, config._pending_uploads[0])
    expected_exists_calls = [mock.call(self.new_bucket, self.new_remote_path)]
    expected_insert_calls = [mock.call(self.new_bucket, self.new_remote_path,
                                       self.new_dep_path)]
    expected_copy_calls = []
    expected_delete_calls = []

    self.assertRaises(cloud_storage.CloudStorageError,
                      config.ExecuteUpdateJobs)
    self.assertTrue(config._is_dirty)
    self.assertEqual(1, len(config._pending_uploads))
    self.assertEqual(self.new_pending_upload, config._pending_uploads[0])
    self.assertEqual(self.new_dependencies, config._config_data)
    file_module = fake_filesystem.FakeFileOpen(self.fs)
    expected_file_lines = list(self.expected_file_lines)
    for line in file_module(self.file_path):
      self.assertEqual(expected_file_lines.pop(0), line.strip())
    self.fs.CloseOpenFile(file_module(self.file_path))
    self.assertEqual(1, len(config._pending_uploads))
    self.assertEqual(self.new_pending_upload, config._pending_uploads[0])
    self.assertEqual(expected_insert_calls,
                     uploader_cs_mock.Insert.call_args_list)
    self.assertEqual(expected_exists_calls,
                     uploader_cs_mock.Exists.call_args_list)
    self.assertEqual(expected_copy_calls,
                     uploader_cs_mock.Copy.call_args_list)
    self.assertEqual(expected_delete_calls,
                     uploader_cs_mock.Delete.call_args_list)

  @mock.patch('dependency_manager.uploader.cloud_storage')
  def testExecuteUpdateJobsFailureOnInsertCSCollisionForce(
      self, uploader_cs_mock):
    uploader_cs_mock.Exists.return_value = True
    uploader_cs_mock.Insert.side_effect = cloud_storage.CloudStorageError
    self.fs.CreateFile(self.file_path,
                       contents='\n'.join(self.expected_file_lines))
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    config._config_data = self.new_dependencies.copy()
    config._is_dirty = True
    config._pending_uploads = [self.new_pending_upload]
    self.assertEqual(self.new_dependencies, config._config_data)
    self.assertTrue(config._is_dirty)
    self.assertEqual(1, len(config._pending_uploads))
    self.assertEqual(self.new_pending_upload, config._pending_uploads[0])
    expected_exists_calls = [mock.call(self.new_bucket, self.new_remote_path)]
    expected_insert_calls = [mock.call(self.new_bucket, self.new_remote_path,
                                       self.new_dep_path)]
    expected_copy_calls = [mock.call(self.new_bucket, self.new_bucket,
                                     self.new_remote_path,
                                     self.expected_new_backup_path),
                           mock.call(self.new_bucket, self.new_bucket,
                                     self.expected_new_backup_path,
                                     self.new_remote_path)]
    expected_delete_calls = []

    self.assertRaises(cloud_storage.CloudStorageError,
                      config.ExecuteUpdateJobs, force=True)
    self.assertTrue(config._is_dirty)
    self.assertEqual(1, len(config._pending_uploads))
    self.assertEqual(self.new_pending_upload, config._pending_uploads[0])
    self.assertEqual(self.new_dependencies, config._config_data)
    file_module = fake_filesystem.FakeFileOpen(self.fs)
    expected_file_lines = list(self.expected_file_lines)
    for line in file_module(self.file_path):
      self.assertEqual(expected_file_lines.pop(0), line.strip())
    self.fs.CloseOpenFile(file_module(self.file_path))
    self.assertEqual(1, len(config._pending_uploads))
    self.assertEqual(self.new_pending_upload, config._pending_uploads[0])
    self.assertEqual(expected_insert_calls,
                     uploader_cs_mock.Insert.call_args_list)
    self.assertEqual(expected_exists_calls,
                     uploader_cs_mock.Exists.call_args_list)
    self.assertEqual(expected_copy_calls,
                     uploader_cs_mock.Copy.call_args_list)
    self.assertEqual(expected_delete_calls,
                     uploader_cs_mock.Delete.call_args_list)

  @mock.patch('dependency_manager.uploader.cloud_storage')
  def testExecuteUpdateJobsFailureOnInsertCSCollisionNoForce(
      self, uploader_cs_mock):
    uploader_cs_mock.Exists.return_value = True
    uploader_cs_mock.Insert.side_effect = cloud_storage.CloudStorageError
    self.fs.CreateFile(self.file_path,
                       contents='\n'.join(self.expected_file_lines))
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    config._config_data = self.new_dependencies.copy()
    config._is_dirty = True
    config._pending_uploads = [self.new_pending_upload]
    self.assertEqual(self.new_dependencies, config._config_data)
    self.assertTrue(config._is_dirty)
    self.assertEqual(1, len(config._pending_uploads))
    self.assertEqual(self.new_pending_upload, config._pending_uploads[0])
    expected_exists_calls = [mock.call(self.new_bucket, self.new_remote_path)]
    expected_insert_calls = []
    expected_copy_calls = []
    expected_delete_calls = []

    self.assertRaises(cloud_storage.CloudStorageError,
                      config.ExecuteUpdateJobs)
    self.assertTrue(config._is_dirty)
    self.assertEqual(1, len(config._pending_uploads))
    self.assertEqual(self.new_pending_upload, config._pending_uploads[0])
    self.assertEqual(self.new_dependencies, config._config_data)
    file_module = fake_filesystem.FakeFileOpen(self.fs)
    expected_file_lines = list(self.expected_file_lines)
    for line in file_module(self.file_path):
      self.assertEqual(expected_file_lines.pop(0), line.strip())
    self.fs.CloseOpenFile(file_module(self.file_path))
    self.assertEqual(1, len(config._pending_uploads))
    self.assertEqual(self.new_pending_upload, config._pending_uploads[0])
    self.assertEqual(expected_insert_calls,
                     uploader_cs_mock.Insert.call_args_list)
    self.assertEqual(expected_exists_calls,
                     uploader_cs_mock.Exists.call_args_list)
    self.assertEqual(expected_copy_calls,
                     uploader_cs_mock.Copy.call_args_list)
    self.assertEqual(expected_delete_calls,
                     uploader_cs_mock.Delete.call_args_list)

  @mock.patch('dependency_manager.uploader.cloud_storage')
  def testExecuteUpdateJobsFailureOnCopy(
      self, uploader_cs_mock):
    uploader_cs_mock.Exists.return_value = True
    uploader_cs_mock.Copy.side_effect = cloud_storage.CloudStorageError
    self.fs.CreateFile(self.file_path,
                       contents='\n'.join(self.expected_file_lines))
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    config._config_data = self.new_dependencies.copy()
    config._is_dirty = True
    config._pending_uploads = [self.new_pending_upload]
    self.assertEqual(self.new_dependencies, config._config_data)
    self.assertTrue(config._is_dirty)
    self.assertEqual(1, len(config._pending_uploads))
    self.assertEqual(self.new_pending_upload, config._pending_uploads[0])
    expected_exists_calls = [mock.call(self.new_bucket, self.new_remote_path)]
    expected_insert_calls = []
    expected_copy_calls = [mock.call(self.new_bucket, self.new_bucket,
                                     self.new_remote_path,
                                     self.expected_new_backup_path)]
    expected_delete_calls = []

    self.assertRaises(cloud_storage.CloudStorageError,
                      config.ExecuteUpdateJobs, force=True)
    self.assertTrue(config._is_dirty)
    self.assertEqual(1, len(config._pending_uploads))
    self.assertEqual(self.new_pending_upload, config._pending_uploads[0])
    self.assertEqual(self.new_dependencies, config._config_data)
    file_module = fake_filesystem.FakeFileOpen(self.fs)
    expected_file_lines = list(self.expected_file_lines)
    for line in file_module(self.file_path):
      self.assertEqual(expected_file_lines.pop(0), line.strip())
    self.fs.CloseOpenFile(file_module(self.file_path))
    self.assertEqual(1, len(config._pending_uploads))
    self.assertEqual(self.new_pending_upload, config._pending_uploads[0])
    self.assertEqual(expected_insert_calls,
                     uploader_cs_mock.Insert.call_args_list)
    self.assertEqual(expected_exists_calls,
                     uploader_cs_mock.Exists.call_args_list)
    self.assertEqual(expected_copy_calls,
                     uploader_cs_mock.Copy.call_args_list)
    self.assertEqual(expected_delete_calls,
                     uploader_cs_mock.Delete.call_args_list)

  @mock.patch('dependency_manager.uploader.cloud_storage')
  def testExecuteUpdateJobsFailureOnSecondInsertNoCSCollision(
      self, uploader_cs_mock):
    uploader_cs_mock.Exists.return_value = False
    uploader_cs_mock.Insert.side_effect = [
        True, cloud_storage.CloudStorageError]
    self.fs.CreateFile(self.file_path,
                       contents='\n'.join(self.expected_file_lines))
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    config._config_data = self.new_dependencies.copy()
    config._is_dirty = True
    config._pending_uploads = [self.new_pending_upload,
                               self.final_pending_upload]
    self.assertEqual(self.new_dependencies, config._config_data)
    self.assertTrue(config._is_dirty)
    self.assertEqual(2, len(config._pending_uploads))
    self.assertEqual(self.new_pending_upload, config._pending_uploads[0])
    self.assertEqual(self.final_pending_upload, config._pending_uploads[1])
    expected_exists_calls = [mock.call(self.new_bucket, self.new_remote_path),
                             mock.call(self.final_bucket,
                                       self.final_remote_path)]
    expected_insert_calls = [mock.call(self.new_bucket, self.new_remote_path,
                                       self.new_dep_path),
                             mock.call(self.final_bucket,
                                       self.final_remote_path,
                                       self.final_dep_path)]
    expected_copy_calls = []
    expected_delete_calls = [mock.call(self.new_bucket, self.new_remote_path)]

    self.assertRaises(cloud_storage.CloudStorageError,
                      config.ExecuteUpdateJobs)
    self.assertTrue(config._is_dirty)
    self.assertEqual(2, len(config._pending_uploads))
    self.assertEqual(self.new_pending_upload, config._pending_uploads[0])
    self.assertEqual(self.final_pending_upload, config._pending_uploads[1])
    self.assertEqual(self.new_dependencies, config._config_data)
    file_module = fake_filesystem.FakeFileOpen(self.fs)
    expected_file_lines = list(self.expected_file_lines)
    for line in file_module(self.file_path):
      self.assertEqual(expected_file_lines.pop(0), line.strip())
    self.fs.CloseOpenFile(file_module(self.file_path))
    self.assertEqual(expected_insert_calls,
                     uploader_cs_mock.Insert.call_args_list)
    self.assertEqual(expected_exists_calls,
                     uploader_cs_mock.Exists.call_args_list)
    self.assertEqual(expected_copy_calls,
                     uploader_cs_mock.Copy.call_args_list)
    self.assertEqual(expected_delete_calls,
                     uploader_cs_mock.Delete.call_args_list)

  @mock.patch('dependency_manager.uploader.cloud_storage')
  def testExecuteUpdateJobsFailureOnSecondInsertCSCollisionForce(
      self, uploader_cs_mock):
    uploader_cs_mock.Exists.return_value = True
    uploader_cs_mock.Insert.side_effect = [
        True, cloud_storage.CloudStorageError]
    self.fs.CreateFile(self.file_path,
                       contents='\n'.join(self.expected_file_lines))
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    config._config_data = self.new_dependencies.copy()
    config._is_dirty = True
    config._pending_uploads = [self.new_pending_upload,
                               self.final_pending_upload]
    self.assertEqual(self.new_dependencies, config._config_data)
    self.assertTrue(config._is_dirty)
    self.assertEqual(2, len(config._pending_uploads))
    self.assertEqual(self.new_pending_upload, config._pending_uploads[0])
    self.assertEqual(self.final_pending_upload, config._pending_uploads[1])
    expected_exists_calls = [mock.call(self.new_bucket, self.new_remote_path),
                             mock.call(self.final_bucket,
                                       self.final_remote_path)]
    expected_insert_calls = [mock.call(self.new_bucket, self.new_remote_path,
                                       self.new_dep_path),
                             mock.call(self.final_bucket,
                                       self.final_remote_path,
                                       self.final_dep_path)]
    expected_copy_calls = [mock.call(self.new_bucket, self.new_bucket,
                                     self.new_remote_path,
                                     self.expected_new_backup_path),
                           mock.call(self.final_bucket, self.final_bucket,
                                     self.final_remote_path,
                                     self.expected_final_backup_path),
                           mock.call(self.final_bucket, self.final_bucket,
                                     self.expected_final_backup_path,
                                     self.final_remote_path),
                           mock.call(self.new_bucket, self.new_bucket,
                                     self.expected_new_backup_path,
                                     self.new_remote_path)]
    expected_delete_calls = []

    self.assertRaises(cloud_storage.CloudStorageError,
                      config.ExecuteUpdateJobs, force=True)
    self.assertTrue(config._is_dirty)
    self.assertEqual(2, len(config._pending_uploads))
    self.assertEqual(self.new_pending_upload, config._pending_uploads[0])
    self.assertEqual(self.final_pending_upload, config._pending_uploads[1])
    self.assertEqual(self.new_dependencies, config._config_data)
    file_module = fake_filesystem.FakeFileOpen(self.fs)
    expected_file_lines = list(self.expected_file_lines)
    for line in file_module(self.file_path):
      self.assertEqual(expected_file_lines.pop(0), line.strip())
    self.fs.CloseOpenFile(file_module(self.file_path))
    self.assertEqual(expected_insert_calls,
                     uploader_cs_mock.Insert.call_args_list)
    self.assertEqual(expected_exists_calls,
                     uploader_cs_mock.Exists.call_args_list)
    self.assertEqual(expected_copy_calls,
                     uploader_cs_mock.Copy.call_args_list)
    self.assertEqual(expected_delete_calls,
                     uploader_cs_mock.Delete.call_args_list)

  @mock.patch('dependency_manager.uploader.cloud_storage')
  def testExecuteUpdateJobsFailureOnSecondInsertFirstCSCollisionForce(
      self, uploader_cs_mock):
    uploader_cs_mock.Exists.side_effect = [True, False, True]
    uploader_cs_mock.Insert.side_effect = [
        True, cloud_storage.CloudStorageError]
    self.fs.CreateFile(self.file_path,
                       contents='\n'.join(self.expected_file_lines))
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    config._config_data = self.new_dependencies.copy()
    config._is_dirty = True
    config._pending_uploads = [self.new_pending_upload,
                               self.final_pending_upload]
    self.assertEqual(self.new_dependencies, config._config_data)
    self.assertTrue(config._is_dirty)
    self.assertEqual(2, len(config._pending_uploads))
    self.assertEqual(self.new_pending_upload, config._pending_uploads[0])
    self.assertEqual(self.final_pending_upload, config._pending_uploads[1])
    expected_exists_calls = [mock.call(self.new_bucket, self.new_remote_path),
                             mock.call(self.final_bucket,
                                       self.final_remote_path)]
    expected_insert_calls = [mock.call(self.new_bucket, self.new_remote_path,
                                       self.new_dep_path),
                             mock.call(self.final_bucket,
                                       self.final_remote_path,
                                       self.final_dep_path)]
    expected_copy_calls = [mock.call(self.new_bucket, self.new_bucket,
                                     self.new_remote_path,
                                     self.expected_new_backup_path),
                           mock.call(self.new_bucket, self.new_bucket,
                                     self.expected_new_backup_path,
                                     self.new_remote_path)]
    expected_delete_calls = []

    self.assertRaises(cloud_storage.CloudStorageError,
                      config.ExecuteUpdateJobs, force=True)
    self.assertTrue(config._is_dirty)
    self.assertEqual(2, len(config._pending_uploads))
    self.assertEqual(self.new_pending_upload, config._pending_uploads[0])
    self.assertEqual(self.final_pending_upload, config._pending_uploads[1])
    self.assertEqual(self.new_dependencies, config._config_data)
    file_module = fake_filesystem.FakeFileOpen(self.fs)
    expected_file_lines = list(self.expected_file_lines)
    for line in file_module(self.file_path):
      self.assertEqual(expected_file_lines.pop(0), line.strip())
    self.fs.CloseOpenFile(file_module(self.file_path))
    self.assertEqual(expected_insert_calls,
                     uploader_cs_mock.Insert.call_args_list)
    self.assertEqual(expected_exists_calls,
                     uploader_cs_mock.Exists.call_args_list)
    self.assertEqual(expected_copy_calls,
                     uploader_cs_mock.Copy.call_args_list)
    self.assertEqual(expected_delete_calls,
                     uploader_cs_mock.Delete.call_args_list)

  @mock.patch('dependency_manager.uploader.cloud_storage')
  def testExecuteUpdateJobsFailureOnFirstCSCollisionNoForce(
      self, uploader_cs_mock):
    uploader_cs_mock.Exists.side_effect = [True, False, True]
    uploader_cs_mock.Insert.side_effect = [
        True, cloud_storage.CloudStorageError]
    self.fs.CreateFile(self.file_path,
                       contents='\n'.join(self.expected_file_lines))
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    config._config_data = self.new_dependencies.copy()
    config._is_dirty = True
    config._pending_uploads = [self.new_pending_upload,
                               self.final_pending_upload]
    self.assertEqual(self.new_dependencies, config._config_data)
    self.assertTrue(config._is_dirty)
    self.assertEqual(2, len(config._pending_uploads))
    self.assertEqual(self.new_pending_upload, config._pending_uploads[0])
    self.assertEqual(self.final_pending_upload, config._pending_uploads[1])
    expected_exists_calls = [mock.call(self.new_bucket, self.new_remote_path)]
    expected_insert_calls = []
    expected_copy_calls = []
    expected_delete_calls = []

    self.assertRaises(cloud_storage.CloudStorageError,
                      config.ExecuteUpdateJobs)
    self.assertTrue(config._is_dirty)
    self.assertEqual(2, len(config._pending_uploads))
    self.assertEqual(self.new_pending_upload, config._pending_uploads[0])
    self.assertEqual(self.final_pending_upload, config._pending_uploads[1])
    self.assertEqual(self.new_dependencies, config._config_data)
    file_module = fake_filesystem.FakeFileOpen(self.fs)
    expected_file_lines = list(self.expected_file_lines)
    for line in file_module(self.file_path):
      self.assertEqual(expected_file_lines.pop(0), line.strip())
    self.fs.CloseOpenFile(file_module(self.file_path))
    self.assertEqual(expected_insert_calls,
                     uploader_cs_mock.Insert.call_args_list)
    self.assertEqual(expected_exists_calls,
                     uploader_cs_mock.Exists.call_args_list)
    self.assertEqual(expected_copy_calls,
                     uploader_cs_mock.Copy.call_args_list)
    self.assertEqual(expected_delete_calls,
                     uploader_cs_mock.Delete.call_args_list)

  @mock.patch('dependency_manager.uploader.cloud_storage')
  def testExecuteUpdateJobsFailureOnSecondCopyCSCollision(
      self, uploader_cs_mock):
    uploader_cs_mock.Exists.return_value = True
    uploader_cs_mock.Insert.return_value = True
    uploader_cs_mock.Copy.side_effect = [
        True, cloud_storage.CloudStorageError, True]
    self.fs.CreateFile(self.file_path,
                       contents='\n'.join(self.expected_file_lines))
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    config._config_data = self.new_dependencies.copy()
    config._is_dirty = True
    config._pending_uploads = [self.new_pending_upload,
                               self.final_pending_upload]
    self.assertEqual(self.new_dependencies, config._config_data)
    self.assertTrue(config._is_dirty)
    self.assertEqual(2, len(config._pending_uploads))
    self.assertEqual(self.new_pending_upload, config._pending_uploads[0])
    self.assertEqual(self.final_pending_upload, config._pending_uploads[1])
    expected_exists_calls = [mock.call(self.new_bucket, self.new_remote_path),
                             mock.call(self.final_bucket,
                                       self.final_remote_path)]
    expected_insert_calls = [mock.call(self.new_bucket, self.new_remote_path,
                                       self.new_dep_path)]
    expected_copy_calls = [mock.call(self.new_bucket, self.new_bucket,
                                     self.new_remote_path,
                                     self.expected_new_backup_path),
                           mock.call(self.final_bucket, self.final_bucket,
                                     self.final_remote_path,
                                     self.expected_final_backup_path),
                           mock.call(self.new_bucket, self.new_bucket,
                                     self.expected_new_backup_path,
                                     self.new_remote_path)]
    expected_delete_calls = []

    self.assertRaises(cloud_storage.CloudStorageError,
                      config.ExecuteUpdateJobs, force=True)
    self.assertTrue(config._is_dirty)
    self.assertEqual(2, len(config._pending_uploads))
    self.assertEqual(self.new_pending_upload, config._pending_uploads[0])
    self.assertEqual(self.final_pending_upload, config._pending_uploads[1])
    self.assertEqual(self.new_dependencies, config._config_data)
    file_module = fake_filesystem.FakeFileOpen(self.fs)
    expected_file_lines = list(self.expected_file_lines)
    for line in file_module(self.file_path):
      self.assertEqual(expected_file_lines.pop(0), line.strip())
    self.fs.CloseOpenFile(file_module(self.file_path))
    self.assertEqual(expected_insert_calls,
                     uploader_cs_mock.Insert.call_args_list)
    self.assertEqual(expected_exists_calls,
                     uploader_cs_mock.Exists.call_args_list)
    self.assertEqual(expected_copy_calls,
                     uploader_cs_mock.Copy.call_args_list)
    self.assertEqual(expected_delete_calls,
                     uploader_cs_mock.Delete.call_args_list)

  @mock.patch('dependency_manager.uploader.cloud_storage')
  def testExecuteUpdateJobsFailureOnSecondCopyNoCSCollisionForce(
      self, uploader_cs_mock):
    uploader_cs_mock.Exists.side_effect = [False, True, False]
    uploader_cs_mock.Copy.side_effect = cloud_storage.CloudStorageError
    self.fs.CreateFile(self.file_path,
                       contents='\n'.join(self.expected_file_lines))
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    config._config_data = self.new_dependencies.copy()
    config._is_dirty = True
    config._pending_uploads = [self.new_pending_upload,
                               self.final_pending_upload]
    self.assertEqual(self.new_dependencies, config._config_data)
    self.assertTrue(config._is_dirty)
    self.assertEqual(2, len(config._pending_uploads))
    self.assertEqual(self.new_pending_upload, config._pending_uploads[0])
    self.assertEqual(self.final_pending_upload, config._pending_uploads[1])
    expected_exists_calls = [mock.call(self.new_bucket, self.new_remote_path),
                             mock.call(self.final_bucket,
                                       self.final_remote_path)]
    expected_insert_calls = [mock.call(self.new_bucket, self.new_remote_path,
                                       self.new_dep_path)]
    expected_copy_calls = [mock.call(self.final_bucket, self.final_bucket,
                                     self.final_remote_path,
                                     self.expected_final_backup_path)]
    expected_delete_calls = [mock.call(self.new_bucket, self.new_remote_path)]

    self.assertRaises(cloud_storage.CloudStorageError,
                      config.ExecuteUpdateJobs, force=True)
    self.assertTrue(config._is_dirty)
    self.assertEqual(2, len(config._pending_uploads))
    self.assertEqual(self.new_pending_upload, config._pending_uploads[0])
    self.assertEqual(self.final_pending_upload, config._pending_uploads[1])
    self.assertEqual(self.new_dependencies, config._config_data)
    file_module = fake_filesystem.FakeFileOpen(self.fs)
    expected_file_lines = list(self.expected_file_lines)
    for line in file_module(self.file_path):
      self.assertEqual(expected_file_lines.pop(0), line.strip())
    self.fs.CloseOpenFile(file_module(self.file_path))
    self.assertEqual(expected_insert_calls,
                     uploader_cs_mock.Insert.call_args_list)
    self.assertEqual(expected_exists_calls,
                     uploader_cs_mock.Exists.call_args_list)
    self.assertEqual(expected_copy_calls,
                     uploader_cs_mock.Copy.call_args_list)
    self.assertEqual(expected_delete_calls,
                     uploader_cs_mock.Delete.call_args_list)

  @mock.patch('dependency_manager.uploader.cloud_storage')
  def testExecuteUpdateJobsFailureOnSecondCopyNoCSCollisionNoForce(
      self, uploader_cs_mock):
    uploader_cs_mock.Exists.side_effect = [False, True, False]
    uploader_cs_mock.Copy.side_effect = cloud_storage.CloudStorageError
    self.fs.CreateFile(self.file_path,
                       contents='\n'.join(self.expected_file_lines))
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    config._config_data = self.new_dependencies.copy()
    config._is_dirty = True
    config._pending_uploads = [self.new_pending_upload,
                               self.final_pending_upload]
    self.assertEqual(self.new_dependencies, config._config_data)
    self.assertTrue(config._is_dirty)
    self.assertEqual(2, len(config._pending_uploads))
    self.assertEqual(self.new_pending_upload, config._pending_uploads[0])
    self.assertEqual(self.final_pending_upload, config._pending_uploads[1])
    expected_exists_calls = [mock.call(self.new_bucket, self.new_remote_path),
                             mock.call(self.final_bucket,
                                       self.final_remote_path)]
    expected_insert_calls = [mock.call(self.new_bucket, self.new_remote_path,
                                       self.new_dep_path)]
    expected_copy_calls = []
    expected_delete_calls = [mock.call(self.new_bucket, self.new_remote_path)]

    self.assertRaises(cloud_storage.CloudStorageError,
                      config.ExecuteUpdateJobs)
    self.assertTrue(config._is_dirty)
    self.assertEqual(2, len(config._pending_uploads))
    self.assertEqual(self.new_pending_upload, config._pending_uploads[0])
    self.assertEqual(self.final_pending_upload, config._pending_uploads[1])
    self.assertEqual(self.new_dependencies, config._config_data)
    file_module = fake_filesystem.FakeFileOpen(self.fs)
    expected_file_lines = list(self.expected_file_lines)
    for line in file_module(self.file_path):
      self.assertEqual(expected_file_lines.pop(0), line.strip())
    self.fs.CloseOpenFile(file_module(self.file_path))
    self.assertEqual(expected_insert_calls,
                     uploader_cs_mock.Insert.call_args_list)
    self.assertEqual(expected_exists_calls,
                     uploader_cs_mock.Exists.call_args_list)
    self.assertEqual(expected_copy_calls,
                     uploader_cs_mock.Copy.call_args_list)
    self.assertEqual(expected_delete_calls,
                     uploader_cs_mock.Delete.call_args_list)

  @mock.patch('dependency_manager.uploader.cloud_storage')
  def testExecuteUpdateJobsSuccessOnePendingDepNoCloudStorageCollision(
      self, uploader_cs_mock):
    uploader_cs_mock.Exists.return_value = False
    self.fs.CreateFile(self.file_path,
                       contents='\n'.join(self.expected_file_lines))
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    config._config_data = self.new_dependencies.copy()
    config._pending_uploads = [self.new_pending_upload]
    self.assertEqual(self.new_dependencies, config._config_data)
    self.assertTrue(config._IsDirty())
    self.assertEqual(1, len(config._pending_uploads))
    self.assertEqual(self.new_pending_upload, config._pending_uploads[0])
    expected_exists_calls = [mock.call(self.new_bucket, self.new_remote_path)]
    expected_insert_calls = [mock.call(self.new_bucket, self.new_remote_path,
                                       self.new_dep_path)]
    expected_copy_calls = []
    expected_delete_calls = []

    self.assertTrue(config.ExecuteUpdateJobs())
    self.assertFalse(config._IsDirty())
    self.assertFalse(config._pending_uploads)
    self.assertEqual(self.new_dependencies, config._config_data)
    file_module = fake_filesystem.FakeFileOpen(self.fs)
    expected_file_lines = list(self.new_expected_file_lines)
    for line in file_module(self.file_path):
      self.assertEqual(expected_file_lines.pop(0), line.strip())
    self.fs.CloseOpenFile(file_module(self.file_path))
    self.assertFalse(config._pending_uploads)
    self.assertEqual(expected_insert_calls,
                     uploader_cs_mock.Insert.call_args_list)
    self.assertEqual(expected_exists_calls,
                     uploader_cs_mock.Exists.call_args_list)
    self.assertEqual(expected_copy_calls,
                     uploader_cs_mock.Copy.call_args_list)
    self.assertEqual(expected_delete_calls,
                     uploader_cs_mock.Delete.call_args_list)

  @mock.patch('dependency_manager.uploader.cloud_storage')
  def testExecuteUpdateJobsSuccessOnePendingDepCloudStorageCollision(
      self, uploader_cs_mock):
    uploader_cs_mock.Exists.return_value = True
    self.fs.CreateFile(self.file_path,
                       contents='\n'.join(self.expected_file_lines))
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    config._config_data = self.new_dependencies.copy()
    config._pending_uploads = [self.new_pending_upload]
    self.assertEqual(self.new_dependencies, config._config_data)
    self.assertTrue(config._IsDirty())
    self.assertEqual(1, len(config._pending_uploads))
    self.assertEqual(self.new_pending_upload, config._pending_uploads[0])
    expected_exists_calls = [mock.call(self.new_bucket, self.new_remote_path)]
    expected_insert_calls = [mock.call(self.new_bucket, self.new_remote_path,
                                       self.new_dep_path)]
    expected_copy_calls = [mock.call(self.new_bucket, self.new_bucket,
                                     self.new_remote_path,
                                     self.expected_new_backup_path)]

    self.assertTrue(config.ExecuteUpdateJobs(force=True))
    self.assertFalse(config._IsDirty())
    self.assertFalse(config._pending_uploads)
    self.assertEqual(self.new_dependencies, config._config_data)
    file_module = fake_filesystem.FakeFileOpen(self.fs)
    expected_file_lines = list(self.new_expected_file_lines)
    for line in file_module(self.file_path):
      self.assertEqual(expected_file_lines.pop(0), line.strip())
    self.fs.CloseOpenFile(file_module(self.file_path))
    self.assertFalse(config._pending_uploads)
    self.assertEqual(expected_insert_calls,
                     uploader_cs_mock.Insert.call_args_list)
    self.assertEqual(expected_exists_calls,
                     uploader_cs_mock.Exists.call_args_list)
    self.assertEqual(expected_copy_calls,
                     uploader_cs_mock.Copy.call_args_list)

  @mock.patch('dependency_manager.uploader.cloud_storage')
  def testExecuteUpdateJobsErrorOnePendingDepCloudStorageCollisionNoForce(
      self, uploader_cs_mock):
    uploader_cs_mock.Exists.return_value = True
    self.fs.CreateFile(self.file_path,
                       contents='\n'.join(self.expected_file_lines))
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    config._config_data = self.new_dependencies.copy()
    config._is_dirty = True
    config._pending_uploads = [self.new_pending_upload]
    self.assertEqual(self.new_dependencies, config._config_data)
    self.assertTrue(config._is_dirty)
    self.assertEqual(1, len(config._pending_uploads))
    self.assertEqual(self.new_pending_upload, config._pending_uploads[0])
    expected_exists_calls = [mock.call(self.new_bucket, self.new_remote_path)]
    expected_insert_calls = []
    expected_copy_calls = []

    self.assertRaises(dependency_manager.CloudStorageUploadConflictError,
                      config.ExecuteUpdateJobs)
    self.assertTrue(config._is_dirty)
    self.assertTrue(config._pending_uploads)
    self.assertEqual(self.new_dependencies, config._config_data)
    self.assertEqual(1, len(config._pending_uploads))
    self.assertEqual(self.new_pending_upload, config._pending_uploads[0])
    file_module = fake_filesystem.FakeFileOpen(self.fs)
    expected_file_lines = list(self.expected_file_lines)
    for line in file_module(self.file_path):
      self.assertEqual(expected_file_lines.pop(0), line.strip())
    self.fs.CloseOpenFile(file_module(self.file_path))
    self.assertEqual(expected_insert_calls,
                     uploader_cs_mock.Insert.call_args_list)
    self.assertEqual(expected_exists_calls,
                     uploader_cs_mock.Exists.call_args_list)
    self.assertEqual(expected_copy_calls,
                     uploader_cs_mock.Copy.call_args_list)

  @mock.patch('dependency_manager.uploader.cloud_storage')
  def testExecuteUpdateJobsSuccessMultiplePendingDepsOneCloudStorageCollision(
      self, uploader_cs_mock):
    uploader_cs_mock.Exists.side_effect = [False, True]
    self.fs.CreateFile(self.file_path,
                       contents='\n'.join(self.expected_file_lines))
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    config._config_data = self.final_dependencies.copy()
    config._pending_uploads = [self.new_pending_upload,
                               self.final_pending_upload]
    self.assertEqual(self.final_dependencies, config._config_data)
    self.assertTrue(config._IsDirty())
    self.assertEqual(2, len(config._pending_uploads))
    self.assertEqual(self.new_pending_upload, config._pending_uploads[0])
    self.assertEqual(self.final_pending_upload, config._pending_uploads[1])

    expected_exists_calls = [mock.call(self.new_bucket, self.new_remote_path),
                             mock.call(self.final_bucket,
                                       self.final_remote_path)]
    expected_insert_calls = [mock.call(self.new_bucket, self.new_remote_path,
                                       self.new_dep_path),
                             mock.call(self.final_bucket,
                                       self.final_remote_path,
                                       self.final_dep_path)]
    expected_copy_calls = [mock.call(self.final_bucket, self.final_bucket,
                                     self.final_remote_path,
                                     self.expected_final_backup_path)]

    self.assertTrue(config.ExecuteUpdateJobs(force=True))
    self.assertFalse(config._IsDirty())
    self.assertFalse(config._pending_uploads)
    self.assertEqual(self.final_dependencies, config._config_data)
    file_module = fake_filesystem.FakeFileOpen(self.fs)
    expected_file_lines = list(self.final_expected_file_lines)
    for line in file_module(self.file_path):
      self.assertEqual(expected_file_lines.pop(0), line.strip())
    self.fs.CloseOpenFile(file_module(self.file_path))
    self.assertFalse(config._pending_uploads)
    self.assertEqual(expected_insert_calls,
                     uploader_cs_mock.Insert.call_args_list)
    self.assertEqual(expected_exists_calls,
                     uploader_cs_mock.Exists.call_args_list)
    self.assertEqual(expected_copy_calls,
                     uploader_cs_mock.Copy.call_args_list)

  @mock.patch('dependency_manager.uploader.cloud_storage')
  def testUpdateCloudStorageDependenciesReadOnlyConfig(
      self, uploader_cs_mock):
    self.fs.CreateFile(self.file_path,
                       contents='\n'.join(self.expected_file_lines))
    config = dependency_manager.BaseConfig(self.file_path)
    with self.assertRaises(dependency_manager.ReadWriteError):
      config.AddCloudStorageDependencyUpdateJob(
          'dep', 'plat', 'path')
    with self.assertRaises(dependency_manager.ReadWriteError):
      config.AddCloudStorageDependencyUpdateJob(
          'dep', 'plat', 'path', version='1.2.3')
    with self.assertRaises(dependency_manager.ReadWriteError):
      config.AddCloudStorageDependencyUpdateJob(
          'dep', 'plat', 'path', execute_job=False)
    with self.assertRaises(dependency_manager.ReadWriteError):
      config.AddCloudStorageDependencyUpdateJob(
          'dep', 'plat', 'path', version='1.2.3', execute_job=False)

  @mock.patch('dependency_manager.uploader.cloud_storage')
  def testUpdateCloudStorageDependenciesMissingDependency(
      self, uploader_cs_mock):
    self.fs.CreateFile(self.file_path,
                       contents='\n'.join(self.expected_file_lines))
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    self.assertRaises(ValueError, config.AddCloudStorageDependencyUpdateJob,
                      'dep', 'plat', 'path')
    self.assertRaises(ValueError, config.AddCloudStorageDependencyUpdateJob,
                      'dep', 'plat', 'path', version='1.2.3')
    self.assertRaises(ValueError, config.AddCloudStorageDependencyUpdateJob,
                      'dep', 'plat', 'path', execute_job=False)
    self.assertRaises(ValueError, config.AddCloudStorageDependencyUpdateJob,
                      'dep', 'plat', 'path', version='1.2.3', execute_job=False)

  @mock.patch('dependency_manager.uploader.cloud_storage')
  @mock.patch('dependency_manager.base_config.cloud_storage')
  def testUpdateCloudStorageDependenciesWrite(
      self, base_config_cs_mock, uploader_cs_mock):
    expected_dependencies = self.dependencies
    self.fs.CreateFile(self.file_path,
                       contents='\n'.join(self.expected_file_lines))
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    self.assertFalse(config._IsDirty())
    self.assertEqual(expected_dependencies, config._config_data)

    base_config_cs_mock.CalculateHash.return_value = self.new_dep_hash
    uploader_cs_mock.Exists.return_value = False
    expected_dependencies = self.new_dependencies
    config.AddCloudStorageDependencyUpdateJob(
        'dep1', 'plat2', self.new_dep_path, execute_job=True)
    self.assertFalse(config._IsDirty())
    self.assertFalse(config._pending_uploads)
    self.assertEqual(expected_dependencies, config._config_data)
    # check that file contents has been updated
    file_module = fake_filesystem.FakeFileOpen(self.fs)
    expected_file_lines = list(self.new_expected_file_lines)
    for line in file_module(self.file_path):
      self.assertEqual(expected_file_lines.pop(0), line.strip())
    self.fs.CloseOpenFile(file_module(self.file_path))

    expected_dependencies = self.final_dependencies
    base_config_cs_mock.CalculateHash.return_value = self.final_dep_hash
    config.AddCloudStorageDependencyUpdateJob(
        'dep2', 'plat1', self.final_dep_path, execute_job=True)
    self.assertFalse(config._IsDirty())
    self.assertFalse(config._pending_uploads)
    self.assertEqual(expected_dependencies, config._config_data)
    # check that file contents has been updated
    expected_file_lines = list(self.final_expected_file_lines)
    file_module = fake_filesystem.FakeFileOpen(self.fs)
    for line in file_module(self.file_path):
      self.assertEqual(expected_file_lines.pop(0), line.strip())
    self.fs.CloseOpenFile(file_module(self.file_path))

  @mock.patch('dependency_manager.uploader.cloud_storage')
  @mock.patch('dependency_manager.base_config.cloud_storage')
  def testUpdateCloudStorageDependenciesNoWrite(
      self, base_config_cs_mock, uploader_cs_mock):
    self.fs.CreateFile(self.file_path,
                       contents='\n'.join(self.expected_file_lines))
    config = dependency_manager.BaseConfig(self.file_path, writable=True)

    self.assertRaises(ValueError, config.AddCloudStorageDependencyUpdateJob,
                      'dep', 'plat', 'path')
    self.assertRaises(ValueError, config.AddCloudStorageDependencyUpdateJob,
                      'dep', 'plat', 'path', version='1.2.3')

    expected_dependencies = self.dependencies
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    self.assertFalse(config._IsDirty())
    self.assertFalse(config._pending_uploads)
    self.assertEqual(expected_dependencies, config._config_data)

    base_config_cs_mock.CalculateHash.return_value = self.new_dep_hash
    uploader_cs_mock.Exists.return_value = False
    expected_dependencies = self.new_dependencies
    config.AddCloudStorageDependencyUpdateJob(
        'dep1', 'plat2', self.new_dep_path, execute_job=False)
    self.assertTrue(config._IsDirty())
    self.assertEqual(1, len(config._pending_uploads))
    self.assertEqual(self.new_pending_upload, config._pending_uploads[0])
    self.assertEqual(expected_dependencies, config._config_data)
    # check that file contents have not been updated.
    expected_file_lines = list(self.expected_file_lines)
    file_module = fake_filesystem.FakeFileOpen(self.fs)
    for line in file_module(self.file_path):
      self.assertEqual(expected_file_lines.pop(0), line.strip())
    self.fs.CloseOpenFile(file_module(self.file_path))

    expected_dependencies = self.final_dependencies
    base_config_cs_mock.CalculateHash.return_value = self.final_dep_hash
    config.AddCloudStorageDependencyUpdateJob(
        'dep2', 'plat1', self.final_dep_path, execute_job=False)
    self.assertTrue(config._IsDirty())
    self.assertEqual(expected_dependencies, config._config_data)
    # check that file contents have not been updated.
    expected_file_lines = list(self.expected_file_lines)
    file_module = fake_filesystem.FakeFileOpen(self.fs)
    for line in file_module(self.file_path):
      self.assertEqual(expected_file_lines.pop(0), line.strip())
    self.fs.CloseOpenFile(file_module(self.file_path))


class BaseConfigDataManipulationUnittests(fake_filesystem_unittest.TestCase):
  def setUp(self):
    self.addTypeEqualityFunc(uploader.CloudStorageUploader,
                             uploader.CloudStorageUploader.__eq__)
    self.setUpPyfakefs()

    self.cs_bucket = 'bucket1'
    self.cs_base_folder = 'dependencies_folder'
    self.cs_hash = 'hash12'
    self.download_path = '../../relative/dep1/path2'
    self.local_paths = ['../../../relative/local/path21',
                        '../../../relative/local/path22']
    self.platform_dict = {'cloud_storage_hash': self.cs_hash,
                          'download_path': self.download_path,
                          'local_paths': self.local_paths}
    self.dependencies = {
        'dep1': {
            'cloud_storage_bucket': self.cs_bucket,
            'cloud_storage_base_folder': self.cs_base_folder,
            'file_info': {
                'plat1': {
                    'cloud_storage_hash': 'hash11',
                    'download_path': '../../relative/dep1/path1',
                    'local_paths': ['../../../relative/local/path11',
                                    '../../../relative/local/path12']},
                'plat2': self.platform_dict
            }
        },
        'dep2': {
            'cloud_storage_bucket': 'bucket2',
            'file_info': {
                'plat1': {
                    'cloud_storage_hash': 'hash21',
                    'download_path': '../../relative/dep2/path1',
                    'local_paths': ['../../../relative/local/path31',
                                    '../../../relative/local/path32']},
                'plat2': {
                    'cloud_storage_hash': 'hash22',
                    'download_path': '../../relative/dep2/path2'}}}}

    self.file_path = os.path.abspath(os.path.join(
        'path', 'to', 'config', 'file'))


    self.expected_file_lines = [
      # pylint: disable=bad-continuation
      '{', '"config_type": "BaseConfig",', '"dependencies": {',
        '"dep1": {', '"cloud_storage_base_folder": "dependencies_folder",',
          '"cloud_storage_bucket": "bucket1",', '"file_info": {',
            '"plat1": {', '"cloud_storage_hash": "hash11",',
              '"download_path": "../../relative/dep1/path1",',
              '"local_paths": [', '"../../../relative/local/path11",',
                              '"../../../relative/local/path12"', ']', '},',
            '"plat2": {', '"cloud_storage_hash": "hash12",',
              '"download_path": "../../relative/dep1/path2",',
              '"local_paths": [', '"../../../relative/local/path21",',
                              '"../../../relative/local/path22"', ']',
              '}', '}', '},',
        '"dep2": {', '"cloud_storage_bucket": "bucket2",', '"file_info": {',
            '"plat1": {', '"cloud_storage_hash": "hash21",',
              '"download_path": "../../relative/dep2/path1",',
              '"local_paths": [', '"../../../relative/local/path31",',
                              '"../../../relative/local/path32"', ']', '},',
            '"plat2": {', '"cloud_storage_hash": "hash22",',
              '"download_path": "../../relative/dep2/path2"', '}', '}', '}',
      '}', '}']
    self.fs.CreateFile(self.file_path,
                       contents='\n'.join(self.expected_file_lines))

  def testContaining(self):
    config = dependency_manager.BaseConfig(self.file_path)
    self.assertTrue('dep1' in config)
    self.assertTrue('dep2' in config)
    self.assertFalse('dep3' in config)

  def testAddNewDependencyNotWriteable(self):
    config = dependency_manager.BaseConfig(self.file_path)
    with self.assertRaises(dependency_manager.ReadWriteError):
      config.AddNewDependency('dep4', 'foo', 'bar')

  def testAddNewDependencyWriteableButDependencyAlreadyExists(self):
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    with self.assertRaises(ValueError):
      config.AddNewDependency('dep2', 'foo', 'bar')

  def testAddNewDependencySuccessfully(self):
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    config.AddNewDependency('dep3', 'foo', 'bar')
    self.assertTrue('dep3' in config)

  def testSetDownloadPathNotWritable(self):
    config = dependency_manager.BaseConfig(self.file_path)
    with self.assertRaises(dependency_manager.ReadWriteError):
      config.SetDownloadPath('dep2', 'plat1', '../../relative/dep1/path1')

  def testSetDownloadPathOnExistingPlatformSuccesfully(self):
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    download_path = '../../relative/dep1/foo.bar'
    config.SetDownloadPath('dep2', 'plat1', download_path)
    self.assertEqual(
        download_path,
        config._GetPlatformData('dep2', 'plat1', 'download_path'))

  def testSetDownloadPathOnNewPlatformSuccesfully(self):
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    download_path = '../../relative/dep1/foo.bar'
    config.SetDownloadPath('dep2', 'newplat', download_path)
    self.assertEqual(
        download_path,
        config._GetPlatformData('dep2', 'newplat', 'download_path'))


  def testSetPlatformDataFailureNotWritable(self):
    config = dependency_manager.BaseConfig(self.file_path)
    self.assertRaises(
        dependency_manager.ReadWriteError, config._SetPlatformData,
        'dep1', 'plat1', 'cloud_storage_bucket', 'new_bucket')
    self.assertEqual(self.dependencies, config._config_data)

  def testSetPlatformDataFailure(self):
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    self.assertRaises(ValueError, config._SetPlatformData, 'missing_dep',
                      'plat2', 'cloud_storage_bucket', 'new_bucket')
    self.assertEqual(self.dependencies, config._config_data)
    self.assertRaises(ValueError, config._SetPlatformData, 'dep1',
                      'missing_plat', 'cloud_storage_bucket', 'new_bucket')
    self.assertEqual(self.dependencies, config._config_data)


  def testSetPlatformDataCloudStorageBucketSuccess(self):
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    updated_cs_dependencies = {
        'dep1': {'cloud_storage_bucket': 'new_bucket',
                 'cloud_storage_base_folder': 'dependencies_folder',
                 'file_info': {
                     'plat1': {
                         'cloud_storage_hash': 'hash11',
                         'download_path': '../../relative/dep1/path1',
                         'local_paths': ['../../../relative/local/path11',
                                         '../../../relative/local/path12']},
                     'plat2': {
                         'cloud_storage_hash': 'hash12',
                         'download_path': '../../relative/dep1/path2',
                         'local_paths': ['../../../relative/local/path21',
                                         '../../../relative/local/path22']}}},
        'dep2': {'cloud_storage_bucket': 'bucket2',
                 'file_info': {
                     'plat1': {
                         'cloud_storage_hash': 'hash21',
                         'download_path': '../../relative/dep2/path1',
                         'local_paths': ['../../../relative/local/path31',
                                         '../../../relative/local/path32']},
                     'plat2': {
                         'cloud_storage_hash': 'hash22',
                         'download_path': '../../relative/dep2/path2'}}}}
    config._SetPlatformData('dep1', 'plat2', 'cloud_storage_bucket',
                            'new_bucket')
    self.assertEqual(updated_cs_dependencies, config._config_data)

  def testSetPlatformDataCloudStorageBaseFolderSuccess(self):
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    updated_cs_dependencies = {
        'dep1': {'cloud_storage_bucket': 'bucket1',
                 'cloud_storage_base_folder': 'new_dependencies_folder',
                 'file_info': {
                     'plat1': {
                         'cloud_storage_hash': 'hash11',
                         'download_path': '../../relative/dep1/path1',
                         'local_paths': ['../../../relative/local/path11',
                                         '../../../relative/local/path12']},
                     'plat2': {
                         'cloud_storage_hash': 'hash12',
                         'download_path': '../../relative/dep1/path2',
                         'local_paths': ['../../../relative/local/path21',
                                         '../../../relative/local/path22']}}},
        'dep2': {'cloud_storage_bucket': 'bucket2',
                 'file_info': {
                     'plat1': {
                         'cloud_storage_hash': 'hash21',
                         'download_path': '../../relative/dep2/path1',
                         'local_paths': ['../../../relative/local/path31',
                                         '../../../relative/local/path32']},
                     'plat2': {
                         'cloud_storage_hash': 'hash22',
                         'download_path': '../../relative/dep2/path2'}}}}
    config._SetPlatformData('dep1', 'plat2', 'cloud_storage_base_folder',
                            'new_dependencies_folder')
    self.assertEqual(updated_cs_dependencies, config._config_data)

  def testSetPlatformDataHashSuccess(self):
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    updated_cs_dependencies = {
        'dep1': {'cloud_storage_bucket': 'bucket1',
                 'cloud_storage_base_folder': 'dependencies_folder',
                 'file_info': {
                     'plat1': {
                         'cloud_storage_hash': 'hash11',
                         'download_path': '../../relative/dep1/path1',
                         'local_paths': ['../../../relative/local/path11',
                                         '../../../relative/local/path12']},
                     'plat2': {
                         'cloud_storage_hash': 'new_hash',
                         'download_path': '../../relative/dep1/path2',
                         'local_paths': ['../../../relative/local/path21',
                                         '../../../relative/local/path22']}}},
        'dep2': {'cloud_storage_bucket': 'bucket2',
                 'file_info': {
                     'plat1': {
                         'cloud_storage_hash': 'hash21',
                         'download_path': '../../relative/dep2/path1',
                         'local_paths': ['../../../relative/local/path31',
                                         '../../../relative/local/path32']},
                     'plat2': {
                         'cloud_storage_hash': 'hash22',
                         'download_path': '../../relative/dep2/path2'}}}}
    config._SetPlatformData('dep1', 'plat2', 'cloud_storage_hash',
                            'new_hash')
    self.assertEqual(updated_cs_dependencies, config._config_data)

  def testSetPlatformDataDownloadPathSuccess(self):
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    updated_cs_dependencies = {
        'dep1': {'cloud_storage_bucket': 'bucket1',
                 'cloud_storage_base_folder': 'dependencies_folder',
                 'file_info': {
                     'plat1': {
                         'cloud_storage_hash': 'hash11',
                         'download_path': '../../relative/dep1/path1',
                         'local_paths': ['../../../relative/local/path11',
                                         '../../../relative/local/path12']},
                     'plat2': {
                         'cloud_storage_hash': 'hash12',
                         'download_path': '../../new/dep1/path2',
                         'local_paths': ['../../../relative/local/path21',
                                         '../../../relative/local/path22']}}},
        'dep2': {'cloud_storage_bucket': 'bucket2',
                 'file_info': {
                     'plat1': {
                         'cloud_storage_hash': 'hash21',
                         'download_path': '../../relative/dep2/path1',
                         'local_paths': ['../../../relative/local/path31',
                                         '../../../relative/local/path32']},
                     'plat2': {
                         'cloud_storage_hash': 'hash22',
                         'download_path': '../../relative/dep2/path2'}}}}
    config._SetPlatformData('dep1', 'plat2', 'download_path',
                            '../../new/dep1/path2')
    self.assertEqual(updated_cs_dependencies, config._config_data)

  def testSetPlatformDataLocalPathSuccess(self):
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    updated_cs_dependencies = {
        'dep1': {'cloud_storage_bucket': 'bucket1',
                 'cloud_storage_base_folder': 'dependencies_folder',
                 'file_info': {
                     'plat1': {
                         'cloud_storage_hash': 'hash11',
                         'download_path': '../../relative/dep1/path1',
                         'local_paths': ['../../../relative/local/path11',
                                         '../../../relative/local/path12']},
                     'plat2': {
                         'cloud_storage_hash': 'hash12',
                         'download_path': '../../relative/dep1/path2',
                         'local_paths': ['../../new/relative/local/path21',
                                         '../../new/relative/local/path22']}}},
        'dep2': {'cloud_storage_bucket': 'bucket2',
                 'file_info': {
                     'plat1': {
                         'cloud_storage_hash': 'hash21',
                         'download_path': '../../relative/dep2/path1',
                         'local_paths': ['../../../relative/local/path31',
                                         '../../../relative/local/path32']},
                     'plat2': {
                         'cloud_storage_hash': 'hash22',
                         'download_path': '../../relative/dep2/path2'}}}}
    config._SetPlatformData('dep1', 'plat2', 'local_paths',
                            ['../../new/relative/local/path21',
                             '../../new/relative/local/path22'])
    self.assertEqual(updated_cs_dependencies, config._config_data)

  def testGetPlatformDataFailure(self):
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    self.assertRaises(ValueError, config._GetPlatformData, 'missing_dep',
                      'plat2', 'cloud_storage_bucket')
    self.assertEqual(self.dependencies, config._config_data)
    self.assertRaises(ValueError, config._GetPlatformData, 'dep1',
                      'missing_plat', 'cloud_storage_bucket')
    self.assertEqual(self.dependencies, config._config_data)

  def testGetPlatformDataDictSuccess(self):
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    self.assertEqual(self.platform_dict,
                     config._GetPlatformData('dep1', 'plat2'))
    self.assertEqual(self.dependencies, config._config_data)

  def testGetPlatformDataCloudStorageBucketSuccess(self):
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    self.assertEqual(self.cs_bucket, config._GetPlatformData(
        'dep1', 'plat2', 'cloud_storage_bucket'))
    self.assertEqual(self.dependencies, config._config_data)

  def testGetPlatformDataCloudStorageBaseFolderSuccess(self):
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    self.assertEqual(self.cs_base_folder, config._GetPlatformData(
        'dep1', 'plat2', 'cloud_storage_base_folder'))
    self.assertEqual(self.dependencies, config._config_data)

  def testGetPlatformDataHashSuccess(self):
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    self.assertEqual(self.cs_hash, config._GetPlatformData(
        'dep1', 'plat2', 'cloud_storage_hash'))
    self.assertEqual(self.dependencies, config._config_data)

  def testGetPlatformDataDownloadPathSuccess(self):
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    self.assertEqual(self.download_path, config._GetPlatformData(
        'dep1', 'plat2', 'download_path'))
    self.assertEqual(self.dependencies, config._config_data)

  def testGetPlatformDataLocalPathSuccess(self):
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    self.assertEqual(self.local_paths, config._GetPlatformData(
        'dep1', 'plat2', 'local_paths'))
    self.assertEqual(self.dependencies, config._config_data)

class BaseConfigTest(unittest.TestCase):
  """ Subclassable unittests for BaseConfig.
  For subclasses: override setUp, GetConfigDataFromDict,
    and EndToEndExpectedConfigData as needed.

    setUp must set the following properties:
      self.config_type: String returnedd from GetConfigType in config subclass.
      self.config_class: the class for the config subclass.
      self.config_module: importable module for the config subclass.
      self.empty_dict: expected dictionary for an empty config, as it would be
        stored in a json file.
      self.one_dep_dict: example dictionary for a config with one dependency,
        as it would be stored in a json file.
  """
  def setUp(self):
    self.config_type = 'BaseConfig'
    self.config_class = dependency_manager.BaseConfig
    self.config_module = 'dependency_manager.base_config'

    self.empty_dict = {'config_type': self.config_type,
                       'dependencies': {}}

    dependency_dict = {
        'dep': {
            'cloud_storage_base_folder': 'cs_base_folder1',
            'cloud_storage_bucket': 'bucket1',
            'file_info': {
                'plat1_arch1': {
                    'cloud_storage_hash': 'hash111',
                    'download_path': 'download_path111',
                    'cs_remote_path': 'cs_path111',
                    'version_in_cs': 'version_111',
                    'local_paths': ['local_path1110', 'local_path1111']
                },
                'plat1_arch2': {
                    'cloud_storage_hash': 'hash112',
                    'download_path': 'download_path112',
                    'cs_remote_path': 'cs_path112',
                    'local_paths': ['local_path1120', 'local_path1121']
                },
                'win_arch1': {
                    'cloud_storage_hash': 'hash1w1',
                    'download_path': 'download\\path\\1w1',
                    'cs_remote_path': 'cs_path1w1',
                    'local_paths': ['local\\path\\1w10', 'local\\path\\1w11']
                },
                'all_the_variables': {
                    'cloud_storage_hash': 'hash111',
                    'download_path': 'download_path111',
                    'cs_remote_path': 'cs_path111',
                    'version_in_cs': 'version_111',
                    'path_within_archive': 'path/within/archive',
                    'local_paths': ['local_path1110', 'local_path1111']
                }
            }
        }
    }
    self.one_dep_dict = {'config_type': self.config_type,
                         'dependencies': dependency_dict}

  def GetConfigDataFromDict(self, config_dict):
    return config_dict.get('dependencies', {})

  @mock.patch('os.path')
  @mock.patch('__builtin__.open')
  def testInitBaseProperties(self, open_mock, path_mock):
    # Init is not meant to be overridden, so we should be mocking the
    # base_config's json module, even in subclasses.
    json_module = 'dependency_manager.base_config.json'
    with mock.patch(json_module) as json_mock:
      json_mock.load.return_value = self.empty_dict.copy()
      config = self.config_class('file_path')
      self.assertEqual('file_path', config._config_path)
      self.assertEqual(self.config_type, config.GetConfigType())
      self.assertEqual(self.GetConfigDataFromDict(self.empty_dict),
                       config._config_data)

  @mock.patch('dependency_manager.dependency_info.DependencyInfo')
  @mock.patch('os.path')
  @mock.patch('__builtin__.open')
  def testInitWithDependencies(self, open_mock, path_mock, dep_info_mock):
    # Init is not meant to be overridden, so we should be mocking the
    # base_config's json module, even in subclasses.
    json_module = 'dependency_manager.base_config.json'
    with mock.patch(json_module) as json_mock:
      json_mock.load.return_value = self.one_dep_dict
      config = self.config_class('file_path')
      self.assertEqual('file_path', config._config_path)
      self.assertEqual(self.config_type, config.GetConfigType())
      self.assertEqual(self.GetConfigDataFromDict(self.one_dep_dict),
                       config._config_data)

  def testFormatPath(self):
    self.assertEqual(None, self.config_class._FormatPath(None))
    self.assertEqual('', self.config_class._FormatPath(''))
    self.assertEqual('some_string',
                     self.config_class._FormatPath('some_string'))

    expected_path = os.path.join('some', 'file', 'path')
    self.assertEqual(expected_path,
                     self.config_class._FormatPath('some/file/path'))
    self.assertEqual(expected_path,
                     self.config_class._FormatPath('some\\file\\path'))

  @mock.patch('dependency_manager.base_config.json')
  @mock.patch('dependency_manager.dependency_info.DependencyInfo')
  @mock.patch('os.path.exists')
  @mock.patch('__builtin__.open')
  def testIterDependenciesError(
      self, open_mock, exists_mock, dep_info_mock, json_mock):
    # Init is not meant to be overridden, so we should be mocking the
    # base_config's json module, even in subclasses.
    json_mock.load.return_value = self.one_dep_dict
    config = self.config_class('file_path', writable=True)
    self.assertEqual(self.GetConfigDataFromDict(self.one_dep_dict),
                     config._config_data)
    self.assertTrue(config._writable)
    with self.assertRaises(dependency_manager.ReadWriteError):
      for _ in config.IterDependencyInfo():
        pass

  @mock.patch('dependency_manager.base_config.json')
  @mock.patch('dependency_manager.dependency_info.DependencyInfo')
  @mock.patch('os.path.exists')
  @mock.patch('__builtin__.open')
  def testIterDependencies(
      self, open_mock, exists_mock, dep_info_mock, json_mock):
    json_mock.load.return_value = self.one_dep_dict
    config = self.config_class('file_path')
    self.assertEqual(self.GetConfigDataFromDict(self.one_dep_dict),
                     config._config_data)
    expected_dep_info = ['dep_info0', 'dep_info1', 'dep_info2']
    dep_info_mock.side_effect = expected_dep_info
    expected_calls = [
        mock.call('dep', 'plat1_arch1', 'file_path', cs_bucket='bucket1',
                  cs_hash='hash111', download_path='download_path111',
                  cs_remote_path='cs_path111',
                  local_paths=['local_path1110', 'local_path1111']),
        mock.call('dep', 'plat1_arch1', 'file_path', cs_bucket='bucket1',
                  cs_hash='hash112', download_path='download_path112',
                  cs_remote_path='cs_path112',
                  local_paths=['local_path1120', 'local_path1121']),
        mock.call('dep', 'win_arch1', 'file_path', cs_bucket='bucket1',
                  cs_hash='hash1w1',
                  download_path=os.path.join('download', 'path', '1w1'),
                  cs_remote_path='cs_path1w1',
                  local_paths=[os.path.join('download', 'path', '1w10'),
                               os.path.join('download', 'path', '1w11')])]
    deps_seen = []
    for dep_info in config.IterDependencyInfo():
      deps_seen.append(dep_info)
    dep_info_mock.assert_call_args(expected_calls)
    self.assertItemsEqual(expected_dep_info, deps_seen)

  @mock.patch('dependency_manager.base_config.json')
  @mock.patch('os.path.exists')
  @mock.patch('__builtin__.open')
  def testIterDependenciesStaleGlob(self, open_mock, exists_mock, json_mock):
    json_mock.load.return_value = self.one_dep_dict
    config = self.config_class('file_path')

    abspath = os.path.abspath
    should_match = set(map(abspath, [
        'dep_all_the_variables_0123456789abcdef0123456789abcdef01234567',
        'dep_all_the_variables_123456789abcdef0123456789abcdef012345678']))
    # Not testing case changes, because Windows is case-insensitive.
    should_not_match = set(map(abspath, [
        # A configuration that doesn't unzip shouldn't clear any stale unzips.
        'dep_plat1_arch1_0123456789abcdef0123456789abcdef01234567',
        # "Hash" component less than 40 characters (not a valid SHA1 hash).
        'dep_all_the_variables_0123456789abcdef0123456789abcdef0123456',
        # "Hash" component greater than 40 characters (not a valid SHA1 hash).
        'dep_all_the_variables_0123456789abcdef0123456789abcdef012345678',
        # "Hash" component not comprised of hex (not a valid SHA1 hash).
        'dep_all_the_variables_0123456789gggggg0123456789gggggg01234567']))

    # Create a fake filesystem just for glob to use
    fake_fs = fake_filesystem.FakeFilesystem()
    fake_glob = fake_filesystem_glob.FakeGlobModule(fake_fs)
    for stale_dir in set.union(should_match, should_not_match):
      fake_fs.CreateDirectory(stale_dir)
      fake_fs.CreateFile(os.path.join(stale_dir, 'some_file'))

    for dep_info in config.IterDependencyInfo():
      if dep_info.platform == 'all_the_variables':
        cs_info = dep_info.cloud_storage_info
        actual_glob = cs_info._archive_info._stale_unzip_path_glob
        actual_matches = set(fake_glob.glob(actual_glob))
        self.assertItemsEqual(should_match, actual_matches)
