prefab-cloud-ruby 0.24.3 → 0.24.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +1 -1
- data/.rubocop.yml +13 -0
- data/CHANGELOG.md +78 -0
- data/Gemfile.lock +4 -4
- data/VERSION +1 -1
- data/bin/console +21 -0
- data/compile_protos.sh +6 -0
- data/lib/prefab/client.rb +25 -4
- data/lib/prefab/config_client.rb +17 -6
- data/lib/prefab/config_loader.rb +1 -1
- data/lib/prefab/config_resolver.rb +2 -4
- data/lib/prefab/config_value_wrapper.rb +18 -0
- data/lib/prefab/context.rb +22 -2
- data/lib/prefab/context_shape.rb +20 -0
- data/lib/prefab/context_shape_aggregator.rb +63 -0
- data/lib/prefab/criteria_evaluator.rb +61 -41
- data/lib/prefab/evaluated_configs_aggregator.rb +60 -0
- data/lib/prefab/evaluated_keys_aggregator.rb +41 -0
- data/lib/prefab/http_connection.rb +5 -1
- data/lib/prefab/local_config_parser.rb +13 -13
- data/lib/prefab/log_path_aggregator.rb +64 -0
- data/lib/prefab/logger_client.rb +11 -13
- data/lib/prefab/options.rb +37 -1
- data/lib/prefab/periodic_sync.rb +51 -0
- data/lib/prefab/time_helpers.rb +7 -0
- data/lib/prefab-cloud-ruby.rb +9 -2
- data/lib/prefab_pb.rb +33 -220
- data/prefab-cloud-ruby.gemspec +21 -5
- data/test/test_config_loader.rb +15 -15
- data/test/test_config_resolver.rb +102 -102
- data/test/test_config_value_unwrapper.rb +13 -13
- data/test/test_context.rb +42 -0
- data/test/test_context_shape.rb +51 -0
- data/test/test_context_shape_aggregator.rb +137 -0
- data/test/test_criteria_evaluator.rb +253 -150
- data/test/test_evaluated_configs_aggregator.rb +254 -0
- data/test/test_evaluated_keys_aggregator.rb +54 -0
- data/test/test_helper.rb +34 -2
- data/test/test_log_path_aggregator.rb +57 -0
- data/test/test_logger.rb +33 -33
- data/test/test_weighted_value_resolver.rb +2 -2
- metadata +21 -5
- data/lib/prefab/log_path_collector.rb +0 -102
- data/test/test_log_path_collector.rb +0 -58
@@ -0,0 +1,254 @@
|
|
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
|
@@ -0,0 +1,54 @@
|
|
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
|
data/test/test_helper.rb
CHANGED
@@ -33,6 +33,12 @@ class MockBaseClient
|
|
33
33
|
|
34
34
|
def log_internal(level, message); end
|
35
35
|
|
36
|
+
def context_shape_aggregator; end
|
37
|
+
|
38
|
+
def evaluated_keys_aggregator; end
|
39
|
+
|
40
|
+
def evaluated_configs_aggregator; end
|
41
|
+
|
36
42
|
def config_value(key)
|
37
43
|
@config_values[key]
|
38
44
|
end
|
@@ -48,7 +54,7 @@ class MockConfigClient
|
|
48
54
|
end
|
49
55
|
|
50
56
|
def get_config(key)
|
51
|
-
|
57
|
+
PrefabProto::Config.new(value: @config_values[key], key: key)
|
52
58
|
end
|
53
59
|
|
54
60
|
def mock_this_config(key, config_value)
|
@@ -95,7 +101,7 @@ def new_client(overrides = {})
|
|
95
101
|
end
|
96
102
|
|
97
103
|
def string_list(values)
|
98
|
-
|
104
|
+
PrefabProto::ConfigValue.new(string_list: PrefabProto::StringList.new(values: values))
|
99
105
|
end
|
100
106
|
|
101
107
|
def inject_config(client, config)
|
@@ -109,3 +115,29 @@ def inject_project_env_id(client, project_env_id)
|
|
109
115
|
resolver = client.config_client.instance_variable_get('@config_resolver')
|
110
116
|
resolver.project_env_id = project_env_id
|
111
117
|
end
|
118
|
+
|
119
|
+
def wait_for_post_requests(client)
|
120
|
+
max_wait = 2
|
121
|
+
sleep_time = 0.01
|
122
|
+
|
123
|
+
requests = []
|
124
|
+
|
125
|
+
client.define_singleton_method(:post) do |*params|
|
126
|
+
requests.push(params)
|
127
|
+
|
128
|
+
OpenStruct.new(status: 200)
|
129
|
+
end
|
130
|
+
|
131
|
+
yield
|
132
|
+
|
133
|
+
# let the flush thread run
|
134
|
+
wait_time = 0
|
135
|
+
while requests.empty?
|
136
|
+
wait_time += sleep_time
|
137
|
+
sleep sleep_time
|
138
|
+
|
139
|
+
raise "Waited #{max_wait} seconds for the flush thread to run, but it never did" if wait_time > max_wait
|
140
|
+
end
|
141
|
+
|
142
|
+
requests
|
143
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'timecop'
|
5
|
+
|
6
|
+
class TestLogPathAggregator < Minitest::Test
|
7
|
+
MAX_WAIT = 2
|
8
|
+
SLEEP_TIME = 0.01
|
9
|
+
|
10
|
+
def test_push
|
11
|
+
aggregator = Prefab::LogPathAggregator.new(client: new_client, max_paths: 2, sync_interval: 1000)
|
12
|
+
|
13
|
+
aggregator.push('test.test_log_path_aggregator.test_push.1', ::Logger::INFO)
|
14
|
+
aggregator.push('test.test_log_path_aggregator.test_push.2', ::Logger::DEBUG)
|
15
|
+
|
16
|
+
assert_equal 2, aggregator.data.size
|
17
|
+
|
18
|
+
# we've reached the limit, so no more
|
19
|
+
aggregator.push('test.test_log_path_aggregator.test_push.3', ::Logger::INFO)
|
20
|
+
assert_equal 2, aggregator.data.size
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_sync
|
24
|
+
Timecop.freeze do
|
25
|
+
client = new_client(namespace: 'this.is.a.namespace')
|
26
|
+
|
27
|
+
2.times { client.log.info('here is a message') }
|
28
|
+
3.times { client.log.error('here is a message') }
|
29
|
+
|
30
|
+
requests = wait_for_post_requests(client) do
|
31
|
+
client.log_path_aggregator.send(:sync)
|
32
|
+
end
|
33
|
+
|
34
|
+
assert_equal [[
|
35
|
+
'/api/v1/known-loggers',
|
36
|
+
PrefabProto::Loggers.new(
|
37
|
+
loggers: [PrefabProto::Logger.new(logger_name: 'test.test_log_path_aggregator.test_sync',
|
38
|
+
infos: 2, errors: 3)],
|
39
|
+
start_at: Prefab::TimeHelpers.now_in_ms,
|
40
|
+
end_at: Prefab::TimeHelpers.now_in_ms,
|
41
|
+
instance_hash: client.instance_hash,
|
42
|
+
namespace: 'this.is.a.namespace'
|
43
|
+
)
|
44
|
+
]], requests
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def new_client(overrides = {})
|
51
|
+
super(**{
|
52
|
+
prefab_datasources: Prefab::Options::DATASOURCES::ALL,
|
53
|
+
api_key: '123-development-yourapikey-SDK',
|
54
|
+
collect_sync_interval: 1000 # we'll trigger sync manually in our test
|
55
|
+
}.merge(overrides))
|
56
|
+
end
|
57
|
+
end
|
data/test/test_logger.rb
CHANGED
@@ -10,10 +10,10 @@ class TestLogger < Minitest::Test
|
|
10
10
|
WRONG_ENV_VALUE = 'ERROR'
|
11
11
|
PROJECT_ENV_ID = 1
|
12
12
|
|
13
|
-
DEFAULT_ROW =
|
13
|
+
DEFAULT_ROW = PrefabProto::ConfigRow.new(
|
14
14
|
values: [
|
15
|
-
|
16
|
-
value:
|
15
|
+
PrefabProto::ConditionalValue.new(
|
16
|
+
value: PrefabProto::ConfigValue.new(log_level: DEFAULT_VALUE)
|
17
17
|
)
|
18
18
|
]
|
19
19
|
)
|
@@ -179,44 +179,44 @@ class TestLogger < Minitest::Test
|
|
179
179
|
def test_logging_with_criteria_on_top_level_key
|
180
180
|
prefix = 'my.own.prefix'
|
181
181
|
|
182
|
-
config =
|
182
|
+
config = PrefabProto::Config.new(
|
183
183
|
key: 'log-level',
|
184
184
|
rows: [
|
185
185
|
DEFAULT_ROW,
|
186
186
|
|
187
187
|
# wrong env
|
188
|
-
|
188
|
+
PrefabProto::ConfigRow.new(
|
189
189
|
project_env_id: TEST_ENV_ID,
|
190
190
|
values: [
|
191
|
-
|
191
|
+
PrefabProto::ConditionalValue.new(
|
192
192
|
criteria: [
|
193
|
-
|
194
|
-
operator:
|
193
|
+
PrefabProto::Criterion.new(
|
194
|
+
operator: PrefabProto::Criterion::CriterionOperator::PROP_IS_ONE_OF,
|
195
195
|
value_to_match: string_list(['hotmail.com', 'gmail.com']),
|
196
196
|
property_name: 'user.email_suffix'
|
197
197
|
)
|
198
198
|
],
|
199
|
-
value:
|
199
|
+
value: PrefabProto::ConfigValue.new(log_level: WRONG_ENV_VALUE)
|
200
200
|
)
|
201
201
|
]
|
202
202
|
),
|
203
203
|
|
204
204
|
# correct env
|
205
|
-
|
205
|
+
PrefabProto::ConfigRow.new(
|
206
206
|
project_env_id: PROJECT_ENV_ID,
|
207
207
|
values: [
|
208
|
-
|
208
|
+
PrefabProto::ConditionalValue.new(
|
209
209
|
criteria: [
|
210
|
-
|
211
|
-
operator:
|
210
|
+
PrefabProto::Criterion.new(
|
211
|
+
operator: PrefabProto::Criterion::CriterionOperator::PROP_IS_ONE_OF,
|
212
212
|
value_to_match: string_list(['hotmail.com', 'gmail.com']),
|
213
213
|
property_name: 'user.email_suffix'
|
214
214
|
)
|
215
215
|
],
|
216
|
-
value:
|
216
|
+
value: PrefabProto::ConfigValue.new(log_level: DESIRED_VALUE)
|
217
217
|
),
|
218
|
-
|
219
|
-
value:
|
218
|
+
PrefabProto::ConditionalValue.new(
|
219
|
+
value: PrefabProto::ConfigValue.new(log_level: DEFAULT_ENV_VALUE)
|
220
220
|
)
|
221
221
|
]
|
222
222
|
)
|
@@ -272,56 +272,56 @@ class TestLogger < Minitest::Test
|
|
272
272
|
def test_logging_with_criteria_on_key_path
|
273
273
|
prefix = 'my.own.prefix'
|
274
274
|
|
275
|
-
config =
|
275
|
+
config = PrefabProto::Config.new(
|
276
276
|
key: 'log-level.my.own.prefix.test.test_logger',
|
277
277
|
rows: [
|
278
278
|
DEFAULT_ROW,
|
279
279
|
|
280
280
|
# wrong env
|
281
|
-
|
281
|
+
PrefabProto::ConfigRow.new(
|
282
282
|
project_env_id: TEST_ENV_ID,
|
283
283
|
values: [
|
284
|
-
|
284
|
+
PrefabProto::ConditionalValue.new(
|
285
285
|
criteria: [
|
286
|
-
|
287
|
-
operator:
|
286
|
+
PrefabProto::Criterion.new(
|
287
|
+
operator: PrefabProto::Criterion::CriterionOperator::PROP_IS_ONE_OF,
|
288
288
|
value_to_match: string_list(['hotmail.com', 'gmail.com']),
|
289
289
|
property_name: 'email_suffix'
|
290
290
|
)
|
291
291
|
],
|
292
|
-
value:
|
292
|
+
value: PrefabProto::ConfigValue.new(log_level: WRONG_ENV_VALUE)
|
293
293
|
)
|
294
294
|
]
|
295
295
|
),
|
296
296
|
|
297
297
|
# correct env
|
298
|
-
|
298
|
+
PrefabProto::ConfigRow.new(
|
299
299
|
project_env_id: PROJECT_ENV_ID,
|
300
300
|
values: [
|
301
|
-
|
301
|
+
PrefabProto::ConditionalValue.new(
|
302
302
|
criteria: [
|
303
|
-
|
304
|
-
operator:
|
303
|
+
PrefabProto::Criterion.new(
|
304
|
+
operator: PrefabProto::Criterion::CriterionOperator::PROP_IS_ONE_OF,
|
305
305
|
value_to_match: string_list(['hotmail.com', 'gmail.com']),
|
306
306
|
property_name: 'user.email_suffix'
|
307
307
|
)
|
308
308
|
],
|
309
|
-
value:
|
309
|
+
value: PrefabProto::ConfigValue.new(log_level: DESIRED_VALUE)
|
310
310
|
),
|
311
311
|
|
312
|
-
|
312
|
+
PrefabProto::ConditionalValue.new(
|
313
313
|
criteria: [
|
314
|
-
|
315
|
-
operator:
|
314
|
+
PrefabProto::Criterion.new(
|
315
|
+
operator: PrefabProto::Criterion::CriterionOperator::PROP_IS_ONE_OF,
|
316
316
|
value_to_match: string_list(%w[user:4567]),
|
317
317
|
property_name: 'user.tracking_id'
|
318
318
|
)
|
319
319
|
],
|
320
|
-
value:
|
320
|
+
value: PrefabProto::ConfigValue.new(log_level: DESIRED_VALUE)
|
321
321
|
),
|
322
322
|
|
323
|
-
|
324
|
-
value:
|
323
|
+
PrefabProto::ConditionalValue.new(
|
324
|
+
value: PrefabProto::ConfigValue.new(log_level: DEFAULT_ENV_VALUE)
|
325
325
|
)
|
326
326
|
]
|
327
327
|
)
|
@@ -58,8 +58,8 @@ class TestWeightedValueResolver < Minitest::Test
|
|
58
58
|
end
|
59
59
|
|
60
60
|
def weighted_value(string, weight)
|
61
|
-
|
62
|
-
value:
|
61
|
+
PrefabProto::WeightedValue.new(
|
62
|
+
value: PrefabProto::ConfigValue.new(string: string), weight: weight
|
63
63
|
)
|
64
64
|
end
|
65
65
|
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.
|
4
|
+
version: 0.24.5
|
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-
|
11
|
+
date: 2023-07-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -172,9 +172,11 @@ dependencies:
|
|
172
172
|
version: '0'
|
173
173
|
description: Feature Flags, Live Config, and Dynamic Log Levels as a service
|
174
174
|
email: jdwyer@prefab.cloud
|
175
|
-
executables:
|
175
|
+
executables:
|
176
|
+
- console
|
176
177
|
extensions: []
|
177
178
|
extra_rdoc_files:
|
179
|
+
- CHANGELOG.md
|
178
180
|
- LICENSE.txt
|
179
181
|
- README.md
|
180
182
|
files:
|
@@ -182,7 +184,9 @@ files:
|
|
182
184
|
- ".envrc.sample"
|
183
185
|
- ".github/workflows/ruby.yml"
|
184
186
|
- ".gitmodules"
|
187
|
+
- ".rubocop.yml"
|
185
188
|
- ".tool-versions"
|
189
|
+
- CHANGELOG.md
|
186
190
|
- CODEOWNERS
|
187
191
|
- Gemfile
|
188
192
|
- Gemfile.lock
|
@@ -190,6 +194,7 @@ files:
|
|
190
194
|
- README.md
|
191
195
|
- Rakefile
|
192
196
|
- VERSION
|
197
|
+
- bin/console
|
193
198
|
- compile_protos.sh
|
194
199
|
- lib/prefab-cloud-ruby.rb
|
195
200
|
- lib/prefab/client.rb
|
@@ -197,25 +202,32 @@ files:
|
|
197
202
|
- lib/prefab/config_loader.rb
|
198
203
|
- lib/prefab/config_resolver.rb
|
199
204
|
- lib/prefab/config_value_unwrapper.rb
|
205
|
+
- lib/prefab/config_value_wrapper.rb
|
200
206
|
- lib/prefab/context.rb
|
207
|
+
- lib/prefab/context_shape.rb
|
208
|
+
- lib/prefab/context_shape_aggregator.rb
|
201
209
|
- lib/prefab/criteria_evaluator.rb
|
202
210
|
- lib/prefab/error.rb
|
203
211
|
- lib/prefab/errors/initialization_timeout_error.rb
|
204
212
|
- lib/prefab/errors/invalid_api_key_error.rb
|
205
213
|
- lib/prefab/errors/missing_default_error.rb
|
214
|
+
- lib/prefab/evaluated_configs_aggregator.rb
|
215
|
+
- lib/prefab/evaluated_keys_aggregator.rb
|
206
216
|
- lib/prefab/exponential_backoff.rb
|
207
217
|
- lib/prefab/feature_flag_client.rb
|
208
218
|
- lib/prefab/http_connection.rb
|
209
219
|
- lib/prefab/internal_logger.rb
|
210
220
|
- lib/prefab/local_config_parser.rb
|
211
|
-
- lib/prefab/
|
221
|
+
- lib/prefab/log_path_aggregator.rb
|
212
222
|
- lib/prefab/logger_client.rb
|
213
223
|
- lib/prefab/murmer3.rb
|
214
224
|
- lib/prefab/noop_cache.rb
|
215
225
|
- lib/prefab/noop_stats.rb
|
216
226
|
- lib/prefab/options.rb
|
227
|
+
- lib/prefab/periodic_sync.rb
|
217
228
|
- lib/prefab/resolved_config_presenter.rb
|
218
229
|
- lib/prefab/sse_logger.rb
|
230
|
+
- lib/prefab/time_helpers.rb
|
219
231
|
- lib/prefab/weighted_value_resolver.rb
|
220
232
|
- lib/prefab/yaml_config_parser.rb
|
221
233
|
- lib/prefab_pb.rb
|
@@ -230,13 +242,17 @@ files:
|
|
230
242
|
- test/test_config_resolver.rb
|
231
243
|
- test/test_config_value_unwrapper.rb
|
232
244
|
- test/test_context.rb
|
245
|
+
- test/test_context_shape.rb
|
246
|
+
- test/test_context_shape_aggregator.rb
|
233
247
|
- test/test_criteria_evaluator.rb
|
248
|
+
- test/test_evaluated_configs_aggregator.rb
|
249
|
+
- test/test_evaluated_keys_aggregator.rb
|
234
250
|
- test/test_exponential_backoff.rb
|
235
251
|
- test/test_feature_flag_client.rb
|
236
252
|
- test/test_helper.rb
|
237
253
|
- test/test_integration.rb
|
238
254
|
- test/test_local_config_parser.rb
|
239
|
-
- test/
|
255
|
+
- test/test_log_path_aggregator.rb
|
240
256
|
- test/test_logger.rb
|
241
257
|
- test/test_options.rb
|
242
258
|
- test/test_weighted_value_resolver.rb
|