Skip to content

Commit 35011e4

Browse files
authored
Merge pull request #507 from splitio/unsupported-matcher
added unsupported matcher fix
2 parents 8326138 + 2d26fbb commit 35011e4

File tree

6 files changed

+82
-6
lines changed

6 files changed

+82
-6
lines changed

splitio/models/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
class MatcherNotFoundException(Exception):
2+
"""Exception to raise when a matcher is not found."""
3+
4+
def __init__(self, custom_message):
5+
"""Constructor."""
6+
Exception.__init__(self, custom_message)

splitio/models/grammar/condition.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from enum import Enum
44

5+
from splitio.models import MatcherNotFoundException
56
from splitio.models.grammar import matchers
67
from splitio.models.grammar import partitions
78

@@ -123,7 +124,11 @@ def from_raw(raw_condition):
123124
for raw_partition in raw_condition['partitions']
124125
]
125126

126-
matcher_objects = [matchers.from_raw(x) for x in raw_condition['matcherGroup']['matchers']]
127+
try:
128+
matcher_objects = [matchers.from_raw(x) for x in raw_condition['matcherGroup']['matchers']]
129+
except MatcherNotFoundException as e:
130+
raise MatcherNotFoundException(str(e))
131+
127132
combiner = _MATCHER_COMBINERS[raw_condition['matcherGroup']['combiner']]
128133
label = raw_condition.get('label')
129134

splitio/models/grammar/matchers/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Matchers entrypoint module."""
2+
from splitio.models import MatcherNotFoundException
23
from splitio.models.grammar.matchers.keys import AllKeysMatcher, UserDefinedSegmentMatcher
34
from splitio.models.grammar.matchers.numeric import BetweenMatcher, EqualToMatcher, \
45
GreaterThanOrEqualMatcher, LessThanOrEqualMatcher
@@ -63,5 +64,5 @@ def from_raw(raw_matcher):
6364
try:
6465
builder = _MATCHER_BUILDERS[matcher_type]
6566
except KeyError:
66-
raise ValueError('Invalid matcher type %s' % matcher_type)
67+
raise MatcherNotFoundException('Invalid matcher type %s' % matcher_type)
6768
return builder(raw_matcher)

splitio/models/splits.py

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,46 @@
11
"""Splits module."""
22
from enum import Enum
33
from collections import namedtuple
4+
import logging
45

6+
from splitio.models import MatcherNotFoundException
57
from splitio.models.grammar import condition
68

9+
_LOGGER = logging.getLogger(__name__)
710

811
SplitView = namedtuple(
912
'SplitView',
1013
['name', 'traffic_type', 'killed', 'treatments', 'change_number', 'configs', 'default_treatment', 'sets']
1114
)
1215

16+
_DEFAULT_CONDITIONS_TEMPLATE = {
17+
"conditionType": "ROLLOUT",
18+
"matcherGroup": {
19+
"combiner": "AND",
20+
"matchers": [
21+
{
22+
"keySelector": None,
23+
"matcherType": "ALL_KEYS",
24+
"negate": False,
25+
"userDefinedSegmentMatcherData": None,
26+
"whitelistMatcherData": None,
27+
"unaryNumericMatcherData": None,
28+
"betweenMatcherData": None,
29+
"dependencyMatcherData": None,
30+
"booleanMatcherData": None,
31+
"stringMatcherData": None
32+
}]
33+
},
34+
"partitions": [
35+
{
36+
"treatment": "control",
37+
"size": 100
38+
}
39+
],
40+
"label": "unsupported matcher type"
41+
}
42+
43+
1344

1445
class Status(Enum):
1546
"""Split status."""
@@ -238,6 +269,27 @@ def from_raw(raw_split):
238269
:return: A parsed Split object capable of performing evaluations.
239270
:rtype: Split
240271
"""
272+
try:
273+
return Split(
274+
raw_split['name'],
275+
raw_split['seed'],
276+
raw_split['killed'],
277+
raw_split['defaultTreatment'],
278+
raw_split['trafficTypeName'],
279+
raw_split['status'],
280+
raw_split['changeNumber'],
281+
[condition.from_raw(c) for c in raw_split['conditions']],
282+
raw_split.get('algo'),
283+
traffic_allocation=raw_split.get('trafficAllocation'),
284+
traffic_allocation_seed=raw_split.get('trafficAllocationSeed'),
285+
configurations=raw_split.get('configurations'),
286+
sets=set(raw_split.get('sets')) if raw_split.get('sets') is not None else []
287+
)
288+
except MatcherNotFoundException as e:
289+
_LOGGER.error(str(e))
290+
pass
291+
292+
_LOGGER.debug("Using default conditions template for feature flag: %s", raw_split['name'])
241293
return Split(
242294
raw_split['name'],
243295
raw_split['seed'],
@@ -246,7 +298,7 @@ def from_raw(raw_split):
246298
raw_split['trafficTypeName'],
247299
raw_split['status'],
248300
raw_split['changeNumber'],
249-
[condition.from_raw(c) for c in raw_split['conditions']],
301+
[condition.from_raw(_DEFAULT_CONDITIONS_TEMPLATE)],
250302
raw_split.get('algo'),
251303
traffic_allocation=raw_split.get('trafficAllocation'),
252304
traffic_allocation_seed=raw_split.get('trafficAllocationSeed'),

tests/client/test_manager.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
"""SDK main manager test module."""
2-
import pytest
3-
42
from splitio.client.factory import SplitFactory
53
from splitio.client.manager import SplitManager, _LOGGER as _logger
64
from splitio.storage import SplitStorage, EventStorage, ImpressionStorage, SegmentStorage

tests/models/test_splits.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
"""Split model tests module."""
2+
import copy
23

34
from splitio.models import splits
45
from splitio.models.grammar.condition import Condition
56

6-
77
class SplitTests(object):
88
"""Split model tests."""
99

@@ -119,3 +119,17 @@ def test_to_split_view(self):
119119
assert set(as_split_view.treatments) == set(['on', 'off'])
120120
assert as_split_view.default_treatment == self.raw['defaultTreatment']
121121
assert sorted(as_split_view.sets) == sorted(list(self.raw['sets']))
122+
123+
def test_incorrect_matcher(self):
124+
"""Test incorrect matcher in split model parsing."""
125+
split = copy.deepcopy(self.raw)
126+
split['conditions'][0]['matcherGroup']['matchers'][0]['matcherType'] = 'INVALID_MATCHER'
127+
parsed = splits.from_raw(split)
128+
assert parsed.conditions[0].to_json() == splits._DEFAULT_CONDITIONS_TEMPLATE
129+
130+
# using multiple conditions
131+
split = copy.deepcopy(self.raw)
132+
split['conditions'].append(split['conditions'][0])
133+
split['conditions'][0]['matcherGroup']['matchers'][0]['matcherType'] = 'INVALID_MATCHER'
134+
parsed = splits.from_raw(split)
135+
assert parsed.conditions[0].to_json() == splits._DEFAULT_CONDITIONS_TEMPLATE

0 commit comments

Comments
 (0)