flipper-cloud 0.20.0.beta1 → 0.20.2
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/examples/cloud/basic.rb +2 -2
- data/examples/cloud/cached_in_memory.rb +2 -2
- data/examples/cloud/import.rb +9 -9
- data/examples/cloud/local_adapter.rb +2 -2
- data/lib/flipper/cloud/configuration.rb +14 -2
- data/lib/flipper/cloud/middleware.rb +14 -1
- data/lib/flipper/version.rb +1 -1
- data/spec/flipper/cloud/configuration_spec.rb +2 -2
- data/spec/flipper/cloud/dsl_spec.rb +43 -0
- data/spec/flipper/cloud/middleware_spec.rb +92 -3
- data/spec/flipper/cloud_spec.rb +85 -0
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ad99886efa608844beb4f7efdd5603ff60280c2ac5ca871a8de2e5fcbb2459f5
|
4
|
+
data.tar.gz: f5f162782dd28d9d5e55616030202eb47899438f700d12ec7de218bc9bdba353
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 44632f5b5c82b6c72c447716f8946768c03d2388c60fbfcdc07b43ee79389f094d49da3c1a1b5c4f34b4a1172e72b1dd2dbc67128838210f9cb3fb0dace41193
|
7
|
+
data.tar.gz: d6968fb80d7cdc47ebb5bb692780e6eee715faf845644302c28cc5f86217c19c939df18456382e5e614d9a72f39d3793298d054aa7d8d076d143ae3393eee8fc
|
data/examples/cloud/basic.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# Usage (from the repo root):
|
2
|
-
#
|
2
|
+
# env FLIPPER_CLOUD_TOKEN=<token> bundle exec ruby examples/cloud/basic.rb
|
3
3
|
require 'pathname'
|
4
4
|
require 'logger'
|
5
5
|
root_path = Pathname(__FILE__).dirname.join('..').expand_path
|
@@ -7,7 +7,7 @@ lib_path = root_path.join('lib')
|
|
7
7
|
$:.unshift(lib_path)
|
8
8
|
|
9
9
|
require 'flipper/cloud'
|
10
|
-
flipper = Flipper::Cloud.new
|
10
|
+
flipper = Flipper::Cloud.new
|
11
11
|
|
12
12
|
flipper[:stats].enable
|
13
13
|
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# env FLIPPER_CLOUD_TOKEN=<token> bundle exec ruby examples/cloud/cached_in_memory.rb
|
1
2
|
require File.expand_path('../../example_setup', __FILE__)
|
2
3
|
|
3
4
|
require 'flipper/cloud'
|
@@ -5,12 +6,11 @@ require 'flipper/adapters/active_support_cache_store'
|
|
5
6
|
require 'active_support/cache'
|
6
7
|
require 'active_support/cache/memory_store'
|
7
8
|
|
8
|
-
token = ENV.fetch("TOKEN") { abort "TOKEN environment variable not set." }
|
9
9
|
feature_name = ENV.fetch("FEATURE") { "testing" }.to_sym
|
10
10
|
|
11
11
|
Flipper.configure do |config|
|
12
12
|
config.default do
|
13
|
-
Flipper::Cloud.new
|
13
|
+
Flipper::Cloud.new do |cloud|
|
14
14
|
cloud.debug_output = STDOUT
|
15
15
|
cloud.adapter do |adapter|
|
16
16
|
Flipper::Adapters::ActiveSupportCacheStore.new(adapter,
|
data/examples/cloud/import.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# Usage (from the repo root):
|
2
|
-
# env
|
2
|
+
# env FLIPPER_CLOUD_TOKEN=<token> bundle exec ruby examples/cloud/import.rb
|
3
3
|
require 'pathname'
|
4
4
|
require 'logger'
|
5
5
|
root_path = Pathname(__FILE__).dirname.join('..').expand_path
|
@@ -10,14 +10,14 @@ require 'flipper'
|
|
10
10
|
require 'flipper/cloud'
|
11
11
|
|
12
12
|
memory_adapter = Flipper::Adapters::Memory.new
|
13
|
-
|
13
|
+
flipper = Flipper.new(memory_adapter)
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
flipper.enable(:test)
|
16
|
+
flipper.enable(:search)
|
17
|
+
flipper.enable_actor(:stats, Flipper::Actor.new("jnunemaker"))
|
18
|
+
flipper.enable_percentage_of_time(:logging, 5)
|
19
19
|
|
20
|
-
|
20
|
+
cloud = Flipper::Cloud.new
|
21
21
|
|
22
|
-
#
|
23
|
-
|
22
|
+
# makes cloud identical to memory flipper
|
23
|
+
cloud.import(flipper)
|
@@ -5,13 +5,13 @@
|
|
5
5
|
# never raise. You could get a slow request every now and then if cloud is
|
6
6
|
# unavailable, but we are hoping to fix that soon by doing the cloud update in a
|
7
7
|
# background thread.
|
8
|
+
# env FLIPPER_CLOUD_TOKEN=<token> bundle exec ruby examples/cloud/local_adapter.rb
|
8
9
|
require File.expand_path('../../example_setup', __FILE__)
|
9
10
|
|
10
11
|
require 'logger'
|
11
12
|
require 'flipper/cloud'
|
12
13
|
require 'flipper/adapters/redis'
|
13
14
|
|
14
|
-
token = ENV.fetch("TOKEN") { abort "TOKEN environment variable not set." }
|
15
15
|
feature_name = ENV.fetch("FEATURE") { "testing" }.to_sym
|
16
16
|
|
17
17
|
redis = Redis.new(logger: Logger.new(STDOUT))
|
@@ -19,7 +19,7 @@ redis.flushdb
|
|
19
19
|
|
20
20
|
Flipper.configure do |config|
|
21
21
|
config.default do
|
22
|
-
Flipper::Cloud.new
|
22
|
+
Flipper::Cloud.new do |cloud|
|
23
23
|
cloud.debug_output = STDOUT
|
24
24
|
cloud.local_adapter = Flipper::Adapters::Redis.new(redis)
|
25
25
|
cloud.sync_interval = 10
|
@@ -1,5 +1,7 @@
|
|
1
|
+
require "socket"
|
1
2
|
require "flipper/adapters/http"
|
2
3
|
require "flipper/adapters/memory"
|
4
|
+
require "flipper/adapters/dual_write"
|
3
5
|
require "flipper/adapters/sync"
|
4
6
|
|
5
7
|
module Flipper
|
@@ -67,7 +69,7 @@ module Flipper
|
|
67
69
|
@token = options.fetch(:token) { ENV["FLIPPER_CLOUD_TOKEN"] }
|
68
70
|
|
69
71
|
if @token.nil?
|
70
|
-
raise ArgumentError, "Flipper::Cloud token is missing. Please set FLIPPER_CLOUD_TOKEN or provide the token
|
72
|
+
raise ArgumentError, "Flipper::Cloud token is missing. Please set FLIPPER_CLOUD_TOKEN or provide the token (e.g. Flipper::Cloud.new('token'))."
|
71
73
|
end
|
72
74
|
|
73
75
|
@instrumenter = options.fetch(:instrumenter, Instrumenters::Noop)
|
@@ -129,7 +131,11 @@ module Flipper
|
|
129
131
|
private
|
130
132
|
|
131
133
|
def app_adapter
|
132
|
-
sync_method == :webhook ?
|
134
|
+
sync_method == :webhook ? dual_write_adapter : sync_adapter
|
135
|
+
end
|
136
|
+
|
137
|
+
def dual_write_adapter
|
138
|
+
Flipper::Adapters::DualWrite.new(local_adapter, http_adapter)
|
133
139
|
end
|
134
140
|
|
135
141
|
def sync_adapter
|
@@ -147,6 +153,12 @@ module Flipper
|
|
147
153
|
debug_output: @debug_output,
|
148
154
|
headers: {
|
149
155
|
"Flipper-Cloud-Token" => @token,
|
156
|
+
"Feature-Flipper-Token" => @token,
|
157
|
+
"Client-Lang" => "ruby",
|
158
|
+
"Client-Lang-Version" => "#{RUBY_VERSION} p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE})",
|
159
|
+
"Client-Platform" => RUBY_PLATFORM,
|
160
|
+
"Client-Engine" => defined?(RUBY_ENGINE) ? RUBY_ENGINE : "",
|
161
|
+
"Client-Hostname" => Socket.gethostname,
|
150
162
|
},
|
151
163
|
})
|
152
164
|
end
|
@@ -32,7 +32,20 @@ module Flipper
|
|
32
32
|
begin
|
33
33
|
message_verifier = MessageVerifier.new(secret: flipper.sync_secret)
|
34
34
|
if message_verifier.verify(payload, signature)
|
35
|
-
|
35
|
+
begin
|
36
|
+
flipper.sync
|
37
|
+
body = JSON.generate({
|
38
|
+
groups: Flipper.group_names.map { |name| {name: name}}
|
39
|
+
})
|
40
|
+
rescue Flipper::Adapters::Http::Error => error
|
41
|
+
status = error.response.code.to_i == 402 ? 402 : 500
|
42
|
+
headers["Flipper-Cloud-Response-Error-Class"] = error.class.name
|
43
|
+
headers["Flipper-Cloud-Response-Error-Message"] = error.message
|
44
|
+
rescue => error
|
45
|
+
status = 500
|
46
|
+
headers["Flipper-Cloud-Response-Error-Class"] = error.class.name
|
47
|
+
headers["Flipper-Cloud-Response-Error-Message"] = error.message
|
48
|
+
end
|
36
49
|
end
|
37
50
|
rescue MessageVerifier::InvalidSignature
|
38
51
|
status = 400
|
data/lib/flipper/version.rb
CHANGED
@@ -143,7 +143,7 @@ RSpec.describe Flipper::Cloud::Configuration do
|
|
143
143
|
}))
|
144
144
|
|
145
145
|
expect(instance.sync_method).to eq(:webhook)
|
146
|
-
expect(instance.adapter).to be_instance_of(Flipper::Adapters::
|
146
|
+
expect(instance.adapter).to be_instance_of(Flipper::Adapters::DualWrite)
|
147
147
|
end
|
148
148
|
|
149
149
|
it "raises ArgumentError for invalid sync_method" do
|
@@ -171,7 +171,7 @@ RSpec.describe Flipper::Cloud::Configuration do
|
|
171
171
|
}))
|
172
172
|
|
173
173
|
expect(instance.sync_method).to eq(:webhook)
|
174
|
-
expect(instance.adapter).to be_instance_of(Flipper::Adapters::
|
174
|
+
expect(instance.adapter).to be_instance_of(Flipper::Adapters::DualWrite)
|
175
175
|
end
|
176
176
|
|
177
177
|
it "can set sync_secret" do
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'helper'
|
2
2
|
require 'flipper/cloud/configuration'
|
3
3
|
require 'flipper/cloud/dsl'
|
4
|
+
require 'flipper/adapters/operation_logger'
|
4
5
|
require 'flipper/adapters/instrumented'
|
5
6
|
|
6
7
|
RSpec.describe Flipper::Cloud::DSL do
|
@@ -41,4 +42,46 @@ RSpec.describe Flipper::Cloud::DSL do
|
|
41
42
|
dsl = described_class.new(cloud_configuration)
|
42
43
|
expect(dsl.sync_secret).to eq("tasty")
|
43
44
|
end
|
45
|
+
|
46
|
+
context "when sync_method is webhook" do
|
47
|
+
let(:local_adapter) do
|
48
|
+
Flipper::Adapters::OperationLogger.new Flipper::Adapters::Memory.new
|
49
|
+
end
|
50
|
+
|
51
|
+
let(:cloud_configuration) do
|
52
|
+
cloud_configuration = Flipper::Cloud::Configuration.new({
|
53
|
+
token: "asdf",
|
54
|
+
sync_secret: "tasty",
|
55
|
+
sync_method: :webhook,
|
56
|
+
local_adapter: local_adapter
|
57
|
+
})
|
58
|
+
end
|
59
|
+
|
60
|
+
subject do
|
61
|
+
described_class.new(cloud_configuration)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "sends reads to local adapter" do
|
65
|
+
subject.features
|
66
|
+
subject.enabled?(:foo)
|
67
|
+
expect(local_adapter.count(:features)).to be(1)
|
68
|
+
expect(local_adapter.count(:get)).to be(1)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "sends writes to cloud and local" do
|
72
|
+
add_stub = stub_request(:post, "https://www.flippercloud.io/adapter/features").
|
73
|
+
with({headers: {'Flipper-Cloud-Token'=>'asdf'}}).
|
74
|
+
to_return(status: 200, body: '{}', headers: {})
|
75
|
+
enable_stub = stub_request(:post, "https://www.flippercloud.io/adapter/features/foo/boolean").
|
76
|
+
with(headers: {'Flipper-Cloud-Token'=>'asdf'}).
|
77
|
+
to_return(status: 200, body: '{}', headers: {})
|
78
|
+
|
79
|
+
subject.enable(:foo)
|
80
|
+
|
81
|
+
expect(local_adapter.count(:add)).to be(1)
|
82
|
+
expect(local_adapter.count(:enable)).to be(1)
|
83
|
+
expect(add_stub).to have_been_requested
|
84
|
+
expect(enable_stub).to have_been_requested
|
85
|
+
end
|
86
|
+
end
|
44
87
|
end
|
@@ -43,6 +43,12 @@ RSpec.describe Flipper::Cloud::Middleware do
|
|
43
43
|
let(:app) { Flipper::Cloud.app(flipper) }
|
44
44
|
|
45
45
|
it 'uses instance to sync' do
|
46
|
+
Flipper.register(:admins) { |*args| false }
|
47
|
+
Flipper.register(:staff) { |*args| false }
|
48
|
+
Flipper.register(:basic) { |*args| false }
|
49
|
+
Flipper.register(:plus) { |*args| false }
|
50
|
+
Flipper.register(:premium) { |*args| false }
|
51
|
+
|
46
52
|
stub = stub_request_for_token('regular')
|
47
53
|
env = {
|
48
54
|
"HTTP_FLIPPER_CLOUD_SIGNATURE" => signature_header_value,
|
@@ -50,6 +56,15 @@ RSpec.describe Flipper::Cloud::Middleware do
|
|
50
56
|
post '/webhooks', request_body, env
|
51
57
|
|
52
58
|
expect(last_response.status).to eq(200)
|
59
|
+
expect(JSON.parse(last_response.body)).to eq({
|
60
|
+
"groups" => [
|
61
|
+
{"name" => "admins"},
|
62
|
+
{"name" => "staff"},
|
63
|
+
{"name" => "basic"},
|
64
|
+
{"name" => "plus"},
|
65
|
+
{"name" => "premium"},
|
66
|
+
],
|
67
|
+
})
|
53
68
|
expect(stub).to have_been_requested
|
54
69
|
end
|
55
70
|
end
|
@@ -72,6 +87,75 @@ RSpec.describe Flipper::Cloud::Middleware do
|
|
72
87
|
end
|
73
88
|
end
|
74
89
|
|
90
|
+
context "when flipper cloud responds with 402" do
|
91
|
+
let(:app) { Flipper::Cloud.app(flipper) }
|
92
|
+
|
93
|
+
it "results in 402" do
|
94
|
+
Flipper.register(:admins) { |*args| false }
|
95
|
+
Flipper.register(:staff) { |*args| false }
|
96
|
+
Flipper.register(:basic) { |*args| false }
|
97
|
+
Flipper.register(:plus) { |*args| false }
|
98
|
+
Flipper.register(:premium) { |*args| false }
|
99
|
+
|
100
|
+
stub = stub_request_for_token('regular', status: 402)
|
101
|
+
env = {
|
102
|
+
"HTTP_FLIPPER_CLOUD_SIGNATURE" => signature_header_value,
|
103
|
+
}
|
104
|
+
post '/webhooks', request_body, env
|
105
|
+
|
106
|
+
expect(last_response.status).to eq(402)
|
107
|
+
expect(last_response.headers["Flipper-Cloud-Response-Error-Class"]).to eq("Flipper::Adapters::Http::Error")
|
108
|
+
expect(last_response.headers["Flipper-Cloud-Response-Error-Message"]).to eq("Failed with status: 402")
|
109
|
+
expect(stub).to have_been_requested
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
context "when flipper cloud responds with non-402 and non-2xx code" do
|
114
|
+
let(:app) { Flipper::Cloud.app(flipper) }
|
115
|
+
|
116
|
+
it "results in 500" do
|
117
|
+
Flipper.register(:admins) { |*args| false }
|
118
|
+
Flipper.register(:staff) { |*args| false }
|
119
|
+
Flipper.register(:basic) { |*args| false }
|
120
|
+
Flipper.register(:plus) { |*args| false }
|
121
|
+
Flipper.register(:premium) { |*args| false }
|
122
|
+
|
123
|
+
stub = stub_request_for_token('regular', status: 503)
|
124
|
+
env = {
|
125
|
+
"HTTP_FLIPPER_CLOUD_SIGNATURE" => signature_header_value,
|
126
|
+
}
|
127
|
+
post '/webhooks', request_body, env
|
128
|
+
|
129
|
+
expect(last_response.status).to eq(500)
|
130
|
+
expect(last_response.headers["Flipper-Cloud-Response-Error-Class"]).to eq("Flipper::Adapters::Http::Error")
|
131
|
+
expect(last_response.headers["Flipper-Cloud-Response-Error-Message"]).to eq("Failed with status: 503")
|
132
|
+
expect(stub).to have_been_requested
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
context "when flipper cloud responds with timeout" do
|
137
|
+
let(:app) { Flipper::Cloud.app(flipper) }
|
138
|
+
|
139
|
+
it "results in 500" do
|
140
|
+
Flipper.register(:admins) { |*args| false }
|
141
|
+
Flipper.register(:staff) { |*args| false }
|
142
|
+
Flipper.register(:basic) { |*args| false }
|
143
|
+
Flipper.register(:plus) { |*args| false }
|
144
|
+
Flipper.register(:premium) { |*args| false }
|
145
|
+
|
146
|
+
stub = stub_request_for_token('regular', status: :timeout)
|
147
|
+
env = {
|
148
|
+
"HTTP_FLIPPER_CLOUD_SIGNATURE" => signature_header_value,
|
149
|
+
}
|
150
|
+
post '/webhooks', request_body, env
|
151
|
+
|
152
|
+
expect(last_response.status).to eq(500)
|
153
|
+
expect(last_response.headers["Flipper-Cloud-Response-Error-Class"]).to eq("Net::OpenTimeout")
|
154
|
+
expect(last_response.headers["Flipper-Cloud-Response-Error-Message"]).to eq("execution expired")
|
155
|
+
expect(stub).to have_been_requested
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
75
159
|
context 'when initialized with flipper instance and flipper instance in env' do
|
76
160
|
let(:app) { Flipper::Cloud.app(flipper) }
|
77
161
|
let(:signature) {
|
@@ -162,12 +246,17 @@ RSpec.describe Flipper::Cloud::Middleware do
|
|
162
246
|
|
163
247
|
private
|
164
248
|
|
165
|
-
def stub_request_for_token(token)
|
166
|
-
stub_request(:get, "https://www.flippercloud.io/adapter/features").
|
249
|
+
def stub_request_for_token(token, status: 200)
|
250
|
+
stub = stub_request(:get, "https://www.flippercloud.io/adapter/features").
|
167
251
|
with({
|
168
252
|
headers: {
|
169
253
|
'Flipper-Cloud-Token' => token,
|
170
254
|
},
|
171
|
-
})
|
255
|
+
})
|
256
|
+
if status == :timeout
|
257
|
+
stub.to_timeout
|
258
|
+
else
|
259
|
+
stub.to_return(status: status, body: response_body, headers: {})
|
260
|
+
end
|
172
261
|
end
|
173
262
|
end
|
data/spec/flipper/cloud_spec.rb
CHANGED
@@ -114,4 +114,89 @@ RSpec.describe Flipper::Cloud do
|
|
114
114
|
described_class.new('asdf', open_timeout: 1)
|
115
115
|
end
|
116
116
|
end
|
117
|
+
|
118
|
+
it 'can import' do
|
119
|
+
stub_request(:post, /www\.flippercloud\.io\/adapter\/features.*/).
|
120
|
+
with(headers: {
|
121
|
+
'Feature-Flipper-Token'=>'asdf',
|
122
|
+
'Flipper-Cloud-Token'=>'asdf',
|
123
|
+
}).to_return(status: 200, body: "{}", headers: {})
|
124
|
+
|
125
|
+
flipper = Flipper.new(Flipper::Adapters::Memory.new)
|
126
|
+
|
127
|
+
flipper.enable(:test)
|
128
|
+
flipper.enable(:search)
|
129
|
+
flipper.enable_actor(:stats, Flipper::Actor.new("jnunemaker"))
|
130
|
+
flipper.enable_percentage_of_time(:logging, 5)
|
131
|
+
|
132
|
+
cloud_flipper = Flipper::Cloud.new("asdf")
|
133
|
+
|
134
|
+
get_all = {
|
135
|
+
"logging" => {actors: Set.new, boolean: nil, groups: Set.new, percentage_of_actors: nil, percentage_of_time: "5"},
|
136
|
+
"search" => {actors: Set.new, boolean: "true", groups: Set.new, percentage_of_actors: nil, percentage_of_time: nil},
|
137
|
+
"stats" => {actors: Set["jnunemaker"], boolean: nil, groups: Set.new, percentage_of_actors: nil, percentage_of_time: nil},
|
138
|
+
"test" => {actors: Set.new, boolean: "true", groups: Set.new, percentage_of_actors: nil, percentage_of_time: nil},
|
139
|
+
}
|
140
|
+
|
141
|
+
expect(flipper.adapter.get_all).to eq(get_all)
|
142
|
+
cloud_flipper.import(flipper)
|
143
|
+
expect(flipper.adapter.get_all).to eq(get_all)
|
144
|
+
expect(cloud_flipper.adapter.get_all).to eq(get_all)
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'raises error for failure while importing' do
|
148
|
+
stub_request(:post, /www\.flippercloud\.io\/adapter\/features.*/).
|
149
|
+
with(headers: {
|
150
|
+
'Feature-Flipper-Token'=>'asdf',
|
151
|
+
'Flipper-Cloud-Token'=>'asdf',
|
152
|
+
}).to_return(status: 500, body: "{}")
|
153
|
+
|
154
|
+
flipper = Flipper.new(Flipper::Adapters::Memory.new)
|
155
|
+
|
156
|
+
flipper.enable(:test)
|
157
|
+
flipper.enable(:search)
|
158
|
+
flipper.enable_actor(:stats, Flipper::Actor.new("jnunemaker"))
|
159
|
+
flipper.enable_percentage_of_time(:logging, 5)
|
160
|
+
|
161
|
+
cloud_flipper = Flipper::Cloud.new("asdf")
|
162
|
+
|
163
|
+
get_all = {
|
164
|
+
"logging" => {actors: Set.new, boolean: nil, groups: Set.new, percentage_of_actors: nil, percentage_of_time: "5"},
|
165
|
+
"search" => {actors: Set.new, boolean: "true", groups: Set.new, percentage_of_actors: nil, percentage_of_time: nil},
|
166
|
+
"stats" => {actors: Set["jnunemaker"], boolean: nil, groups: Set.new, percentage_of_actors: nil, percentage_of_time: nil},
|
167
|
+
"test" => {actors: Set.new, boolean: "true", groups: Set.new, percentage_of_actors: nil, percentage_of_time: nil},
|
168
|
+
}
|
169
|
+
|
170
|
+
expect(flipper.adapter.get_all).to eq(get_all)
|
171
|
+
expect { cloud_flipper.import(flipper) }.to raise_error(Flipper::Adapters::Http::Error)
|
172
|
+
expect(flipper.adapter.get_all).to eq(get_all)
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'raises error for timeout while importing' do
|
176
|
+
stub_request(:post, /www\.flippercloud\.io\/adapter\/features.*/).
|
177
|
+
with(headers: {
|
178
|
+
'Feature-Flipper-Token'=>'asdf',
|
179
|
+
'Flipper-Cloud-Token'=>'asdf',
|
180
|
+
}).to_timeout
|
181
|
+
|
182
|
+
flipper = Flipper.new(Flipper::Adapters::Memory.new)
|
183
|
+
|
184
|
+
flipper.enable(:test)
|
185
|
+
flipper.enable(:search)
|
186
|
+
flipper.enable_actor(:stats, Flipper::Actor.new("jnunemaker"))
|
187
|
+
flipper.enable_percentage_of_time(:logging, 5)
|
188
|
+
|
189
|
+
cloud_flipper = Flipper::Cloud.new("asdf")
|
190
|
+
|
191
|
+
get_all = {
|
192
|
+
"logging" => {actors: Set.new, boolean: nil, groups: Set.new, percentage_of_actors: nil, percentage_of_time: "5"},
|
193
|
+
"search" => {actors: Set.new, boolean: "true", groups: Set.new, percentage_of_actors: nil, percentage_of_time: nil},
|
194
|
+
"stats" => {actors: Set["jnunemaker"], boolean: nil, groups: Set.new, percentage_of_actors: nil, percentage_of_time: nil},
|
195
|
+
"test" => {actors: Set.new, boolean: "true", groups: Set.new, percentage_of_actors: nil, percentage_of_time: nil},
|
196
|
+
}
|
197
|
+
|
198
|
+
expect(flipper.adapter.get_all).to eq(get_all)
|
199
|
+
expect { cloud_flipper.import(flipper) }.to raise_error(Net::OpenTimeout)
|
200
|
+
expect(flipper.adapter.get_all).to eq(get_all)
|
201
|
+
end
|
117
202
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flipper-cloud
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.20.
|
4
|
+
version: 0.20.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Nunemaker
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-01-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: flipper
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.20.
|
19
|
+
version: 0.20.2
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.20.
|
26
|
+
version: 0.20.2
|
27
27
|
description:
|
28
28
|
email:
|
29
29
|
- nunemaker@gmail.com
|
@@ -65,9 +65,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
65
65
|
version: '0'
|
66
66
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
67
67
|
requirements:
|
68
|
-
- - "
|
68
|
+
- - ">="
|
69
69
|
- !ruby/object:Gem::Version
|
70
|
-
version:
|
70
|
+
version: '0'
|
71
71
|
requirements: []
|
72
72
|
rubygems_version: 3.0.3
|
73
73
|
signing_key:
|