From 33f46ba4aa34e066a70a5ad792254574b5985f83 Mon Sep 17 00:00:00 2001 From: Yoshi Automation Bot Date: Fri, 19 Jun 2020 19:35:25 -0700 Subject: [PATCH] feat: add async client (#8) * changes without context autosynth cannot find the source of changes triggered by earlier changes in this repository, or by version upgrades to tools such as linters. * fix(python): change autodoc_default_flags to autodoc_default_options Source-Author: HemangChothani <50404902+HemangChothani@users.noreply.github.com> Source-Date: Thu Jun 18 22:50:02 2020 +0530 Source-Repo: googleapis/synthtool Source-Sha: cd522c3b4dde821766d95c80ae5aeb43d7a41170 Source-Link: https://github.com/googleapis/synthtool/commit/cd522c3b4dde821766d95c80ae5aeb43d7a41170 * test: update tests for async Co-authored-by: Bu Sun Kim --- docs/conf.py | 2 +- docs/osconfig_v1/services.rst | 6 +- docs/osconfig_v1/types.rst | 4 +- google/cloud/osconfig/__init__.py | 5 +- google/cloud/osconfig_v1/__init__.py | 1 - .../services/os_config_service/__init__.py | 3 +- .../os_config_service/async_client.py | 790 +++++ .../services/os_config_service/client.py | 105 +- .../services/os_config_service/pagers.py | 198 +- .../os_config_service/transports/__init__.py | 8 +- .../os_config_service/transports/base.py | 68 +- .../os_config_service/transports/grpc.py | 21 +- .../transports/grpc_asyncio.py | 428 +++ noxfile.py | 1 + setup.py | 2 +- synth.metadata | 8 +- synth.py | 8 +- .../osconfig_v1/test_os_config_service.py | 2635 +++++++++++++++++ .../osconfig_v1/test_os_config_service.py | 1228 -------- 19 files changed, 4210 insertions(+), 1311 deletions(-) create mode 100644 google/cloud/osconfig_v1/services/os_config_service/async_client.py create mode 100644 google/cloud/osconfig_v1/services/os_config_service/transports/grpc_asyncio.py create mode 100644 tests/unit/gapic/osconfig_v1/test_os_config_service.py delete mode 100644 tests/unit/osconfig_v1/test_os_config_service.py diff --git a/docs/conf.py b/docs/conf.py index 10b42c7..3fa863c 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -43,7 +43,7 @@ # autodoc/autosummary flags autoclass_content = "both" -autodoc_default_flags = ["members"] +autodoc_default_options = {"members": True} autosummary_generate = True diff --git a/docs/osconfig_v1/services.rst b/docs/osconfig_v1/services.rst index 19eca48..dbdc04f 100644 --- a/docs/osconfig_v1/services.rst +++ b/docs/osconfig_v1/services.rst @@ -1,6 +1,6 @@ -Client for Google Cloud Osconfig API -==================================== +Services for Google Cloud Osconfig v1 API +========================================= -.. automodule:: google.cloud.osconfig_v1 +.. automodule:: google.cloud.osconfig_v1.services.os_config_service :members: :inherited-members: diff --git a/docs/osconfig_v1/types.rst b/docs/osconfig_v1/types.rst index bf4222e..3121f99 100644 --- a/docs/osconfig_v1/types.rst +++ b/docs/osconfig_v1/types.rst @@ -1,5 +1,5 @@ -Types for Google Cloud Osconfig API -=================================== +Types for Google Cloud Osconfig v1 API +====================================== .. automodule:: google.cloud.osconfig_v1.types :members: diff --git a/google/cloud/osconfig/__init__.py b/google/cloud/osconfig/__init__.py index 4896e10..85461f3 100644 --- a/google/cloud/osconfig/__init__.py +++ b/google/cloud/osconfig/__init__.py @@ -15,7 +15,9 @@ # limitations under the License. # - +from google.cloud.osconfig_v1.services.os_config_service.async_client import ( + OsConfigServiceAsyncClient, +) from google.cloud.osconfig_v1.services.os_config_service.client import ( OsConfigServiceClient, ) @@ -80,6 +82,7 @@ "ListPatchJobsResponse", "MonthlySchedule", "OneTimeSchedule", + "OsConfigServiceAsyncClient", "OsConfigServiceClient", "PatchConfig", "PatchDeployment", diff --git a/google/cloud/osconfig_v1/__init__.py b/google/cloud/osconfig_v1/__init__.py index 62aca0f..723191a 100644 --- a/google/cloud/osconfig_v1/__init__.py +++ b/google/cloud/osconfig_v1/__init__.py @@ -15,7 +15,6 @@ # limitations under the License. # - from .services.os_config_service import OsConfigServiceClient from .types.patch_deployments import CreatePatchDeploymentRequest from .types.patch_deployments import DeletePatchDeploymentRequest diff --git a/google/cloud/osconfig_v1/services/os_config_service/__init__.py b/google/cloud/osconfig_v1/services/os_config_service/__init__.py index e51c876..5f9e562 100644 --- a/google/cloud/osconfig_v1/services/os_config_service/__init__.py +++ b/google/cloud/osconfig_v1/services/os_config_service/__init__.py @@ -16,5 +16,6 @@ # from .client import OsConfigServiceClient +from .async_client import OsConfigServiceAsyncClient -__all__ = ("OsConfigServiceClient",) +__all__ = ("OsConfigServiceClient", "OsConfigServiceAsyncClient") diff --git a/google/cloud/osconfig_v1/services/os_config_service/async_client.py b/google/cloud/osconfig_v1/services/os_config_service/async_client.py new file mode 100644 index 0000000..b06f297 --- /dev/null +++ b/google/cloud/osconfig_v1/services/os_config_service/async_client.py @@ -0,0 +1,790 @@ +# -*- coding: utf-8 -*- + +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# 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. +# + +from collections import OrderedDict +import functools +import re +from typing import Dict, Sequence, Tuple, Type, Union +import pkg_resources + +import google.api_core.client_options as ClientOptions # type: ignore +from google.api_core import exceptions # type: ignore +from google.api_core import gapic_v1 # type: ignore +from google.api_core import retry as retries # type: ignore +from google.auth import credentials # type: ignore +from google.oauth2 import service_account # type: ignore + +from google.cloud.osconfig_v1.services.os_config_service import pagers +from google.cloud.osconfig_v1.types import patch_deployments +from google.cloud.osconfig_v1.types import patch_jobs +from google.protobuf import duration_pb2 as duration # type: ignore +from google.protobuf import timestamp_pb2 as timestamp # type: ignore + +from .transports.base import OsConfigServiceTransport +from .transports.grpc_asyncio import OsConfigServiceGrpcAsyncIOTransport +from .client import OsConfigServiceClient + + +class OsConfigServiceAsyncClient: + """OS Config API + The OS Config service is a server-side component that you can + use to manage package installations and patch jobs for virtual + machine instances. + """ + + _client: OsConfigServiceClient + + DEFAULT_ENDPOINT = OsConfigServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = OsConfigServiceClient.DEFAULT_MTLS_ENDPOINT + + patch_deployment_path = staticmethod(OsConfigServiceClient.patch_deployment_path) + + from_service_account_file = OsConfigServiceClient.from_service_account_file + from_service_account_json = from_service_account_file + + get_transport_class = functools.partial( + type(OsConfigServiceClient).get_transport_class, type(OsConfigServiceClient) + ) + + def __init__( + self, + *, + credentials: credentials.Credentials = None, + transport: Union[str, OsConfigServiceTransport] = "grpc_asyncio", + client_options: ClientOptions = None, + ) -> None: + """Instantiate the os config service client. + + Args: + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + transport (Union[str, ~.OsConfigServiceTransport]): The + transport to use. If set to None, a transport is chosen + automatically. + client_options (ClientOptions): Custom options for the client. It + won't take effect if a ``transport`` instance is provided. + (1) The ``api_endpoint`` property can be used to override the + default endpoint provided by the client. GOOGLE_API_USE_MTLS + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint, this is the default value for + the environment variable) and "auto" (auto switch to the default + mTLS endpoint if client SSL credentials is present). However, + the ``api_endpoint`` property takes precedence if provided. + (2) The ``client_cert_source`` property is used to provide client + SSL credentials for mutual TLS transport. If not provided, the + default SSL credentials will be used if present. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + + self._client = OsConfigServiceClient( + credentials=credentials, transport=transport, client_options=client_options + ) + + async def execute_patch_job( + self, + request: patch_jobs.ExecutePatchJobRequest = None, + *, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> patch_jobs.PatchJob: + r"""Patch VM instances by creating and running a patch + job. + + Args: + request (:class:`~.patch_jobs.ExecutePatchJobRequest`): + The request object. A request message to initiate + patching across Compute Engine instances. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.patch_jobs.PatchJob: + A high level representation of a patch job that is + either in progress or has completed. + + Instances details are not included in the job. To + paginate through instance details, use + ListPatchJobInstanceDetails. + + For more information about patch jobs, see `Creating + patch + jobs `__. + + """ + # Create or coerce a protobuf request object. + + request = patch_jobs.ExecutePatchJobRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.execute_patch_job, + default_timeout=None, + client_info=_client_info, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata) + + # Done; return the response. + return response + + async def get_patch_job( + self, + request: patch_jobs.GetPatchJobRequest = None, + *, + name: str = None, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> patch_jobs.PatchJob: + r"""Get the patch job. This can be used to track the + progress of an ongoing patch job or review the details + of completed jobs. + + Args: + request (:class:`~.patch_jobs.GetPatchJobRequest`): + The request object. Request to get an active or + completed patch job. + name (:class:`str`): + Required. Name of the patch in the form + ``projects/*/patchJobs/*`` + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.patch_jobs.PatchJob: + A high level representation of a patch job that is + either in progress or has completed. + + Instances details are not included in the job. To + paginate through instance details, use + ListPatchJobInstanceDetails. + + For more information about patch jobs, see `Creating + patch + jobs `__. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + if request is not None and any([name]): + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = patch_jobs.GetPatchJobRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_patch_job, + default_timeout=None, + client_info=_client_info, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata) + + # Done; return the response. + return response + + async def cancel_patch_job( + self, + request: patch_jobs.CancelPatchJobRequest = None, + *, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> patch_jobs.PatchJob: + r"""Cancel a patch job. The patch job must be active. + Canceled patch jobs cannot be restarted. + + Args: + request (:class:`~.patch_jobs.CancelPatchJobRequest`): + The request object. Message for canceling a patch job. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.patch_jobs.PatchJob: + A high level representation of a patch job that is + either in progress or has completed. + + Instances details are not included in the job. To + paginate through instance details, use + ListPatchJobInstanceDetails. + + For more information about patch jobs, see `Creating + patch + jobs `__. + + """ + # Create or coerce a protobuf request object. + + request = patch_jobs.CancelPatchJobRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.cancel_patch_job, + default_timeout=None, + client_info=_client_info, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata) + + # Done; return the response. + return response + + async def list_patch_jobs( + self, + request: patch_jobs.ListPatchJobsRequest = None, + *, + parent: str = None, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListPatchJobsAsyncPager: + r"""Get a list of patch jobs. + + Args: + request (:class:`~.patch_jobs.ListPatchJobsRequest`): + The request object. A request message for listing patch + jobs. + parent (:class:`str`): + Required. In the form of ``projects/*`` + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.pagers.ListPatchJobsAsyncPager: + A response message for listing patch + jobs. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + if request is not None and any([parent]): + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = patch_jobs.ListPatchJobsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_patch_jobs, + default_timeout=None, + client_info=_client_info, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListPatchJobsAsyncPager( + method=rpc, request=request, response=response + ) + + # Done; return the response. + return response + + async def list_patch_job_instance_details( + self, + request: patch_jobs.ListPatchJobInstanceDetailsRequest = None, + *, + parent: str = None, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListPatchJobInstanceDetailsAsyncPager: + r"""Get a list of instance details for a given patch job. + + Args: + request (:class:`~.patch_jobs.ListPatchJobInstanceDetailsRequest`): + The request object. Request to list details for all + instances that are part of a patch job. + parent (:class:`str`): + Required. The parent for the instances are in the form + of ``projects/*/patchJobs/*``. + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.pagers.ListPatchJobInstanceDetailsAsyncPager: + A response message for listing the + instances details for a patch job. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + if request is not None and any([parent]): + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = patch_jobs.ListPatchJobInstanceDetailsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_patch_job_instance_details, + default_timeout=None, + client_info=_client_info, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListPatchJobInstanceDetailsAsyncPager( + method=rpc, request=request, response=response + ) + + # Done; return the response. + return response + + async def create_patch_deployment( + self, + request: patch_deployments.CreatePatchDeploymentRequest = None, + *, + parent: str = None, + patch_deployment: patch_deployments.PatchDeployment = None, + patch_deployment_id: str = None, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> patch_deployments.PatchDeployment: + r"""Create an OS Config patch deployment. + + Args: + request (:class:`~.patch_deployments.CreatePatchDeploymentRequest`): + The request object. A request message for creating a + patch deployment. + parent (:class:`str`): + Required. The project to apply this patch deployment to + in the form ``projects/*``. + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + patch_deployment (:class:`~.patch_deployments.PatchDeployment`): + Required. The patch deployment to + create. + This corresponds to the ``patch_deployment`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + patch_deployment_id (:class:`str`): + Required. A name for the patch deployment in the + project. When creating a name the following rules apply: + + - Must contain only lowercase letters, numbers, and + hyphens. + - Must start with a letter. + - Must be between 1-63 characters. + - Must end with a number or a letter. + - Must be unique within the project. + + This corresponds to the ``patch_deployment_id`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.patch_deployments.PatchDeployment: + Patch deployments are configurations that individual + patch jobs use to complete a patch. These configurations + include instance filter, package repository settings, + and a schedule. For more information about creating and + managing patch deployments, see `Scheduling patch + jobs `__. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + if request is not None and any([parent, patch_deployment, patch_deployment_id]): + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = patch_deployments.CreatePatchDeploymentRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + + if parent is not None: + request.parent = parent + if patch_deployment is not None: + request.patch_deployment = patch_deployment + if patch_deployment_id is not None: + request.patch_deployment_id = patch_deployment_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.create_patch_deployment, + default_timeout=None, + client_info=_client_info, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata) + + # Done; return the response. + return response + + async def get_patch_deployment( + self, + request: patch_deployments.GetPatchDeploymentRequest = None, + *, + name: str = None, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> patch_deployments.PatchDeployment: + r"""Get an OS Config patch deployment. + + Args: + request (:class:`~.patch_deployments.GetPatchDeploymentRequest`): + The request object. A request message for retrieving a + patch deployment. + name (:class:`str`): + Required. The resource name of the patch deployment in + the form ``projects/*/patchDeployments/*``. + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.patch_deployments.PatchDeployment: + Patch deployments are configurations that individual + patch jobs use to complete a patch. These configurations + include instance filter, package repository settings, + and a schedule. For more information about creating and + managing patch deployments, see `Scheduling patch + jobs `__. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + if request is not None and any([name]): + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = patch_deployments.GetPatchDeploymentRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_patch_deployment, + default_timeout=None, + client_info=_client_info, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata) + + # Done; return the response. + return response + + async def list_patch_deployments( + self, + request: patch_deployments.ListPatchDeploymentsRequest = None, + *, + parent: str = None, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.ListPatchDeploymentsAsyncPager: + r"""Get a page of OS Config patch deployments. + + Args: + request (:class:`~.patch_deployments.ListPatchDeploymentsRequest`): + The request object. A request message for listing patch + deployments. + parent (:class:`str`): + Required. The resource name of the parent in the form + ``projects/*``. + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.pagers.ListPatchDeploymentsAsyncPager: + A response message for listing patch + deployments. + Iterating over this object will yield + results and resolve additional pages + automatically. + + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + if request is not None and any([parent]): + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = patch_deployments.ListPatchDeploymentsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_patch_deployments, + default_timeout=None, + client_info=_client_info, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = await rpc(request, retry=retry, timeout=timeout, metadata=metadata) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListPatchDeploymentsAsyncPager( + method=rpc, request=request, response=response + ) + + # Done; return the response. + return response + + async def delete_patch_deployment( + self, + request: patch_deployments.DeletePatchDeploymentRequest = None, + *, + name: str = None, + retry: retries.Retry = gapic_v1.method.DEFAULT, + timeout: float = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Delete an OS Config patch deployment. + + Args: + request (:class:`~.patch_deployments.DeletePatchDeploymentRequest`): + The request object. A request message for deleting a + patch deployment. + name (:class:`str`): + Required. The resource name of the patch deployment in + the form ``projects/*/patchDeployments/*``. + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Sanity check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + if request is not None and any([name]): + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = patch_deployments.DeletePatchDeploymentRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.delete_patch_deployment, + default_timeout=None, + client_info=_client_info, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Send the request. + await rpc(request, retry=retry, timeout=timeout, metadata=metadata) + + +try: + _client_info = gapic_v1.client_info.ClientInfo( + gapic_version=pkg_resources.get_distribution("google-cloud-os-config").version + ) +except pkg_resources.DistributionNotFound: + _client_info = gapic_v1.client_info.ClientInfo() + + +__all__ = ("OsConfigServiceAsyncClient",) diff --git a/google/cloud/osconfig_v1/services/os_config_service/client.py b/google/cloud/osconfig_v1/services/os_config_service/client.py index 39a7c3f..9e0ba0e 100644 --- a/google/cloud/osconfig_v1/services/os_config_service/client.py +++ b/google/cloud/osconfig_v1/services/os_config_service/client.py @@ -16,6 +16,7 @@ # from collections import OrderedDict +import os import re from typing import Callable, Dict, Sequence, Tuple, Type, Union import pkg_resources @@ -25,6 +26,8 @@ from google.api_core import gapic_v1 # type: ignore from google.api_core import retry as retries # type: ignore from google.auth import credentials # type: ignore +from google.auth.transport import mtls # type: ignore +from google.auth.exceptions import MutualTLSChannelError # type: ignore from google.oauth2 import service_account # type: ignore from google.cloud.osconfig_v1.services.os_config_service import pagers @@ -35,6 +38,7 @@ from .transports.base import OsConfigServiceTransport from .transports.grpc import OsConfigServiceGrpcTransport +from .transports.grpc_asyncio import OsConfigServiceGrpcAsyncIOTransport class OsConfigServiceClientMeta(type): @@ -49,6 +53,7 @@ class OsConfigServiceClientMeta(type): OrderedDict() ) # type: Dict[str, Type[OsConfigServiceTransport]] _transport_registry["grpc"] = OsConfigServiceGrpcTransport + _transport_registry["grpc_asyncio"] = OsConfigServiceGrpcAsyncIOTransport def get_transport_class(cls, label: str = None) -> Type[OsConfigServiceTransport]: """Return an appropriate transport class. @@ -164,21 +169,49 @@ def __init__( transport (Union[str, ~.OsConfigServiceTransport]): The transport to use. If set to None, a transport is chosen automatically. - client_options (ClientOptions): Custom options for the client. + client_options (ClientOptions): Custom options for the client. It + won't take effect if a ``transport`` instance is provided. (1) The ``api_endpoint`` property can be used to override the - default endpoint provided by the client. - (2) If ``transport`` argument is None, ``client_options`` can be - used to create a mutual TLS transport. If ``client_cert_source`` - is provided, mutual TLS transport will be created with the given - ``api_endpoint`` or the default mTLS endpoint, and the client - SSL credentials obtained from ``client_cert_source``. + default endpoint provided by the client. GOOGLE_API_USE_MTLS + environment variable can also be used to override the endpoint: + "always" (always use the default mTLS endpoint), "never" (always + use the default regular endpoint, this is the default value for + the environment variable) and "auto" (auto switch to the default + mTLS endpoint if client SSL credentials is present). However, + the ``api_endpoint`` property takes precedence if provided. + (2) The ``client_cert_source`` property is used to provide client + SSL credentials for mutual TLS transport. If not provided, the + default SSL credentials will be used if present. Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport creation failed for any reason. """ if isinstance(client_options, dict): client_options = ClientOptions.from_dict(client_options) + if client_options is None: + client_options = ClientOptions.ClientOptions() + + if client_options.api_endpoint is None: + use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS", "never") + if use_mtls_env == "never": + client_options.api_endpoint = self.DEFAULT_ENDPOINT + elif use_mtls_env == "always": + client_options.api_endpoint = self.DEFAULT_MTLS_ENDPOINT + elif use_mtls_env == "auto": + has_client_cert_source = ( + client_options.client_cert_source is not None + or mtls.has_default_client_cert_source() + ) + client_options.api_endpoint = ( + self.DEFAULT_MTLS_ENDPOINT + if has_client_cert_source + else self.DEFAULT_ENDPOINT + ) + else: + raise MutualTLSChannelError( + "Unsupported GOOGLE_API_USE_MTLS value. Accepted values: never, auto, always" + ) # Save or instantiate the transport. # Ordinarily, we provide the transport, but allowing a custom transport @@ -191,38 +224,12 @@ def __init__( "provide its credentials directly." ) self._transport = transport - elif client_options is None or ( - client_options.api_endpoint is None - and client_options.client_cert_source is None - ): - # Don't trigger mTLS if we get an empty ClientOptions. + else: Transport = type(self).get_transport_class(transport) self._transport = Transport( - credentials=credentials, host=self.DEFAULT_ENDPOINT - ) - else: - # We have a non-empty ClientOptions. If client_cert_source is - # provided, trigger mTLS with user provided endpoint or the default - # mTLS endpoint. - if client_options.client_cert_source: - api_mtls_endpoint = ( - client_options.api_endpoint - if client_options.api_endpoint - else self.DEFAULT_MTLS_ENDPOINT - ) - else: - api_mtls_endpoint = None - - api_endpoint = ( - client_options.api_endpoint - if client_options.api_endpoint - else self.DEFAULT_ENDPOINT - ) - - self._transport = OsConfigServiceGrpcTransport( credentials=credentials, - host=api_endpoint, - api_mtls_endpoint=api_mtls_endpoint, + host=client_options.api_endpoint, + api_mtls_endpoint=client_options.api_endpoint, client_cert_source=client_options.client_cert_source, ) @@ -274,6 +281,12 @@ def execute_patch_job( client_info=_client_info, ) + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + # Send the request. response = rpc(request, retry=retry, timeout=timeout, metadata=metadata) @@ -408,6 +421,12 @@ def cancel_patch_job( client_info=_client_info, ) + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + # Send the request. response = rpc(request, retry=retry, timeout=timeout, metadata=metadata) @@ -662,6 +681,12 @@ def create_patch_deployment( client_info=_client_info, ) + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + # Send the request. response = rpc(request, retry=retry, timeout=timeout, metadata=metadata) @@ -876,6 +901,12 @@ def delete_patch_deployment( client_info=_client_info, ) + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + # Send the request. rpc(request, retry=retry, timeout=timeout, metadata=metadata) diff --git a/google/cloud/osconfig_v1/services/os_config_service/pagers.py b/google/cloud/osconfig_v1/services/os_config_service/pagers.py index 6d0c848..83ef8f6 100644 --- a/google/cloud/osconfig_v1/services/os_config_service/pagers.py +++ b/google/cloud/osconfig_v1/services/os_config_service/pagers.py @@ -15,7 +15,7 @@ # limitations under the License. # -from typing import Any, Callable, Iterable +from typing import Any, AsyncIterable, Awaitable, Callable, Iterable from google.cloud.osconfig_v1.types import patch_deployments from google.cloud.osconfig_v1.types import patch_jobs @@ -80,6 +80,70 @@ def __repr__(self) -> str: return "{0}<{1!r}>".format(self.__class__.__name__, self._response) +class ListPatchJobsAsyncPager: + """A pager for iterating through ``list_patch_jobs`` requests. + + This class thinly wraps an initial + :class:`~.patch_jobs.ListPatchJobsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``patch_jobs`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListPatchJobs`` requests and continue to iterate + through the ``patch_jobs`` field on the + corresponding responses. + + All the usual :class:`~.patch_jobs.ListPatchJobsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[ + [patch_jobs.ListPatchJobsRequest], + Awaitable[patch_jobs.ListPatchJobsResponse], + ], + request: patch_jobs.ListPatchJobsRequest, + response: patch_jobs.ListPatchJobsResponse, + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (:class:`~.patch_jobs.ListPatchJobsRequest`): + The initial request object. + response (:class:`~.patch_jobs.ListPatchJobsResponse`): + The initial response object. + """ + self._method = method + self._request = patch_jobs.ListPatchJobsRequest(request) + self._response = response + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterable[patch_jobs.ListPatchJobsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request) + yield self._response + + def __aiter__(self) -> AsyncIterable[patch_jobs.PatchJob]: + async def async_generator(): + async for page in self.pages: + for response in page.patch_jobs: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + class ListPatchJobInstanceDetailsPager: """A pager for iterating through ``list_patch_job_instance_details`` requests. @@ -140,6 +204,72 @@ def __repr__(self) -> str: return "{0}<{1!r}>".format(self.__class__.__name__, self._response) +class ListPatchJobInstanceDetailsAsyncPager: + """A pager for iterating through ``list_patch_job_instance_details`` requests. + + This class thinly wraps an initial + :class:`~.patch_jobs.ListPatchJobInstanceDetailsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``patch_job_instance_details`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListPatchJobInstanceDetails`` requests and continue to iterate + through the ``patch_job_instance_details`` field on the + corresponding responses. + + All the usual :class:`~.patch_jobs.ListPatchJobInstanceDetailsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[ + [patch_jobs.ListPatchJobInstanceDetailsRequest], + Awaitable[patch_jobs.ListPatchJobInstanceDetailsResponse], + ], + request: patch_jobs.ListPatchJobInstanceDetailsRequest, + response: patch_jobs.ListPatchJobInstanceDetailsResponse, + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (:class:`~.patch_jobs.ListPatchJobInstanceDetailsRequest`): + The initial request object. + response (:class:`~.patch_jobs.ListPatchJobInstanceDetailsResponse`): + The initial response object. + """ + self._method = method + self._request = patch_jobs.ListPatchJobInstanceDetailsRequest(request) + self._response = response + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self + ) -> AsyncIterable[patch_jobs.ListPatchJobInstanceDetailsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request) + yield self._response + + def __aiter__(self) -> AsyncIterable[patch_jobs.PatchJobInstanceDetails]: + async def async_generator(): + async for page in self.pages: + for response in page.patch_job_instance_details: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + class ListPatchDeploymentsPager: """A pager for iterating through ``list_patch_deployments`` requests. @@ -198,3 +328,69 @@ def __iter__(self) -> Iterable[patch_deployments.PatchDeployment]: def __repr__(self) -> str: return "{0}<{1!r}>".format(self.__class__.__name__, self._response) + + +class ListPatchDeploymentsAsyncPager: + """A pager for iterating through ``list_patch_deployments`` requests. + + This class thinly wraps an initial + :class:`~.patch_deployments.ListPatchDeploymentsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``patch_deployments`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListPatchDeployments`` requests and continue to iterate + through the ``patch_deployments`` field on the + corresponding responses. + + All the usual :class:`~.patch_deployments.ListPatchDeploymentsResponse` + attributes are available on the pager. If multiple requests are made, only + the most recent response is retained, and thus used for attribute lookup. + """ + + def __init__( + self, + method: Callable[ + [patch_deployments.ListPatchDeploymentsRequest], + Awaitable[patch_deployments.ListPatchDeploymentsResponse], + ], + request: patch_deployments.ListPatchDeploymentsRequest, + response: patch_deployments.ListPatchDeploymentsResponse, + ): + """Instantiate the pager. + + Args: + method (Callable): The method that was originally called, and + which instantiated this pager. + request (:class:`~.patch_deployments.ListPatchDeploymentsRequest`): + The initial request object. + response (:class:`~.patch_deployments.ListPatchDeploymentsResponse`): + The initial response object. + """ + self._method = method + self._request = patch_deployments.ListPatchDeploymentsRequest(request) + self._response = response + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages( + self + ) -> AsyncIterable[patch_deployments.ListPatchDeploymentsResponse]: + yield self._response + while self._response.next_page_token: + self._request.page_token = self._response.next_page_token + self._response = await self._method(self._request) + yield self._response + + def __aiter__(self) -> AsyncIterable[patch_deployments.PatchDeployment]: + async def async_generator(): + async for page in self.pages: + for response in page.patch_deployments: + yield response + + return async_generator() + + def __repr__(self) -> str: + return "{0}<{1!r}>".format(self.__class__.__name__, self._response) diff --git a/google/cloud/osconfig_v1/services/os_config_service/transports/__init__.py b/google/cloud/osconfig_v1/services/os_config_service/transports/__init__.py index 78893a3..242dbcd 100644 --- a/google/cloud/osconfig_v1/services/os_config_service/transports/__init__.py +++ b/google/cloud/osconfig_v1/services/os_config_service/transports/__init__.py @@ -20,11 +20,17 @@ from .base import OsConfigServiceTransport from .grpc import OsConfigServiceGrpcTransport +from .grpc_asyncio import OsConfigServiceGrpcAsyncIOTransport # Compile a registry of transports. _transport_registry = OrderedDict() # type: Dict[str, Type[OsConfigServiceTransport]] _transport_registry["grpc"] = OsConfigServiceGrpcTransport +_transport_registry["grpc_asyncio"] = OsConfigServiceGrpcAsyncIOTransport -__all__ = ("OsConfigServiceTransport", "OsConfigServiceGrpcTransport") +__all__ = ( + "OsConfigServiceTransport", + "OsConfigServiceGrpcTransport", + "OsConfigServiceGrpcAsyncIOTransport", +) diff --git a/google/cloud/osconfig_v1/services/os_config_service/transports/base.py b/google/cloud/osconfig_v1/services/os_config_service/transports/base.py index c62124e..190f55f 100644 --- a/google/cloud/osconfig_v1/services/os_config_service/transports/base.py +++ b/google/cloud/osconfig_v1/services/os_config_service/transports/base.py @@ -26,7 +26,7 @@ from google.protobuf import empty_pb2 as empty # type: ignore -class OsConfigServiceTransport(metaclass=abc.ABCMeta): +class OsConfigServiceTransport(abc.ABC): """Abstract transport class for OsConfigService.""" AUTH_SCOPES = ("https://www.googleapis.com/auth/cloud-platform",) @@ -36,6 +36,7 @@ def __init__( *, host: str = "osconfig.googleapis.com", credentials: credentials.Credentials = None, + **kwargs, ) -> None: """Instantiate the transport. @@ -63,69 +64,98 @@ def __init__( @property def execute_patch_job( self - ) -> typing.Callable[[patch_jobs.ExecutePatchJobRequest], patch_jobs.PatchJob]: - raise NotImplementedError + ) -> typing.Callable[ + [patch_jobs.ExecutePatchJobRequest], + typing.Union[patch_jobs.PatchJob, typing.Awaitable[patch_jobs.PatchJob]], + ]: + raise NotImplementedError() @property def get_patch_job( self - ) -> typing.Callable[[patch_jobs.GetPatchJobRequest], patch_jobs.PatchJob]: - raise NotImplementedError + ) -> typing.Callable[ + [patch_jobs.GetPatchJobRequest], + typing.Union[patch_jobs.PatchJob, typing.Awaitable[patch_jobs.PatchJob]], + ]: + raise NotImplementedError() @property def cancel_patch_job( self - ) -> typing.Callable[[patch_jobs.CancelPatchJobRequest], patch_jobs.PatchJob]: - raise NotImplementedError + ) -> typing.Callable[ + [patch_jobs.CancelPatchJobRequest], + typing.Union[patch_jobs.PatchJob, typing.Awaitable[patch_jobs.PatchJob]], + ]: + raise NotImplementedError() @property def list_patch_jobs( self ) -> typing.Callable[ - [patch_jobs.ListPatchJobsRequest], patch_jobs.ListPatchJobsResponse + [patch_jobs.ListPatchJobsRequest], + typing.Union[ + patch_jobs.ListPatchJobsResponse, + typing.Awaitable[patch_jobs.ListPatchJobsResponse], + ], ]: - raise NotImplementedError + raise NotImplementedError() @property def list_patch_job_instance_details( self ) -> typing.Callable[ [patch_jobs.ListPatchJobInstanceDetailsRequest], - patch_jobs.ListPatchJobInstanceDetailsResponse, + typing.Union[ + patch_jobs.ListPatchJobInstanceDetailsResponse, + typing.Awaitable[patch_jobs.ListPatchJobInstanceDetailsResponse], + ], ]: - raise NotImplementedError + raise NotImplementedError() @property def create_patch_deployment( self ) -> typing.Callable[ [patch_deployments.CreatePatchDeploymentRequest], - patch_deployments.PatchDeployment, + typing.Union[ + patch_deployments.PatchDeployment, + typing.Awaitable[patch_deployments.PatchDeployment], + ], ]: - raise NotImplementedError + raise NotImplementedError() @property def get_patch_deployment( self ) -> typing.Callable[ - [patch_deployments.GetPatchDeploymentRequest], patch_deployments.PatchDeployment + [patch_deployments.GetPatchDeploymentRequest], + typing.Union[ + patch_deployments.PatchDeployment, + typing.Awaitable[patch_deployments.PatchDeployment], + ], ]: - raise NotImplementedError + raise NotImplementedError() @property def list_patch_deployments( self ) -> typing.Callable[ [patch_deployments.ListPatchDeploymentsRequest], - patch_deployments.ListPatchDeploymentsResponse, + typing.Union[ + patch_deployments.ListPatchDeploymentsResponse, + typing.Awaitable[patch_deployments.ListPatchDeploymentsResponse], + ], ]: - raise NotImplementedError + raise NotImplementedError() @property def delete_patch_deployment( self - ) -> typing.Callable[[patch_deployments.DeletePatchDeploymentRequest], empty.Empty]: - raise NotImplementedError + ) -> typing.Callable[ + [patch_deployments.DeletePatchDeploymentRequest], + typing.Union[empty.Empty, typing.Awaitable[empty.Empty]], + ]: + raise NotImplementedError() __all__ = ("OsConfigServiceTransport",) diff --git a/google/cloud/osconfig_v1/services/os_config_service/transports/grpc.py b/google/cloud/osconfig_v1/services/os_config_service/transports/grpc.py index f2ca285..69f0de6 100644 --- a/google/cloud/osconfig_v1/services/os_config_service/transports/grpc.py +++ b/google/cloud/osconfig_v1/services/os_config_service/transports/grpc.py @@ -15,9 +15,10 @@ # limitations under the License. # -from typing import Callable, Dict, Tuple +from typing import Callable, Dict, Optional, Sequence, Tuple from google.api_core import grpc_helpers # type: ignore +from google import auth # type: ignore from google.auth import credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -47,6 +48,8 @@ class OsConfigServiceGrpcTransport(OsConfigServiceTransport): top of HTTP/2); the ``grpcio`` package must be installed. """ + _stubs: Dict[str, Callable] + def __init__( self, *, @@ -78,8 +81,8 @@ def __init__( is None. Raises: - google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport - creation failed for any reason. + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. """ if channel: # Sanity check: Ensure that channel and credentials are not both @@ -95,6 +98,9 @@ def __init__( else api_mtls_endpoint + ":443" ) + if credentials is None: + credentials, _ = auth.default(scopes=self.AUTH_SCOPES) + # Create SSL credentials with client_cert_source or application # default SSL credentials. if client_cert_source: @@ -106,7 +112,7 @@ def __init__( ssl_credentials = SslCredentials().ssl_credentials # create a new channel. The provided one is ignored. - self._grpc_channel = grpc_helpers.create_channel( + self._grpc_channel = type(self).create_channel( host, credentials=credentials, ssl_credentials=ssl_credentials, @@ -122,6 +128,7 @@ def create_channel( cls, host: str = "osconfig.googleapis.com", credentials: credentials.Credentials = None, + scopes: Optional[Sequence[str]] = None, **kwargs ) -> grpc.Channel: """Create and return a gRPC channel object. @@ -132,13 +139,17 @@ def create_channel( credentials identify this application to the service. If none are specified, the client will attempt to ascertain the credentials from the environment. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. kwargs (Optional[dict]): Keyword arguments, which are passed to the channel creation. Returns: grpc.Channel: A gRPC channel object. """ + scopes = scopes or cls.AUTH_SCOPES return grpc_helpers.create_channel( - host, credentials=credentials, scopes=cls.AUTH_SCOPES, **kwargs + host, credentials=credentials, scopes=scopes, **kwargs ) @property diff --git a/google/cloud/osconfig_v1/services/os_config_service/transports/grpc_asyncio.py b/google/cloud/osconfig_v1/services/os_config_service/transports/grpc_asyncio.py new file mode 100644 index 0000000..c2601c9 --- /dev/null +++ b/google/cloud/osconfig_v1/services/os_config_service/transports/grpc_asyncio.py @@ -0,0 +1,428 @@ +# -*- coding: utf-8 -*- + +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# 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. +# + +from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple + +from google.api_core import grpc_helpers_async # type: ignore +from google.auth import credentials # type: ignore +from google.auth.transport.grpc import SslCredentials # type: ignore + +import grpc # type: ignore +from grpc.experimental import aio # type: ignore + +from google.cloud.osconfig_v1.types import patch_deployments +from google.cloud.osconfig_v1.types import patch_jobs +from google.protobuf import empty_pb2 as empty # type: ignore + +from .base import OsConfigServiceTransport +from .grpc import OsConfigServiceGrpcTransport + + +class OsConfigServiceGrpcAsyncIOTransport(OsConfigServiceTransport): + """gRPC AsyncIO backend transport for OsConfigService. + + OS Config API + The OS Config service is a server-side component that you can + use to manage package installations and patch jobs for virtual + machine instances. + + This class defines the same methods as the primary client, so the + primary client can load the underlying transport implementation + and call it. + + It sends protocol buffers over the wire using gRPC (which is built on + top of HTTP/2); the ``grpcio`` package must be installed. + """ + + _grpc_channel: aio.Channel + _stubs: Dict[str, Callable] = {} + + @classmethod + def create_channel( + cls, + host: str = "osconfig.googleapis.com", + credentials: credentials.Credentials = None, + scopes: Optional[Sequence[str]] = None, + **kwargs + ) -> aio.Channel: + """Create and return a gRPC AsyncIO channel object. + Args: + address (Optional[str]): The host for the channel to use. + credentials (Optional[~.Credentials]): The + authorization credentials to attach to requests. These + credentials identify this application to the service. If + none are specified, the client will attempt to ascertain + the credentials from the environment. + scopes (Optional[Sequence[str]]): A optional list of scopes needed for this + service. These are only used when credentials are not specified and + are passed to :func:`google.auth.default`. + kwargs (Optional[dict]): Keyword arguments, which are passed to the + channel creation. + Returns: + aio.Channel: A gRPC AsyncIO channel object. + """ + scopes = scopes or cls.AUTH_SCOPES + return grpc_helpers_async.create_channel( + host, credentials=credentials, scopes=scopes, **kwargs + ) + + def __init__( + self, + *, + host: str = "osconfig.googleapis.com", + credentials: credentials.Credentials = None, + channel: aio.Channel = None, + api_mtls_endpoint: str = None, + client_cert_source: Callable[[], Tuple[bytes, bytes]] = None + ) -> None: + """Instantiate the transport. + + Args: + host (Optional[str]): The hostname to connect to. + credentials (Optional[google.auth.credentials.Credentials]): The + authorization credentials to attach to requests. These + credentials identify the application to the service; if none + are specified, the client will attempt to ascertain the + credentials from the environment. + This argument is ignored if ``channel`` is provided. + channel (Optional[aio.Channel]): A ``Channel`` instance through + which to make calls. + api_mtls_endpoint (Optional[str]): The mutual TLS endpoint. If + provided, it overrides the ``host`` argument and tries to create + a mutual TLS channel with client SSL credentials from + ``client_cert_source`` or applicatin default SSL credentials. + client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A + callback to provide client SSL certificate bytes and private key + bytes, both in PEM format. It is ignored if ``api_mtls_endpoint`` + is None. + + Raises: + google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport + creation failed for any reason. + """ + if channel: + # Sanity check: Ensure that channel and credentials are not both + # provided. + credentials = False + + # If a channel was explicitly provided, set it. + self._grpc_channel = channel + elif api_mtls_endpoint: + host = ( + api_mtls_endpoint + if ":" in api_mtls_endpoint + else api_mtls_endpoint + ":443" + ) + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + ssl_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + ssl_credentials = SslCredentials().ssl_credentials + + # create a new channel. The provided one is ignored. + self._grpc_channel = type(self).create_channel( + host, + credentials=credentials, + ssl_credentials=ssl_credentials, + scopes=self.AUTH_SCOPES, + ) + + # Run the base constructor. + super().__init__(host=host, credentials=credentials) + self._stubs = {} + + @property + def grpc_channel(self) -> aio.Channel: + """Create the channel designed to connect to this service. + + This property caches on the instance; repeated calls return + the same channel. + """ + # Sanity check: Only create a new channel if we do not already + # have one. + if not hasattr(self, "_grpc_channel"): + self._grpc_channel = self.create_channel( + self._host, credentials=self._credentials + ) + + # Return the channel from cache. + return self._grpc_channel + + @property + def execute_patch_job( + self + ) -> Callable[[patch_jobs.ExecutePatchJobRequest], Awaitable[patch_jobs.PatchJob]]: + r"""Return a callable for the execute patch job method over gRPC. + + Patch VM instances by creating and running a patch + job. + + Returns: + Callable[[~.ExecutePatchJobRequest], + Awaitable[~.PatchJob]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "execute_patch_job" not in self._stubs: + self._stubs["execute_patch_job"] = self.grpc_channel.unary_unary( + "/google.cloud.osconfig.v1.OsConfigService/ExecutePatchJob", + request_serializer=patch_jobs.ExecutePatchJobRequest.serialize, + response_deserializer=patch_jobs.PatchJob.deserialize, + ) + return self._stubs["execute_patch_job"] + + @property + def get_patch_job( + self + ) -> Callable[[patch_jobs.GetPatchJobRequest], Awaitable[patch_jobs.PatchJob]]: + r"""Return a callable for the get patch job method over gRPC. + + Get the patch job. This can be used to track the + progress of an ongoing patch job or review the details + of completed jobs. + + Returns: + Callable[[~.GetPatchJobRequest], + Awaitable[~.PatchJob]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_patch_job" not in self._stubs: + self._stubs["get_patch_job"] = self.grpc_channel.unary_unary( + "/google.cloud.osconfig.v1.OsConfigService/GetPatchJob", + request_serializer=patch_jobs.GetPatchJobRequest.serialize, + response_deserializer=patch_jobs.PatchJob.deserialize, + ) + return self._stubs["get_patch_job"] + + @property + def cancel_patch_job( + self + ) -> Callable[[patch_jobs.CancelPatchJobRequest], Awaitable[patch_jobs.PatchJob]]: + r"""Return a callable for the cancel patch job method over gRPC. + + Cancel a patch job. The patch job must be active. + Canceled patch jobs cannot be restarted. + + Returns: + Callable[[~.CancelPatchJobRequest], + Awaitable[~.PatchJob]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "cancel_patch_job" not in self._stubs: + self._stubs["cancel_patch_job"] = self.grpc_channel.unary_unary( + "/google.cloud.osconfig.v1.OsConfigService/CancelPatchJob", + request_serializer=patch_jobs.CancelPatchJobRequest.serialize, + response_deserializer=patch_jobs.PatchJob.deserialize, + ) + return self._stubs["cancel_patch_job"] + + @property + def list_patch_jobs( + self + ) -> Callable[ + [patch_jobs.ListPatchJobsRequest], Awaitable[patch_jobs.ListPatchJobsResponse] + ]: + r"""Return a callable for the list patch jobs method over gRPC. + + Get a list of patch jobs. + + Returns: + Callable[[~.ListPatchJobsRequest], + Awaitable[~.ListPatchJobsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_patch_jobs" not in self._stubs: + self._stubs["list_patch_jobs"] = self.grpc_channel.unary_unary( + "/google.cloud.osconfig.v1.OsConfigService/ListPatchJobs", + request_serializer=patch_jobs.ListPatchJobsRequest.serialize, + response_deserializer=patch_jobs.ListPatchJobsResponse.deserialize, + ) + return self._stubs["list_patch_jobs"] + + @property + def list_patch_job_instance_details( + self + ) -> Callable[ + [patch_jobs.ListPatchJobInstanceDetailsRequest], + Awaitable[patch_jobs.ListPatchJobInstanceDetailsResponse], + ]: + r"""Return a callable for the list patch job instance + details method over gRPC. + + Get a list of instance details for a given patch job. + + Returns: + Callable[[~.ListPatchJobInstanceDetailsRequest], + Awaitable[~.ListPatchJobInstanceDetailsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_patch_job_instance_details" not in self._stubs: + self._stubs[ + "list_patch_job_instance_details" + ] = self.grpc_channel.unary_unary( + "/google.cloud.osconfig.v1.OsConfigService/ListPatchJobInstanceDetails", + request_serializer=patch_jobs.ListPatchJobInstanceDetailsRequest.serialize, + response_deserializer=patch_jobs.ListPatchJobInstanceDetailsResponse.deserialize, + ) + return self._stubs["list_patch_job_instance_details"] + + @property + def create_patch_deployment( + self + ) -> Callable[ + [patch_deployments.CreatePatchDeploymentRequest], + Awaitable[patch_deployments.PatchDeployment], + ]: + r"""Return a callable for the create patch deployment method over gRPC. + + Create an OS Config patch deployment. + + Returns: + Callable[[~.CreatePatchDeploymentRequest], + Awaitable[~.PatchDeployment]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_patch_deployment" not in self._stubs: + self._stubs["create_patch_deployment"] = self.grpc_channel.unary_unary( + "/google.cloud.osconfig.v1.OsConfigService/CreatePatchDeployment", + request_serializer=patch_deployments.CreatePatchDeploymentRequest.serialize, + response_deserializer=patch_deployments.PatchDeployment.deserialize, + ) + return self._stubs["create_patch_deployment"] + + @property + def get_patch_deployment( + self + ) -> Callable[ + [patch_deployments.GetPatchDeploymentRequest], + Awaitable[patch_deployments.PatchDeployment], + ]: + r"""Return a callable for the get patch deployment method over gRPC. + + Get an OS Config patch deployment. + + Returns: + Callable[[~.GetPatchDeploymentRequest], + Awaitable[~.PatchDeployment]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_patch_deployment" not in self._stubs: + self._stubs["get_patch_deployment"] = self.grpc_channel.unary_unary( + "/google.cloud.osconfig.v1.OsConfigService/GetPatchDeployment", + request_serializer=patch_deployments.GetPatchDeploymentRequest.serialize, + response_deserializer=patch_deployments.PatchDeployment.deserialize, + ) + return self._stubs["get_patch_deployment"] + + @property + def list_patch_deployments( + self + ) -> Callable[ + [patch_deployments.ListPatchDeploymentsRequest], + Awaitable[patch_deployments.ListPatchDeploymentsResponse], + ]: + r"""Return a callable for the list patch deployments method over gRPC. + + Get a page of OS Config patch deployments. + + Returns: + Callable[[~.ListPatchDeploymentsRequest], + Awaitable[~.ListPatchDeploymentsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_patch_deployments" not in self._stubs: + self._stubs["list_patch_deployments"] = self.grpc_channel.unary_unary( + "/google.cloud.osconfig.v1.OsConfigService/ListPatchDeployments", + request_serializer=patch_deployments.ListPatchDeploymentsRequest.serialize, + response_deserializer=patch_deployments.ListPatchDeploymentsResponse.deserialize, + ) + return self._stubs["list_patch_deployments"] + + @property + def delete_patch_deployment( + self + ) -> Callable[ + [patch_deployments.DeletePatchDeploymentRequest], Awaitable[empty.Empty] + ]: + r"""Return a callable for the delete patch deployment method over gRPC. + + Delete an OS Config patch deployment. + + Returns: + Callable[[~.DeletePatchDeploymentRequest], + Awaitable[~.Empty]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_patch_deployment" not in self._stubs: + self._stubs["delete_patch_deployment"] = self.grpc_channel.unary_unary( + "/google.cloud.osconfig.v1.OsConfigService/DeletePatchDeployment", + request_serializer=patch_deployments.DeletePatchDeploymentRequest.serialize, + response_deserializer=empty.Empty.FromString, + ) + return self._stubs["delete_patch_deployment"] + + +__all__ = ("OsConfigServiceGrpcAsyncIOTransport",) diff --git a/noxfile.py b/noxfile.py index c552bbb..a7fa38f 100644 --- a/noxfile.py +++ b/noxfile.py @@ -66,6 +66,7 @@ def lint_setup_py(session): def default(session): # Install all test dependencies, then install this package in-place. + session.install("asyncmock", "pytest-asyncio") session.install("mock", "pytest", "pytest-cov") session.install("-e", ".") diff --git a/setup.py b/setup.py index 2f3af28..379f5bb 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ # 'Development Status :: 5 - Production/Stable' release_status = "Development Status :: 4 - Beta" dependencies = [ - "google-api-core[grpc] >= 1.17.0, < 2.0.0dev", + "google-api-core[grpc] >= 1.17.2, < 2.0.0dev", "proto-plus >= 0.4.0", "libcst >= 0.2.5", ] diff --git a/synth.metadata b/synth.metadata index c0c507a..020d69a 100644 --- a/synth.metadata +++ b/synth.metadata @@ -3,8 +3,8 @@ { "git": { "name": ".", - "remote": "sso://devrel/cloud/libraries/python/python-os-config", - "sha": "143b9270390ff38775e2fbcd2288e8bfe4a82797" + "remote": "https://github.com/googleapis/python-os-config.git", + "sha": "b43ea51c28470874fdf5da026970202009d48651" } }, { @@ -19,14 +19,14 @@ "git": { "name": "synthtool", "remote": "https://github.com/googleapis/synthtool.git", - "sha": "88645a8f6e1b1c90fed625158960ffec565b023a" + "sha": "cd522c3b4dde821766d95c80ae5aeb43d7a41170" } }, { "git": { "name": "synthtool", "remote": "https://github.com/googleapis/synthtool.git", - "sha": "88645a8f6e1b1c90fed625158960ffec565b023a" + "sha": "cd522c3b4dde821766d95c80ae5aeb43d7a41170" } } ], diff --git a/synth.py b/synth.py index 43dad4d..d850f7a 100644 --- a/synth.py +++ b/synth.py @@ -39,7 +39,7 @@ s.replace(["google/**/*.py", "tests/**/*.py"], "google-cloud-osconfig", "google-cloud-os-config") # Add newline after last item in list -s.replace("google/cloud/**/client.py", +s.replace("google/cloud/**/*_client.py", "(- Must be unique within the project\.)", "\g<1>\n") @@ -55,8 +55,8 @@ # Add templated files # ---------------------------------------------------------------------------- templated_files = common.py_library( - cov_level=100, samples=False, + microgenerator=True, unit_test_python_versions=["3.6", "3.7", "3.8"], system_test_python_versions=["3.7"], ) @@ -65,8 +65,4 @@ ) # the microgenerator has a good coveragerc file -# Extra lint ignores for microgenerator tests -# TODO: Remove when https://github.com/googleapis/gapic-generator-python/issues/425 is closed -s.replace(".flake8", "(ignore = .*)", "\g<1>, F401, F841") - s.shell.run(["nox", "-s", "blacken"], hide_output=False) \ No newline at end of file diff --git a/tests/unit/gapic/osconfig_v1/test_os_config_service.py b/tests/unit/gapic/osconfig_v1/test_os_config_service.py new file mode 100644 index 0000000..823f1ab --- /dev/null +++ b/tests/unit/gapic/osconfig_v1/test_os_config_service.py @@ -0,0 +1,2635 @@ +# -*- coding: utf-8 -*- + +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# 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. +# + +import os +import mock + +import grpc +from grpc.experimental import aio +import math +import pytest + +from google import auth +from google.api_core import client_options +from google.api_core import grpc_helpers +from google.api_core import grpc_helpers_async +from google.auth import credentials +from google.auth.exceptions import MutualTLSChannelError +from google.cloud.osconfig_v1.services.os_config_service import ( + OsConfigServiceAsyncClient, +) +from google.cloud.osconfig_v1.services.os_config_service import OsConfigServiceClient +from google.cloud.osconfig_v1.services.os_config_service import pagers +from google.cloud.osconfig_v1.services.os_config_service import transports +from google.cloud.osconfig_v1.types import patch_deployments +from google.cloud.osconfig_v1.types import patch_jobs +from google.cloud.osconfig_v1.types import patch_jobs as gco_patch_jobs +from google.oauth2 import service_account +from google.protobuf import duration_pb2 as duration # type: ignore +from google.protobuf import timestamp_pb2 as timestamp # type: ignore +from google.type import datetime_pb2 as datetime # type: ignore +from google.type import dayofweek_pb2 as dayofweek # type: ignore +from google.type import timeofday_pb2 as timeofday # type: ignore + + +def client_cert_source_callback(): + return b"cert bytes", b"key bytes" + + +def test__get_default_mtls_endpoint(): + api_endpoint = "example.googleapis.com" + api_mtls_endpoint = "example.mtls.googleapis.com" + sandbox_endpoint = "example.sandbox.googleapis.com" + sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" + non_googleapi = "api.example.com" + + assert OsConfigServiceClient._get_default_mtls_endpoint(None) is None + assert ( + OsConfigServiceClient._get_default_mtls_endpoint(api_endpoint) + == api_mtls_endpoint + ) + assert ( + OsConfigServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) + == api_mtls_endpoint + ) + assert ( + OsConfigServiceClient._get_default_mtls_endpoint(sandbox_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + OsConfigServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) + == sandbox_mtls_endpoint + ) + assert ( + OsConfigServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + ) + + +@pytest.mark.parametrize( + "client_class", [OsConfigServiceClient, OsConfigServiceAsyncClient] +) +def test_os_config_service_client_from_service_account_file(client_class): + creds = credentials.AnonymousCredentials() + with mock.patch.object( + service_account.Credentials, "from_service_account_file" + ) as factory: + factory.return_value = creds + client = client_class.from_service_account_file("dummy/file/path.json") + assert client._transport._credentials == creds + + client = client_class.from_service_account_json("dummy/file/path.json") + assert client._transport._credentials == creds + + assert client._transport._host == "osconfig.googleapis.com:443" + + +def test_os_config_service_client_get_transport_class(): + transport = OsConfigServiceClient.get_transport_class() + assert transport == transports.OsConfigServiceGrpcTransport + + transport = OsConfigServiceClient.get_transport_class("grpc") + assert transport == transports.OsConfigServiceGrpcTransport + + +@pytest.mark.parametrize( + "client_class,transport_class,transport_name", + [ + (OsConfigServiceClient, transports.OsConfigServiceGrpcTransport, "grpc"), + ( + OsConfigServiceAsyncClient, + transports.OsConfigServiceGrpcAsyncIOTransport, + "grpc_asyncio", + ), + ], +) +def test_os_config_service_client_client_options( + client_class, transport_class, transport_name +): + # Check that if channel is provided we won't create a new one. + with mock.patch.object(OsConfigServiceClient, "get_transport_class") as gtc: + transport = transport_class(credentials=credentials.AnonymousCredentials()) + client = client_class(transport=transport) + gtc.assert_not_called() + + # Check that if channel is provided via str we will create a new one. + with mock.patch.object(OsConfigServiceClient, "get_transport_class") as gtc: + client = client_class(transport=transport_name) + gtc.assert_called() + + # Check the case api_endpoint is provided. + options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + api_mtls_endpoint="squid.clam.whelk", + client_cert_source=None, + credentials=None, + host="squid.clam.whelk", + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is + # "never". + os.environ["GOOGLE_API_USE_MTLS"] = "never" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, + credentials=None, + host=client.DEFAULT_ENDPOINT, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS is + # "always". + os.environ["GOOGLE_API_USE_MTLS"] = "always" + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, + client_cert_source=None, + credentials=None, + host=client.DEFAULT_MTLS_ENDPOINT, + ) + + # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is + # "auto", and client_cert_source is provided. + os.environ["GOOGLE_API_USE_MTLS"] = "auto" + options = client_options.ClientOptions( + client_cert_source=client_cert_source_callback + ) + with mock.patch.object(transport_class, "__init__") as patched: + patched.return_value = None + client = client_class(client_options=options) + patched.assert_called_once_with( + api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, + client_cert_source=client_cert_source_callback, + credentials=None, + host=client.DEFAULT_MTLS_ENDPOINT, + ) + + # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is + # "auto", and default_client_cert_source is provided. + os.environ["GOOGLE_API_USE_MTLS"] = "auto" + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=True, + ): + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, + client_cert_source=None, + credentials=None, + host=client.DEFAULT_MTLS_ENDPOINT, + ) + + # Check the case api_endpoint is not provided, GOOGLE_API_USE_MTLS is + # "auto", but client_cert_source and default_client_cert_source are None. + os.environ["GOOGLE_API_USE_MTLS"] = "auto" + with mock.patch.object(transport_class, "__init__") as patched: + with mock.patch( + "google.auth.transport.mtls.has_default_client_cert_source", + return_value=False, + ): + patched.return_value = None + client = client_class() + patched.assert_called_once_with( + api_mtls_endpoint=client.DEFAULT_ENDPOINT, + client_cert_source=None, + credentials=None, + host=client.DEFAULT_ENDPOINT, + ) + + # Check the case api_endpoint is not provided and GOOGLE_API_USE_MTLS has + # unsupported value. + os.environ["GOOGLE_API_USE_MTLS"] = "Unsupported" + with pytest.raises(MutualTLSChannelError): + client = client_class() + + del os.environ["GOOGLE_API_USE_MTLS"] + + +def test_os_config_service_client_client_options_from_dict(): + with mock.patch( + "google.cloud.osconfig_v1.services.os_config_service.transports.OsConfigServiceGrpcTransport.__init__" + ) as grpc_transport: + grpc_transport.return_value = None + client = OsConfigServiceClient( + client_options={"api_endpoint": "squid.clam.whelk"} + ) + grpc_transport.assert_called_once_with( + api_mtls_endpoint="squid.clam.whelk", + client_cert_source=None, + credentials=None, + host="squid.clam.whelk", + ) + + +def test_execute_patch_job(transport: str = "grpc"): + client = OsConfigServiceClient( + credentials=credentials.AnonymousCredentials(), transport=transport + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = patch_jobs.ExecutePatchJobRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._transport.execute_patch_job), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = patch_jobs.PatchJob( + name="name_value", + display_name="display_name_value", + description="description_value", + state=patch_jobs.PatchJob.State.STARTED, + dry_run=True, + error_message="error_message_value", + percent_complete=0.1705, + patch_deployment="patch_deployment_value", + ) + + response = client.execute_patch_job(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, patch_jobs.PatchJob) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.state == patch_jobs.PatchJob.State.STARTED + + assert response.dry_run is True + assert response.error_message == "error_message_value" + assert math.isclose(response.percent_complete, 0.1705, rel_tol=1e-6) + assert response.patch_deployment == "patch_deployment_value" + + +@pytest.mark.asyncio +async def test_execute_patch_job_async(transport: str = "grpc_asyncio"): + client = OsConfigServiceAsyncClient( + credentials=credentials.AnonymousCredentials(), transport=transport + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = patch_jobs.ExecutePatchJobRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.execute_patch_job), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + patch_jobs.PatchJob( + name="name_value", + display_name="display_name_value", + description="description_value", + state=patch_jobs.PatchJob.State.STARTED, + dry_run=True, + error_message="error_message_value", + percent_complete=0.1705, + patch_deployment="patch_deployment_value", + ) + ) + + response = await client.execute_patch_job(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, patch_jobs.PatchJob) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.state == patch_jobs.PatchJob.State.STARTED + + assert response.dry_run is True + assert response.error_message == "error_message_value" + assert math.isclose(response.percent_complete, 0.1705, rel_tol=1e-6) + assert response.patch_deployment == "patch_deployment_value" + + +def test_execute_patch_job_field_headers(): + client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = patch_jobs.ExecutePatchJobRequest() + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._transport.execute_patch_job), "__call__" + ) as call: + call.return_value = patch_jobs.PatchJob() + + client.execute_patch_job(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "parent=parent/value") in kw["metadata"] + + +@pytest.mark.asyncio +async def test_execute_patch_job_field_headers_async(): + client = OsConfigServiceAsyncClient(credentials=credentials.AnonymousCredentials()) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = patch_jobs.ExecutePatchJobRequest() + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.execute_patch_job), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(patch_jobs.PatchJob()) + + await client.execute_patch_job(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "parent=parent/value") in kw["metadata"] + + +def test_get_patch_job(transport: str = "grpc"): + client = OsConfigServiceClient( + credentials=credentials.AnonymousCredentials(), transport=transport + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = patch_jobs.GetPatchJobRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client._transport.get_patch_job), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = patch_jobs.PatchJob( + name="name_value", + display_name="display_name_value", + description="description_value", + state=patch_jobs.PatchJob.State.STARTED, + dry_run=True, + error_message="error_message_value", + percent_complete=0.1705, + patch_deployment="patch_deployment_value", + ) + + response = client.get_patch_job(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, patch_jobs.PatchJob) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.state == patch_jobs.PatchJob.State.STARTED + + assert response.dry_run is True + assert response.error_message == "error_message_value" + assert math.isclose(response.percent_complete, 0.1705, rel_tol=1e-6) + assert response.patch_deployment == "patch_deployment_value" + + +@pytest.mark.asyncio +async def test_get_patch_job_async(transport: str = "grpc_asyncio"): + client = OsConfigServiceAsyncClient( + credentials=credentials.AnonymousCredentials(), transport=transport + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = patch_jobs.GetPatchJobRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.get_patch_job), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + patch_jobs.PatchJob( + name="name_value", + display_name="display_name_value", + description="description_value", + state=patch_jobs.PatchJob.State.STARTED, + dry_run=True, + error_message="error_message_value", + percent_complete=0.1705, + patch_deployment="patch_deployment_value", + ) + ) + + response = await client.get_patch_job(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, patch_jobs.PatchJob) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.state == patch_jobs.PatchJob.State.STARTED + + assert response.dry_run is True + assert response.error_message == "error_message_value" + assert math.isclose(response.percent_complete, 0.1705, rel_tol=1e-6) + assert response.patch_deployment == "patch_deployment_value" + + +def test_get_patch_job_field_headers(): + client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = patch_jobs.GetPatchJobRequest() + request.name = "name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client._transport.get_patch_job), "__call__") as call: + call.return_value = patch_jobs.PatchJob() + + client.get_patch_job(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "name=name/value") in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_patch_job_field_headers_async(): + client = OsConfigServiceAsyncClient(credentials=credentials.AnonymousCredentials()) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = patch_jobs.GetPatchJobRequest() + request.name = "name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.get_patch_job), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(patch_jobs.PatchJob()) + + await client.get_patch_job(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "name=name/value") in kw["metadata"] + + +def test_get_patch_job_flattened(): + client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client._transport.get_patch_job), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = patch_jobs.PatchJob() + + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_patch_job(name="name_value") + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0].name == "name_value" + + +def test_get_patch_job_flattened_error(): + client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_patch_job(patch_jobs.GetPatchJobRequest(), name="name_value") + + +@pytest.mark.asyncio +async def test_get_patch_job_flattened_async(): + client = OsConfigServiceAsyncClient(credentials=credentials.AnonymousCredentials()) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.get_patch_job), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = patch_jobs.PatchJob() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(patch_jobs.PatchJob()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_patch_job(name="name_value") + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0].name == "name_value" + + +@pytest.mark.asyncio +async def test_get_patch_job_flattened_error_async(): + client = OsConfigServiceAsyncClient(credentials=credentials.AnonymousCredentials()) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_patch_job(patch_jobs.GetPatchJobRequest(), name="name_value") + + +def test_cancel_patch_job(transport: str = "grpc"): + client = OsConfigServiceClient( + credentials=credentials.AnonymousCredentials(), transport=transport + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = patch_jobs.CancelPatchJobRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._transport.cancel_patch_job), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = patch_jobs.PatchJob( + name="name_value", + display_name="display_name_value", + description="description_value", + state=patch_jobs.PatchJob.State.STARTED, + dry_run=True, + error_message="error_message_value", + percent_complete=0.1705, + patch_deployment="patch_deployment_value", + ) + + response = client.cancel_patch_job(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, patch_jobs.PatchJob) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.state == patch_jobs.PatchJob.State.STARTED + + assert response.dry_run is True + assert response.error_message == "error_message_value" + assert math.isclose(response.percent_complete, 0.1705, rel_tol=1e-6) + assert response.patch_deployment == "patch_deployment_value" + + +@pytest.mark.asyncio +async def test_cancel_patch_job_async(transport: str = "grpc_asyncio"): + client = OsConfigServiceAsyncClient( + credentials=credentials.AnonymousCredentials(), transport=transport + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = patch_jobs.CancelPatchJobRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.cancel_patch_job), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + patch_jobs.PatchJob( + name="name_value", + display_name="display_name_value", + description="description_value", + state=patch_jobs.PatchJob.State.STARTED, + dry_run=True, + error_message="error_message_value", + percent_complete=0.1705, + patch_deployment="patch_deployment_value", + ) + ) + + response = await client.cancel_patch_job(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, patch_jobs.PatchJob) + assert response.name == "name_value" + assert response.display_name == "display_name_value" + assert response.description == "description_value" + assert response.state == patch_jobs.PatchJob.State.STARTED + + assert response.dry_run is True + assert response.error_message == "error_message_value" + assert math.isclose(response.percent_complete, 0.1705, rel_tol=1e-6) + assert response.patch_deployment == "patch_deployment_value" + + +def test_cancel_patch_job_field_headers(): + client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = patch_jobs.CancelPatchJobRequest() + request.name = "name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._transport.cancel_patch_job), "__call__" + ) as call: + call.return_value = patch_jobs.PatchJob() + + client.cancel_patch_job(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "name=name/value") in kw["metadata"] + + +@pytest.mark.asyncio +async def test_cancel_patch_job_field_headers_async(): + client = OsConfigServiceAsyncClient(credentials=credentials.AnonymousCredentials()) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = patch_jobs.CancelPatchJobRequest() + request.name = "name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.cancel_patch_job), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(patch_jobs.PatchJob()) + + await client.cancel_patch_job(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "name=name/value") in kw["metadata"] + + +def test_list_patch_jobs(transport: str = "grpc"): + client = OsConfigServiceClient( + credentials=credentials.AnonymousCredentials(), transport=transport + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = patch_jobs.ListPatchJobsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client._transport.list_patch_jobs), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = patch_jobs.ListPatchJobsResponse( + next_page_token="next_page_token_value" + ) + + response = client.list_patch_jobs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListPatchJobsPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.asyncio +async def test_list_patch_jobs_async(transport: str = "grpc_asyncio"): + client = OsConfigServiceAsyncClient( + credentials=credentials.AnonymousCredentials(), transport=transport + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = patch_jobs.ListPatchJobsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.list_patch_jobs), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + patch_jobs.ListPatchJobsResponse(next_page_token="next_page_token_value") + ) + + response = await client.list_patch_jobs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListPatchJobsAsyncPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_patch_jobs_field_headers(): + client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = patch_jobs.ListPatchJobsRequest() + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client._transport.list_patch_jobs), "__call__") as call: + call.return_value = patch_jobs.ListPatchJobsResponse() + + client.list_patch_jobs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "parent=parent/value") in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_patch_jobs_field_headers_async(): + client = OsConfigServiceAsyncClient(credentials=credentials.AnonymousCredentials()) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = patch_jobs.ListPatchJobsRequest() + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.list_patch_jobs), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + patch_jobs.ListPatchJobsResponse() + ) + + await client.list_patch_jobs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "parent=parent/value") in kw["metadata"] + + +def test_list_patch_jobs_flattened(): + client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client._transport.list_patch_jobs), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = patch_jobs.ListPatchJobsResponse() + + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_patch_jobs(parent="parent_value") + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0].parent == "parent_value" + + +def test_list_patch_jobs_flattened_error(): + client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_patch_jobs(patch_jobs.ListPatchJobsRequest(), parent="parent_value") + + +@pytest.mark.asyncio +async def test_list_patch_jobs_flattened_async(): + client = OsConfigServiceAsyncClient(credentials=credentials.AnonymousCredentials()) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.list_patch_jobs), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = patch_jobs.ListPatchJobsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + patch_jobs.ListPatchJobsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_patch_jobs(parent="parent_value") + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0].parent == "parent_value" + + +@pytest.mark.asyncio +async def test_list_patch_jobs_flattened_error_async(): + client = OsConfigServiceAsyncClient(credentials=credentials.AnonymousCredentials()) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_patch_jobs( + patch_jobs.ListPatchJobsRequest(), parent="parent_value" + ) + + +def test_list_patch_jobs_pager(): + client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client._transport.list_patch_jobs), "__call__") as call: + # Set the response to a series of pages. + call.side_effect = ( + patch_jobs.ListPatchJobsResponse( + patch_jobs=[ + patch_jobs.PatchJob(), + patch_jobs.PatchJob(), + patch_jobs.PatchJob(), + ], + next_page_token="abc", + ), + patch_jobs.ListPatchJobsResponse(patch_jobs=[], next_page_token="def"), + patch_jobs.ListPatchJobsResponse( + patch_jobs=[patch_jobs.PatchJob()], next_page_token="ghi" + ), + patch_jobs.ListPatchJobsResponse( + patch_jobs=[patch_jobs.PatchJob(), patch_jobs.PatchJob()] + ), + RuntimeError, + ) + results = [i for i in client.list_patch_jobs(request={})] + assert len(results) == 6 + assert all(isinstance(i, patch_jobs.PatchJob) for i in results) + + +def test_list_patch_jobs_pages(): + client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client._transport.list_patch_jobs), "__call__") as call: + # Set the response to a series of pages. + call.side_effect = ( + patch_jobs.ListPatchJobsResponse( + patch_jobs=[ + patch_jobs.PatchJob(), + patch_jobs.PatchJob(), + patch_jobs.PatchJob(), + ], + next_page_token="abc", + ), + patch_jobs.ListPatchJobsResponse(patch_jobs=[], next_page_token="def"), + patch_jobs.ListPatchJobsResponse( + patch_jobs=[patch_jobs.PatchJob()], next_page_token="ghi" + ), + patch_jobs.ListPatchJobsResponse( + patch_jobs=[patch_jobs.PatchJob(), patch_jobs.PatchJob()] + ), + RuntimeError, + ) + pages = list(client.list_patch_jobs(request={}).pages) + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token + + +@pytest.mark.asyncio +async def test_list_patch_jobs_async_pager(): + client = OsConfigServiceAsyncClient(credentials=credentials.AnonymousCredentials) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.list_patch_jobs), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + patch_jobs.ListPatchJobsResponse( + patch_jobs=[ + patch_jobs.PatchJob(), + patch_jobs.PatchJob(), + patch_jobs.PatchJob(), + ], + next_page_token="abc", + ), + patch_jobs.ListPatchJobsResponse(patch_jobs=[], next_page_token="def"), + patch_jobs.ListPatchJobsResponse( + patch_jobs=[patch_jobs.PatchJob()], next_page_token="ghi" + ), + patch_jobs.ListPatchJobsResponse( + patch_jobs=[patch_jobs.PatchJob(), patch_jobs.PatchJob()] + ), + RuntimeError, + ) + async_pager = await client.list_patch_jobs(request={}) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, patch_jobs.PatchJob) for i in responses) + + +@pytest.mark.asyncio +async def test_list_patch_jobs_async_pages(): + client = OsConfigServiceAsyncClient(credentials=credentials.AnonymousCredentials) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.list_patch_jobs), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + patch_jobs.ListPatchJobsResponse( + patch_jobs=[ + patch_jobs.PatchJob(), + patch_jobs.PatchJob(), + patch_jobs.PatchJob(), + ], + next_page_token="abc", + ), + patch_jobs.ListPatchJobsResponse(patch_jobs=[], next_page_token="def"), + patch_jobs.ListPatchJobsResponse( + patch_jobs=[patch_jobs.PatchJob()], next_page_token="ghi" + ), + patch_jobs.ListPatchJobsResponse( + patch_jobs=[patch_jobs.PatchJob(), patch_jobs.PatchJob()] + ), + RuntimeError, + ) + pages = [] + async for page in (await client.list_patch_jobs(request={})).pages: + pages.append(page) + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token + + +def test_list_patch_job_instance_details(transport: str = "grpc"): + client = OsConfigServiceClient( + credentials=credentials.AnonymousCredentials(), transport=transport + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = patch_jobs.ListPatchJobInstanceDetailsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._transport.list_patch_job_instance_details), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = patch_jobs.ListPatchJobInstanceDetailsResponse( + next_page_token="next_page_token_value" + ) + + response = client.list_patch_job_instance_details(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListPatchJobInstanceDetailsPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.asyncio +async def test_list_patch_job_instance_details_async(transport: str = "grpc_asyncio"): + client = OsConfigServiceAsyncClient( + credentials=credentials.AnonymousCredentials(), transport=transport + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = patch_jobs.ListPatchJobInstanceDetailsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.list_patch_job_instance_details), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + patch_jobs.ListPatchJobInstanceDetailsResponse( + next_page_token="next_page_token_value" + ) + ) + + response = await client.list_patch_job_instance_details(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListPatchJobInstanceDetailsAsyncPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_patch_job_instance_details_field_headers(): + client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = patch_jobs.ListPatchJobInstanceDetailsRequest() + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._transport.list_patch_job_instance_details), "__call__" + ) as call: + call.return_value = patch_jobs.ListPatchJobInstanceDetailsResponse() + + client.list_patch_job_instance_details(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "parent=parent/value") in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_patch_job_instance_details_field_headers_async(): + client = OsConfigServiceAsyncClient(credentials=credentials.AnonymousCredentials()) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = patch_jobs.ListPatchJobInstanceDetailsRequest() + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.list_patch_job_instance_details), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + patch_jobs.ListPatchJobInstanceDetailsResponse() + ) + + await client.list_patch_job_instance_details(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "parent=parent/value") in kw["metadata"] + + +def test_list_patch_job_instance_details_flattened(): + client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._transport.list_patch_job_instance_details), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = patch_jobs.ListPatchJobInstanceDetailsResponse() + + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_patch_job_instance_details(parent="parent_value") + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0].parent == "parent_value" + + +def test_list_patch_job_instance_details_flattened_error(): + client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_patch_job_instance_details( + patch_jobs.ListPatchJobInstanceDetailsRequest(), parent="parent_value" + ) + + +@pytest.mark.asyncio +async def test_list_patch_job_instance_details_flattened_async(): + client = OsConfigServiceAsyncClient(credentials=credentials.AnonymousCredentials()) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.list_patch_job_instance_details), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = patch_jobs.ListPatchJobInstanceDetailsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + patch_jobs.ListPatchJobInstanceDetailsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_patch_job_instance_details(parent="parent_value") + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0].parent == "parent_value" + + +@pytest.mark.asyncio +async def test_list_patch_job_instance_details_flattened_error_async(): + client = OsConfigServiceAsyncClient(credentials=credentials.AnonymousCredentials()) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_patch_job_instance_details( + patch_jobs.ListPatchJobInstanceDetailsRequest(), parent="parent_value" + ) + + +def test_list_patch_job_instance_details_pager(): + client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._transport.list_patch_job_instance_details), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + patch_jobs.ListPatchJobInstanceDetailsResponse( + patch_job_instance_details=[ + patch_jobs.PatchJobInstanceDetails(), + patch_jobs.PatchJobInstanceDetails(), + patch_jobs.PatchJobInstanceDetails(), + ], + next_page_token="abc", + ), + patch_jobs.ListPatchJobInstanceDetailsResponse( + patch_job_instance_details=[], next_page_token="def" + ), + patch_jobs.ListPatchJobInstanceDetailsResponse( + patch_job_instance_details=[patch_jobs.PatchJobInstanceDetails()], + next_page_token="ghi", + ), + patch_jobs.ListPatchJobInstanceDetailsResponse( + patch_job_instance_details=[ + patch_jobs.PatchJobInstanceDetails(), + patch_jobs.PatchJobInstanceDetails(), + ] + ), + RuntimeError, + ) + results = [i for i in client.list_patch_job_instance_details(request={})] + assert len(results) == 6 + assert all(isinstance(i, patch_jobs.PatchJobInstanceDetails) for i in results) + + +def test_list_patch_job_instance_details_pages(): + client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._transport.list_patch_job_instance_details), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + patch_jobs.ListPatchJobInstanceDetailsResponse( + patch_job_instance_details=[ + patch_jobs.PatchJobInstanceDetails(), + patch_jobs.PatchJobInstanceDetails(), + patch_jobs.PatchJobInstanceDetails(), + ], + next_page_token="abc", + ), + patch_jobs.ListPatchJobInstanceDetailsResponse( + patch_job_instance_details=[], next_page_token="def" + ), + patch_jobs.ListPatchJobInstanceDetailsResponse( + patch_job_instance_details=[patch_jobs.PatchJobInstanceDetails()], + next_page_token="ghi", + ), + patch_jobs.ListPatchJobInstanceDetailsResponse( + patch_job_instance_details=[ + patch_jobs.PatchJobInstanceDetails(), + patch_jobs.PatchJobInstanceDetails(), + ] + ), + RuntimeError, + ) + pages = list(client.list_patch_job_instance_details(request={}).pages) + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token + + +@pytest.mark.asyncio +async def test_list_patch_job_instance_details_async_pager(): + client = OsConfigServiceAsyncClient(credentials=credentials.AnonymousCredentials) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.list_patch_job_instance_details), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + patch_jobs.ListPatchJobInstanceDetailsResponse( + patch_job_instance_details=[ + patch_jobs.PatchJobInstanceDetails(), + patch_jobs.PatchJobInstanceDetails(), + patch_jobs.PatchJobInstanceDetails(), + ], + next_page_token="abc", + ), + patch_jobs.ListPatchJobInstanceDetailsResponse( + patch_job_instance_details=[], next_page_token="def" + ), + patch_jobs.ListPatchJobInstanceDetailsResponse( + patch_job_instance_details=[patch_jobs.PatchJobInstanceDetails()], + next_page_token="ghi", + ), + patch_jobs.ListPatchJobInstanceDetailsResponse( + patch_job_instance_details=[ + patch_jobs.PatchJobInstanceDetails(), + patch_jobs.PatchJobInstanceDetails(), + ] + ), + RuntimeError, + ) + async_pager = await client.list_patch_job_instance_details(request={}) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, patch_jobs.PatchJobInstanceDetails) for i in responses) + + +@pytest.mark.asyncio +async def test_list_patch_job_instance_details_async_pages(): + client = OsConfigServiceAsyncClient(credentials=credentials.AnonymousCredentials) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.list_patch_job_instance_details), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + patch_jobs.ListPatchJobInstanceDetailsResponse( + patch_job_instance_details=[ + patch_jobs.PatchJobInstanceDetails(), + patch_jobs.PatchJobInstanceDetails(), + patch_jobs.PatchJobInstanceDetails(), + ], + next_page_token="abc", + ), + patch_jobs.ListPatchJobInstanceDetailsResponse( + patch_job_instance_details=[], next_page_token="def" + ), + patch_jobs.ListPatchJobInstanceDetailsResponse( + patch_job_instance_details=[patch_jobs.PatchJobInstanceDetails()], + next_page_token="ghi", + ), + patch_jobs.ListPatchJobInstanceDetailsResponse( + patch_job_instance_details=[ + patch_jobs.PatchJobInstanceDetails(), + patch_jobs.PatchJobInstanceDetails(), + ] + ), + RuntimeError, + ) + pages = [] + async for page in ( + await client.list_patch_job_instance_details(request={}) + ).pages: + pages.append(page) + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token + + +def test_create_patch_deployment(transport: str = "grpc"): + client = OsConfigServiceClient( + credentials=credentials.AnonymousCredentials(), transport=transport + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = patch_deployments.CreatePatchDeploymentRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._transport.create_patch_deployment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = patch_deployments.PatchDeployment( + name="name_value", description="description_value" + ) + + response = client.create_patch_deployment(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, patch_deployments.PatchDeployment) + assert response.name == "name_value" + assert response.description == "description_value" + + +@pytest.mark.asyncio +async def test_create_patch_deployment_async(transport: str = "grpc_asyncio"): + client = OsConfigServiceAsyncClient( + credentials=credentials.AnonymousCredentials(), transport=transport + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = patch_deployments.CreatePatchDeploymentRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.create_patch_deployment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + patch_deployments.PatchDeployment( + name="name_value", description="description_value" + ) + ) + + response = await client.create_patch_deployment(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, patch_deployments.PatchDeployment) + assert response.name == "name_value" + assert response.description == "description_value" + + +def test_create_patch_deployment_field_headers(): + client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = patch_deployments.CreatePatchDeploymentRequest() + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._transport.create_patch_deployment), "__call__" + ) as call: + call.return_value = patch_deployments.PatchDeployment() + + client.create_patch_deployment(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "parent=parent/value") in kw["metadata"] + + +@pytest.mark.asyncio +async def test_create_patch_deployment_field_headers_async(): + client = OsConfigServiceAsyncClient(credentials=credentials.AnonymousCredentials()) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = patch_deployments.CreatePatchDeploymentRequest() + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.create_patch_deployment), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + patch_deployments.PatchDeployment() + ) + + await client.create_patch_deployment(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "parent=parent/value") in kw["metadata"] + + +def test_create_patch_deployment_flattened(): + client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._transport.create_patch_deployment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = patch_deployments.PatchDeployment() + + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_patch_deployment( + parent="parent_value", + patch_deployment=patch_deployments.PatchDeployment(name="name_value"), + patch_deployment_id="patch_deployment_id_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0].parent == "parent_value" + assert args[0].patch_deployment == patch_deployments.PatchDeployment( + name="name_value" + ) + assert args[0].patch_deployment_id == "patch_deployment_id_value" + + +def test_create_patch_deployment_flattened_error(): + client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_patch_deployment( + patch_deployments.CreatePatchDeploymentRequest(), + parent="parent_value", + patch_deployment=patch_deployments.PatchDeployment(name="name_value"), + patch_deployment_id="patch_deployment_id_value", + ) + + +@pytest.mark.asyncio +async def test_create_patch_deployment_flattened_async(): + client = OsConfigServiceAsyncClient(credentials=credentials.AnonymousCredentials()) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.create_patch_deployment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = patch_deployments.PatchDeployment() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + patch_deployments.PatchDeployment() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_patch_deployment( + parent="parent_value", + patch_deployment=patch_deployments.PatchDeployment(name="name_value"), + patch_deployment_id="patch_deployment_id_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0].parent == "parent_value" + assert args[0].patch_deployment == patch_deployments.PatchDeployment( + name="name_value" + ) + assert args[0].patch_deployment_id == "patch_deployment_id_value" + + +@pytest.mark.asyncio +async def test_create_patch_deployment_flattened_error_async(): + client = OsConfigServiceAsyncClient(credentials=credentials.AnonymousCredentials()) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.create_patch_deployment( + patch_deployments.CreatePatchDeploymentRequest(), + parent="parent_value", + patch_deployment=patch_deployments.PatchDeployment(name="name_value"), + patch_deployment_id="patch_deployment_id_value", + ) + + +def test_get_patch_deployment(transport: str = "grpc"): + client = OsConfigServiceClient( + credentials=credentials.AnonymousCredentials(), transport=transport + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = patch_deployments.GetPatchDeploymentRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._transport.get_patch_deployment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = patch_deployments.PatchDeployment( + name="name_value", description="description_value" + ) + + response = client.get_patch_deployment(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, patch_deployments.PatchDeployment) + assert response.name == "name_value" + assert response.description == "description_value" + + +@pytest.mark.asyncio +async def test_get_patch_deployment_async(transport: str = "grpc_asyncio"): + client = OsConfigServiceAsyncClient( + credentials=credentials.AnonymousCredentials(), transport=transport + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = patch_deployments.GetPatchDeploymentRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.get_patch_deployment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + patch_deployments.PatchDeployment( + name="name_value", description="description_value" + ) + ) + + response = await client.get_patch_deployment(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, patch_deployments.PatchDeployment) + assert response.name == "name_value" + assert response.description == "description_value" + + +def test_get_patch_deployment_field_headers(): + client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = patch_deployments.GetPatchDeploymentRequest() + request.name = "name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._transport.get_patch_deployment), "__call__" + ) as call: + call.return_value = patch_deployments.PatchDeployment() + + client.get_patch_deployment(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "name=name/value") in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_patch_deployment_field_headers_async(): + client = OsConfigServiceAsyncClient(credentials=credentials.AnonymousCredentials()) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = patch_deployments.GetPatchDeploymentRequest() + request.name = "name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.get_patch_deployment), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + patch_deployments.PatchDeployment() + ) + + await client.get_patch_deployment(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "name=name/value") in kw["metadata"] + + +def test_get_patch_deployment_flattened(): + client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._transport.get_patch_deployment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = patch_deployments.PatchDeployment() + + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_patch_deployment(name="name_value") + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0].name == "name_value" + + +def test_get_patch_deployment_flattened_error(): + client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_patch_deployment( + patch_deployments.GetPatchDeploymentRequest(), name="name_value" + ) + + +@pytest.mark.asyncio +async def test_get_patch_deployment_flattened_async(): + client = OsConfigServiceAsyncClient(credentials=credentials.AnonymousCredentials()) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.get_patch_deployment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = patch_deployments.PatchDeployment() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + patch_deployments.PatchDeployment() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_patch_deployment(name="name_value") + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0].name == "name_value" + + +@pytest.mark.asyncio +async def test_get_patch_deployment_flattened_error_async(): + client = OsConfigServiceAsyncClient(credentials=credentials.AnonymousCredentials()) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_patch_deployment( + patch_deployments.GetPatchDeploymentRequest(), name="name_value" + ) + + +def test_list_patch_deployments(transport: str = "grpc"): + client = OsConfigServiceClient( + credentials=credentials.AnonymousCredentials(), transport=transport + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = patch_deployments.ListPatchDeploymentsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._transport.list_patch_deployments), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = patch_deployments.ListPatchDeploymentsResponse( + next_page_token="next_page_token_value" + ) + + response = client.list_patch_deployments(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListPatchDeploymentsPager) + assert response.next_page_token == "next_page_token_value" + + +@pytest.mark.asyncio +async def test_list_patch_deployments_async(transport: str = "grpc_asyncio"): + client = OsConfigServiceAsyncClient( + credentials=credentials.AnonymousCredentials(), transport=transport + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = patch_deployments.ListPatchDeploymentsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.list_patch_deployments), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + patch_deployments.ListPatchDeploymentsResponse( + next_page_token="next_page_token_value" + ) + ) + + response = await client.list_patch_deployments(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + + assert args[0] == request + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListPatchDeploymentsAsyncPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_patch_deployments_field_headers(): + client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = patch_deployments.ListPatchDeploymentsRequest() + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._transport.list_patch_deployments), "__call__" + ) as call: + call.return_value = patch_deployments.ListPatchDeploymentsResponse() + + client.list_patch_deployments(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "parent=parent/value") in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_patch_deployments_field_headers_async(): + client = OsConfigServiceAsyncClient(credentials=credentials.AnonymousCredentials()) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = patch_deployments.ListPatchDeploymentsRequest() + request.parent = "parent/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.list_patch_deployments), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + patch_deployments.ListPatchDeploymentsResponse() + ) + + await client.list_patch_deployments(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "parent=parent/value") in kw["metadata"] + + +def test_list_patch_deployments_flattened(): + client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._transport.list_patch_deployments), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = patch_deployments.ListPatchDeploymentsResponse() + + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_patch_deployments(parent="parent_value") + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0].parent == "parent_value" + + +def test_list_patch_deployments_flattened_error(): + client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_patch_deployments( + patch_deployments.ListPatchDeploymentsRequest(), parent="parent_value" + ) + + +@pytest.mark.asyncio +async def test_list_patch_deployments_flattened_async(): + client = OsConfigServiceAsyncClient(credentials=credentials.AnonymousCredentials()) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.list_patch_deployments), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = patch_deployments.ListPatchDeploymentsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + patch_deployments.ListPatchDeploymentsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_patch_deployments(parent="parent_value") + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0].parent == "parent_value" + + +@pytest.mark.asyncio +async def test_list_patch_deployments_flattened_error_async(): + client = OsConfigServiceAsyncClient(credentials=credentials.AnonymousCredentials()) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_patch_deployments( + patch_deployments.ListPatchDeploymentsRequest(), parent="parent_value" + ) + + +def test_list_patch_deployments_pager(): + client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._transport.list_patch_deployments), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + patch_deployments.ListPatchDeploymentsResponse( + patch_deployments=[ + patch_deployments.PatchDeployment(), + patch_deployments.PatchDeployment(), + patch_deployments.PatchDeployment(), + ], + next_page_token="abc", + ), + patch_deployments.ListPatchDeploymentsResponse( + patch_deployments=[], next_page_token="def" + ), + patch_deployments.ListPatchDeploymentsResponse( + patch_deployments=[patch_deployments.PatchDeployment()], + next_page_token="ghi", + ), + patch_deployments.ListPatchDeploymentsResponse( + patch_deployments=[ + patch_deployments.PatchDeployment(), + patch_deployments.PatchDeployment(), + ] + ), + RuntimeError, + ) + results = [i for i in client.list_patch_deployments(request={})] + assert len(results) == 6 + assert all(isinstance(i, patch_deployments.PatchDeployment) for i in results) + + +def test_list_patch_deployments_pages(): + client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._transport.list_patch_deployments), "__call__" + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + patch_deployments.ListPatchDeploymentsResponse( + patch_deployments=[ + patch_deployments.PatchDeployment(), + patch_deployments.PatchDeployment(), + patch_deployments.PatchDeployment(), + ], + next_page_token="abc", + ), + patch_deployments.ListPatchDeploymentsResponse( + patch_deployments=[], next_page_token="def" + ), + patch_deployments.ListPatchDeploymentsResponse( + patch_deployments=[patch_deployments.PatchDeployment()], + next_page_token="ghi", + ), + patch_deployments.ListPatchDeploymentsResponse( + patch_deployments=[ + patch_deployments.PatchDeployment(), + patch_deployments.PatchDeployment(), + ] + ), + RuntimeError, + ) + pages = list(client.list_patch_deployments(request={}).pages) + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token + + +@pytest.mark.asyncio +async def test_list_patch_deployments_async_pager(): + client = OsConfigServiceAsyncClient(credentials=credentials.AnonymousCredentials) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.list_patch_deployments), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + patch_deployments.ListPatchDeploymentsResponse( + patch_deployments=[ + patch_deployments.PatchDeployment(), + patch_deployments.PatchDeployment(), + patch_deployments.PatchDeployment(), + ], + next_page_token="abc", + ), + patch_deployments.ListPatchDeploymentsResponse( + patch_deployments=[], next_page_token="def" + ), + patch_deployments.ListPatchDeploymentsResponse( + patch_deployments=[patch_deployments.PatchDeployment()], + next_page_token="ghi", + ), + patch_deployments.ListPatchDeploymentsResponse( + patch_deployments=[ + patch_deployments.PatchDeployment(), + patch_deployments.PatchDeployment(), + ] + ), + RuntimeError, + ) + async_pager = await client.list_patch_deployments(request={}) + assert async_pager.next_page_token == "abc" + responses = [] + async for response in async_pager: + responses.append(response) + + assert len(responses) == 6 + assert all(isinstance(i, patch_deployments.PatchDeployment) for i in responses) + + +@pytest.mark.asyncio +async def test_list_patch_deployments_async_pages(): + client = OsConfigServiceAsyncClient(credentials=credentials.AnonymousCredentials) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.list_patch_deployments), + "__call__", + new_callable=mock.AsyncMock, + ) as call: + # Set the response to a series of pages. + call.side_effect = ( + patch_deployments.ListPatchDeploymentsResponse( + patch_deployments=[ + patch_deployments.PatchDeployment(), + patch_deployments.PatchDeployment(), + patch_deployments.PatchDeployment(), + ], + next_page_token="abc", + ), + patch_deployments.ListPatchDeploymentsResponse( + patch_deployments=[], next_page_token="def" + ), + patch_deployments.ListPatchDeploymentsResponse( + patch_deployments=[patch_deployments.PatchDeployment()], + next_page_token="ghi", + ), + patch_deployments.ListPatchDeploymentsResponse( + patch_deployments=[ + patch_deployments.PatchDeployment(), + patch_deployments.PatchDeployment(), + ] + ), + RuntimeError, + ) + pages = [] + async for page in (await client.list_patch_deployments(request={})).pages: + pages.append(page) + for page, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page.raw_page.next_page_token == token + + +def test_delete_patch_deployment(transport: str = "grpc"): + client = OsConfigServiceClient( + credentials=credentials.AnonymousCredentials(), transport=transport + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = patch_deployments.DeletePatchDeploymentRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._transport.delete_patch_deployment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = None + + response = client.delete_patch_deployment(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_patch_deployment_async(transport: str = "grpc_asyncio"): + client = OsConfigServiceAsyncClient( + credentials=credentials.AnonymousCredentials(), transport=transport + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = patch_deployments.DeletePatchDeploymentRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.delete_patch_deployment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + + response = await client.delete_patch_deployment(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + + assert args[0] == request + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_patch_deployment_field_headers(): + client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = patch_deployments.DeletePatchDeploymentRequest() + request.name = "name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._transport.delete_patch_deployment), "__call__" + ) as call: + call.return_value = None + + client.delete_patch_deployment(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "name=name/value") in kw["metadata"] + + +@pytest.mark.asyncio +async def test_delete_patch_deployment_field_headers_async(): + client = OsConfigServiceAsyncClient(credentials=credentials.AnonymousCredentials()) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = patch_deployments.DeletePatchDeploymentRequest() + request.name = "name/value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.delete_patch_deployment), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + + await client.delete_patch_deployment(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ("x-goog-request-params", "name=name/value") in kw["metadata"] + + +def test_delete_patch_deployment_flattened(): + client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._transport.delete_patch_deployment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = None + + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.delete_patch_deployment(name="name_value") + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0].name == "name_value" + + +def test_delete_patch_deployment_flattened_error(): + client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_patch_deployment( + patch_deployments.DeletePatchDeploymentRequest(), name="name_value" + ) + + +@pytest.mark.asyncio +async def test_delete_patch_deployment_flattened_async(): + client = OsConfigServiceAsyncClient(credentials=credentials.AnonymousCredentials()) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client._client._transport.delete_patch_deployment), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = None + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.delete_patch_deployment(name="name_value") + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0].name == "name_value" + + +@pytest.mark.asyncio +async def test_delete_patch_deployment_flattened_error_async(): + client = OsConfigServiceAsyncClient(credentials=credentials.AnonymousCredentials()) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_patch_deployment( + patch_deployments.DeletePatchDeploymentRequest(), name="name_value" + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.OsConfigServiceGrpcTransport( + credentials=credentials.AnonymousCredentials() + ) + with pytest.raises(ValueError): + client = OsConfigServiceClient( + credentials=credentials.AnonymousCredentials(), transport=transport + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.OsConfigServiceGrpcTransport( + credentials=credentials.AnonymousCredentials() + ) + client = OsConfigServiceClient(transport=transport) + assert client._transport is transport + + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.OsConfigServiceGrpcTransport( + credentials=credentials.AnonymousCredentials() + ) + channel = transport.grpc_channel + assert channel + + transport = transports.OsConfigServiceGrpcAsyncIOTransport( + credentials=credentials.AnonymousCredentials() + ) + channel = transport.grpc_channel + assert channel + + +def test_transport_grpc_default(): + # A client should use the gRPC transport by default. + client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) + assert isinstance(client._transport, transports.OsConfigServiceGrpcTransport) + + +def test_os_config_service_base_transport(): + # Instantiate the base transport. + transport = transports.OsConfigServiceTransport( + credentials=credentials.AnonymousCredentials() + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + "execute_patch_job", + "get_patch_job", + "cancel_patch_job", + "list_patch_jobs", + "list_patch_job_instance_details", + "create_patch_deployment", + "get_patch_deployment", + "list_patch_deployments", + "delete_patch_deployment", + ) + for method in methods: + with pytest.raises(NotImplementedError): + getattr(transport, method)(request=object()) + + +def test_os_config_service_auth_adc(): + # If no credentials are provided, we should use ADC credentials. + with mock.patch.object(auth, "default") as adc: + adc.return_value = (credentials.AnonymousCredentials(), None) + OsConfigServiceClient() + adc.assert_called_once_with( + scopes=("https://www.googleapis.com/auth/cloud-platform",) + ) + + +def test_os_config_service_transport_auth_adc(): + # If credentials and host are not provided, the transport class should use + # ADC credentials. + with mock.patch.object(auth, "default") as adc: + adc.return_value = (credentials.AnonymousCredentials(), None) + transports.OsConfigServiceGrpcTransport(host="squid.clam.whelk") + adc.assert_called_once_with( + scopes=("https://www.googleapis.com/auth/cloud-platform",) + ) + + +def test_os_config_service_host_no_port(): + client = OsConfigServiceClient( + credentials=credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="osconfig.googleapis.com" + ), + ) + assert client._transport._host == "osconfig.googleapis.com:443" + + +def test_os_config_service_host_with_port(): + client = OsConfigServiceClient( + credentials=credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions( + api_endpoint="osconfig.googleapis.com:8000" + ), + ) + assert client._transport._host == "osconfig.googleapis.com:8000" + + +def test_os_config_service_grpc_transport_channel(): + channel = grpc.insecure_channel("http://localhost/") + + # Check that if channel is provided, mtls endpoint and client_cert_source + # won't be used. + callback = mock.MagicMock() + transport = transports.OsConfigServiceGrpcTransport( + host="squid.clam.whelk", + channel=channel, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=callback, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert not callback.called + + +def test_os_config_service_grpc_asyncio_transport_channel(): + channel = aio.insecure_channel("http://localhost/") + + # Check that if channel is provided, mtls endpoint and client_cert_source + # won't be used. + callback = mock.MagicMock() + transport = transports.OsConfigServiceGrpcAsyncIOTransport( + host="squid.clam.whelk", + channel=channel, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=callback, + ) + assert transport.grpc_channel == channel + assert transport._host == "squid.clam.whelk:443" + assert not callback.called + + +@mock.patch("grpc.ssl_channel_credentials", autospec=True) +@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) +def test_os_config_service_grpc_transport_channel_mtls_with_client_cert_source( + grpc_create_channel, grpc_ssl_channel_cred +): + # Check that if channel is None, but api_mtls_endpoint and client_cert_source + # are provided, then a mTLS channel will be created. + mock_cred = mock.Mock() + + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + transport = transports.OsConfigServiceGrpcTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + ssl_credentials=mock_ssl_cred, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ) + assert transport.grpc_channel == mock_grpc_channel + + +@mock.patch("grpc.ssl_channel_credentials", autospec=True) +@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) +def test_os_config_service_grpc_asyncio_transport_channel_mtls_with_client_cert_source( + grpc_create_channel, grpc_ssl_channel_cred +): + # Check that if channel is None, but api_mtls_endpoint and client_cert_source + # are provided, then a mTLS channel will be created. + mock_cred = mock.Mock() + + mock_ssl_cred = mock.Mock() + grpc_ssl_channel_cred.return_value = mock_ssl_cred + + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + transport = transports.OsConfigServiceGrpcAsyncIOTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint="mtls.squid.clam.whelk", + client_cert_source=client_cert_source_callback, + ) + grpc_ssl_channel_cred.assert_called_once_with( + certificate_chain=b"cert bytes", private_key=b"key bytes" + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + ssl_credentials=mock_ssl_cred, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ) + assert transport.grpc_channel == mock_grpc_channel + + +@pytest.mark.parametrize( + "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] +) +@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) +def test_os_config_service_grpc_transport_channel_mtls_with_adc( + grpc_create_channel, api_mtls_endpoint +): + # Check that if channel and client_cert_source are None, but api_mtls_endpoint + # is provided, then a mTLS channel will be created with SSL ADC. + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + # Mock google.auth.transport.grpc.SslCredentials class. + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + mock_cred = mock.Mock() + transport = transports.OsConfigServiceGrpcTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint=api_mtls_endpoint, + client_cert_source=None, + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + ssl_credentials=mock_ssl_cred, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ) + assert transport.grpc_channel == mock_grpc_channel + + +@pytest.mark.parametrize( + "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] +) +@mock.patch("google.api_core.grpc_helpers_async.create_channel", autospec=True) +def test_os_config_service_grpc_asyncio_transport_channel_mtls_with_adc( + grpc_create_channel, api_mtls_endpoint +): + # Check that if channel and client_cert_source are None, but api_mtls_endpoint + # is provided, then a mTLS channel will be created with SSL ADC. + mock_grpc_channel = mock.Mock() + grpc_create_channel.return_value = mock_grpc_channel + + # Mock google.auth.transport.grpc.SslCredentials class. + mock_ssl_cred = mock.Mock() + with mock.patch.multiple( + "google.auth.transport.grpc.SslCredentials", + __init__=mock.Mock(return_value=None), + ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), + ): + mock_cred = mock.Mock() + transport = transports.OsConfigServiceGrpcAsyncIOTransport( + host="squid.clam.whelk", + credentials=mock_cred, + api_mtls_endpoint=api_mtls_endpoint, + client_cert_source=None, + ) + grpc_create_channel.assert_called_once_with( + "mtls.squid.clam.whelk:443", + credentials=mock_cred, + ssl_credentials=mock_ssl_cred, + scopes=("https://www.googleapis.com/auth/cloud-platform",), + ) + assert transport.grpc_channel == mock_grpc_channel + + +def test_patch_deployment_path(): + project = "squid" + patch_deployment = "clam" + + expected = "projects/{project}/patchDeployments/{patch_deployment}".format( + project=project, patch_deployment=patch_deployment + ) + actual = OsConfigServiceClient.patch_deployment_path(project, patch_deployment) + assert expected == actual + + +def test_parse_patch_deployment_path(): + expected = {"project": "whelk", "patch_deployment": "octopus"} + path = OsConfigServiceClient.patch_deployment_path(**expected) + + # Check that the path construction is reversible. + actual = OsConfigServiceClient.parse_patch_deployment_path(path) + assert expected == actual diff --git a/tests/unit/osconfig_v1/test_os_config_service.py b/tests/unit/osconfig_v1/test_os_config_service.py deleted file mode 100644 index 4a5bc2f..0000000 --- a/tests/unit/osconfig_v1/test_os_config_service.py +++ /dev/null @@ -1,1228 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# - -from unittest import mock - -import grpc -import math -import pytest - -from google import auth -from google.api_core import client_options -from google.api_core import grpc_helpers -from google.auth import credentials -from google.cloud.osconfig_v1.services.os_config_service import OsConfigServiceClient -from google.cloud.osconfig_v1.services.os_config_service import pagers -from google.cloud.osconfig_v1.services.os_config_service import transports -from google.cloud.osconfig_v1.types import patch_deployments -from google.cloud.osconfig_v1.types import patch_jobs -from google.cloud.osconfig_v1.types import patch_jobs as gco_patch_jobs -from google.oauth2 import service_account -from google.protobuf import duration_pb2 as duration # type: ignore -from google.protobuf import timestamp_pb2 as timestamp # type: ignore -from google.type import datetime_pb2 as datetime # type: ignore -from google.type import dayofweek_pb2 as dayofweek # type: ignore -from google.type import timeofday_pb2 as timeofday # type: ignore - - -def client_cert_source_callback(): - return b"cert bytes", b"key bytes" - - -def test__get_default_mtls_endpoint(): - api_endpoint = "example.googleapis.com" - api_mtls_endpoint = "example.mtls.googleapis.com" - sandbox_endpoint = "example.sandbox.googleapis.com" - sandbox_mtls_endpoint = "example.mtls.sandbox.googleapis.com" - non_googleapi = "api.example.com" - - assert OsConfigServiceClient._get_default_mtls_endpoint(None) is None - assert ( - OsConfigServiceClient._get_default_mtls_endpoint(api_endpoint) - == api_mtls_endpoint - ) - assert ( - OsConfigServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) - == api_mtls_endpoint - ) - assert ( - OsConfigServiceClient._get_default_mtls_endpoint(sandbox_endpoint) - == sandbox_mtls_endpoint - ) - assert ( - OsConfigServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) - == sandbox_mtls_endpoint - ) - assert ( - OsConfigServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi - ) - - -def test_os_config_service_client_from_service_account_file(): - creds = credentials.AnonymousCredentials() - with mock.patch.object( - service_account.Credentials, "from_service_account_file" - ) as factory: - factory.return_value = creds - client = OsConfigServiceClient.from_service_account_file("dummy/file/path.json") - assert client._transport._credentials == creds - - client = OsConfigServiceClient.from_service_account_json("dummy/file/path.json") - assert client._transport._credentials == creds - - assert client._transport._host == "osconfig.googleapis.com:443" - - -def test_os_config_service_client_client_options(): - # Check that if channel is provided we won't create a new one. - with mock.patch( - "google.cloud.osconfig_v1.services.os_config_service.OsConfigServiceClient.get_transport_class" - ) as gtc: - transport = transports.OsConfigServiceGrpcTransport( - credentials=credentials.AnonymousCredentials() - ) - client = OsConfigServiceClient(transport=transport) - gtc.assert_not_called() - - # Check mTLS is not triggered with empty client options. - options = client_options.ClientOptions() - with mock.patch( - "google.cloud.osconfig_v1.services.os_config_service.OsConfigServiceClient.get_transport_class" - ) as gtc: - transport = gtc.return_value = mock.MagicMock() - client = OsConfigServiceClient(client_options=options) - transport.assert_called_once_with( - credentials=None, host=client.DEFAULT_ENDPOINT - ) - - # Check mTLS is not triggered if api_endpoint is provided but - # client_cert_source is None. - options = client_options.ClientOptions(api_endpoint="squid.clam.whelk") - with mock.patch( - "google.cloud.osconfig_v1.services.os_config_service.transports.OsConfigServiceGrpcTransport.__init__" - ) as grpc_transport: - grpc_transport.return_value = None - client = OsConfigServiceClient(client_options=options) - grpc_transport.assert_called_once_with( - api_mtls_endpoint=None, - client_cert_source=None, - credentials=None, - host="squid.clam.whelk", - ) - - # Check mTLS is triggered if client_cert_source is provided. - options = client_options.ClientOptions( - client_cert_source=client_cert_source_callback - ) - with mock.patch( - "google.cloud.osconfig_v1.services.os_config_service.transports.OsConfigServiceGrpcTransport.__init__" - ) as grpc_transport: - grpc_transport.return_value = None - client = OsConfigServiceClient(client_options=options) - grpc_transport.assert_called_once_with( - api_mtls_endpoint=client.DEFAULT_MTLS_ENDPOINT, - client_cert_source=client_cert_source_callback, - credentials=None, - host=client.DEFAULT_ENDPOINT, - ) - - # Check mTLS is triggered if api_endpoint and client_cert_source are provided. - options = client_options.ClientOptions( - api_endpoint="squid.clam.whelk", client_cert_source=client_cert_source_callback - ) - with mock.patch( - "google.cloud.osconfig_v1.services.os_config_service.transports.OsConfigServiceGrpcTransport.__init__" - ) as grpc_transport: - grpc_transport.return_value = None - client = OsConfigServiceClient(client_options=options) - grpc_transport.assert_called_once_with( - api_mtls_endpoint="squid.clam.whelk", - client_cert_source=client_cert_source_callback, - credentials=None, - host="squid.clam.whelk", - ) - - -def test_os_config_service_client_client_options_from_dict(): - with mock.patch( - "google.cloud.osconfig_v1.services.os_config_service.transports.OsConfigServiceGrpcTransport.__init__" - ) as grpc_transport: - grpc_transport.return_value = None - client = OsConfigServiceClient( - client_options={"api_endpoint": "squid.clam.whelk"} - ) - grpc_transport.assert_called_once_with( - api_mtls_endpoint=None, - client_cert_source=None, - credentials=None, - host="squid.clam.whelk", - ) - - -def test_execute_patch_job(transport: str = "grpc"): - client = OsConfigServiceClient( - credentials=credentials.AnonymousCredentials(), transport=transport - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = patch_jobs.ExecutePatchJobRequest() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._transport.execute_patch_job), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = patch_jobs.PatchJob( - name="name_value", - display_name="display_name_value", - description="description_value", - state=patch_jobs.PatchJob.State.STARTED, - dry_run=True, - error_message="error_message_value", - percent_complete=0.1705, - patch_deployment="patch_deployment_value", - ) - - response = client.execute_patch_job(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, patch_jobs.PatchJob) - assert response.name == "name_value" - assert response.display_name == "display_name_value" - assert response.description == "description_value" - assert response.state == patch_jobs.PatchJob.State.STARTED - - assert response.dry_run is True - assert response.error_message == "error_message_value" - assert math.isclose(response.percent_complete, 0.1705, rel_tol=1e-6) - assert response.patch_deployment == "patch_deployment_value" - - -def test_get_patch_job(transport: str = "grpc"): - client = OsConfigServiceClient( - credentials=credentials.AnonymousCredentials(), transport=transport - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = patch_jobs.GetPatchJobRequest() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.get_patch_job), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = patch_jobs.PatchJob( - name="name_value", - display_name="display_name_value", - description="description_value", - state=patch_jobs.PatchJob.State.STARTED, - dry_run=True, - error_message="error_message_value", - percent_complete=0.1705, - patch_deployment="patch_deployment_value", - ) - - response = client.get_patch_job(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, patch_jobs.PatchJob) - assert response.name == "name_value" - assert response.display_name == "display_name_value" - assert response.description == "description_value" - assert response.state == patch_jobs.PatchJob.State.STARTED - - assert response.dry_run is True - assert response.error_message == "error_message_value" - assert math.isclose(response.percent_complete, 0.1705, rel_tol=1e-6) - assert response.patch_deployment == "patch_deployment_value" - - -def test_get_patch_job_field_headers(): - client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = patch_jobs.GetPatchJobRequest(name="name/value") - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.get_patch_job), "__call__") as call: - call.return_value = patch_jobs.PatchJob() - client.get_patch_job(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "name=name/value") in kw["metadata"] - - -def test_get_patch_job_flattened(): - client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.get_patch_job), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = patch_jobs.PatchJob() - - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = client.get_patch_job(name="name_value") - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - - -def test_get_patch_job_flattened_error(): - client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.get_patch_job(patch_jobs.GetPatchJobRequest(), name="name_value") - - -def test_cancel_patch_job(transport: str = "grpc"): - client = OsConfigServiceClient( - credentials=credentials.AnonymousCredentials(), transport=transport - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = patch_jobs.CancelPatchJobRequest() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._transport.cancel_patch_job), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = patch_jobs.PatchJob( - name="name_value", - display_name="display_name_value", - description="description_value", - state=patch_jobs.PatchJob.State.STARTED, - dry_run=True, - error_message="error_message_value", - percent_complete=0.1705, - patch_deployment="patch_deployment_value", - ) - - response = client.cancel_patch_job(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, patch_jobs.PatchJob) - assert response.name == "name_value" - assert response.display_name == "display_name_value" - assert response.description == "description_value" - assert response.state == patch_jobs.PatchJob.State.STARTED - - assert response.dry_run is True - assert response.error_message == "error_message_value" - assert math.isclose(response.percent_complete, 0.1705, rel_tol=1e-6) - assert response.patch_deployment == "patch_deployment_value" - - -def test_list_patch_jobs(transport: str = "grpc"): - client = OsConfigServiceClient( - credentials=credentials.AnonymousCredentials(), transport=transport - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = patch_jobs.ListPatchJobsRequest() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_patch_jobs), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = patch_jobs.ListPatchJobsResponse( - next_page_token="next_page_token_value" - ) - - response = client.list_patch_jobs(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListPatchJobsPager) - assert response.next_page_token == "next_page_token_value" - - -def test_list_patch_jobs_field_headers(): - client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = patch_jobs.ListPatchJobsRequest(parent="parent/value") - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_patch_jobs), "__call__") as call: - call.return_value = patch_jobs.ListPatchJobsResponse() - client.list_patch_jobs(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "parent=parent/value") in kw["metadata"] - - -def test_list_patch_jobs_flattened(): - client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_patch_jobs), "__call__") as call: - # Designate an appropriate return value for the call. - call.return_value = patch_jobs.ListPatchJobsResponse() - - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = client.list_patch_jobs(parent="parent_value") - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - - -def test_list_patch_jobs_flattened_error(): - client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.list_patch_jobs(patch_jobs.ListPatchJobsRequest(), parent="parent_value") - - -def test_list_patch_jobs_pager(): - client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_patch_jobs), "__call__") as call: - # Set the response to a series of pages. - call.side_effect = ( - patch_jobs.ListPatchJobsResponse( - patch_jobs=[ - patch_jobs.PatchJob(), - patch_jobs.PatchJob(), - patch_jobs.PatchJob(), - ], - next_page_token="abc", - ), - patch_jobs.ListPatchJobsResponse(patch_jobs=[], next_page_token="def"), - patch_jobs.ListPatchJobsResponse( - patch_jobs=[patch_jobs.PatchJob()], next_page_token="ghi" - ), - patch_jobs.ListPatchJobsResponse( - patch_jobs=[patch_jobs.PatchJob(), patch_jobs.PatchJob()] - ), - RuntimeError, - ) - results = [i for i in client.list_patch_jobs(request={})] - assert len(results) == 6 - assert all(isinstance(i, patch_jobs.PatchJob) for i in results) - - -def test_list_patch_jobs_pages(): - client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object(type(client._transport.list_patch_jobs), "__call__") as call: - # Set the response to a series of pages. - call.side_effect = ( - patch_jobs.ListPatchJobsResponse( - patch_jobs=[ - patch_jobs.PatchJob(), - patch_jobs.PatchJob(), - patch_jobs.PatchJob(), - ], - next_page_token="abc", - ), - patch_jobs.ListPatchJobsResponse(patch_jobs=[], next_page_token="def"), - patch_jobs.ListPatchJobsResponse( - patch_jobs=[patch_jobs.PatchJob()], next_page_token="ghi" - ), - patch_jobs.ListPatchJobsResponse( - patch_jobs=[patch_jobs.PatchJob(), patch_jobs.PatchJob()] - ), - RuntimeError, - ) - pages = list(client.list_patch_jobs(request={}).pages) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token - - -def test_list_patch_job_instance_details(transport: str = "grpc"): - client = OsConfigServiceClient( - credentials=credentials.AnonymousCredentials(), transport=transport - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = patch_jobs.ListPatchJobInstanceDetailsRequest() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._transport.list_patch_job_instance_details), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = patch_jobs.ListPatchJobInstanceDetailsResponse( - next_page_token="next_page_token_value" - ) - - response = client.list_patch_job_instance_details(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListPatchJobInstanceDetailsPager) - assert response.next_page_token == "next_page_token_value" - - -def test_list_patch_job_instance_details_field_headers(): - client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = patch_jobs.ListPatchJobInstanceDetailsRequest(parent="parent/value") - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._transport.list_patch_job_instance_details), "__call__" - ) as call: - call.return_value = patch_jobs.ListPatchJobInstanceDetailsResponse() - client.list_patch_job_instance_details(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "parent=parent/value") in kw["metadata"] - - -def test_list_patch_job_instance_details_flattened(): - client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._transport.list_patch_job_instance_details), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = patch_jobs.ListPatchJobInstanceDetailsResponse() - - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = client.list_patch_job_instance_details(parent="parent_value") - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - - -def test_list_patch_job_instance_details_flattened_error(): - client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.list_patch_job_instance_details( - patch_jobs.ListPatchJobInstanceDetailsRequest(), parent="parent_value" - ) - - -def test_list_patch_job_instance_details_pager(): - client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._transport.list_patch_job_instance_details), "__call__" - ) as call: - # Set the response to a series of pages. - call.side_effect = ( - patch_jobs.ListPatchJobInstanceDetailsResponse( - patch_job_instance_details=[ - patch_jobs.PatchJobInstanceDetails(), - patch_jobs.PatchJobInstanceDetails(), - patch_jobs.PatchJobInstanceDetails(), - ], - next_page_token="abc", - ), - patch_jobs.ListPatchJobInstanceDetailsResponse( - patch_job_instance_details=[], next_page_token="def" - ), - patch_jobs.ListPatchJobInstanceDetailsResponse( - patch_job_instance_details=[patch_jobs.PatchJobInstanceDetails()], - next_page_token="ghi", - ), - patch_jobs.ListPatchJobInstanceDetailsResponse( - patch_job_instance_details=[ - patch_jobs.PatchJobInstanceDetails(), - patch_jobs.PatchJobInstanceDetails(), - ] - ), - RuntimeError, - ) - results = [i for i in client.list_patch_job_instance_details(request={})] - assert len(results) == 6 - assert all(isinstance(i, patch_jobs.PatchJobInstanceDetails) for i in results) - - -def test_list_patch_job_instance_details_pages(): - client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._transport.list_patch_job_instance_details), "__call__" - ) as call: - # Set the response to a series of pages. - call.side_effect = ( - patch_jobs.ListPatchJobInstanceDetailsResponse( - patch_job_instance_details=[ - patch_jobs.PatchJobInstanceDetails(), - patch_jobs.PatchJobInstanceDetails(), - patch_jobs.PatchJobInstanceDetails(), - ], - next_page_token="abc", - ), - patch_jobs.ListPatchJobInstanceDetailsResponse( - patch_job_instance_details=[], next_page_token="def" - ), - patch_jobs.ListPatchJobInstanceDetailsResponse( - patch_job_instance_details=[patch_jobs.PatchJobInstanceDetails()], - next_page_token="ghi", - ), - patch_jobs.ListPatchJobInstanceDetailsResponse( - patch_job_instance_details=[ - patch_jobs.PatchJobInstanceDetails(), - patch_jobs.PatchJobInstanceDetails(), - ] - ), - RuntimeError, - ) - pages = list(client.list_patch_job_instance_details(request={}).pages) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token - - -def test_create_patch_deployment(transport: str = "grpc"): - client = OsConfigServiceClient( - credentials=credentials.AnonymousCredentials(), transport=transport - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = patch_deployments.CreatePatchDeploymentRequest() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._transport.create_patch_deployment), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = patch_deployments.PatchDeployment( - name="name_value", description="description_value" - ) - - response = client.create_patch_deployment(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, patch_deployments.PatchDeployment) - assert response.name == "name_value" - assert response.description == "description_value" - - -def test_create_patch_deployment_flattened(): - client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._transport.create_patch_deployment), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = patch_deployments.PatchDeployment() - - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = client.create_patch_deployment( - parent="parent_value", - patch_deployment=patch_deployments.PatchDeployment(name="name_value"), - patch_deployment_id="patch_deployment_id_value", - ) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - assert args[0].patch_deployment == patch_deployments.PatchDeployment( - name="name_value" - ) - assert args[0].patch_deployment_id == "patch_deployment_id_value" - - -def test_create_patch_deployment_flattened_error(): - client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.create_patch_deployment( - patch_deployments.CreatePatchDeploymentRequest(), - parent="parent_value", - patch_deployment=patch_deployments.PatchDeployment(name="name_value"), - patch_deployment_id="patch_deployment_id_value", - ) - - -def test_get_patch_deployment(transport: str = "grpc"): - client = OsConfigServiceClient( - credentials=credentials.AnonymousCredentials(), transport=transport - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = patch_deployments.GetPatchDeploymentRequest() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._transport.get_patch_deployment), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = patch_deployments.PatchDeployment( - name="name_value", description="description_value" - ) - - response = client.get_patch_deployment(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, patch_deployments.PatchDeployment) - assert response.name == "name_value" - assert response.description == "description_value" - - -def test_get_patch_deployment_field_headers(): - client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = patch_deployments.GetPatchDeploymentRequest(name="name/value") - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._transport.get_patch_deployment), "__call__" - ) as call: - call.return_value = patch_deployments.PatchDeployment() - client.get_patch_deployment(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "name=name/value") in kw["metadata"] - - -def test_get_patch_deployment_flattened(): - client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._transport.get_patch_deployment), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = patch_deployments.PatchDeployment() - - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = client.get_patch_deployment(name="name_value") - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - - -def test_get_patch_deployment_flattened_error(): - client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.get_patch_deployment( - patch_deployments.GetPatchDeploymentRequest(), name="name_value" - ) - - -def test_list_patch_deployments(transport: str = "grpc"): - client = OsConfigServiceClient( - credentials=credentials.AnonymousCredentials(), transport=transport - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = patch_deployments.ListPatchDeploymentsRequest() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._transport.list_patch_deployments), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = patch_deployments.ListPatchDeploymentsResponse( - next_page_token="next_page_token_value" - ) - - response = client.list_patch_deployments(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - - assert args[0] == request - - # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListPatchDeploymentsPager) - assert response.next_page_token == "next_page_token_value" - - -def test_list_patch_deployments_field_headers(): - client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) - - # Any value that is part of the HTTP/1.1 URI should be sent as - # a field header. Set these to a non-empty value. - request = patch_deployments.ListPatchDeploymentsRequest(parent="parent/value") - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._transport.list_patch_deployments), "__call__" - ) as call: - call.return_value = patch_deployments.ListPatchDeploymentsResponse() - client.list_patch_deployments(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0] == request - - # Establish that the field header was sent. - _, _, kw = call.mock_calls[0] - assert ("x-goog-request-params", "parent=parent/value") in kw["metadata"] - - -def test_list_patch_deployments_flattened(): - client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._transport.list_patch_deployments), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = patch_deployments.ListPatchDeploymentsResponse() - - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = client.list_patch_deployments(parent="parent_value") - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0].parent == "parent_value" - - -def test_list_patch_deployments_flattened_error(): - client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.list_patch_deployments( - patch_deployments.ListPatchDeploymentsRequest(), parent="parent_value" - ) - - -def test_list_patch_deployments_pager(): - client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._transport.list_patch_deployments), "__call__" - ) as call: - # Set the response to a series of pages. - call.side_effect = ( - patch_deployments.ListPatchDeploymentsResponse( - patch_deployments=[ - patch_deployments.PatchDeployment(), - patch_deployments.PatchDeployment(), - patch_deployments.PatchDeployment(), - ], - next_page_token="abc", - ), - patch_deployments.ListPatchDeploymentsResponse( - patch_deployments=[], next_page_token="def" - ), - patch_deployments.ListPatchDeploymentsResponse( - patch_deployments=[patch_deployments.PatchDeployment()], - next_page_token="ghi", - ), - patch_deployments.ListPatchDeploymentsResponse( - patch_deployments=[ - patch_deployments.PatchDeployment(), - patch_deployments.PatchDeployment(), - ] - ), - RuntimeError, - ) - results = [i for i in client.list_patch_deployments(request={})] - assert len(results) == 6 - assert all(isinstance(i, patch_deployments.PatchDeployment) for i in results) - - -def test_list_patch_deployments_pages(): - client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._transport.list_patch_deployments), "__call__" - ) as call: - # Set the response to a series of pages. - call.side_effect = ( - patch_deployments.ListPatchDeploymentsResponse( - patch_deployments=[ - patch_deployments.PatchDeployment(), - patch_deployments.PatchDeployment(), - patch_deployments.PatchDeployment(), - ], - next_page_token="abc", - ), - patch_deployments.ListPatchDeploymentsResponse( - patch_deployments=[], next_page_token="def" - ), - patch_deployments.ListPatchDeploymentsResponse( - patch_deployments=[patch_deployments.PatchDeployment()], - next_page_token="ghi", - ), - patch_deployments.ListPatchDeploymentsResponse( - patch_deployments=[ - patch_deployments.PatchDeployment(), - patch_deployments.PatchDeployment(), - ] - ), - RuntimeError, - ) - pages = list(client.list_patch_deployments(request={}).pages) - for page, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page.raw_page.next_page_token == token - - -def test_delete_patch_deployment(transport: str = "grpc"): - client = OsConfigServiceClient( - credentials=credentials.AnonymousCredentials(), transport=transport - ) - - # Everything is optional in proto3 as far as the runtime is concerned, - # and we are mocking out the actual API, so just send an empty request. - request = patch_deployments.DeletePatchDeploymentRequest() - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._transport.delete_patch_deployment), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = None - - response = client.delete_patch_deployment(request) - - # Establish that the underlying gRPC stub method was called. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - - assert args[0] == request - - # Establish that the response is the type that we expect. - assert response is None - - -def test_delete_patch_deployment_flattened(): - client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) - - # Mock the actual call within the gRPC stub, and fake the request. - with mock.patch.object( - type(client._transport.delete_patch_deployment), "__call__" - ) as call: - # Designate an appropriate return value for the call. - call.return_value = None - - # Call the method with a truthy value for each flattened field, - # using the keyword arguments to the method. - response = client.delete_patch_deployment(name="name_value") - - # Establish that the underlying call was made with the expected - # request object values. - assert len(call.mock_calls) == 1 - _, args, _ = call.mock_calls[0] - assert args[0].name == "name_value" - - -def test_delete_patch_deployment_flattened_error(): - client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.delete_patch_deployment( - patch_deployments.DeletePatchDeploymentRequest(), name="name_value" - ) - - -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.OsConfigServiceGrpcTransport( - credentials=credentials.AnonymousCredentials() - ) - with pytest.raises(ValueError): - client = OsConfigServiceClient( - credentials=credentials.AnonymousCredentials(), transport=transport - ) - - -def test_transport_instance(): - # A client may be instantiated with a custom transport instance. - transport = transports.OsConfigServiceGrpcTransport( - credentials=credentials.AnonymousCredentials() - ) - client = OsConfigServiceClient(transport=transport) - assert client._transport is transport - - -def test_transport_grpc_default(): - # A client should use the gRPC transport by default. - client = OsConfigServiceClient(credentials=credentials.AnonymousCredentials()) - assert isinstance(client._transport, transports.OsConfigServiceGrpcTransport) - - -def test_os_config_service_base_transport(): - # Instantiate the base transport. - transport = transports.OsConfigServiceTransport( - credentials=credentials.AnonymousCredentials() - ) - - # Every method on the transport should just blindly - # raise NotImplementedError. - methods = ( - "execute_patch_job", - "get_patch_job", - "cancel_patch_job", - "list_patch_jobs", - "list_patch_job_instance_details", - "create_patch_deployment", - "get_patch_deployment", - "list_patch_deployments", - "delete_patch_deployment", - ) - for method in methods: - with pytest.raises(NotImplementedError): - getattr(transport, method)(request=object()) - - -def test_os_config_service_auth_adc(): - # If no credentials are provided, we should use ADC credentials. - with mock.patch.object(auth, "default") as adc: - adc.return_value = (credentials.AnonymousCredentials(), None) - OsConfigServiceClient() - adc.assert_called_once_with( - scopes=("https://www.googleapis.com/auth/cloud-platform",) - ) - - -def test_os_config_service_host_no_port(): - client = OsConfigServiceClient( - credentials=credentials.AnonymousCredentials(), - client_options=client_options.ClientOptions( - api_endpoint="osconfig.googleapis.com" - ), - transport="grpc", - ) - assert client._transport._host == "osconfig.googleapis.com:443" - - -def test_os_config_service_host_with_port(): - client = OsConfigServiceClient( - credentials=credentials.AnonymousCredentials(), - client_options=client_options.ClientOptions( - api_endpoint="osconfig.googleapis.com:8000" - ), - transport="grpc", - ) - assert client._transport._host == "osconfig.googleapis.com:8000" - - -def test_os_config_service_grpc_transport_channel(): - channel = grpc.insecure_channel("http://localhost/") - - # Check that if channel is provided, mtls endpoint and client_cert_source - # won't be used. - callback = mock.MagicMock() - transport = transports.OsConfigServiceGrpcTransport( - host="squid.clam.whelk", - channel=channel, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=callback, - ) - assert transport.grpc_channel == channel - assert transport._host == "squid.clam.whelk:443" - assert not callback.called - - -@mock.patch("grpc.ssl_channel_credentials", autospec=True) -@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) -def test_os_config_service_grpc_transport_channel_mtls_with_client_cert_source( - grpc_create_channel, grpc_ssl_channel_cred -): - # Check that if channel is None, but api_mtls_endpoint and client_cert_source - # are provided, then a mTLS channel will be created. - mock_cred = mock.Mock() - - mock_ssl_cred = mock.Mock() - grpc_ssl_channel_cred.return_value = mock_ssl_cred - - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - transport = transports.OsConfigServiceGrpcTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint="mtls.squid.clam.whelk", - client_cert_source=client_cert_source_callback, - ) - grpc_ssl_channel_cred.assert_called_once_with( - certificate_chain=b"cert bytes", private_key=b"key bytes" - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - ssl_credentials=mock_ssl_cred, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ) - assert transport.grpc_channel == mock_grpc_channel - - -@pytest.mark.parametrize( - "api_mtls_endpoint", ["mtls.squid.clam.whelk", "mtls.squid.clam.whelk:443"] -) -@mock.patch("google.api_core.grpc_helpers.create_channel", autospec=True) -def test_os_config_service_grpc_transport_channel_mtls_with_adc( - grpc_create_channel, api_mtls_endpoint -): - # Check that if channel and client_cert_source are None, but api_mtls_endpoint - # is provided, then a mTLS channel will be created with SSL ADC. - mock_grpc_channel = mock.Mock() - grpc_create_channel.return_value = mock_grpc_channel - - # Mock google.auth.transport.grpc.SslCredentials class. - mock_ssl_cred = mock.Mock() - with mock.patch.multiple( - "google.auth.transport.grpc.SslCredentials", - __init__=mock.Mock(return_value=None), - ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred), - ): - mock_cred = mock.Mock() - transport = transports.OsConfigServiceGrpcTransport( - host="squid.clam.whelk", - credentials=mock_cred, - api_mtls_endpoint=api_mtls_endpoint, - client_cert_source=None, - ) - grpc_create_channel.assert_called_once_with( - "mtls.squid.clam.whelk:443", - credentials=mock_cred, - ssl_credentials=mock_ssl_cred, - scopes=("https://www.googleapis.com/auth/cloud-platform",), - ) - assert transport.grpc_channel == mock_grpc_channel - - -def test_patch_deployment_path(): - project = "squid" - patch_deployment = "clam" - - expected = "projects/{project}/patchDeployments/{patch_deployment}".format( - project=project, patch_deployment=patch_deployment - ) - actual = OsConfigServiceClient.patch_deployment_path(project, patch_deployment) - assert expected == actual - - -def test_parse_patch_deployment_path(): - expected = {"project": "whelk", "patch_deployment": "octopus"} - path = OsConfigServiceClient.patch_deployment_path(**expected) - - # Check that the path construction is reversible. - actual = OsConfigServiceClient.parse_patch_deployment_path(path) - assert expected == actual