From 0eb9baf93cd7f578fceea612881be2d40a742c7f Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Wed, 15 Apr 2020 01:42:29 -0600 Subject: [PATCH 1/2] Add several configuration related fixes Fixes #582 --- .../opentelemetry/configuration/__init__.py | 22 ++++++++++--------- .../tests/configuration/test_configuration.py | 19 +++++++++++----- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/opentelemetry-api/src/opentelemetry/configuration/__init__.py b/opentelemetry-api/src/opentelemetry/configuration/__init__.py index 9b23c52bee6..57b1c324c6c 100644 --- a/opentelemetry-api/src/opentelemetry/configuration/__init__.py +++ b/opentelemetry-api/src/opentelemetry/configuration/__init__.py @@ -19,27 +19,27 @@ Simple configuration manager This is a configuration manager for OpenTelemetry. It reads configuration -values from environment variables prefixed with -``OPENTELEMETRY_PYTHON_`` whose characters are only all caps and underscores. -The first character after ``OPENTELEMETRY_PYTHON_`` must be an uppercase -character. +values from environment variables prefixed with ``OPENTELEMETRY_PYTHON_`` whose +characters are only alphanumeric characters and unserscores, except for the +first character after ``OPENTELEMETRY_PYTHON_`` which must not be a number. For example, these environment variables will be read: 1. ``OPENTELEMETRY_PYTHON_SOMETHING`` 2. ``OPENTELEMETRY_PYTHON_SOMETHING_ELSE_`` 3. ``OPENTELEMETRY_PYTHON_SOMETHING_ELSE_AND__ELSE`` +4. ``OPENTELEMETRY_PYTHON_SOMETHING_ELSE_AND_else`` +4. ``OPENTELEMETRY_PYTHON_SOMETHING_ELSE_AND_else2`` These won't: 1. ``OPENTELEMETRY_PYTH_SOMETHING`` -2. ``OPENTELEMETRY_PYTHON_something`` -3. ``OPENTELEMETRY_PYTHON_SOMETHING_2_AND__ELSE`` -4. ``OPENTELEMETRY_PYTHON_SOMETHING_%_ELSE`` +2. ``OPENTELEMETRY_PYTHON_2_SOMETHING_AND__ELSE`` +3. ``OPENTELEMETRY_PYTHON_SOMETHING_%_ELSE`` The values stored in the environment variables can be found in an instance of ``opentelemetry.configuration.Configuration``. This class can be instantiated -freely because instantiating it returns a singleton. +freely because instantiating it returns always the same object. For example, if the environment variable ``OPENTELEMETRY_PYTHON_METER_PROVIDER`` value is ``my_meter_provider``, then @@ -93,11 +93,13 @@ def __new__(cls) -> "Configuration": for key, value in environ.items(): - match = fullmatch("OPENTELEMETRY_PYTHON_([A-Z][A-Z_]*)", key) + match = fullmatch( + r"OPENTELEMETRY_PYTHON_([A-Za-z_][\w_]*)", key + ) if match is not None: - key = match.group(1).lower() + key = match.group(1) setattr(Configuration, "_{}".format(key), value) setattr( diff --git a/opentelemetry-api/tests/configuration/test_configuration.py b/opentelemetry-api/tests/configuration/test_configuration.py index d5a63630912..6e74c5e7957 100644 --- a/opentelemetry-api/tests/configuration/test_configuration.py +++ b/opentelemetry-api/tests/configuration/test_configuration.py @@ -21,6 +21,9 @@ class TestConfiguration(TestCase): def setUp(self): + # This is added here to force a reload of the whole Configuration + # class, resetting its internal attributes so that each tests starts + # with a clean class. from opentelemetry.configuration import Configuration # type: ignore def tearDown(self): @@ -35,15 +38,21 @@ def test_singleton(self): { "OPENTELEMETRY_PYTHON_METER_PROVIDER": "meter_provider", "OPENTELEMETRY_PYTHON_TRACER_PROVIDER": "tracer_provider", + "OPENTELEMETRY_PYTHON_OThER": "other", + "OPENTELEMETRY_PTHON_TRACEX_PROVIDER": "tracex_provider", }, ) def test_environment_variables(self): # type: ignore self.assertEqual( - Configuration().meter_provider, "meter_provider" + Configuration().METER_PROVIDER, "meter_provider" ) # pylint: disable=no-member self.assertEqual( - Configuration().tracer_provider, "tracer_provider" + Configuration().TRACER_PROVIDER, "tracer_provider" ) # pylint: disable=no-member + self.assertEqual( + Configuration().OThER, "other" + ) # pylint: disable=no-member + self.assertIsNone(Configuration().TRACEX_PROVIDER) @patch.dict( "os.environ", # type: ignore @@ -51,11 +60,11 @@ def test_environment_variables(self): # type: ignore ) def test_property(self): with self.assertRaises(AttributeError): - Configuration().tracer_provider = "new_tracer_provider" + Configuration().TRACER_PROVIDER = "new_tracer_provider" def test_slots(self): with self.assertRaises(AttributeError): - Configuration().xyz = "xyz" # pylint: disable=assigning-non-slot + Configuration().XYZ = "xyz" # pylint: disable=assigning-non-slot def test_getattr(self): - Configuration().xyz is None + self.assertIsNone(Configuration().XYZ) From dbd8ac96abab94a8441c4039939051831383a906 Mon Sep 17 00:00:00 2001 From: Diego Hurtado Date: Wed, 15 Apr 2020 15:41:38 -0600 Subject: [PATCH 2/2] Add a test with a number --- opentelemetry-api/tests/configuration/test_configuration.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/opentelemetry-api/tests/configuration/test_configuration.py b/opentelemetry-api/tests/configuration/test_configuration.py index 6e74c5e7957..9688ec28b6c 100644 --- a/opentelemetry-api/tests/configuration/test_configuration.py +++ b/opentelemetry-api/tests/configuration/test_configuration.py @@ -39,6 +39,7 @@ def test_singleton(self): "OPENTELEMETRY_PYTHON_METER_PROVIDER": "meter_provider", "OPENTELEMETRY_PYTHON_TRACER_PROVIDER": "tracer_provider", "OPENTELEMETRY_PYTHON_OThER": "other", + "OPENTELEMETRY_PYTHON_OTHER_7": "other_7", "OPENTELEMETRY_PTHON_TRACEX_PROVIDER": "tracex_provider", }, ) @@ -52,6 +53,9 @@ def test_environment_variables(self): # type: ignore self.assertEqual( Configuration().OThER, "other" ) # pylint: disable=no-member + self.assertEqual( + Configuration().OTHER_7, "other_7" + ) # pylint: disable=no-member self.assertIsNone(Configuration().TRACEX_PROVIDER) @patch.dict(