diff --git a/optimizely/config_manager.py b/optimizely/config_manager.py index b1e5b02d..5c0ee342 100644 --- a/optimizely/config_manager.py +++ b/optimizely/config_manager.py @@ -1,4 +1,4 @@ -# Copyright 2019, Optimizely +# Copyright 2019-2020, Optimizely # 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 @@ -26,6 +26,7 @@ from .notification_center import NotificationCenter from .helpers import enums from .helpers import validator +from .optimizely_config import OptimizelyConfigService ABC = abc.ABCMeta('ABC', (object,), {'__slots__': ()}) @@ -89,6 +90,7 @@ def __init__( logger=logger, error_handler=error_handler, notification_center=notification_center, ) self._config = None + self.optimizely_config = None self.validate_schema = not skip_json_validation self._set_config(datafile) @@ -128,6 +130,7 @@ def _set_config(self, datafile): return self._config = config + self.optimizely_config = OptimizelyConfigService(config).get_config() self.notification_center.send_notifications(enums.NotificationTypes.OPTIMIZELY_CONFIG_UPDATE) self.logger.debug( 'Received new datafile and updated config. ' diff --git a/optimizely/optimizely.py b/optimizely/optimizely.py index 72496edc..3e8de499 100644 --- a/optimizely/optimizely.py +++ b/optimizely/optimizely.py @@ -751,4 +751,8 @@ def get_optimizely_config(self): self.logger.error(enums.Errors.INVALID_PROJECT_CONFIG.format('get_optimizely_config')) return None + # Customized Config Manager may not have optimizely_config defined. + if hasattr(self.config_manager, 'optimizely_config'): + return self.config_manager.optimizely_config + return OptimizelyConfigService(project_config).get_config() diff --git a/tests/test_config_manager.py b/tests/test_config_manager.py index c7425f4c..b2117a17 100644 --- a/tests/test_config_manager.py +++ b/tests/test_config_manager.py @@ -1,4 +1,4 @@ -# Copyright 2019, Optimizely +# Copyright 2019-2020, Optimizely # 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 @@ -18,6 +18,7 @@ from optimizely import config_manager from optimizely import exceptions as optimizely_exceptions +from optimizely import optimizely_config from optimizely import project_config from optimizely.helpers import enums @@ -75,13 +76,19 @@ def test_set_config__success(self): ) mock_notification_center.send_notifications.assert_called_once_with('OPTIMIZELY_CONFIG_UPDATE') + self.assertIsInstance( + project_config_manager.optimizely_config, + optimizely_config.OptimizelyConfig + ) + def test_set_config__twice(self): """ Test calling set_config twice with same content to ensure config is not updated. """ test_datafile = json.dumps(self.config_dict_with_features) mock_logger = mock.Mock() mock_notification_center = mock.Mock() - with mock.patch('optimizely.config_manager.BaseConfigManager._validate_instantiation_options'): + with mock.patch('optimizely.config_manager.BaseConfigManager._validate_instantiation_options'), \ + mock.patch('optimizely.optimizely_config.OptimizelyConfigService.get_config') as mock_opt_service: project_config_manager = config_manager.StaticConfigManager( datafile=test_datafile, logger=mock_logger, notification_center=mock_notification_center, ) @@ -92,14 +99,18 @@ def test_set_config__twice(self): ) self.assertEqual(1, mock_logger.debug.call_count) mock_notification_center.send_notifications.assert_called_once_with('OPTIMIZELY_CONFIG_UPDATE') + self.assertEqual(1, mock_opt_service.call_count) mock_logger.reset_mock() mock_notification_center.reset_mock() + mock_opt_service.reset_mock() # Call set config again and confirm that no new log message denoting config update is there project_config_manager._set_config(test_datafile) self.assertEqual(0, mock_logger.debug.call_count) self.assertEqual(0, mock_notification_center.call_count) + # Assert that mock_opt_service is not called again. + self.assertEqual(0, mock_opt_service.call_count) def test_set_config__schema_validation(self): """ Test set_config calls or does not call schema validation based on skip_json_validation value. """ diff --git a/tests/test_optimizely.py b/tests/test_optimizely.py index 44bbf27e..4770bcdb 100644 --- a/tests/test_optimizely.py +++ b/tests/test_optimizely.py @@ -3945,6 +3945,29 @@ def test_get_optimizely_config_returns_instance_of_optimizely_config(self): opt_config = opt_obj.get_optimizely_config() self.assertIsInstance(opt_config, optimizely_config.OptimizelyConfig) + def test_get_optimizely_config_with_custom_config_manager(self): + """ Test that get_optimizely_config returns a valid instance of OptimizelyConfig + when a custom config manager is used. """ + + some_obj = optimizely.Optimizely(json.dumps(self.config_dict_with_features)) + return_config = some_obj.config_manager.get_config() + + class SomeConfigManager(object): + def get_config(self): + return return_config + + opt_obj = optimizely.Optimizely(config_manager=SomeConfigManager()) + self.assertIsInstance( + opt_obj.get_optimizely_config(), + optimizely_config.OptimizelyConfig + ) + + with mock.patch('optimizely.optimizely_config.OptimizelyConfigService.get_config') as mock_opt_service: + opt_obj = optimizely.Optimizely(config_manager=SomeConfigManager()) + opt_obj.get_optimizely_config() + + self.assertEqual(1, mock_opt_service.call_count) + class OptimizelyWithExceptionTest(base.BaseTest): def setUp(self):