From 01a61b9812a4fe974137a3e2881f0439e8fe2033 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Wed, 24 Mar 2021 11:44:22 -0400 Subject: [PATCH 1/2] add failing tests --- tests/test_store.py | 22 ++++++++++++++++++++++ tests/test_z_integration.py | 9 +++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/tests/test_store.py b/tests/test_store.py index 31dae8a..d6c5f58 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -74,6 +74,13 @@ def test_store_get_setting_interpolate_value(): assert value == '42-staging-secrets!' +def test_store_get_setting_interpolate_missing(): + store = Store([DictBackend({'service_host': 'cool-db-server:6000'})]) + + with pytest.raises(SettingNotFoundException): + store.get_setting('service_url') + + def test_store_get_setting_interpolate_default(): store = Store([DictBackend({'service_host': 'cool-db-server:6000'})]) @@ -82,6 +89,21 @@ def test_store_get_setting_interpolate_default(): assert value == 'https://cool-db-server:6000/db' +def test_store_get_setting_interpolate_special_character_boundary(): + store = Store([DictBackend(dict( + service_url='https://${user}:${dbpass}@${host}:${port}/${db}', + user='bob', + dbpass='secret', + host='cool-db-server', + port='6000', + db='db1', + ))]) + + value = store.get_setting('service_url') + + assert value == 'https://bob:secret@cool-db-server:6000/db1' + + def test_store_add_backend(): store = Store([]) diff --git a/tests/test_z_integration.py b/tests/test_z_integration.py index a8cc170..93278bb 100644 --- a/tests/test_z_integration.py +++ b/tests/test_z_integration.py @@ -89,10 +89,15 @@ def test_dict_defaults(monkeypatch): def test_interpolation(monkeypatch, tmp_path): monkeypatch.setenv('ENVIRONMENT', 'STAGING') - monkeypatch.setenv('REDIS_URL', 'https://redis:4012') + monkeypatch.setenv('REDIS_HOST', 'redis') + monkeypatch.setenv('REDIS_PORT', '4012') path = tmp_path / 'config.env' path.write_text(DOTENV_CONTENTS) - path.write_text('APP_NAME=supertest-${ENVIRONMENT}-1') + path.write_text( + 'APP_NAME=supertest-${ENVIRONMENT}-1\n' + # make sure more than one variable is possible + 'REDIS_URL=https://${REDIS_HOST}:${REDIS_PORT}\n' + ) store = configstore.Store([ configstore.EnvVarBackend(), From ac7a441ec7afbe7e011d1e46fab0a503862840f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Araujo?= Date: Wed, 24 Mar 2021 11:53:59 -0400 Subject: [PATCH 2/2] add fix --- CHANGELOG.rst | 2 ++ configstore/store.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index d595273..465c3eb 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,8 @@ v0.8 (unreleased) ==== +Fix interpolation of multiple variables in one setting value. + v0.7 ==== diff --git a/configstore/store.py b/configstore/store.py index 430b8cd..b4198b1 100644 --- a/configstore/store.py +++ b/configstore/store.py @@ -73,7 +73,7 @@ def get_setting(self, key, default=_no_default, *, asbool=False): return ret def interpolate(self, string): - res = re.sub(r"\$\{([_a-zA-Z0-9]+)\}", self._replace, string, count=1) + res = re.sub(r"\$\{([_a-zA-Z0-9]+)\}", self._replace, string) return res def _replace(self, matchobj):