Merge "Pylint fixing base_could_client,acloud_main,avd and common_operations."
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
new file mode 100644
index 0000000..67d515e
--- /dev/null
+++ b/pylintrc
@@ -0,0 +1,18 @@
+[MESSAGES CONTROL]
+
+disable=
+ relative-import,
+ too-few-public-methods,
+ fixme,
+ too-many-instance-attributes,
+ too-many-arguments
+
+[BASIC]
+
+# Acloud uses PascalCase for functions/methods except for test methods which use
+# camelCase.
+method-rgx=[A-Z_][a-zA-Z0-9]{2,30}$|(__[a-z][a-zA-Z0-9_]+__)$|test[A-Z_][a-zA-Z0-9]{2,30}$
+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, ip