Skip to content

Commit a5d5102

Browse files
committed
Add skip_all registration option
1 parent 9dac630 commit a5d5102

7 files changed

Lines changed: 154 additions & 17 deletions

File tree

‎CHANGELOG.markdown‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
#### Unreleased
2+
* Add a `skip_all` registration option for checks and check collections that
3+
should remain directly accessible without running at `/okcomputer/all`
24
* Don't use a shared closure for each spawned thread
35
> awilfox: https://github.com/okcomputer-ruby/okcomputer/pull/27
46
* ActionMailerCheck: Support :sendmail and :test

‎README.markdown‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,32 @@ end
182182
OkComputer::Registry.register "check_for_odds", MyCustomCheck.new
183183
```
184184

185+
### Grouping Checks
186+
187+
Use a `CheckCollection` to expose several related checks from one endpoint. Register
188+
the collection with `skip_all: true` when the group should not run as part of the
189+
default `/okcomputer/all` endpoint:
190+
191+
```ruby
192+
# config/initializers/okcomputer.rb
193+
versions = OkComputer::CheckCollection.new("Versions")
194+
195+
OkComputer::Registry.register "versions", versions, skip_all: true
196+
OkComputer::Registry.register "ruby_version", OkComputer::RubyVersionCheck.new, "versions"
197+
OkComputer::Registry.register "app_version", OkComputer::AppVersionCheck.new, "versions"
198+
```
199+
200+
The group is available at `/okcomputer/versions` and `/okcomputer/versions.json`.
201+
Its checks remain individually available, but neither the group nor its checks run
202+
at `/okcomputer/all`.
203+
204+
An individual check can also be omitted from `/okcomputer/all` while retaining its
205+
own endpoint:
206+
207+
```ruby
208+
OkComputer::Registry.register "ruby_version", OkComputer::RubyVersionCheck.new, skip_all: true
209+
```
210+
185211
### Registering Optional Checks
186212

187213
Register an optional check like so:

‎lib/ok_computer/check.rb‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
module OkComputer
44
class Check
55
# to be set by Registry upon registration
6-
attr_accessor :registrant_name
6+
attr_accessor :registrant_name, :skip_all
77
# nil by default, only set to true if the check deems itself failed
88
attr_accessor :failure_occurred
99
# nil by default, set by #check to control the output

‎lib/ok_computer/check_collection.rb‎

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
module OkComputer
22
class CheckCollection
3-
attr_accessor :collection, :registrant_name, :display
3+
attr_accessor :collection, :registrant_name, :display, :skip_all
44

55
# Public: Initialize a new CheckCollection
66
#
77
# display - the display name for the Check Collection
8-
def initialize(display)
8+
# exclude_skipped_checks - whether checks marked skip_all should be omitted
9+
def initialize(display, exclude_skipped_checks=false)
910
self.display = display
1011
self.collection = {}
12+
self.skip_all = false
13+
@exclude_skipped_checks = exclude_skipped_checks
1114
end
1215

1316
# Public: Run the collection's checks
@@ -37,7 +40,7 @@ def [](key)
3740
#
3841
# Returns an Array of the collection's values
3942
def checks
40-
collection.values
43+
included_collection.values
4144
end
4245

4346
def <=>(check)
@@ -51,13 +54,13 @@ def <=>(check)
5154
alias_method :values, :checks
5255

5356
def check_names
54-
collection.keys
57+
included_collection.keys
5558
end
5659

5760
alias_method :keys, :check_names
5861

5962
def sub_collections
60-
checks.select{ |c| c.is_a?(CheckCollection)}
63+
collection.values.select{ |c| c.is_a?(CheckCollection)}
6164
end
6265

6366
def self_and_sub_collections
@@ -108,6 +111,11 @@ def success?
108111

109112
private
110113

114+
def included_collection
115+
return collection unless @exclude_skipped_checks
116+
collection.reject{ |_name, check| check.respond_to?(:skip_all) && check.skip_all }
117+
end
118+
111119
def check_in_sequence
112120
checks.each(&:run)
113121
end

‎lib/ok_computer/registry.rb‎

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,33 @@ def self.all
3131
#
3232
# Returns @default_collection
3333
def self.default_collection
34-
@default_collection ||= CheckCollection.new('Default Collection')
34+
@default_collection ||= CheckCollection.new('Default Collection', true)
3535
end
3636

3737
# Public: Register the given check with OkComputer
3838
#
3939
# check_name - The name of the check to retrieve
4040
# check_object - Instance of Checker to register
4141
# collection_name - The name of the check collection the check should be registered to
42-
def self.register(check_name, check_object, collection_name=nil)
43-
find_collection(collection_name).register(check_name, check_object)
42+
# options - Set skip_all to true to omit the check from the default collection's results
43+
def self.register(check_name, check_object, collection_name=nil, options={})
44+
if collection_name.is_a?(Hash)
45+
options = collection_name
46+
collection_name = nil
47+
end
48+
49+
if collection_name && options[:skip_all]
50+
raise ArgumentError, "skip_all is only supported in the default collection"
51+
end
52+
53+
if !collection_name && check_object.respond_to?(:skip_all=)
54+
check_object.skip_all = !!options[:skip_all]
55+
elsif options[:skip_all]
56+
raise ArgumentError, "skip_all requires a check that supports skip_all="
57+
end
58+
59+
collection = find_collection(collection_name)
60+
collection.register(check_name, check_object)
4461
end
4562

4663
# Public: Remove the check of the given name being checked

‎spec/ok_computer/check_collection_spec.rb‎

Lines changed: 61 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,12 @@
22

33
module OkComputer
44
describe CheckCollection do
5-
let(:foocheck) { double(:check) }
6-
let(:barcheck) { double(:check) }
5+
let(:foocheck) { Check.new }
6+
let(:barcheck) { Check.new }
77
let(:registry) { {foo: foocheck, bar: barcheck} }
88

9-
before do
10-
allow(foocheck).to receive(:registrant_name=)
11-
allow(barcheck).to receive(:registrant_name=)
12-
end
13-
149
subject { CheckCollection.new("foo collection name") }
10+
let(:default_collection) { CheckCollection.new("foo collection name", true) }
1511

1612
context ".new" do
1713
it "sets the display name of the check collection" do
@@ -33,6 +29,15 @@ module OkComputer
3329
expect(barcheck).to receive(:run)
3430
subject.run
3531
end
32+
33+
it "does not run checks registered with skip_all" do
34+
foocheck.skip_all = true
35+
default_collection.register(:foo, foocheck)
36+
default_collection.register(:bar, barcheck)
37+
expect(foocheck).not_to receive(:run)
38+
expect(barcheck).to receive(:run)
39+
default_collection.run
40+
end
3641
end
3742
end
3843
end
@@ -43,6 +48,19 @@ module OkComputer
4348
subject.register(:bar, barcheck)
4449
expect(subject.checks).to eq(registry.values)
4550
end
51+
52+
it "omits checks registered with skip_all" do
53+
foocheck.skip_all = true
54+
default_collection.register(:foo, foocheck)
55+
default_collection.register(:bar, barcheck)
56+
expect(default_collection.checks).to eq([barcheck])
57+
end
58+
59+
it "does not omit skipped checks from a named collection" do
60+
foocheck.skip_all = true
61+
subject.register(:foo, foocheck)
62+
expect(subject.checks).to eq([foocheck])
63+
end
4664
end
4765

4866
context "#register" do
@@ -67,6 +85,12 @@ module OkComputer
6785
expect(subject.fetch(:foo)).to eq(foocheck)
6886
end
6987

88+
it "finds checks registered with skip_all" do
89+
foocheck.skip_all = true
90+
subject.register(:foo, foocheck)
91+
expect(subject.fetch(:foo)).to eq(foocheck)
92+
end
93+
7094
it "finds checks in a sub_collection" do
7195
sub_collection = CheckCollection.new("sub")
7296
subject.register("sub", sub_collection)
@@ -121,7 +145,17 @@ module OkComputer
121145
subject.register(:bar, barcheck)
122146
allow(foocheck).to receive(:to_text) { "foo" }
123147
allow(barcheck).to receive(:to_text) { "bar" }
124-
expect(subject.to_text).to eq("foo collection name\n\s\sfoo\n\s\sbar")
148+
expect(subject.to_text).to eq("foo collection name\n\s\sbar\n\s\sfoo")
149+
end
150+
151+
it "omits checks registered with skip_all" do
152+
foocheck.skip_all = true
153+
default_collection.register(:foo, foocheck)
154+
default_collection.register(:bar, barcheck)
155+
allow(foocheck).to receive(:to_text) { "foo" }
156+
allow(barcheck).to receive(:to_text) { "bar" }
157+
expect(foocheck).not_to receive(:to_text)
158+
expect(default_collection.to_text).to eq("foo collection name\n\s\sbar")
125159
end
126160
end
127161

@@ -134,6 +168,16 @@ module OkComputer
134168
combined_hash = JSON.parse(foocheck.to_json).merge(JSON.parse(barcheck.to_json))
135169
expect(subject.to_json).to eq(combined_hash.to_json)
136170
end
171+
172+
it "omits checks registered with skip_all" do
173+
foocheck.skip_all = true
174+
default_collection.register(:foo, foocheck)
175+
default_collection.register(:bar, barcheck)
176+
allow(foocheck).to receive(:to_json) { {"foo" => "foo result"}.to_json }
177+
allow(barcheck).to receive(:to_json) { {"bar" => "bar result"}.to_json }
178+
expect(foocheck).not_to receive(:to_json)
179+
expect(default_collection.to_json).to eq({"bar" => "bar result"}.to_json)
180+
end
137181
end
138182

139183
context "#success?" do
@@ -152,6 +196,15 @@ module OkComputer
152196
allow(barcheck).to receive(:success?) { false }
153197
expect(subject).not_to be_success
154198
end
199+
200+
it "ignores failures from checks registered with skip_all" do
201+
foocheck.skip_all = true
202+
default_collection.register(:foo, foocheck)
203+
default_collection.register(:bar, barcheck)
204+
allow(barcheck).to receive(:success?) { true }
205+
expect(foocheck).not_to receive(:success?)
206+
expect(default_collection).to be_success
207+
end
155208
end
156209
end
157210
end

‎spec/ok_computer/registry_spec.rb‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,20 @@ module OkComputer
6262
Registry.register(check_name, check_object)
6363
end
6464

65+
it "keeps a check fetchable when skip_all is true" do
66+
skipped_check = Check.new
67+
Registry.register(check_name, skipped_check, skip_all: true)
68+
expect(Registry.fetch(check_name)).to eq(skipped_check)
69+
expect(Registry.all.checks).not_to include(skipped_check)
70+
end
71+
72+
it "includes a skipped check when it is registered again without skip_all" do
73+
skipped_check = Check.new
74+
Registry.register(check_name, skipped_check, skip_all: true)
75+
Registry.register(check_name, skipped_check)
76+
expect(Registry.all.checks).to include(skipped_check)
77+
end
78+
6579
it "throws a collection not found error if a collection with the given name is not found" do
6680
expect { Registry.register(check_name, check_object, "missing collection") }.to raise_error(Registry::CollectionNotFound)
6781
end
@@ -73,6 +87,23 @@ module OkComputer
7387
expect(collection.fetch(check_name)).to eq(check_object)
7488
end
7589

90+
it "can omit a check collection and its checks from all" do
91+
collection = CheckCollection.new('Versions')
92+
Registry.register('versions', collection, skip_all: true)
93+
Registry.register(check_name, check_object, 'versions')
94+
95+
expect(Registry.fetch('versions')).to eq(collection)
96+
expect(Registry.fetch(check_name)).to eq(check_object)
97+
expect(Registry.all.checks).not_to include(collection)
98+
end
99+
100+
it "rejects skip_all when registering inside a check collection" do
101+
Registry.register('test_collection', collection)
102+
expect {
103+
Registry.register(check_name, check_object, 'test_collection', skip_all: true)
104+
}.to raise_error(ArgumentError, /default collection/)
105+
end
106+
76107
it "gracefully handles checks defined with a combination of strings and symbols as their name" do
77108
Registry.register("foo", Check.new)
78109
Registry.register(:bar, Check.new)

0 commit comments

Comments
 (0)