prefab-cloud-ruby 0.11.0 → 0.12.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/Gemfile.lock +5 -5
- data/README.md +9 -0
- data/VERSION +1 -1
- data/lib/prefab/client.rb +29 -37
- data/lib/prefab/config_client.rb +107 -85
- data/lib/prefab/config_helper.rb +8 -0
- data/lib/prefab/config_loader.rb +30 -9
- data/lib/prefab/config_resolver.rb +22 -18
- data/lib/prefab/feature_flag_client.rb +23 -26
- data/lib/prefab/internal_logger.rb +28 -0
- data/lib/prefab/logger_client.rb +1 -1
- data/lib/prefab/options.rb +81 -0
- data/lib/prefab/prefab.rb +32 -0
- data/lib/prefab-cloud-ruby.rb +2 -0
- data/lib/prefab_pb.rb +21 -17
- data/lib/prefab_services_pb.rb +14 -0
- data/prefab-cloud-ruby.gemspec +7 -3
- data/test/.prefab.test.config.yaml +5 -1
- data/test/harness_server.rb +2 -1
- data/test/test_config_client.rb +19 -0
- data/test/test_config_loader.rb +32 -18
- data/test/test_config_resolver.rb +34 -28
- data/test/test_feature_flag_client.rb +37 -44
- data/test/test_helper.rb +4 -4
- metadata +6 -2
@@ -30,7 +30,7 @@ module Prefab
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def evaluate(feature_name, lookup_key, attributes, feature_obj, variants)
|
33
|
-
|
33
|
+
value_of_variant(get_variant(feature_name, lookup_key, attributes, feature_obj, variants))
|
34
34
|
end
|
35
35
|
|
36
36
|
private
|
@@ -50,19 +50,12 @@ module Prefab
|
|
50
50
|
return get_variant_obj(variants, feature_obj.inactive_variant_idx)
|
51
51
|
end
|
52
52
|
|
53
|
-
# if user_targets.match
|
54
|
-
feature_obj.user_targets.each do |target|
|
55
|
-
if (target.identifiers.include? lookup_key)
|
56
|
-
return get_variant_obj(variants, target.variant_idx)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
53
|
#default to inactive
|
61
54
|
variant_weights = [Prefab::VariantWeight.new(variant_idx: feature_obj.inactive_variant_idx, weight: 1)]
|
62
55
|
|
63
56
|
# if rules.match
|
64
57
|
feature_obj.rules.each do |rule|
|
65
|
-
if criteria_match?(rule, lookup_key, attributes)
|
58
|
+
if criteria_match?(rule.criteria, lookup_key, attributes)
|
66
59
|
variant_weights = rule.variant_weights
|
67
60
|
break
|
68
61
|
end
|
@@ -107,22 +100,25 @@ module Prefab
|
|
107
100
|
int_value / MAX_32_FLOAT
|
108
101
|
end
|
109
102
|
|
110
|
-
def criteria_match?(rule, lookup_key, attributes)
|
103
|
+
# def criteria_match?(rule, lookup_key, attributes)
|
104
|
+
#
|
105
|
+
# end
|
106
|
+
def criteria_match?(criteria, lookup_key, attributes)
|
111
107
|
|
112
|
-
if
|
108
|
+
if criteria.operator == :ALWAYS_TRUE
|
113
109
|
return true
|
114
|
-
elsif
|
115
|
-
return
|
116
|
-
elsif
|
117
|
-
return !
|
118
|
-
elsif
|
119
|
-
return segment_matches(
|
120
|
-
elsif
|
121
|
-
return segment_matches(
|
122
|
-
elsif
|
123
|
-
return
|
124
|
-
elsif
|
125
|
-
return !(
|
110
|
+
elsif criteria.operator == :LOOKUP_KEY_IN
|
111
|
+
return criteria.values.include?(lookup_key)
|
112
|
+
elsif criteria.operator == :LOOKUP_KEY_NOT_IN
|
113
|
+
return !criteria.values.include?(lookup_key)
|
114
|
+
elsif criteria.operator == :IN_SEG
|
115
|
+
return segment_matches(criteria.values, lookup_key, attributes).any?
|
116
|
+
elsif criteria.operator == :NOT_IN_SEG
|
117
|
+
return segment_matches(criteria.values, lookup_key, attributes).none?
|
118
|
+
elsif criteria.operator == :PROP_IS_ONE_OF
|
119
|
+
return criteria.values.include?(attributes[criteria.property]) || criteria.values.include?(attributes[criteria.property.to_sym])
|
120
|
+
elsif criteria.operator == :PROP_IS_NOT_ONE_OF
|
121
|
+
return !(criteria.values.include?(attributes[criteria.property]) || criteria.values.include?(attributes[criteria.property.to_sym]))
|
126
122
|
end
|
127
123
|
@base_client.log.info("Unknown Operator")
|
128
124
|
false
|
@@ -142,10 +138,11 @@ module Prefab
|
|
142
138
|
end
|
143
139
|
end
|
144
140
|
|
141
|
+
# does a given segment match?
|
145
142
|
def segment_match?(segment, lookup_key, attributes)
|
146
|
-
|
147
|
-
|
148
|
-
|
143
|
+
segment.criterion.map do |criteria|
|
144
|
+
criteria_match?(criteria, lookup_key, attributes)
|
145
|
+
end.any?
|
149
146
|
end
|
150
147
|
end
|
151
148
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Prefab
|
2
|
+
class InternalLogger < Logger
|
3
|
+
def initialize(path, logger)
|
4
|
+
@path = path
|
5
|
+
@logger = logger
|
6
|
+
end
|
7
|
+
|
8
|
+
def debug(progname = nil, &block)
|
9
|
+
@logger.log_internal yield, @path, progname, DEBUG
|
10
|
+
end
|
11
|
+
|
12
|
+
def info(progname = nil, &block)
|
13
|
+
@logger.log_internal yield, @path, progname, INFO
|
14
|
+
end
|
15
|
+
|
16
|
+
def warn(progname = nil, &block)
|
17
|
+
@logger.log_internal yield, @path, progname, WARN
|
18
|
+
end
|
19
|
+
|
20
|
+
def error(progname = nil, &block)
|
21
|
+
@logger.log_internal yield, @path, progname, ERROR
|
22
|
+
end
|
23
|
+
|
24
|
+
def fatal(progname = nil, &block)
|
25
|
+
@logger.log_internal yield, @path, progname, FATAL
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/prefab/logger_client.rb
CHANGED
@@ -122,7 +122,7 @@ module Prefab
|
|
122
122
|
# sanitize & clean the path of the caller so the key
|
123
123
|
# looks like log_level.app.models.user
|
124
124
|
def get_path(absolute_path, base_label)
|
125
|
-
path = absolute_path + ""
|
125
|
+
path = (absolute_path || "unknown") + ""
|
126
126
|
path.slice! Dir.pwd
|
127
127
|
|
128
128
|
path.gsub!(/.*?(?=\/lib\/)/im, "")
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module Prefab
|
2
|
+
class Options
|
3
|
+
attr_reader :api_key
|
4
|
+
attr_reader :logdev
|
5
|
+
attr_reader :log_formatter
|
6
|
+
attr_reader :stats
|
7
|
+
attr_reader :shared_cache
|
8
|
+
attr_reader :namespace
|
9
|
+
attr_reader :prefab_api_url
|
10
|
+
attr_reader :prefab_grpc_url
|
11
|
+
attr_reader :on_no_default
|
12
|
+
attr_reader :initialization_timeout_sec
|
13
|
+
attr_reader :on_init_failure
|
14
|
+
attr_reader :prefab_config_override_dir
|
15
|
+
attr_reader :prefab_config_classpath_dir
|
16
|
+
attr_reader :defaults_env
|
17
|
+
|
18
|
+
DEFAULT_LOG_FORMATTER = proc { |severity, datetime, progname, msg|
|
19
|
+
"#{severity.ljust(5)} #{datetime}: #{progname} #{msg}\n"
|
20
|
+
}
|
21
|
+
|
22
|
+
module ON_INITIALIZATION_FAILURE
|
23
|
+
RAISE = 1
|
24
|
+
RETURN = 2
|
25
|
+
end
|
26
|
+
module ON_NO_DEFAULT
|
27
|
+
RAISE = 1
|
28
|
+
RETURN = 2
|
29
|
+
end
|
30
|
+
module DATASOURCES
|
31
|
+
ALL = 1
|
32
|
+
LOCAL_ONLY = 2
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize(
|
36
|
+
api_key: ENV['PREFAB_API_KEY'],
|
37
|
+
logdev: $stdout,
|
38
|
+
stats: NoopStats.new, # receives increment("prefab.limitcheck", {:tags=>["policy_group:page_view", "pass:true"]})
|
39
|
+
shared_cache: NoopCache.new, # Something that quacks like Rails.cache ideally memcached
|
40
|
+
namespace: "",
|
41
|
+
log_formatter: DEFAULT_LOG_FORMATTER,
|
42
|
+
prefab_api_url: ENV["PREFAB_API_URL"] || 'https://api.prefab.cloud',
|
43
|
+
prefab_grpc_url: ENV["PREFAB_GRPC_URL"] || 'grpc.prefab.cloud:443',
|
44
|
+
on_no_default: ON_NO_DEFAULT::RAISE, # options :raise, :warn_and_return_nil,
|
45
|
+
initialization_timeout_sec: 10, # how long to wait before on_init_failure
|
46
|
+
on_init_failure: ON_INITIALIZATION_FAILURE::RAISE, #options :unlock_and_continue, :lock_and_keep_trying, :raise
|
47
|
+
# new_config_callback: nil, #callback method
|
48
|
+
# live_override_url: nil,
|
49
|
+
prefab_datasources: ENV['PREFAB_DATASOURCES'] == "LOCAL_ONLY" ? DATASOURCES::LOCAL_ONLY : DATASOURCES::ALL,
|
50
|
+
prefab_config_override_dir: Dir.home,
|
51
|
+
prefab_config_classpath_dir: ".",
|
52
|
+
defaults_env: ""
|
53
|
+
)
|
54
|
+
# debugger
|
55
|
+
@api_key = api_key
|
56
|
+
@logdev = logdev
|
57
|
+
@stats = stats
|
58
|
+
@shared_cache = shared_cache
|
59
|
+
@namespace = namespace
|
60
|
+
@log_formatter = log_formatter
|
61
|
+
@prefab_api_url = prefab_api_url
|
62
|
+
@prefab_grpc_url = prefab_grpc_url
|
63
|
+
@on_no_default = on_no_default
|
64
|
+
@initialization_timeout_sec = initialization_timeout_sec
|
65
|
+
@on_init_failure = on_init_failure
|
66
|
+
@prefab_datasources = prefab_datasources
|
67
|
+
@prefab_config_classpath_dir = prefab_config_classpath_dir
|
68
|
+
@prefab_config_override_dir = prefab_config_override_dir
|
69
|
+
@defaults_env = defaults_env
|
70
|
+
end
|
71
|
+
|
72
|
+
def local_only?
|
73
|
+
@prefab_datasources == DATASOURCES::LOCAL_ONLY
|
74
|
+
end
|
75
|
+
|
76
|
+
# https://api.prefab.cloud -> https://api-prefab-cloud.global.ssl.fastly.net
|
77
|
+
def url_for_api_cdn
|
78
|
+
ENV['PREFAB_CDN_URL'] || "#{@prefab_api_url.gsub(/\./, "-")}.global.ssl.fastly.net"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Prefab
|
2
|
+
|
3
|
+
@@singleton__mutex__ = Mutex.new
|
4
|
+
|
5
|
+
public
|
6
|
+
|
7
|
+
def self.initialize(options = nil)
|
8
|
+
@@singleton__mutex__.synchronize do
|
9
|
+
unless @singleton.nil?
|
10
|
+
puts 'Prefab Double Initialization'
|
11
|
+
return @singleton
|
12
|
+
end
|
13
|
+
@singleton = Prefab::Client.new(options)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.get(key)
|
18
|
+
require_initialization
|
19
|
+
@singleton.config_client.get(key)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def self.require_initialization
|
25
|
+
if @singleton.nil?
|
26
|
+
puts "Prefab initializing for you. You probably want to call Prefab.initialize(Prefab::Options.new())"
|
27
|
+
self.initialize
|
28
|
+
end
|
29
|
+
end
|
30
|
+
module_function initialize
|
31
|
+
module_function get
|
32
|
+
end
|
data/lib/prefab-cloud-ruby.rb
CHANGED
data/lib/prefab_pb.rb
CHANGED
@@ -75,14 +75,12 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
|
|
75
75
|
value :MAXIMUM, 2
|
76
76
|
end
|
77
77
|
add_message "prefab.FeatureFlagVariant" do
|
78
|
+
proto3_optional :int, :int64, 1
|
79
|
+
proto3_optional :string, :string, 2
|
80
|
+
proto3_optional :double, :double, 3
|
81
|
+
proto3_optional :bool, :bool, 4
|
78
82
|
optional :name, :string, 5
|
79
83
|
optional :description, :string, 6
|
80
|
-
oneof :type do
|
81
|
-
optional :int, :int64, 1
|
82
|
-
optional :string, :string, 2
|
83
|
-
optional :double, :double, 3
|
84
|
-
optional :bool, :bool, 4
|
85
|
-
end
|
86
84
|
end
|
87
85
|
add_message "prefab.Criteria" do
|
88
86
|
optional :property, :string, 1
|
@@ -106,15 +104,7 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
|
|
106
104
|
repeated :variant_weights, :message, 2, "prefab.VariantWeight"
|
107
105
|
end
|
108
106
|
add_message "prefab.Segment" do
|
109
|
-
|
110
|
-
optional :description, :string, 2
|
111
|
-
repeated :includes, :string, 3
|
112
|
-
repeated :excludes, :string, 4
|
113
|
-
repeated :criterion, :message, 5, "prefab.Criteria"
|
114
|
-
end
|
115
|
-
add_message "prefab.UserTarget" do
|
116
|
-
optional :variant_idx, :int32, 1
|
117
|
-
repeated :identifiers, :string, 2
|
107
|
+
repeated :criterion, :message, 1, "prefab.Criteria"
|
118
108
|
end
|
119
109
|
add_message "prefab.VariantWeight" do
|
120
110
|
optional :weight, :int32, 1
|
@@ -123,9 +113,21 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
|
|
123
113
|
add_message "prefab.FeatureFlag" do
|
124
114
|
optional :active, :bool, 1
|
125
115
|
optional :inactive_variant_idx, :int32, 2
|
126
|
-
repeated :user_targets, :message, 4, "prefab.UserTarget"
|
127
116
|
repeated :rules, :message, 5, "prefab.Rule"
|
128
117
|
end
|
118
|
+
add_message "prefab.Identity" do
|
119
|
+
proto3_optional :lookup, :string, 1
|
120
|
+
map :attributes, :string, :string, 2
|
121
|
+
end
|
122
|
+
add_message "prefab.ClientConfigValue" do
|
123
|
+
proto3_optional :int, :int64, 1
|
124
|
+
proto3_optional :string, :string, 2
|
125
|
+
proto3_optional :double, :double, 3
|
126
|
+
proto3_optional :bool, :bool, 4
|
127
|
+
end
|
128
|
+
add_message "prefab.ConfigEvaluations" do
|
129
|
+
map :values, :string, :message, 1, "prefab.ClientConfigValue"
|
130
|
+
end
|
129
131
|
add_message "prefab.LimitDefinition" do
|
130
132
|
optional :policy_name, :enum, 2, "prefab.LimitResponse.LimitPolicyNames"
|
131
133
|
optional :limit, :int32, 3
|
@@ -205,9 +207,11 @@ module Prefab
|
|
205
207
|
Criteria::CriteriaOperator = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.Criteria.CriteriaOperator").enummodule
|
206
208
|
Rule = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.Rule").msgclass
|
207
209
|
Segment = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.Segment").msgclass
|
208
|
-
UserTarget = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.UserTarget").msgclass
|
209
210
|
VariantWeight = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.VariantWeight").msgclass
|
210
211
|
FeatureFlag = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.FeatureFlag").msgclass
|
212
|
+
Identity = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.Identity").msgclass
|
213
|
+
ClientConfigValue = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.ClientConfigValue").msgclass
|
214
|
+
ConfigEvaluations = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.ConfigEvaluations").msgclass
|
211
215
|
LimitDefinition = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.LimitDefinition").msgclass
|
212
216
|
LimitDefinition::SafetyLevel = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.LimitDefinition.SafetyLevel").enummodule
|
213
217
|
LimitDefinitions = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.LimitDefinitions").msgclass
|
data/lib/prefab_services_pb.rb
CHANGED
@@ -47,6 +47,20 @@ module Prefab
|
|
47
47
|
rpc :GetBlock, ::Prefab::IdBlockRequest, ::Prefab::IdBlock
|
48
48
|
end
|
49
49
|
|
50
|
+
Stub = Service.rpc_stub_class
|
51
|
+
end
|
52
|
+
module ClientService
|
53
|
+
class Service
|
54
|
+
|
55
|
+
include ::GRPC::GenericService
|
56
|
+
|
57
|
+
self.marshal_class_method = :encode
|
58
|
+
self.unmarshal_class_method = :decode
|
59
|
+
self.service_name = 'prefab.ClientService'
|
60
|
+
|
61
|
+
rpc :GetAll, ::Prefab::Identity, ::Prefab::ConfigEvaluations
|
62
|
+
end
|
63
|
+
|
50
64
|
Stub = Service.rpc_stub_class
|
51
65
|
end
|
52
66
|
end
|
data/prefab-cloud-ruby.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: prefab-cloud-ruby 0.
|
5
|
+
# stub: prefab-cloud-ruby 0.12.0 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "prefab-cloud-ruby".freeze
|
9
|
-
s.version = "0.
|
9
|
+
s.version = "0.12.0"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib".freeze]
|
13
13
|
s.authors = ["Jeff Dwyer".freeze]
|
14
|
-
s.date = "2022-
|
14
|
+
s.date = "2022-07-21"
|
15
15
|
s.description = "RateLimits & Config as a service".freeze
|
16
16
|
s.email = "jdwyer@prefab.cloud".freeze
|
17
17
|
s.extra_rdoc_files = [
|
@@ -38,10 +38,13 @@ Gem::Specification.new do |s|
|
|
38
38
|
"lib/prefab/config_loader.rb",
|
39
39
|
"lib/prefab/config_resolver.rb",
|
40
40
|
"lib/prefab/feature_flag_client.rb",
|
41
|
+
"lib/prefab/internal_logger.rb",
|
41
42
|
"lib/prefab/logger_client.rb",
|
42
43
|
"lib/prefab/murmer3.rb",
|
43
44
|
"lib/prefab/noop_cache.rb",
|
44
45
|
"lib/prefab/noop_stats.rb",
|
46
|
+
"lib/prefab/options.rb",
|
47
|
+
"lib/prefab/prefab.rb",
|
45
48
|
"lib/prefab/ratelimit_client.rb",
|
46
49
|
"lib/prefab_pb.rb",
|
47
50
|
"lib/prefab_services_pb.rb",
|
@@ -49,6 +52,7 @@ Gem::Specification.new do |s|
|
|
49
52
|
"run_test_harness_server.sh",
|
50
53
|
"test/.prefab.test.config.yaml",
|
51
54
|
"test/harness_server.rb",
|
55
|
+
"test/test_config_client.rb",
|
52
56
|
"test/test_config_loader.rb",
|
53
57
|
"test/test_config_resolver.rb",
|
54
58
|
"test/test_feature_flag_client.rb",
|
data/test/harness_server.rb
CHANGED
@@ -18,6 +18,7 @@ class RackApp
|
|
18
18
|
api_key = props["api_key"]
|
19
19
|
user_key = props["user_key"]
|
20
20
|
is_feature_flag = !props["feature_flag"].nil?
|
21
|
+
attributes = props["attributes"]
|
21
22
|
puts props
|
22
23
|
client = Prefab::Client.new(
|
23
24
|
api_key: api_key,
|
@@ -35,7 +36,7 @@ class RackApp
|
|
35
36
|
|
36
37
|
if is_feature_flag
|
37
38
|
puts "EVALFF #{key} #{user_key}"
|
38
|
-
rtn = client.feature_flag_client.get(key, user_key,
|
39
|
+
rtn = client.feature_flag_client.get(key, user_key, attributes).to_s
|
39
40
|
else
|
40
41
|
rtn = client.config_client.get(key).to_s
|
41
42
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class TestConfigClient < Minitest::Test
|
4
|
+
def setup
|
5
|
+
options = Prefab::Options.new(
|
6
|
+
prefab_config_override_dir: "none",
|
7
|
+
prefab_config_classpath_dir: "test",
|
8
|
+
defaults_env: "unit_tests",
|
9
|
+
local_only: true
|
10
|
+
)
|
11
|
+
@config_client = Prefab::ConfigClient.new(MockBaseClient.new(options), 10)
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_load
|
15
|
+
assert_equal "test sample value", @config_client.get("sample")
|
16
|
+
assert_equal 123, @config_client.get("sample_int")
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
data/test/test_config_loader.rb
CHANGED
@@ -2,40 +2,54 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
class TestConfigLoader < Minitest::Test
|
4
4
|
def setup
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
options = Prefab::Options.new(
|
6
|
+
prefab_config_override_dir: "none",
|
7
|
+
prefab_config_classpath_dir: "test",
|
8
|
+
defaults_env: "unit_tests"
|
9
|
+
)
|
10
|
+
@loader = Prefab::ConfigLoader.new(MockBaseClient.new(options))
|
8
11
|
end
|
9
12
|
|
10
13
|
def test_load
|
11
14
|
should_be :int, 123, "sample_int"
|
12
|
-
should_be :string, "
|
15
|
+
should_be :string, "test sample value", "sample"
|
13
16
|
should_be :bool, true, "sample_bool"
|
14
17
|
should_be :double, 12.12, "sample_double"
|
15
18
|
end
|
16
19
|
|
20
|
+
def test_load_in_no_default_env
|
21
|
+
options = Prefab::Options.new(
|
22
|
+
prefab_config_override_dir: "none",
|
23
|
+
prefab_config_classpath_dir: "test",
|
24
|
+
# no defaults_env
|
25
|
+
)
|
26
|
+
@loader = Prefab::ConfigLoader.new(MockBaseClient.new(options))
|
27
|
+
should_be :string, "default sample value", "sample"
|
28
|
+
should_be :bool, true, "sample_bool"
|
29
|
+
end
|
30
|
+
|
17
31
|
def test_highwater
|
18
32
|
assert_equal 0, @loader.highwater_mark
|
19
|
-
@loader.set(Prefab::Config.new(id: 1, key: "sample_int", rows: [Prefab::ConfigRow.new(value: Prefab::ConfigValue.new(int: 456))]))
|
33
|
+
@loader.set(Prefab::Config.new(id: 1, key: "sample_int", rows: [Prefab::ConfigRow.new(value: Prefab::ConfigValue.new(int: 456))]),"test")
|
20
34
|
assert_equal 1, @loader.highwater_mark
|
21
35
|
|
22
|
-
@loader.set(Prefab::Config.new(id: 5, key: "sample_int", rows: [Prefab::ConfigRow.new(value: Prefab::ConfigValue.new(int: 456))]))
|
36
|
+
@loader.set(Prefab::Config.new(id: 5, key: "sample_int", rows: [Prefab::ConfigRow.new(value: Prefab::ConfigValue.new(int: 456))]),"test")
|
23
37
|
assert_equal 5, @loader.highwater_mark
|
24
|
-
@loader.set(Prefab::Config.new(id: 2, key: "sample_int", rows: [Prefab::ConfigRow.new(value: Prefab::ConfigValue.new(int: 456))]))
|
38
|
+
@loader.set(Prefab::Config.new(id: 2, key: "sample_int", rows: [Prefab::ConfigRow.new(value: Prefab::ConfigValue.new(int: 456))]),"test")
|
25
39
|
assert_equal 5, @loader.highwater_mark
|
26
40
|
end
|
27
41
|
|
28
42
|
def test_keeps_most_recent
|
29
43
|
assert_equal 0, @loader.highwater_mark
|
30
|
-
@loader.set(Prefab::Config.new(id: 1, key: "sample_int", rows: [Prefab::ConfigRow.new(value: Prefab::ConfigValue.new(int: 1))]))
|
44
|
+
@loader.set(Prefab::Config.new(id: 1, key: "sample_int", rows: [Prefab::ConfigRow.new(value: Prefab::ConfigValue.new(int: 1))]),"test")
|
31
45
|
assert_equal 1, @loader.highwater_mark
|
32
46
|
should_be :int, 1, "sample_int"
|
33
47
|
|
34
|
-
@loader.set(Prefab::Config.new(id: 4, key: "sample_int", rows: [Prefab::ConfigRow.new(value: Prefab::ConfigValue.new(int: 4))]))
|
48
|
+
@loader.set(Prefab::Config.new(id: 4, key: "sample_int", rows: [Prefab::ConfigRow.new(value: Prefab::ConfigValue.new(int: 4))]),"test")
|
35
49
|
assert_equal 4, @loader.highwater_mark
|
36
50
|
should_be :int, 4, "sample_int"
|
37
51
|
|
38
|
-
@loader.set(Prefab::Config.new(id: 2, key: "sample_int", rows: [Prefab::ConfigRow.new(value: Prefab::ConfigValue.new(int: 2))]))
|
52
|
+
@loader.set(Prefab::Config.new(id: 2, key: "sample_int", rows: [Prefab::ConfigRow.new(value: Prefab::ConfigValue.new(int: 2))]),"test")
|
39
53
|
assert_equal 4, @loader.highwater_mark
|
40
54
|
should_be :int, 4, "sample_int"
|
41
55
|
end
|
@@ -43,14 +57,14 @@ class TestConfigLoader < Minitest::Test
|
|
43
57
|
def test_api_precedence
|
44
58
|
should_be :int, 123, "sample_int"
|
45
59
|
|
46
|
-
@loader.set(Prefab::Config.new(key: "sample_int", rows: [Prefab::ConfigRow.new(value: Prefab::ConfigValue.new(int: 456))]))
|
60
|
+
@loader.set(Prefab::Config.new(key: "sample_int", rows: [Prefab::ConfigRow.new(value: Prefab::ConfigValue.new(int: 456))]), "test")
|
47
61
|
should_be :int, 456, "sample_int"
|
48
62
|
end
|
49
63
|
|
50
64
|
def test_api_deltas
|
51
65
|
val = Prefab::ConfigValue.new(int: 456)
|
52
66
|
config = Prefab::Config.new(key: "sample_int", rows: [Prefab::ConfigRow.new(value: val)])
|
53
|
-
@loader.set(config)
|
67
|
+
@loader.set(config, "test")
|
54
68
|
|
55
69
|
configs = Prefab::Configs.new
|
56
70
|
configs.configs << config
|
@@ -59,11 +73,11 @@ class TestConfigLoader < Minitest::Test
|
|
59
73
|
|
60
74
|
def test_loading_tombstones_removes_entries
|
61
75
|
val = Prefab::ConfigValue.new(int: 456)
|
62
|
-
config = Prefab::Config.new(key: "sample_int", rows: [Prefab::ConfigRow.new(value: val)])
|
63
|
-
@loader.set(config)
|
76
|
+
config = Prefab::Config.new(key: "sample_int", rows: [Prefab::ConfigRow.new(value: val)], id: 2)
|
77
|
+
@loader.set(config, "test")
|
64
78
|
|
65
|
-
config = Prefab::Config.new(key: "sample_int", rows: [])
|
66
|
-
@loader.set(config)
|
79
|
+
config = Prefab::Config.new(key: "sample_int", rows: [], id: 3)
|
80
|
+
@loader.set(config, "test")
|
67
81
|
|
68
82
|
configs = Prefab::Configs.new
|
69
83
|
assert_equal configs, @loader.get_api_deltas
|
@@ -72,8 +86,8 @@ class TestConfigLoader < Minitest::Test
|
|
72
86
|
private
|
73
87
|
|
74
88
|
def should_be(type, value, key)
|
75
|
-
assert_equal type, @loader.calc_config[key].rows[0].value.type
|
76
|
-
assert_equal value, @loader.calc_config[key].rows[0].value.send(type)
|
89
|
+
assert_equal type, @loader.calc_config[key][:config].rows[0].value.type
|
90
|
+
assert_equal value, @loader.calc_config[key][:config].rows[0].value.send(type)
|
77
91
|
end
|
78
92
|
|
79
93
|
end
|
@@ -10,7 +10,7 @@ class TestConfigResolver < Minitest::Test
|
|
10
10
|
@loader = MockConfigLoader.new
|
11
11
|
|
12
12
|
loaded_values = {
|
13
|
-
"key" => Prefab::Config.new(
|
13
|
+
"key" => { config: Prefab::Config.new(
|
14
14
|
key: "key",
|
15
15
|
rows: [
|
16
16
|
Prefab::ConfigRow.new(
|
@@ -42,13 +42,14 @@ class TestConfigResolver < Minitest::Test
|
|
42
42
|
),
|
43
43
|
|
44
44
|
]
|
45
|
-
),
|
46
|
-
"key2" => Prefab::Config.new(
|
45
|
+
) },
|
46
|
+
"key2" => { config: Prefab::Config.new(
|
47
47
|
key: "key2",
|
48
48
|
rows: [
|
49
49
|
value: Prefab::ConfigValue.new(string: "valueB2"),
|
50
50
|
]
|
51
|
-
)
|
51
|
+
) }
|
52
|
+
|
52
53
|
}
|
53
54
|
|
54
55
|
@loader.stub :calc_config, loaded_values do
|
@@ -107,25 +108,27 @@ class TestConfigResolver < Minitest::Test
|
|
107
108
|
|
108
109
|
@loader = MockConfigLoader.new
|
109
110
|
loaded_values = {
|
110
|
-
"ff" =>
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
111
|
+
"ff" => { source: 'test',
|
112
|
+
config: Prefab::Config.new(
|
113
|
+
key: "ff",
|
114
|
+
variants: [
|
115
|
+
Prefab::FeatureFlagVariant.new(string: "inactive"),
|
116
|
+
Prefab::FeatureFlagVariant.new(string: "default"),
|
117
|
+
Prefab::FeatureFlagVariant.new(string: "env"),
|
118
|
+
],
|
119
|
+
rows: [
|
120
|
+
{ value: Prefab::ConfigValue.new(feature_flag: Prefab::FeatureFlag.new(
|
121
|
+
inactive_variant_idx: 0,
|
122
|
+
rules: default_ff_rule(1),
|
123
|
+
)) },
|
124
|
+
{ project_env_id: TEST_ENV_ID,
|
125
|
+
value: Prefab::ConfigValue.new(feature_flag: Prefab::FeatureFlag.new(
|
126
|
+
inactive_variant_idx: 0,
|
127
|
+
rules: default_ff_rule(2),
|
128
|
+
)) }
|
129
|
+
]
|
130
|
+
)
|
131
|
+
}
|
129
132
|
}
|
130
133
|
@loader.stub :calc_config, loaded_values do
|
131
134
|
resolver = Prefab::ConfigResolver.new(MockBaseClient.new, @loader)
|
@@ -140,18 +143,18 @@ class TestConfigResolver < Minitest::Test
|
|
140
143
|
@loader = MockConfigLoader.new
|
141
144
|
|
142
145
|
loaded_values = {
|
143
|
-
"Key:With:Colons" => Prefab::Config.new(
|
146
|
+
"Key:With:Colons" => { config: Prefab::Config.new(
|
144
147
|
key: "Key:With:Colons",
|
145
148
|
rows: [Prefab::ConfigRow.new(
|
146
149
|
value: Prefab::ConfigValue.new(string: "value")
|
147
150
|
)]
|
148
|
-
),
|
149
|
-
"proj:apikey" => Prefab::Config.new(
|
151
|
+
) },
|
152
|
+
"proj:apikey" => { config: Prefab::Config.new(
|
150
153
|
key: "proj:apikey",
|
151
154
|
rows: [Prefab::ConfigRow.new(
|
152
155
|
value: Prefab::ConfigValue.new(string: "v2")
|
153
156
|
)]
|
154
|
-
)
|
157
|
+
) }
|
155
158
|
}
|
156
159
|
|
157
160
|
@loader.stub :calc_config, loaded_values do
|
@@ -189,7 +192,10 @@ class TestConfigResolver < Minitest::Test
|
|
189
192
|
end
|
190
193
|
|
191
194
|
def resolver_for_namespace(namespace, loader, project_env_id: TEST_ENV_ID)
|
192
|
-
|
195
|
+
options = Prefab::Options.new(
|
196
|
+
namespace: namespace
|
197
|
+
)
|
198
|
+
resolver = Prefab::ConfigResolver.new(MockBaseClient.new(options), loader)
|
193
199
|
resolver.project_env_id = project_env_id
|
194
200
|
resolver.update
|
195
201
|
resolver
|