flipper 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +1 -0
- data/Changelog.md +12 -0
- data/Gemfile +4 -7
- data/Guardfile +16 -4
- data/README.md +63 -34
- data/examples/basic.rb +1 -1
- data/examples/dsl.rb +10 -12
- data/examples/group.rb +10 -4
- data/examples/individual_actor.rb +9 -6
- data/examples/instrumentation.rb +39 -0
- data/examples/percentage_of_actors.rb +12 -9
- data/examples/percentage_of_random.rb +4 -2
- data/lib/flipper.rb +43 -10
- data/lib/flipper/adapter.rb +106 -21
- data/lib/flipper/adapters/memoized.rb +7 -0
- data/lib/flipper/adapters/memory.rb +10 -3
- data/lib/flipper/adapters/operation_logger.rb +7 -0
- data/lib/flipper/dsl.rb +73 -16
- data/lib/flipper/errors.rb +6 -0
- data/lib/flipper/feature.rb +117 -19
- data/lib/flipper/gate.rb +72 -4
- data/lib/flipper/gates/actor.rb +41 -12
- data/lib/flipper/gates/boolean.rb +21 -11
- data/lib/flipper/gates/group.rb +45 -12
- data/lib/flipper/gates/percentage_of_actors.rb +29 -10
- data/lib/flipper/gates/percentage_of_random.rb +22 -9
- data/lib/flipper/instrumentation/log_subscriber.rb +107 -0
- data/lib/flipper/instrumentation/metriks.rb +6 -0
- data/lib/flipper/instrumentation/metriks_subscriber.rb +92 -0
- data/lib/flipper/instrumenters/memory.rb +25 -0
- data/lib/flipper/instrumenters/noop.rb +9 -0
- data/lib/flipper/key.rb +23 -4
- data/lib/flipper/registry.rb +22 -6
- data/lib/flipper/spec/shared_adapter_specs.rb +59 -12
- data/lib/flipper/toggle.rb +19 -2
- data/lib/flipper/toggles/boolean.rb +36 -3
- data/lib/flipper/toggles/set.rb +9 -3
- data/lib/flipper/toggles/value.rb +9 -3
- data/lib/flipper/type.rb +1 -0
- data/lib/flipper/types/actor.rb +12 -14
- data/lib/flipper/types/percentage.rb +8 -2
- data/lib/flipper/version.rb +1 -1
- data/spec/flipper/adapter_spec.rb +163 -27
- data/spec/flipper/adapters/memoized_spec.rb +6 -6
- data/spec/flipper/dsl_spec.rb +51 -54
- data/spec/flipper/feature_spec.rb +179 -17
- data/spec/flipper/gate_spec.rb +47 -0
- data/spec/flipper/gates/actor_spec.rb +52 -0
- data/spec/flipper/gates/boolean_spec.rb +52 -0
- data/spec/flipper/gates/group_spec.rb +79 -0
- data/spec/flipper/gates/percentage_of_actors_spec.rb +98 -0
- data/spec/flipper/gates/percentage_of_random_spec.rb +54 -0
- data/spec/flipper/instrumentation/log_subscriber_spec.rb +104 -0
- data/spec/flipper/instrumentation/metriks_subscriber_spec.rb +69 -0
- data/spec/flipper/instrumenters/memory_spec.rb +26 -0
- data/spec/flipper/instrumenters/noop_spec.rb +22 -0
- data/spec/flipper/key_spec.rb +8 -2
- data/spec/flipper/registry_spec.rb +20 -2
- data/spec/flipper/toggle_spec.rb +22 -0
- data/spec/flipper/toggles/boolean_spec.rb +40 -0
- data/spec/flipper/toggles/set_spec.rb +35 -0
- data/spec/flipper/toggles/value_spec.rb +55 -0
- data/spec/flipper/types/actor_spec.rb +28 -33
- data/spec/flipper_spec.rb +16 -3
- data/spec/helper.rb +37 -3
- data/spec/integration_spec.rb +90 -83
- metadata +40 -4
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'flipper/instrumenters/memory'
|
3
|
+
|
4
|
+
describe Flipper::Gates::Actor do
|
5
|
+
let(:adapter) { double('Adapter', :set_members => []) }
|
6
|
+
let(:feature) { double('Feature', :name => :search, :adapter => adapter) }
|
7
|
+
let(:instrumenter) { Flipper::Instrumenters::Memory.new }
|
8
|
+
|
9
|
+
subject {
|
10
|
+
described_class.new(feature, :instrumenter => instrumenter)
|
11
|
+
}
|
12
|
+
|
13
|
+
describe "instrumentation" do
|
14
|
+
it "is recorded for open" do
|
15
|
+
thing = Struct.new(:flipper_id).new('22')
|
16
|
+
subject.open?(thing)
|
17
|
+
|
18
|
+
event = instrumenter.events.last
|
19
|
+
event.should_not be_nil
|
20
|
+
event.name.should eq('gate_operation.flipper')
|
21
|
+
event.payload.should eq({
|
22
|
+
:thing => thing,
|
23
|
+
:operation => :open?,
|
24
|
+
:result => false,
|
25
|
+
:gate_name => :actor,
|
26
|
+
:feature_name => :search,
|
27
|
+
})
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#description" do
|
32
|
+
context "with actors in set" do
|
33
|
+
before do
|
34
|
+
adapter.stub(:set_members => Set['bacon', 'ham'])
|
35
|
+
end
|
36
|
+
|
37
|
+
it "returns text" do
|
38
|
+
subject.description.should eq("actors (bacon, ham)")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "with no actors in set" do
|
43
|
+
before do
|
44
|
+
adapter.stub(:set_members => Set.new)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "returns disabled" do
|
48
|
+
subject.description.should eq('disabled')
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'flipper/instrumenters/memory'
|
3
|
+
|
4
|
+
describe Flipper::Gates::Boolean do
|
5
|
+
let(:adapter) { double('Adapter', :read => nil) }
|
6
|
+
let(:feature) { double('Feature', :name => :search, :adapter => adapter) }
|
7
|
+
let(:instrumenter) { Flipper::Instrumenters::Memory.new }
|
8
|
+
|
9
|
+
subject {
|
10
|
+
described_class.new(feature, :instrumenter => instrumenter)
|
11
|
+
}
|
12
|
+
|
13
|
+
describe "#description" do
|
14
|
+
context "for enabled" do
|
15
|
+
before do
|
16
|
+
subject.stub(:enabled? => true)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "returns Enabled" do
|
20
|
+
subject.description.should eq('Enabled')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "for disabled" do
|
25
|
+
before do
|
26
|
+
subject.stub(:enabled? => false)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "returns Disabled" do
|
30
|
+
subject.description.should eq('Disabled')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "instrumentation" do
|
36
|
+
it "is recorded for open" do
|
37
|
+
thing = nil
|
38
|
+
subject.open?(thing)
|
39
|
+
|
40
|
+
event = instrumenter.events.last
|
41
|
+
event.should_not be_nil
|
42
|
+
event.name.should eq('gate_operation.flipper')
|
43
|
+
event.payload.should eq({
|
44
|
+
:thing => thing,
|
45
|
+
:operation => :open?,
|
46
|
+
:result => false,
|
47
|
+
:gate_name => :boolean,
|
48
|
+
:feature_name => :search,
|
49
|
+
})
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'flipper/instrumenters/memory'
|
3
|
+
|
4
|
+
describe Flipper::Gates::Group do
|
5
|
+
let(:adapter) { double('Adapter', :set_members => []) }
|
6
|
+
let(:feature) { double('Feature', :name => :search, :adapter => adapter) }
|
7
|
+
let(:instrumenter) { Flipper::Instrumenters::Memory.new }
|
8
|
+
|
9
|
+
subject {
|
10
|
+
described_class.new(feature, :instrumenter => instrumenter)
|
11
|
+
}
|
12
|
+
|
13
|
+
describe "instrumentation" do
|
14
|
+
it "is recorded for open" do
|
15
|
+
thing = Struct.new(:flipper_id).new('22')
|
16
|
+
subject.open?(thing)
|
17
|
+
|
18
|
+
event = instrumenter.events.last
|
19
|
+
event.should_not be_nil
|
20
|
+
event.name.should eq('gate_operation.flipper')
|
21
|
+
event.payload.should eq({
|
22
|
+
:thing => thing,
|
23
|
+
:operation => :open?,
|
24
|
+
:result => false,
|
25
|
+
:gate_name => :group,
|
26
|
+
:feature_name => :search,
|
27
|
+
})
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#description" do
|
32
|
+
context "with groups in set" do
|
33
|
+
before do
|
34
|
+
adapter.stub(:set_members => Set['bacon', 'ham'])
|
35
|
+
end
|
36
|
+
|
37
|
+
it "returns text" do
|
38
|
+
subject.description.should eq("groups (bacon, ham)")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "with no groups in set" do
|
43
|
+
before do
|
44
|
+
adapter.stub(:set_members => Set.new)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "returns disabled" do
|
48
|
+
subject.description.should eq('disabled')
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "#open?" do
|
54
|
+
context "with a group in adapter, but not registered" do
|
55
|
+
before do
|
56
|
+
Flipper.register(:staff) { |thing| true }
|
57
|
+
adapter.stub(:set_members => Set[:newbs, :staff])
|
58
|
+
end
|
59
|
+
|
60
|
+
it "ignores group" do
|
61
|
+
thing = Struct.new(:flipper_id).new('5')
|
62
|
+
subject.open?(thing).should be_true
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context "thing that does not respond to method in group block" do
|
67
|
+
before do
|
68
|
+
Flipper.register(:stinkers) { |thing| thing.stinker? }
|
69
|
+
adapter.stub(:set_members => Set[:stinkers])
|
70
|
+
end
|
71
|
+
|
72
|
+
it "raises error" do
|
73
|
+
expect {
|
74
|
+
subject.open?(Object.new)
|
75
|
+
}.to raise_error(NoMethodError)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'flipper/instrumenters/memory'
|
3
|
+
|
4
|
+
describe Flipper::Gates::PercentageOfActors do
|
5
|
+
let(:adapter) { double('Adapter', :read => nil) }
|
6
|
+
let(:feature) { double('Feature', :name => :search, :adapter => adapter) }
|
7
|
+
let(:instrumenter) { Flipper::Instrumenters::Memory.new }
|
8
|
+
|
9
|
+
subject {
|
10
|
+
described_class.new(feature, :instrumenter => instrumenter)
|
11
|
+
}
|
12
|
+
|
13
|
+
describe "instrumentation" do
|
14
|
+
it "is recorded for open" do
|
15
|
+
thing = Struct.new(:flipper_id).new('22')
|
16
|
+
subject.open?(thing)
|
17
|
+
|
18
|
+
event = instrumenter.events.last
|
19
|
+
event.should_not be_nil
|
20
|
+
event.name.should eq('gate_operation.flipper')
|
21
|
+
event.payload.should eq({
|
22
|
+
:thing => thing,
|
23
|
+
:operation => :open?,
|
24
|
+
:result => false,
|
25
|
+
:gate_name => :percentage_of_actors,
|
26
|
+
:feature_name => :search,
|
27
|
+
})
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#description" do
|
32
|
+
context "when enabled" do
|
33
|
+
before do
|
34
|
+
adapter.stub(:read => 22)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "returns text" do
|
38
|
+
subject.description.should eq('22% of actors')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "when disabled" do
|
43
|
+
before do
|
44
|
+
adapter.stub(:read => nil)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "returns disabled" do
|
48
|
+
subject.description.should eq('disabled')
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "#open?" do
|
54
|
+
context "when compared against two features" do
|
55
|
+
let(:percentage) { 0.05 }
|
56
|
+
let(:number_of_actors) { 100 }
|
57
|
+
|
58
|
+
let(:actors) {
|
59
|
+
(1..number_of_actors).map { |n|
|
60
|
+
Struct.new(:flipper_id).new(n)
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
64
|
+
let(:feature_one_enabled_actors) do
|
65
|
+
feature_one = double('Feature', :name => :name_one, :adapter => adapter)
|
66
|
+
gate = described_class.new(feature_one)
|
67
|
+
actors.select { |actor| gate.open? actor }
|
68
|
+
end
|
69
|
+
|
70
|
+
let(:feature_two_enabled_actors) do
|
71
|
+
feature_two = double('Feature', :name => :name_two, :adapter => adapter)
|
72
|
+
gate = described_class.new(feature_two)
|
73
|
+
actors.select { |actor| gate.open? actor }
|
74
|
+
end
|
75
|
+
|
76
|
+
before do
|
77
|
+
percentage_as_integer = percentage * 100
|
78
|
+
adapter.stub(:read => percentage_as_integer)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "does not enable both features for same set of actors" do
|
82
|
+
feature_one_enabled_actors.should_not eq(feature_two_enabled_actors)
|
83
|
+
end
|
84
|
+
|
85
|
+
it "enables feature for accurate number of actors for each feature" do
|
86
|
+
margin_of_error = 0.02 * number_of_actors # 2 percent margin of error
|
87
|
+
expected_enabled_size = number_of_actors * percentage
|
88
|
+
|
89
|
+
[
|
90
|
+
feature_one_enabled_actors.size,
|
91
|
+
feature_two_enabled_actors.size,
|
92
|
+
].each do |actual_enabled_size|
|
93
|
+
actual_enabled_size.should be_within(margin_of_error).of(expected_enabled_size)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'flipper/instrumenters/memory'
|
3
|
+
|
4
|
+
describe Flipper::Gates::PercentageOfRandom do
|
5
|
+
let(:adapter) { double('Adapter', :read => 5) }
|
6
|
+
let(:feature) { double('Feature', :name => :search, :adapter => adapter) }
|
7
|
+
let(:instrumenter) { Flipper::Instrumenters::Memory.new }
|
8
|
+
|
9
|
+
subject {
|
10
|
+
described_class.new(feature, :instrumenter => instrumenter)
|
11
|
+
}
|
12
|
+
|
13
|
+
describe "instrumentation" do
|
14
|
+
it "is recorded for open" do
|
15
|
+
thing = Struct.new(:flipper_id).new('22')
|
16
|
+
subject.open?(thing)
|
17
|
+
|
18
|
+
event = instrumenter.events.last
|
19
|
+
event.should_not be_nil
|
20
|
+
event.name.should eq('gate_operation.flipper')
|
21
|
+
|
22
|
+
event.payload[:thing].should eq(thing)
|
23
|
+
event.payload[:operation].should eq(:open?)
|
24
|
+
event.payload[:gate_name].should eq(:percentage_of_random)
|
25
|
+
event.payload[:feature_name].should eq(:search)
|
26
|
+
|
27
|
+
# random so don't test value
|
28
|
+
event.payload.key?(:result).should be_true
|
29
|
+
event.payload[:result].should_not be_nil
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#description" do
|
34
|
+
context "when enabled" do
|
35
|
+
before do
|
36
|
+
adapter.stub(:read => 22)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "returns text" do
|
40
|
+
subject.description.should eq('22% of the time')
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context "when disabled" do
|
45
|
+
before do
|
46
|
+
adapter.stub(:read => nil)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "returns disabled" do
|
50
|
+
subject.description.should eq('disabled')
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'flipper/adapters/memory'
|
3
|
+
require 'flipper/instrumentation/log_subscriber'
|
4
|
+
|
5
|
+
describe Flipper::Instrumentation::LogSubscriber do
|
6
|
+
let(:adapter) { Flipper::Adapters::Memory.new }
|
7
|
+
let(:flipper) {
|
8
|
+
Flipper.new(adapter, :instrumenter => ActiveSupport::Notifications)
|
9
|
+
}
|
10
|
+
|
11
|
+
before do
|
12
|
+
Flipper.register(:admins) { |thing|
|
13
|
+
thing.respond_to?(:admin?) && thing.admin?
|
14
|
+
}
|
15
|
+
|
16
|
+
@io = StringIO.new
|
17
|
+
logger = Logger.new(@io)
|
18
|
+
logger.formatter = proc { |severity, datetime, progname, msg| "#{msg}\n" }
|
19
|
+
described_class.logger = logger
|
20
|
+
end
|
21
|
+
|
22
|
+
after do
|
23
|
+
described_class.logger = nil
|
24
|
+
end
|
25
|
+
|
26
|
+
let(:log) { @io.string }
|
27
|
+
|
28
|
+
context "feature enabled checks" do
|
29
|
+
before do
|
30
|
+
clear_logs
|
31
|
+
flipper[:search].enabled?
|
32
|
+
end
|
33
|
+
|
34
|
+
it "logs feature calls with result after operation" do
|
35
|
+
feature_line = find_line('Flipper feature(search) enabled? false')
|
36
|
+
feature_line.should include('[ thing=nil ]')
|
37
|
+
end
|
38
|
+
|
39
|
+
it "logs adapter calls" do
|
40
|
+
adapter_line = find_line('Flipper feature(search) adapter(memory) read("search/boolean")')
|
41
|
+
adapter_line.should include('[ result=nil ]')
|
42
|
+
end
|
43
|
+
|
44
|
+
it "logs gate calls" do
|
45
|
+
gate_line = find_line('Flipper feature(search) gate(boolean) open? false')
|
46
|
+
gate_line.should include('[ thing=nil ]')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context "feature enabled checks with a thing" do
|
51
|
+
let(:user) { Struct.new(:flipper_id).new('1') }
|
52
|
+
|
53
|
+
before do
|
54
|
+
clear_logs
|
55
|
+
flipper[:search].enabled?(user)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "logs thing for feature" do
|
59
|
+
feature_line = find_line('Flipper feature(search) enabled?')
|
60
|
+
feature_line.should include(user.inspect)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "logs thing for gate" do
|
64
|
+
gate_line = find_line('Flipper feature(search) gate(boolean) open')
|
65
|
+
gate_line.should include(user.inspect)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context "changing feature enabled state" do
|
70
|
+
let(:user) { Struct.new(:flipper_id).new('1') }
|
71
|
+
|
72
|
+
before do
|
73
|
+
clear_logs
|
74
|
+
flipper[:search].enable(user)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "logs feature calls with result in brackets" do
|
78
|
+
feature_line = find_line('Flipper feature(search) enable true')
|
79
|
+
feature_line.should include("[ thing=#{user.inspect} gate_name=actor ]")
|
80
|
+
end
|
81
|
+
|
82
|
+
it "logs adapter value" do
|
83
|
+
adapter_line = find_line('Flipper feature(search) adapter(memory) set_add("search/actors")')
|
84
|
+
adapter_line.should include("value=#{user.flipper_id.to_s.inspect}")
|
85
|
+
end
|
86
|
+
|
87
|
+
it "logs adapter calls not related to a specific feature" do
|
88
|
+
adapter_line = find_line('Flipper adapter(memory) set_add("features")')
|
89
|
+
log.should_not include('Could not log')
|
90
|
+
log.should_not include('NoMethodError: undefined method')
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def find_line(str)
|
95
|
+
regex = /#{Regexp.escape(str)}/
|
96
|
+
lines = log.split("\n")
|
97
|
+
lines.detect { |line| line =~ regex } ||
|
98
|
+
raise("Could not find line matching #{str.inspect} in #{lines.inspect}")
|
99
|
+
end
|
100
|
+
|
101
|
+
def clear_logs
|
102
|
+
@io.string = ''
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'flipper/adapters/memory'
|
3
|
+
require 'flipper/instrumentation/metriks'
|
4
|
+
|
5
|
+
describe Flipper::Instrumentation::MetriksSubscriber do
|
6
|
+
let(:adapter) { Flipper::Adapters::Memory.new }
|
7
|
+
let(:flipper) {
|
8
|
+
Flipper.new(adapter, :instrumenter => ActiveSupport::Notifications)
|
9
|
+
}
|
10
|
+
|
11
|
+
let(:user) { user = Struct.new(:flipper_id).new('1') }
|
12
|
+
|
13
|
+
before do
|
14
|
+
Metriks::Registry.default.clear
|
15
|
+
end
|
16
|
+
|
17
|
+
context "for enabled feature" do
|
18
|
+
it "updates feature metrics when calls happen" do
|
19
|
+
flipper[:stats].enable(user)
|
20
|
+
Metriks.timer("flipper.feature_operation.enable").count.should be(1)
|
21
|
+
|
22
|
+
flipper[:stats].enabled?(user)
|
23
|
+
Metriks.timer("flipper.feature_operation.enabled").count.should be(1)
|
24
|
+
Metriks.meter("flipper.feature.stats.enabled").count.should be(1)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "for disabled feature" do
|
29
|
+
it "updates feature metrics when calls happen" do
|
30
|
+
flipper[:stats].disable(user)
|
31
|
+
Metriks.timer("flipper.feature_operation.disable").count.should be(1)
|
32
|
+
|
33
|
+
flipper[:stats].enabled?(user)
|
34
|
+
Metriks.timer("flipper.feature_operation.enabled").count.should be(1)
|
35
|
+
Metriks.meter("flipper.feature.stats.disabled").count.should be(1)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
it "updates adapter metrics when calls happen" do
|
40
|
+
flipper[:stats].enable(user)
|
41
|
+
# one for features and one for actors
|
42
|
+
Metriks.timer("flipper.adapter.memory.set_add").count.should be(2)
|
43
|
+
|
44
|
+
flipper[:stats].enabled?(user)
|
45
|
+
Metriks.timer("flipper.adapter.memory.read").count.should be(1)
|
46
|
+
# one for actors and one for groups
|
47
|
+
Metriks.timer("flipper.adapter.memory.set_members").count.should be(2)
|
48
|
+
|
49
|
+
flipper[:stats].disable(user)
|
50
|
+
Metriks.timer("flipper.adapter.memory.set_delete").count.should be(1)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "updates gate metrics when calls happen" do
|
54
|
+
flipper[:stats].enable(user)
|
55
|
+
flipper[:stats].enabled?(user)
|
56
|
+
|
57
|
+
Metriks.timer("flipper.gate_operation.boolean.open").count.should be(1)
|
58
|
+
Metriks.timer("flipper.feature.stats.gate_operation.boolean.open").count.should be(1)
|
59
|
+
Metriks.meter("flipper.feature.stats.gate.actor.open").count.should be(1)
|
60
|
+
Metriks.meter("flipper.feature.stats.gate.boolean.closed").count.should be(1)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Helper for seeing what is in the metriks registry
|
64
|
+
def print_registry_names
|
65
|
+
Metriks::Registry.default.each do |name, metric|
|
66
|
+
puts name
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|