Пример #1
0
    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
Пример #2
0
    def test_destroy(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)

        def _get_storage_mock(name):
            return {
                'splits': split_storage,
                'segments': segment_storage,
                'impressions': impression_storage,
                'events': event_storage,
            }[name]
        factory = mocker.Mock(spec=SplitFactory)
        destroyed_mock = mocker.PropertyMock()
        type(factory).destroyed = destroyed_mock

        impmanager = mocker.Mock(spec=ImpressionManager)
        recorder = StandardRecorder(impmanager, event_storage, impression_storage)
        client = Client(factory, recorder, True)
        client.destroy()
        assert factory.destroy.mock_calls == [mocker.call()]
        assert client.destroyed is not None
        assert destroyed_mock.mock_calls == [mocker.call()]
Пример #3
0
    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
Пример #4
0
    def client(self):
        """
        Return a new client.

        This client is only a set of references to structures hold by the factory.
        Creating one a fast operation and safe to be used anywhere.
        """
        return Client(self, self._impressions_manager, self._labels_enabled)
Пример #5
0
    def test_evaluations_before_running_post_fork(self, mocker):
        destroyed_property = mocker.PropertyMock()
        destroyed_property.return_value = False

        factory = mocker.Mock(spec=SplitFactory)
        factory._waiting_fork.return_value = True
        type(factory).destroyed = destroyed_property

        expected_msg = [
            mocker.call('Client is not ready - no calls possible')
        ]

        client = Client(factory, mocker.Mock())
        _logger = mocker.Mock()
        mocker.patch('splitio.client.client._LOGGER', new=_logger)

        assert client.get_treatment('some_key', 'some_feature') == CONTROL
        assert _logger.error.mock_calls == expected_msg
        _logger.reset_mock()

        assert client.get_treatment_with_config('some_key', 'some_feature') == (CONTROL, None)
        assert _logger.error.mock_calls == expected_msg
        _logger.reset_mock()

        assert client.track("some_key", "traffic_type", "event_type", None) is False
        assert _logger.error.mock_calls == expected_msg
        _logger.reset_mock()

        assert client.get_treatments(None, ['some_feature']) == {'some_feature': CONTROL}
        assert _logger.error.mock_calls == expected_msg
        _logger.reset_mock()

        assert client.get_treatments_with_config('some_key', ['some_feature']) == {'some_feature': (CONTROL, None)}
        assert _logger.error.mock_calls == expected_msg
        _logger.reset_mock()
Пример #6
0
    def test_get_treatment(self, mocker):
        """Test get_treatment execution paths."""
        split_storage = mocker.Mock(spec=SplitStorage)
        segment_storage = mocker.Mock(spec=SegmentStorage)
        impression_storage = mocker.Mock(spec=ImpressionStorage)
        event_storage = mocker.Mock(spec=EventStorage)
        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]

        destroyed_property = mocker.PropertyMock()
        destroyed_property.return_value = False

        factory = mocker.Mock(spec=SplitFactory)
        factory._get_storage.side_effect = _get_storage_mock
        type(factory).destroyed = destroyed_property

        mocker.patch('splitio.client.client.time.time', new=lambda: 1)
        mocker.patch('splitio.client.client.get_latency_bucket_index', new=lambda x: 5)

        client = Client(factory, True, None)
        client._evaluator = mocker.Mock(spec=Evaluator)
        client._evaluator.evaluate_treatment.return_value = {
            'treatment': 'on',
            'configurations': None,
            'impression': {
                'label': 'some_label',
                'change_number': 123
            }
        }
        client._logger = mocker.Mock()
        client._send_impression_to_listener = mocker.Mock()

        assert client.get_treatment('some_key', 'some_feature') == 'on'
        assert mocker.call(
            [Impression('some_key', 'some_feature', 'on', 'some_label', 123, None, 1000)]
        ) in impression_storage.put.mock_calls
        assert mocker.call('sdk.getTreatment', 5) in telemetry_storage.inc_latency.mock_calls
        assert client._logger.mock_calls == []
        assert mocker.call(
            Impression('some_key', 'some_feature', 'on', 'some_label', 123, None, 1000),
            None
        ) in client._send_impression_to_listener.mock_calls

        # Test with exception:
        split_storage.get_change_number.return_value = -1
        def _raise(*_):
            raise Exception('something')
        client._evaluator.evaluate_treatment.side_effect = _raise
        assert client.get_treatment('some_key', 'some_feature') == 'control'
        assert mocker.call(
            [Impression('some_key', 'some_feature', 'control', 'exception', -1, None, 1000)]
        ) in impression_storage.put.mock_calls
        assert len(telemetry_storage.inc_latency.mock_calls) == 2
Пример #7
0
    def test_destroy(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)
        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)
        destroyed_mock = mocker.PropertyMock()
        type(factory).destroyed = destroyed_mock

        client = Client(factory)
        client.destroy()
        assert factory.destroy.mock_calls == [mocker.call()]
        assert client.destroyed is not None
        assert destroyed_mock.mock_calls == [mocker.call()]
Пример #8
0
    def test_get_treatment_with_config(self, mocker):
        """Test get_treatment execution paths."""
        split_storage = mocker.Mock(spec=SplitStorage)
        segment_storage = mocker.Mock(spec=SegmentStorage)
        impression_storage = mocker.Mock(spec=ImpressionStorage)
        event_storage = mocker.Mock(spec=EventStorage)

        def _get_storage_mock(name):
            return {
                'splits': split_storage,
                'segments': segment_storage,
                'impressions': impression_storage,
                'events': event_storage,
            }[name]

        destroyed_property = mocker.PropertyMock()
        destroyed_property.return_value = False

        factory = mocker.Mock(spec=SplitFactory)
        factory._get_storage.side_effect = _get_storage_mock
        factory._waiting_fork.return_value = False
        type(factory).destroyed = destroyed_property

        mocker.patch('splitio.client.client.utctime_ms', new=lambda: 1000)
        mocker.patch('splitio.client.client.get_latency_bucket_index', new=lambda x: 5)

        impmanager = mocker.Mock(spec=ImpressionManager)
        recorder = StandardRecorder(impmanager, event_storage, impression_storage)
        client = Client(factory, recorder, True)
        client._evaluator = mocker.Mock(spec=Evaluator)
        client._evaluator.evaluate_feature.return_value = {
            'treatment': 'on',
            'configurations': '{"some_config": True}',
            'impression': {
                'label': 'some_label',
                'change_number': 123
            }
        }
        _logger = mocker.Mock()
        client._send_impression_to_listener = mocker.Mock()

        assert client.get_treatment_with_config(
            'some_key',
            'some_feature'
        ) == ('on', '{"some_config": True}')
        assert mocker.call(
            [(Impression('some_key', 'some_feature', 'on', 'some_label', 123, None, 1000), None)]
        ) in impmanager.process_impressions.mock_calls
        assert _logger.mock_calls == []

        # Test with client not ready
        ready_property = mocker.PropertyMock()
        ready_property.return_value = False
        type(factory).ready = ready_property
        impmanager.process_impressions.reset_mock()
        assert client.get_treatment_with_config('some_key', 'some_feature', {'some_attribute': 1}) == ('control', None)
        assert mocker.call(
            [(Impression('some_key', 'some_feature', 'control', Label.NOT_READY, mocker.ANY, mocker.ANY, mocker.ANY),
              {'some_attribute': 1})]
        ) in impmanager.process_impressions.mock_calls

        # Test with exception:
        ready_property.return_value = True
        split_storage.get_change_number.return_value = -1

        def _raise(*_):
            raise Exception('something')
        client._evaluator.evaluate_feature.side_effect = _raise
        assert client.get_treatment_with_config('some_key', 'some_feature') == ('control', None)
        assert mocker.call(
            [(Impression('some_key', 'some_feature', 'control', 'exception', -1, None, 1000), None)]
        ) in impmanager.process_impressions.mock_calls
Пример #9
0
    def test_get_treatments_with_config(self, mocker):
        """Test get_treatment execution paths."""
        split_storage = mocker.Mock(spec=SplitStorage)
        segment_storage = mocker.Mock(spec=SegmentStorage)
        impression_storage = mocker.Mock(spec=ImpressionStorage)
        event_storage = mocker.Mock(spec=EventStorage)
        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]

        destroyed_property = mocker.PropertyMock()
        destroyed_property.return_value = False

        factory = mocker.Mock(spec=SplitFactory)
        factory._get_storage.side_effect = _get_storage_mock
        factory._waiting_fork.return_value = False
        type(factory).destroyed = destroyed_property

        mocker.patch('splitio.client.client.utctime_ms', new=lambda: 1000)
        mocker.patch('splitio.client.client.get_latency_bucket_index',
                     new=lambda x: 5)

        impmanager = mocker.Mock(spec=ImpressionManager)
        recorder = StandardRecorder(impmanager, telemetry_storage,
                                    event_storage, impression_storage)
        client = Client(factory, recorder, True)
        client._evaluator = mocker.Mock(spec=Evaluator)
        evaluation = {
            'treatment': 'on',
            'configurations': '{"color": "red"}',
            'impression': {
                'label': 'some_label',
                'change_number': 123
            }
        }
        client._evaluator.evaluate_features.return_value = {
            'f1': evaluation,
            'f2': evaluation
        }
        _logger = mocker.Mock()
        assert client.get_treatments_with_config('key', ['f1', 'f2']) == {
            'f1': ('on', '{"color": "red"}'),
            'f2': ('on', '{"color": "red"}')
        }

        impressions_called = impmanager.process_impressions.mock_calls[0][1][0]
        assert (Impression('key', 'f1', 'on', 'some_label', 123, None,
                           1000), None) in impressions_called
        assert (Impression('key', 'f2', 'on', 'some_label', 123, None,
                           1000), None) in impressions_called
        assert mocker.call('sdk.getTreatmentsWithConfig',
                           5) in telemetry_storage.inc_latency.mock_calls
        assert _logger.mock_calls == []

        # Test with client not ready
        ready_property = mocker.PropertyMock()
        ready_property.return_value = False
        type(factory).ready = ready_property
        impmanager.process_impressions.reset_mock()
        assert client.get_treatments_with_config('some_key', ['some_feature'],
                                                 {'some_attribute': 1}) == {
                                                     'some_feature':
                                                     ('control', None)
                                                 }
        assert mocker.call([
            (Impression('some_key', 'some_feature', 'control', Label.NOT_READY,
                        mocker.ANY, mocker.ANY, mocker.ANY), {
                            'some_attribute': 1
                        })
        ]) in impmanager.process_impressions.mock_calls

        # Test with exception:
        ready_property.return_value = True
        split_storage.get_change_number.return_value = -1

        def _raise(*_):
            raise Exception('something')

        client._evaluator.evaluate_features.side_effect = _raise
        assert client.get_treatments_with_config('key', ['f1', 'f2']) == {
            'f1': ('control', None),
            'f2': ('control', None)
        }
        assert len(telemetry_storage.inc_latency.mock_calls) == 2