Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions splitio/client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,9 @@ def destroyed(self):
"""Return whether the factory holding this client has been destroyed."""
return self._factory.destroyed

def _evaluate_if_ready(self, matching_key, bucketing_key, feature, attributes=None):
def _evaluate_if_ready(self, matching_key, bucketing_key, feature, method, attributes=None):
if not self.ready:
_LOGGER.warning("%s: The SDK is not ready, results may be incorrect for feature flag %s. Make sure to wait for SDK readiness before using this method", method, feature)
self._telemetry_init_producer.record_not_ready_usage()
return {
'treatment': CONTROL,
Expand Down Expand Up @@ -102,7 +103,7 @@ def _make_evaluation(self, key, feature_flag, attributes, method_name, metric_na
or not input_validator.validate_attributes(attributes, method_name):
return CONTROL, None

result = self._evaluate_if_ready(matching_key, bucketing_key, feature_flag, attributes)
result = self._evaluate_if_ready(matching_key, bucketing_key, feature_flag, method_name, attributes)

impression = self._build_impression(
matching_key,
Expand Down Expand Up @@ -167,7 +168,7 @@ def _make_evaluations(self, key, feature_flags, attributes, method_name, metric_

try:
evaluations = self._evaluate_features_if_ready(matching_key, bucketing_key,
list(feature_flags), attributes)
list(feature_flags), method_name, attributes)

for feature_flag in feature_flags:
try:
Expand Down Expand Up @@ -212,8 +213,9 @@ def _make_evaluations(self, key, feature_flags, attributes, method_name, metric_
_LOGGER.debug('Error: ', exc_info=True)
return input_validator.generate_control_treatments(list(feature_flags), method_name)

def _evaluate_features_if_ready(self, matching_key, bucketing_key, feature_flags, attributes=None):
def _evaluate_features_if_ready(self, matching_key, bucketing_key, feature_flags, method, attributes=None):
if not self.ready:
_LOGGER.warning("%s: The SDK is not ready, results may be incorrect for feature flags %s. Make sure to wait for SDK readiness before using this method", method, ', '.join([feature for feature in feature_flags]))
self._telemetry_init_producer.record_not_ready_usage()
return {
feature_flag: {
Expand Down
3 changes: 2 additions & 1 deletion splitio/models/splits.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

SplitView = namedtuple(
'SplitView',
['name', 'traffic_type', 'killed', 'treatments', 'change_number', 'configs', 'sets']
['name', 'traffic_type', 'killed', 'treatments', 'change_number', 'configs', 'default_treatment', 'sets']
)


Expand Down Expand Up @@ -200,6 +200,7 @@ def to_split_view(self):
list(set(part.treatment for cond in self.conditions for part in cond.partitions)),
self.change_number,
self._configurations if self._configurations is not None else {},
self._default_treatment,
list(self._sets) if self._sets is not None else []
)

Expand Down
13 changes: 11 additions & 2 deletions tests/client/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ def test_get_treatment(self, mocker):
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
assert _logger.call(["The SDK is not ready, results may be incorrect for feature flag %s. Make sure to wait for SDK readiness before using this method", 'some_feature'])

# Test with exception:
ready_property.return_value = True
Expand Down Expand Up @@ -159,6 +160,7 @@ def test_get_treatment_with_config(self, mocker):
[(Impression('some_key', 'some_feature', 'control', Label.NOT_READY, mocker.ANY, mocker.ANY, mocker.ANY),
{'some_attribute': 1})]
) in impmanager.process_impressions.mock_calls
assert _logger.call(["The SDK is not ready, results may be incorrect for feature flag %s. Make sure to wait for SDK readiness before using this method", 'some_feature'])

# Test with exception:
ready_property.return_value = True
Expand Down Expand Up @@ -236,6 +238,7 @@ def test_get_treatments(self, mocker):
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
assert _logger.call(["The SDK is not ready, results may be incorrect for feature flags %s. Make sure to wait for SDK readiness before using this method", 'some_feature'])

# Test with exception:
ready_property.return_value = True
Expand Down Expand Up @@ -310,6 +313,7 @@ def test_get_treatments_with_config(self, mocker):
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
assert _logger.call(["The SDK is not ready, results may be incorrect for feature flags %s. Make sure to wait for SDK readiness before using this method", 'some_feature'])

# Test with exception:
ready_property.return_value = True
Expand Down Expand Up @@ -400,6 +404,7 @@ def evaluate_features(feature_flag_names, matching_key, bucketing_key, attribute
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
assert _logger.call(["The SDK is not ready, results may be incorrect for feature flags %s. Make sure to wait for SDK readiness before using this method", 'some_feature'])

# Test with exception:
ready_property.return_value = True
Expand Down Expand Up @@ -465,7 +470,6 @@ def evaluate_features(feature_flag_names, matching_key, bucketing_key, attribute
client._evaluator.evaluate_features = evaluate_features
_logger = mocker.Mock()
client._send_impression_to_listener = mocker.Mock()
# pytest.set_trace()
assert client.get_treatments_by_flag_sets('key', ['set1', 'set2']) == {'f1': 'on', 'f2': 'on'}

impressions_called = impmanager.process_impressions.mock_calls[0][1][0]
Expand All @@ -488,6 +492,7 @@ def evaluate_features(feature_flag_names, matching_key, bucketing_key, attribute
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
assert _logger.call(["The SDK is not ready, results may be incorrect for feature flags %s. Make sure to wait for SDK readiness before using this method", 'some_feature'])

# Test with exception:
ready_property.return_value = True
Expand Down Expand Up @@ -581,6 +586,7 @@ def evaluate_features(feature_flag_names, matching_key, bucketing_key, attribute
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
assert _logger.call(["The SDK is not ready, results may be incorrect for feature flags %s. Make sure to wait for SDK readiness before using this method", 'some_feature'])

# Test with exception:
ready_property.return_value = True
Expand Down Expand Up @@ -677,6 +683,7 @@ def evaluate_features(feature_flag_names, matching_key, bucketing_key, attribute
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
assert _logger.call(["The SDK is not ready, results may be incorrect for feature flags %s. Make sure to wait for SDK readiness before using this method", 'some_feature'])

# Test with exception:
ready_property.return_value = True
Expand Down Expand Up @@ -748,6 +755,7 @@ def test_track(self, mocker):
telemetry_producer.get_telemetry_init_producer(),
mocker.Mock()
)
_logger = mocker.Mock()

destroyed_mock = mocker.PropertyMock()
destroyed_mock.return_value = False
Expand All @@ -762,6 +770,7 @@ def test_track(self, mocker):
size=1024
)
]) in event_storage.put.mock_calls
assert _logger.call("track: the SDK is not ready, results may be incorrect. Make sure to wait for SDK readiness before using this method")

def test_evaluations_before_running_post_fork(self, mocker):
destroyed_property = mocker.PropertyMock()
Expand Down Expand Up @@ -837,7 +846,7 @@ def test_telemetry_not_ready(self, mocker):
)
client = Client(factory, mocker.Mock())
client.ready = False
client._evaluate_if_ready('matching_key','matching_key', 'feature')
client._evaluate_if_ready('matching_key','matching_key', 'method', 'feature')
assert(telemetry_storage._tel_config._not_ready == 1)
client.track('key', 'tt', 'ev')
assert(telemetry_storage._tel_config._not_ready == 2)
Expand Down
1 change: 1 addition & 0 deletions tests/models/test_splits.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,5 @@ def test_to_split_view(self):
assert as_split_view.killed == self.raw['killed']
assert as_split_view.traffic_type == self.raw['trafficTypeName']
assert set(as_split_view.treatments) == set(['on', 'off'])
assert as_split_view.default_treatment == self.raw['defaultTreatment']
assert sorted(as_split_view.sets) == sorted(list(self.raw['sets']))