flipper 0.3.0 → 0.4.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.
- 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
|