Exemplo n.º 1
0
class RedisReadOnlyTest(TestCase, MockUtilsMixin):
    def setUp(self):
        self._some_config = mock.MagicMock()
        self._split_changes_file_name = join(dirname(__file__), 'splitChangesReadOnly.json')

        with open(self._split_changes_file_name) as f:
            self._json = load(f)
            split_definition = self._json['splits'][0]
            split_name = split_definition['name']

        self._redis = get_redis({'redisPrefix': 'test'})

        self._mocked_redis = ReadOnlyRedisMock(self._redis)
        self._redis_split_cache = RedisSplitCache(self._redis)
        self._redis_split_cache.add_split(split_name, split_definition)
        self._client = Client(RedisBroker(self._mocked_redis, self._some_config))

        self._impression = mock.MagicMock()
        self._start = mock.MagicMock()
        self._operation = mock.MagicMock()

    def test_redis_read_only_mode(self):
        self.assertEqual(self._client.get_treatment('valid', 'test_read_only_1'), 'on')
        self.assertEqual(self._client.get_treatment('invalid', 'test_read_only_1'), 'off')
        self.assertEqual(self._client.get_treatment('valid', 'test_read_only_1_invalid'), 'control')
Exemplo n.º 2
0
    def setUp(self):
        self._some_config = mock.MagicMock()
        self._split_changes_file_name = join(dirname(__file__),
                                             'splitGetTreatments.json')

        with open(self._split_changes_file_name) as f:
            self._json = load(f)
            split_definition = self._json['splits'][0]
            split_name = split_definition['name']

        self._redis = get_redis({'redisPrefix': 'getTreatmentsTest'})

        self._redis_split_cache = RedisSplitCache(self._redis)
        self._redis_split_cache.add_split(split_name, split_definition)
        self._client = Client(RedisBroker(self._redis, self._some_config))

        self._config = {
            'ready': 180000,
            'redisDb': 0,
            'redisHost': 'localhost',
            'redisPosrt': 6379,
            'redisPrefix': 'getTreatmentsTest'
        }
        self._factory = get_factory('asdqwe123456', config=self._config)
        self._split = self._factory.client()
Exemplo n.º 3
0
    def setUp(self):
        self._segment_changes_file_name = join(dirname(__file__), 'segmentChanges.json')
        self._split_changes_file_name = join(dirname(__file__), 'splitChanges.json')

        self._redis = get_redis({'redisPrefix': 'test'})
        self._redis_split_cache = RedisSplitCache(self._redis)
        self._redis_segment_cache = RedisSegmentCache(self._redis)
Exemplo n.º 4
0
    def setUp(self):
        self._some_config = mock.MagicMock()
        self._split_changes_file_name = join(
            dirname(__file__), 'splitCustomImpressionListener.json')

        with open(self._split_changes_file_name) as f:
            self._json = load(f)
            split_definition = self._json['splits'][0]
            split_name = split_definition['name']

        self._redis = get_redis(
            {'redisPrefix': 'customImpressionListenerTest'})

        self._redis_split_cache = RedisSplitCache(self._redis)
        self._redis_split_cache.add_split(split_name, split_definition)
        self._client = Client(RedisBroker(self._redis, self._some_config))

        self.some_feature = 'feature_0'
        self.some_impression_0 = Impression(matching_key=mock.MagicMock(),
                                            feature_name=self.some_feature,
                                            treatment=mock.MagicMock(),
                                            label=mock.MagicMock(),
                                            change_number=mock.MagicMock(),
                                            bucketing_key=mock.MagicMock(),
                                            time=mock.MagicMock())
 def setUp(self):
     self.decode_mock = self.patch('splitio.redis_support.decode')
     self.encode_mock = self.patch('splitio.redis_support.encode')
     self.some_split_name = mock.MagicMock()
     self.some_split_name_str = 'some_split_name'
     self.some_split = mock.MagicMock()
     self.some_change_number = mock.MagicMock()
     self.some_redis = mock.MagicMock()
     self.a_split_cache = RedisSplitCache(self.some_redis)
Exemplo n.º 6
0
class RedisSplitCacheTests(TestCase, MockUtilsMixin):
    def setUp(self):
        self.decode_mock = self.patch('splitio.redis_support.decode')
        self.encode_mock = self.patch('splitio.redis_support.encode')
        self.some_split_name = mock.MagicMock()
        self.some_split_name_str = 'some_split_name'
        self.some_split = mock.MagicMock()
        self.some_change_number = mock.MagicMock()
        self.some_redis = mock.MagicMock()
        self.a_split_cache = RedisSplitCache(self.some_redis)

    def test_set_change_number_sets_change_number_key(self):
        """Test that set_change_number sets the change number key"""
        self.a_split_cache.set_change_number(self.some_change_number)
        self.some_redis.set.assert_called_once_with('SPLITIO.splits.till',
                                                    self.some_change_number,
                                                    None)

    def test_get_change_number_gets_segment_change_number_key(self):
        """Test that get_change_number gets the change number key"""
        self.some_redis.get.return_value = '1234'
        result = self.a_split_cache.get_change_number()
        self.assertEqual(int(self.some_redis.get.return_value), result)
        self.assertIsInstance(result, int)
        self.some_redis.get.assert_called_once_with('SPLITIO.splits.till')

    def test_get_change_number_returns_default_value_if_not_set(self):
        """Test that get_change_number returns -1 if the value is not set"""
        self.some_redis.get.return_value = None
        self.assertEqual(-1, self.a_split_cache.get_change_number())

    def test_add_split_sets_split_key_with_pickled_split(self):
        """Test that add_split sets the split key with pickled split"""
        self.a_split_cache.add_split(self.some_split_name_str, self.some_split)
        self.encode_mock.assert_called_once_with(self.some_split)
        self.some_redis.set.assert_called_once_with(
            'SPLITIO.split.some_split_name', self.encode_mock.return_value)

    def test_get_split_returns_none_if_not_cached(self):
        """Test that if a split is not cached get_split returns None"""
        self.some_redis.get.return_value = None
        self.assertEqual(
            None, self.a_split_cache.get_split(self.some_split_name_str))
        self.some_redis.get.assert_called_once_with(
            'SPLITIO.split.some_split_name')

    def test_remove_split_deletes_split_key(self):
        """Test that remove_split deletes the split key"""
        self.a_split_cache.remove_split(self.some_split_name_str)
        self.some_redis.delete.assert_called_once_with(
            'SPLITIO.split.some_split_name')
Exemplo n.º 7
0
    def setUp(self):
        self._some_config = mock.MagicMock()
        self._split_changes_file_name = join(dirname(__file__), 'splitChangesReadOnly.json')

        with open(self._split_changes_file_name) as f:
            self._json = load(f)
            split_definition = self._json['splits'][0]
            split_name = split_definition['name']

        self._redis = get_redis({'redisPrefix': 'test'})

        self._mocked_redis = ReadOnlyRedisMock(self._redis)
        self._redis_split_cache = RedisSplitCache(self._redis)
        self._redis_split_cache.add_split(split_name, split_definition)
        self._client = Client(RedisBroker(self._mocked_redis, self._some_config))

        self._impression = mock.MagicMock()
        self._start = mock.MagicMock()
        self._operation = mock.MagicMock()
Exemplo n.º 8
0
def run(arguments):
    try:
        config = parse_config_file(arguments['<config_file>'])
        redis = get_redis(config)
        split_cache = RedisSplitCache(redis)
        sdk_api = api_factory(config)
        split_change_fetcher = ApiSplitChangeFetcher(sdk_api)
        segment_cache = RedisSegmentCache(redis)
        split_parser = RedisSplitParser(segment_cache)
        update_splits(split_cache, split_change_fetcher, split_parser)
    except:
        logger.exception('Exception caught updating splits')
Exemplo n.º 9
0
def _update_splits(seconds, config):
    try:
        while True:
            redis = get_redis(config)
            split_cache = RedisSplitCache(redis)
            sdk_api = api_factory(config)
            split_change_fetcher = ApiSplitChangeFetcher(sdk_api)
            segment_cache = RedisSegmentCache(redis)
            split_parser = RedisSplitParser(segment_cache)
            update_splits(split_cache, split_change_fetcher, split_parser)

            time.sleep(seconds)
    except:
        logger.exception('Exception caught updating splits')
Exemplo n.º 10
0
    def __init__(self, redis, config):
        """A Broker implementation that uses Redis as its backend.
        :param redis: A redis broker
        :type redis: StrctRedis"""
        super(RedisBroker, self).__init__(config)

        split_cache = RedisSplitCache(redis)
        split_fetcher = CacheBasedSplitFetcher(split_cache)

        impressions_cache = RedisImpressionsCache(redis)
        treatment_log = CacheBasedTreatmentLog(impressions_cache)

        metrics_cache = RedisMetricsCache(redis)
        delegate_metrics = CacheBasedMetrics(metrics_cache)
        metrics = AsyncMetrics(delegate_metrics)

        self._split_fetcher = split_fetcher
        self._treatment_log = treatment_log
        self._metrics = metrics

        self._event_storage = RedisEventsCache(redis)
Exemplo n.º 11
0
class CacheInterfacesTests(TestCase):
    def setUp(self):
        self._segment_changes_file_name = join(dirname(__file__), 'segmentChanges.json')
        self._split_changes_file_name = join(dirname(__file__), 'splitChanges.json')

        self._redis = get_redis({'redisPrefix': 'test'})
        self._redis_split_cache = RedisSplitCache(self._redis)
        self._redis_segment_cache = RedisSegmentCache(self._redis)

    def test_split_cache_interface(self):

        with open(self._split_changes_file_name) as f:
            self._json = load(f)
            split_definition = self._json['splits'][0]
            split_name = split_definition['name']

        #Add and get Split
        self._redis_split_cache.add_split(split_name, split_definition)
        self.assertEqual(split_definition['name'], self._redis_split_cache.get_split(split_name).name)
        self.assertEqual(split_definition['killed'], self._redis_split_cache.get_split(split_name).killed)
        self.assertEqual(split_definition['seed'], self._redis_split_cache.get_split(split_name).seed)

        #Remove Split
        self._redis_split_cache.remove_split(split_name)
        self.assertIsNone(self._redis_split_cache.get_split(split_name))

        #Change Number
        self._redis_split_cache.set_change_number(1212)
        self.assertEqual(1212, self._redis_split_cache.get_change_number())
Exemplo n.º 12
0
class CustomImpressionListenerTestOnRedis(TestCase):
    def setUp(self):
        self._some_config = mock.MagicMock()
        self._split_changes_file_name = join(
            dirname(__file__), 'splitCustomImpressionListener.json')

        with open(self._split_changes_file_name) as f:
            self._json = load(f)
            split_definition = self._json['splits'][0]
            split_name = split_definition['name']

        self._redis = get_redis(
            {'redisPrefix': 'customImpressionListenerTest'})

        self._redis_split_cache = RedisSplitCache(self._redis)
        self._redis_split_cache.add_split(split_name, split_definition)
        self._client = Client(RedisBroker(self._redis, self._some_config))

        self.some_feature = 'feature_0'
        self.some_impression_0 = Impression(matching_key=mock.MagicMock(),
                                            feature_name=self.some_feature,
                                            treatment=mock.MagicMock(),
                                            label=mock.MagicMock(),
                                            change_number=mock.MagicMock(),
                                            bucketing_key=mock.MagicMock(),
                                            time=mock.MagicMock())

    def test_client_raise_attribute_error(self):
        client_1 = Client(RedisBroker(self._redis, self._some_config), True,
                          ImpressionListenerClientEmpty())

        with self.assertRaises(AttributeError):
            client_1._impression_listener.log_impression(
                self.some_impression_0)

    def test_send_data_to_client(self):
        impression_client = ImpressionListenerClient()
        impression_wrapper = ImpressionListenerWrapper(impression_client)

        impression_wrapper.log_impression(self.some_impression_0)

        self.assertIn('impression', impression_client._data_logged)
        impression_logged = impression_client._data_logged['impression']
        self.assertIsInstance(impression_logged, Impression)
        self.assertDictEqual(
            {
                'impression': {
                    'keyName': self.some_impression_0.matching_key,
                    'treatment': self.some_impression_0.treatment,
                    'time': self.some_impression_0.time,
                    'changeNumber': self.some_impression_0.change_number,
                    'label': self.some_impression_0.label,
                    'bucketingKey': self.some_impression_0.bucketing_key
                }
            }, {
                'impression': {
                    'keyName': impression_logged.matching_key,
                    'treatment': impression_logged.treatment,
                    'time': impression_logged.time,
                    'changeNumber': impression_logged.change_number,
                    'label': impression_logged.label,
                    'bucketingKey': impression_logged.bucketing_key
                }
            })

        self.assertIn('instance-id', impression_client._data_logged)
        self.assertEqual(impression_client._data_logged['instance-id'],
                         DEFAULT_CONFIG['splitSdkMachineIp'])

        self.assertIn('sdk-language-version', impression_client._data_logged)
        self.assertEqual(
            impression_client._data_logged['sdk-language-version'],
            SDK_VERSION)

        self.assertIn('attributes', impression_client._data_logged)

    def test_client_throwing_exception_in_listener(self):
        impressionListenerClient = ImpressionListenerClientWithException()

        config = {
            'ready': 180000,
            'impressionListener': impressionListenerClient,
            'redisDb': 0,
            'redisHost': 'localhost',
            'redisPosrt': 6379,
            'redisPrefix': 'customImpressionListenerTest'
        }
        factory = get_factory('asdqwe123456', config=config)
        split = factory.client()

        self.assertEqual(split.get_treatment('valid', 'iltest'), 'on')

    def test_client(self):
        impressionListenerClient = ImpressionListenerClient()

        config = {
            'ready': 180000,
            'impressionListener': impressionListenerClient,
            'redisDb': 0,
            'redisHost': 'localhost',
            'redisPosrt': 6379,
            'redisPrefix': 'customImpressionListenerTest'
        }
        factory = get_factory('asdqwe123456', config=config)
        split = factory.client()

        self.assertEqual(split.get_treatment('valid', 'iltest'), 'on')
        self.assertEqual(split.get_treatment('invalid', 'iltest'), 'off')
        self.assertEqual(split.get_treatment('valid', 'iltest_invalid'),
                         'control')

    def test_client_without_impression_listener(self):
        config = {
            'ready': 180000,
            'redisDb': 0,
            'redisHost': 'localhost',
            'redisPosrt': 6379,
            'redisPrefix': 'customImpressionListenerTest'
        }
        factory = get_factory('asdqwe123456', config=config)
        split = factory.client()

        self.assertEqual(split.get_treatment('valid', 'iltest'), 'on')
        self.assertEqual(split.get_treatment('invalid', 'iltest'), 'off')
        self.assertEqual(split.get_treatment('valid', 'iltest_invalid'),
                         'control')

    def test_client_when_impression_listener_is_none(self):
        config = {
            'ready': 180000,
            'redisDb': 0,
            'impressionListener': None,
            'redisHost': 'localhost',
            'redisPosrt': 6379,
            'redisPrefix': 'customImpressionListenerTest'
        }
        factory = get_factory('asdqwe123456', config=config)
        split = factory.client()

        self.assertEqual(split.get_treatment('valid', 'iltest'), 'on')
        self.assertEqual(split.get_treatment('invalid', 'iltest'), 'off')
        self.assertEqual(split.get_treatment('valid', 'iltest_invalid'),
                         'control')

    def test_client_with_empty_impression_listener(self):
        config = {
            'ready': 180000,
            'redisDb': 0,
            'impressionListener': ImpressionListenerClientEmpty(),
            'redisHost': 'localhost',
            'redisPosrt': 6379,
            'redisPrefix': 'customImpressionListenerTest'
        }
        factory = get_factory('asdqwe123456', config=config)
        split = factory.client()

        self.assertEqual(split.get_treatment('valid', 'iltest'), 'on')
        self.assertEqual(split.get_treatment('invalid', 'iltest'), 'off')
        self.assertEqual(split.get_treatment('valid', 'iltest_invalid'),
                         'control')

    def test_throwing_exception_in_listener(self):
        impression_exception = ImpressionListenerClientWithException()

        impression_wrapper = ImpressionListenerWrapper(impression_exception)

        with self.assertRaises(ImpressionListenerException):
            impression_wrapper.log_impression(self.some_impression_0)
Exemplo n.º 13
0
class GetTreatmentsTest(TestCase):
    def setUp(self):
        self._some_config = mock.MagicMock()
        self._split_changes_file_name = join(dirname(__file__),
                                             'splitGetTreatments.json')

        with open(self._split_changes_file_name) as f:
            self._json = load(f)
            split_definition = self._json['splits'][0]
            split_name = split_definition['name']

        self._redis = get_redis({'redisPrefix': 'getTreatmentsTest'})

        self._redis_split_cache = RedisSplitCache(self._redis)
        self._redis_split_cache.add_split(split_name, split_definition)
        self._client = Client(RedisBroker(self._redis, self._some_config))

        self._config = {
            'ready': 180000,
            'redisDb': 0,
            'redisHost': 'localhost',
            'redisPosrt': 6379,
            'redisPrefix': 'getTreatmentsTest'
        }
        self._factory = get_factory('asdqwe123456', config=self._config)
        self._split = self._factory.client()

    def test_clien_with_distinct_features(self):
        results = self._split.get_treatments(
            'some_key', ['some_feature', 'some_feature_2'])
        self.assertIn('some_feature', results)
        self.assertIn('some_feature_2', results)
        self.assertDictEqual(results, {
            'some_feature': 'control',
            'some_feature_2': 'control'
        })

    def test_clien_with_repeated_features(self):
        results = self._split.get_treatments(
            'some_key',
            ['some_feature', 'some_feature_2', 'some_feature', 'some_feature'])
        self.assertIn('some_feature', results)
        self.assertIn('some_feature_2', results)
        self.assertDictEqual(results, {
            'some_feature': 'control',
            'some_feature_2': 'control'
        })

    def test_clien_with_none_and_repeated_features(self):
        results = self._split.get_treatments('some_key', [
            'some_feature', None, 'some_feature_2', 'some_feature',
            'some_feature', None
        ])
        self.assertIn('some_feature', results)
        self.assertIn('some_feature_2', results)
        self.assertDictEqual(results, {
            'some_feature': 'control',
            'some_feature_2': 'control'
        })

    def test_client_with_valid_none_and_repeated_features_and_invalid_key(
            self):
        features = [
            'some_feature', 'get_treatments_test', 'some_feature_2',
            'some_feature', 'get_treatments_test', None, 'valid'
        ]
        results = self._split.get_treatments('some_key', features)
        self.assertIn('some_feature', results)
        self.assertIn('some_feature_2', results)
        self.assertIn('get_treatments_test', results)
        self.assertEqual(results['some_feature'], 'control')
        self.assertEqual(results['some_feature_2'], 'control')
        self.assertEqual(results['get_treatments_test'], 'off')

    def test_client_with_valid_none_and_repeated_features_and_valid_key(self):
        features = [
            'some_feature', 'get_treatments_test', 'some_feature_2',
            'some_feature', 'get_treatments_test', None, 'valid'
        ]
        results = self._split.get_treatments('valid', features)
        self.assertIn('some_feature', results)
        self.assertIn('some_feature_2', results)
        self.assertIn('get_treatments_test', results)
        self.assertEqual(results['some_feature'], 'control')
        self.assertEqual(results['some_feature_2'], 'control')
        self.assertEqual(results['get_treatments_test'], 'on')

    def test_client_with_valid_none_invalid_and_repeated_features_and_valid_key(
            self):
        features = [
            'some_feature', 'get_treatments_test', 'some_feature_2',
            'some_feature', 'get_treatments_test', None, 'valid', True, [],
            True
        ]
        results = self._split.get_treatments('valid', features)
        self.assertIn('some_feature', results)
        self.assertIn('some_feature_2', results)
        self.assertIn('get_treatments_test', results)
        self.assertEqual(results['some_feature'], 'control')
        self.assertEqual(results['some_feature_2'], 'control')
        self.assertEqual(results['get_treatments_test'], 'on')