예제 #1
0
    def test_fetch_segment(self, mocker):
        """Test fetching a whole segment."""
        adapter = mocker.Mock(spec=RedisAdapter)
        adapter.smembers.return_value = set(["key1", "key2", "key3"])
        adapter.get.return_value = '100'
        from_raw = mocker.Mock()
        mocker.patch('splitio.storage.redis.segments.from_raw', new=from_raw)

        storage = RedisSegmentStorage(adapter)
        result = storage.get('some_segment')
        assert isinstance(result, Segment)
        assert result.name == 'some_segment'
        assert result.contains('key1')
        assert result.contains('key2')
        assert result.contains('key3')
        assert result.change_number == 100
        assert adapter.smembers.mock_calls == [
            mocker.call('SPLITIO.segment.some_segment')
        ]
        assert adapter.get.mock_calls == [
            mocker.call('SPLITIO.segment.some_segment.till')
        ]

        # Assert that if segment doesn't exist, None is returned
        adapter.reset_mock()
        from_raw.reset_mock()
        adapter.smembers.return_value = set()
        assert storage.get('some_segment') is None
        assert adapter.smembers.mock_calls == [
            mocker.call('SPLITIO.segment.some_segment')
        ]
        assert adapter.get.mock_calls == [
            mocker.call('SPLITIO.segment.some_segment.till')
        ]
예제 #2
0
 def test_segment_contains(self, mocker):
     """Test segment contains functionality."""
     adapter = mocker.Mock(spec=RedisAdapter)
     storage = RedisSegmentStorage(adapter)
     adapter.sismember.return_value = True
     assert storage.segment_contains('some_segment', 'some_key') is True
     assert adapter.sismember.mock_calls == [
         mocker.call('SPLITIO.segment.some_segment', 'some_key')
     ]
예제 #3
0
    def test_fetch_change_number(self, mocker):
        """Test fetching change number."""
        adapter = mocker.Mock(spec=RedisAdapter)
        adapter.get.return_value = '100'

        storage = RedisSegmentStorage(adapter)
        result = storage.get_change_number('some_segment')
        assert result == 100
        assert adapter.get.mock_calls == [mocker.call('SPLITIO.segment.some_segment.till')]
예제 #4
0
def _build_redis_factory(api_key, cfg):
    """Build and return a split factory with redis-based storage."""
    sdk_metadata = util.get_metadata(cfg)
    redis_adapter = redis.build(cfg)
    cache_enabled = cfg.get('redisLocalCacheEnabled', False)
    cache_ttl = cfg.get('redisLocalCacheTTL', 5)
    storages = {
        'splits': RedisSplitStorage(redis_adapter, cache_enabled, cache_ttl),
        'segments': RedisSegmentStorage(redis_adapter),
        'impressions': RedisImpressionsStorage(redis_adapter, sdk_metadata),
        'events': RedisEventsStorage(redis_adapter, sdk_metadata),
    }
    data_sampling = cfg.get('dataSampling', DEFAULT_DATA_SAMPLING)
    if data_sampling < _MIN_DEFAULT_DATA_SAMPLING_ALLOWED:
        _LOGGER.warning("dataSampling cannot be less than %.2f, defaulting to minimum",
                        _MIN_DEFAULT_DATA_SAMPLING_ALLOWED)
        data_sampling = _MIN_DEFAULT_DATA_SAMPLING_ALLOWED
    recorder = PipelinedRecorder(
        redis_adapter.pipeline,
        ImpressionsManager(cfg['impressionsMode'], False,
                           _wrap_impression_listener(cfg['impressionListener'], sdk_metadata)),
        storages['events'],
        storages['impressions'],
        data_sampling,
    )
    return SplitFactory(
        api_key,
        storages,
        cfg['labelsEnabled'],
        recorder,
    )
예제 #5
0
def _build_redis_factory(config):
    """Build and return a split factory with redis-based storage."""
    cfg = DEFAULT_CONFIG.copy()
    cfg.update(config)
    sdk_metadata = util.get_metadata(config)
    redis_adapter = redis.build(config)
    storages = {
        'splits': RedisSplitStorage(redis_adapter),
        'segments': RedisSegmentStorage(redis_adapter),
        'impressions': RedisImpressionsStorage(redis_adapter, sdk_metadata),
        'events': RedisEventsStorage(redis_adapter, sdk_metadata),
        'telemetry': RedisTelemetryStorage(redis_adapter, sdk_metadata)
    }
    return SplitFactory(storages,
                        cfg['labelsEnabled'],
                        impression_listener=_wrap_impression_listener(
                            cfg['impressionListener'], sdk_metadata))
예제 #6
0
    def test_put_fetch_contains(self):
        """Test storing and retrieving splits in redis."""
        adapter = _build_default_client({})
        try:
            storage = RedisSegmentStorage(adapter)
            adapter.sadd(storage._get_key('some_segment'), 'key1', 'key2', 'key3', 'key4')
            adapter.set(storage._get_till_key('some_segment'), 123)
            assert storage.segment_contains('some_segment', 'key0') is False
            assert storage.segment_contains('some_segment', 'key1') is True
            assert storage.segment_contains('some_segment', 'key2') is True
            assert storage.segment_contains('some_segment', 'key3') is True
            assert storage.segment_contains('some_segment', 'key4') is True
            assert storage.segment_contains('some_segment', 'key5') is False

            fetched = storage.get('some_segment')
            assert fetched.keys == set(['key1', 'key2', 'key3', 'key4'])
            assert fetched.change_number == 123
        finally:
            adapter.delete('SPLITIO.segment.some_segment', 'SPLITIO.segment.some_segment.till')
예제 #7
0
def _build_redis_factory(api_key, cfg):
    """Build and return a split factory with redis-based storage."""
    sdk_metadata = util.get_metadata(cfg)
    redis_adapter = redis.build(cfg)
    cache_enabled = cfg.get('redisLocalCacheEnabled', False)
    cache_ttl = cfg.get('redisLocalCacheTTL', 5)
    storages = {
        'splits': RedisSplitStorage(redis_adapter, cache_enabled, cache_ttl),
        'segments': RedisSegmentStorage(redis_adapter),
        'impressions': RedisImpressionsStorage(redis_adapter, sdk_metadata),
        'events': RedisEventsStorage(redis_adapter, sdk_metadata),
        'telemetry': RedisTelemetryStorage(redis_adapter, sdk_metadata)
    }
    return SplitFactory(
        api_key,
        storages,
        cfg['labelsEnabled'],
        ImpressionsManager(storages['impressions'].put, cfg['impressionsMode'], False,
                           _wrap_impression_listener(cfg['impressionListener'], sdk_metadata))
    )
예제 #8
0
    def setup_method(self):
        """Prepare storages with test data."""
        metadata = SdkMetadata('python-1.2.3', 'some_ip', 'some_name')
        redis_client = build(DEFAULT_CONFIG.copy())
        split_storage = RedisSplitStorage(redis_client, True)
        segment_storage = RedisSegmentStorage(redis_client)

        split_fn = os.path.join(os.path.dirname(__file__), 'files',
                                'splitChanges.json')
        with open(split_fn, 'r') as flo:
            data = json.loads(flo.read())
        for split in data['splits']:
            redis_client.set(split_storage._get_key(split['name']),
                             json.dumps(split))
        redis_client.set(split_storage._SPLIT_TILL_KEY, data['till'])

        segment_fn = os.path.join(os.path.dirname(__file__), 'files',
                                  'segmentEmployeesChanges.json')
        with open(segment_fn, 'r') as flo:
            data = json.loads(flo.read())
        redis_client.sadd(segment_storage._get_key(data['name']),
                          *data['added'])
        redis_client.set(segment_storage._get_till_key(data['name']),
                         data['till'])

        segment_fn = os.path.join(os.path.dirname(__file__), 'files',
                                  'segmentHumanBeignsChanges.json')
        with open(segment_fn, 'r') as flo:
            data = json.loads(flo.read())
        redis_client.sadd(segment_storage._get_key(data['name']),
                          *data['added'])
        redis_client.set(segment_storage._get_till_key(data['name']),
                         data['till'])

        storages = {
            'splits': split_storage,
            'segments': segment_storage,
            'impressions': RedisImpressionsStorage(redis_client, metadata),
            'events': RedisEventsStorage(redis_client, metadata),
        }
        impmanager = ImpressionsManager(storages['impressions'].put,
                                        ImpressionsMode.DEBUG)
        recorder = PipelinedRecorder(redis_client.pipeline, impmanager,
                                     storages['events'],
                                     storages['impressions'])
        self.factory = SplitFactory('some_api_key', storages, True, recorder)  # pylint:disable=attribute-defined-outside-init
예제 #9
0
    def setup_method(self):
        """Prepare storages with test data."""
        metadata = SdkMetadata('python-1.2.3', 'some_ip', 'some_name')
        redis_client = RedisAdapter(StrictRedis())
        split_storage = RedisSplitStorage(redis_client, True)
        segment_storage = RedisSegmentStorage(redis_client)

        split_fn = os.path.join(os.path.dirname(__file__), 'files',
                                'splitChanges.json')
        with open(split_fn, 'r') as flo:
            data = json.loads(flo.read())
        for split in data['splits']:
            redis_client.set(split_storage._get_key(split['name']),
                             json.dumps(split))
        redis_client.set(split_storage._SPLIT_TILL_KEY, data['till'])

        segment_fn = os.path.join(os.path.dirname(__file__), 'files',
                                  'segmentEmployeesChanges.json')
        with open(segment_fn, 'r') as flo:
            data = json.loads(flo.read())
        redis_client.sadd(segment_storage._get_key(data['name']),
                          *data['added'])
        redis_client.set(segment_storage._get_till_key(data['name']),
                         data['till'])

        segment_fn = os.path.join(os.path.dirname(__file__), 'files',
                                  'segmentHumanBeignsChanges.json')
        with open(segment_fn, 'r') as flo:
            data = json.loads(flo.read())
        redis_client.sadd(segment_storage._get_key(data['name']),
                          *data['added'])
        redis_client.set(segment_storage._get_till_key(data['name']),
                         data['till'])

        self.factory = SplitFactory(
            'some_api_key',
            {  #pylint:disable=attribute-defined-outside-init
                'splits': split_storage,
                'segments': segment_storage,
                'impressions': RedisImpressionsStorage(redis_client, metadata),
                'events': RedisEventsStorage(redis_client, metadata),
                'telemetry': RedisTelemetryStorage(redis_client, metadata)
            },
            True)