From b5ea0b2d862b3afe9bcfd06caf2a9216b37126e6 Mon Sep 17 00:00:00 2001 From: HemangChothani Date: Sat, 28 Nov 2020 20:15:03 +0530 Subject: [PATCH 1/2] feat: avoid authentication when use emulator --- google/cloud/storage/client.py | 11 +++++++++++ tests/unit/test_client.py | 26 ++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/google/cloud/storage/client.py b/google/cloud/storage/client.py index c211144f8..33632e23d 100644 --- a/google/cloud/storage/client.py +++ b/google/cloud/storage/client.py @@ -20,6 +20,7 @@ import datetime import functools import json +import os import warnings import google.api_core.client_options @@ -31,6 +32,7 @@ from google.cloud.exceptions import NotFound from google.cloud.storage._helpers import _get_storage_host from google.cloud.storage._helpers import _bucket_bound_hostname_url +from google.cloud.storage._helpers import STORAGE_EMULATOR_ENV_VAR from google.cloud.storage._http import Connection from google.cloud.storage._signing import ( get_expiration_seconds_v4, @@ -112,6 +114,15 @@ def __init__( if project is _marker: project = None + if os.getenv(STORAGE_EMULATOR_ENV_VAR) is not None: + credentials = AnonymousCredentials() + if project in [_marker, None]: + project = os.getenv("GCLOUD_PROJECT") + if project is None: + raise ValueError( + "For emulator pass `project` as a argument or set `GCLOUD_PROJECT` via environment variable" + ) + super(Client, self).__init__( project=project, credentials=credentials, diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py index 4efc35e98..d5af4d176 100644 --- a/tests/unit/test_client.py +++ b/tests/unit/test_client.py @@ -219,6 +219,32 @@ def test_ctor_w_client_info(self): self.assertEqual(list(client._batch_stack), []) self.assertIs(client._connection._client_info, client_info) + def test_ctor_w_emulator_w_env_var_glcoud_project(self): + from google.cloud.storage._helpers import STORAGE_EMULATOR_ENV_VAR + + HOST = "https://api.example.com" + PROJECT = "test" + + with mock.patch("os.environ", {STORAGE_EMULATOR_ENV_VAR: HOST}): + with mock.patch("os.getenv", side_effect=[HOST, PROJECT]): + client = self._make_one() + self.assertEqual(client.project, PROJECT) + self.assertEqual(client._connection.API_BASE_URL, HOST) + + def test_ctor_w_emulator_w_project_argument(self): + HOST = "https://api.example.com" + PROJECT = "test" + + with mock.patch("os.getenv", side_effect=[HOST]): + client = self._make_one(project=PROJECT) + self.assertEqual(client.project, PROJECT) + + def test_ctor_w_emulator_missing_project(self): + HOST = "https://api.example.com" + with mock.patch("os.getenv", side_effect=[HOST, None]): + with self.assertRaises(ValueError): + self._make_one() + def test_create_anonymous_client(self): from google.auth.credentials import AnonymousCredentials from google.cloud.storage._http import Connection From e436dad9d0a16dd7860927d7a98c940f0bb098e5 Mon Sep 17 00:00:00 2001 From: HemangChothani Date: Thu, 3 Dec 2020 17:03:44 +0530 Subject: [PATCH 2/2] feat: changes in unit tests to mock environ --- google/cloud/storage/client.py | 3 ++- tests/unit/test_client.py | 37 ++++++++++++++++++++++++++-------- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/google/cloud/storage/client.py b/google/cloud/storage/client.py index 33632e23d..ce34f3cc3 100644 --- a/google/cloud/storage/client.py +++ b/google/cloud/storage/client.py @@ -120,7 +120,8 @@ def __init__( project = os.getenv("GCLOUD_PROJECT") if project is None: raise ValueError( - "For emulator pass `project` as a argument or set `GCLOUD_PROJECT` via environment variable" + "To use the GCS emulator, pass 'project' as an argument " + "or set GCLOUD_PROJECT environment variable" ) super(Client, self).__init__( diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py index d5af4d176..0ba109a9d 100644 --- a/tests/unit/test_client.py +++ b/tests/unit/test_client.py @@ -220,28 +220,49 @@ def test_ctor_w_client_info(self): self.assertIs(client._connection._client_info, client_info) def test_ctor_w_emulator_w_env_var_glcoud_project(self): + from google.auth.credentials import AnonymousCredentials from google.cloud.storage._helpers import STORAGE_EMULATOR_ENV_VAR HOST = "https://api.example.com" PROJECT = "test" + environ = { + STORAGE_EMULATOR_ENV_VAR: HOST, + "GCLOUD_PROJECT": PROJECT, + } - with mock.patch("os.environ", {STORAGE_EMULATOR_ENV_VAR: HOST}): - with mock.patch("os.getenv", side_effect=[HOST, PROJECT]): - client = self._make_one() - self.assertEqual(client.project, PROJECT) - self.assertEqual(client._connection.API_BASE_URL, HOST) + with mock.patch("os.environ", environ): + client = self._make_one() + + self.assertEqual(client.project, PROJECT) + self.assertEqual(client._connection.API_BASE_URL, HOST) + self.assertIsInstance(client._credentials, AnonymousCredentials) def test_ctor_w_emulator_w_project_argument(self): + from google.auth.credentials import AnonymousCredentials + from google.cloud.storage._helpers import STORAGE_EMULATOR_ENV_VAR + HOST = "https://api.example.com" PROJECT = "test" + ENVIRON_PROJECT = "environ-project" + environ = { + STORAGE_EMULATOR_ENV_VAR: HOST, + "GCLOUD_PROJECT": ENVIRON_PROJECT, + } - with mock.patch("os.getenv", side_effect=[HOST]): + with mock.patch("os.environ", environ): client = self._make_one(project=PROJECT) - self.assertEqual(client.project, PROJECT) + + self.assertEqual(client.project, PROJECT) + self.assertEqual(client._connection.API_BASE_URL, HOST) + self.assertIsInstance(client._credentials, AnonymousCredentials) def test_ctor_w_emulator_missing_project(self): + from google.cloud.storage._helpers import STORAGE_EMULATOR_ENV_VAR + HOST = "https://api.example.com" - with mock.patch("os.getenv", side_effect=[HOST, None]): + environ = {STORAGE_EMULATOR_ENV_VAR: HOST} + + with mock.patch("os.environ", environ): with self.assertRaises(ValueError): self._make_one()