Skip to content

Commit 71c04c2

Browse files
authored
Merge pull request #556 from splitio/T-FME-4181-prereq-evaluator
Updated evaluator
2 parents 16125cf + e58a513 commit 71c04c2

File tree

4 files changed

+110
-4
lines changed

4 files changed

+110
-4
lines changed

lib/splitclient-rb/engine/models/label.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ class SplitIoClient::Engine::Models::Label
66
NOT_IN_SPLIT = 'not in split'.freeze
77
NOT_READY = 'not ready'.freeze
88
NOT_FOUND = 'definition not found'.freeze
9+
PREREQUISITES_NOT_MET = 'prerequisites not met'.freeze
910
end

lib/splitclient-rb/engine/parser/evaluator.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@ def split_configurations(treatment, split)
3838
end
3939

4040
def match(split, keys, attributes)
41+
prerequisites_matcher = SplitIoClient::PrerequisitesMatcher.new(split[:prerequisites], @config.split_logger)
42+
return treatment_hash(Models::Label::PREREQUISITES_NOT_MET, split[:defaultTreatment], split[:changeNumber], split_configurations(split[:defaultTreatment], split)) unless prerequisites_matcher.match?(
43+
matching_key: keys[:matching_key],
44+
bucketing_key: keys[:bucketing_key],
45+
evaluator: self,
46+
attributes: attributes
47+
)
48+
4149
in_rollout = false
4250
key = keys[:bucketing_key] ? keys[:bucketing_key] : keys[:matching_key]
4351
legacy_algo = (split[:algo] == 1 || split[:algo] == nil) ? true : false

spec/engine/parser/evaluator_spec.rb

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@
33
require 'spec_helper'
44

55
describe SplitIoClient::Engine::Parser::Evaluator do
6-
let(:segments_repository) { SplitIoClient::Cache::Repositories::SegmentsRepository.new(@default_config) }
7-
let(:rule_based_segments_repository) { SplitIoClient::Cache::Repositories::RuleBasedSegmentsRepository.new(@default_config) }
6+
let(:config) { SplitIoClient::SplitConfig.new(logger: Logger.new(StringIO.new)) }
7+
let(:segments_repository) { SplitIoClient::Cache::Repositories::SegmentsRepository.new(config) }
8+
let(:rule_based_segments_repository) { SplitIoClient::Cache::Repositories::RuleBasedSegmentsRepository.new(config) }
89
let(:flag_sets_repository) {SplitIoClient::Cache::Repositories::MemoryFlagSetsRepository.new([])}
910
let(:flag_set_filter) {SplitIoClient::Cache::Filter::FlagSetsFilter.new([])}
10-
let(:splits_repository) { SplitIoClient::Cache::Repositories::SplitsRepository.new(@default_config, flag_sets_repository, flag_set_filter) }
11-
let(:evaluator) { described_class.new(segments_repository, splits_repository, rule_based_segments_repository, true) }
11+
let(:splits_repository) { SplitIoClient::Cache::Repositories::SplitsRepository.new(config, flag_sets_repository, flag_set_filter) }
12+
let(:evaluator) { described_class.new(segments_repository, splits_repository, rule_based_segments_repository, config) }
1213

1314
let(:killed_split) { { killed: true, defaultTreatment: 'default' } }
1415
let(:archived_split) { { status: 'ARCHIVED' } }
@@ -17,6 +18,11 @@
1718
SplitIoClient.root, 'spec/test_data/splits/engine/dependency_matcher.json'
1819
)), symbolize_names: true)
1920
end
21+
let(:split_data_prereq) do
22+
JSON.parse(File.read(File.join(
23+
SplitIoClient.root, 'spec/test_data/splits/engine/prerequisites_matcher.json'
24+
)), symbolize_names: true)
25+
end
2026

2127
it 'returns killed treatment' do
2228
expect(evaluator.evaluate_feature_flag({ matching_key: 'foo' }, killed_split))
@@ -40,4 +46,16 @@
4046
evaluator.evaluate_feature_flag({ bucketing_key: nil, matching_key: 'fake_user_id_1' }, split_data[:ff][:d][1])
4147
end
4248
end
49+
50+
context 'prerequisites matcher' do
51+
it 'test match' do
52+
splits_repository.update([split_data_prereq[:ff][:d][0], split_data_prereq[:ff][:d][1]], [], 1234)
53+
54+
result = evaluator.evaluate_feature_flag({ bucketing_key: nil, matching_key: 'fake_user' }, 'test_prereq')
55+
expect(result[:treatment]).to eq('off_default')
56+
57+
result = evaluator.evaluate_feature_flag({ bucketing_key: nil, matching_key: 'fake_user_id_1' }, 'test_prereq')
58+
expect(result[:treatment]).to eq('on')
59+
end
60+
end
4361
end
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
{ "ff":{
2+
"d": [
3+
{
4+
"orgId":"cee838c0-b3eb-11e5-855f-4eacec19f7bf",
5+
"environment":"cf2d09f0-b3eb-11e5-855f-4eacec19f7bf",
6+
"name":"test_whitelist",
7+
"prerequisites": [],
8+
"trafficTypeId":"u",
9+
"trafficTypeName":"User",
10+
"seed":-1245274114,
11+
"status":"ACTIVE",
12+
"killed":false,
13+
"defaultTreatment":"off",
14+
"conditions":[
15+
{
16+
"matcherGroup":{
17+
"combiner":"AND",
18+
"matchers":[
19+
{
20+
"matcherType":"WHITELIST",
21+
"negate":false,
22+
"userDefinedSegmentMatcherData":null,
23+
"whitelistMatcherData":{
24+
"whitelist":[
25+
"fake_user_id_1",
26+
"fake_user_id_3"
27+
]
28+
}
29+
}
30+
]
31+
},
32+
"partitions":[
33+
{
34+
"treatment":"on",
35+
"size":100
36+
}
37+
]
38+
}
39+
],
40+
"sets": ["set_4"]
41+
},
42+
{
43+
"orgId":"cee838c0-b3eb-11e5-855f-4eacec19f7bf",
44+
"environment":"cf2d09f0-b3eb-11e5-855f-4eacec19f7bf",
45+
"name":"test_prereq",
46+
"prerequisites": [{"n": "test_whitelist", "ts": ["on"]}],
47+
"trafficTypeId":"u",
48+
"trafficTypeName":"User",
49+
"seed":-1245274114,
50+
"status":"ACTIVE",
51+
"killed":false,
52+
"defaultTreatment":"off_default",
53+
"conditions":[
54+
{
55+
"matcherGroup":{
56+
"combiner":"AND",
57+
"matchers":[
58+
{
59+
"matcherType":"ALL_KEYS",
60+
"negate":false,
61+
"userDefinedSegmentMatcherData":null,
62+
"whitelistMatcherData":null
63+
}
64+
]
65+
},
66+
"partitions":[
67+
{
68+
"treatment":"on",
69+
"size":100
70+
}
71+
]
72+
}
73+
]
74+
}
75+
],
76+
"s": -1,
77+
"t": -1
78+
}, "rbs": {"d":[], "s":-1, "t": -1}
79+
}

0 commit comments

Comments
 (0)