prefab-cloud-ruby 0.20.0 → 0.22.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.envrc.sample +3 -0
  3. data/.github/workflows/ruby.yml +5 -1
  4. data/.gitmodules +3 -0
  5. data/Gemfile +14 -12
  6. data/Gemfile.lock +24 -14
  7. data/README.md +12 -10
  8. data/Rakefile +13 -14
  9. data/VERSION +1 -1
  10. data/lib/prefab/auth_interceptor.rb +2 -1
  11. data/lib/prefab/cancellable_interceptor.rb +8 -7
  12. data/lib/prefab/client.rb +52 -27
  13. data/lib/prefab/config_client.rb +59 -70
  14. data/lib/prefab/config_loader.rb +7 -114
  15. data/lib/prefab/config_resolver.rb +27 -57
  16. data/lib/prefab/config_value_unwrapper.rb +23 -0
  17. data/lib/prefab/criteria_evaluator.rb +96 -0
  18. data/lib/prefab/errors/invalid_api_key_error.rb +1 -1
  19. data/lib/prefab/feature_flag_client.rb +13 -145
  20. data/lib/prefab/internal_logger.rb +7 -6
  21. data/lib/prefab/local_config_parser.rb +110 -0
  22. data/lib/prefab/log_path_collector.rb +98 -0
  23. data/lib/prefab/logger_client.rb +46 -44
  24. data/lib/prefab/murmer3.rb +3 -4
  25. data/lib/prefab/noop_cache.rb +5 -7
  26. data/lib/prefab/noop_stats.rb +2 -3
  27. data/lib/prefab/options.rb +32 -11
  28. data/lib/prefab/ratelimit_client.rb +11 -13
  29. data/lib/prefab/sse_logger.rb +3 -2
  30. data/lib/prefab/weighted_value_resolver.rb +42 -0
  31. data/lib/prefab/yaml_config_parser.rb +32 -0
  32. data/lib/prefab-cloud-ruby.rb +7 -2
  33. data/lib/prefab_pb.rb +70 -43
  34. data/lib/prefab_services_pb.rb +14 -1
  35. data/prefab-cloud-ruby.gemspec +33 -19
  36. data/test/.prefab.unit_tests.config.yaml +3 -2
  37. data/test/integration_test.rb +98 -0
  38. data/test/integration_test_helpers.rb +37 -0
  39. data/test/test_client.rb +56 -31
  40. data/test/test_config_client.rb +21 -20
  41. data/test/test_config_loader.rb +48 -37
  42. data/test/test_config_resolver.rb +312 -135
  43. data/test/test_config_value_unwrapper.rb +83 -0
  44. data/test/test_criteria_evaluator.rb +533 -0
  45. data/test/test_feature_flag_client.rb +35 -347
  46. data/test/test_helper.rb +18 -14
  47. data/test/test_integration.rb +33 -0
  48. data/test/test_local_config_parser.rb +78 -0
  49. data/test/test_log_path_collector.rb +56 -0
  50. data/test/test_logger.rb +52 -51
  51. data/test/test_options.rb +32 -0
  52. data/test/test_weighted_value_resolver.rb +65 -0
  53. metadata +30 -16
  54. data/lib/prefab/config_helper.rb +0 -31
  55. data/run_test_harness_server.sh +0 -8
  56. 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 "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",
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
- "info")
24
- assert_equal "unknown.info",
23
+ 'info')
24
+ assert_equal 'unknown.info',
25
25
  @logger.get_path(nil,
26
- "info")
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 "active_support.log_subscriber.info",
37
+ assert_equal 'active_support.log_subscriber.info',
38
38
  @logger.get_loc_path(backtrace_location.new(nil,
39
- "info",
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 "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",
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("PREFAB_LOG_CLIENT_BOOTSTRAP_LOG_LEVEL", "info") do
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("app.models.user"), "PREFAB_LOG_CLIENT_BOOTSTRAP_LOG_LEVEL is info"
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("app.models.user"), "default is warn"
54
+ assert_equal ::Logger::WARN,
55
+ @logger.level_of('app.models.user'), 'default is warn'
56
56
 
57
- @logger.set_config_client(MockConfigClient.new("log-level.app" => :INFO))
58
- assert_equal Logger::INFO,
59
- @logger.level_of("app.models.user")
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("log-level.app" => :DEBUG))
62
- assert_equal Logger::DEBUG,
63
- @logger.level_of("app.models.user")
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("log-level.app" => :DEBUG,
66
- "log-level.app.models" => :ERROR))
67
- assert_equal Logger::ERROR,
68
- @logger.level_of("app.models.user"), "test leveling"
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("test message", "test.path", "", Logger::WARN)
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("test message", "test.path", "", Logger::UNKNOWN)
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/, calls: 2)
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("should not log", "test.path", "", Logger::WARN)
88
+ logger.log_internal('should not log', 'test.path', '', ::Logger::WARN)
88
89
  end
89
- logger.log_internal("should log", "test.path", "", Logger::WARN)
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("test message", "test.path", "", Logger::WARN)
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("test message", "test.path", "", Logger::UNKNOWN)
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("should not log", "test.path", "", Logger::WARN)
109
+ logger.log('should not log', 'test.path', '', ::Logger::WARN)
109
110
  end
110
- logger.log("should log", "test.path", "", Logger::WARN)
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 = "MY MESSAGE"
129
+ message = 'MY MESSAGE'
129
130
 
130
131
  prefab.log.error message
131
132
 
132
- assert_logged io, 'ERROR', "test.test_logger.test_logging_without_a_progname", message
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', "test.test_logger.test_logging_without_a_progname_or_message", ""
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 = "MY MESSAGE"
146
+ message = 'MY MESSAGE'
146
147
 
147
- prefab.log.progname = "MY_PROGNAME"
148
+ prefab.log.progname = 'MY_PROGNAME'
148
149
  prefab.log.error message
149
150
 
150
- assert_logged io, 'ERROR', "MY_PROGNAME test.test_logger.test_logging_with_a_progname", message
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 = "MY_PROGNAME"
157
+ prefab.log.progname = 'MY_PROGNAME'
157
158
  prefab.log.error
158
159
 
159
- assert_logged io, 'ERROR', "MY_PROGNAME test.test_logger.test_logging_with_a_progname_and_no_message", "MY_PROGNAME"
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} [-\+]?\d+: #{path}: #{message}\n/, logged_io.string)
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 pattern, configs = {}, calls: 1
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
- return [prefab, io]
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.20.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: 2022-12-02 00:00:00.000000000 Z
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: ld-eventsource
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: grpc
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: google-protobuf
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: googleapis-common-protos-types
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: benchmark-ips
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: :development
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: grpc-tools
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: rdoc
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: bundler
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: simplecov
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: thin
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/harness_server.rb
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
@@ -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
@@ -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
@@ -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