From 0d3b4939cdae196ea9b0edc00e13f61d7d71777d Mon Sep 17 00:00:00 2001 From: Yoshi Automation Bot Date: Thu, 1 Apr 2021 16:30:02 -0700 Subject: [PATCH] fix: BREAKING deprecate TransferableSkus fields (#14) This PR was generated using Autosynth. :rainbow: Synth log will be available here: https://source.cloud.google.com/results/invocations/a03a3673-1422-46d6-80b4-aa3d507db98e/targets - [ ] To automatically regenerate this PR, check this box. PiperOrigin-RevId: 358862009 Source-Link: https://github.com/googleapis/googleapis/commit/2916ac4a35c49441baa5dc8c7e2ad5a1205ed2ca --- .kokoro/samples/python3.6/periodic-head.cfg | 11 + .kokoro/samples/python3.7/periodic-head.cfg | 11 + .kokoro/samples/python3.8/periodic-head.cfg | 11 + .kokoro/test-samples-against-head.sh | 28 + .kokoro/test-samples-impl.sh | 102 +++ .kokoro/test-samples.sh | 96 +-- .pre-commit-config.yaml | 2 +- .../cloud_channel_service/async_client.py | 333 +++++----- .../services/cloud_channel_service/client.py | 301 +++++---- .../cloud_channel_service/transports/base.py | 18 +- .../cloud_channel_service/transports/grpc.py | 404 ++++++------ .../transports/grpc_asyncio.py | 412 ++++++------- google/cloud/channel_v1/types/__init__.py | 258 ++++---- google/cloud/channel_v1/types/customers.py | 3 +- google/cloud/channel_v1/types/entitlements.py | 12 - google/cloud/channel_v1/types/offers.py | 6 + google/cloud/channel_v1/types/service.py | 6 - noxfile.py | 29 +- renovate.json | 3 +- scripts/fixup_channel_v1_keywords.py | 2 +- synth.metadata | 110 +--- testing/constraints-3.7.txt | 2 + testing/constraints-3.8.txt | 2 + testing/constraints-3.9.txt | 2 + tests/unit/gapic/channel_v1/__init__.py | 15 + .../channel_v1/test_cloud_channel_service.py | 582 +++++++++++++++++- 26 files changed, 1632 insertions(+), 1129 deletions(-) create mode 100644 .kokoro/samples/python3.6/periodic-head.cfg create mode 100644 .kokoro/samples/python3.7/periodic-head.cfg create mode 100644 .kokoro/samples/python3.8/periodic-head.cfg create mode 100755 .kokoro/test-samples-against-head.sh create mode 100755 .kokoro/test-samples-impl.sh diff --git a/.kokoro/samples/python3.6/periodic-head.cfg b/.kokoro/samples/python3.6/periodic-head.cfg new file mode 100644 index 0000000..f9cfcd3 --- /dev/null +++ b/.kokoro/samples/python3.6/periodic-head.cfg @@ -0,0 +1,11 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "True" +} + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/python-pubsub/.kokoro/test-samples-against-head.sh" +} diff --git a/.kokoro/samples/python3.7/periodic-head.cfg b/.kokoro/samples/python3.7/periodic-head.cfg new file mode 100644 index 0000000..f9cfcd3 --- /dev/null +++ b/.kokoro/samples/python3.7/periodic-head.cfg @@ -0,0 +1,11 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "True" +} + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/python-pubsub/.kokoro/test-samples-against-head.sh" +} diff --git a/.kokoro/samples/python3.8/periodic-head.cfg b/.kokoro/samples/python3.8/periodic-head.cfg new file mode 100644 index 0000000..f9cfcd3 --- /dev/null +++ b/.kokoro/samples/python3.8/periodic-head.cfg @@ -0,0 +1,11 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "True" +} + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/python-pubsub/.kokoro/test-samples-against-head.sh" +} diff --git a/.kokoro/test-samples-against-head.sh b/.kokoro/test-samples-against-head.sh new file mode 100755 index 0000000..97a5f49 --- /dev/null +++ b/.kokoro/test-samples-against-head.sh @@ -0,0 +1,28 @@ +#!/bin/bash +# 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 +# +# https://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. + +# A customized test runner for samples. +# +# For periodic builds, you can specify this file for testing against head. + +# `-e` enables the script to automatically fail when a command fails +# `-o pipefail` sets the exit code to the rightmost comment to exit with a non-zero +set -eo pipefail +# Enables `**` to include files nested inside sub-folders +shopt -s globstar + +cd github/python-channel + +exec .kokoro/test-samples-impl.sh diff --git a/.kokoro/test-samples-impl.sh b/.kokoro/test-samples-impl.sh new file mode 100755 index 0000000..cf5de74 --- /dev/null +++ b/.kokoro/test-samples-impl.sh @@ -0,0 +1,102 @@ +#!/bin/bash +# Copyright 2021 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 +# +# https://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. + + +# `-e` enables the script to automatically fail when a command fails +# `-o pipefail` sets the exit code to the rightmost comment to exit with a non-zero +set -eo pipefail +# Enables `**` to include files nested inside sub-folders +shopt -s globstar + +# Exit early if samples directory doesn't exist +if [ ! -d "./samples" ]; then + echo "No tests run. `./samples` not found" + exit 0 +fi + +# Disable buffering, so that the logs stream through. +export PYTHONUNBUFFERED=1 + +# Debug: show build environment +env | grep KOKORO + +# Install nox +python3.6 -m pip install --upgrade --quiet nox + +# Use secrets acessor service account to get secrets +if [[ -f "${KOKORO_GFILE_DIR}/secrets_viewer_service_account.json" ]]; then + gcloud auth activate-service-account \ + --key-file="${KOKORO_GFILE_DIR}/secrets_viewer_service_account.json" \ + --project="cloud-devrel-kokoro-resources" +fi + +# This script will create 3 files: +# - testing/test-env.sh +# - testing/service-account.json +# - testing/client-secrets.json +./scripts/decrypt-secrets.sh + +source ./testing/test-env.sh +export GOOGLE_APPLICATION_CREDENTIALS=$(pwd)/testing/service-account.json + +# For cloud-run session, we activate the service account for gcloud sdk. +gcloud auth activate-service-account \ + --key-file "${GOOGLE_APPLICATION_CREDENTIALS}" + +export GOOGLE_CLIENT_SECRETS=$(pwd)/testing/client-secrets.json + +echo -e "\n******************** TESTING PROJECTS ********************" + +# Switch to 'fail at end' to allow all tests to complete before exiting. +set +e +# Use RTN to return a non-zero value if the test fails. +RTN=0 +ROOT=$(pwd) +# Find all requirements.txt in the samples directory (may break on whitespace). +for file in samples/**/requirements.txt; do + cd "$ROOT" + # Navigate to the project folder. + file=$(dirname "$file") + cd "$file" + + echo "------------------------------------------------------------" + echo "- testing $file" + echo "------------------------------------------------------------" + + # Use nox to execute the tests for the project. + python3.6 -m nox -s "$RUN_TESTS_SESSION" + EXIT=$? + + # If this is a periodic build, send the test log to the FlakyBot. + # See https://github.com/googleapis/repo-automation-bots/tree/master/packages/flakybot. + if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"periodic"* ]]; then + chmod +x $KOKORO_GFILE_DIR/linux_amd64/flakybot + $KOKORO_GFILE_DIR/linux_amd64/flakybot + fi + + if [[ $EXIT -ne 0 ]]; then + RTN=1 + echo -e "\n Testing failed: Nox returned a non-zero exit code. \n" + else + echo -e "\n Testing completed.\n" + fi + +done +cd "$ROOT" + +# Workaround for Kokoro permissions issue: delete secrets +rm testing/{test-env.sh,client-secrets.json,service-account.json} + +exit "$RTN" diff --git a/.kokoro/test-samples.sh b/.kokoro/test-samples.sh index 9c43c66..deac97c 100755 --- a/.kokoro/test-samples.sh +++ b/.kokoro/test-samples.sh @@ -13,6 +13,10 @@ # See the License for the specific language governing permissions and # limitations under the License. +# The default test runner for samples. +# +# For periodic builds, we rewinds the repo to the latest release, and +# run test-samples-impl.sh. # `-e` enables the script to automatically fail when a command fails # `-o pipefail` sets the exit code to the rightmost comment to exit with a non-zero @@ -24,87 +28,19 @@ cd github/python-channel # Run periodic samples tests at latest release if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"periodic"* ]]; then + # preserving the test runner implementation. + cp .kokoro/test-samples-impl.sh "${TMPDIR}/test-samples-impl.sh" + echo "--- IMPORTANT IMPORTANT IMPORTANT ---" + echo "Now we rewind the repo back to the latest release..." LATEST_RELEASE=$(git describe --abbrev=0 --tags) git checkout $LATEST_RELEASE -fi - -# Exit early if samples directory doesn't exist -if [ ! -d "./samples" ]; then - echo "No tests run. `./samples` not found" - exit 0 -fi - -# Disable buffering, so that the logs stream through. -export PYTHONUNBUFFERED=1 - -# Debug: show build environment -env | grep KOKORO - -# Install nox -python3.6 -m pip install --upgrade --quiet nox - -# Use secrets acessor service account to get secrets -if [[ -f "${KOKORO_GFILE_DIR}/secrets_viewer_service_account.json" ]]; then - gcloud auth activate-service-account \ - --key-file="${KOKORO_GFILE_DIR}/secrets_viewer_service_account.json" \ - --project="cloud-devrel-kokoro-resources" -fi - -# This script will create 3 files: -# - testing/test-env.sh -# - testing/service-account.json -# - testing/client-secrets.json -./scripts/decrypt-secrets.sh - -source ./testing/test-env.sh -export GOOGLE_APPLICATION_CREDENTIALS=$(pwd)/testing/service-account.json - -# For cloud-run session, we activate the service account for gcloud sdk. -gcloud auth activate-service-account \ - --key-file "${GOOGLE_APPLICATION_CREDENTIALS}" - -export GOOGLE_CLIENT_SECRETS=$(pwd)/testing/client-secrets.json - -echo -e "\n******************** TESTING PROJECTS ********************" - -# Switch to 'fail at end' to allow all tests to complete before exiting. -set +e -# Use RTN to return a non-zero value if the test fails. -RTN=0 -ROOT=$(pwd) -# Find all requirements.txt in the samples directory (may break on whitespace). -for file in samples/**/requirements.txt; do - cd "$ROOT" - # Navigate to the project folder. - file=$(dirname "$file") - cd "$file" - - echo "------------------------------------------------------------" - echo "- testing $file" - echo "------------------------------------------------------------" - - # Use nox to execute the tests for the project. - python3.6 -m nox -s "$RUN_TESTS_SESSION" - EXIT=$? - - # If this is a periodic build, send the test log to the FlakyBot. - # See https://github.com/googleapis/repo-automation-bots/tree/master/packages/flakybot. - if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"periodic"* ]]; then - chmod +x $KOKORO_GFILE_DIR/linux_amd64/flakybot - $KOKORO_GFILE_DIR/linux_amd64/flakybot + echo "The current head is: " + echo $(git rev-parse --verify HEAD) + echo "--- IMPORTANT IMPORTANT IMPORTANT ---" + # move back the test runner implementation if there's no file. + if [ ! -f .kokoro/test-samples-impl.sh ]; then + cp "${TMPDIR}/test-samples-impl.sh" .kokoro/test-samples-impl.sh fi +fi - if [[ $EXIT -ne 0 ]]; then - RTN=1 - echo -e "\n Testing failed: Nox returned a non-zero exit code. \n" - else - echo -e "\n Testing completed.\n" - fi - -done -cd "$ROOT" - -# Workaround for Kokoro permissions issue: delete secrets -rm testing/{test-env.sh,client-secrets.json,service-account.json} - -exit "$RTN" +exec .kokoro/test-samples-impl.sh diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a9024b1..32302e4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,6 +12,6 @@ repos: hooks: - id: black - repo: https://gitlab.com/pycqa/flake8 - rev: 3.8.4 + rev: 3.9.0 hooks: - id: flake8 diff --git a/google/cloud/channel_v1/services/cloud_channel_service/async_client.py b/google/cloud/channel_v1/services/cloud_channel_service/async_client.py index cd80746..dc16a3e 100644 --- a/google/cloud/channel_v1/services/cloud_channel_service/async_client.py +++ b/google/cloud/channel_v1/services/cloud_channel_service/async_client.py @@ -127,8 +127,36 @@ class CloudChannelServiceAsyncClient: CloudChannelServiceClient.parse_common_location_path ) - from_service_account_info = CloudChannelServiceClient.from_service_account_info - from_service_account_file = CloudChannelServiceClient.from_service_account_file + @classmethod + def from_service_account_info(cls, info: dict, *args, **kwargs): + """Creates an instance of this client using the provided credentials info. + + Args: + info (dict): The service account private key info. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CloudChannelServiceAsyncClient: The constructed client. + """ + return CloudChannelServiceClient.from_service_account_info.__func__(CloudChannelServiceAsyncClient, info, *args, **kwargs) # type: ignore + + @classmethod + def from_service_account_file(cls, filename: str, *args, **kwargs): + """Creates an instance of this client using the provided credentials + file. + + Args: + filename (str): The path to the service account private key json + file. + args: Additional arguments to pass to the constructor. + kwargs: Additional arguments to pass to the constructor. + + Returns: + CloudChannelServiceAsyncClient: The constructed client. + """ + return CloudChannelServiceClient.from_service_account_file.__func__(CloudChannelServiceAsyncClient, filename, *args, **kwargs) # type: ignore + from_service_account_json = from_service_account_file @property @@ -370,14 +398,15 @@ async def check_cloud_identity_accounts_exist( - INVALID_ARGUMENT: Missing or invalid required parameters in the request. - INVALID_VALUE: Invalid domain value in the request. - - NOT_FOUND: If there is no - [CloudIdentityCustomerAccount][google.cloud.channel.v1.CloudIdentityCustomerAccount] - customer for the domain specified in the request. Return Value: List of [CloudIdentityCustomerAccount][google.cloud.channel.v1.CloudIdentityCustomerAccount] - resources if any exist for the domain, otherwise an error is - returned. + resources for the domain. List may be empty. + + Note: in the v1alpha1 version of the API, a NOT_FOUND error is + returned if no + [CloudIdentityCustomerAccount][google.cloud.channel.v1.CloudIdentityCustomerAccount] + resources match the domain. Args: request (:class:`google.cloud.channel_v1.types.CheckCloudIdentityAccountsExistRequest`): @@ -433,19 +462,13 @@ async def create_customer( Possible Error Codes: - .. raw:: html + - PERMISSION_DENIED: If the reseller account making the request + and the reseller account being queried for are different. + - INVALID_ARGUMENT: It can happen in following scenarios - - + - Missing or invalid required parameters in the request. + - Domain field value doesn't match the domain specified in + primary email. Return Value: If successful, the newly created [Customer][google.cloud.channel.v1.Customer] resource, otherwise @@ -813,20 +836,16 @@ async def list_transferable_skus( Possible Error Codes: - .. raw:: html - - + - PERMISSION_DENIED: Appears because of one of the following - + + - The customer doesn't belong to the reseller and no auth + token. + - The supplied auth token is invalid. + - The reseller account making the request and the queries + reseller account are different. + + - INVALID_ARGUMENT: Missing or invalid required parameters in + the request. Return Value: List of [TransferableSku][google.cloud.channel.v1.TransferableSku] for @@ -901,11 +920,13 @@ async def list_transferable_offers( Possible Error Codes: - - PERMISSION_DENIED, due to one of the following reasons: (a) - If the customer doesn't belong to the reseller and no auth - token or invalid auth token is supplied. (b) If the reseller - account making the request and the reseller account being - queried for are different. + - PERMISSION_DENIED: Appears because of one of the following: + + - If the customer doesn't belong to the reseller and no auth + token or invalid auth token is supplied. + - If the reseller account making the request and the + reseller account being queried for are different. + - INVALID_ARGUMENT: Missing or invalid required parameters in the request. @@ -1039,50 +1060,47 @@ async def create_entitlement( Possible Error Codes: - .. raw:: html - - + - PERMISSION_DENIED: If the customer doesn't belong to the + reseller. + - INVALID_ARGUMENT: It can happen in below scenarios - + + - Missing or invalid required parameters in the request. + - Cannot purchase an entitlement if there is already an + entitlement for customer, for a SKU from the same product + family. + - INVALID_VALUE: Offer passed in isn't valid. Make sure + OfferId is valid. If it is valid, then contact Google + Channel support for further troubleshooting. + + - NOT_FOUND: If the customer or offer resource is not found for + the reseller. + - ALREADY_EXISTS: This failure can happen in the following + cases: + + - If the SKU has been already purchased for the customer. + - If the customer's primary email already exists. In this + case retry after changing the customer's primary contact + email. + + - CONDITION_NOT_MET or FAILED_PRECONDITION: This failure can + happen in the following cases: + + - Purchasing a SKU that requires domain verification and the + domain has not been verified. + - Purchasing an Add-On SKU like Vault or Drive without + purchasing the pre-requisite SKU, such as Google Workspace + Business Starter. + - Applicable only for developer accounts: reseller and + resold domain. Must meet the following domain naming + requirements: + + - Domain names must start with goog-test. + - Resold domain names must include the reseller domain. + + - INTERNAL: Any non-user error related to a technical issue in + the backend. Contact Cloud Channel Support in this case. + - UNKNOWN: Any non-user error related to a technical issue in + the backend. Contact Cloud Channel Support in this case. Return Value: Long Running Operation ID. @@ -1784,35 +1802,36 @@ async def transfer_entitlements( Possible Error Codes: - .. raw:: html - - + - PERMISSION_DENIED: If the customer doesn't belong to the + reseller. + - INVALID_ARGUMENT: Missing or invalid required parameters in + the request. + - NOT_FOUND: If the customer or offer resource is not found for + the reseller. + - ALREADY_EXISTS: If the SKU has been already transferred for + the customer. + - CONDITION_NOT_MET or FAILED_PRECONDITION: This failure can + happen in the following cases: + + - Transferring a SKU that requires domain verification and + the domain has not been verified. + - Transferring an Add-On SKU like Vault or Drive without + transferring the pre-requisite SKU, such as G Suite Basic. + - Applicable only for developer accounts: reseller and + resold domain must follow the domain naming convention as + follows: + + - Domain names must start with goog-test. + - Resold domain names must include the reseller domain. + + - All transferring entitlements must be specified. + + - INTERNAL: Any non-user error related to a technical issue in + the backend. Please contact Cloud Channel Support in this + case. + - UNKNOWN: Any non-user error related to a technical issue in + the backend. Please contact Cloud Channel Support in this + case. Return Value: Long Running Operation ID. @@ -1885,37 +1904,34 @@ async def transfer_entitlements_to_google( Possible Error Codes: - .. raw:: html - - + - PERMISSION_DENIED: If the customer doesn't belong to the + reseller. + - INVALID_ARGUMENT: Missing or invalid required parameters in + the request. + - NOT_FOUND: If the customer or offer resource is not found for + the reseller. + - ALREADY_EXISTS: If the SKU has been already transferred for + the customer. + - CONDITION_NOT_MET or FAILED_PRECONDITION: This failure can + happen in the following cases: + + - Transferring a SKU that requires domain verification and + the domain has not been verified. + - Transferring an Add-On SKU like Vault or Drive without + purchasing the pre-requisite SKU, such as G Suite Basic. + - Applicable only for developer accounts: reseller and + resold domain must follow the domain naming convention as + follows: + + - Domain names must start with goog-test. + - Resold domain names must include the reseller domain. + + - INTERNAL: Any non-user error related to a technical issue in + the backend. Please contact Cloud Channel Support in this + case. + - UNKNOWN: Any non-user error related to a technical issue in + the backend. Please contact Cloud Channel Support in this + case. Return Value: Long Running Operation ID. @@ -2219,25 +2235,20 @@ async def update_channel_partner_link( Possible Error Codes: - .. raw:: html - - + - PERMISSION_DENIED: If the reseller account making the request + and the reseller account being queried for are different. + - INVALID_ARGUMENT: It can happen in following scenarios - + + - Missing or invalid required parameters in the request. + - Updating link state from invited to active or suspended. + - Sending reseller_cloud_identity_id, invite_url or name in + update mask. + + - NOT_FOUND: ChannelPartnerLink resource not found. + - INTERNAL: Any non-user error related to a technical issue in + the backend. In this case, contact Cloud Channel support. + - UNKNOWN: Any non-user error related to a technical issue in + the backend. In this case, contact Cloud Channel support. Return Value: If successful, the updated [ChannelPartnerLink][google.cloud.channel.v1.ChannelPartnerLink] diff --git a/google/cloud/channel_v1/services/cloud_channel_service/client.py b/google/cloud/channel_v1/services/cloud_channel_service/client.py index 0bb610f..e818cc9 100644 --- a/google/cloud/channel_v1/services/cloud_channel_service/client.py +++ b/google/cloud/channel_v1/services/cloud_channel_service/client.py @@ -611,14 +611,15 @@ def check_cloud_identity_accounts_exist( - INVALID_ARGUMENT: Missing or invalid required parameters in the request. - INVALID_VALUE: Invalid domain value in the request. - - NOT_FOUND: If there is no - [CloudIdentityCustomerAccount][google.cloud.channel.v1.CloudIdentityCustomerAccount] - customer for the domain specified in the request. Return Value: List of [CloudIdentityCustomerAccount][google.cloud.channel.v1.CloudIdentityCustomerAccount] - resources if any exist for the domain, otherwise an error is - returned. + resources for the domain. List may be empty. + + Note: in the v1alpha1 version of the API, a NOT_FOUND error is + returned if no + [CloudIdentityCustomerAccount][google.cloud.channel.v1.CloudIdentityCustomerAccount] + resources match the domain. Args: request (google.cloud.channel_v1.types.CheckCloudIdentityAccountsExistRequest): @@ -677,19 +678,13 @@ def create_customer( Possible Error Codes: - .. raw:: html + - PERMISSION_DENIED: If the reseller account making the request + and the reseller account being queried for are different. + - INVALID_ARGUMENT: It can happen in following scenarios - - + - Missing or invalid required parameters in the request. + - Domain field value doesn't match the domain specified in + primary email. Return Value: If successful, the newly created [Customer][google.cloud.channel.v1.Customer] resource, otherwise @@ -1062,20 +1057,16 @@ def list_transferable_skus( Possible Error Codes: - .. raw:: html - - + - PERMISSION_DENIED: Appears because of one of the following - + + - The customer doesn't belong to the reseller and no auth + token. + - The supplied auth token is invalid. + - The reseller account making the request and the queries + reseller account are different. + + - INVALID_ARGUMENT: Missing or invalid required parameters in + the request. Return Value: List of [TransferableSku][google.cloud.channel.v1.TransferableSku] for @@ -1151,11 +1142,13 @@ def list_transferable_offers( Possible Error Codes: - - PERMISSION_DENIED, due to one of the following reasons: (a) - If the customer doesn't belong to the reseller and no auth - token or invalid auth token is supplied. (b) If the reseller - account making the request and the reseller account being - queried for are different. + - PERMISSION_DENIED: Appears because of one of the following: + + - If the customer doesn't belong to the reseller and no auth + token or invalid auth token is supplied. + - If the reseller account making the request and the + reseller account being queried for are different. + - INVALID_ARGUMENT: Missing or invalid required parameters in the request. @@ -1291,50 +1284,47 @@ def create_entitlement( Possible Error Codes: - .. raw:: html - - + - PERMISSION_DENIED: If the customer doesn't belong to the + reseller. + - INVALID_ARGUMENT: It can happen in below scenarios - + + - Missing or invalid required parameters in the request. + - Cannot purchase an entitlement if there is already an + entitlement for customer, for a SKU from the same product + family. + - INVALID_VALUE: Offer passed in isn't valid. Make sure + OfferId is valid. If it is valid, then contact Google + Channel support for further troubleshooting. + + - NOT_FOUND: If the customer or offer resource is not found for + the reseller. + - ALREADY_EXISTS: This failure can happen in the following + cases: + + - If the SKU has been already purchased for the customer. + - If the customer's primary email already exists. In this + case retry after changing the customer's primary contact + email. + + - CONDITION_NOT_MET or FAILED_PRECONDITION: This failure can + happen in the following cases: + + - Purchasing a SKU that requires domain verification and the + domain has not been verified. + - Purchasing an Add-On SKU like Vault or Drive without + purchasing the pre-requisite SKU, such as Google Workspace + Business Starter. + - Applicable only for developer accounts: reseller and + resold domain. Must meet the following domain naming + requirements: + + - Domain names must start with goog-test. + - Resold domain names must include the reseller domain. + + - INTERNAL: Any non-user error related to a technical issue in + the backend. Contact Cloud Channel Support in this case. + - UNKNOWN: Any non-user error related to a technical issue in + the backend. Contact Cloud Channel Support in this case. Return Value: Long Running Operation ID. @@ -2044,35 +2034,36 @@ def transfer_entitlements( Possible Error Codes: - .. raw:: html - - + - PERMISSION_DENIED: If the customer doesn't belong to the + reseller. + - INVALID_ARGUMENT: Missing or invalid required parameters in + the request. + - NOT_FOUND: If the customer or offer resource is not found for + the reseller. + - ALREADY_EXISTS: If the SKU has been already transferred for + the customer. + - CONDITION_NOT_MET or FAILED_PRECONDITION: This failure can + happen in the following cases: + + - Transferring a SKU that requires domain verification and + the domain has not been verified. + - Transferring an Add-On SKU like Vault or Drive without + transferring the pre-requisite SKU, such as G Suite Basic. + - Applicable only for developer accounts: reseller and + resold domain must follow the domain naming convention as + follows: + + - Domain names must start with goog-test. + - Resold domain names must include the reseller domain. + + - All transferring entitlements must be specified. + + - INTERNAL: Any non-user error related to a technical issue in + the backend. Please contact Cloud Channel Support in this + case. + - UNKNOWN: Any non-user error related to a technical issue in + the backend. Please contact Cloud Channel Support in this + case. Return Value: Long Running Operation ID. @@ -2146,37 +2137,34 @@ def transfer_entitlements_to_google( Possible Error Codes: - .. raw:: html - - + - PERMISSION_DENIED: If the customer doesn't belong to the + reseller. + - INVALID_ARGUMENT: Missing or invalid required parameters in + the request. + - NOT_FOUND: If the customer or offer resource is not found for + the reseller. + - ALREADY_EXISTS: If the SKU has been already transferred for + the customer. + - CONDITION_NOT_MET or FAILED_PRECONDITION: This failure can + happen in the following cases: + + - Transferring a SKU that requires domain verification and + the domain has not been verified. + - Transferring an Add-On SKU like Vault or Drive without + purchasing the pre-requisite SKU, such as G Suite Basic. + - Applicable only for developer accounts: reseller and + resold domain must follow the domain naming convention as + follows: + + - Domain names must start with goog-test. + - Resold domain names must include the reseller domain. + + - INTERNAL: Any non-user error related to a technical issue in + the backend. Please contact Cloud Channel Support in this + case. + - UNKNOWN: Any non-user error related to a technical issue in + the backend. Please contact Cloud Channel Support in this + case. Return Value: Long Running Operation ID. @@ -2490,25 +2478,20 @@ def update_channel_partner_link( Possible Error Codes: - .. raw:: html - - + - PERMISSION_DENIED: If the reseller account making the request + and the reseller account being queried for are different. + - INVALID_ARGUMENT: It can happen in following scenarios - + + - Missing or invalid required parameters in the request. + - Updating link state from invited to active or suspended. + - Sending reseller_cloud_identity_id, invite_url or name in + update mask. + + - NOT_FOUND: ChannelPartnerLink resource not found. + - INTERNAL: Any non-user error related to a technical issue in + the backend. In this case, contact Cloud Channel support. + - UNKNOWN: Any non-user error related to a technical issue in + the backend. In this case, contact Cloud Channel support. Return Value: If successful, the updated [ChannelPartnerLink][google.cloud.channel.v1.ChannelPartnerLink] diff --git a/google/cloud/channel_v1/services/cloud_channel_service/transports/base.py b/google/cloud/channel_v1/services/cloud_channel_service/transports/base.py index 638837c..eb5e22c 100644 --- a/google/cloud/channel_v1/services/cloud_channel_service/transports/base.py +++ b/google/cloud/channel_v1/services/cloud_channel_service/transports/base.py @@ -73,10 +73,10 @@ def __init__( scope (Optional[Sequence[str]]): A list of scopes. quota_project_id (Optional[str]): An optional project to use for billing and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. """ # Save the hostname. Default to port 443 (HTTPS) if none is specified. @@ -84,6 +84,9 @@ def __init__( host += ":443" self._host = host + # Save the scopes. + self._scopes = scopes or self.AUTH_SCOPES + # If no credentials are provided, then determine the appropriate # defaults. if credentials and credentials_file: @@ -93,20 +96,17 @@ def __init__( if credentials_file is not None: credentials, _ = auth.load_credentials_from_file( - credentials_file, scopes=scopes, quota_project_id=quota_project_id + credentials_file, scopes=self._scopes, quota_project_id=quota_project_id ) elif credentials is None: credentials, _ = auth.default( - scopes=scopes, quota_project_id=quota_project_id + scopes=self._scopes, quota_project_id=quota_project_id ) # Save the credentials. self._credentials = credentials - # Lifted into its own function so it can be stubbed out during tests. - self._prep_wrapped_messages(client_info) - def _prep_wrapped_messages(self, client_info): # Precompute the wrapped methods. self._wrapped_methods = { diff --git a/google/cloud/channel_v1/services/cloud_channel_service/transports/grpc.py b/google/cloud/channel_v1/services/cloud_channel_service/transports/grpc.py index 7ef0a39..34e8a20 100644 --- a/google/cloud/channel_v1/services/cloud_channel_service/transports/grpc.py +++ b/google/cloud/channel_v1/services/cloud_channel_service/transports/grpc.py @@ -140,7 +140,10 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._grpc_channel = None self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client = None if api_mtls_endpoint: warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) @@ -148,70 +151,50 @@ def __init__( warnings.warn("client_cert_source is deprecated", DeprecationWarning) if channel: - # Sanity check: Ensure that channel and credentials are not both - # provided. + # Ignore credentials if a channel was passed. credentials = False - # If a channel was explicitly provided, set it. self._grpc_channel = channel self._ssl_channel_credentials = None - elif api_mtls_endpoint: - host = ( - api_mtls_endpoint - if ":" in api_mtls_endpoint - else api_mtls_endpoint + ":443" - ) - - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - - # 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, - credentials_file=credentials_file, - ssl_credentials=ssl_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - self._ssl_channel_credentials = ssl_credentials else: - host = host if ":" in host else host + ":443" + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + ) - # create a new channel. The provided one is ignored. + if not self._grpc_channel: self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, + self._host, + credentials=self._credentials, credentials_file=credentials_file, + scopes=self._scopes, ssl_credentials=self._ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, options=[ ("grpc.max_send_message_length", -1), @@ -219,18 +202,8 @@ def __init__( ], ) - self._stubs = {} # type: Dict[str, Callable] - self._operations_client = None - - # Run the base constructor. - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - client_info=client_info, - ) + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) @classmethod def create_channel( @@ -244,7 +217,7 @@ def create_channel( ) -> grpc.Channel: """Create and return a gRPC channel object. Args: - address (Optional[str]): The host for the channel to use. + host (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 @@ -394,14 +367,15 @@ def check_cloud_identity_accounts_exist( - INVALID_ARGUMENT: Missing or invalid required parameters in the request. - INVALID_VALUE: Invalid domain value in the request. - - NOT_FOUND: If there is no - [CloudIdentityCustomerAccount][google.cloud.channel.v1.CloudIdentityCustomerAccount] - customer for the domain specified in the request. Return Value: List of [CloudIdentityCustomerAccount][google.cloud.channel.v1.CloudIdentityCustomerAccount] - resources if any exist for the domain, otherwise an error is - returned. + resources for the domain. List may be empty. + + Note: in the v1alpha1 version of the API, a NOT_FOUND error is + returned if no + [CloudIdentityCustomerAccount][google.cloud.channel.v1.CloudIdentityCustomerAccount] + resources match the domain. Returns: Callable[[~.CheckCloudIdentityAccountsExistRequest], @@ -434,19 +408,13 @@ def create_customer( Possible Error Codes: - .. raw:: html + - PERMISSION_DENIED: If the reseller account making the request + and the reseller account being queried for are different. + - INVALID_ARGUMENT: It can happen in following scenarios - - + - Missing or invalid required parameters in the request. + - Domain field value doesn't match the domain specified in + primary email. Return Value: If successful, the newly created [Customer][google.cloud.channel.v1.Customer] resource, otherwise @@ -652,20 +620,16 @@ def list_transferable_skus( Possible Error Codes: - .. raw:: html - - + - PERMISSION_DENIED: Appears because of one of the following - + + - The customer doesn't belong to the reseller and no auth + token. + - The supplied auth token is invalid. + - The reseller account making the request and the queries + reseller account are different. + + - INVALID_ARGUMENT: Missing or invalid required parameters in + the request. Return Value: List of [TransferableSku][google.cloud.channel.v1.TransferableSku] for @@ -708,11 +672,13 @@ def list_transferable_offers( Possible Error Codes: - - PERMISSION_DENIED, due to one of the following reasons: (a) - If the customer doesn't belong to the reseller and no auth - token or invalid auth token is supplied. (b) If the reseller - account making the request and the reseller account being - queried for are different. + - PERMISSION_DENIED: Appears because of one of the following: + + - If the customer doesn't belong to the reseller and no auth + token or invalid auth token is supplied. + - If the reseller account making the request and the + reseller account being queried for are different. + - INVALID_ARGUMENT: Missing or invalid required parameters in the request. @@ -787,50 +753,47 @@ def create_entitlement( Possible Error Codes: - .. raw:: html - - + - PERMISSION_DENIED: If the customer doesn't belong to the + reseller. + - INVALID_ARGUMENT: It can happen in below scenarios - + + - Missing or invalid required parameters in the request. + - Cannot purchase an entitlement if there is already an + entitlement for customer, for a SKU from the same product + family. + - INVALID_VALUE: Offer passed in isn't valid. Make sure + OfferId is valid. If it is valid, then contact Google + Channel support for further troubleshooting. + + - NOT_FOUND: If the customer or offer resource is not found for + the reseller. + - ALREADY_EXISTS: This failure can happen in the following + cases: + + - If the SKU has been already purchased for the customer. + - If the customer's primary email already exists. In this + case retry after changing the customer's primary contact + email. + + - CONDITION_NOT_MET or FAILED_PRECONDITION: This failure can + happen in the following cases: + + - Purchasing a SKU that requires domain verification and the + domain has not been verified. + - Purchasing an Add-On SKU like Vault or Drive without + purchasing the pre-requisite SKU, such as Google Workspace + Business Starter. + - Applicable only for developer accounts: reseller and + resold domain. Must meet the following domain naming + requirements: + + - Domain names must start with goog-test. + - Resold domain names must include the reseller domain. + + - INTERNAL: Any non-user error related to a technical issue in + the backend. Contact Cloud Channel Support in this case. + - UNKNOWN: Any non-user error related to a technical issue in + the backend. Contact Cloud Channel Support in this case. Return Value: Long Running Operation ID. @@ -1227,35 +1190,36 @@ def transfer_entitlements( Possible Error Codes: - .. raw:: html - - + - PERMISSION_DENIED: If the customer doesn't belong to the + reseller. + - INVALID_ARGUMENT: Missing or invalid required parameters in + the request. + - NOT_FOUND: If the customer or offer resource is not found for + the reseller. + - ALREADY_EXISTS: If the SKU has been already transferred for + the customer. + - CONDITION_NOT_MET or FAILED_PRECONDITION: This failure can + happen in the following cases: + + - Transferring a SKU that requires domain verification and + the domain has not been verified. + - Transferring an Add-On SKU like Vault or Drive without + transferring the pre-requisite SKU, such as G Suite Basic. + - Applicable only for developer accounts: reseller and + resold domain must follow the domain naming convention as + follows: + + - Domain names must start with goog-test. + - Resold domain names must include the reseller domain. + + - All transferring entitlements must be specified. + + - INTERNAL: Any non-user error related to a technical issue in + the backend. Please contact Cloud Channel Support in this + case. + - UNKNOWN: Any non-user error related to a technical issue in + the backend. Please contact Cloud Channel Support in this + case. Return Value: Long Running Operation ID. @@ -1293,37 +1257,34 @@ def transfer_entitlements_to_google( Possible Error Codes: - .. raw:: html - - + - PERMISSION_DENIED: If the customer doesn't belong to the + reseller. + - INVALID_ARGUMENT: Missing or invalid required parameters in + the request. + - NOT_FOUND: If the customer or offer resource is not found for + the reseller. + - ALREADY_EXISTS: If the SKU has been already transferred for + the customer. + - CONDITION_NOT_MET or FAILED_PRECONDITION: This failure can + happen in the following cases: + + - Transferring a SKU that requires domain verification and + the domain has not been verified. + - Transferring an Add-On SKU like Vault or Drive without + purchasing the pre-requisite SKU, such as G Suite Basic. + - Applicable only for developer accounts: reseller and + resold domain must follow the domain naming convention as + follows: + + - Domain names must start with goog-test. + - Resold domain names must include the reseller domain. + + - INTERNAL: Any non-user error related to a technical issue in + the backend. Please contact Cloud Channel Support in this + case. + - UNKNOWN: Any non-user error related to a technical issue in + the backend. Please contact Cloud Channel Support in this + case. Return Value: Long Running Operation ID. @@ -1508,25 +1469,20 @@ def update_channel_partner_link( Possible Error Codes: - .. raw:: html - - + - PERMISSION_DENIED: If the reseller account making the request + and the reseller account being queried for are different. + - INVALID_ARGUMENT: It can happen in following scenarios - + + - Missing or invalid required parameters in the request. + - Updating link state from invited to active or suspended. + - Sending reseller_cloud_identity_id, invite_url or name in + update mask. + + - NOT_FOUND: ChannelPartnerLink resource not found. + - INTERNAL: Any non-user error related to a technical issue in + the backend. In this case, contact Cloud Channel support. + - UNKNOWN: Any non-user error related to a technical issue in + the backend. In this case, contact Cloud Channel support. Return Value: If successful, the updated [ChannelPartnerLink][google.cloud.channel.v1.ChannelPartnerLink] diff --git a/google/cloud/channel_v1/services/cloud_channel_service/transports/grpc_asyncio.py b/google/cloud/channel_v1/services/cloud_channel_service/transports/grpc_asyncio.py index 51b6913..b086617 100644 --- a/google/cloud/channel_v1/services/cloud_channel_service/transports/grpc_asyncio.py +++ b/google/cloud/channel_v1/services/cloud_channel_service/transports/grpc_asyncio.py @@ -95,7 +95,7 @@ def create_channel( ) -> aio.Channel: """Create and return a gRPC AsyncIO channel object. Args: - address (Optional[str]): The host for the channel to use. + host (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 @@ -173,10 +173,10 @@ def __init__( ignored if ``channel`` or ``ssl_channel_credentials`` is provided. quota_project_id (Optional[str]): An optional project to use for billing and quota. - client_info (google.api_core.gapic_v1.client_info.ClientInfo): - The client info used to send a user-agent string along with - API requests. If ``None``, then default info will be used. - Generally, you only need to set this if you're developing + client_info (google.api_core.gapic_v1.client_info.ClientInfo): + The client info used to send a user-agent string along with + API requests. If ``None``, then default info will be used. + Generally, you only need to set this if you're developing your own client library. Raises: @@ -185,7 +185,10 @@ def __init__( google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` and ``credentials_file`` are passed. """ + self._grpc_channel = None self._ssl_channel_credentials = ssl_channel_credentials + self._stubs: Dict[str, Callable] = {} + self._operations_client = None if api_mtls_endpoint: warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) @@ -193,70 +196,50 @@ def __init__( warnings.warn("client_cert_source is deprecated", DeprecationWarning) if channel: - # Sanity check: Ensure that channel and credentials are not both - # provided. + # Ignore credentials if a channel was passed. credentials = False - # If a channel was explicitly provided, set it. self._grpc_channel = channel self._ssl_channel_credentials = None - elif api_mtls_endpoint: - host = ( - api_mtls_endpoint - if ":" in api_mtls_endpoint - else api_mtls_endpoint + ":443" - ) - - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) - - # 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, - credentials_file=credentials_file, - ssl_credentials=ssl_credentials, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - options=[ - ("grpc.max_send_message_length", -1), - ("grpc.max_receive_message_length", -1), - ], - ) - self._ssl_channel_credentials = ssl_credentials else: - host = host if ":" in host else host + ":443" + if api_mtls_endpoint: + host = api_mtls_endpoint + + # Create SSL credentials with client_cert_source or application + # default SSL credentials. + if client_cert_source: + cert, key = client_cert_source() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) + else: + self._ssl_channel_credentials = SslCredentials().ssl_credentials - if credentials is None: - credentials, _ = auth.default( - scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id - ) + else: + if client_cert_source_for_mtls and not ssl_channel_credentials: + cert, key = client_cert_source_for_mtls() + self._ssl_channel_credentials = grpc.ssl_channel_credentials( + certificate_chain=cert, private_key=key + ) - if client_cert_source_for_mtls and not ssl_channel_credentials: - cert, key = client_cert_source_for_mtls() - self._ssl_channel_credentials = grpc.ssl_channel_credentials( - certificate_chain=cert, private_key=key - ) + # The base transport sets the host, credentials and scopes + super().__init__( + host=host, + credentials=credentials, + credentials_file=credentials_file, + scopes=scopes, + quota_project_id=quota_project_id, + client_info=client_info, + ) - # create a new channel. The provided one is ignored. + if not self._grpc_channel: self._grpc_channel = type(self).create_channel( - host, - credentials=credentials, + self._host, + credentials=self._credentials, credentials_file=credentials_file, + scopes=self._scopes, ssl_credentials=self._ssl_channel_credentials, - scopes=scopes or self.AUTH_SCOPES, quota_project_id=quota_project_id, options=[ ("grpc.max_send_message_length", -1), @@ -264,18 +247,8 @@ def __init__( ], ) - # Run the base constructor. - super().__init__( - host=host, - credentials=credentials, - credentials_file=credentials_file, - scopes=scopes or self.AUTH_SCOPES, - quota_project_id=quota_project_id, - client_info=client_info, - ) - - self._stubs = {} - self._operations_client = None + # Wrap messages. This must be done after self._grpc_channel exists + self._prep_wrapped_messages(client_info) @property def grpc_channel(self) -> aio.Channel: @@ -402,14 +375,15 @@ def check_cloud_identity_accounts_exist( - INVALID_ARGUMENT: Missing or invalid required parameters in the request. - INVALID_VALUE: Invalid domain value in the request. - - NOT_FOUND: If there is no - [CloudIdentityCustomerAccount][google.cloud.channel.v1.CloudIdentityCustomerAccount] - customer for the domain specified in the request. Return Value: List of [CloudIdentityCustomerAccount][google.cloud.channel.v1.CloudIdentityCustomerAccount] - resources if any exist for the domain, otherwise an error is - returned. + resources for the domain. List may be empty. + + Note: in the v1alpha1 version of the API, a NOT_FOUND error is + returned if no + [CloudIdentityCustomerAccount][google.cloud.channel.v1.CloudIdentityCustomerAccount] + resources match the domain. Returns: Callable[[~.CheckCloudIdentityAccountsExistRequest], @@ -442,19 +416,13 @@ def create_customer( Possible Error Codes: - .. raw:: html + - PERMISSION_DENIED: If the reseller account making the request + and the reseller account being queried for are different. + - INVALID_ARGUMENT: It can happen in following scenarios - - + - Missing or invalid required parameters in the request. + - Domain field value doesn't match the domain specified in + primary email. Return Value: If successful, the newly created [Customer][google.cloud.channel.v1.Customer] resource, otherwise @@ -667,20 +635,16 @@ def list_transferable_skus( Possible Error Codes: - .. raw:: html - - + - PERMISSION_DENIED: Appears because of one of the following - + + - The customer doesn't belong to the reseller and no auth + token. + - The supplied auth token is invalid. + - The reseller account making the request and the queries + reseller account are different. + + - INVALID_ARGUMENT: Missing or invalid required parameters in + the request. Return Value: List of [TransferableSku][google.cloud.channel.v1.TransferableSku] for @@ -724,11 +688,13 @@ def list_transferable_offers( Possible Error Codes: - - PERMISSION_DENIED, due to one of the following reasons: (a) - If the customer doesn't belong to the reseller and no auth - token or invalid auth token is supplied. (b) If the reseller - account making the request and the reseller account being - queried for are different. + - PERMISSION_DENIED: Appears because of one of the following: + + - If the customer doesn't belong to the reseller and no auth + token or invalid auth token is supplied. + - If the reseller account making the request and the + reseller account being queried for are different. + - INVALID_ARGUMENT: Missing or invalid required parameters in the request. @@ -803,50 +769,47 @@ def create_entitlement( Possible Error Codes: - .. raw:: html - - + - PERMISSION_DENIED: If the customer doesn't belong to the + reseller. + - INVALID_ARGUMENT: It can happen in below scenarios - + + - Missing or invalid required parameters in the request. + - Cannot purchase an entitlement if there is already an + entitlement for customer, for a SKU from the same product + family. + - INVALID_VALUE: Offer passed in isn't valid. Make sure + OfferId is valid. If it is valid, then contact Google + Channel support for further troubleshooting. + + - NOT_FOUND: If the customer or offer resource is not found for + the reseller. + - ALREADY_EXISTS: This failure can happen in the following + cases: + + - If the SKU has been already purchased for the customer. + - If the customer's primary email already exists. In this + case retry after changing the customer's primary contact + email. + + - CONDITION_NOT_MET or FAILED_PRECONDITION: This failure can + happen in the following cases: + + - Purchasing a SKU that requires domain verification and the + domain has not been verified. + - Purchasing an Add-On SKU like Vault or Drive without + purchasing the pre-requisite SKU, such as Google Workspace + Business Starter. + - Applicable only for developer accounts: reseller and + resold domain. Must meet the following domain naming + requirements: + + - Domain names must start with goog-test. + - Resold domain names must include the reseller domain. + + - INTERNAL: Any non-user error related to a technical issue in + the backend. Contact Cloud Channel Support in this case. + - UNKNOWN: Any non-user error related to a technical issue in + the backend. Contact Cloud Channel Support in this case. Return Value: Long Running Operation ID. @@ -1249,35 +1212,36 @@ def transfer_entitlements( Possible Error Codes: - .. raw:: html - - + - PERMISSION_DENIED: If the customer doesn't belong to the + reseller. + - INVALID_ARGUMENT: Missing or invalid required parameters in + the request. + - NOT_FOUND: If the customer or offer resource is not found for + the reseller. + - ALREADY_EXISTS: If the SKU has been already transferred for + the customer. + - CONDITION_NOT_MET or FAILED_PRECONDITION: This failure can + happen in the following cases: + + - Transferring a SKU that requires domain verification and + the domain has not been verified. + - Transferring an Add-On SKU like Vault or Drive without + transferring the pre-requisite SKU, such as G Suite Basic. + - Applicable only for developer accounts: reseller and + resold domain must follow the domain naming convention as + follows: + + - Domain names must start with goog-test. + - Resold domain names must include the reseller domain. + + - All transferring entitlements must be specified. + + - INTERNAL: Any non-user error related to a technical issue in + the backend. Please contact Cloud Channel Support in this + case. + - UNKNOWN: Any non-user error related to a technical issue in + the backend. Please contact Cloud Channel Support in this + case. Return Value: Long Running Operation ID. @@ -1317,37 +1281,34 @@ def transfer_entitlements_to_google( Possible Error Codes: - .. raw:: html - - + - PERMISSION_DENIED: If the customer doesn't belong to the + reseller. + - INVALID_ARGUMENT: Missing or invalid required parameters in + the request. + - NOT_FOUND: If the customer or offer resource is not found for + the reseller. + - ALREADY_EXISTS: If the SKU has been already transferred for + the customer. + - CONDITION_NOT_MET or FAILED_PRECONDITION: This failure can + happen in the following cases: + + - Transferring a SKU that requires domain verification and + the domain has not been verified. + - Transferring an Add-On SKU like Vault or Drive without + purchasing the pre-requisite SKU, such as G Suite Basic. + - Applicable only for developer accounts: reseller and + resold domain must follow the domain naming convention as + follows: + + - Domain names must start with goog-test. + - Resold domain names must include the reseller domain. + + - INTERNAL: Any non-user error related to a technical issue in + the backend. Please contact Cloud Channel Support in this + case. + - UNKNOWN: Any non-user error related to a technical issue in + the backend. Please contact Cloud Channel Support in this + case. Return Value: Long Running Operation ID. @@ -1533,25 +1494,20 @@ def update_channel_partner_link( Possible Error Codes: - .. raw:: html - - + - PERMISSION_DENIED: If the reseller account making the request + and the reseller account being queried for are different. + - INVALID_ARGUMENT: It can happen in following scenarios - + + - Missing or invalid required parameters in the request. + - Updating link state from invited to active or suspended. + - Sending reseller_cloud_identity_id, invite_url or name in + update mask. + + - NOT_FOUND: ChannelPartnerLink resource not found. + - INTERNAL: Any non-user error related to a technical issue in + the backend. In this case, contact Cloud Channel support. + - UNKNOWN: Any non-user error related to a technical issue in + the backend. In this case, contact Cloud Channel support. Return Value: If successful, the updated [ChannelPartnerLink][google.cloud.channel.v1.ChannelPartnerLink] diff --git a/google/cloud/channel_v1/types/__init__.py b/google/cloud/channel_v1/types/__init__.py index 3acdc3a..e0de3c6 100644 --- a/google/cloud/channel_v1/types/__init__.py +++ b/google/cloud/channel_v1/types/__init__.py @@ -15,110 +15,110 @@ # limitations under the License. # -from .common import ( - EduData, - CloudIdentityInfo, - Value, - AdminUser, -) from .channel_partner_links import ( ChannelPartnerLink, - ChannelPartnerLinkView, ChannelPartnerLinkState, + ChannelPartnerLinkView, +) +from .common import ( + AdminUser, + CloudIdentityInfo, + EduData, + Value, ) from .customers import ( - Customer, ContactInfo, + Customer, ) -from .products import ( - Product, - Sku, - MarketingInfo, - Media, - MediaType, +from .entitlements import ( + AssociationInfo, + CommitmentSettings, + Entitlement, + Parameter, + ProvisionedService, + RenewalSettings, + TransferableSku, + TransferEligibility, + TrialSettings, ) from .offers import ( - Offer, - ParameterDefinition, Constraints, CustomerConstraints, + Offer, + ParameterDefinition, + Period, Plan, - PriceByResource, Price, + PriceByResource, PricePhase, PriceTier, - Period, - PromotionalOrderType, PaymentPlan, PaymentType, - ResourceType, PeriodType, -) -from .entitlements import ( - Entitlement, - Parameter, - AssociationInfo, - ProvisionedService, - CommitmentSettings, - RenewalSettings, - TrialSettings, - TransferableSku, - TransferEligibility, + PromotionalOrderType, + ResourceType, ) from .operations import OperationMetadata +from .products import ( + MarketingInfo, + Media, + Product, + Sku, + MediaType, +) from .service import ( + ActivateEntitlementRequest, + CancelEntitlementRequest, + ChangeOfferRequest, + ChangeParametersRequest, + ChangeRenewalSettingsRequest, CheckCloudIdentityAccountsExistRequest, - CloudIdentityCustomerAccount, CheckCloudIdentityAccountsExistResponse, - ListCustomersRequest, - ListCustomersResponse, - GetCustomerRequest, + CloudIdentityCustomerAccount, + CreateChannelPartnerLinkRequest, CreateCustomerRequest, - UpdateCustomerRequest, + CreateEntitlementRequest, DeleteCustomerRequest, - ProvisionCloudIdentityRequest, - ListEntitlementsRequest, - ListEntitlementsResponse, - ListTransferableSkusRequest, - ListTransferableSkusResponse, - ListTransferableOffersRequest, - ListTransferableOffersResponse, - TransferableOffer, + GetChannelPartnerLinkRequest, + GetCustomerRequest, GetEntitlementRequest, ListChannelPartnerLinksRequest, ListChannelPartnerLinksResponse, - GetChannelPartnerLinkRequest, - CreateChannelPartnerLinkRequest, - UpdateChannelPartnerLinkRequest, - CreateEntitlementRequest, - TransferEntitlementsRequest, - TransferEntitlementsResponse, - TransferEntitlementsToGoogleRequest, - ChangeParametersRequest, - ChangeRenewalSettingsRequest, - ChangeOfferRequest, - StartPaidServiceRequest, - CancelEntitlementRequest, - SuspendEntitlementRequest, - ActivateEntitlementRequest, - ListProductsRequest, - ListProductsResponse, - ListSkusRequest, - ListSkusResponse, + ListCustomersRequest, + ListCustomersResponse, + ListEntitlementsRequest, + ListEntitlementsResponse, ListOffersRequest, ListOffersResponse, - ListPurchasableSkusRequest, - ListPurchasableSkusResponse, - PurchasableSku, + ListProductsRequest, + ListProductsResponse, ListPurchasableOffersRequest, ListPurchasableOffersResponse, + ListPurchasableSkusRequest, + ListPurchasableSkusResponse, + ListSkusRequest, + ListSkusResponse, + ListSubscribersRequest, + ListSubscribersResponse, + ListTransferableOffersRequest, + ListTransferableOffersResponse, + ListTransferableSkusRequest, + ListTransferableSkusResponse, + ProvisionCloudIdentityRequest, PurchasableOffer, + PurchasableSku, RegisterSubscriberRequest, RegisterSubscriberResponse, + StartPaidServiceRequest, + SuspendEntitlementRequest, + TransferableOffer, + TransferEntitlementsRequest, + TransferEntitlementsResponse, + TransferEntitlementsToGoogleRequest, UnregisterSubscriberRequest, UnregisterSubscriberResponse, - ListSubscribersRequest, - ListSubscribersResponse, + UpdateChannelPartnerLinkRequest, + UpdateCustomerRequest, ) from .subscriber_event import ( CustomerEvent, @@ -127,97 +127,97 @@ ) __all__ = ( - "EduData", - "CloudIdentityInfo", - "Value", - "AdminUser", "ChannelPartnerLink", - "ChannelPartnerLinkView", "ChannelPartnerLinkState", - "Customer", + "ChannelPartnerLinkView", + "AdminUser", + "CloudIdentityInfo", + "EduData", + "Value", "ContactInfo", - "Product", - "Sku", - "MarketingInfo", - "Media", - "MediaType", - "Offer", - "ParameterDefinition", + "Customer", + "AssociationInfo", + "CommitmentSettings", + "Entitlement", + "Parameter", + "ProvisionedService", + "RenewalSettings", + "TransferableSku", + "TransferEligibility", + "TrialSettings", "Constraints", "CustomerConstraints", + "Offer", + "ParameterDefinition", + "Period", "Plan", - "PriceByResource", "Price", + "PriceByResource", "PricePhase", "PriceTier", - "Period", - "PromotionalOrderType", "PaymentPlan", "PaymentType", - "ResourceType", "PeriodType", - "Entitlement", - "Parameter", - "AssociationInfo", - "ProvisionedService", - "CommitmentSettings", - "RenewalSettings", - "TrialSettings", - "TransferableSku", - "TransferEligibility", + "PromotionalOrderType", + "ResourceType", "OperationMetadata", + "MarketingInfo", + "Media", + "Product", + "Sku", + "MediaType", + "ActivateEntitlementRequest", + "CancelEntitlementRequest", + "ChangeOfferRequest", + "ChangeParametersRequest", + "ChangeRenewalSettingsRequest", "CheckCloudIdentityAccountsExistRequest", - "CloudIdentityCustomerAccount", "CheckCloudIdentityAccountsExistResponse", - "ListCustomersRequest", - "ListCustomersResponse", - "GetCustomerRequest", + "CloudIdentityCustomerAccount", + "CreateChannelPartnerLinkRequest", "CreateCustomerRequest", - "UpdateCustomerRequest", + "CreateEntitlementRequest", "DeleteCustomerRequest", - "ProvisionCloudIdentityRequest", - "ListEntitlementsRequest", - "ListEntitlementsResponse", - "ListTransferableSkusRequest", - "ListTransferableSkusResponse", - "ListTransferableOffersRequest", - "ListTransferableOffersResponse", - "TransferableOffer", + "GetChannelPartnerLinkRequest", + "GetCustomerRequest", "GetEntitlementRequest", "ListChannelPartnerLinksRequest", "ListChannelPartnerLinksResponse", - "GetChannelPartnerLinkRequest", - "CreateChannelPartnerLinkRequest", - "UpdateChannelPartnerLinkRequest", - "CreateEntitlementRequest", - "TransferEntitlementsRequest", - "TransferEntitlementsResponse", - "TransferEntitlementsToGoogleRequest", - "ChangeParametersRequest", - "ChangeRenewalSettingsRequest", - "ChangeOfferRequest", - "StartPaidServiceRequest", - "CancelEntitlementRequest", - "SuspendEntitlementRequest", - "ActivateEntitlementRequest", - "ListProductsRequest", - "ListProductsResponse", - "ListSkusRequest", - "ListSkusResponse", + "ListCustomersRequest", + "ListCustomersResponse", + "ListEntitlementsRequest", + "ListEntitlementsResponse", "ListOffersRequest", "ListOffersResponse", - "ListPurchasableSkusRequest", - "ListPurchasableSkusResponse", - "PurchasableSku", + "ListProductsRequest", + "ListProductsResponse", "ListPurchasableOffersRequest", "ListPurchasableOffersResponse", + "ListPurchasableSkusRequest", + "ListPurchasableSkusResponse", + "ListSkusRequest", + "ListSkusResponse", + "ListSubscribersRequest", + "ListSubscribersResponse", + "ListTransferableOffersRequest", + "ListTransferableOffersResponse", + "ListTransferableSkusRequest", + "ListTransferableSkusResponse", + "ProvisionCloudIdentityRequest", "PurchasableOffer", + "PurchasableSku", "RegisterSubscriberRequest", "RegisterSubscriberResponse", + "StartPaidServiceRequest", + "SuspendEntitlementRequest", + "TransferableOffer", + "TransferEntitlementsRequest", + "TransferEntitlementsResponse", + "TransferEntitlementsToGoogleRequest", "UnregisterSubscriberRequest", "UnregisterSubscriberResponse", - "ListSubscribersRequest", - "ListSubscribersResponse", + "UpdateChannelPartnerLinkRequest", + "UpdateCustomerRequest", "CustomerEvent", "EntitlementEvent", "SubscriberEvent", diff --git a/google/cloud/channel_v1/types/customers.py b/google/cloud/channel_v1/types/customers.py index 0568feb..c788211 100644 --- a/google/cloud/channel_v1/types/customers.py +++ b/google/cloud/channel_v1/types/customers.py @@ -41,7 +41,8 @@ class Customer(proto.Message): org_postal_address (google.type.postal_address_pb2.PostalAddress): Required. Address of the organization of the customer entity. Region and zip codes are - required to enforce US laws and embargoes. + required to enforce US laws and embargoes. Valid + address lines are required for all customers. Language code is discarded. Use the Customer- level language code to set the customer's language. diff --git a/google/cloud/channel_v1/types/entitlements.py b/google/cloud/channel_v1/types/entitlements.py index ffd6999..0099224 100644 --- a/google/cloud/channel_v1/types/entitlements.py +++ b/google/cloud/channel_v1/types/entitlements.py @@ -22,7 +22,6 @@ from google.cloud.channel_v1.types import offers from google.cloud.channel_v1.types import products from google.protobuf import timestamp_pb2 as timestamp # type: ignore -from google.protobuf import wrappers_pb2 as wrappers # type: ignore __protobuf__ = proto.module( @@ -270,11 +269,6 @@ class TransferableSku(proto.Message): not own. Read-only. Attributes: - is_commitment (google.protobuf.wrappers_pb2.BoolValue): - Whether a transferable SKU is commitment- - ased or not. - commitment_end_timestamp (google.protobuf.timestamp_pb2.Timestamp): - Commitment end timestamp. transfer_eligibility (google.cloud.channel_v1.types.TransferEligibility): Describes the transfer eligibility of a SKU. sku (google.cloud.channel_v1.types.Sku): @@ -282,12 +276,6 @@ class TransferableSku(proto.Message): resource as specified in the Offer. """ - is_commitment = proto.Field(proto.MESSAGE, number=6, message=wrappers.BoolValue,) - - commitment_end_timestamp = proto.Field( - proto.MESSAGE, number=7, message=timestamp.Timestamp, - ) - transfer_eligibility = proto.Field( proto.MESSAGE, number=9, message="TransferEligibility", ) diff --git a/google/cloud/channel_v1/types/offers.py b/google/cloud/channel_v1/types/offers.py index 0aa8b91..8685084 100644 --- a/google/cloud/channel_v1/types/offers.py +++ b/google/cloud/channel_v1/types/offers.py @@ -259,6 +259,10 @@ class Plan(proto.Message): regular pricing goes into effect when trial period ends, or if paid service is started before the end of the trial period. + billing_account (str): + Reseller Billing account to charge after an + offer transaction. Only present for Google Cloud + Platform offers. """ payment_plan = proto.Field(proto.ENUM, number=1, enum="PaymentPlan",) @@ -269,6 +273,8 @@ class Plan(proto.Message): trial_period = proto.Field(proto.MESSAGE, number=4, message="Period",) + billing_account = proto.Field(proto.STRING, number=5) + class PriceByResource(proto.Message): r"""Represents price by resource type. diff --git a/google/cloud/channel_v1/types/service.py b/google/cloud/channel_v1/types/service.py index 47e6e12..819bf70 100644 --- a/google/cloud/channel_v1/types/service.py +++ b/google/cloud/channel_v1/types/service.py @@ -646,10 +646,6 @@ class CreateChannelPartnerLinkRequest(proto.Message): Required. The channel partner link to create. Either channel_partner_link.reseller_cloud_identity_id or domain can be used to create a link. - domain (str): - Optional. The invited partner's domain. Either domain or - channel_partner_link.reseller_cloud_identity_id can be used - to create a link. """ parent = proto.Field(proto.STRING, number=1) @@ -658,8 +654,6 @@ class CreateChannelPartnerLinkRequest(proto.Message): proto.MESSAGE, number=2, message=gcc_channel_partner_links.ChannelPartnerLink, ) - domain = proto.Field(proto.STRING, number=3) - class UpdateChannelPartnerLinkRequest(proto.Message): r"""Request message for diff --git a/noxfile.py b/noxfile.py index 72b3875..af50a60 100644 --- a/noxfile.py +++ b/noxfile.py @@ -18,6 +18,7 @@ from __future__ import absolute_import import os +import pathlib import shutil import nox @@ -30,6 +31,8 @@ SYSTEM_TEST_PYTHON_VERSIONS = ["3.8"] UNIT_TEST_PYTHON_VERSIONS = ["3.6", "3.7", "3.8", "3.9"] +CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() + # 'docfx' is excluded since it only needs to run in 'docs-presubmit' nox.options.sessions = [ "unit", @@ -41,6 +44,9 @@ "docs", ] +# Error if a python version is missing +nox.options.error_on_missing_interpreters = True + @nox.session(python=DEFAULT_PYTHON_VERSION) def lint(session): @@ -81,13 +87,15 @@ 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", + constraints_path = str( + CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" ) + session.install("asyncmock", "pytest-asyncio", "-c", constraints_path) - session.install("-e", ".") + session.install("mock", "pytest", "pytest-cov", "-c", constraints_path) + + session.install("-e", ".", "-c", constraints_path) # Run py.test against the unit tests. session.run( @@ -114,6 +122,9 @@ def unit(session): @nox.session(python=SYSTEM_TEST_PYTHON_VERSIONS) def system(session): """Run the system test suite.""" + constraints_path = str( + CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" + ) system_test_path = os.path.join("tests", "system.py") system_test_folder_path = os.path.join("tests", "system") @@ -138,10 +149,8 @@ def system(session): # Install all test dependencies, then install this package into the # virtualenv's dist-packages. - session.install( - "mock", "pytest", "google-cloud-testutils", - ) - session.install("-e", ".") + session.install("mock", "pytest", "google-cloud-testutils", "-c", constraints_path) + session.install("-e", ".", "-c", constraints_path) # Run py.test against the system tests. if system_test_exists: @@ -202,9 +211,7 @@ def docfx(session): """Build the docfx yaml files for this library.""" session.install("-e", ".") - # sphinx-docfx-yaml supports up to sphinx version 1.5.5. - # https://github.com/docascode/sphinx-docfx-yaml/issues/97 - session.install("sphinx==1.5.5", "alabaster", "recommonmark", "sphinx-docfx-yaml") + session.install("sphinx", "alabaster", "recommonmark", "gcp-sphinx-docfx-yaml") shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True) session.run( diff --git a/renovate.json b/renovate.json index 4fa9493..f08bc22 100644 --- a/renovate.json +++ b/renovate.json @@ -1,5 +1,6 @@ { "extends": [ "config:base", ":preserveSemverRanges" - ] + ], + "ignorePaths": [".pre-commit-config.yaml"] } diff --git a/scripts/fixup_channel_v1_keywords.py b/scripts/fixup_channel_v1_keywords.py index 2e11568..7324026 100644 --- a/scripts/fixup_channel_v1_keywords.py +++ b/scripts/fixup_channel_v1_keywords.py @@ -47,7 +47,7 @@ class channelCallTransformer(cst.CSTTransformer): 'change_parameters': ('name', 'parameters', 'request_id', 'purchase_order_id', ), 'change_renewal_settings': ('name', 'renewal_settings', 'request_id', ), 'check_cloud_identity_accounts_exist': ('parent', 'domain', ), - 'create_channel_partner_link': ('parent', 'channel_partner_link', 'domain', ), + 'create_channel_partner_link': ('parent', 'channel_partner_link', ), 'create_customer': ('parent', 'customer', ), 'create_entitlement': ('parent', 'entitlement', 'request_id', ), 'delete_customer': ('name', ), diff --git a/synth.metadata b/synth.metadata index 243c103..ca85ab7 100644 --- a/synth.metadata +++ b/synth.metadata @@ -3,30 +3,30 @@ { "git": { "name": ".", - "remote": "https://github.com/googleapis/python-channel.git", - "sha": "dc5395aee4540ec259b239731682123c23a437de" + "remote": "git@github.com:googleapis/python-channel", + "sha": "3c38048d06fdd5ea2ef52c035ab7a16e3e30f8ce" } }, { "git": { "name": "googleapis", "remote": "https://github.com/googleapis/googleapis.git", - "sha": "5e3dacee19405529b841b53797df799c2383536c", - "internalRef": "355923884" + "sha": "56fc6d43fed71188d7e18f3ca003544646c4ab35", + "internalRef": "366346972" } }, { "git": { "name": "synthtool", "remote": "https://github.com/googleapis/synthtool.git", - "sha": "0780323da96d5a53925fe0547757181fe76e8f1e" + "sha": "6d76df2138f8f841e5a5b9ac427f81def520c15f" } }, { "git": { "name": "synthtool", "remote": "https://github.com/googleapis/synthtool.git", - "sha": "0780323da96d5a53925fe0547757181fe76e8f1e" + "sha": "6d76df2138f8f841e5a5b9ac427f81def520c15f" } } ], @@ -40,103 +40,5 @@ "generator": "bazel" } } - ], - "generatedFiles": [ - ".coveragerc", - ".flake8", - ".github/CONTRIBUTING.md", - ".github/ISSUE_TEMPLATE/bug_report.md", - ".github/ISSUE_TEMPLATE/feature_request.md", - ".github/ISSUE_TEMPLATE/support_request.md", - ".github/PULL_REQUEST_TEMPLATE.md", - ".github/header-checker-lint.yml", - ".github/release-please.yml", - ".github/snippet-bot.yml", - ".gitignore", - ".kokoro/build.sh", - ".kokoro/continuous/common.cfg", - ".kokoro/continuous/continuous.cfg", - ".kokoro/docker/docs/Dockerfile", - ".kokoro/docker/docs/fetch_gpg_keys.sh", - ".kokoro/docs/common.cfg", - ".kokoro/docs/docs-presubmit.cfg", - ".kokoro/docs/docs.cfg", - ".kokoro/populate-secrets.sh", - ".kokoro/presubmit/common.cfg", - ".kokoro/presubmit/presubmit.cfg", - ".kokoro/publish-docs.sh", - ".kokoro/release.sh", - ".kokoro/release/common.cfg", - ".kokoro/release/release.cfg", - ".kokoro/samples/lint/common.cfg", - ".kokoro/samples/lint/continuous.cfg", - ".kokoro/samples/lint/periodic.cfg", - ".kokoro/samples/lint/presubmit.cfg", - ".kokoro/samples/python3.6/common.cfg", - ".kokoro/samples/python3.6/continuous.cfg", - ".kokoro/samples/python3.6/periodic.cfg", - ".kokoro/samples/python3.6/presubmit.cfg", - ".kokoro/samples/python3.7/common.cfg", - ".kokoro/samples/python3.7/continuous.cfg", - ".kokoro/samples/python3.7/periodic.cfg", - ".kokoro/samples/python3.7/presubmit.cfg", - ".kokoro/samples/python3.8/common.cfg", - ".kokoro/samples/python3.8/continuous.cfg", - ".kokoro/samples/python3.8/periodic.cfg", - ".kokoro/samples/python3.8/presubmit.cfg", - ".kokoro/test-samples.sh", - ".kokoro/trampoline.sh", - ".kokoro/trampoline_v2.sh", - ".pre-commit-config.yaml", - ".trampolinerc", - "CODE_OF_CONDUCT.md", - "CONTRIBUTING.rst", - "LICENSE", - "MANIFEST.in", - "docs/_static/custom.css", - "docs/_templates/layout.html", - "docs/channel_v1/cloud_channel_service.rst", - "docs/channel_v1/services.rst", - "docs/channel_v1/types.rst", - "docs/conf.py", - "docs/multiprocessing.rst", - "google/cloud/channel/__init__.py", - "google/cloud/channel/py.typed", - "google/cloud/channel_v1/__init__.py", - "google/cloud/channel_v1/py.typed", - "google/cloud/channel_v1/services/__init__.py", - "google/cloud/channel_v1/services/cloud_channel_service/__init__.py", - "google/cloud/channel_v1/services/cloud_channel_service/async_client.py", - "google/cloud/channel_v1/services/cloud_channel_service/client.py", - "google/cloud/channel_v1/services/cloud_channel_service/pagers.py", - "google/cloud/channel_v1/services/cloud_channel_service/transports/__init__.py", - "google/cloud/channel_v1/services/cloud_channel_service/transports/base.py", - "google/cloud/channel_v1/services/cloud_channel_service/transports/grpc.py", - "google/cloud/channel_v1/services/cloud_channel_service/transports/grpc_asyncio.py", - "google/cloud/channel_v1/types/__init__.py", - "google/cloud/channel_v1/types/channel_partner_links.py", - "google/cloud/channel_v1/types/common.py", - "google/cloud/channel_v1/types/customers.py", - "google/cloud/channel_v1/types/entitlements.py", - "google/cloud/channel_v1/types/offers.py", - "google/cloud/channel_v1/types/operations.py", - "google/cloud/channel_v1/types/products.py", - "google/cloud/channel_v1/types/service.py", - "google/cloud/channel_v1/types/subscriber_event.py", - "mypy.ini", - "noxfile.py", - "renovate.json", - "scripts/decrypt-secrets.sh", - "scripts/fixup_channel_v1_keywords.py", - "scripts/readme-gen/readme_gen.py", - "scripts/readme-gen/templates/README.tmpl.rst", - "scripts/readme-gen/templates/auth.tmpl.rst", - "scripts/readme-gen/templates/auth_api_key.tmpl.rst", - "scripts/readme-gen/templates/install_deps.tmpl.rst", - "scripts/readme-gen/templates/install_portaudio.tmpl.rst", - "setup.cfg", - "testing/.gitignore", - "tests/unit/gapic/channel_v1/__init__.py", - "tests/unit/gapic/channel_v1/test_cloud_channel_service.py" ] } \ No newline at end of file diff --git a/testing/constraints-3.7.txt b/testing/constraints-3.7.txt index e69de29..da93009 100644 --- a/testing/constraints-3.7.txt +++ b/testing/constraints-3.7.txt @@ -0,0 +1,2 @@ +# This constraints file is left inentionally empty +# so the latest version of dependencies is installed \ No newline at end of file diff --git a/testing/constraints-3.8.txt b/testing/constraints-3.8.txt index e69de29..da93009 100644 --- a/testing/constraints-3.8.txt +++ b/testing/constraints-3.8.txt @@ -0,0 +1,2 @@ +# This constraints file is left inentionally empty +# so the latest version of dependencies is installed \ No newline at end of file diff --git a/testing/constraints-3.9.txt b/testing/constraints-3.9.txt index e69de29..da93009 100644 --- a/testing/constraints-3.9.txt +++ b/testing/constraints-3.9.txt @@ -0,0 +1,2 @@ +# This constraints file is left inentionally empty +# so the latest version of dependencies is installed \ No newline at end of file diff --git a/tests/unit/gapic/channel_v1/__init__.py b/tests/unit/gapic/channel_v1/__init__.py index 8b13789..42ffdf2 100644 --- a/tests/unit/gapic/channel_v1/__init__.py +++ b/tests/unit/gapic/channel_v1/__init__.py @@ -1 +1,16 @@ +# -*- 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. +# diff --git a/tests/unit/gapic/channel_v1/test_cloud_channel_service.py b/tests/unit/gapic/channel_v1/test_cloud_channel_service.py index 1772cc1..a593db5 100644 --- a/tests/unit/gapic/channel_v1/test_cloud_channel_service.py +++ b/tests/unit/gapic/channel_v1/test_cloud_channel_service.py @@ -104,15 +104,19 @@ def test__get_default_mtls_endpoint(): ) -def test_cloud_channel_service_client_from_service_account_info(): +@pytest.mark.parametrize( + "client_class", [CloudChannelServiceClient, CloudChannelServiceAsyncClient,] +) +def test_cloud_channel_service_client_from_service_account_info(client_class): creds = credentials.AnonymousCredentials() with mock.patch.object( service_account.Credentials, "from_service_account_info" ) as factory: factory.return_value = creds info = {"valid": True} - client = CloudChannelServiceClient.from_service_account_info(info) + client = client_class.from_service_account_info(info) assert client.transport._credentials == creds + assert isinstance(client, client_class) assert client.transport._host == "cloudchannel.googleapis.com:443" @@ -128,9 +132,11 @@ def test_cloud_channel_service_client_from_service_account_file(client_class): factory.return_value = creds client = client_class.from_service_account_file("dummy/file/path.json") assert client.transport._credentials == creds + assert isinstance(client, client_class) client = client_class.from_service_account_json("dummy/file/path.json") assert client.transport._credentials == creds + assert isinstance(client, client_class) assert client.transport._host == "cloudchannel.googleapis.com:443" @@ -515,6 +521,22 @@ def test_list_customers_from_dict(): test_list_customers(request_type=dict) +def test_list_customers_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = CloudChannelServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_customers), "__call__") as call: + client.list_customers() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == service.ListCustomersRequest() + + @pytest.mark.asyncio async def test_list_customers_async( transport: str = "grpc_asyncio", request_type=service.ListCustomersRequest @@ -801,6 +823,22 @@ def test_get_customer_from_dict(): test_get_customer(request_type=dict) +def test_get_customer_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = CloudChannelServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_customer), "__call__") as call: + client.get_customer() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == service.GetCustomerRequest() + + @pytest.mark.asyncio async def test_get_customer_async( transport: str = "grpc_asyncio", request_type=service.GetCustomerRequest @@ -1014,6 +1052,24 @@ def test_check_cloud_identity_accounts_exist_from_dict(): test_check_cloud_identity_accounts_exist(request_type=dict) +def test_check_cloud_identity_accounts_exist_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = CloudChannelServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.check_cloud_identity_accounts_exist), "__call__" + ) as call: + client.check_cloud_identity_accounts_exist() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == service.CheckCloudIdentityAccountsExistRequest() + + @pytest.mark.asyncio async def test_check_cloud_identity_accounts_exist_async( transport: str = "grpc_asyncio", @@ -1165,6 +1221,22 @@ def test_create_customer_from_dict(): test_create_customer(request_type=dict) +def test_create_customer_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = CloudChannelServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.create_customer), "__call__") as call: + client.create_customer() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == service.CreateCustomerRequest() + + @pytest.mark.asyncio async def test_create_customer_async( transport: str = "grpc_asyncio", request_type=service.CreateCustomerRequest @@ -1329,6 +1401,22 @@ def test_update_customer_from_dict(): test_update_customer(request_type=dict) +def test_update_customer_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = CloudChannelServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.update_customer), "__call__") as call: + client.update_customer() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == service.UpdateCustomerRequest() + + @pytest.mark.asyncio async def test_update_customer_async( transport: str = "grpc_asyncio", request_type=service.UpdateCustomerRequest @@ -1474,6 +1562,22 @@ def test_delete_customer_from_dict(): test_delete_customer(request_type=dict) +def test_delete_customer_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = CloudChannelServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_customer), "__call__") as call: + client.delete_customer() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == service.DeleteCustomerRequest() + + @pytest.mark.asyncio async def test_delete_customer_async( transport: str = "grpc_asyncio", request_type=service.DeleteCustomerRequest @@ -1662,6 +1766,24 @@ def test_provision_cloud_identity_from_dict(): test_provision_cloud_identity(request_type=dict) +def test_provision_cloud_identity_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = CloudChannelServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.provision_cloud_identity), "__call__" + ) as call: + client.provision_cloud_identity() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == service.ProvisionCloudIdentityRequest() + + @pytest.mark.asyncio async def test_provision_cloud_identity_async( transport: str = "grpc_asyncio", request_type=service.ProvisionCloudIdentityRequest @@ -1796,6 +1918,24 @@ def test_list_entitlements_from_dict(): test_list_entitlements(request_type=dict) +def test_list_entitlements_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = CloudChannelServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_entitlements), "__call__" + ) as call: + client.list_entitlements() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == service.ListEntitlementsRequest() + + @pytest.mark.asyncio async def test_list_entitlements_async( transport: str = "grpc_asyncio", request_type=service.ListEntitlementsRequest @@ -2082,6 +2222,24 @@ def test_list_transferable_skus_from_dict(): test_list_transferable_skus(request_type=dict) +def test_list_transferable_skus_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = CloudChannelServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_transferable_skus), "__call__" + ) as call: + client.list_transferable_skus() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == service.ListTransferableSkusRequest() + + @pytest.mark.asyncio async def test_list_transferable_skus_async( transport: str = "grpc_asyncio", request_type=service.ListTransferableSkusRequest @@ -2394,6 +2552,24 @@ def test_list_transferable_offers_from_dict(): test_list_transferable_offers(request_type=dict) +def test_list_transferable_offers_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = CloudChannelServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_transferable_offers), "__call__" + ) as call: + client.list_transferable_offers() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == service.ListTransferableOffersRequest() + + @pytest.mark.asyncio async def test_list_transferable_offers_async( transport: str = "grpc_asyncio", request_type=service.ListTransferableOffersRequest @@ -2722,6 +2898,22 @@ def test_get_entitlement_from_dict(): test_get_entitlement(request_type=dict) +def test_get_entitlement_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = CloudChannelServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_entitlement), "__call__") as call: + client.get_entitlement() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == service.GetEntitlementRequest() + + @pytest.mark.asyncio async def test_get_entitlement_async( transport: str = "grpc_asyncio", request_type=service.GetEntitlementRequest @@ -2867,6 +3059,24 @@ def test_create_entitlement_from_dict(): test_create_entitlement(request_type=dict) +def test_create_entitlement_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = CloudChannelServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_entitlement), "__call__" + ) as call: + client.create_entitlement() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == service.CreateEntitlementRequest() + + @pytest.mark.asyncio async def test_create_entitlement_async( transport: str = "grpc_asyncio", request_type=service.CreateEntitlementRequest @@ -2996,6 +3206,24 @@ def test_change_parameters_from_dict(): test_change_parameters(request_type=dict) +def test_change_parameters_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = CloudChannelServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.change_parameters), "__call__" + ) as call: + client.change_parameters() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == service.ChangeParametersRequest() + + @pytest.mark.asyncio async def test_change_parameters_async( transport: str = "grpc_asyncio", request_type=service.ChangeParametersRequest @@ -3125,6 +3353,24 @@ def test_change_renewal_settings_from_dict(): test_change_renewal_settings(request_type=dict) +def test_change_renewal_settings_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = CloudChannelServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.change_renewal_settings), "__call__" + ) as call: + client.change_renewal_settings() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == service.ChangeRenewalSettingsRequest() + + @pytest.mark.asyncio async def test_change_renewal_settings_async( transport: str = "grpc_asyncio", request_type=service.ChangeRenewalSettingsRequest @@ -3250,6 +3496,22 @@ def test_change_offer_from_dict(): test_change_offer(request_type=dict) +def test_change_offer_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = CloudChannelServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.change_offer), "__call__") as call: + client.change_offer() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == service.ChangeOfferRequest() + + @pytest.mark.asyncio async def test_change_offer_async( transport: str = "grpc_asyncio", request_type=service.ChangeOfferRequest @@ -3373,6 +3635,24 @@ def test_start_paid_service_from_dict(): test_start_paid_service(request_type=dict) +def test_start_paid_service_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = CloudChannelServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.start_paid_service), "__call__" + ) as call: + client.start_paid_service() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == service.StartPaidServiceRequest() + + @pytest.mark.asyncio async def test_start_paid_service_async( transport: str = "grpc_asyncio", request_type=service.StartPaidServiceRequest @@ -3502,6 +3782,24 @@ def test_suspend_entitlement_from_dict(): test_suspend_entitlement(request_type=dict) +def test_suspend_entitlement_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = CloudChannelServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.suspend_entitlement), "__call__" + ) as call: + client.suspend_entitlement() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == service.SuspendEntitlementRequest() + + @pytest.mark.asyncio async def test_suspend_entitlement_async( transport: str = "grpc_asyncio", request_type=service.SuspendEntitlementRequest @@ -3631,6 +3929,24 @@ def test_cancel_entitlement_from_dict(): test_cancel_entitlement(request_type=dict) +def test_cancel_entitlement_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = CloudChannelServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.cancel_entitlement), "__call__" + ) as call: + client.cancel_entitlement() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == service.CancelEntitlementRequest() + + @pytest.mark.asyncio async def test_cancel_entitlement_async( transport: str = "grpc_asyncio", request_type=service.CancelEntitlementRequest @@ -3760,6 +4076,24 @@ def test_activate_entitlement_from_dict(): test_activate_entitlement(request_type=dict) +def test_activate_entitlement_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = CloudChannelServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.activate_entitlement), "__call__" + ) as call: + client.activate_entitlement() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == service.ActivateEntitlementRequest() + + @pytest.mark.asyncio async def test_activate_entitlement_async( transport: str = "grpc_asyncio", request_type=service.ActivateEntitlementRequest @@ -3889,6 +4223,24 @@ def test_transfer_entitlements_from_dict(): test_transfer_entitlements(request_type=dict) +def test_transfer_entitlements_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = CloudChannelServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.transfer_entitlements), "__call__" + ) as call: + client.transfer_entitlements() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == service.TransferEntitlementsRequest() + + @pytest.mark.asyncio async def test_transfer_entitlements_async( transport: str = "grpc_asyncio", request_type=service.TransferEntitlementsRequest @@ -4018,6 +4370,24 @@ def test_transfer_entitlements_to_google_from_dict(): test_transfer_entitlements_to_google(request_type=dict) +def test_transfer_entitlements_to_google_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = CloudChannelServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.transfer_entitlements_to_google), "__call__" + ) as call: + client.transfer_entitlements_to_google() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == service.TransferEntitlementsToGoogleRequest() + + @pytest.mark.asyncio async def test_transfer_entitlements_to_google_async( transport: str = "grpc_asyncio", @@ -4153,6 +4523,24 @@ def test_list_channel_partner_links_from_dict(): test_list_channel_partner_links(request_type=dict) +def test_list_channel_partner_links_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = CloudChannelServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_channel_partner_links), "__call__" + ) as call: + client.list_channel_partner_links() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == service.ListChannelPartnerLinksRequest() + + @pytest.mark.asyncio async def test_list_channel_partner_links_async( transport: str = "grpc_asyncio", request_type=service.ListChannelPartnerLinksRequest @@ -4481,6 +4869,24 @@ def test_get_channel_partner_link_from_dict(): test_get_channel_partner_link(request_type=dict) +def test_get_channel_partner_link_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = CloudChannelServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_channel_partner_link), "__call__" + ) as call: + client.get_channel_partner_link() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == service.GetChannelPartnerLinkRequest() + + @pytest.mark.asyncio async def test_get_channel_partner_link_async( transport: str = "grpc_asyncio", request_type=service.GetChannelPartnerLinkRequest @@ -4643,6 +5049,24 @@ def test_create_channel_partner_link_from_dict(): test_create_channel_partner_link(request_type=dict) +def test_create_channel_partner_link_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = CloudChannelServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_channel_partner_link), "__call__" + ) as call: + client.create_channel_partner_link() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == service.CreateChannelPartnerLinkRequest() + + @pytest.mark.asyncio async def test_create_channel_partner_link_async( transport: str = "grpc_asyncio", @@ -4806,6 +5230,24 @@ def test_update_channel_partner_link_from_dict(): test_update_channel_partner_link(request_type=dict) +def test_update_channel_partner_link_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = CloudChannelServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_channel_partner_link), "__call__" + ) as call: + client.update_channel_partner_link() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == service.UpdateChannelPartnerLinkRequest() + + @pytest.mark.asyncio async def test_update_channel_partner_link_async( transport: str = "grpc_asyncio", @@ -4955,6 +5397,22 @@ def test_list_products_from_dict(): test_list_products(request_type=dict) +def test_list_products_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = CloudChannelServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_products), "__call__") as call: + client.list_products() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == service.ListProductsRequest() + + @pytest.mark.asyncio async def test_list_products_async( transport: str = "grpc_asyncio", request_type=service.ListProductsRequest @@ -5151,6 +5609,22 @@ def test_list_skus_from_dict(): test_list_skus(request_type=dict) +def test_list_skus_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = CloudChannelServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_skus), "__call__") as call: + client.list_skus() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == service.ListSkusRequest() + + @pytest.mark.asyncio async def test_list_skus_async( transport: str = "grpc_asyncio", request_type=service.ListSkusRequest @@ -5387,6 +5861,22 @@ def test_list_offers_from_dict(): test_list_offers(request_type=dict) +def test_list_offers_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = CloudChannelServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_offers), "__call__") as call: + client.list_offers() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == service.ListOffersRequest() + + @pytest.mark.asyncio async def test_list_offers_async( transport: str = "grpc_asyncio", request_type=service.ListOffersRequest @@ -5635,6 +6125,24 @@ def test_list_purchasable_skus_from_dict(): test_list_purchasable_skus(request_type=dict) +def test_list_purchasable_skus_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = CloudChannelServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_purchasable_skus), "__call__" + ) as call: + client.list_purchasable_skus() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == service.ListPurchasableSkusRequest() + + @pytest.mark.asyncio async def test_list_purchasable_skus_async( transport: str = "grpc_asyncio", request_type=service.ListPurchasableSkusRequest @@ -5931,6 +6439,24 @@ def test_list_purchasable_offers_from_dict(): test_list_purchasable_offers(request_type=dict) +def test_list_purchasable_offers_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = CloudChannelServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_purchasable_offers), "__call__" + ) as call: + client.list_purchasable_offers() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == service.ListPurchasableOffersRequest() + + @pytest.mark.asyncio async def test_list_purchasable_offers_async( transport: str = "grpc_asyncio", request_type=service.ListPurchasableOffersRequest @@ -6237,6 +6763,24 @@ def test_register_subscriber_from_dict(): test_register_subscriber(request_type=dict) +def test_register_subscriber_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = CloudChannelServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.register_subscriber), "__call__" + ) as call: + client.register_subscriber() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == service.RegisterSubscriberRequest() + + @pytest.mark.asyncio async def test_register_subscriber_async( transport: str = "grpc_asyncio", request_type=service.RegisterSubscriberRequest @@ -6371,6 +6915,24 @@ def test_unregister_subscriber_from_dict(): test_unregister_subscriber(request_type=dict) +def test_unregister_subscriber_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = CloudChannelServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.unregister_subscriber), "__call__" + ) as call: + client.unregister_subscriber() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == service.UnregisterSubscriberRequest() + + @pytest.mark.asyncio async def test_unregister_subscriber_async( transport: str = "grpc_asyncio", request_type=service.UnregisterSubscriberRequest @@ -6511,6 +7073,22 @@ def test_list_subscribers_from_dict(): test_list_subscribers(request_type=dict) +def test_list_subscribers_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = CloudChannelServiceClient( + credentials=credentials.AnonymousCredentials(), transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_subscribers), "__call__") as call: + client.list_subscribers() + call.assert_called() + _, args, _ = call.mock_calls[0] + + assert args[0] == service.ListSubscribersRequest() + + @pytest.mark.asyncio async def test_list_subscribers_async( transport: str = "grpc_asyncio", request_type=service.ListSubscribersRequest