def test_add_events(self, mocker): """Test that adding impressions to storage works.""" adapter = mocker.Mock(spec=RedisAdapter) metadata = get_metadata({}) storage = RedisEventsStorage(adapter, metadata) events = [ EventWrapper(event=Event('key1', 'user', 'purchase', 10, 123456, None), size=32768), EventWrapper(event=Event('key2', 'user', 'purchase', 10, 123456, None), size=32768), EventWrapper(event=Event('key3', 'user', 'purchase', 10, 123456, None), size=32768), EventWrapper(event=Event('key4', 'user', 'purchase', 10, 123456, None), size=32768), ] assert storage.put(events) is True list_of_raw_events = [json.dumps({ 'm': { # METADATA PORTION 's': metadata.sdk_version, 'n': metadata.instance_name, 'i': metadata.instance_ip, }, 'e': { # EVENT PORTION 'key': e.event.key, 'trafficTypeName': e.event.traffic_type_name, 'eventTypeId': e.event.event_type_id, 'value': e.event.value, 'timestamp': e.event.timestamp, 'properties': e.event.properties, } }) for e in events] # To deal with python2 & 3 differences in hashing/order when dumping json. list_of_raw_json_strings_called = adapter.rpush.mock_calls[0][1][1:] list_of_events_called = [ json.loads(event) for event in list_of_raw_json_strings_called ] list_of_events_sent = [ json.loads(event) for event in list_of_raw_events ] for item in list_of_events_sent: assert item in list_of_events_called # assert adapter.rpush.mock_calls == [mocker.call('SPLITIO.events', to_validate)] # Assert that if an exception is thrown it's caught and False is returned adapter.reset_mock() def _raise_exc(*_): raise RedisAdapterException('something') adapter.rpush.side_effect = _raise_exc assert storage.put(events) is False
def test_put_pop_events(self, mocker): """Test storing and fetching events.""" uwsgi = get_uwsgi(True) storage = UWSGIEventStorage(uwsgi) events = [ EventWrapper(event=Event('key1', 'user', 'purchase', 10, 123456, None), size=32768), EventWrapper(event=Event('key2', 'user', 'purchase', 10, 123456, None), size=32768), EventWrapper(event=Event('key3', 'user', 'purchase', 10, 123456, None), size=32768), EventWrapper(event=Event('key4', 'user', 'purchase', 10, 123456, None), size=32768), ] storage.put(events) res = storage.pop_many(10) assert res == [ Event('key1', 'user', 'purchase', 10, 123456, None), Event('key2', 'user', 'purchase', 10, 123456, None), Event('key3', 'user', 'purchase', 10, 123456, None), Event('key4', 'user', 'purchase', 10, 123456, None) ]
def test_track(self, mocker): """Test that destroy/destroyed calls are forwarded to the factory.""" split_storage = mocker.Mock(spec=SplitStorage) segment_storage = mocker.Mock(spec=SegmentStorage) impression_storage = mocker.Mock(spec=ImpressionStorage) event_storage = mocker.Mock(spec=EventStorage) event_storage.put.return_value = True def _get_storage_mock(name): return { 'splits': split_storage, 'segments': segment_storage, 'impressions': impression_storage, 'events': event_storage, }[name] factory = mocker.Mock(spec=SplitFactory) factory._get_storage = _get_storage_mock destroyed_mock = mocker.PropertyMock() destroyed_mock.return_value = False factory._waiting_fork.return_value = False type(factory).destroyed = destroyed_mock factory._apikey = 'test' mocker.patch('splitio.client.client.utctime_ms', new=lambda: 1000) impmanager = mocker.Mock(spec=ImpressionManager) recorder = StandardRecorder(impmanager, event_storage, impression_storage) client = Client(factory, recorder, True) assert client.track('key', 'user', 'purchase', 12) is True assert mocker.call([ EventWrapper( event=Event('key', 'user', 'purchase', 12, 1000, None), size=1024 ) ]) in event_storage.put.mock_calls
def track(self, key, traffic_type, event_type, value=None, properties=None): """ Track an event. :param key: user key associated to the event :type key: str :param traffic_type: traffic type name :type traffic_type: str :param event_type: event type name :type event_type: str :param value: (Optional) value associated to the event :type value: Number :param properties: (Optional) properties associated to the event :type properties: dict :return: Whether the event was created or not. :rtype: bool """ if self.destroyed: _LOGGER.error( "Client has already been destroyed - no calls possible") return False if self._factory._waiting_fork(): _LOGGER.error("Client is not ready - no calls possible") return False key = input_validator.validate_track_key(key) event_type = input_validator.validate_event_type(event_type) should_validate_existance = self.ready and self._factory._apikey != 'localhost' # pylint: disable=protected-access traffic_type = input_validator.validate_traffic_type( traffic_type, should_validate_existance, self._factory._get_storage('splits'), # pylint: disable=protected-access ) value = input_validator.validate_value(value) valid, properties, size = input_validator.valid_properties(properties) if key is None or event_type is None or traffic_type is None or value is False \ or valid is False: return False event = Event( key=key, traffic_type_name=traffic_type, event_type_id=event_type, value=value, timestamp=utctime_ms(), properties=properties, ) return self._recorder.record_track_stats( [EventWrapper( event=event, size=size, )])
def test_track(self, mocker): """Test that destroy/destroyed calls are forwarded to the factory.""" split_storage = mocker.Mock(spec=SplitStorage) segment_storage = mocker.Mock(spec=SegmentStorage) impression_storage = mocker.Mock(spec=ImpressionStorage) event_storage = mocker.Mock(spec=EventStorage) event_storage.put.return_value = True telemetry_storage = mocker.Mock(spec=TelemetryStorage) def _get_storage_mock(name): return { 'splits': split_storage, 'segments': segment_storage, 'impressions': impression_storage, 'events': event_storage, 'telemetry': telemetry_storage }[name] factory = mocker.Mock(spec=SplitFactory) factory._get_storage = _get_storage_mock destroyed_mock = mocker.PropertyMock() destroyed_mock.return_value = False type(factory).destroyed = destroyed_mock factory._apikey = 'test' mocker.patch('splitio.client.client.time.time', new=lambda: 1) client = Client(factory) assert client.track('key', 'user', 'purchase', 12) is True assert mocker.call([ EventWrapper( event=Event('key', 'user', 'purchase', 12, 1000, None), size=1024 ) ]) in event_storage.put.mock_calls
def test_queue_full_hook_properties(self, mocker): """Test queue_full_hook is executed when the queue is full regarding properties.""" storage = InMemoryEventStorage(200) queue_full_hook = mocker.Mock() storage.set_queue_full_hook(queue_full_hook) events = [EventWrapper(event=Event('key%d' % i, 'user', 'purchase', 12.5, 1, None), size=32768) for i in range(160)] storage.put(events) assert queue_full_hook.mock_calls == [mocker.call()]
def test_queue_full_hook(self, mocker): """Test queue_full_hook is executed when the queue is full.""" storage = InMemoryEventStorage(100) queue_full_hook = mocker.Mock() storage.set_queue_full_hook(queue_full_hook) events = [EventWrapper(event=Event('key%d' % i, 'user', 'purchase', 12.5, 321654, None), size=1024) for i in range(0, 101)] storage.put(events) assert queue_full_hook.mock_calls == [mocker.call()]
def test_push_pop_events(self): """Test pushing and retrieving events.""" storage = InMemoryEventStorage(100) storage.put([ EventWrapper( event=Event('key1', 'user', 'purchase', 3.5, 123456, None), size=1024, ) ]) storage.put([ EventWrapper( event=Event('key2', 'user', 'purchase', 3.5, 123456, None), size=1024, ) ]) storage.put([ EventWrapper( event=Event('key3', 'user', 'purchase', 3.5, 123456, None), size=1024, ) ]) # Assert impressions are retrieved in the same order they are inserted. assert storage.pop_many(1) == [ Event('key1', 'user', 'purchase', 3.5, 123456, None) ] assert storage.pop_many(1) == [ Event('key2', 'user', 'purchase', 3.5, 123456, None) ] assert storage.pop_many(1) == [ Event('key3', 'user', 'purchase', 3.5, 123456, None) ] # Assert inserting multiple impressions at once works and maintains order. events = [ EventWrapper( event=Event('key1', 'user', 'purchase', 3.5, 123456, None), size=1024, ), EventWrapper( event=Event('key2', 'user', 'purchase', 3.5, 123456, None), size=1024, ), EventWrapper( event=Event('key3', 'user', 'purchase', 3.5, 123456, None), size=1024, ), ] assert storage.put(events) # Assert events are retrieved in the same order they are inserted. assert storage.pop_many(1) == [ Event('key1', 'user', 'purchase', 3.5, 123456, None) ] assert storage.pop_many(1) == [ Event('key2', 'user', 'purchase', 3.5, 123456, None) ] assert storage.pop_many(1) == [ Event('key3', 'user', 'purchase', 3.5, 123456, None) ]
def test_clear(self): """Test clear method.""" storage = InMemoryEventStorage(100) storage.put([ EventWrapper( event=Event('key1', 'user', 'purchase', 3.5, 123456, None), size=1024, ) ]) assert storage._events.qsize() == 1 storage.clear() assert storage._events.qsize() == 0