prefab-cloud-ruby 0.20.0 → 0.22.0
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/.envrc.sample +3 -0
- data/.github/workflows/ruby.yml +5 -1
- data/.gitmodules +3 -0
- data/Gemfile +14 -12
- data/Gemfile.lock +24 -14
- data/README.md +12 -10
- data/Rakefile +13 -14
- data/VERSION +1 -1
- data/lib/prefab/auth_interceptor.rb +2 -1
- data/lib/prefab/cancellable_interceptor.rb +8 -7
- data/lib/prefab/client.rb +52 -27
- data/lib/prefab/config_client.rb +59 -70
- data/lib/prefab/config_loader.rb +7 -114
- data/lib/prefab/config_resolver.rb +27 -57
- data/lib/prefab/config_value_unwrapper.rb +23 -0
- data/lib/prefab/criteria_evaluator.rb +96 -0
- data/lib/prefab/errors/invalid_api_key_error.rb +1 -1
- data/lib/prefab/feature_flag_client.rb +13 -145
- data/lib/prefab/internal_logger.rb +7 -6
- data/lib/prefab/local_config_parser.rb +110 -0
- data/lib/prefab/log_path_collector.rb +98 -0
- data/lib/prefab/logger_client.rb +46 -44
- data/lib/prefab/murmer3.rb +3 -4
- data/lib/prefab/noop_cache.rb +5 -7
- data/lib/prefab/noop_stats.rb +2 -3
- data/lib/prefab/options.rb +32 -11
- data/lib/prefab/ratelimit_client.rb +11 -13
- data/lib/prefab/sse_logger.rb +3 -2
- data/lib/prefab/weighted_value_resolver.rb +42 -0
- data/lib/prefab/yaml_config_parser.rb +32 -0
- data/lib/prefab-cloud-ruby.rb +7 -2
- data/lib/prefab_pb.rb +70 -43
- data/lib/prefab_services_pb.rb +14 -1
- data/prefab-cloud-ruby.gemspec +33 -19
- data/test/.prefab.unit_tests.config.yaml +3 -2
- data/test/integration_test.rb +98 -0
- data/test/integration_test_helpers.rb +37 -0
- data/test/test_client.rb +56 -31
- data/test/test_config_client.rb +21 -20
- data/test/test_config_loader.rb +48 -37
- data/test/test_config_resolver.rb +312 -135
- data/test/test_config_value_unwrapper.rb +83 -0
- data/test/test_criteria_evaluator.rb +533 -0
- data/test/test_feature_flag_client.rb +35 -347
- data/test/test_helper.rb +18 -14
- data/test/test_integration.rb +33 -0
- data/test/test_local_config_parser.rb +78 -0
- data/test/test_log_path_collector.rb +56 -0
- data/test/test_logger.rb +52 -51
- data/test/test_options.rb +32 -0
- data/test/test_weighted_value_resolver.rb +65 -0
- metadata +30 -16
- data/lib/prefab/config_helper.rb +0 -31
- data/run_test_harness_server.sh +0 -8
- data/test/harness_server.rb +0 -64
data/test/test_logger.rb
CHANGED
@@ -11,19 +11,19 @@ class TestCLogger < Minitest::Test
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def test_get_path
|
14
|
-
assert_equal
|
15
|
-
@logger.get_path(
|
16
|
-
|
17
|
-
|
18
|
-
assert_equal
|
19
|
-
@logger.get_path(
|
20
|
-
|
21
|
-
assert_equal
|
14
|
+
assert_equal 'test_l.foo_warn',
|
15
|
+
@logger.get_path('/Users/jdwyah/Documents/workspace/RateLimitInc/prefab-cloud-ruby/lib/test_l.rb',
|
16
|
+
'foo_warn')
|
17
|
+
|
18
|
+
assert_equal 'active_support.log_subscriber.info',
|
19
|
+
@logger.get_path('/Users/jdwyah/.rvm/gems/ruby-2.3.3@forcerank/gems/activesupport-4.1.16/lib/active_support/log_subscriber.rb',
|
20
|
+
'info')
|
21
|
+
assert_equal 'active_support.log_subscriber.info',
|
22
22
|
@logger.get_path("/Users/jeffdwyer/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/activesupport-7.0.2.4/lib/active_support/log_subscriber.rb:130:in `info'",
|
23
|
-
|
24
|
-
assert_equal
|
23
|
+
'info')
|
24
|
+
assert_equal 'unknown.info',
|
25
25
|
@logger.get_path(nil,
|
26
|
-
|
26
|
+
'info')
|
27
27
|
end
|
28
28
|
|
29
29
|
def test_loc_resolution
|
@@ -34,80 +34,81 @@ class TestCLogger < Minitest::Test
|
|
34
34
|
end # https://ruby-doc.org/core-3.0.0/Thread/Backtrace/Location.html
|
35
35
|
|
36
36
|
# verify that even if the Thread::Backtrace::Location does not have an absolute_location, we do our best
|
37
|
-
assert_equal
|
37
|
+
assert_equal 'active_support.log_subscriber.info',
|
38
38
|
@logger.get_loc_path(backtrace_location.new(nil,
|
39
|
-
|
39
|
+
'info',
|
40
40
|
"/Users/jeffdwyer/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/activesupport-7.0.2.4/lib/active_support/log_subscriber.rb:130:in `info'"))
|
41
|
-
assert_equal
|
42
|
-
@logger.get_loc_path(backtrace_location.new(
|
43
|
-
|
41
|
+
assert_equal 'test_l.info',
|
42
|
+
@logger.get_loc_path(backtrace_location.new('/Users/jdwyah/Documents/workspace/RateLimitInc/prefab-cloud-ruby/lib/test_l.rb',
|
43
|
+
'info',
|
44
44
|
"/Users/jeffdwyer/.asdf/installs/ruby/3.1.2/lib/ruby/gems/3.1.0/gems/activesupport-7.0.2.4/lib/active_support/log_subscriber.rb:130:in `info'"))
|
45
45
|
end
|
46
46
|
|
47
47
|
def test_level_of
|
48
|
-
with_env(
|
48
|
+
with_env('PREFAB_LOG_CLIENT_BOOTSTRAP_LOG_LEVEL', 'info') do
|
49
49
|
# env var overrides the default level
|
50
|
-
assert_equal Logger::INFO,
|
51
|
-
@logger.level_of(
|
50
|
+
assert_equal ::Logger::INFO,
|
51
|
+
@logger.level_of('app.models.user'), 'PREFAB_LOG_CLIENT_BOOTSTRAP_LOG_LEVEL is info'
|
52
52
|
|
53
53
|
@logger.set_config_client(MockConfigClient.new({}))
|
54
|
-
assert_equal Logger::WARN,
|
55
|
-
@logger.level_of(
|
54
|
+
assert_equal ::Logger::WARN,
|
55
|
+
@logger.level_of('app.models.user'), 'default is warn'
|
56
56
|
|
57
|
-
@logger.set_config_client(MockConfigClient.new(
|
58
|
-
assert_equal Logger::INFO,
|
59
|
-
@logger.level_of(
|
57
|
+
@logger.set_config_client(MockConfigClient.new('log-level.app' => :INFO))
|
58
|
+
assert_equal ::Logger::INFO,
|
59
|
+
@logger.level_of('app.models.user')
|
60
60
|
|
61
|
-
@logger.set_config_client(MockConfigClient.new(
|
62
|
-
assert_equal Logger::DEBUG,
|
63
|
-
@logger.level_of(
|
61
|
+
@logger.set_config_client(MockConfigClient.new('log-level.app' => :DEBUG))
|
62
|
+
assert_equal ::Logger::DEBUG,
|
63
|
+
@logger.level_of('app.models.user')
|
64
64
|
|
65
|
-
@logger.set_config_client(MockConfigClient.new(
|
66
|
-
|
67
|
-
assert_equal Logger::ERROR,
|
68
|
-
@logger.level_of(
|
65
|
+
@logger.set_config_client(MockConfigClient.new('log-level.app' => :DEBUG,
|
66
|
+
'log-level.app.models' => :ERROR))
|
67
|
+
assert_equal ::Logger::ERROR,
|
68
|
+
@logger.level_of('app.models.user'), 'test leveling'
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
72
72
|
def test_log_internal
|
73
73
|
logger, mock_logdev = mock_logger_expecting(/W, \[.*\] WARN -- cloud.prefab.client.test.path: : test message/)
|
74
|
-
logger.log_internal(
|
74
|
+
logger.log_internal('test message', 'test.path', '', ::Logger::WARN)
|
75
75
|
mock_logdev.verify
|
76
76
|
end
|
77
77
|
|
78
78
|
def test_log_internal_unknown
|
79
79
|
logger, mock_logdev = mock_logger_expecting(/A, \[.*\] ANY -- cloud.prefab.client.test.path: : test message/)
|
80
|
-
logger.log_internal(
|
80
|
+
logger.log_internal('test message', 'test.path', '', ::Logger::UNKNOWN)
|
81
81
|
mock_logdev.verify
|
82
82
|
end
|
83
83
|
|
84
84
|
def test_log_internal_silencing
|
85
|
-
logger, mock_logdev = mock_logger_expecting(/W, \[.*\] WARN -- cloud.prefab.client.test.path: : should log/,
|
85
|
+
logger, mock_logdev = mock_logger_expecting(/W, \[.*\] WARN -- cloud.prefab.client.test.path: : should log/,
|
86
|
+
calls: 2)
|
86
87
|
logger.silence do
|
87
|
-
logger.log_internal(
|
88
|
+
logger.log_internal('should not log', 'test.path', '', ::Logger::WARN)
|
88
89
|
end
|
89
|
-
logger.log_internal(
|
90
|
+
logger.log_internal('should log', 'test.path', '', ::Logger::WARN)
|
90
91
|
mock_logdev.verify
|
91
92
|
end
|
92
93
|
|
93
94
|
def test_log
|
94
95
|
logger, mock_logdev = mock_logger_expecting(/W, \[.*\] WARN -- test.path: : test message/)
|
95
|
-
logger.log(
|
96
|
+
logger.log('test message', 'test.path', '', ::Logger::WARN)
|
96
97
|
mock_logdev.verify
|
97
98
|
end
|
98
99
|
|
99
100
|
def test_log_unknown
|
100
101
|
logger, mock_logdev = mock_logger_expecting(/A, \[.*\] ANY -- test.path: : test message/)
|
101
|
-
logger.log(
|
102
|
+
logger.log('test message', 'test.path', '', ::Logger::UNKNOWN)
|
102
103
|
mock_logdev.verify
|
103
104
|
end
|
104
105
|
|
105
106
|
def test_log_silencing
|
106
107
|
logger, mock_logdev = mock_logger_expecting(/W, \[.*\] WARN -- test.path: : should log/, calls: 2)
|
107
108
|
logger.silence do
|
108
|
-
logger.log(
|
109
|
+
logger.log('should not log', 'test.path', '', ::Logger::WARN)
|
109
110
|
end
|
110
|
-
logger.log(
|
111
|
+
logger.log('should log', 'test.path', '', ::Logger::WARN)
|
111
112
|
mock_logdev.verify
|
112
113
|
end
|
113
114
|
|
@@ -125,11 +126,11 @@ class TestCLogger < Minitest::Test
|
|
125
126
|
|
126
127
|
def test_logging_without_a_progname
|
127
128
|
prefab, io = captured_logger
|
128
|
-
message =
|
129
|
+
message = 'MY MESSAGE'
|
129
130
|
|
130
131
|
prefab.log.error message
|
131
132
|
|
132
|
-
assert_logged io, 'ERROR',
|
133
|
+
assert_logged io, 'ERROR', 'test.test_logger.test_logging_without_a_progname', message
|
133
134
|
end
|
134
135
|
|
135
136
|
def test_logging_without_a_progname_or_message
|
@@ -137,35 +138,35 @@ class TestCLogger < Minitest::Test
|
|
137
138
|
|
138
139
|
prefab.log.error
|
139
140
|
|
140
|
-
assert_logged io, 'ERROR',
|
141
|
+
assert_logged io, 'ERROR', 'test.test_logger.test_logging_without_a_progname_or_message', ''
|
141
142
|
end
|
142
143
|
|
143
144
|
def test_logging_with_a_progname
|
144
145
|
prefab, io = captured_logger
|
145
|
-
message =
|
146
|
+
message = 'MY MESSAGE'
|
146
147
|
|
147
|
-
prefab.log.progname =
|
148
|
+
prefab.log.progname = 'MY_PROGNAME'
|
148
149
|
prefab.log.error message
|
149
150
|
|
150
|
-
assert_logged io, 'ERROR',
|
151
|
+
assert_logged io, 'ERROR', 'MY_PROGNAME test.test_logger.test_logging_with_a_progname', message
|
151
152
|
end
|
152
153
|
|
153
154
|
def test_logging_with_a_progname_and_no_message
|
154
155
|
prefab, io = captured_logger
|
155
156
|
|
156
|
-
prefab.log.progname =
|
157
|
+
prefab.log.progname = 'MY_PROGNAME'
|
157
158
|
prefab.log.error
|
158
159
|
|
159
|
-
assert_logged io, 'ERROR',
|
160
|
+
assert_logged io, 'ERROR', 'MY_PROGNAME test.test_logger.test_logging_with_a_progname_and_no_message', 'MY_PROGNAME'
|
160
161
|
end
|
161
162
|
|
162
163
|
private
|
163
164
|
|
164
165
|
def assert_logged(logged_io, level, path, message)
|
165
|
-
assert_match(/#{level} \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} [
|
166
|
+
assert_match(/#{level} \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} [-+]?\d+: #{path}: #{message}\n/, logged_io.string)
|
166
167
|
end
|
167
168
|
|
168
|
-
def mock_logger_expecting
|
169
|
+
def mock_logger_expecting(pattern, configs = {}, calls: 1)
|
169
170
|
mock_logdev = Minitest::Mock.new
|
170
171
|
mock_logdev.expect :write, nil do |arg|
|
171
172
|
pattern.match(arg)
|
@@ -189,6 +190,6 @@ class TestCLogger < Minitest::Test
|
|
189
190
|
))
|
190
191
|
prefab = Prefab::Client.new(options)
|
191
192
|
|
192
|
-
|
193
|
+
[prefab, io]
|
193
194
|
end
|
194
195
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
class TestOptions < Minitest::Test
|
6
|
+
API_KEY = 'abcdefg'
|
7
|
+
|
8
|
+
def test_works_with_named_arguments
|
9
|
+
assert_equal API_KEY, Prefab::Options.new(api_key: API_KEY).api_key
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_works_with_hash
|
13
|
+
assert_equal API_KEY, Prefab::Options.new({ api_key: API_KEY }).api_key
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_collect_max_paths
|
17
|
+
assert_equal 1000, Prefab::Options.new.collect_max_paths
|
18
|
+
assert_equal 100, Prefab::Options.new(collect_max_paths: 100).collect_max_paths
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_collect_max_paths_with_local_only
|
22
|
+
options = Prefab::Options.new(collect_max_paths: 100,
|
23
|
+
prefab_datasources: Prefab::Options::DATASOURCES::LOCAL_ONLY)
|
24
|
+
assert_equal 0, options.collect_max_paths
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_collect_max_paths_with_collect_logs_false
|
28
|
+
options = Prefab::Options.new(collect_max_paths: 100,
|
29
|
+
collect_logs: false)
|
30
|
+
assert_equal 0, options.collect_max_paths
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
class TestWeightedValueResolver < Minitest::Test
|
6
|
+
KEY = 'config_key'
|
7
|
+
|
8
|
+
def test_resolving_single_value
|
9
|
+
values = weighted_values([['abc', 1]])
|
10
|
+
resolver = Prefab::WeightedValueResolver.new(values, KEY, nil)
|
11
|
+
assert_equal 'abc', resolver.resolve.value.string
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_resolving_multiple_values_evenly_distributed
|
15
|
+
values = weighted_values([['abc', 1], ['def', 1]])
|
16
|
+
|
17
|
+
resolver = Prefab::WeightedValueResolver.new(values, KEY, 'user:001')
|
18
|
+
assert_equal 'abc', resolver.resolve.value.string
|
19
|
+
|
20
|
+
resolver = Prefab::WeightedValueResolver.new(values, KEY, 'user:456')
|
21
|
+
assert_equal 'def', resolver.resolve.value.string
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_resolving_multiple_values_unevenly_distributed
|
25
|
+
values = weighted_values([['abc', 1], ['def', 98], ['ghi', 1]])
|
26
|
+
|
27
|
+
resolver = Prefab::WeightedValueResolver.new(values, KEY, 'user:456')
|
28
|
+
assert_equal 'def', resolver.resolve.value.string
|
29
|
+
|
30
|
+
resolver = Prefab::WeightedValueResolver.new(values, KEY, 'user:103')
|
31
|
+
assert_equal 'ghi', resolver.resolve.value.string
|
32
|
+
|
33
|
+
resolver = Prefab::WeightedValueResolver.new(values, KEY, 'user:119')
|
34
|
+
assert_equal 'abc', resolver.resolve.value.string
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_resolving_multiple_values_with_simulation
|
38
|
+
values = weighted_values([['abc', 1], ['def', 98], ['ghi', 1]])
|
39
|
+
results = {}
|
40
|
+
|
41
|
+
10_000.times do |i|
|
42
|
+
result = Prefab::WeightedValueResolver.new(values, KEY, "user:#{i}").resolve.value.string
|
43
|
+
results[result] ||= 0
|
44
|
+
results[result] += 1
|
45
|
+
end
|
46
|
+
|
47
|
+
assert_in_delta 100, results['abc'], 20
|
48
|
+
assert_in_delta 9800, results['def'], 50
|
49
|
+
assert_in_delta 100, results['ghi'], 20
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def weighted_values(values_and_weights)
|
55
|
+
values_and_weights.map do |value, weight|
|
56
|
+
weighted_value(value, weight)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def weighted_value(string, weight)
|
61
|
+
Prefab::WeightedValue.new(
|
62
|
+
value: Prefab::ConfigValue.new(string: string), weight: weight
|
63
|
+
)
|
64
|
+
end
|
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.
|
4
|
+
version: 0.22.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:
|
11
|
+
date: 2023-03-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -45,7 +45,7 @@ dependencies:
|
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: '0'
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
|
-
name:
|
48
|
+
name: googleapis-common-protos-types
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
50
50
|
requirements:
|
51
51
|
- - ">="
|
@@ -59,7 +59,7 @@ dependencies:
|
|
59
59
|
- !ruby/object:Gem::Version
|
60
60
|
version: '0'
|
61
61
|
- !ruby/object:Gem::Dependency
|
62
|
-
name:
|
62
|
+
name: google-protobuf
|
63
63
|
requirement: !ruby/object:Gem::Requirement
|
64
64
|
requirements:
|
65
65
|
- - ">="
|
@@ -73,7 +73,7 @@ dependencies:
|
|
73
73
|
- !ruby/object:Gem::Version
|
74
74
|
version: '0'
|
75
75
|
- !ruby/object:Gem::Dependency
|
76
|
-
name:
|
76
|
+
name: grpc
|
77
77
|
requirement: !ruby/object:Gem::Requirement
|
78
78
|
requirements:
|
79
79
|
- - ">="
|
@@ -87,7 +87,7 @@ dependencies:
|
|
87
87
|
- !ruby/object:Gem::Version
|
88
88
|
version: '0'
|
89
89
|
- !ruby/object:Gem::Dependency
|
90
|
-
name:
|
90
|
+
name: ld-eventsource
|
91
91
|
requirement: !ruby/object:Gem::Requirement
|
92
92
|
requirements:
|
93
93
|
- - ">="
|
@@ -101,13 +101,13 @@ dependencies:
|
|
101
101
|
- !ruby/object:Gem::Version
|
102
102
|
version: '0'
|
103
103
|
- !ruby/object:Gem::Dependency
|
104
|
-
name:
|
104
|
+
name: uuid
|
105
105
|
requirement: !ruby/object:Gem::Requirement
|
106
106
|
requirements:
|
107
107
|
- - ">="
|
108
108
|
- !ruby/object:Gem::Version
|
109
109
|
version: '0'
|
110
|
-
type: :
|
110
|
+
type: :runtime
|
111
111
|
prerelease: false
|
112
112
|
version_requirements: !ruby/object:Gem::Requirement
|
113
113
|
requirements:
|
@@ -115,7 +115,7 @@ dependencies:
|
|
115
115
|
- !ruby/object:Gem::Version
|
116
116
|
version: '0'
|
117
117
|
- !ruby/object:Gem::Dependency
|
118
|
-
name:
|
118
|
+
name: benchmark-ips
|
119
119
|
requirement: !ruby/object:Gem::Requirement
|
120
120
|
requirements:
|
121
121
|
- - ">="
|
@@ -129,7 +129,7 @@ dependencies:
|
|
129
129
|
- !ruby/object:Gem::Version
|
130
130
|
version: '0'
|
131
131
|
- !ruby/object:Gem::Dependency
|
132
|
-
name:
|
132
|
+
name: bundler
|
133
133
|
requirement: !ruby/object:Gem::Requirement
|
134
134
|
requirements:
|
135
135
|
- - ">="
|
@@ -143,7 +143,7 @@ dependencies:
|
|
143
143
|
- !ruby/object:Gem::Version
|
144
144
|
version: '0'
|
145
145
|
- !ruby/object:Gem::Dependency
|
146
|
-
name:
|
146
|
+
name: grpc-tools
|
147
147
|
requirement: !ruby/object:Gem::Requirement
|
148
148
|
requirements:
|
149
149
|
- - ">="
|
@@ -171,7 +171,7 @@ dependencies:
|
|
171
171
|
- !ruby/object:Gem::Version
|
172
172
|
version: 2.4.9
|
173
173
|
- !ruby/object:Gem::Dependency
|
174
|
-
name:
|
174
|
+
name: rdoc
|
175
175
|
requirement: !ruby/object:Gem::Requirement
|
176
176
|
requirements:
|
177
177
|
- - ">="
|
@@ -185,7 +185,7 @@ dependencies:
|
|
185
185
|
- !ruby/object:Gem::Version
|
186
186
|
version: '0'
|
187
187
|
- !ruby/object:Gem::Dependency
|
188
|
-
name:
|
188
|
+
name: simplecov
|
189
189
|
requirement: !ruby/object:Gem::Requirement
|
190
190
|
requirements:
|
191
191
|
- - ">="
|
@@ -207,7 +207,9 @@ extra_rdoc_files:
|
|
207
207
|
- README.md
|
208
208
|
files:
|
209
209
|
- ".envrc"
|
210
|
+
- ".envrc.sample"
|
210
211
|
- ".github/workflows/ruby.yml"
|
212
|
+
- ".gitmodules"
|
211
213
|
- ".tool-versions"
|
212
214
|
- CODEOWNERS
|
213
215
|
- Gemfile
|
@@ -222,15 +224,18 @@ files:
|
|
222
224
|
- lib/prefab/cancellable_interceptor.rb
|
223
225
|
- lib/prefab/client.rb
|
224
226
|
- lib/prefab/config_client.rb
|
225
|
-
- lib/prefab/config_helper.rb
|
226
227
|
- lib/prefab/config_loader.rb
|
227
228
|
- lib/prefab/config_resolver.rb
|
229
|
+
- lib/prefab/config_value_unwrapper.rb
|
230
|
+
- lib/prefab/criteria_evaluator.rb
|
228
231
|
- lib/prefab/error.rb
|
229
232
|
- lib/prefab/errors/initialization_timeout_error.rb
|
230
233
|
- lib/prefab/errors/invalid_api_key_error.rb
|
231
234
|
- lib/prefab/errors/missing_default_error.rb
|
232
235
|
- lib/prefab/feature_flag_client.rb
|
233
236
|
- lib/prefab/internal_logger.rb
|
237
|
+
- lib/prefab/local_config_parser.rb
|
238
|
+
- lib/prefab/log_path_collector.rb
|
234
239
|
- lib/prefab/logger_client.rb
|
235
240
|
- lib/prefab/murmer3.rb
|
236
241
|
- lib/prefab/noop_cache.rb
|
@@ -238,20 +243,29 @@ files:
|
|
238
243
|
- lib/prefab/options.rb
|
239
244
|
- lib/prefab/ratelimit_client.rb
|
240
245
|
- lib/prefab/sse_logger.rb
|
246
|
+
- lib/prefab/weighted_value_resolver.rb
|
247
|
+
- lib/prefab/yaml_config_parser.rb
|
241
248
|
- lib/prefab_pb.rb
|
242
249
|
- lib/prefab_services_pb.rb
|
243
250
|
- prefab-cloud-ruby.gemspec
|
244
|
-
- run_test_harness_server.sh
|
245
251
|
- test/.prefab.default.config.yaml
|
246
252
|
- test/.prefab.unit_tests.config.yaml
|
247
|
-
- test/
|
253
|
+
- test/integration_test.rb
|
254
|
+
- test/integration_test_helpers.rb
|
248
255
|
- test/test_client.rb
|
249
256
|
- test/test_config_client.rb
|
250
257
|
- test/test_config_loader.rb
|
251
258
|
- test/test_config_resolver.rb
|
259
|
+
- test/test_config_value_unwrapper.rb
|
260
|
+
- test/test_criteria_evaluator.rb
|
252
261
|
- test/test_feature_flag_client.rb
|
253
262
|
- test/test_helper.rb
|
263
|
+
- test/test_integration.rb
|
264
|
+
- test/test_local_config_parser.rb
|
265
|
+
- test/test_log_path_collector.rb
|
254
266
|
- test/test_logger.rb
|
267
|
+
- test/test_options.rb
|
268
|
+
- test/test_weighted_value_resolver.rb
|
255
269
|
homepage: http://github.com/prefab-cloud/prefab-cloud-ruby
|
256
270
|
licenses:
|
257
271
|
- MIT
|
data/lib/prefab/config_helper.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module Prefab
|
3
|
-
module ConfigHelper
|
4
|
-
def value_of(config_value)
|
5
|
-
case config_value.type
|
6
|
-
when :string
|
7
|
-
config_value.string
|
8
|
-
when :int
|
9
|
-
config_value.int
|
10
|
-
when :double
|
11
|
-
config_value.double
|
12
|
-
when :bool
|
13
|
-
config_value.bool
|
14
|
-
when :feature_flag
|
15
|
-
config_value.feature_flag
|
16
|
-
when :segment
|
17
|
-
config_value.segment
|
18
|
-
when :log_level
|
19
|
-
config_value.log_level
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def value_of_variant(feature_flag_variant)
|
24
|
-
return feature_flag_variant.string if feature_flag_variant.has_string?
|
25
|
-
return feature_flag_variant.int if feature_flag_variant.has_int?
|
26
|
-
return feature_flag_variant.double if feature_flag_variant.has_double?
|
27
|
-
return feature_flag_variant.bool if feature_flag_variant.has_bool?
|
28
|
-
return nil
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
data/run_test_harness_server.sh
DELETED
@@ -1,8 +0,0 @@
|
|
1
|
-
#! /usr/bin/env bash
|
2
|
-
|
3
|
-
PREFAB_CDN_URL="https://api-prefab-cloud.global.ssl.fastly.net" \
|
4
|
-
PREFAB_LOG_CLIENT_BOOTSTRAP_LOG_LEVEL=debug \
|
5
|
-
PREFAB_CLOUD_HTTP=true \
|
6
|
-
PREFAB_API_KEY="1|local_development_api_key" \
|
7
|
-
PREFAB_GRPC_URL="localhost:50051" \
|
8
|
-
ruby -Ilib test/harness_server.rb
|
data/test/harness_server.rb
DELETED
@@ -1,64 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require 'prefab-cloud-ruby'
|
3
|
-
require 'rack'
|
4
|
-
require 'base64'
|
5
|
-
require 'json'
|
6
|
-
|
7
|
-
handler = Rack::Handler::Thin
|
8
|
-
|
9
|
-
#
|
10
|
-
# This is a very lightweight server that allows the compliance harness to excercise the prefab client
|
11
|
-
#
|
12
|
-
class RackApp
|
13
|
-
def call(env)
|
14
|
-
props = CGI::parse(env["QUERY_STRING"])
|
15
|
-
props = JSON.parse(Base64.decode64(props["props"][0]))
|
16
|
-
|
17
|
-
key = props["key"]
|
18
|
-
namespace = props["namespace"]
|
19
|
-
api_key = props["api_key"]
|
20
|
-
user_key = props["user_key"]
|
21
|
-
is_feature_flag = !props["feature_flag"].nil?
|
22
|
-
attributes = props["attributes"]
|
23
|
-
puts props
|
24
|
-
|
25
|
-
options = Prefab::Options.new(
|
26
|
-
api_key: api_key,
|
27
|
-
namespace: namespace,
|
28
|
-
initialization_timeout_sec: 1,
|
29
|
-
# We want to `return` rather than raise so we'll use the initial payload if we can't connect to the SSE server
|
30
|
-
on_init_failure: Prefab::Options::ON_INITIALIZATION_FAILURE::RETURN,
|
31
|
-
# Want to return `nil` rather than raise so we can verify empty values
|
32
|
-
on_no_default: Prefab::Options::ON_NO_DEFAULT::RETURN_NIL
|
33
|
-
)
|
34
|
-
|
35
|
-
client = Prefab::Client.new(options)
|
36
|
-
|
37
|
-
puts "Key #{key}"
|
38
|
-
puts "User #{user_key}"
|
39
|
-
puts "api_key #{api_key}"
|
40
|
-
puts "Namespace #{namespace}"
|
41
|
-
puts "Props! #{props}"
|
42
|
-
puts "is_feature_flag! #{is_feature_flag}"
|
43
|
-
|
44
|
-
puts client.config_client.to_s
|
45
|
-
|
46
|
-
if is_feature_flag
|
47
|
-
puts "EVALFF #{key} #{user_key}"
|
48
|
-
rtn = client.feature_flag_client.get(key, user_key, attributes).to_s
|
49
|
-
else
|
50
|
-
rtn = client.config_client.get(key).to_s
|
51
|
-
end
|
52
|
-
|
53
|
-
puts "return #{rtn}"
|
54
|
-
|
55
|
-
[200, { "Content-Type" => "text/plain" }, rtn]
|
56
|
-
|
57
|
-
rescue Exception => e
|
58
|
-
puts "ERROR #{e.message}"
|
59
|
-
puts e.backtrace
|
60
|
-
[500, { "Content-Type" => "text/plain" }, e.message]
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
handler.run RackApp.new
|