Skip to content

Commit abf690b

Browse files
Merge branch 'master' into mnoman/rmMDspellcheck
2 parents fb9f68d + ba65058 commit abf690b

File tree

5 files changed

+60
-6
lines changed

5 files changed

+60
-6
lines changed

.travis.yml

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ stages:
1919
- 'Linting'
2020
- 'Integration tests'
2121
- 'Test'
22+
- 'Source Clear'
2223

2324
jobs:
2425
include:
@@ -51,12 +52,18 @@ jobs:
5152
- $HOME/travisci-tools/trigger-script-with-status-update.sh
5253
after_success: travis_terminate 0
5354
- stage: 'Test'
54-
addons:
55-
srcclr: true
5655
dist: xenial
5756
python: "3.7"
5857
- stage: 'Test'
59-
addons:
60-
srcclr: true
6158
dist: xenial
6259
python: "3.8"
60+
61+
- stage: 'Source Clear'
62+
if: type = cron
63+
addons:
64+
srcclr: true
65+
before_install: skip
66+
install: skip
67+
before_script: skip
68+
script: skip
69+
after_success: skip

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Optimizely Python SDK Changelog
22

3+
## 3.5.1
4+
July 10th, 2020
5+
6+
### Bug Fixes:
7+
* Fixed HTTP request exception handling in `PollingConfigManager`. ([#285](https://github.com/optimizely/python-sdk/pull/285))
8+
39
## 3.5.0
410
July 9th, 2020
511

optimizely/config_manager.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ def _handle_response(self, response):
325325
"""
326326
try:
327327
response.raise_for_status()
328-
except requests_exceptions.HTTPError as err:
328+
except requests_exceptions.RequestException as err:
329329
self.logger.error('Fetching datafile from {} failed. Error: {}'.format(self.datafile_url, str(err)))
330330
return
331331

optimizely/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@
1111
# See the License for the specific language governing permissions and
1212
# limitations under the License.
1313

14-
version_info = (3, 5, 0)
14+
version_info = (3, 5, 1)
1515
__version__ = '.'.join(str(v) for v in version_info)

tests/test_config_manager.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,47 @@ def test_fetch_datafile(self, _):
392392
)
393393
self.assertEqual(test_headers['Last-Modified'], project_config_manager.last_modified)
394394
self.assertIsInstance(project_config_manager.get_config(), project_config.ProjectConfig)
395+
self.assertTrue(project_config_manager.is_running)
396+
397+
def test_fetch_datafile__exception_raised(self, _):
398+
""" Test that config_manager keeps running if exception is raised when fetching datafile. """
399+
class MockExceptionResponse(object):
400+
def raise_for_status(self):
401+
raise requests.exceptions.RequestException('Error Error !!')
402+
403+
sdk_key = 'some_key'
404+
mock_logger = mock.Mock()
405+
with mock.patch('optimizely.config_manager.PollingConfigManager.fetch_datafile'):
406+
project_config_manager = config_manager.PollingConfigManager(sdk_key=sdk_key, logger=mock_logger)
407+
expected_datafile_url = enums.ConfigManager.DATAFILE_URL_TEMPLATE.format(sdk_key=sdk_key)
408+
test_headers = {'Last-Modified': 'New Time'}
409+
test_datafile = json.dumps(self.config_dict_with_features)
410+
test_response = requests.Response()
411+
test_response.status_code = 200
412+
test_response.headers = test_headers
413+
test_response._content = test_datafile
414+
with mock.patch('requests.get', return_value=test_response):
415+
project_config_manager.fetch_datafile()
416+
417+
self.assertEqual(test_headers['Last-Modified'], project_config_manager.last_modified)
418+
self.assertIsInstance(project_config_manager.get_config(), project_config.ProjectConfig)
419+
420+
# Call fetch_datafile again, but raise exception this time
421+
with mock.patch('requests.get', return_value=MockExceptionResponse()) as mock_requests:
422+
project_config_manager.fetch_datafile()
423+
424+
mock_requests.assert_called_once_with(
425+
expected_datafile_url,
426+
headers={'If-Modified-Since': test_headers['Last-Modified']},
427+
timeout=enums.ConfigManager.REQUEST_TIMEOUT,
428+
)
429+
mock_logger.error.assert_called_once_with('Fetching datafile from {} failed. Error: Error Error !!'.format(
430+
expected_datafile_url
431+
))
432+
self.assertEqual(test_headers['Last-Modified'], project_config_manager.last_modified)
433+
self.assertIsInstance(project_config_manager.get_config(), project_config.ProjectConfig)
434+
# Confirm that config manager keeps running
435+
self.assertTrue(project_config_manager.is_running)
395436

396437
def test_is_running(self, _):
397438
""" Test that polling thread is running after instance of PollingConfigManager is created. """

0 commit comments

Comments
 (0)