pylint fixing for {cvd,gcompute}_compute_client and device_driver.

Also fixed up the unittests to use mock.patch appropriately.

Bug: None
Test: pylint and run_tests.sh pass
Change-Id: I5aaf4e8a17bf354a4428e2517f496b63edb8ed6e
diff --git a/internal/lib/cvd_compute_client.py b/internal/lib/cvd_compute_client.py
index 1b55faa..1bd3e99 100644
--- a/internal/lib/cvd_compute_client.py
+++ b/internal/lib/cvd_compute_client.py
@@ -41,7 +41,6 @@
 
 import getpass
 import logging
-import os
 
 from acloud.internal.lib import android_compute_client
 from acloud.internal.lib import gcompute_client
@@ -50,115 +49,85 @@
 
 
 class CvdComputeClient(android_compute_client.AndroidComputeClient):
-  """Client that manages Anadroid Virtual Device."""
+    """Client that manages Anadroid Virtual Device."""
 
-  DATA_POLICY_CREATE_IF_MISSING = "create_if_missing"
+    DATA_POLICY_CREATE_IF_MISSING = "create_if_missing"
 
-  def __init__(self, acloud_config, oauth2_credentials):
-    """Initialize.
+    # TODO: refactor CreateInstance to take in an object that contains these
+    # args, this method differs too and holds way too cf-specific args to put in
+    # the parent method.
+    # pylint: disable=arguments-differ
+    def CreateInstance(self, instance, image_name, image_project, build_target,
+                       branch, build_id, kernel_branch=None,
+                       kernel_build_id=None, blank_data_disk_size_gb=None):
+        """Create a cuttlefish instance given stable host image and build id.
 
-    Args:
-      acloud_config: An AcloudConfig object.
-      oauth2_credentials: An oauth2client.OAuth2Credentials instance.
-    """
-    super(CvdComputeClient, self).__init__(acloud_config, oauth2_credentials)
+        Args:
+          instance: instance name.
+          image_name: A string, the name of the GCE image.
+          image_project: A string, name of the project where the image belongs.
+                         Assume the default project if None.
+          build_target: Target name, e.g. "aosp_cf_x86_phone-userdebug"
+          branch: Branch name, e.g. "aosp-master"
+          build_id: Build id, a string, e.g. "2263051", "P2804227"
+          kernel_branch: Kernel branch name, e.g. "kernel-android-cf-4.4-x86_64"
+          kernel_build_id: Kernel build id, a string, e.g. "2263051", "P2804227"
+          blank_data_disk_size_gb: Size of the blank data disk in GB.
+        """
+        self._CheckMachineSize()
 
-  def _GetDiskArgs(self, disk_name, image_name, image_project, disk_size_gb):
-    """Helper to generate disk args that is used to create an instance.
+        # A blank data disk would be created on the host. Make sure the size of
+        # the boot disk is large enough to hold it.
+        boot_disk_size_gb = (
+            int(self.GetImage(image_name, image_project)["diskSizeGb"]) +
+            blank_data_disk_size_gb)
+        disk_args = self._GetDiskArgs(
+            instance, image_name, image_project, boot_disk_size_gb)
 
-    Args:
-      disk_name: A string
-      image_name: A string
-      image_project: A string
-      disk_size_gb: An integer
+        # Transitional metadata variable as outlined in go/cuttlefish-deployment
+        # These metadata tell the host instance to fetch and launch one
+        # cuttlefish device (cvd-01). Ideally we should use a separate tool to
+        # manage CVD devices on the host instance and not through metadata.
+        # TODO(b/77626419): Remove these metadata once the
+        # cuttlefish-google.service is turned off on the host instance.
+        metadata = self._metadata.copy()
+        resolution = self._resolution.split("x")
+        metadata["cvd_01_dpi"] = resolution[3]
+        metadata["cvd_01_fetch_android_build_target"] = build_target
+        metadata["cvd_01_fetch_android_bid"] = "{branch}/{build_id}".format(
+            branch=branch, build_id=build_id)
+        if kernel_branch and kernel_build_id:
+            metadata["cvd_01_fetch_kernel_bid"] = "{branch}/{build_id}".format(
+                branch=kernel_branch, build_id=kernel_build_id)
+        metadata["cvd_01_launch"] = "1"
+        metadata["cvd_01_x_res"] = resolution[0]
+        metadata["cvd_01_y_res"] = resolution[1]
+        if blank_data_disk_size_gb > 0:
+            # Policy 'create_if_missing' would create a blank userdata disk if
+            # missing. If already exist, reuse the disk.
+            metadata["cvd_01_data_policy"] = self.DATA_POLICY_CREATE_IF_MISSING
+            metadata["cvd_01_blank_data_disk_size"] = str(
+                blank_data_disk_size_gb * 1024)
 
-    Returns:
-      A dictionary representing disk args.
-    """
-    return [{
-        "type": "PERSISTENT",
-        "boot": True,
-        "mode": "READ_WRITE",
-        "autoDelete": True,
-        "initializeParams": {
-            "diskName": disk_name,
-            "sourceImage": self.GetImage(image_name, image_project)["selfLink"],
-            "diskSizeGb": disk_size_gb
-        },
-    }]
+        # Add per-instance ssh key
+        if self._ssh_public_key_path:
+            rsa = self._LoadSshPublicKey(self._ssh_public_key_path)
+            logger.info("ssh_public_key_path is specified in config: %s, "
+                        "will add the key to the instance.",
+                        self._ssh_public_key_path)
+            metadata["sshKeys"] = "%s:%s" % (getpass.getuser(), rsa)
+        else:
+            logger.warning(
+                "ssh_public_key_path is not specified in config, "
+                "only project-wide key will be effective.")
 
-  def CreateInstance(
-      self, instance, image_name, image_project, build_target, branch, build_id,
-      kernel_branch=None, kernel_build_id=None, blank_data_disk_size_gb=None):
-    """Create a cuttlefish instance given a stable host image and a build id.
-
-    Args:
-      instance: instance name.
-      image_name: A string, the name of the GCE image.
-      image_project: A string, name of the project where the image belongs.
-                     Assume the default project if None.
-      build_target: Target name, e.g. "aosp_cf_x86_phone-userdebug"
-      branch: Branch name, e.g. "aosp-master"
-      build_id: Build id, a string, e.g. "2263051", "P2804227"
-      kernel_branch: Kernel branch name, e.g. "kernel-android-cf-4.4-x86_64"
-      kernel_build_id: Kernel build id, a string, e.g. "2263051", "P2804227"
-      blank_data_disk_size_gb: Size of the blank data disk in GB.
-    """
-    self._CheckMachineSize()
-
-    # A blank data disk would be created on the host. Make sure the size of the
-    # boot disk is large enough to hold it.
-    boot_disk_size_gb = (
-        int(self.GetImage(image_name, image_project)["diskSizeGb"]) +
-        blank_data_disk_size_gb)
-    disk_args = self._GetDiskArgs(
-        instance, image_name, image_project, boot_disk_size_gb)
-
-    # Transitional metadata variable as outlined in go/cuttlefish-deployment
-    # These metadata tell the host instance to fetch and launch one cuttlefish
-    # device (cvd-01). Ideally we should use a separate tool to manage CVD
-    # devices on the host instance and not through metadata.
-    # TODO(b/77626419): Remove these metadata once the cuttlefish-google.service
-    # is
-    # turned off on the host instance.
-    metadata = self._metadata.copy()
-    resolution = self._resolution.split("x")
-    metadata["cvd_01_dpi"] = resolution[3]
-    metadata["cvd_01_fetch_android_build_target"] = build_target
-    metadata["cvd_01_fetch_android_bid"] = "{branch}/{build_id}".format(
-        branch=branch, build_id=build_id)
-    if kernel_branch and kernel_build_id:
-      metadata["cvd_01_fetch_kernel_bid"] = "{branch}/{build_id}".format(
-          branch=kernel_branch, build_id=kernel_build_id)
-    metadata["cvd_01_launch"] = "1"
-    metadata["cvd_01_x_res"] = resolution[0]
-    metadata["cvd_01_y_res"] = resolution[1]
-    if blank_data_disk_size_gb > 0:
-      # Policy 'create_if_missing' would create a blank userdata disk if
-      # missing. If already exist, reuse the disk.
-      metadata["cvd_01_data_policy"] = self.DATA_POLICY_CREATE_IF_MISSING
-      metadata["cvd_01_blank_data_disk_size"] = str(
-          blank_data_disk_size_gb * 1024)
-
-    # Add per-instance ssh key
-    if self._ssh_public_key_path:
-      rsa = self._LoadSshPublicKey(self._ssh_public_key_path)
-      logger.info("ssh_public_key_path is specified in config: %s, "
-                  "will add the key to the instance.",
-                  self._ssh_public_key_path)
-      metadata["sshKeys"] = "%s:%s" % (getpass.getuser(), rsa)
-    else:
-      logger.warning(
-          "ssh_public_key_path is not specified in config, "
-          "only project-wide key will be effective.")
-
-    gcompute_client.ComputeClient.CreateInstance(
-        self,
-        instance=instance,
-        image_name=image_name,
-        image_project=image_project,
-        disk_args=disk_args,
-        metadata=metadata,
-        machine_type=self._machine_type,
-        network=self._network,
-        zone=self._zone)
+        gcompute_client.ComputeClient.CreateInstance(
+            self,
+            instance=instance,
+            image_name=image_name,
+            image_project=image_project,
+            disk_args=disk_args,
+            metadata=metadata,
+            machine_type=self._machine_type,
+            network=self._network,
+            zone=self._zone)
diff --git a/internal/lib/cvd_compute_client_test.py b/internal/lib/cvd_compute_client_test.py
index 8b322ef..75005ed 100644
--- a/internal/lib/cvd_compute_client_test.py
+++ b/internal/lib/cvd_compute_client_test.py
@@ -16,102 +16,103 @@
 
 """Tests for acloud.internal.lib.cvd_compute_client."""
 
+import unittest
 import mock
 
-import unittest
 from acloud.internal.lib import cvd_compute_client
 from acloud.internal.lib import driver_test_lib
 from acloud.internal.lib import gcompute_client
 
 
 class CvdComputeClientTest(driver_test_lib.BaseDriverTest):
-  """Test CvdComputeClient."""
+    """Test CvdComputeClient."""
 
-  SSH_PUBLIC_KEY_PATH = ""
-  INSTANCE = "fake-instance"
-  IMAGE = "fake-image"
-  IMAGE_PROJECT = "fake-iamge-project"
-  MACHINE_TYPE = "fake-machine-type"
-  NETWORK = "fake-network"
-  ZONE = "fake-zone"
-  BRANCH = "fake-branch"
-  TARGET = "aosp_cf_x86_phone-userdebug"
-  BUILD_ID = "2263051"
-  KERNEL_BRANCH = "fake-kernel-branch"
-  KERNEL_BUILD_ID = "1234567"
-  DPI = 160
-  X_RES = 720
-  Y_RES = 1280
-  METADATA = {"metadata_key": "metadata_value"}
-  EXTRA_DATA_DISK_SIZE_GB = 4
-  BOOT_DISK_SIZE_GB = 10
+    SSH_PUBLIC_KEY_PATH = ""
+    INSTANCE = "fake-instance"
+    IMAGE = "fake-image"
+    IMAGE_PROJECT = "fake-iamge-project"
+    MACHINE_TYPE = "fake-machine-type"
+    NETWORK = "fake-network"
+    ZONE = "fake-zone"
+    BRANCH = "fake-branch"
+    TARGET = "aosp_cf_x86_phone-userdebug"
+    BUILD_ID = "2263051"
+    KERNEL_BRANCH = "fake-kernel-branch"
+    KERNEL_BUILD_ID = "1234567"
+    DPI = 160
+    X_RES = 720
+    Y_RES = 1280
+    METADATA = {"metadata_key": "metadata_value"}
+    EXTRA_DATA_DISK_SIZE_GB = 4
+    BOOT_DISK_SIZE_GB = 10
 
-  def _GetFakeConfig(self):
-    """Create a fake configuration object.
+    def _GetFakeConfig(self):
+        """Create a fake configuration object.
 
-    Returns:
-      A fake configuration mock object.
-    """
-    fake_cfg = mock.MagicMock()
-    fake_cfg.ssh_public_key_path = self.SSH_PUBLIC_KEY_PATH
-    fake_cfg.machine_type = self.MACHINE_TYPE
-    fake_cfg.network = self.NETWORK
-    fake_cfg.zone = self.ZONE
-    fake_cfg.resolution = "{x}x{y}x32x{dpi}".format(
-        x=self.X_RES, y=self.Y_RES, dpi=self.DPI)
-    fake_cfg.metadata_variable = self.METADATA
-    fake_cfg.extra_data_disk_size_gb = self.EXTRA_DATA_DISK_SIZE_GB
-    return fake_cfg
+        Returns:
+            A fake configuration mock object.
+        """
+        fake_cfg = mock.MagicMock()
+        fake_cfg.ssh_public_key_path = self.SSH_PUBLIC_KEY_PATH
+        fake_cfg.machine_type = self.MACHINE_TYPE
+        fake_cfg.network = self.NETWORK
+        fake_cfg.zone = self.ZONE
+        fake_cfg.resolution = "{x}x{y}x32x{dpi}".format(
+            x=self.X_RES, y=self.Y_RES, dpi=self.DPI)
+        fake_cfg.metadata_variable = self.METADATA
+        fake_cfg.extra_data_disk_size_gb = self.EXTRA_DATA_DISK_SIZE_GB
+        return fake_cfg
 
-  def setUp(self):
-    """Set up the test."""
-    super(CvdComputeClientTest, self).setUp()
-    self.Patch(cvd_compute_client.CvdComputeClient, "InitResourceHandle")
-    self.cvd_compute_client = cvd_compute_client.CvdComputeClient(
-        self._GetFakeConfig(), mock.MagicMock())
+    def setUp(self):
+        """Set up the test."""
+        super(CvdComputeClientTest, self).setUp()
+        self.Patch(cvd_compute_client.CvdComputeClient, "InitResourceHandle")
+        self.cvd_compute_client = cvd_compute_client.CvdComputeClient(
+            self._GetFakeConfig(), mock.MagicMock())
 
-  def testCreateInstance(self):
-    """Test CreateInstance."""
-    self.Patch(gcompute_client.ComputeClient, "CompareMachineSize",
-               return_value=1)
-    self.Patch(gcompute_client.ComputeClient, "GetImage",
-               return_value={"diskSizeGb": 10})
-    self.Patch(gcompute_client.ComputeClient, "CreateInstance")
-    self.Patch(cvd_compute_client.CvdComputeClient, "_GetDiskArgs",
-               return_value=[{"fake_arg": "fake_value"}])
+    @mock.patch.object(gcompute_client.ComputeClient, "CompareMachineSize",
+                       return_value=1)
+    @mock.patch.object(gcompute_client.ComputeClient, "GetImage",
+                       return_value={"diskSizeGb": 10})
+    @mock.patch.object(gcompute_client.ComputeClient, "CreateInstance")
+    @mock.patch.object(cvd_compute_client.CvdComputeClient, "_GetDiskArgs",
+                       return_value=[{"fake_arg": "fake_value"}])
+    def testCreateInstance(self, _get_disk_args, mock_create, _get_image,
+                           _compare_machine_size):
+        """Test CreateInstance."""
+        expected_metadata = {
+            "cvd_01_dpi": str(self.DPI),
+            "cvd_01_fetch_android_build_target": self.TARGET,
+            "cvd_01_fetch_android_bid": "{branch}/{build_id}".format(
+                branch=self.BRANCH, build_id=self.BUILD_ID),
+            "cvd_01_fetch_kernel_bid": "{branch}/{build_id}".format(
+                branch=self.KERNEL_BRANCH, build_id=self.KERNEL_BUILD_ID),
+            "cvd_01_launch": "1",
+            "cvd_01_x_res": str(self.X_RES),
+            "cvd_01_y_res": str(self.Y_RES),
+            "cvd_01_data_policy":
+                self.cvd_compute_client.DATA_POLICY_CREATE_IF_MISSING,
+            "cvd_01_blank_data_disk_size": str(self.EXTRA_DATA_DISK_SIZE_GB * 1024),
+        }
+        expected_metadata.update(self.METADATA)
+        expected_disk_args = [{"fake_arg": "fake_value"}]
 
-    expected_metadata = {
-        "cvd_01_dpi": str(self.DPI),
-        "cvd_01_fetch_android_build_target": self.TARGET,
-        "cvd_01_fetch_android_bid": "{branch}/{build_id}".format(
-            branch=self.BRANCH, build_id=self.BUILD_ID),
-        "cvd_01_fetch_kernel_bid": "{branch}/{build_id}".format(
-            branch=self.KERNEL_BRANCH, build_id=self.KERNEL_BUILD_ID),
-        "cvd_01_launch": "1",
-        "cvd_01_x_res": str(self.X_RES),
-        "cvd_01_y_res": str(self.Y_RES),
-        "cvd_01_data_policy":
-            self.cvd_compute_client.DATA_POLICY_CREATE_IF_MISSING,
-        "cvd_01_blank_data_disk_size": str(self.EXTRA_DATA_DISK_SIZE_GB * 1024),
-    }
-    expected_metadata.update(self.METADATA)
-    expected_disk_args = [{"fake_arg": "fake_value"}]
-
-    self.cvd_compute_client.CreateInstance(
-        self.INSTANCE, self.IMAGE, self.IMAGE_PROJECT, self.TARGET, self.BRANCH,
-        self.BUILD_ID, self.KERNEL_BRANCH, self.KERNEL_BUILD_ID,
-        self.EXTRA_DATA_DISK_SIZE_GB)
-    gcompute_client.ComputeClient.CreateInstance.assert_called_with(
-        self.cvd_compute_client,
-        instance=self.INSTANCE,
-        image_name=self.IMAGE,
-        image_project=self.IMAGE_PROJECT,
-        disk_args=expected_disk_args,
-        metadata=expected_metadata,
-        machine_type=self.MACHINE_TYPE,
-        network=self.NETWORK,
-        zone=self.ZONE)
+        self.cvd_compute_client.CreateInstance(
+            self.INSTANCE, self.IMAGE, self.IMAGE_PROJECT, self.TARGET, self.BRANCH,
+            self.BUILD_ID, self.KERNEL_BRANCH, self.KERNEL_BUILD_ID,
+            self.EXTRA_DATA_DISK_SIZE_GB)
+        # gcompute_client.ComputeClient.CreateInstance.assert_called_with(
+        mock_create.assert_called_with(
+            self.cvd_compute_client,
+            instance=self.INSTANCE,
+            image_name=self.IMAGE,
+            image_project=self.IMAGE_PROJECT,
+            disk_args=expected_disk_args,
+            metadata=expected_metadata,
+            machine_type=self.MACHINE_TYPE,
+            network=self.NETWORK,
+            zone=self.ZONE)
 
 
 if __name__ == "__main__":
-  unittest.main()
+    unittest.main()
diff --git a/internal/lib/gcompute_client.py b/internal/lib/gcompute_client.py
index cfda687..a215d7a 100755
--- a/internal/lib/gcompute_client.py
+++ b/internal/lib/gcompute_client.py
@@ -26,6 +26,7 @@
 and it only keeps states about authentication. ComputeClient should be very
 generic, and only knows how to talk to Compute Engine APIs.
 """
+# pylint: disable=too-many-lines
 import copy
 import functools
 import logging
@@ -39,6 +40,14 @@
 
 _MAX_RETRIES_ON_FINGERPRINT_CONFLICT = 10
 
+BASE_DISK_ARGS = {
+    "type": "PERSISTENT",
+    "boot": True,
+    "mode": "READ_WRITE",
+    "autoDelete": True,
+    "initializeParams": {},
+}
+
 
 class OperationScope(object):
     """Represents operation scope enum."""
@@ -76,6 +85,7 @@
     return isinstance(exc, errors.HttpError) and exc.code == 412
 
 
+# pylint: disable=too-many-public-methods
 class ComputeClient(base_cloud_client.BaseCloudApiClient):
     """Client that manages GCE."""
 
@@ -980,53 +990,51 @@
                                "type": "ONE_TO_ONE_NAT"}]
         }
 
-    def _GetDiskArgs(self, disk_name, image_name, image_project=None):
+    def _GetDiskArgs(self, disk_name, image_name, image_project=None,
+                     disk_size_gb=None):
         """Helper to generate disk args that is used to create an instance.
 
         Args:
             disk_name: A string
             image_name: A string
             image_project: A string
+            disk_size_gb: An integer
 
         Returns:
-            A dictionary representing disk args.
+            List holding dict of disk args.
         """
-        return [{
-            "type": "PERSISTENT",
-            "boot": True,
-            "mode": "READ_WRITE",
-            "autoDelete": True,
-            "initializeParams": {
-                "diskName": disk_name,
-                "sourceImage": self.GetImage(image_name, image_project)["selfLink"],
-            },
-        }]
+        args = copy.deepcopy(BASE_DISK_ARGS)
+        args["initializeParams"] = {
+            "diskName": disk_name,
+            "sourceImage": self.GetImage(image_name, image_project)["selfLink"],
+        }
+        # TODO: Remove this check once it's validated that we can either pass in
+        # a None diskSizeGb or we find an appropriate default val.
+        if disk_size_gb:
+            args["diskSizeGb"] = disk_size_gb
+        return [args]
 
-    def CreateInstance(self,
-                       instance,
-                       image_name,
-                       machine_type,
-                       metadata,
-                       network,
-                       zone,
-                       disk_args=None,
-                       image_project=None,
+    # pylint: disable=too-many-locals
+    def CreateInstance(self, instance, image_name, machine_type, metadata,
+                       network, zone, disk_args=None, image_project=None,
                        gpu=None):
         """Create a gce instance with a gce image.
 
         Args:
-            instance: instance name.
-            image_name: A source image used to create this disk.
-            machine_type: A string, representing machine_type, e.g. "n1-standard-1"
-            metadata: A dictionary that maps a metadata name to its value.
+            instance: A string, instance name.
+            image_name: A string, source image used to create this disk.
+            machine_type: A string, representing machine_type,
+                          e.g. "n1-standard-1"
+            metadata: A dict, maps a metadata name to its value.
             network: A string, representing network name, e.g. "default"
             zone: A string, representing zone name, e.g. "us-central1-f"
-            disk_args: A list of extra disk args, see _GetDiskArgs for example,
-                       if None, will create a disk using the given image.
-            image_project: A string, name of the project where the image belongs.
-                           Assume the default project if None.
-            gpu: The type of gpu to attach. e.g. "nvidia-tesla-k80", if None no
-                 gpus will be attached. For more details see:
+            disk_args: A list of extra disk args (strings), see _GetDiskArgs
+                       for example, if None, will create a disk using the given
+                       image.
+            image_project: A string, name of the project where the image
+                           belongs. Assume the default project if None.
+            gpu: A string, type of gpu to attach. e.g. "nvidia-tesla-k80", if
+                 None no gpus will be attached. For more details see:
                  https://cloud.google.com/compute/docs/gpus/add-gpus
         """
         disk_args = (disk_args or self._GetDiskArgs(instance, image_name,
@@ -1055,7 +1063,7 @@
                              for key, val in metadata.iteritems()]
             body["metadata"] = {"items": metadata_list}
         logger.info("Creating instance: project %s, zone %s, body:%s",
-            	    self._project, zone, body)
+                    self._project, zone, body)
         api = self.service.instances().insert(project=self._project,
                                               zone=zone,
                                               body=body)
@@ -1319,8 +1327,8 @@
 
         entry = "%s:%s" % (user, rsa)
         logger.debug("New RSA entry: %s", entry)
-        sshkey_item["value"] = "\n".join([sshkey_item["value"].strip(), entry
-                                          ]).strip()
+        sshkey_item["value"] = "\n".join([sshkey_item["value"].strip(),
+                                          entry]).strip()
         self.SetCommonInstanceMetadata(metadata)
 
     def CheckAccess(self):
diff --git a/internal/lib/gcompute_client_test.py b/internal/lib/gcompute_client_test.py
index 01b0a9e..7535a72 100644
--- a/internal/lib/gcompute_client_test.py
+++ b/internal/lib/gcompute_client_test.py
@@ -13,16 +13,19 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
-
 """Tests for acloud.internal.lib.gcompute_client."""
+# pylint: disable=too-many-lines
 
+import copy
 import os
 
-import apiclient.http
+import unittest
 import mock
+
+# pylint: disable=import-error
+import apiclient.http
 from absl.testing import parameterized
 
-import unittest
 from acloud.internal.lib import driver_test_lib
 from acloud.internal.lib import gcompute_client
 from acloud.internal.lib import utils
@@ -34,7 +37,7 @@
     "us-east1-d/disks/fake-disk")
 PROJECT = "fake-project"
 
-
+# pylint: disable=protected-access, too-many-public-methods
 class ComputeClientTest(driver_test_lib.BaseDriverTest, parameterized.TestCase):
     """Test ComputeClient."""
 
@@ -65,6 +68,11 @@
             fake_cfg, mock.MagicMock())
         self.compute_client._service = mock.MagicMock()
 
+        self._disk_args = copy.deepcopy(gcompute_client.BASE_DISK_ARGS)
+        self._disk_args["initializeParams"] = {"diskName": self.INSTANCE,
+                                               "sourceImage": self.IMAGE_URL}
+
+    # pylint: disable=invalid-name
     def _SetupMocksForGetOperationStatus(self, mock_result, operation_scope):
         """A helper class for setting up mocks for testGetOperationStatus*.
 
@@ -135,16 +143,17 @@
                                 {"name": self.OPERATION_NAME},
                                 gcompute_client.OperationScope.GLOBAL)
 
-    def testWaitOnOperation(self):
+    @mock.patch.object(errors, "GceOperationTimeoutError")
+    @mock.patch.object(utils, "PollAndWait")
+    def testWaitOnOperation(self, mock_poll, mock_gce_operation_timeout_error):
         """Test WaitOnOperation."""
         mock_error = mock.MagicMock()
-        self.Patch(utils, "PollAndWait")
-        self.Patch(errors, "GceOperationTimeoutError", return_value=mock_error)
+        mock_gce_operation_timeout_error.return_value = mock_error
         self.compute_client.WaitOnOperation(
             operation={"name": self.OPERATION_NAME},
             operation_scope=gcompute_client.OperationScope.REGION,
             scope_name=self.REGION)
-        utils.PollAndWait.assert_called_with(
+        mock_poll.assert_called_with(
             func=self.compute_client._GetOperationStatus,
             expected_return="DONE",
             timeout_exception=mock_error,
@@ -196,7 +205,7 @@
     # pyformat: enable
     def testCreateImage(self, source_uri, source_disk, labels, expected_body):
         """Test CreateImage."""
-        self.Patch(gcompute_client.ComputeClient, "WaitOnOperation")
+        mock_wait = self.Patch(gcompute_client.ComputeClient, "WaitOnOperation")
         resource_mock = mock.MagicMock()
         self.compute_client._service.images = mock.MagicMock(
             return_value=resource_mock)
@@ -205,34 +214,35 @@
             image_name=self.IMAGE, source_uri=source_uri,
             source_disk=source_disk, labels=labels)
         resource_mock.insert.assert_called_with(
-                project=PROJECT, body=expected_body)
-        self.compute_client.WaitOnOperation.assert_called_with(
+            project=PROJECT, body=expected_body)
+        mock_wait.assert_called_with(
             operation=mock.ANY,
             operation_scope=gcompute_client.OperationScope.GLOBAL)
 
-    @unittest.skip("Needs to use mock lib for proper mocking.")
-    def testSetImageLabel(self):
-        # TODO: AddMockObject() needs to be converted to use mock.
-        # self.AddMockObject(self.compute_client._service, "images",
-        #                    return_value=mock.MagicMock(setLabels=mock.MagicMock()))
-        image = {"name": self.IMAGE,
-                 "sourceDisk": GS_IMAGE_SOURCE_DISK,
-                 "labelFingerprint": self.IMAGE_FINGERPRINT,
-                 "labels": {"a": "aaa", "b": "bbb"}}
-        # self.AddMockObject(self.compute_client, "GetImage", return_value=image)
-        new_labels = {"a": "xxx", "c": "ccc"}
-        # Test
-        self.compute_client.SetImageLabels(
-            self.IMAGE, new_labels)
-        # Check result
-        expected_labels = {"a": "xxx", "b": "bbb", "c": "ccc"}
-        self.compute_client._service.images().setLabels.assert_called_with(
-            project=PROJECT,
-            resource=self.IMAGE,
-            body={
-                "labels": expected_labels,
-                "labelFingerprint": self.IMAGE_FINGERPRINT
-            })
+    @mock.patch.object(gcompute_client.ComputeClient, "GetImage")
+    def testSetImageLabel(self, mock_get_image):
+        """Test SetImageLabel."""
+        with mock.patch.object(self.compute_client._service, "images",
+                               return_value=mock.MagicMock(
+                                   setLabels=mock.MagicMock())) as _:
+            image = {"name": self.IMAGE,
+                     "sourceDisk": GS_IMAGE_SOURCE_DISK,
+                     "labelFingerprint": self.IMAGE_FINGERPRINT,
+                     "labels": {"a": "aaa", "b": "bbb"}}
+            mock_get_image.return_value = image
+            new_labels = {"a": "xxx", "c": "ccc"}
+            # Test
+            self.compute_client.SetImageLabels(
+                self.IMAGE, new_labels)
+            # Check result
+            expected_labels = {"a": "xxx", "b": "bbb", "c": "ccc"}
+            self.compute_client._service.images().setLabels.assert_called_with(
+                project=PROJECT,
+                resource=self.IMAGE,
+                body={
+                    "labels": expected_labels,
+                    "labelFingerprint": self.IMAGE_FINGERPRINT
+                })
 
     @parameterized.parameters(
         (GS_IMAGE_SOURCE_URI, GS_IMAGE_SOURCE_DISK),
@@ -243,18 +253,14 @@
                           image_name=self.IMAGE, source_uri=source_uri,
                           source_disk=source_disk)
 
-    def testCreateImageFail(self):
-        """Test CreateImage fails."""
-        self.Patch(
-            gcompute_client.ComputeClient,
-            "WaitOnOperation",
-            side_effect=errors.DriverError("Expected fake error"))
-        self.Patch(
-            gcompute_client.ComputeClient,
-            "CheckImageExists",
-            return_value=True)
-        self.Patch(gcompute_client.ComputeClient, "DeleteImage")
 
+    @mock.patch.object(gcompute_client.ComputeClient, "DeleteImage")
+    @mock.patch.object(gcompute_client.ComputeClient, "CheckImageExists",
+                       return_value=True)
+    @mock.patch.object(gcompute_client.ComputeClient, "WaitOnOperation",
+                       side_effect=errors.DriverError("Expected fake error"))
+    def testCreateImageFail(self, mock_wait, mock_check, mock_delete):
+        """Test CreateImage fails."""
         resource_mock = mock.MagicMock()
         self.compute_client._service.images = mock.MagicMock(
             return_value=resource_mock)
@@ -274,11 +280,11 @@
             source_uri=GS_IMAGE_SOURCE_URI)
         resource_mock.insert.assert_called_with(
             project=PROJECT, body=expected_body)
-        self.compute_client.WaitOnOperation.assert_called_with(
+        mock_wait.assert_called_with(
             operation=mock.ANY,
             operation_scope=gcompute_client.OperationScope.GLOBAL)
-        self.compute_client.CheckImageExists.assert_called_with(self.IMAGE)
-        self.compute_client.DeleteImage.assert_called_with(self.IMAGE)
+        mock_check.assert_called_with(self.IMAGE)
+        mock_delete.assert_called_with(self.IMAGE)
 
     def testCheckImageExistsTrue(self):
         """Test CheckImageExists return True."""
@@ -301,9 +307,9 @@
             side_effect=errors.ResourceNotFoundError(404, "no image"))
         self.assertFalse(self.compute_client.CheckImageExists(self.IMAGE))
 
-    def testDeleteImage(self):
+    @mock.patch.object(gcompute_client.ComputeClient, "WaitOnOperation")
+    def testDeleteImage(self, mock_wait):
         """Test DeleteImage."""
-        self.Patch(gcompute_client.ComputeClient, "WaitOnOperation")
         resource_mock = mock.MagicMock()
         self.compute_client._service.images = mock.MagicMock(
             return_value=resource_mock)
@@ -311,7 +317,7 @@
         self.compute_client.DeleteImage(self.IMAGE)
         resource_mock.delete.assert_called_with(
             project=PROJECT, image=self.IMAGE)
-        self.assertTrue(self.compute_client.WaitOnOperation.called)
+        self.assertTrue(mock_wait.called)
 
     def _SetupBatchHttpRequestMock(self):
         """Setup BatchHttpRequest mock."""
@@ -330,10 +336,10 @@
         mock_batch.execute = _Execute
         self.Patch(apiclient.http, "BatchHttpRequest", return_value=mock_batch)
 
-    def testDeleteImages(self):
+    @mock.patch.object(gcompute_client.ComputeClient, "WaitOnOperation")
+    def testDeleteImages(self, mock_wait):
         """Test DeleteImages."""
         self._SetupBatchHttpRequestMock()
-        self.Patch(gcompute_client.ComputeClient, "WaitOnOperation")
         fake_images = ["fake_image_1", "fake_image_2"]
         mock_api = mock.MagicMock()
         resource_mock = mock.MagicMock()
@@ -349,8 +355,7 @@
             mock.call(project=PROJECT, image="fake_image_2")
         ]
         resource_mock.delete.assert_has_calls(calls, any_order=True)
-        self.assertEqual(
-            gcompute_client.ComputeClient.WaitOnOperation.call_count, 2)
+        self.assertEqual(mock_wait.call_count, 2)
         self.assertEqual(error_msgs, [])
         self.assertEqual(failed, [])
         self.assertEqual(set(deleted), set(fake_images))
@@ -438,22 +443,16 @@
         resource_mock.list.assert_has_calls(calls)
         self.assertEqual(instances, [instance_1, instance_2])
 
-    def testCreateInstance(self):
+    @mock.patch.object(gcompute_client.ComputeClient, "GetImage")
+    @mock.patch.object(gcompute_client.ComputeClient, "GetNetworkUrl")
+    @mock.patch.object(gcompute_client.ComputeClient, "GetMachineType")
+    @mock.patch.object(gcompute_client.ComputeClient, "WaitOnOperation")
+    def testCreateInstance(self, mock_wait, mock_get_mach_type,
+                           mock_get_network_url, mock_get_image):
         """Test CreateInstance."""
-        self.Patch(gcompute_client.ComputeClient, "WaitOnOperation")
-        self.Patch(
-            gcompute_client.ComputeClient,
-            "GetMachineType",
-            return_value={"selfLink": self.MACHINE_TYPE_URL})
-        self.Patch(
-            gcompute_client.ComputeClient,
-            "GetNetworkUrl",
-            return_value=self.NETWORK_URL)
-        self.Patch(
-            gcompute_client.ComputeClient,
-            "GetImage",
-            return_value={"selfLink": self.IMAGE_URL})
-
+        mock_get_mach_type.return_value = {"selfLink": self.MACHINE_TYPE_URL}
+        mock_get_network_url.return_value = self.NETWORK_URL
+        mock_get_image.return_value = {"selfLink": self.IMAGE_URL}
         resource_mock = mock.MagicMock()
         self.compute_client._service.instances = mock.MagicMock(
             return_value=resource_mock)
@@ -471,18 +470,7 @@
                     ],
                 }
             ],
-            "disks": [
-                {
-                    "type": "PERSISTENT",
-                    "boot": True,
-                    "mode": "READ_WRITE",
-                    "autoDelete": True,
-                    "initializeParams": {
-                        "diskName": self.INSTANCE,
-                        "sourceImage": self.IMAGE_URL,
-                    },
-                }
-            ],
+            "disks": [self._disk_args],
             "serviceAccounts": [
                 {"email": "default",
                  "scopes": self.compute_client.DEFAULT_INSTANCE_SCOPE}
@@ -503,30 +491,24 @@
 
         resource_mock.insert.assert_called_with(
             project=PROJECT, zone=self.ZONE, body=expected_body)
-        self.compute_client.WaitOnOperation.assert_called_with(
+        mock_wait.assert_called_with(
             mock.ANY,
             operation_scope=gcompute_client.OperationScope.ZONE,
             scope_name=self.ZONE)
 
-    def testCreateInstanceWithGpu(self):
+    @mock.patch.object(gcompute_client.ComputeClient, "GetAcceleratorUrl")
+    @mock.patch.object(gcompute_client.ComputeClient, "GetImage")
+    @mock.patch.object(gcompute_client.ComputeClient, "GetNetworkUrl")
+    @mock.patch.object(gcompute_client.ComputeClient, "GetMachineType")
+    @mock.patch.object(gcompute_client.ComputeClient, "WaitOnOperation")
+    def testCreateInstanceWithGpu(self, mock_wait, mock_get_mach,
+                                  mock_get_network, mock_get_image,
+                                  mock_get_accel):
         """Test CreateInstance with a GPU parameter not set to None."""
-        self.Patch(gcompute_client.ComputeClient, "WaitOnOperation")
-        self.Patch(
-            gcompute_client.ComputeClient,
-            "GetMachineType",
-            return_value={"selfLink": self.MACHINE_TYPE_URL})
-        self.Patch(
-            gcompute_client.ComputeClient,
-            "GetNetworkUrl",
-            return_value=self.NETWORK_URL)
-        self.Patch(
-            gcompute_client.ComputeClient,
-            "GetAcceleratorUrl",
-            return_value=self.ACCELERATOR_URL)
-        self.Patch(
-            gcompute_client.ComputeClient,
-            "GetImage",
-            return_value={"selfLink": self.IMAGE_URL})
+        mock_get_mach.return_value = {"selfLink": self.MACHINE_TYPE_URL}
+        mock_get_network.return_value = self.NETWORK_URL
+        mock_get_accel.return_value = self.ACCELERATOR_URL
+        mock_get_image.return_value = {"selfLink": self.IMAGE_URL}
 
         resource_mock = mock.MagicMock()
         self.compute_client._service.instances = mock.MagicMock(
@@ -546,16 +528,7 @@
                     "type": "ONE_TO_ONE_NAT"
                 }],
             }],
-            "disks": [{
-                "type": "PERSISTENT",
-                "boot": True,
-                "mode": "READ_WRITE",
-                "autoDelete": True,
-                "initializeParams": {
-                    "diskName": self.INSTANCE,
-                    "sourceImage": self.IMAGE_URL,
-                },
-            }],
+            "disks": [self._disk_args],
             "serviceAccounts": [{
                 "email": "default",
                 "scopes": self.compute_client.DEFAULT_INSTANCE_SCOPE
@@ -586,13 +559,13 @@
 
         resource_mock.insert.assert_called_with(
             project=PROJECT, zone=self.ZONE, body=expected_body)
-        self.compute_client.WaitOnOperation.assert_called_with(
+        mock_wait.assert_called_with(
             mock.ANY, operation_scope=gcompute_client.OperationScope.ZONE,
             scope_name=self.ZONE)
 
-    def testDeleteInstance(self):
+    @mock.patch.object(gcompute_client.ComputeClient, "WaitOnOperation")
+    def testDeleteInstance(self, mock_wait):
         """Test DeleteInstance."""
-        self.Patch(gcompute_client.ComputeClient, "WaitOnOperation")
         resource_mock = mock.MagicMock()
         self.compute_client._service.instances = mock.MagicMock(
             return_value=resource_mock)
@@ -601,15 +574,15 @@
             instance=self.INSTANCE, zone=self.ZONE)
         resource_mock.delete.assert_called_with(
             project=PROJECT, zone=self.ZONE, instance=self.INSTANCE)
-        self.compute_client.WaitOnOperation.assert_called_with(
+        mock_wait.assert_called_with(
             mock.ANY,
             operation_scope=gcompute_client.OperationScope.ZONE,
             scope_name=self.ZONE)
 
-    def testDeleteInstances(self):
+    @mock.patch.object(gcompute_client.ComputeClient, "WaitOnOperation")
+    def testDeleteInstances(self, mock_wait):
         """Test DeleteInstances."""
         self._SetupBatchHttpRequestMock()
-        self.Patch(gcompute_client.ComputeClient, "WaitOnOperation")
         fake_instances = ["fake_instance_1", "fake_instance_2"]
         mock_api = mock.MagicMock()
         resource_mock = mock.MagicMock()
@@ -629,8 +602,7 @@
                 zone=self.ZONE)
         ]
         resource_mock.delete.assert_has_calls(calls, any_order=True)
-        self.assertEqual(
-            gcompute_client.ComputeClient.WaitOnOperation.call_count, 2)
+        self.assertEqual(mock_wait.call_count, 2)
         self.assertEqual(error_msgs, [])
         self.assertEqual(failed, [])
         self.assertEqual(set(deleted), set(fake_instances))
@@ -639,7 +611,7 @@
                               (None, PROJECT))
     def testCreateDisk(self, source_project, expected_project_to_use):
         """Test CreateDisk with images."""
-        self.Patch(gcompute_client.ComputeClient, "WaitOnOperation")
+        mock_wait = self.Patch(gcompute_client.ComputeClient, "WaitOnOperation")
         resource_mock = mock.MagicMock()
         self.compute_client._service.disks = mock.MagicMock(
             return_value=resource_mock)
@@ -660,14 +632,14 @@
                     "projects/%s/zones/%s/diskTypes/pd-standard" % (PROJECT,
                                                                     self.ZONE)
             })
-        self.assertTrue(self.compute_client.WaitOnOperation.called)
+        self.assertTrue(mock_wait.called)
 
     @parameterized.parameters(
         (gcompute_client.PersistentDiskType.STANDARD, "pd-standard"),
         (gcompute_client.PersistentDiskType.SSD, "pd-ssd"))
     def testCreateDiskWithType(self, disk_type, expected_disk_type_string):
         """Test CreateDisk with images."""
-        self.Patch(gcompute_client.ComputeClient, "WaitOnOperation")
+        mock_wait = self.Patch(gcompute_client.ComputeClient, "WaitOnOperation")
         resource_mock = mock.MagicMock()
         self.compute_client._service.disks = mock.MagicMock(
             return_value=resource_mock)
@@ -692,11 +664,11 @@
                     "projects/%s/zones/%s/diskTypes/%s" %
                     (PROJECT, self.ZONE, expected_disk_type_string)
             })
-        self.assertTrue(self.compute_client.WaitOnOperation.called)
+        self.assertTrue(mock_wait.called)
 
-    def testAttachDisk(self):
+    @mock.patch.object(gcompute_client.ComputeClient, "WaitOnOperation")
+    def testAttachDisk(self, mock_wait):
         """Test AttachDisk."""
-        self.Patch(gcompute_client.ComputeClient, "WaitOnOperation")
         resource_mock = mock.MagicMock()
         self.compute_client._service.instances = mock.MagicMock(
             return_value=resource_mock)
@@ -712,11 +684,11 @@
                 "deviceName": "fake_disk",
                 "source": "fake-selfLink"
             })
-        self.assertTrue(self.compute_client.WaitOnOperation.called)
+        self.assertTrue(mock_wait.called)
 
-    def testDetachDisk(self):
+    @mock.patch.object(gcompute_client.ComputeClient, "WaitOnOperation")
+    def testDetachDisk(self, mock_wait):
         """Test DetachDisk."""
-        self.Patch(gcompute_client.ComputeClient, "WaitOnOperation")
         resource_mock = mock.MagicMock()
         self.compute_client._service.instances = mock.MagicMock(
             return_value=resource_mock)
@@ -727,15 +699,13 @@
             zone=self.ZONE,
             instance="fake_instance_1",
             deviceName="fake_disk")
-        self.assertTrue(self.compute_client.WaitOnOperation.called)
+        self.assertTrue(mock_wait.called)
 
-    def testAttachAccelerator(self):
+    @mock.patch.object(gcompute_client.ComputeClient, "GetAcceleratorUrl")
+    @mock.patch.object(gcompute_client.ComputeClient, "WaitOnOperation")
+    def testAttachAccelerator(self, mock_wait, mock_get_accel):
         """Test AttachAccelerator."""
-        self.Patch(gcompute_client.ComputeClient, "WaitOnOperation")
-        self.Patch(
-            gcompute_client.ComputeClient,
-            "GetAcceleratorUrl",
-            return_value=self.ACCELERATOR_URL)
+        mock_get_accel.return_value = self.ACCELERATOR_URL
         resource_mock = mock.MagicMock()
         self.compute_client._service.instances = mock.MagicMock(
             return_value=resource_mock)
@@ -752,11 +722,12 @@
                     "acceleratorCount": 1
                 }]
             })
-        self.assertTrue(self.compute_client.WaitOnOperation.called)
+        self.assertTrue(mock_wait.called)
 
-    def testBatchExecuteOnInstances(self):
+    @mock.patch.object(gcompute_client.ComputeClient, "WaitOnOperation")
+    def testBatchExecuteOnInstances(self, mock_wait):
+        """Test BatchExecuteOnInstances."""
         self._SetupBatchHttpRequestMock()
-        self.Patch(gcompute_client.ComputeClient, "WaitOnOperation")
         action = mock.MagicMock(return_value=mock.MagicMock())
         fake_instances = ["fake_instance_1", "fake_instance_2"]
         done, failed, error_msgs = self.compute_client._BatchExecuteOnInstances(
@@ -764,15 +735,14 @@
         calls = [mock.call(instance="fake_instance_1"),
                  mock.call(instance="fake_instance_2")]
         action.assert_has_calls(calls, any_order=True)
-        self.assertEqual(
-            gcompute_client.ComputeClient.WaitOnOperation.call_count, 2)
+        self.assertEqual(mock_wait.call_count, 2)
         self.assertEqual(set(done), set(fake_instances))
         self.assertEqual(error_msgs, [])
         self.assertEqual(failed, [])
 
-    def testResetInstance(self):
+    @mock.patch.object(gcompute_client.ComputeClient, "WaitOnOperation")
+    def testResetInstance(self, mock_wait):
         """Test ResetInstance."""
-        self.Patch(gcompute_client.ComputeClient, "WaitOnOperation")
         resource_mock = mock.MagicMock()
         self.compute_client._service.instances = mock.MagicMock(
             return_value=resource_mock)
@@ -781,7 +751,7 @@
             instance=self.INSTANCE, zone=self.ZONE)
         resource_mock.reset.assert_called_with(
             project=PROJECT, zone=self.ZONE, instance=self.INSTANCE)
-        self.compute_client.WaitOnOperation.assert_called_with(
+        mock_wait.assert_called_with(
             mock.ANY,
             operation_scope=gcompute_client.OperationScope.ZONE,
             scope_name=self.ZONE)
@@ -799,7 +769,7 @@
             expected_result: An integer, 0, 1 or -1, or None if not set.
             expected_error_type: An exception type, if set will check for exception.
         """
-        self.Patch(
+        mock_get_mach_type = self.Patch(
             gcompute_client.ComputeClient,
             "GetMachineType",
             side_effect=[machine_info_1, machine_info_2])
@@ -812,7 +782,7 @@
                                                             self.ZONE)
             self.assertEqual(result, expected_result)
 
-        self.compute_client.GetMachineType.assert_has_calls(
+        mock_get_mach_type.assert_has_calls(
             [mock.call("name1", self.ZONE), mock.call("name2", self.ZONE)])
 
     def testCompareMachineSizeSmall(self):
@@ -887,10 +857,12 @@
             port=1)
 
     def testGetSerialPortOutput(self):
+        """Test GetSerialPortOutput."""
         response = {"contents": "fake contents"}
         self._GetSerialPortOutputTestHelper(response)
 
     def testGetSerialPortOutputFail(self):
+        """Test GetSerialPortOutputFail."""
         response = {"malformed": "fake contents"}
         self._GetSerialPortOutputTestHelper(response)
 
@@ -991,10 +963,10 @@
                                 self.compute_client.AddSshRsa, fake_user,
                                 "/path/to/test_rsa.pub")
 
-    def testDeleteDisks(self):
+    @mock.patch.object(gcompute_client.ComputeClient, "WaitOnOperation")
+    def testDeleteDisks(self, mock_wait):
         """Test DeleteDisks."""
         self._SetupBatchHttpRequestMock()
-        self.Patch(gcompute_client.ComputeClient, "WaitOnOperation")
         fake_disks = ["fake_disk_1", "fake_disk_2"]
         mock_api = mock.MagicMock()
         resource_mock = mock.MagicMock()
@@ -1010,19 +982,20 @@
             mock.call(project=PROJECT, disk="fake_disk_2", zone=self.ZONE)
         ]
         resource_mock.delete.assert_has_calls(calls, any_order=True)
-        self.assertEqual(
-            gcompute_client.ComputeClient.WaitOnOperation.call_count, 2)
+        self.assertEqual(mock_wait.call_count, 2)
         self.assertEqual(error_msgs, [])
         self.assertEqual(failed, [])
         self.assertEqual(set(deleted), set(fake_disks))
 
     def testRetryOnFingerPrintError(self):
+        """Test RetryOnFingerPrintError."""
         @utils.RetryOnException(gcompute_client._IsFingerPrintError, 10)
         def Raise412(sentinel):
-          if not sentinel.hitFingerPrintConflict.called:
-            sentinel.hitFingerPrintConflict()
-            raise errors.HttpError(412, "resource labels have changed")
-          return "Passed"
+            """Raise 412 HTTP exception."""
+            if not sentinel.hitFingerPrintConflict.called:
+                sentinel.hitFingerPrintConflict()
+                raise errors.HttpError(412, "resource labels have changed")
+            return "Passed"
 
         sentinel = mock.MagicMock()
         result = Raise412(sentinel)
diff --git a/public/device_driver.py b/public/device_driver.py
index 810a3a8..31cbb12 100755
--- a/public/device_driver.py
+++ b/public/device_driver.py
@@ -62,6 +62,7 @@
 ADB_CONNECT_CMD = "adb connect 127.0.0.1:%(adb_port)d"
 
 
+# pylint: disable=invalid-name
 class AndroidVirtualDevicePool(object):
     """A class that manages a pool of devices."""
 
@@ -375,6 +376,7 @@
                       vnc_port)
 
 
+# pylint: disable=too-many-locals
 def CreateAndroidVirtualDevices(cfg,
                                 build_target=None,
                                 build_id=None,
@@ -631,7 +633,7 @@
     """
     credentials = auth.CreateCredentials(cfg, ALL_SCOPES)
     compute_client = android_compute_client.AndroidComputeClient(
-            cfg, credentials)
+        cfg, credentials)
     logger.info("Checking if user has access to project %s", cfg.project)
     if not compute_client.CheckAccess():
         logger.error("User does not have access to project %s", cfg.project)
diff --git a/public/device_driver_test.py b/public/device_driver_test.py
index 321a87b..41853ba 100644
--- a/public/device_driver_test.py
+++ b/public/device_driver_test.py
@@ -19,10 +19,11 @@
 import datetime
 import uuid
 
-import dateutil.parser
+import unittest
 import mock
 
-import unittest
+import dateutil.parser
+
 from acloud.internal.lib import auth
 from acloud.internal.lib import android_build_client
 from acloud.internal.lib import android_compute_client
@@ -31,6 +32,26 @@
 from acloud.public import device_driver
 
 
+def _CreateCfg():
+    """A helper method that creates a mock configuration object."""
+    cfg = mock.MagicMock()
+    cfg.service_account_name = "fake@service.com"
+    cfg.service_account_private_key_path = "/fake/path/to/key"
+    cfg.zone = "fake_zone"
+    cfg.disk_image_name = "fake_image.tar.gz"
+    cfg.disk_image_mime_type = "fake/type"
+    cfg.storage_bucket_name = "fake_bucket"
+    cfg.extra_data_disk_size_gb = 4
+    cfg.precreated_data_image_map = {
+        4: "extradisk-image-4gb",
+        10: "extradisk-image-10gb"
+    }
+    cfg.ssh_private_key_path = ""
+    cfg.ssh_public_key_path = ""
+
+    return cfg
+
+
 class DeviceDriverTest(driver_test_lib.BaseDriverTest):
     """Test device_driver."""
 
@@ -39,7 +60,7 @@
         super(DeviceDriverTest, self).setUp()
         self.build_client = mock.MagicMock()
         self.Patch(android_build_client, "AndroidBuildClient",
-            return_value=self.build_client)
+                   return_value=self.build_client)
         self.storage_client = mock.MagicMock()
         self.Patch(
             gstorage_client, "StorageClient", return_value=self.storage_client)
@@ -50,28 +71,9 @@
             return_value=self.compute_client)
         self.Patch(auth, "CreateCredentials", return_value=mock.MagicMock())
 
-    def _CreateCfg(self):
-        """A helper method that creates a mock configuration object."""
-        cfg = mock.MagicMock()
-        cfg.service_account_name = "fake@service.com"
-        cfg.service_account_private_key_path = "/fake/path/to/key"
-        cfg.zone = "fake_zone"
-        cfg.disk_image_name = "fake_image.tar.gz"
-        cfg.disk_image_mime_type = "fake/type"
-        cfg.storage_bucket_name = "fake_bucket"
-        cfg.extra_data_disk_size_gb = 4
-        cfg.precreated_data_image_map = {
-            4: "extradisk-image-4gb",
-            10: "extradisk-image-10gb"
-        }
-        cfg.ssh_private_key_path = ""
-        cfg.ssh_public_key_path = ""
-
-        return cfg
-
     def testCreateAndroidVirtualDevices(self):
         """Test CreateAndroidVirtualDevices."""
-        cfg = self._CreateCfg()
+        cfg = _CreateCfg()
         fake_gs_url = "fake_gs_url"
         fake_ip = "140.1.1.1"
         fake_instance = "fake-instance"
@@ -93,14 +95,14 @@
         self.compute_client.GetDataDiskName.return_value = disk_name
 
         # Verify
-        r = device_driver.CreateAndroidVirtualDevices(
-        cfg, fake_build_target, fake_build_id)
+        report = device_driver.CreateAndroidVirtualDevices(
+            cfg, fake_build_target, fake_build_id)
         self.build_client.CopyTo.assert_called_with(
-        fake_build_target, fake_build_id, artifact_name=cfg.disk_image_name,
-        destination_bucket=cfg.storage_bucket_name,
-        destination_path=fake_gs_object)
+            fake_build_target, fake_build_id, artifact_name=cfg.disk_image_name,
+            destination_bucket=cfg.storage_bucket_name,
+            destination_path=fake_gs_object)
         self.compute_client.CreateImage.assert_called_with(
-        image_name=fake_image, source_uri=fake_gs_url)
+            image_name=fake_image, source_uri=fake_gs_url)
         self.compute_client.CreateInstance.assert_called_with(
             instance=fake_instance,
             image_name=fake_image,
@@ -109,7 +111,7 @@
         self.storage_client.Delete(cfg.storage_bucket_name, fake_gs_object)
 
         self.assertEquals(
-            r.data,
+            report.data,
             {
                 "devices": [
                     {
@@ -119,8 +121,8 @@
                 ],
             }
         )
-        self.assertEquals(r.command, "create")
-        self.assertEquals(r.status, "SUCCESS")
+        self.assertEquals(report.command, "create")
+        self.assertEquals(report.status, "SUCCESS")
 
 
     def testDeleteAndroidVirtualDevices(self):
@@ -128,11 +130,11 @@
         instance_names = ["fake-instance-1", "fake-instance-2"]
         self.compute_client.DeleteInstances.return_value = (instance_names, [],
                                                             [])
-        cfg = self._CreateCfg()
-        r = device_driver.DeleteAndroidVirtualDevices(cfg, instance_names)
+        cfg = _CreateCfg()
+        report = device_driver.DeleteAndroidVirtualDevices(cfg, instance_names)
         self.compute_client.DeleteInstances.assert_called_once_with(
             instance_names, cfg.zone)
-        self.assertEquals(r.data, {
+        self.assertEquals(report.data, {
             "deleted": [
                 {
                     "name": instance_names[0],
@@ -144,10 +146,11 @@
                 },
             ],
         })
-        self.assertEquals(r.command, "delete")
-        self.assertEquals(r.status, "SUCCESS")
+        self.assertEquals(report.command, "delete")
+        self.assertEquals(report.status, "SUCCESS")
 
     def testCleanup(self):
+        """Test Cleanup."""
         expiration_mins = 30
         before_deadline = "2015-10-29T12:00:30.018-07:00"
         after_deadline = "2015-10-29T12:45:30.018-07:00"
@@ -212,9 +215,9 @@
                                                         [])
         self.storage_client.DeleteFiles.return_value = (["fake_object_1"], [],
                                                         [])
-        cfg = self._CreateCfg()
-        r = device_driver.Cleanup(cfg, expiration_mins)
-        self.assertEqual(r.errors, [])
+        cfg = _CreateCfg()
+        report = device_driver.Cleanup(cfg, expiration_mins)
+        self.assertEqual(report.errors, [])
         expected_report_data = {
             "deleted": [
                 {"name": "fake_instance_1",
@@ -227,7 +230,7 @@
                  "type": "cached_build_artifact"},
             ]
         }
-        self.assertEqual(r.data, expected_report_data)
+        self.assertEqual(report.data, expected_report_data)
 
         self.compute_client.ListInstances.assert_called_once_with(
             zone=cfg.zone)
diff --git a/pylintrc b/pylintrc
index 853169e..67d515e 100644
--- a/pylintrc
+++ b/pylintrc
@@ -15,4 +15,4 @@
 function-rgx=[A-Z_][a-zA-Z0-9]{2,30}$|(__[a-z][a-zA-Z0-9_]+__)$
 
 # Good variable names which should always be accepted, separated by a comma
-good-names=e, f, logger
+good-names=e, f, logger, ip