diff --git a/splitio/api/impressions.py b/splitio/api/impressions.py index 4d1993ae..19c79a88 100644 --- a/splitio/api/impressions.py +++ b/splitio/api/impressions.py @@ -37,7 +37,8 @@ def _build_bulk(impressions): 'c': impression.change_number, 'r': impression.label, 'b': impression.bucketing_key, - 'pt': impression.previous_time + 'pt': impression.previous_time, + 'properties': impression.properties } for impression in imps ] diff --git a/splitio/client/client.py b/splitio/client/client.py index ca5df5fa..94413289 100644 --- a/splitio/client/client.py +++ b/splitio/client/client.py @@ -137,7 +137,7 @@ def _build_impression(self, key, bucketing, feature, result, properties=None): bucketing_key=bucketing, time=utctime_ms(), previous_time=None, - properties=json.dumps(properties)), + properties=json.dumps(properties) if properties is not None else None), disabled=result['impressions_disabled']) def _build_impressions(self, key, bucketing, results, properties=None): diff --git a/splitio/storage/pluggable.py b/splitio/storage/pluggable.py index 36b27d7d..71e487c6 100644 --- a/splitio/storage/pluggable.py +++ b/splitio/storage/pluggable.py @@ -1231,6 +1231,7 @@ def _wrap_impressions(self, impressions): 'r': impression.label, 'c': impression.change_number, 'm': impression.time, + 'properties': impression.properties } } bulk_impressions.append(json.dumps(to_store)) diff --git a/splitio/storage/redis.py b/splitio/storage/redis.py index 09ddee29..ad1badf0 100644 --- a/splitio/storage/redis.py +++ b/splitio/storage/redis.py @@ -1100,6 +1100,7 @@ def _wrap_impressions(self, impressions): 'r': impression.label, 'c': impression.change_number, 'm': impression.time, + 'properties': impression.properties } } bulk_impressions.append(json.dumps(to_store)) diff --git a/tests/api/test_impressions_api.py b/tests/api/test_impressions_api.py index 63193021..2215aa04 100644 --- a/tests/api/test_impressions_api.py +++ b/tests/api/test_impressions_api.py @@ -14,20 +14,20 @@ from splitio.storage.inmemmory import InMemoryTelemetryStorage, InMemoryTelemetryStorageAsync impressions_mock = [ - Impression('k1', 'f1', 'on', 'l1', 123456, 'b1', 321654, {}), - Impression('k2', 'f2', 'off', 'l1', 123456, 'b1', 321654, {}), - Impression('k3', 'f1', 'on', 'l1', 123456, 'b1', 321654, {}) + Impression('k1', 'f1', 'on', 'l1', 123456, 'b1', 321654, None, {'prop': 'val'}), + Impression('k2', 'f2', 'off', 'l1', 123456, 'b1', 321654, None, None), + Impression('k3', 'f1', 'on', 'l1', 123456, 'b1', 321654, None, None) ] expectedImpressions = [{ 'f': 'f1', 'i': [ - {'k': 'k1', 'b': 'b1', 't': 'on', 'r': 'l1', 'm': 321654, 'c': 123456, 'pt': None}, - {'k': 'k3', 'b': 'b1', 't': 'on', 'r': 'l1', 'm': 321654, 'c': 123456, 'pt': None}, + {'k': 'k1', 'b': 'b1', 't': 'on', 'r': 'l1', 'm': 321654, 'c': 123456, 'pt': None, 'properties': {"prop": "val"}}, + {'k': 'k3', 'b': 'b1', 't': 'on', 'r': 'l1', 'm': 321654, 'c': 123456, 'pt': None, 'properties': None}, ], }, { 'f': 'f2', 'i': [ - {'k': 'k2', 'b': 'b1', 't': 'off', 'r': 'l1', 'm': 321654, 'c': 123456, 'pt': None}, + {'k': 'k2', 'b': 'b1', 't': 'off', 'r': 'l1', 'm': 321654, 'c': 123456, 'pt': None, 'properties': None}, ] }] diff --git a/tests/client/test_client.py b/tests/client/test_client.py index 601e0ecb..66c7c195 100644 --- a/tests/client/test_client.py +++ b/tests/client/test_client.py @@ -87,7 +87,7 @@ def synchronize_config(*_): } _logger = mocker.Mock() assert client.get_treatment('some_key', 'SPLIT_2') == 'on' - assert impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, 'null')] + assert impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, None)] assert _logger.mock_calls == [] # Test with client not ready @@ -96,7 +96,7 @@ def synchronize_config(*_): type(factory).ready = ready_property # pytest.set_trace() assert client.get_treatment('some_key', 'SPLIT_2', {'some_attribute': 1}) == 'control' - assert impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'control', Label.NOT_READY, None, None, 1000, None, 'null')] + assert impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'control', Label.NOT_READY, None, None, 1000, None, None)] # Test with exception: ready_property.return_value = True @@ -104,7 +104,7 @@ def _raise(*_): raise RuntimeError('something') client._evaluator.eval_with_context.side_effect = _raise assert client.get_treatment('some_key', 'SPLIT_2') == 'control' - assert impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'control', 'exception', None, None, 1000, None, 'null')] + assert impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'control', 'exception', None, None, 1000, None, None)] factory.destroy() def test_get_treatment_with_config(self, mocker): @@ -164,7 +164,7 @@ def synchronize_config(*_): 'some_key', 'SPLIT_2' ) == ('on', '{"some_config": True}') - assert impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, 'null')] + assert impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, None)] assert _logger.mock_calls == [] # Test with client not ready @@ -181,7 +181,7 @@ def _raise(*_): raise RuntimeError('something') client._evaluator.eval_with_context.side_effect = _raise assert client.get_treatment_with_config('some_key', 'SPLIT_2') == ('control', None) - assert impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'control', 'exception', None, None, 1000, None, 'null')] + assert impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'control', 'exception', None, None, 1000, None, None)] factory.destroy() def test_get_treatments(self, mocker): @@ -244,8 +244,8 @@ def synchronize_config(*_): assert treatments == {'SPLIT_2': 'on', 'SPLIT_1': 'on'} impressions_called = impression_storage.pop_many(100) - assert Impression('key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, 'null') in impressions_called - assert Impression('key', 'SPLIT_1', 'on', 'some_label', 123, None, 1000, None, 'null') in impressions_called + assert Impression('key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, None) in impressions_called + assert Impression('key', 'SPLIT_1', 'on', 'some_label', 123, None, 1000, None, None) in impressions_called assert _logger.mock_calls == [] # Test with client not ready @@ -323,8 +323,8 @@ def synchronize_config(*_): assert client.get_treatments_by_flag_set('key', 'set_1') == {'SPLIT_2': 'on', 'SPLIT_1': 'on'} impressions_called = impression_storage.pop_many(100) - assert Impression('key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, 'null') in impressions_called - assert Impression('key', 'SPLIT_1', 'on', 'some_label', 123, None, 1000, None, 'null') in impressions_called + assert Impression('key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, None) in impressions_called + assert Impression('key', 'SPLIT_1', 'on', 'some_label', 123, None, 1000, None, None) in impressions_called assert _logger.mock_calls == [] # Test with client not ready @@ -402,8 +402,8 @@ def synchronize_config(*_): assert client.get_treatments_by_flag_sets('key', ['set_1']) == {'SPLIT_2': 'on', 'SPLIT_1': 'on'} impressions_called = impression_storage.pop_many(100) - assert Impression('key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, 'null') in impressions_called - assert Impression('key', 'SPLIT_1', 'on', 'some_label', 123, None, 1000, None, 'null') in impressions_called + assert Impression('key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, None) in impressions_called + assert Impression('key', 'SPLIT_1', 'on', 'some_label', 123, None, 1000, None, None) in impressions_called assert _logger.mock_calls == [] # Test with client not ready @@ -482,8 +482,8 @@ def synchronize_config(*_): } impressions_called = impression_storage.pop_many(100) - assert Impression('key', 'SPLIT_1', 'on', 'some_label', 123, None, 1000, None, 'null') in impressions_called - assert Impression('key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, 'null') in impressions_called + assert Impression('key', 'SPLIT_1', 'on', 'some_label', 123, None, 1000, None, None) in impressions_called + assert Impression('key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, None) in impressions_called assert _logger.mock_calls == [] # Test with client not ready @@ -565,8 +565,8 @@ def synchronize_config(*_): } impressions_called = impression_storage.pop_many(100) - assert Impression('key', 'SPLIT_1', 'on', 'some_label', 123, None, 1000, None, 'null') in impressions_called - assert Impression('key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, 'null') in impressions_called + assert Impression('key', 'SPLIT_1', 'on', 'some_label', 123, None, 1000, None, None) in impressions_called + assert Impression('key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, None) in impressions_called assert _logger.mock_calls == [] # Test with client not ready @@ -645,8 +645,8 @@ def synchronize_config(*_): } impressions_called = impression_storage.pop_many(100) - assert Impression('key', 'SPLIT_1', 'on', 'some_label', 123, None, 1000, None, 'null') in impressions_called - assert Impression('key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, 'null') in impressions_called + assert Impression('key', 'SPLIT_1', 'on', 'some_label', 123, None, 1000, None, None) in impressions_called + assert Impression('key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, None) in impressions_called assert _logger.mock_calls == [] # Test with client not ready @@ -1331,12 +1331,12 @@ def synchronize_config(*_): assert impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, '{"prop": "value"}')] assert client.get_treatment('some_key', 'SPLIT_2', impressions_properties=12) == 'on' - assert impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, 'null')] + assert impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, None)] assert _logger.error.mock_calls == [mocker.call('%s: properties must be of type dictionary.', 'get_treatment')] _logger.reset_mock() assert client.get_treatment('some_key', 'SPLIT_2', impressions_properties='12') == 'on' - assert impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, 'null')] + assert impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, 1000, None)] assert _logger.error.mock_calls == [mocker.call('%s: properties must be of type dictionary.', 'get_treatment')] assert client.get_treatment_with_config('some_key', 'SPLIT_2', impressions_properties={"prop": "value"}) == ('on', None) @@ -1347,12 +1347,12 @@ def synchronize_config(*_): _logger.reset_mock() assert client.get_treatments('some_key', ['SPLIT_2'], impressions_properties="prop") == {'SPLIT_2': 'on'} - assert impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, 'null')] + assert impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, 1000, None)] assert _logger.error.mock_calls == [mocker.call('%s: properties must be of type dictionary.', 'get_treatments')] _logger.reset_mock() assert client.get_treatments('some_key', ['SPLIT_2'], impressions_properties=123) == {'SPLIT_2': 'on'} - assert impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, 'null')] + assert impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, 1000, None)] assert _logger.error.mock_calls == [mocker.call('%s: properties must be of type dictionary.', 'get_treatments')] assert client.get_treatments_with_config('some_key', ['SPLIT_2'], impressions_properties={"prop": "value"}) == {'SPLIT_2': ('on', None)} @@ -1425,7 +1425,7 @@ async def synchronize_config(*_): } _logger = mocker.Mock() assert await client.get_treatment('some_key', 'SPLIT_2') == 'on' - assert await impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, 'null')] + assert await impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, None)] assert _logger.mock_calls == [] # Test with client not ready @@ -1433,7 +1433,7 @@ async def synchronize_config(*_): ready_property.return_value = False type(factory).ready = ready_property assert await client.get_treatment('some_key', 'SPLIT_2', {'some_attribute': 1}) == 'control' - assert await impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'control', Label.NOT_READY, None, None, 1000, None, 'null')] + assert await impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'control', Label.NOT_READY, None, None, 1000, None, None)] # Test with exception: ready_property.return_value = True @@ -1441,7 +1441,7 @@ def _raise(*_): raise RuntimeError('something') client._evaluator.eval_with_context.side_effect = _raise assert await client.get_treatment('some_key', 'SPLIT_2') == 'control' - assert await impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'control', 'exception', None, None, 1000, None, 'null')] + assert await impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'control', 'exception', None, None, 1000, None, None)] await factory.destroy() @pytest.mark.asyncio @@ -1501,7 +1501,7 @@ async def synchronize_config(*_): 'some_key', 'SPLIT_2' ) == ('on', '{"some_config": True}') - assert await impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, 'null')] + assert await impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, None)] assert _logger.mock_calls == [] # Test with client not ready @@ -1518,7 +1518,7 @@ def _raise(*_): raise RuntimeError('something') client._evaluator.eval_with_context.side_effect = _raise assert await client.get_treatment_with_config('some_key', 'SPLIT_2') == ('control', None) - assert await impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'control', 'exception', None, None, 1000, None, 'null')] + assert await impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'control', 'exception', None, None, 1000, None, None)] await factory.destroy() @pytest.mark.asyncio @@ -1581,8 +1581,8 @@ async def synchronize_config(*_): assert await client.get_treatments('key', ['SPLIT_2', 'SPLIT_1']) == {'SPLIT_2': 'on', 'SPLIT_1': 'on'} impressions_called = await impression_storage.pop_many(100) - assert Impression('key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, 'null') in impressions_called - assert Impression('key', 'SPLIT_1', 'on', 'some_label', 123, None, 1000, None, 'null') in impressions_called + assert Impression('key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, None) in impressions_called + assert Impression('key', 'SPLIT_1', 'on', 'some_label', 123, None, 1000, None, None) in impressions_called assert _logger.mock_calls == [] # Test with client not ready @@ -1661,8 +1661,8 @@ async def synchronize_config(*_): assert await client.get_treatments_by_flag_set('key', 'set_1') == {'SPLIT_2': 'on', 'SPLIT_1': 'on'} impressions_called = await impression_storage.pop_many(100) - assert Impression('key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, 'null') in impressions_called - assert Impression('key', 'SPLIT_1', 'on', 'some_label', 123, None, 1000, None, 'null') in impressions_called + assert Impression('key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, None) in impressions_called + assert Impression('key', 'SPLIT_1', 'on', 'some_label', 123, None, 1000, None, None) in impressions_called assert _logger.mock_calls == [] # Test with client not ready @@ -1741,8 +1741,8 @@ async def synchronize_config(*_): assert await client.get_treatments_by_flag_sets('key', ['set_1']) == {'SPLIT_2': 'on', 'SPLIT_1': 'on'} impressions_called = await impression_storage.pop_many(100) - assert Impression('key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, 'null') in impressions_called - assert Impression('key', 'SPLIT_1', 'on', 'some_label', 123, None, 1000, None, 'null') in impressions_called + assert Impression('key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, None) in impressions_called + assert Impression('key', 'SPLIT_1', 'on', 'some_label', 123, None, 1000, None, None) in impressions_called assert _logger.mock_calls == [] # Test with client not ready @@ -1822,8 +1822,8 @@ async def synchronize_config(*_): } impressions_called = await impression_storage.pop_many(100) - assert Impression('key', 'SPLIT_1', 'on', 'some_label', 123, None, 1000, None, 'null') in impressions_called - assert Impression('key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, 'null') in impressions_called + assert Impression('key', 'SPLIT_1', 'on', 'some_label', 123, None, 1000, None, None) in impressions_called + assert Impression('key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, None) in impressions_called assert _logger.mock_calls == [] # Test with client not ready @@ -1906,8 +1906,8 @@ async def synchronize_config(*_): } impressions_called = await impression_storage.pop_many(100) - assert Impression('key', 'SPLIT_1', 'on', 'some_label', 123, None, 1000, None, 'null') in impressions_called - assert Impression('key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, 'null') in impressions_called + assert Impression('key', 'SPLIT_1', 'on', 'some_label', 123, None, 1000, None, None) in impressions_called + assert Impression('key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, None) in impressions_called assert _logger.mock_calls == [] # Test with client not ready @@ -1990,8 +1990,8 @@ async def synchronize_config(*_): } impressions_called = await impression_storage.pop_many(100) - assert Impression('key', 'SPLIT_1', 'on', 'some_label', 123, None, 1000, None, 'null') in impressions_called - assert Impression('key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, 'null') in impressions_called + assert Impression('key', 'SPLIT_1', 'on', 'some_label', 123, None, 1000, None, None) in impressions_called + assert Impression('key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, None) in impressions_called assert _logger.mock_calls == [] # Test with client not ready @@ -2488,7 +2488,7 @@ async def test_impressions_properties_async(self, mocker): impression_storage = InMemoryImpressionStorageAsync(10, telemetry_runtime_producer) event_storage = mocker.Mock(spec=EventStorage) impmanager = ImpressionManager(StrategyDebugMode(), StrategyNoneMode(), telemetry_runtime_producer) - recorder = StandardRecorderAsync(impmanager, event_storage, impression_storage, telemetry_producer.get_telemetry_evaluation_producer(), telemetry_producer.get_telemetry_runtime_producer()) + recorder = StandardRecorderAsync(impmanager, event_storage, impression_storage, telemetry_producer.get_telemetry_evaluation_producer(), telemetry_producer.get_telemetry_runtime_producer(), imp_counter=ImpressionsCounter()) await split_storage.update([from_raw(splits_json['splitChange1_1']['ff']['d'][0])], [], -1) destroyed_property = mocker.PropertyMock() @@ -2537,12 +2537,12 @@ async def synchronize_config(*_): assert await impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, '{"prop": "value"}')] assert await client.get_treatment('some_key', 'SPLIT_2', impressions_properties=12) == 'on' - assert await impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, 'null')] + assert await impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, None)] assert _logger.error.mock_calls == [mocker.call('%s: properties must be of type dictionary.', 'get_treatment')] _logger.reset_mock() assert await client.get_treatment('some_key', 'SPLIT_2', impressions_properties='12') == 'on' - assert await impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, 'null')] + assert await impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, 1000, None)] assert _logger.error.mock_calls == [mocker.call('%s: properties must be of type dictionary.', 'get_treatment')] assert await client.get_treatment_with_config('some_key', 'SPLIT_2', impressions_properties={"prop": "value"}) == ('on', None) @@ -2553,12 +2553,12 @@ async def synchronize_config(*_): _logger.reset_mock() assert await client.get_treatments('some_key', ['SPLIT_2'], impressions_properties="prop") == {'SPLIT_2': 'on'} - assert await impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, 'null')] + assert await impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, 1000, None)] assert _logger.error.mock_calls == [mocker.call('%s: properties must be of type dictionary.', 'get_treatments')] _logger.reset_mock() assert await client.get_treatments('some_key', ['SPLIT_2'], impressions_properties=123) == {'SPLIT_2': 'on'} - assert await impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, None, 'null')] + assert await impression_storage.pop_many(100) == [Impression('some_key', 'SPLIT_2', 'on', 'some_label', 123, None, 1000, 1000, None)] assert _logger.error.mock_calls == [mocker.call('%s: properties must be of type dictionary.', 'get_treatments')] assert await client.get_treatments_with_config('some_key', ['SPLIT_2'], impressions_properties={"prop": "value"}) == {'SPLIT_2': ('on', None)} diff --git a/tests/client/test_input_validator.py b/tests/client/test_input_validator.py index 1ba6b610..a5a1c91a 100644 --- a/tests/client/test_input_validator.py +++ b/tests/client/test_input_validator.py @@ -766,14 +766,14 @@ def test_track(self, mocker): _logger.reset_mock() assert client.track("some_key", "traffic_type", "event_type", 1, []) is False assert _logger.error.mock_calls == [ - mocker.call("track: properties must be of type dictionary.") + mocker.call("%s: properties must be of type dictionary.", "track") ] # Test track with invalid properties _logger.reset_mock() assert client.track("some_key", "traffic_type", "event_type", 1, True) is False assert _logger.error.mock_calls == [ - mocker.call("track: properties must be of type dictionary.") + mocker.call("%s: properties must be of type dictionary.", "track") ] # Test track with properties @@ -788,7 +788,7 @@ def test_track(self, mocker): _logger.reset_mock() assert client.track("some_key", "traffic_type", "event_type", 1, props1) is True assert _logger.warning.mock_calls == [ - mocker.call("Property %s is of invalid type. Setting value to None", []) + mocker.call("%s: Property %s is of invalid type. Setting value to None", "track", []) ] # Test track with more than 300 properties @@ -798,7 +798,7 @@ def test_track(self, mocker): _logger.reset_mock() assert client.track("some_key", "traffic_type", "event_type", 1, props2) is True assert _logger.warning.mock_calls == [ - mocker.call("Event has more than 300 properties. Some of them will be trimmed when processed") + mocker.call("%s: Event has more than 300 properties. Some of them will be trimmed when processed", "track") ] # Test track with properties higher than 32kb @@ -808,7 +808,7 @@ def test_track(self, mocker): props3["prop" + str(i)] = "a" * 300 assert client.track("some_key", "traffic_type", "event_type", 1, props3) is False assert _logger.error.mock_calls == [ - mocker.call("The maximum size allowed for the properties is 32768 bytes. Current one is 32952 bytes. Event not queued") + mocker.call("%s: The maximum size allowed for the properties is 32768 bytes. Current one is 32952 bytes. Event not queued", "track") ] factory.destroy @@ -2378,14 +2378,14 @@ async def is_valid_traffic_type(*_): _logger.reset_mock() assert await client.track("some_key", "traffic_type", "event_type", 1, []) is False assert _logger.error.mock_calls == [ - mocker.call("track: properties must be of type dictionary.") + mocker.call("%s: properties must be of type dictionary.", "track") ] # Test track with invalid properties _logger.reset_mock() assert await client.track("some_key", "traffic_type", "event_type", 1, True) is False assert _logger.error.mock_calls == [ - mocker.call("track: properties must be of type dictionary.") + mocker.call("%s: properties must be of type dictionary.", "track") ] # Test track with properties @@ -2400,7 +2400,7 @@ async def is_valid_traffic_type(*_): _logger.reset_mock() assert await client.track("some_key", "traffic_type", "event_type", 1, props1) is True assert _logger.warning.mock_calls == [ - mocker.call("Property %s is of invalid type. Setting value to None", []) + mocker.call("%s: Property %s is of invalid type. Setting value to None", "track", []) ] # Test track with more than 300 properties @@ -2410,7 +2410,7 @@ async def is_valid_traffic_type(*_): _logger.reset_mock() assert await client.track("some_key", "traffic_type", "event_type", 1, props2) is True assert _logger.warning.mock_calls == [ - mocker.call("Event has more than 300 properties. Some of them will be trimmed when processed") + mocker.call("%s: Event has more than 300 properties. Some of them will be trimmed when processed", "track") ] # Test track with properties higher than 32kb @@ -2420,7 +2420,7 @@ async def is_valid_traffic_type(*_): props3["prop" + str(i)] = "a" * 300 assert await client.track("some_key", "traffic_type", "event_type", 1, props3) is False assert _logger.error.mock_calls == [ - mocker.call("The maximum size allowed for the properties is 32768 bytes. Current one is 32952 bytes. Event not queued") + mocker.call("%s: The maximum size allowed for the properties is 32768 bytes. Current one is 32952 bytes. Event not queued", "track") ] await factory.destroy() diff --git a/tests/integration/test_client_e2e.py b/tests/integration/test_client_e2e.py index f50869cf..96384f55 100644 --- a/tests/integration/test_client_e2e.py +++ b/tests/integration/test_client_e2e.py @@ -49,6 +49,7 @@ def _validate_last_impressions(client, *to_validate): """Validate the last N impressions are present disregarding the order.""" imp_storage = client._factory._get_storage('impressions') + as_tup_set = set() if isinstance(client._factory._get_storage('splits'), RedisSplitStorage) or isinstance(client._factory._get_storage('splits'), PluggableSplitStorage): if isinstance(client._factory._get_storage('splits'), RedisSplitStorage): redis_client = imp_storage._redis @@ -64,15 +65,28 @@ def _validate_last_impressions(client, *to_validate): json.loads(i) for i in results ] - as_tup_set = set( - (i['i']['f'], i['i']['k'], i['i']['t']) - for i in impressions_raw - ) + if to_validate != (): + if len(to_validate[0]) == 3: + as_tup_set = set( + (i['i']['f'], i['i']['k'], i['i']['t']) + for i in impressions_raw + ) + else: + as_tup_set = set( + (i['i']['f'], i['i']['k'], i['i']['t'], i['i']['properties']) + for i in impressions_raw + ) + assert as_tup_set == set(to_validate) time.sleep(0.2) # delay for redis to sync else: impressions = imp_storage.pop_many(len(to_validate)) - as_tup_set = set((i.feature_name, i.matching_key, i.treatment) for i in impressions) + if to_validate != (): + if len(to_validate[0]) == 3: + as_tup_set = set((i.feature_name, i.matching_key, i.treatment) for i in impressions) + else: + as_tup_set = set((i.feature_name, i.matching_key, i.treatment, i.properties) for i in impressions) + assert as_tup_set == set(to_validate) def _validate_last_events(client, *to_validate): @@ -108,9 +122,9 @@ def _get_treatment(factory, skip_rbs=False): except: pass - assert client.get_treatment('user1', 'sample_feature') == 'on' + assert client.get_treatment('user1', 'sample_feature', impressions_properties={'prop':'value'}) == 'on' if not isinstance(factory._recorder._impressions_manager._strategy, StrategyNoneMode): - _validate_last_impressions(client, ('sample_feature', 'user1', 'on')) + _validate_last_impressions(client, ('sample_feature', 'user1', 'on', '{"prop": "value"}')) assert client.get_treatment('invalidKey', 'sample_feature') == 'off' if not isinstance(factory._recorder._impressions_manager._strategy, StrategyNoneMode): @@ -514,7 +528,7 @@ def setup_method(self): 'events': InMemoryEventStorage(5000, telemetry_runtime_producer), } impmanager = ImpressionsManager(StrategyDebugMode(), StrategyNoneMode(), telemetry_runtime_producer) # no listener - recorder = StandardRecorder(impmanager, storages['events'], storages['impressions'], telemetry_evaluation_producer, telemetry_runtime_producer) + recorder = StandardRecorder(impmanager, storages['events'], storages['impressions'], telemetry_evaluation_producer, telemetry_runtime_producer, imp_counter=ImpressionsCounter()) # Since we are passing None as SDK_Ready event, the factory will use the Redis telemetry call, using try catch to ignore the exception. try: self.factory = SplitFactory('some_api_key', @@ -674,7 +688,7 @@ def setup_method(self): 'events': InMemoryEventStorage(5000, telemetry_runtime_producer), } impmanager = ImpressionsManager(StrategyOptimizedMode(), StrategyNoneMode(), telemetry_runtime_producer) # no listener - recorder = StandardRecorder(impmanager, storages['events'], storages['impressions'], telemetry_evaluation_producer, telemetry_runtime_producer) + recorder = StandardRecorder(impmanager, storages['events'], storages['impressions'], telemetry_evaluation_producer, telemetry_runtime_producer, imp_counter=ImpressionsCounter()) self.factory = SplitFactory('some_api_key', storages, True, @@ -967,7 +981,7 @@ def setup_method(self): } impmanager = ImpressionsManager(StrategyDebugMode(), StrategyNoneMode(), telemetry_runtime_producer) # no listener recorder = PipelinedRecorder(redis_client.pipeline, impmanager, storages['events'], - storages['impressions'], telemetry_redis_storage) + storages['impressions'], telemetry_redis_storage, imp_counter=ImpressionsCounter()) self.factory = SplitFactory('some_api_key', storages, True, @@ -1155,7 +1169,7 @@ def setup_method(self): } impmanager = ImpressionsManager(StrategyDebugMode(), StrategyNoneMode(), telemetry_runtime_producer) # no listener recorder = PipelinedRecorder(redis_client.pipeline, impmanager, - storages['events'], storages['impressions'], telemetry_redis_storage) + storages['events'], storages['impressions'], telemetry_redis_storage, imp_counter=ImpressionsCounter()) self.factory = SplitFactory('some_api_key', storages, True, @@ -1375,7 +1389,7 @@ def setup_method(self): impmanager = ImpressionsManager(StrategyDebugMode(), StrategyNoneMode(), telemetry_runtime_producer) # no listener recorder = StandardRecorder(impmanager, storages['events'], - storages['impressions'], telemetry_evaluation_producer, telemetry_runtime_producer) + storages['impressions'], telemetry_evaluation_producer, telemetry_runtime_producer, imp_counter=ImpressionsCounter()) self.factory = SplitFactory('some_api_key', storages, @@ -1570,7 +1584,7 @@ def setup_method(self): impmanager = ImpressionsManager(StrategyOptimizedMode(), StrategyNoneMode(), telemetry_runtime_producer) # no listener recorder = StandardRecorder(impmanager, storages['events'], - storages['impressions'], telemetry_evaluation_producer, telemetry_runtime_producer) + storages['impressions'], telemetry_evaluation_producer, telemetry_runtime_producer, imp_counter=ImpressionsCounter()) self.factory = SplitFactory('some_api_key', storages, @@ -1617,7 +1631,7 @@ def test_get_treatment(self): client.get_treatment('user1', 'sample_feature') client.get_treatment('user1', 'sample_feature') client.get_treatment('user1', 'sample_feature') - assert self.pluggable_storage_adapter._keys['SPLITIO.impressions'] == [] + assert len(self.pluggable_storage_adapter._keys['SPLITIO.impressions']) == 1 def test_get_treatment_with_config(self): """Test client.get_treatment_with_config().""" @@ -2317,7 +2331,7 @@ async def _setup_method(self): 'events': InMemoryEventStorageAsync(5000, telemetry_runtime_producer), } impmanager = ImpressionsManager(StrategyDebugMode(), StrategyNoneMode(), telemetry_runtime_producer) # no listener - recorder = StandardRecorderAsync(impmanager, storages['events'], storages['impressions'], telemetry_evaluation_producer, telemetry_runtime_producer) + recorder = StandardRecorderAsync(impmanager, storages['events'], storages['impressions'], telemetry_evaluation_producer, telemetry_runtime_producer, imp_counter=ImpressionsCounter()) # Since we are passing None as SDK_Ready event, the factory will use the Redis telemetry call, using try catch to ignore the exception. try: self.factory = SplitFactoryAsync('some_api_key', @@ -2839,7 +2853,7 @@ async def _setup_method(self): } impmanager = ImpressionsManager(StrategyDebugMode(), StrategyNoneMode(), telemetry_runtime_producer) # no listener recorder = PipelinedRecorderAsync(redis_client.pipeline, impmanager, storages['events'], - storages['impressions'], telemetry_redis_storage) + storages['impressions'], telemetry_redis_storage, imp_counter=ImpressionsCounter()) self.factory = SplitFactoryAsync('some_api_key', storages, True, @@ -3061,7 +3075,7 @@ async def _setup_method(self): } impmanager = ImpressionsManager(StrategyDebugMode(), StrategyNoneMode(), telemetry_runtime_producer) # no listener recorder = PipelinedRecorderAsync(redis_client.pipeline, impmanager, storages['events'], - storages['impressions'], telemetry_redis_storage) + storages['impressions'], telemetry_redis_storage, imp_counter=ImpressionsCounter()) self.factory = SplitFactoryAsync('some_api_key', storages, True, @@ -3293,7 +3307,7 @@ async def _setup_method(self): recorder = StandardRecorderAsync(impmanager, storages['events'], storages['impressions'], telemetry_producer.get_telemetry_evaluation_producer(), - telemetry_runtime_producer) + telemetry_runtime_producer, imp_counter=ImpressionsCounter()) self.factory = SplitFactoryAsync('some_api_key', storages, diff --git a/tests/integration/test_pluggable_integration.py b/tests/integration/test_pluggable_integration.py index 20545da5..59534193 100644 --- a/tests/integration/test_pluggable_integration.py +++ b/tests/integration/test_pluggable_integration.py @@ -158,9 +158,9 @@ class PluggableImpressionsStorageIntegrationTests(object): def _put_impressions(self, adapter, metadata): storage = PluggableImpressionsStorage(adapter, metadata) storage.put([ - impressions.Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654), - impressions.Impression('key2', 'feature1', 'on', 'l1', 123456, 'b1', 321654), - impressions.Impression('key3', 'feature1', 'on', 'l1', 123456, 'b1', 321654) + impressions.Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None), + impressions.Impression('key2', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None), + impressions.Impression('key3', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None) ]) diff --git a/tests/integration/test_redis_integration.py b/tests/integration/test_redis_integration.py index 4b70898b..4c85beda 100644 --- a/tests/integration/test_redis_integration.py +++ b/tests/integration/test_redis_integration.py @@ -161,9 +161,9 @@ class RedisImpressionsStorageTests(object): def _put_impressions(self, adapter, metadata): storage = RedisImpressionsStorage(adapter, metadata) storage.put([ - impressions.Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654), - impressions.Impression('key2', 'feature1', 'on', 'l1', 123456, 'b1', 321654), - impressions.Impression('key3', 'feature1', 'on', 'l1', 123456, 'b1', 321654) + impressions.Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None), + impressions.Impression('key2', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None), + impressions.Impression('key3', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None) ]) @@ -394,9 +394,9 @@ class RedisImpressionsStorageAsyncTests(object): async def _put_impressions(self, adapter, metadata): storage = RedisImpressionsStorageAsync(adapter, metadata) await storage.put([ - impressions.Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654), - impressions.Impression('key2', 'feature1', 'on', 'l1', 123456, 'b1', 321654), - impressions.Impression('key3', 'feature1', 'on', 'l1', 123456, 'b1', 321654) + impressions.Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None), + impressions.Impression('key2', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None), + impressions.Impression('key3', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None) ]) diff --git a/tests/recorder/test_recorder.py b/tests/recorder/test_recorder.py index e7a32711..cf226613 100644 --- a/tests/recorder/test_recorder.py +++ b/tests/recorder/test_recorder.py @@ -20,13 +20,13 @@ class StandardRecorderTests(object): def test_standard_recorder(self, mocker): impressions = [ - Impression('k1', 'f1', 'on', 'l1', 123, None, None), - Impression('k1', 'f2', 'on', 'l1', 123, None, None) + Impression('k1', 'f1', 'on', 'l1', 123, None, None, None, None), + Impression('k1', 'f2', 'on', 'l1', 123, None, None, None, None) ] impmanager = mocker.Mock(spec=ImpressionsManager) impmanager.process_impressions.return_value = impressions, 0, [ - (Impression('k1', 'f1', 'on', 'l1', 123, None, None), None), - (Impression('k1', 'f2', 'on', 'l1', 123, None, None), None)], \ + (Impression('k1', 'f1', 'on', 'l1', 123, None, None, None, None), None), + (Impression('k1', 'f2', 'on', 'l1', 123, None, None, None, None), None)], \ [{"f": "f1", "ks": ["l1"]}, {"f": "f2", "ks": ["l1"]}], [('k1', 'f1'), ('k1', 'f2')] event = mocker.Mock(spec=EventStorage) impression = mocker.Mock(spec=ImpressionStorage) @@ -49,16 +49,16 @@ def record_latency(*args, **kwargs): assert(self.passed_args[0] == MethodExceptionsAndLatencies.TREATMENT) assert(self.passed_args[1] == 1) assert listener.log_impression.mock_calls == [ - mocker.call(Impression('k1', 'f1', 'on', 'l1', 123, None, None), None), - mocker.call(Impression('k1', 'f2', 'on', 'l1', 123, None, None), None) + mocker.call(Impression('k1', 'f1', 'on', 'l1', 123, None, None, None, None), None), + mocker.call(Impression('k1', 'f2', 'on', 'l1', 123, None, None, None, None), None) ] assert recorder._imp_counter.track.mock_calls == [mocker.call([{"f": "f1", "ks": ["l1"]}, {"f": "f2", "ks": ["l1"]}])] assert recorder._unique_keys_tracker.track.mock_calls == [mocker.call('k1', 'f1'), mocker.call('k1', 'f2')] def test_pipelined_recorder(self, mocker): impressions = [ - Impression('k1', 'f1', 'on', 'l1', 123, None, None), - Impression('k1', 'f2', 'on', 'l1', 123, None, None) + Impression('k1', 'f1', 'on', 'l1', 123, None, None, None, None), + Impression('k1', 'f2', 'on', 'l1', 123, None, None, None, None) ] redis = mocker.Mock(spec=RedisAdapter) def execute(): @@ -67,8 +67,8 @@ def execute(): impmanager = mocker.Mock(spec=ImpressionsManager) impmanager.process_impressions.return_value = impressions, 0, [ - (Impression('k1', 'f1', 'on', 'l1', 123, None, None), None), - (Impression('k1', 'f2', 'on', 'l1', 123, None, None), None)], \ + (Impression('k1', 'f1', 'on', 'l1', 123, None, None, None, None), None), + (Impression('k1', 'f2', 'on', 'l1', 123, None, None, None, None), None)], \ [{"f": "f1", "ks": ["l1"]}, {"f": "f2", "ks": ["l1"]}], [('k1', 'f1'), ('k1', 'f2')] event = mocker.Mock(spec=RedisEventsStorage) impression = mocker.Mock(spec=RedisImpressionsStorage) @@ -83,22 +83,22 @@ def execute(): assert recorder._telemetry_redis_storage.add_latency_to_pipe.mock_calls[0][1][0] == MethodExceptionsAndLatencies.TREATMENT assert recorder._telemetry_redis_storage.add_latency_to_pipe.mock_calls[0][1][1] == 1 assert listener.log_impression.mock_calls == [ - mocker.call(Impression('k1', 'f1', 'on', 'l1', 123, None, None), None), - mocker.call(Impression('k1', 'f2', 'on', 'l1', 123, None, None), None) + mocker.call(Impression('k1', 'f1', 'on', 'l1', 123, None, None, None, None), None), + mocker.call(Impression('k1', 'f2', 'on', 'l1', 123, None, None, None, None), None) ] assert recorder._imp_counter.track.mock_calls == [mocker.call([{"f": "f1", "ks": ["l1"]}, {"f": "f2", "ks": ["l1"]}])] assert recorder._unique_keys_tracker.track.mock_calls == [mocker.call('k1', 'f1'), mocker.call('k1', 'f2')] def test_sampled_recorder(self, mocker): impressions = [ - Impression('k1', 'f1', 'on', 'l1', 123, None, None), - Impression('k1', 'f2', 'on', 'l1', 123, None, None) + Impression('k1', 'f1', 'on', 'l1', 123, None, None, None, None), + Impression('k1', 'f2', 'on', 'l1', 123, None, None, None, None) ] redis = mocker.Mock(spec=RedisAdapter) impmanager = mocker.Mock(spec=ImpressionsManager) impmanager.process_impressions.return_value = impressions, 0, [ - (Impression('k1', 'f1', 'on', 'l1', 123, None, None), None), - (Impression('k1', 'f2', 'on', 'l1', 123, None, None), None) + (Impression('k1', 'f1', 'on', 'l1', 123, None, None, None, None), None), + (Impression('k1', 'f2', 'on', 'l1', 123, None, None, None, None), None) ], [], [] event = mocker.Mock(spec=EventStorage) @@ -124,13 +124,13 @@ class StandardRecorderAsyncTests(object): @pytest.mark.asyncio async def test_standard_recorder(self, mocker): impressions = [ - Impression('k1', 'f1', 'on', 'l1', 123, None, None), - Impression('k1', 'f2', 'on', 'l1', 123, None, None) + Impression('k1', 'f1', 'on', 'l1', 123, None, None, None, None), + Impression('k1', 'f2', 'on', 'l1', 123, None, None, None, None) ] impmanager = mocker.Mock(spec=ImpressionsManager) impmanager.process_impressions.return_value = impressions, 0, [ - (Impression('k1', 'f1', 'on', 'l1', 123, None, None), {'att1': 'val'}), - (Impression('k1', 'f2', 'on', 'l1', 123, None, None), None)], \ + (Impression('k1', 'f1', 'on', 'l1', 123, None, None, None, None), {'att1': 'val'}), + (Impression('k1', 'f2', 'on', 'l1', 123, None, None, None, None), None)], \ [{"f": "f1", "ks": ["l1"]}, {"f": "f2", "ks": ["l1"]}], [('k1', 'f1'), ('k1', 'f2')] event = mocker.Mock(spec=InMemoryEventStorageAsync) impression = mocker.Mock(spec=InMemoryImpressionStorageAsync) @@ -175,8 +175,8 @@ async def track2(x, y): assert(self.passed_args[0] == MethodExceptionsAndLatencies.TREATMENT) assert(self.passed_args[1] == 1) assert self.listener_impressions == [ - Impression('k1', 'f1', 'on', 'l1', 123, None, None), - Impression('k1', 'f2', 'on', 'l1', 123, None, None), + Impression('k1', 'f1', 'on', 'l1', 123, None, None, None, None), + Impression('k1', 'f2', 'on', 'l1', 123, None, None, None, None), ] assert self.listener_attributes == [{'att1': 'val'}, None] assert self.count == [{"f": "f1", "ks": ["l1"]}, {"f": "f2", "ks": ["l1"]}] @@ -185,8 +185,8 @@ async def track2(x, y): @pytest.mark.asyncio async def test_pipelined_recorder(self, mocker): impressions = [ - Impression('k1', 'f1', 'on', 'l1', 123, None, None), - Impression('k1', 'f2', 'on', 'l1', 123, None, None) + Impression('k1', 'f1', 'on', 'l1', 123, None, None, None, None), + Impression('k1', 'f2', 'on', 'l1', 123, None, None, None, None) ] redis = mocker.Mock(spec=RedisAdapterAsync) async def execute(): @@ -194,8 +194,8 @@ async def execute(): redis().execute = execute impmanager = mocker.Mock(spec=ImpressionsManager) impmanager.process_impressions.return_value = impressions, 0, [ - (Impression('k1', 'f1', 'on', 'l1', 123, None, None), {'att1': 'val'}), - (Impression('k1', 'f2', 'on', 'l1', 123, None, None), None)], \ + (Impression('k1', 'f1', 'on', 'l1', 123, None, None, None, None), {'att1': 'val'}), + (Impression('k1', 'f2', 'on', 'l1', 123, None, None, None, None), None)], \ [{"f": "f1", "ks": ["l1"]}, {"f": "f2", "ks": ["l1"]}], [('k1', 'f1'), ('k1', 'f2')] event = mocker.Mock(spec=RedisEventsStorageAsync) impression = mocker.Mock(spec=RedisImpressionsStorageAsync) @@ -227,8 +227,8 @@ async def track2(x, y): assert recorder._telemetry_redis_storage.add_latency_to_pipe.mock_calls[0][1][0] == MethodExceptionsAndLatencies.TREATMENT assert recorder._telemetry_redis_storage.add_latency_to_pipe.mock_calls[0][1][1] == 1 assert self.listener_impressions == [ - Impression('k1', 'f1', 'on', 'l1', 123, None, None), - Impression('k1', 'f2', 'on', 'l1', 123, None, None), + Impression('k1', 'f1', 'on', 'l1', 123, None, None, None, None), + Impression('k1', 'f2', 'on', 'l1', 123, None, None, None, None), ] assert self.listener_attributes == [{'att1': 'val'}, None] assert self.count == [{"f": "f1", "ks": ["l1"]}, {"f": "f2", "ks": ["l1"]}] @@ -237,14 +237,14 @@ async def track2(x, y): @pytest.mark.asyncio async def test_sampled_recorder(self, mocker): impressions = [ - Impression('k1', 'f1', 'on', 'l1', 123, None, None), - Impression('k1', 'f2', 'on', 'l1', 123, None, None) + Impression('k1', 'f1', 'on', 'l1', 123, None, None, None, None), + Impression('k1', 'f2', 'on', 'l1', 123, None, None, None, None) ] redis = mocker.Mock(spec=RedisAdapterAsync) impmanager = mocker.Mock(spec=ImpressionsManager) impmanager.process_impressions.return_value = impressions, 0, [ - (Impression('k1', 'f1', 'on', 'l1', 123, None, None), None), - (Impression('k1', 'f2', 'on', 'l1', 123, None, None), None) + (Impression('k1', 'f1', 'on', 'l1', 123, None, None, None, None), None), + (Impression('k1', 'f2', 'on', 'l1', 123, None, None, None, None), None) ], [], [] event = mocker.Mock(spec=RedisEventsStorageAsync) impression = mocker.Mock(spec=RedisImpressionsStorageAsync) diff --git a/tests/storage/test_inmemory_storage.py b/tests/storage/test_inmemory_storage.py index 9c5b6ed2..2bb113d7 100644 --- a/tests/storage/test_inmemory_storage.py +++ b/tests/storage/test_inmemory_storage.py @@ -794,39 +794,39 @@ def test_push_pop_impressions(self, mocker): telemetry_producer = TelemetryStorageProducer(telemetry_storage) telemetry_runtime_producer = telemetry_producer.get_telemetry_runtime_producer() storage = InMemoryImpressionStorage(100, telemetry_runtime_producer) - storage.put([Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654)]) - storage.put([Impression('key2', 'feature1', 'on', 'l1', 123456, 'b1', 321654)]) - storage.put([Impression('key3', 'feature1', 'on', 'l1', 123456, 'b1', 321654)]) + storage.put([Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None)]) + storage.put([Impression('key2', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None)]) + storage.put([Impression('key3', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None)]) assert(telemetry_storage._counters._impressions_queued == 3) # Assert impressions are retrieved in the same order they are inserted. assert storage.pop_many(1) == [ - Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654) + Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None) ] assert storage.pop_many(1) == [ - Impression('key2', 'feature1', 'on', 'l1', 123456, 'b1', 321654) + Impression('key2', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None) ] assert storage.pop_many(1) == [ - Impression('key3', 'feature1', 'on', 'l1', 123456, 'b1', 321654) + Impression('key3', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None) ] # Assert inserting multiple impressions at once works and maintains order. impressions = [ - Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654), - Impression('key2', 'feature1', 'on', 'l1', 123456, 'b1', 321654), - Impression('key3', 'feature1', 'on', 'l1', 123456, 'b1', 321654) + Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None), + Impression('key2', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None), + Impression('key3', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None) ] assert storage.put(impressions) # Assert impressions are retrieved in the same order they are inserted. assert storage.pop_many(1) == [ - Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654) + Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None) ] assert storage.pop_many(1) == [ - Impression('key2', 'feature1', 'on', 'l1', 123456, 'b1', 321654) + Impression('key2', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None) ] assert storage.pop_many(1) == [ - Impression('key3', 'feature1', 'on', 'l1', 123456, 'b1', 321654) + Impression('key3', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None) ] def test_queue_full_hook(self, mocker): @@ -835,7 +835,7 @@ def test_queue_full_hook(self, mocker): queue_full_hook = mocker.Mock() storage.set_queue_full_hook(queue_full_hook) impressions = [ - Impression('key%d' % i, 'feature1', 'on', 'l1', 123456, 'b1', 321654) + Impression('key%d' % i, 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None) for i in range(0, 101) ] storage.put(impressions) @@ -844,7 +844,7 @@ def test_queue_full_hook(self, mocker): def test_clear(self, mocker): """Test clear method.""" storage = InMemoryImpressionStorage(100, mocker.Mock()) - storage.put([Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654)]) + storage.put([Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None)]) assert storage._impressions.qsize() == 1 storage.clear() @@ -856,9 +856,9 @@ def test_impressions_dropped(self, mocker): telemetry_producer = TelemetryStorageProducer(telemetry_storage) telemetry_runtime_producer = telemetry_producer.get_telemetry_runtime_producer() storage = InMemoryImpressionStorage(2, telemetry_runtime_producer) - storage.put([Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654)]) - storage.put([Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654)]) - storage.put([Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654)]) + storage.put([Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None)]) + storage.put([Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None)]) + storage.put([Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None)]) assert(telemetry_storage._counters._impressions_dropped == 1) assert(telemetry_storage._counters._impressions_queued == 2) @@ -873,39 +873,39 @@ async def test_push_pop_impressions(self, mocker): telemetry_producer = TelemetryStorageProducerAsync(telemetry_storage) telemetry_runtime_producer = telemetry_producer.get_telemetry_runtime_producer() storage = InMemoryImpressionStorageAsync(100, telemetry_runtime_producer) - await storage.put([Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654)]) - await storage.put([Impression('key2', 'feature1', 'on', 'l1', 123456, 'b1', 321654)]) - await storage.put([Impression('key3', 'feature1', 'on', 'l1', 123456, 'b1', 321654)]) + await storage.put([Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None)]) + await storage.put([Impression('key2', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None)]) + await storage.put([Impression('key3', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None)]) assert(telemetry_storage._counters._impressions_queued == 3) # Assert impressions are retrieved in the same order they are inserted. assert await storage.pop_many(1) == [ - Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654) + Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None) ] assert await storage.pop_many(1) == [ - Impression('key2', 'feature1', 'on', 'l1', 123456, 'b1', 321654) + Impression('key2', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None) ] assert await storage.pop_many(1) == [ - Impression('key3', 'feature1', 'on', 'l1', 123456, 'b1', 321654) + Impression('key3', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None) ] # Assert inserting multiple impressions at once works and maintains order. impressions = [ - Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654), - Impression('key2', 'feature1', 'on', 'l1', 123456, 'b1', 321654), - Impression('key3', 'feature1', 'on', 'l1', 123456, 'b1', 321654) + Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None), + Impression('key2', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None), + Impression('key3', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None) ] assert await storage.put(impressions) # Assert impressions are retrieved in the same order they are inserted. assert await storage.pop_many(1) == [ - Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654) + Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None) ] assert await storage.pop_many(1) == [ - Impression('key2', 'feature1', 'on', 'l1', 123456, 'b1', 321654) + Impression('key2', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None) ] assert await storage.pop_many(1) == [ - Impression('key3', 'feature1', 'on', 'l1', 123456, 'b1', 321654) + Impression('key3', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None) ] @pytest.mark.asyncio @@ -921,7 +921,7 @@ async def queue_full_hook(): storage.set_queue_full_hook(queue_full_hook) impressions = [ - Impression('key%d' % i, 'feature1', 'on', 'l1', 123456, 'b1', 321654) + Impression('key%d' % i, 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None) for i in range(0, 101) ] await storage.put(impressions) @@ -935,7 +935,7 @@ async def test_clear(self, mocker): telemetry_producer = TelemetryStorageProducerAsync(telemetry_storage) telemetry_runtime_producer = telemetry_producer.get_telemetry_runtime_producer() storage = InMemoryImpressionStorageAsync(100, telemetry_runtime_producer) - await storage.put([Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654)]) + await storage.put([Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None)]) assert storage._impressions.qsize() == 1 await storage.clear() assert storage._impressions.qsize() == 0 @@ -947,9 +947,9 @@ async def test_impressions_dropped(self, mocker): telemetry_producer = TelemetryStorageProducerAsync(telemetry_storage) telemetry_runtime_producer = telemetry_producer.get_telemetry_runtime_producer() storage = InMemoryImpressionStorageAsync(2, telemetry_runtime_producer) - await storage.put([Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654)]) - await storage.put([Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654)]) - await storage.put([Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654)]) + await storage.put([Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None)]) + await storage.put([Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None)]) + await storage.put([Impression('key1', 'feature1', 'on', 'l1', 123456, 'b1', 321654, None, None)]) assert(telemetry_storage._counters._impressions_dropped == 1) assert(telemetry_storage._counters._impressions_queued == 2) diff --git a/tests/storage/test_pluggable.py b/tests/storage/test_pluggable.py index 283eb8e3..8b5f9a95 100644 --- a/tests/storage/test_pluggable.py +++ b/tests/storage/test_pluggable.py @@ -646,10 +646,10 @@ def test_put(self): prefix = '' pluggable_imp_storage = PluggableImpressionsStorage(self.mock_adapter, self.metadata, prefix=sprefix) impressions = [ - Impression('key1', 'feature1', 'on', 'some_label', 123456, 'buck1', 321654), - Impression('key2', 'feature2', 'on', 'some_label', 123456, 'buck1', 321654), - Impression('key3', 'feature2', 'on', 'some_label', 123456, 'buck1', 321654), - Impression('key4', 'feature1', 'on', 'some_label', 123456, 'buck1', 321654) + Impression('key1', 'feature1', 'on', 'some_label', 123456, 'buck1', 321654, None, None), + Impression('key2', 'feature2', 'on', 'some_label', 123456, 'buck1', 321654, None, None), + Impression('key3', 'feature2', 'on', 'some_label', 123456, 'buck1', 321654, None, None), + Impression('key4', 'feature1', 'on', 'some_label', 123456, 'buck1', 321654, None, None) ] assert(pluggable_imp_storage.put(impressions)) assert(pluggable_imp_storage._impressions_queue_key in self.mock_adapter._keys) @@ -657,8 +657,8 @@ def test_put(self): assert(self.mock_adapter._expire[prefix + "SPLITIO.impressions"] == PluggableImpressionsStorage.IMPRESSIONS_KEY_DEFAULT_TTL) impressions2 = [ - Impression('key5', 'feature1', 'off', 'some_label', 123456, 'buck1', 321654), - Impression('key6', 'feature2', 'off', 'some_label', 123456, 'buck1', 321654), + Impression('key5', 'feature1', 'off', 'some_label', 123456, 'buck1', 321654, None, None), + Impression('key6', 'feature2', 'off', 'some_label', 123456, 'buck1', 321654, None, None), ] assert(pluggable_imp_storage.put(impressions2)) assert(self.mock_adapter._keys[prefix + "SPLITIO.impressions"] == pluggable_imp_storage._wrap_impressions(impressions + impressions2)) @@ -667,8 +667,8 @@ def test_wrap_impressions(self): for sprefix in [None, 'myprefix']: pluggable_imp_storage = PluggableImpressionsStorage(self.mock_adapter, self.metadata, prefix=sprefix) impressions = [ - Impression('key1', 'feature1', 'on', 'some_label', 123456, 'buck1', 321654), - Impression('key2', 'feature2', 'off', 'some_label', 123456, 'buck1', 321654), + Impression('key1', 'feature1', 'on', 'some_label', 123456, 'buck1', 321654, None, None), + Impression('key2', 'feature2', 'off', 'some_label', 123456, 'buck1', 321654, None, None), ] assert(pluggable_imp_storage._wrap_impressions(impressions) == [ json.dumps({ @@ -685,6 +685,7 @@ def test_wrap_impressions(self): 'r': 'some_label', 'c': 123456, 'm': 321654, + 'properties': None } }), json.dumps({ @@ -701,6 +702,7 @@ def test_wrap_impressions(self): 'r': 'some_label', 'c': 123456, 'm': 321654, + 'properties': None } }) ]) @@ -763,10 +765,10 @@ async def test_put(self): prefix = '' pluggable_imp_storage = PluggableImpressionsStorageAsync(self.mock_adapter, self.metadata, prefix=sprefix) impressions = [ - Impression('key1', 'feature1', 'on', 'some_label', 123456, 'buck1', 321654), - Impression('key2', 'feature2', 'on', 'some_label', 123456, 'buck1', 321654), - Impression('key3', 'feature2', 'on', 'some_label', 123456, 'buck1', 321654), - Impression('key4', 'feature1', 'on', 'some_label', 123456, 'buck1', 321654) + Impression('key1', 'feature1', 'on', 'some_label', 123456, 'buck1', 321654, None, None), + Impression('key2', 'feature2', 'on', 'some_label', 123456, 'buck1', 321654, None, None), + Impression('key3', 'feature2', 'on', 'some_label', 123456, 'buck1', 321654, None, None), + Impression('key4', 'feature1', 'on', 'some_label', 123456, 'buck1', 321654, None, None) ] assert(await pluggable_imp_storage.put(impressions)) assert(pluggable_imp_storage._impressions_queue_key in self.mock_adapter._keys) @@ -774,8 +776,8 @@ async def test_put(self): assert(self.mock_adapter._expire[prefix + "SPLITIO.impressions"] == PluggableImpressionsStorageAsync.IMPRESSIONS_KEY_DEFAULT_TTL) impressions2 = [ - Impression('key5', 'feature1', 'off', 'some_label', 123456, 'buck1', 321654), - Impression('key6', 'feature2', 'off', 'some_label', 123456, 'buck1', 321654), + Impression('key5', 'feature1', 'off', 'some_label', 123456, 'buck1', 321654, None, None), + Impression('key6', 'feature2', 'off', 'some_label', 123456, 'buck1', 321654, None, None), ] assert(await pluggable_imp_storage.put(impressions2)) assert(self.mock_adapter._keys[prefix + "SPLITIO.impressions"] == pluggable_imp_storage._wrap_impressions(impressions + impressions2)) @@ -784,8 +786,8 @@ def test_wrap_impressions(self): for sprefix in [None, 'myprefix']: pluggable_imp_storage = PluggableImpressionsStorageAsync(self.mock_adapter, self.metadata, prefix=sprefix) impressions = [ - Impression('key1', 'feature1', 'on', 'some_label', 123456, 'buck1', 321654), - Impression('key2', 'feature2', 'off', 'some_label', 123456, 'buck1', 321654), + Impression('key1', 'feature1', 'on', 'some_label', 123456, 'buck1', 321654, None, None), + Impression('key2', 'feature2', 'off', 'some_label', 123456, 'buck1', 321654, None, None), ] assert(pluggable_imp_storage._wrap_impressions(impressions) == [ json.dumps({ @@ -802,6 +804,7 @@ def test_wrap_impressions(self): 'r': 'some_label', 'c': 123456, 'm': 321654, + 'properties': None } }), json.dumps({ @@ -818,6 +821,7 @@ def test_wrap_impressions(self): 'r': 'some_label', 'c': 123456, 'm': 321654, + 'properties': None } }) ]) diff --git a/tests/storage/test_redis.py b/tests/storage/test_redis.py index 4537998c..de5ebfd5 100644 --- a/tests/storage/test_redis.py +++ b/tests/storage/test_redis.py @@ -587,10 +587,10 @@ def test_wrap_impressions(self, mocker): storage = RedisImpressionsStorage(adapter, metadata) impressions = [ - Impression('key1', 'feature1', 'on', 'some_label', 123456, 'buck1', 321654), - Impression('key2', 'feature2', 'on', 'some_label', 123456, 'buck1', 321654), - Impression('key3', 'feature2', 'on', 'some_label', 123456, 'buck1', 321654), - Impression('key4', 'feature1', 'on', 'some_label', 123456, 'buck1', 321654) + Impression('key1', 'feature1', 'on', 'some_label', 123456, 'buck1', 321654, None, None), + Impression('key2', 'feature2', 'on', 'some_label', 123456, 'buck1', 321654, None, None), + Impression('key3', 'feature2', 'on', 'some_label', 123456, 'buck1', 321654, None, None), + Impression('key4', 'feature1', 'on', 'some_label', 123456, 'buck1', 321654, None, None) ] to_validate = [json.dumps({ @@ -607,6 +607,7 @@ def test_wrap_impressions(self, mocker): 'r': impression.label, 'c': impression.change_number, 'm': impression.time, + 'properties': None } }) for impression in impressions] @@ -619,10 +620,10 @@ def test_add_impressions(self, mocker): storage = RedisImpressionsStorage(adapter, metadata) impressions = [ - Impression('key1', 'feature1', 'on', 'some_label', 123456, 'buck1', 321654), - Impression('key2', 'feature2', 'on', 'some_label', 123456, 'buck1', 321654), - Impression('key3', 'feature2', 'on', 'some_label', 123456, 'buck1', 321654), - Impression('key4', 'feature1', 'on', 'some_label', 123456, 'buck1', 321654) + Impression('key1', 'feature1', 'on', 'some_label', 123456, 'buck1', 321654, None, None), + Impression('key2', 'feature2', 'on', 'some_label', 123456, 'buck1', 321654, None, None), + Impression('key3', 'feature2', 'on', 'some_label', 123456, 'buck1', 321654, None, None), + Impression('key4', 'feature1', 'on', 'some_label', 123456, 'buck1', 321654, None, None) ] assert storage.put(impressions) is True @@ -641,6 +642,7 @@ def test_add_impressions(self, mocker): 'r': impression.label, 'c': impression.change_number, 'm': impression.time, + 'properties': None } }) for impression in impressions] @@ -661,10 +663,10 @@ def test_add_impressions_to_pipe(self, mocker): storage = RedisImpressionsStorage(adapter, metadata) impressions = [ - Impression('key1', 'feature1', 'on', 'some_label', 123456, 'buck1', 321654), - Impression('key2', 'feature2', 'on', 'some_label', 123456, 'buck1', 321654), - Impression('key3', 'feature2', 'on', 'some_label', 123456, 'buck1', 321654), - Impression('key4', 'feature1', 'on', 'some_label', 123456, 'buck1', 321654) + Impression('key1', 'feature1', 'on', 'some_label', 123456, 'buck1', 321654, None, None), + Impression('key2', 'feature2', 'on', 'some_label', 123456, 'buck1', 321654, None, None), + Impression('key3', 'feature2', 'on', 'some_label', 123456, 'buck1', 321654, None, None), + Impression('key4', 'feature1', 'on', 'some_label', 123456, 'buck1', 321654, None, None) ] to_validate = [json.dumps({ @@ -681,6 +683,7 @@ def test_add_impressions_to_pipe(self, mocker): 'r': impression.label, 'c': impression.change_number, 'm': impression.time, + 'properties': None } }) for impression in impressions] @@ -718,10 +721,10 @@ def test_wrap_impressions(self, mocker): storage = RedisImpressionsStorageAsync(adapter, metadata) impressions = [ - Impression('key1', 'feature1', 'on', 'some_label', 123456, 'buck1', 321654), - Impression('key2', 'feature2', 'on', 'some_label', 123456, 'buck1', 321654), - Impression('key3', 'feature2', 'on', 'some_label', 123456, 'buck1', 321654), - Impression('key4', 'feature1', 'on', 'some_label', 123456, 'buck1', 321654) + Impression('key1', 'feature1', 'on', 'some_label', 123456, 'buck1', 321654, None, None), + Impression('key2', 'feature2', 'on', 'some_label', 123456, 'buck1', 321654, None, None), + Impression('key3', 'feature2', 'on', 'some_label', 123456, 'buck1', 321654, None, None), + Impression('key4', 'feature1', 'on', 'some_label', 123456, 'buck1', 321654, None, None) ] to_validate = [json.dumps({ @@ -738,6 +741,7 @@ def test_wrap_impressions(self, mocker): 'r': impression.label, 'c': impression.change_number, 'm': impression.time, + 'properties': None } }) for impression in impressions] @@ -751,10 +755,10 @@ async def test_add_impressions(self, mocker): storage = RedisImpressionsStorageAsync(adapter, metadata) impressions = [ - Impression('key1', 'feature1', 'on', 'some_label', 123456, 'buck1', 321654), - Impression('key2', 'feature2', 'on', 'some_label', 123456, 'buck1', 321654), - Impression('key3', 'feature2', 'on', 'some_label', 123456, 'buck1', 321654), - Impression('key4', 'feature1', 'on', 'some_label', 123456, 'buck1', 321654) + Impression('key1', 'feature1', 'on', 'some_label', 123456, 'buck1', 321654, None, None), + Impression('key2', 'feature2', 'on', 'some_label', 123456, 'buck1', 321654, None, None), + Impression('key3', 'feature2', 'on', 'some_label', 123456, 'buck1', 321654, None, None), + Impression('key4', 'feature1', 'on', 'some_label', 123456, 'buck1', 321654, None, None) ] self.key = None self.imps = None @@ -779,6 +783,7 @@ async def rpush(key, *imps): 'r': impression.label, 'c': impression.change_number, 'm': impression.time, + 'properties': None } }) for impression in impressions] @@ -800,10 +805,10 @@ def test_add_impressions_to_pipe(self, mocker): storage = RedisImpressionsStorageAsync(adapter, metadata) impressions = [ - Impression('key1', 'feature1', 'on', 'some_label', 123456, 'buck1', 321654), - Impression('key2', 'feature2', 'on', 'some_label', 123456, 'buck1', 321654), - Impression('key3', 'feature2', 'on', 'some_label', 123456, 'buck1', 321654), - Impression('key4', 'feature1', 'on', 'some_label', 123456, 'buck1', 321654) + Impression('key1', 'feature1', 'on', 'some_label', 123456, 'buck1', 321654, None, None), + Impression('key2', 'feature2', 'on', 'some_label', 123456, 'buck1', 321654, None, None), + Impression('key3', 'feature2', 'on', 'some_label', 123456, 'buck1', 321654, None, None), + Impression('key4', 'feature1', 'on', 'some_label', 123456, 'buck1', 321654, None, None) ] to_validate = [json.dumps({ @@ -820,6 +825,7 @@ def test_add_impressions_to_pipe(self, mocker): 'r': impression.label, 'c': impression.change_number, 'm': impression.time, + 'properties': None } }) for impression in impressions] diff --git a/tests/sync/test_impressions_synchronizer.py b/tests/sync/test_impressions_synchronizer.py index 1deaa833..00b65833 100644 --- a/tests/sync/test_impressions_synchronizer.py +++ b/tests/sync/test_impressions_synchronizer.py @@ -17,8 +17,8 @@ class ImpressionsSynchronizerTests(object): def test_synchronize_impressions_error(self, mocker): storage = mocker.Mock(spec=ImpressionStorage) storage.pop_many.return_value = [ - Impression('key1', 'split1', 'on', 'l1', 123456, 'b1', 321654), - Impression('key2', 'split1', 'on', 'l1', 123456, 'b1', 321654), + Impression('key1', 'split1', 'on', 'l1', 123456, 'b1', 321654, None, None), + Impression('key2', 'split1', 'on', 'l1', 123456, 'b1', 321654, None, None), ] api = mocker.Mock() @@ -49,8 +49,8 @@ def run(x): def test_synchronize_impressions(self, mocker): storage = mocker.Mock(spec=ImpressionStorage) storage.pop_many.return_value = [ - Impression('key1', 'split1', 'on', 'l1', 123456, 'b1', 321654), - Impression('key2', 'split1', 'on', 'l1', 123456, 'b1', 321654), + Impression('key1', 'split1', 'on', 'l1', 123456, 'b1', 321654, None, None), + Impression('key2', 'split1', 'on', 'l1', 123456, 'b1', 321654, None, None), ] api = mocker.Mock() @@ -76,8 +76,8 @@ async def test_synchronize_impressions_error(self, mocker): storage = mocker.Mock(spec=ImpressionStorage) async def pop_many(*args): return [ - Impression('key1', 'split1', 'on', 'l1', 123456, 'b1', 321654), - Impression('key2', 'split1', 'on', 'l1', 123456, 'b1', 321654), + Impression('key1', 'split1', 'on', 'l1', 123456, 'b1', 321654, None, None), + Impression('key2', 'split1', 'on', 'l1', 123456, 'b1', 321654, None, None), ] storage.pop_many = pop_many api = mocker.Mock() @@ -113,8 +113,8 @@ async def test_synchronize_impressions(self, mocker): storage = mocker.Mock(spec=ImpressionStorage) async def pop_many(*args): return [ - Impression('key1', 'split1', 'on', 'l1', 123456, 'b1', 321654), - Impression('key2', 'split1', 'on', 'l1', 123456, 'b1', 321654), + Impression('key1', 'split1', 'on', 'l1', 123456, 'b1', 321654, None, None), + Impression('key2', 'split1', 'on', 'l1', 123456, 'b1', 321654, None, None), ] storage.pop_many = pop_many diff --git a/tests/tasks/test_impressions_sync.py b/tests/tasks/test_impressions_sync.py index f19be535..78bbf979 100644 --- a/tests/tasks/test_impressions_sync.py +++ b/tests/tasks/test_impressions_sync.py @@ -20,11 +20,11 @@ def test_normal_operation(self, mocker): """Test that the task works properly under normal circumstances.""" storage = mocker.Mock(spec=ImpressionStorage) impressions = [ - Impression('key1', 'split1', 'on', 'l1', 123456, 'b1', 321654), - Impression('key2', 'split1', 'on', 'l1', 123456, 'b1', 321654), - Impression('key3', 'split2', 'off', 'l1', 123456, 'b1', 321654), - Impression('key4', 'split2', 'on', 'l1', 123456, 'b1', 321654), - Impression('key5', 'split3', 'off', 'l1', 123456, 'b1', 321654) + Impression('key1', 'split1', 'on', 'l1', 123456, 'b1', 321654, None, None), + Impression('key2', 'split1', 'on', 'l1', 123456, 'b1', 321654, None, None), + Impression('key3', 'split2', 'off', 'l1', 123456, 'b1', 321654, None, None), + Impression('key4', 'split2', 'on', 'l1', 123456, 'b1', 321654, None, None), + Impression('key5', 'split3', 'off', 'l1', 123456, 'b1', 321654, None, None) ] storage.pop_many.return_value = impressions api = mocker.Mock(spec=ImpressionsAPI) @@ -55,11 +55,11 @@ async def test_normal_operation(self, mocker): """Test that the task works properly under normal circumstances.""" storage = mocker.Mock(spec=ImpressionStorage) impressions = [ - Impression('key1', 'split1', 'on', 'l1', 123456, 'b1', 321654), - Impression('key2', 'split1', 'on', 'l1', 123456, 'b1', 321654), - Impression('key3', 'split2', 'off', 'l1', 123456, 'b1', 321654), - Impression('key4', 'split2', 'on', 'l1', 123456, 'b1', 321654), - Impression('key5', 'split3', 'off', 'l1', 123456, 'b1', 321654) + Impression('key1', 'split1', 'on', 'l1', 123456, 'b1', 321654, None, None), + Impression('key2', 'split1', 'on', 'l1', 123456, 'b1', 321654, None, None), + Impression('key3', 'split2', 'off', 'l1', 123456, 'b1', 321654, None, None), + Impression('key4', 'split2', 'on', 'l1', 123456, 'b1', 321654, None, None), + Impression('key5', 'split3', 'off', 'l1', 123456, 'b1', 321654, None, None) ] self.pop_called = 0 async def pop_many(*args):