prefab-cloud-ruby 0.24.5 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -0
  3. data/VERSION +1 -1
  4. data/compile_protos.sh +7 -0
  5. data/lib/prefab/client.rb +20 -46
  6. data/lib/prefab/config_client.rb +9 -12
  7. data/lib/prefab/config_resolver.rb +2 -1
  8. data/lib/prefab/config_value_unwrapper.rb +20 -9
  9. data/lib/prefab/context.rb +43 -7
  10. data/lib/prefab/context_shape_aggregator.rb +1 -1
  11. data/lib/prefab/criteria_evaluator.rb +24 -16
  12. data/lib/prefab/evaluation.rb +48 -0
  13. data/lib/prefab/evaluation_summary_aggregator.rb +85 -0
  14. data/lib/prefab/example_contexts_aggregator.rb +76 -0
  15. data/lib/prefab/exponential_backoff.rb +5 -0
  16. data/lib/prefab/feature_flag_client.rb +0 -2
  17. data/lib/prefab/log_path_aggregator.rb +1 -1
  18. data/lib/prefab/logger_client.rb +12 -13
  19. data/lib/prefab/options.rb +52 -43
  20. data/lib/prefab/periodic_sync.rb +30 -13
  21. data/lib/prefab/rate_limit_cache.rb +41 -0
  22. data/lib/prefab/resolved_config_presenter.rb +2 -4
  23. data/lib/prefab/weighted_value_resolver.rb +1 -1
  24. data/lib/prefab-cloud-ruby.rb +5 -5
  25. data/lib/prefab_pb.rb +11 -1
  26. data/prefab-cloud-ruby.gemspec +14 -9
  27. data/test/integration_test.rb +1 -3
  28. data/test/integration_test_helpers.rb +0 -1
  29. data/test/support/common_helpers.rb +174 -0
  30. data/test/support/mock_base_client.rb +44 -0
  31. data/test/support/mock_config_client.rb +19 -0
  32. data/test/support/mock_config_loader.rb +1 -0
  33. data/test/test_client.rb +354 -40
  34. data/test/test_config_client.rb +1 -0
  35. data/test/test_config_loader.rb +1 -0
  36. data/test/test_config_resolver.rb +25 -24
  37. data/test/test_config_value_unwrapper.rb +22 -32
  38. data/test/test_context.rb +1 -0
  39. data/test/test_context_shape_aggregator.rb +11 -1
  40. data/test/test_criteria_evaluator.rb +180 -133
  41. data/test/test_evaluation_summary_aggregator.rb +162 -0
  42. data/test/test_example_contexts_aggregator.rb +238 -0
  43. data/test/test_helper.rb +5 -131
  44. data/test/test_integration.rb +6 -4
  45. data/test/test_local_config_parser.rb +2 -2
  46. data/test/test_log_path_aggregator.rb +9 -1
  47. data/test/test_logger.rb +6 -5
  48. data/test/test_options.rb +33 -2
  49. data/test/test_rate_limit_cache.rb +44 -0
  50. data/test/test_weighted_value_resolver.rb +13 -7
  51. metadata +13 -8
  52. data/lib/prefab/evaluated_configs_aggregator.rb +0 -60
  53. data/lib/prefab/evaluated_keys_aggregator.rb +0 -41
  54. data/lib/prefab/noop_cache.rb +0 -15
  55. data/lib/prefab/noop_stats.rb +0 -8
  56. data/test/test_evaluated_configs_aggregator.rb +0 -254
  57. data/test/test_evaluated_keys_aggregator.rb +0 -54
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+ require 'timecop'
5
+
6
+ class RateLimitCacheTest < Minitest::Test
7
+ def test_set_and_fresh
8
+ cache = Prefab::RateLimitCache.new(5)
9
+ cache.set('key')
10
+ assert cache.fresh?('key')
11
+ end
12
+
13
+ def test_fresh_with_no_set
14
+ cache = Prefab::RateLimitCache.new(5)
15
+ refute cache.fresh?('key')
16
+ end
17
+
18
+ def test_get_after_expiration
19
+ cache = Prefab::RateLimitCache.new(5)
20
+
21
+ Timecop.freeze(Time.now - 6) do
22
+ cache.set('key')
23
+ assert cache.fresh?('key')
24
+ end
25
+
26
+ refute cache.fresh?('key')
27
+
28
+ # but the data is still there
29
+ assert cache.data.get('key')
30
+ end
31
+
32
+ def test_prune
33
+ cache = Prefab::RateLimitCache.new(5)
34
+
35
+ Timecop.freeze(Time.now - 6) do
36
+ cache.set('key')
37
+ assert cache.fresh?('key')
38
+ end
39
+
40
+ cache.prune
41
+
42
+ refute cache.fresh?('key')
43
+ end
44
+ end
@@ -8,30 +8,36 @@ class TestWeightedValueResolver < Minitest::Test
8
8
  def test_resolving_single_value
9
9
  values = weighted_values([['abc', 1]])
10
10
  resolver = Prefab::WeightedValueResolver.new(values, KEY, nil)
11
- assert_equal 'abc', resolver.resolve.value.string
11
+ assert_equal 'abc', resolver.resolve[0].value.string
12
+ assert_equal 0, resolver.resolve[1]
12
13
  end
13
14
 
14
15
  def test_resolving_multiple_values_evenly_distributed
15
16
  values = weighted_values([['abc', 1], ['def', 1]])
16
17
 
17
18
  resolver = Prefab::WeightedValueResolver.new(values, KEY, 'user:001')
18
- assert_equal 'abc', resolver.resolve.value.string
19
+ assert_equal 'abc', resolver.resolve[0].value.string
20
+ assert_equal 0, resolver.resolve[1]
19
21
 
20
22
  resolver = Prefab::WeightedValueResolver.new(values, KEY, 'user:456')
21
- assert_equal 'def', resolver.resolve.value.string
23
+ assert_equal 'def', resolver.resolve[0].value.string
24
+ assert_equal 1, resolver.resolve[1]
22
25
  end
23
26
 
24
27
  def test_resolving_multiple_values_unevenly_distributed
25
28
  values = weighted_values([['abc', 1], ['def', 98], ['ghi', 1]])
26
29
 
27
30
  resolver = Prefab::WeightedValueResolver.new(values, KEY, 'user:456')
28
- assert_equal 'def', resolver.resolve.value.string
31
+ assert_equal 'def', resolver.resolve[0].value.string
32
+ assert_equal 1, resolver.resolve[1]
29
33
 
30
34
  resolver = Prefab::WeightedValueResolver.new(values, KEY, 'user:103')
31
- assert_equal 'ghi', resolver.resolve.value.string
35
+ assert_equal 'ghi', resolver.resolve[0].value.string
36
+ assert_equal 2, resolver.resolve[1]
32
37
 
33
38
  resolver = Prefab::WeightedValueResolver.new(values, KEY, 'user:119')
34
- assert_equal 'abc', resolver.resolve.value.string
39
+ assert_equal 'abc', resolver.resolve[0].value.string
40
+ assert_equal 0, resolver.resolve[1]
35
41
  end
36
42
 
37
43
  def test_resolving_multiple_values_with_simulation
@@ -39,7 +45,7 @@ class TestWeightedValueResolver < Minitest::Test
39
45
  results = {}
40
46
 
41
47
  10_000.times do |i|
42
- result = Prefab::WeightedValueResolver.new(values, KEY, "user:#{i}").resolve.value.string
48
+ result = Prefab::WeightedValueResolver.new(values, KEY, "user:#{i}").resolve[0].value.string
43
49
  results[result] ||= 0
44
50
  results[result] += 1
45
51
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prefab-cloud-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.24.5
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeff Dwyer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-07-10 00:00:00.000000000 Z
11
+ date: 2023-08-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -211,8 +211,9 @@ files:
211
211
  - lib/prefab/errors/initialization_timeout_error.rb
212
212
  - lib/prefab/errors/invalid_api_key_error.rb
213
213
  - lib/prefab/errors/missing_default_error.rb
214
- - lib/prefab/evaluated_configs_aggregator.rb
215
- - lib/prefab/evaluated_keys_aggregator.rb
214
+ - lib/prefab/evaluation.rb
215
+ - lib/prefab/evaluation_summary_aggregator.rb
216
+ - lib/prefab/example_contexts_aggregator.rb
216
217
  - lib/prefab/exponential_backoff.rb
217
218
  - lib/prefab/feature_flag_client.rb
218
219
  - lib/prefab/http_connection.rb
@@ -221,10 +222,9 @@ files:
221
222
  - lib/prefab/log_path_aggregator.rb
222
223
  - lib/prefab/logger_client.rb
223
224
  - lib/prefab/murmer3.rb
224
- - lib/prefab/noop_cache.rb
225
- - lib/prefab/noop_stats.rb
226
225
  - lib/prefab/options.rb
227
226
  - lib/prefab/periodic_sync.rb
227
+ - lib/prefab/rate_limit_cache.rb
228
228
  - lib/prefab/resolved_config_presenter.rb
229
229
  - lib/prefab/sse_logger.rb
230
230
  - lib/prefab/time_helpers.rb
@@ -236,6 +236,10 @@ files:
236
236
  - test/.prefab.unit_tests.config.yaml
237
237
  - test/integration_test.rb
238
238
  - test/integration_test_helpers.rb
239
+ - test/support/common_helpers.rb
240
+ - test/support/mock_base_client.rb
241
+ - test/support/mock_config_client.rb
242
+ - test/support/mock_config_loader.rb
239
243
  - test/test_client.rb
240
244
  - test/test_config_client.rb
241
245
  - test/test_config_loader.rb
@@ -245,8 +249,8 @@ files:
245
249
  - test/test_context_shape.rb
246
250
  - test/test_context_shape_aggregator.rb
247
251
  - test/test_criteria_evaluator.rb
248
- - test/test_evaluated_configs_aggregator.rb
249
- - test/test_evaluated_keys_aggregator.rb
252
+ - test/test_evaluation_summary_aggregator.rb
253
+ - test/test_example_contexts_aggregator.rb
250
254
  - test/test_exponential_backoff.rb
251
255
  - test/test_feature_flag_client.rb
252
256
  - test/test_helper.rb
@@ -255,6 +259,7 @@ files:
255
259
  - test/test_log_path_aggregator.rb
256
260
  - test/test_logger.rb
257
261
  - test/test_options.rb
262
+ - test/test_rate_limit_cache.rb
258
263
  - test/test_weighted_value_resolver.rb
259
264
  homepage: http://github.com/prefab-cloud/prefab-cloud-ruby
260
265
  licenses:
@@ -1,60 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'periodic_sync'
4
-
5
- module Prefab
6
- class EvaluatedConfigsAggregator
7
- include Prefab::PeriodicSync
8
-
9
- attr_reader :data
10
-
11
- def initialize(client:, max_configs:, sync_interval:)
12
- @max_configs = max_configs
13
- @client = client
14
- @name = 'evaluated_configs_aggregator'
15
-
16
- @data = Concurrent::Array.new
17
-
18
- start_periodic_sync(sync_interval)
19
- end
20
-
21
- def push(evaluation)
22
- return if @data.size >= @max_configs
23
-
24
- @data.push(evaluation)
25
- end
26
-
27
- def prepare_data
28
- to_ship = @data.dup
29
- @data.clear
30
-
31
- to_ship.map { |e| coerce_to_proto(e) }
32
- end
33
-
34
- def coerce_to_proto(evaluation)
35
- config, result, context = evaluation
36
-
37
- PrefabProto::EvaluatedConfig.new(
38
- key: config.key,
39
- config_version: config.id,
40
- result: result,
41
- context: context.to_proto(@client.namespace),
42
- timestamp: Prefab::TimeHelpers.now_in_ms
43
- )
44
- end
45
-
46
- private
47
-
48
- def flush(to_ship, _)
49
- @pool.post do
50
- log_internal "Uploading evaluated configs for #{to_ship.size}"
51
-
52
- configs = PrefabProto::EvaluatedConfigs.new(configs: to_ship)
53
-
54
- result = @client.post('/api/v1/evaluated-configs', configs)
55
-
56
- log_internal "Uploaded #{to_ship.size} configs: #{result.status}"
57
- end
58
- end
59
- end
60
- end
@@ -1,41 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'periodic_sync'
4
-
5
- module Prefab
6
- class EvaluatedKeysAggregator
7
- include Prefab::PeriodicSync
8
-
9
- attr_reader :data
10
-
11
- def initialize(client:, max_keys:, sync_interval:)
12
- @max_keys = max_keys
13
- @client = client
14
- @name = 'evaluated_keys_aggregator'
15
-
16
- @data = Concurrent::Set.new
17
-
18
- start_periodic_sync(sync_interval)
19
- end
20
-
21
- def push(key)
22
- return if @data.size >= @max_keys
23
-
24
- @data.add(key)
25
- end
26
-
27
- private
28
-
29
- def flush(to_ship, _)
30
- @pool.post do
31
- log_internal "Uploading evaluated keys for #{to_ship.size}"
32
-
33
- keys = PrefabProto::EvaluatedKeys.new(keys: to_ship.to_a, namespace: @client.namespace)
34
-
35
- result = @client.post('/api/v1/evaluated-keys', keys)
36
-
37
- log_internal "Uploaded #{to_ship.size} keys: #{result.status}"
38
- end
39
- end
40
- end
41
- end
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Prefab
4
- class NoopCache
5
- def fetch(_name, _opts)
6
- yield
7
- end
8
-
9
- def write(name, value, opts = nil); end
10
-
11
- def read(name); end
12
-
13
- def delete(name); end
14
- end
15
- end
@@ -1,8 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Prefab
4
- class NoopStats
5
- # receives increment("prefab.ratelimit.limitcheck", {:tags=>["policy_group:page_view", "pass:true"]})
6
- def increment(name, opts = {}); end
7
- end
8
- end
@@ -1,254 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'test_helper'
4
- require 'timecop'
5
-
6
- class TestEvaluatedConfigsAggregator < Minitest::Test
7
- MAX_WAIT = 2
8
- SLEEP_TIME = 0.01
9
-
10
- def test_push
11
- aggregator = Prefab::EvaluatedConfigsAggregator.new(client: new_client, max_configs: 2, sync_interval: 1000)
12
-
13
- aggregator.push([])
14
- aggregator.push([])
15
-
16
- assert_equal 2, aggregator.data.size
17
-
18
- # we've reached the limit, so no more
19
- aggregator.push([])
20
- assert_equal 2, aggregator.data.size
21
- end
22
-
23
- def test_coerce_to_proto
24
- aggregator = Prefab::EvaluatedConfigsAggregator.new(client: new_client, max_configs: 2, sync_interval: 2)
25
-
26
- Timecop.freeze do
27
- coerced = aggregator.coerce_to_proto([
28
- CONFIG_1,
29
- DESIRED_VALUE,
30
- Prefab::Context.new(CONTEXT)
31
- ])
32
-
33
- assert_equal PrefabProto::EvaluatedConfig.new(
34
- key: CONFIG_1.key,
35
- config_version: CONFIG_1.id,
36
- result: DESIRED_VALUE,
37
- context: PrefabProto::ContextSet.new(
38
- contexts: [
39
- PrefabProto::Context.new(
40
- type: "user",
41
- values: {
42
- "id" => PrefabProto::ConfigValue.new(int: 1),
43
- "email_suffix" => PrefabProto::ConfigValue.new(string: "hotmail.com")
44
- }
45
- ),
46
- PrefabProto::Context.new(
47
- type: "team",
48
- values: {
49
- "id" => PrefabProto::ConfigValue.new(int: 2),
50
- "name" => PrefabProto::ConfigValue.new(string: "team-name")
51
- }
52
- ),
53
- PrefabProto::Context.new(
54
- type: "prefab",
55
- values: {
56
- "current-time" => PrefabProto::ConfigValue.new(int: Prefab::TimeHelpers.now_in_ms),
57
- }
58
- ),
59
- ]
60
- ),
61
- timestamp: Prefab::TimeHelpers.now_in_ms
62
- ), coerced
63
- end
64
- end
65
-
66
- def test_sync
67
- client = new_client(namespace: 'this.is.a.namespace')
68
-
69
- inject_config(client, CONFIG_1)
70
- inject_config(client, CONFIG_2)
71
- inject_project_env_id(client, PROJECT_ENV_ID)
72
-
73
- client.get CONFIG_1.key, 'default', CONTEXT
74
- client.get CONFIG_1.key, 'default', { user: { email_suffix: "example.com" }, device: { mobile: true } }
75
- client.get CONFIG_2.key, 'default', CONTEXT
76
-
77
- # logger items are not reported
78
- client.get "#{Prefab::ConfigClient::LOGGING_KEY_PREFIX}something", 'default', CONTEXT
79
- client.get "#{Prefab::LoggerClient::BASE_KEY}", 'default', CONTEXT
80
-
81
- requests = wait_for_post_requests(client) do
82
- client.evaluated_configs_aggregator.send(:sync)
83
- end
84
-
85
- assert_equal [[
86
- '/api/v1/evaluated-configs',
87
- PrefabProto::EvaluatedConfigs.new(
88
- configs: [
89
- PrefabProto::EvaluatedConfig.new(
90
- key: CONFIG_1.key,
91
- config_version: CONFIG_1.id,
92
- result: DESIRED_VALUE,
93
- context: PrefabProto::ContextSet.new(
94
- contexts: [
95
- PrefabProto::Context.new(
96
- type: "user",
97
- values: {
98
- "id" => PrefabProto::ConfigValue.new(int: 1),
99
- "email_suffix" => PrefabProto::ConfigValue.new(string: "hotmail.com")
100
- }
101
- ),
102
- PrefabProto::Context.new(
103
- type: "team",
104
- values: {
105
- "id" => PrefabProto::ConfigValue.new(int: 2),
106
- "name" => PrefabProto::ConfigValue.new(string: "team-name")
107
- }
108
- ),
109
- PrefabProto::Context.new(
110
- type: "prefab",
111
- values: {
112
- "current-time" => PrefabProto::ConfigValue.new(int: Prefab::TimeHelpers.now_in_ms),
113
- "namespace" => PrefabProto::ConfigValue.new(string: "this.is.a.namespace"),
114
- }
115
- ),
116
- ]
117
- ),
118
- timestamp: Prefab::TimeHelpers.now_in_ms
119
- ),
120
- PrefabProto::EvaluatedConfig.new(
121
- key: CONFIG_1.key,
122
- config_version: CONFIG_1.id,
123
- result: DEFAULT_VALUE,
124
- context: PrefabProto::ContextSet.new(
125
- contexts: [
126
- PrefabProto::Context.new(
127
- type: "user",
128
- values: {
129
- "email_suffix" => PrefabProto::ConfigValue.new(string: "example.com")
130
- }
131
- ),
132
- PrefabProto::Context.new(
133
- type: "device",
134
- values: {
135
- "mobile" => PrefabProto::ConfigValue.new(bool: true),
136
- }
137
- ),
138
- PrefabProto::Context.new(
139
- type: "prefab",
140
- values: {
141
- "current-time" => PrefabProto::ConfigValue.new(int: Prefab::TimeHelpers.now_in_ms),
142
- "namespace" => PrefabProto::ConfigValue.new(string: "this.is.a.namespace"),
143
- }
144
- )
145
-
146
- ]
147
- ),
148
- timestamp: Prefab::TimeHelpers.now_in_ms
149
- ),
150
-
151
- PrefabProto::EvaluatedConfig.new(
152
- key: CONFIG_2.key,
153
- config_version: CONFIG_2.id,
154
- result: DEFAULT_VALUE,
155
- context: PrefabProto::ContextSet.new(
156
- contexts: [
157
- PrefabProto::Context.new(
158
- type: "user",
159
- values: {
160
- "id" => PrefabProto::ConfigValue.new(int: 1),
161
- "email_suffix" => PrefabProto::ConfigValue.new(string: "hotmail.com")
162
- }
163
- ),
164
- PrefabProto::Context.new(
165
- type: "team",
166
- values: {
167
- "id" => PrefabProto::ConfigValue.new(int: 2),
168
- "name" => PrefabProto::ConfigValue.new(string: "team-name")
169
- }
170
- ),
171
- PrefabProto::Context.new(
172
- type: "prefab",
173
- values: {
174
- "current-time" => PrefabProto::ConfigValue.new(int: Prefab::TimeHelpers.now_in_ms),
175
- "namespace" => PrefabProto::ConfigValue.new(string: "this.is.a.namespace"),
176
- }
177
- )
178
- ]
179
- ),
180
- timestamp: Prefab::TimeHelpers.now_in_ms
181
- )
182
-
183
- ]
184
- )
185
- ]], requests
186
- end
187
-
188
- private
189
-
190
- def new_client(overrides = {})
191
- super(**{
192
- prefab_datasources: Prefab::Options::DATASOURCES::ALL,
193
- initialization_timeout_sec: 0,
194
- on_init_failure: Prefab::Options::ON_INITIALIZATION_FAILURE::RETURN,
195
- api_key: '123-development-yourapikey-SDK',
196
- collect_sync_interval: 1000, # we'll trigger sync manually in our test
197
- collect_evaluations: true
198
- }.merge(overrides))
199
- end
200
-
201
- DEFAULT_VALUE = PrefabProto::ConfigValue.new(string: '❌')
202
-
203
- DESIRED_VALUE = PrefabProto::ConfigValue.new(string: "✅")
204
-
205
- DEFAULT_ROW = PrefabProto::ConfigRow.new(
206
- values: [
207
- PrefabProto::ConditionalValue.new(
208
- value: DEFAULT_VALUE
209
- )
210
- ]
211
- )
212
-
213
- PROJECT_ENV_ID = 1
214
-
215
- CONFIG_1 = PrefabProto::Config.new(
216
- id: 1,
217
- key: "key.1",
218
- rows: [
219
- PrefabProto::ConfigRow.new(
220
- project_env_id: PROJECT_ENV_ID,
221
- values: [
222
- PrefabProto::ConditionalValue.new(
223
- criteria: [
224
- PrefabProto::Criterion.new(
225
- operator: PrefabProto::Criterion::CriterionOperator::PROP_IS_ONE_OF,
226
- value_to_match: string_list(['hotmail.com', 'gmail.com']),
227
- property_name: 'user.email_suffix'
228
- )
229
- ],
230
- value: DESIRED_VALUE
231
- )
232
- ]
233
- ),
234
- DEFAULT_ROW
235
- ]
236
- )
237
-
238
- CONFIG_2 = PrefabProto::Config.new(
239
- id: 2,
240
- key: "key.2",
241
- rows: [DEFAULT_ROW,]
242
- )
243
-
244
- CONTEXT = {
245
- user: {
246
- id: 1,
247
- email_suffix: 'hotmail.com'
248
- },
249
- team: {
250
- id: 2,
251
- name: 'team-name'
252
- }
253
- }
254
- end
@@ -1,54 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'test_helper'
4
-
5
- class TestEvaluatedKeysAggregator < Minitest::Test
6
- MAX_WAIT = 2
7
- SLEEP_TIME = 0.01
8
-
9
- def test_push
10
- aggregator = Prefab::EvaluatedKeysAggregator.new(client: new_client, max_keys: 2, sync_interval: 1000)
11
-
12
- aggregator.push('key.1')
13
- aggregator.push('key.2')
14
-
15
- assert_equal 2, aggregator.data.size
16
-
17
- # we've reached the limit, so no more
18
- aggregator.push('key.3')
19
- assert_equal 2, aggregator.data.size
20
- end
21
-
22
- def test_sync
23
- client = new_client(namespace: 'this.is.a.namespace')
24
-
25
- client.get 'key.1', 'default', {}
26
- client.get 'key.1', 'default', {}
27
- client.get 'key.2', 'default', {}
28
-
29
- requests = wait_for_post_requests(client) do
30
- client.evaluated_keys_aggregator.send(:sync)
31
- end
32
-
33
- assert_equal [[
34
- '/api/v1/evaluated-keys',
35
- PrefabProto::EvaluatedKeys.new(
36
- keys: ['key.1', 'key.2'],
37
- namespace: 'this.is.a.namespace'
38
- )
39
- ]], requests
40
- end
41
-
42
- private
43
-
44
- def new_client(overrides = {})
45
- super(**{
46
- prefab_datasources: Prefab::Options::DATASOURCES::ALL,
47
- initialization_timeout_sec: 0,
48
- on_init_failure: Prefab::Options::ON_INITIALIZATION_FAILURE::RETURN,
49
- api_key: '123-development-yourapikey-SDK',
50
- collect_sync_interval: 1000, # we'll trigger sync manually in our test
51
- collect_keys: true
52
- }.merge(overrides))
53
- end
54
- end