diff --git a/gcloud/datastore/_implicit_environ.py b/gcloud/datastore/_implicit_environ.py index ef71cec5a7de..05186188eda7 100644 --- a/gcloud/datastore/_implicit_environ.py +++ b/gcloud/datastore/_implicit_environ.py @@ -14,8 +14,8 @@ """Module to provide implicit behavior based on enviroment. -Acts as a mutable namespace to allow the datastore package to -imply the current dataset ID and connection from the enviroment. +Allows the datastore package to infer the current dataset ID and +connection from the enviroment. """ import os diff --git a/gcloud/storage/__init__.py b/gcloud/storage/__init__.py index 9cd182565f5a..6a4a4179f216 100644 --- a/gcloud/storage/__init__.py +++ b/gcloud/storage/__init__.py @@ -41,6 +41,9 @@ from gcloud import credentials from gcloud.storage import _implicit_environ +from gcloud.storage._implicit_environ import get_default_bucket +from gcloud.storage._implicit_environ import get_default_connection +from gcloud.storage._implicit_environ import get_default_project from gcloud.storage.blob import Blob from gcloud.storage.bucket import Bucket from gcloud.storage.connection import Connection @@ -71,13 +74,13 @@ def set_default_bucket(bucket=None): """ if bucket is None: bucket_name = os.getenv(_BUCKET_ENV_VAR_NAME) - connection = _implicit_environ.CONNECTION + connection = get_default_connection() if bucket_name is not None and connection is not None: bucket = Bucket(connection=connection, name=bucket_name) if bucket is not None: - _implicit_environ.BUCKET = bucket + _implicit_environ._DEFAULTS.bucket = bucket def set_default_project(project=None): @@ -96,7 +99,7 @@ def set_default_project(project=None): project = os.getenv(_PROJECT_ENV_VAR_NAME) if project is not None: - _implicit_environ.PROJECT = project + _implicit_environ._DEFAULTS.project = project def set_default_connection(project=None, connection=None): @@ -109,10 +112,10 @@ def set_default_connection(project=None, connection=None): :param connection: A connection provided to be the default. """ if project is None: - project = _implicit_environ.PROJECT + project = get_default_project() connection = connection or get_connection(project) - _implicit_environ.CONNECTION = connection + _implicit_environ._DEFAULTS.connection = connection def set_defaults(bucket=None, project=None, connection=None): diff --git a/gcloud/storage/_implicit_environ.py b/gcloud/storage/_implicit_environ.py index 69d0a8e3207a..2dbbf139d2be 100644 --- a/gcloud/storage/_implicit_environ.py +++ b/gcloud/storage/_implicit_environ.py @@ -14,16 +14,55 @@ """Module to provide implicit behavior based on enviroment. -Acts as a mutable namespace to allow the datastore package to -infer the current dataset ID and connection from the enviroment. +Allows the storage package to infer the current project, default bucket +and connection from the enviroment. """ -PROJECT = None -"""Module global to allow persistent implied project from enviroment.""" +class _DefaultsContainer(object): + """Container for defaults. -BUCKET = None -"""Module global to allow persistent implied bucket from enviroment.""" + :type project: string + :param project: Persistent implied project from environment. -CONNECTION = None -"""Module global to allow persistent implied connection from enviroment.""" + :type bucket: :class:`gcloud.storage.bucket.Bucket` + :param bucket: Persistent implied default bucket from environment. + + :type connection: :class:`gcloud.storage.connection.Connection` + :param connection: Persistent implied connection from environment. + """ + + def __init__(self, project=None, bucket=None, connection=None): + self.project = project + self.bucket = bucket + self.connection = connection + + +def get_default_project(): + """Get default project. + + :rtype: string or ``NoneType`` + :returns: The default project if one has been set. + """ + return _DEFAULTS.project + + +def get_default_bucket(): + """Get default bucket. + + :rtype: :class:`gcloud.storage.bucket.Bucket` or ``NoneType`` + :returns: The default bucket if one has been set. + """ + return _DEFAULTS.bucket + + +def get_default_connection(): + """Get default connection. + + :rtype: :class:`gcloud.storage.connection.Connection` or ``NoneType`` + :returns: The default connection if one has been set. + """ + return _DEFAULTS.connection + + +_DEFAULTS = _DefaultsContainer() diff --git a/gcloud/storage/_testing.py b/gcloud/storage/_testing.py new file mode 100644 index 000000000000..4eba1a284c54 --- /dev/null +++ b/gcloud/storage/_testing.py @@ -0,0 +1,33 @@ +# Copyright 2014 Google Inc. All rights reserved. +# +# 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. + +"""Shared storage testing utilities.""" + +from gcloud._testing import _Monkey +from gcloud.storage import _implicit_environ +from gcloud.storage._implicit_environ import _DefaultsContainer + + +def _monkey_defaults(*args, **kwargs): + mock_defaults = _DefaultsContainer(*args, **kwargs) + return _Monkey(_implicit_environ, _DEFAULTS=mock_defaults) + + +def _setup_defaults(test_case, *args, **kwargs): + test_case._replaced_defaults = _implicit_environ._DEFAULTS + _implicit_environ._DEFAULTS = _DefaultsContainer(*args, **kwargs) + + +def _tear_down_defaults(test_case): + _implicit_environ._DEFAULTS = test_case._replaced_defaults diff --git a/gcloud/storage/blob.py b/gcloud/storage/blob.py index 61d23e87a95a..dd0bb72d3909 100644 --- a/gcloud/storage/blob.py +++ b/gcloud/storage/blob.py @@ -88,7 +88,7 @@ def __init__(self, name, bucket=None, properties=None): name = properties.get('name') if bucket is None: - bucket = _implicit_environ.BUCKET + bucket = _implicit_environ.get_default_bucket() if bucket is None: raise ValueError('A Blob must have a bucket set.') diff --git a/gcloud/storage/test___init__.py b/gcloud/storage/test___init__.py index f6ad2510fab4..3917e4c061ea 100644 --- a/gcloud/storage/test___init__.py +++ b/gcloud/storage/test___init__.py @@ -74,13 +74,12 @@ def get_connection(*args, **kw): class Test_set_default_bucket(unittest2.TestCase): def setUp(self): - from gcloud.storage import _implicit_environ - self._replaced_bucket = _implicit_environ.BUCKET - _implicit_environ.BUCKET = None + from gcloud.storage._testing import _setup_defaults + _setup_defaults(self) def tearDown(self): - from gcloud.storage import _implicit_environ - _implicit_environ.BUCKET = self._replaced_bucket + from gcloud.storage._testing import _tear_down_defaults + _tear_down_defaults(self) def _callFUT(self, bucket=None): from gcloud.storage import set_default_bucket @@ -95,85 +94,93 @@ def _monkeyEnviron(self, implicit_bucket_name): environ = {_BUCKET_ENV_VAR_NAME: implicit_bucket_name} return _Monkey(os, getenv=environ.get) - def _monkeyImplicit(self, connection): - from gcloud._testing import _Monkey - from gcloud.storage import _implicit_environ - - return _Monkey(_implicit_environ, CONNECTION=connection) - def test_no_env_var_set(self): + from gcloud.storage._testing import _monkey_defaults from gcloud.storage import _implicit_environ + with self._monkeyEnviron(None): - with self._monkeyImplicit(None): + with _monkey_defaults(): self._callFUT() - self.assertEqual(_implicit_environ.BUCKET, None) + self.assertEqual(_implicit_environ.get_default_bucket(), None) def test_set_from_env_var(self): + from gcloud.storage._testing import _monkey_defaults from gcloud.storage import _implicit_environ IMPLICIT_BUCKET_NAME = 'IMPLICIT' CONNECTION = object() with self._monkeyEnviron(IMPLICIT_BUCKET_NAME): - with self._monkeyImplicit(CONNECTION): + with _monkey_defaults(connection=CONNECTION): self._callFUT() - self.assertEqual(_implicit_environ.BUCKET.name, IMPLICIT_BUCKET_NAME) - self.assertEqual(_implicit_environ.BUCKET.connection, CONNECTION) + default_bucket = _implicit_environ.get_default_bucket() + self.assertEqual(default_bucket.name, IMPLICIT_BUCKET_NAME) + self.assertEqual(default_bucket.connection, CONNECTION) def test_set_explicit_w_env_var_set(self): + from gcloud.storage._testing import _monkey_defaults from gcloud.storage import _implicit_environ EXPLICIT_BUCKET = object() with self._monkeyEnviron(None): - with self._monkeyImplicit(None): + with _monkey_defaults(): self._callFUT(EXPLICIT_BUCKET) - self.assertEqual(_implicit_environ.BUCKET, EXPLICIT_BUCKET) + + self.assertEqual(_implicit_environ.get_default_bucket(), + EXPLICIT_BUCKET) def test_set_explicit_no_env_var_set(self): + from gcloud.storage._testing import _monkey_defaults from gcloud.storage import _implicit_environ IMPLICIT_BUCKET_NAME = 'IMPLICIT' CONNECTION = object() EXPLICIT_BUCKET = object() with self._monkeyEnviron(IMPLICIT_BUCKET_NAME): - with self._monkeyImplicit(CONNECTION): + with _monkey_defaults(connection=CONNECTION): self._callFUT(EXPLICIT_BUCKET) - self.assertEqual(_implicit_environ.BUCKET, EXPLICIT_BUCKET) + + self.assertEqual(_implicit_environ.get_default_bucket(), + EXPLICIT_BUCKET) def test_set_explicit_None_wo_env_var_set(self): + from gcloud.storage._testing import _monkey_defaults from gcloud.storage import _implicit_environ CONNECTION = object() with self._monkeyEnviron(None): - with self._monkeyImplicit(CONNECTION): + with _monkey_defaults(connection=CONNECTION): self._callFUT(None) - self.assertEqual(_implicit_environ.BUCKET, None) + self.assertEqual(_implicit_environ.get_default_bucket(), None) def test_set_explicit_None_wo_connection_set(self): + from gcloud.storage._testing import _monkey_defaults from gcloud.storage import _implicit_environ IMPLICIT_BUCKET_NAME = 'IMPLICIT' with self._monkeyEnviron(IMPLICIT_BUCKET_NAME): - with self._monkeyImplicit(None): + with _monkey_defaults(): self._callFUT(None) - self.assertEqual(_implicit_environ.BUCKET, None) + self.assertEqual(_implicit_environ.get_default_bucket(), None) def test_set_explicit_None_w_env_var_set(self): + from gcloud.storage._testing import _monkey_defaults from gcloud.storage import _implicit_environ IMPLICIT_BUCKET_NAME = 'IMPLICIT' CONNECTION = object() with self._monkeyEnviron(IMPLICIT_BUCKET_NAME): - with self._monkeyImplicit(CONNECTION): + with _monkey_defaults(connection=CONNECTION): self._callFUT(None) - self.assertEqual(_implicit_environ.BUCKET.name, IMPLICIT_BUCKET_NAME) - self.assertEqual(_implicit_environ.BUCKET.connection, CONNECTION) + + default_bucket = _implicit_environ.get_default_bucket() + self.assertEqual(default_bucket.name, IMPLICIT_BUCKET_NAME) + self.assertEqual(default_bucket.connection, CONNECTION) class Test_set_default_project(unittest2.TestCase): def setUp(self): - from gcloud.storage import _implicit_environ - self._replaced_project = _implicit_environ.PROJECT - _implicit_environ.PROJECT = None + from gcloud.storage._testing import _setup_defaults + _setup_defaults(self) def tearDown(self): - from gcloud.storage import _implicit_environ - _implicit_environ.PROJECT = self._replaced_project + from gcloud.storage._testing import _tear_down_defaults + _tear_down_defaults(self) def _callFUT(self, project=None): from gcloud.storage import set_default_project @@ -190,21 +197,23 @@ def test_no_env_var_set(self): from gcloud.storage import _implicit_environ with self._monkey(None): self._callFUT() - self.assertEqual(_implicit_environ.PROJECT, None) + self.assertEqual(_implicit_environ.get_default_project(), None) def test_set_from_env_var(self): from gcloud.storage import _implicit_environ IMPLICIT_PROJECT = 'IMPLICIT' with self._monkey(IMPLICIT_PROJECT): self._callFUT() - self.assertEqual(_implicit_environ.PROJECT, IMPLICIT_PROJECT) + self.assertEqual(_implicit_environ.get_default_project(), + IMPLICIT_PROJECT) def test_set_explicit_w_env_var_set(self): from gcloud.storage import _implicit_environ EXPLICIT_PROJECT = 'EXPLICIT' with self._monkey(None): self._callFUT(EXPLICIT_PROJECT) - self.assertEqual(_implicit_environ.PROJECT, EXPLICIT_PROJECT) + self.assertEqual(_implicit_environ.get_default_project(), + EXPLICIT_PROJECT) def test_set_explicit_no_env_var_set(self): from gcloud.storage import _implicit_environ @@ -212,32 +221,33 @@ def test_set_explicit_no_env_var_set(self): EXPLICIT_PROJECT = 'EXPLICIT' with self._monkey(IMPLICIT_PROJECT): self._callFUT(EXPLICIT_PROJECT) - self.assertEqual(_implicit_environ.PROJECT, EXPLICIT_PROJECT) + self.assertEqual(_implicit_environ.get_default_project(), + EXPLICIT_PROJECT) def test_set_explicit_None_wo_env_var_set(self): from gcloud.storage import _implicit_environ with self._monkey(None): self._callFUT(None) - self.assertEqual(_implicit_environ.PROJECT, None) + self.assertEqual(_implicit_environ.get_default_project(), None) def test_set_explicit_None_w_env_var_set(self): from gcloud.storage import _implicit_environ IMPLICIT_PROJECT = 'IMPLICIT' with self._monkey(IMPLICIT_PROJECT): self._callFUT(None) - self.assertEqual(_implicit_environ.PROJECT, IMPLICIT_PROJECT) + self.assertEqual(_implicit_environ.get_default_project(), + IMPLICIT_PROJECT) class Test_set_default_connection(unittest2.TestCase): def setUp(self): - from gcloud.storage import _implicit_environ - self._replaced_connection = _implicit_environ.CONNECTION - _implicit_environ.CONNECTION = None + from gcloud.storage._testing import _setup_defaults + _setup_defaults(self) def tearDown(self): - from gcloud.storage import _implicit_environ - _implicit_environ.CONNECTION = self._replaced_connection + from gcloud.storage._testing import _tear_down_defaults + _tear_down_defaults(self) def _callFUT(self, project=None, connection=None): from gcloud.storage import set_default_connection @@ -246,17 +256,17 @@ def _callFUT(self, project=None, connection=None): def test_set_explicit(self): from gcloud.storage import _implicit_environ - self.assertEqual(_implicit_environ.CONNECTION, None) + self.assertEqual(_implicit_environ.get_default_connection(), None) fake_cnxn = object() self._callFUT(connection=fake_cnxn) - self.assertEqual(_implicit_environ.CONNECTION, fake_cnxn) + self.assertEqual(_implicit_environ.get_default_connection(), fake_cnxn) def test_set_implicit_no_project(self): from gcloud._testing import _Monkey from gcloud import storage from gcloud.storage import _implicit_environ - self.assertEqual(_implicit_environ.CONNECTION, None) + self.assertEqual(_implicit_environ.get_default_connection(), None) fake_cnxn = object() _called_args = [] @@ -270,16 +280,17 @@ def mock_get_connection(*args, **kwargs): with _Monkey(storage, get_connection=mock_get_connection): self._callFUT() - self.assertEqual(_implicit_environ.CONNECTION, fake_cnxn) + self.assertEqual(_implicit_environ.get_default_connection(), fake_cnxn) self.assertEqual(_called_args, [(None,)]) self.assertEqual(_called_kwargs, [{}]) def test_set_implicit_with_implicit_project(self): from gcloud._testing import _Monkey + from gcloud.storage._testing import _monkey_defaults from gcloud import storage from gcloud.storage import _implicit_environ - self.assertEqual(_implicit_environ.CONNECTION, None) + self.assertEqual(_implicit_environ.get_default_connection(), None) fake_cnxn = object() _called_args = [] @@ -292,20 +303,21 @@ def mock_get_connection(*args, **kwargs): PROJECT = 'project' - with _Monkey(_implicit_environ, PROJECT=PROJECT): + with _monkey_defaults(project=PROJECT): with _Monkey(storage, get_connection=mock_get_connection): self._callFUT() - self.assertEqual(_implicit_environ.CONNECTION, fake_cnxn) - self.assertEqual(_called_args, [(PROJECT,)]) - self.assertEqual(_called_kwargs, [{}]) + self.assertEqual(_implicit_environ.get_default_connection(), + fake_cnxn) + self.assertEqual(_called_args, [(PROJECT,)]) + self.assertEqual(_called_kwargs, [{}]) def test_set_implicit_with_explicit_project(self): from gcloud._testing import _Monkey from gcloud import storage from gcloud.storage import _implicit_environ - self.assertEqual(_implicit_environ.CONNECTION, None) + self.assertEqual(_implicit_environ.get_default_connection(), None) fake_cnxn = object() _called_args = [] @@ -321,7 +333,7 @@ def mock_get_connection(*args, **kwargs): with _Monkey(storage, get_connection=mock_get_connection): self._callFUT(PROJECT) - self.assertEqual(_implicit_environ.CONNECTION, fake_cnxn) + self.assertEqual(_implicit_environ.get_default_connection(), fake_cnxn) self.assertEqual(_called_args, [(PROJECT,)]) self.assertEqual(_called_kwargs, [{}]) diff --git a/gcloud/storage/test_blob.py b/gcloud/storage/test_blob.py index 481abecec354..1c35a7b53ce4 100644 --- a/gcloud/storage/test_blob.py +++ b/gcloud/storage/test_blob.py @@ -29,7 +29,11 @@ def test_ctor_implicit_bucket(self): from gcloud.storage import _implicit_environ FAKE_BUCKET = _Bucket(None) - with _Monkey(_implicit_environ, BUCKET=FAKE_BUCKET): + + def mock_get_bucket(): + return FAKE_BUCKET + + with _Monkey(_implicit_environ, get_default_bucket=mock_get_bucket): blob = self._makeOne(None) self.assertEqual(blob.bucket, FAKE_BUCKET) diff --git a/regression/storage.py b/regression/storage.py index 7ec1cac749ba..dee87b7a35fc 100644 --- a/regression/storage.py +++ b/regression/storage.py @@ -20,7 +20,6 @@ from gcloud import exceptions from gcloud import storage from gcloud.storage._helpers import _base64_md5hash -from gcloud.storage import _implicit_environ from gcloud.storage.batch import Batch @@ -30,7 +29,7 @@ storage._PROJECT_ENV_VAR_NAME = 'GCLOUD_TESTS_PROJECT_ID' storage.set_defaults() -CONNECTION = _implicit_environ.CONNECTION +CONNECTION = storage.get_default_connection() def setUpModule():