stoplight 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -107
- data/LICENSE.md +1 -1
- data/README.md +51 -11
- data/lib/stoplight/default.rb +4 -2
- data/lib/stoplight/light.rb +17 -5
- data/lib/stoplight/light/runnable.rb +11 -3
- data/lib/stoplight/notifier/bugsnag.rb +1 -1
- data/lib/stoplight/version.rb +1 -1
- data/spec/stoplight/default_spec.rb +19 -5
- data/spec/stoplight/light/runnable_spec.rb +74 -5
- data/spec/stoplight/light_spec.rb +36 -8
- data/spec/stoplight/notifier/bugsnag_spec.rb +6 -3
- data/spec/stoplight/notifier/hip_chat_spec.rb +8 -1
- data/spec/stoplight/notifier/honeybadger_spec.rb +6 -1
- data/spec/stoplight/notifier/logger_spec.rb +2 -0
- data/spec/stoplight/notifier/slack_spec.rb +8 -1
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1129070df15d367423a8be3a21f9bd73bffc2c74
|
4
|
+
data.tar.gz: c98bfeffa3eddfac90367b7d6d15c308151eccd5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 52f6543a523f1598c604198831b854e4efa112868417385ec45ba6b628138ea5abc05be0b0a95ee8601e7f01680f8f31a47d66aeb2ead79f588e30b1868ae459
|
7
|
+
data.tar.gz: 9df784bc02e745c8dd770c3126a34c37c9b283d5c9712b71f4260e8ed49888a28c9c7b8aa19c5a2001d039d2a2fea51c66dc467e6c7212e4fc9d3d286a0ef65e
|
data/CHANGELOG.md
CHANGED
@@ -1,110 +1,7 @@
|
|
1
1
|
# Change log
|
2
2
|
|
3
|
-
Stoplight uses [Semantic Versioning][
|
3
|
+
Stoplight uses [Semantic Versioning][].
|
4
|
+
The change log is available [on GitHub][].
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
- #78: Added a Bugsnag notifier. Thanks, @bolshakov!
|
8
|
-
- Added a Honeybadger notifier.
|
9
|
-
- #77: Added a logger notifier. Thanks again, @bolshakov!
|
10
|
-
|
11
|
-
## v1.1.1 (2015-07-16)
|
12
|
-
|
13
|
-
- Introduced a generic notifier to reduce duplication between the IO and Slack
|
14
|
-
notifiers.
|
15
|
-
|
16
|
-
## v1.1.0 (2015-07-04)
|
17
|
-
|
18
|
-
- #71: Added Slack notifier. Thanks, @s1mplex!
|
19
|
-
|
20
|
-
## v1.0.0 (2015-02-19)
|
21
|
-
|
22
|
-
- Didn't change anything.
|
23
|
-
|
24
|
-
## v0.5.2 (2015-02-13)
|
25
|
-
|
26
|
-
- Created a convenience function for creating stoplights.
|
27
|
-
- Created a `VERSION` constant.
|
28
|
-
- Added YARD type documentation for public methods.
|
29
|
-
|
30
|
-
## v0.5.1 (2014-11-19)
|
31
|
-
|
32
|
-
- Fixed a logic bug that incorrectly determined red lights to be yellow.
|
33
|
-
|
34
|
-
## v0.5.0 (2014-11-19)
|
35
|
-
|
36
|
-
- Data stores and notifiers can be configured on a per-stoplight basis. This
|
37
|
-
allows stoplights to use stoplights internally.
|
38
|
-
- Stoplights use stoplights internally to wrap calls to data stores and
|
39
|
-
notifiers. This means they gracefully handle either going down.
|
40
|
-
- Data stores only store failures and states. Also failures are stored in a ring
|
41
|
-
buffer. This drastically reduces the amount of data stored.
|
42
|
-
- Stoplights will use the fallback (if it's given) when they fail while they're
|
43
|
-
green. This means they won't re-raise exceptions if you provide a fallback.
|
44
|
-
- Stoplights pass the error to their notifiers when transitioning from green to
|
45
|
-
red.
|
46
|
-
|
47
|
-
## v0.4.1 (2014-10-03)
|
48
|
-
|
49
|
-
- Fixed a bug that caused green to red notifications to sometimes not be sent.
|
50
|
-
|
51
|
-
## v0.4.0 (2014-09-17)
|
52
|
-
|
53
|
-
- Made stoplights handle failing notifiers by logging the failure to standard
|
54
|
-
error.
|
55
|
-
- Made stoplights automatically fall back to a fresh in-memory data store if the
|
56
|
-
primary store is unavailable.
|
57
|
-
- Generalized `Stoplight::Notifier::StandardError` into
|
58
|
-
`Stoplight::Notifier::IO`.
|
59
|
-
- Changed notification format from a string to a lambda. It accepts the same
|
60
|
-
parameters that the format string accepted.
|
61
|
-
- Updated `Stoplight::Notifier::Base#notify` to accept three parameters (the
|
62
|
-
light, the before color, and the after color) instead of just one parameter
|
63
|
-
(the message).
|
64
|
-
- Prevented setting non-positive thresholds.
|
65
|
-
- Removed `Stoplight::Mixin`.
|
66
|
-
|
67
|
-
## v0.3.1 (2014-09-12)
|
68
|
-
|
69
|
-
- Replaced `Stoplight::Failure#error` with `#error_class` and `#error_message`.
|
70
|
-
Also changed the constructor to take the class and the message instead of the
|
71
|
-
error.
|
72
|
-
|
73
|
-
## v0.3.0 (2014-09-11)
|
74
|
-
|
75
|
-
- Allowed formatting notifications.
|
76
|
-
- Added automatic recovery from red lights.
|
77
|
-
- Added `Stoplight::DataStore#clear_stale` for clearing stale lights.
|
78
|
-
- Removed forwarded methods on `Stoplight` module.
|
79
|
-
- Moved some methods from `Stoplight::DataStore::Base` to
|
80
|
-
`Stoplight::DataStore`.
|
81
|
-
- Renamed `Stoplight::DataStore::Base#purge` to `#clear_stale`.
|
82
|
-
- Renamed `Stoplight::DataStore::Base#delete` to `#clear`.
|
83
|
-
- Prefixed data store getters with `get_`.
|
84
|
-
- Added `Stoplight::DataStore::Base#sync`.
|
85
|
-
- Changed `Stoplight::DataStore::Base#get_failures` to return actual failures
|
86
|
-
(`Stoplight::Failure`) instead of strings.
|
87
|
-
|
88
|
-
## v0.2.1 (2014-08-20)
|
89
|
-
|
90
|
-
- Forced times to be serialized as strings.
|
91
|
-
|
92
|
-
## v0.2.0 (2014-08-18)
|
93
|
-
|
94
|
-
- Switched `Stoplight.data_store` and `Stoplight.notifiers` over to using
|
95
|
-
simple accessors.
|
96
|
-
- Modified `Stoplight::DataStore::Redis` to accept an instance of `Redis`.
|
97
|
-
- Refactored `Stoplight::DataStore::Redis` to use fewer keys.
|
98
|
-
- Created `Stoplight::Notifier` and subclasses.
|
99
|
-
- Sent notifications when moving from green to red.
|
100
|
-
- Renamed `Stoplight::Light::DEFAULT_THRESHOLD` to
|
101
|
-
`Stoplight::DEFAULT_THRESHOLD`.
|
102
|
-
- Renamed `Stoplight::Error::NoFallback` to `Stoplight::Error::RedLight`.
|
103
|
-
- Created `Stoplight::Mixin#stoplight` for easily creating and running simple
|
104
|
-
stoplights.
|
105
|
-
|
106
|
-
## v0.1.0 (2014-08-12)
|
107
|
-
|
108
|
-
- Initial release.
|
109
|
-
|
110
|
-
[1]: http://semver.org/spec/v2.0.0.html
|
6
|
+
[semantic versioning]: http://semver.org/spec/v2.0.0.html
|
7
|
+
[on github]: https://github.com/orgsync/stoplight/releases
|
data/LICENSE.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
The MIT License (MIT)
|
2
2
|
|
3
|
-
Copyright (c) 2015 Cameron Desautels, Taylor Fausak & Justin Steffy
|
3
|
+
Copyright (c) 2015-2016 Cameron Desautels, Taylor Fausak & Justin Steffy
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
data/README.md
CHANGED
@@ -45,19 +45,19 @@ Check out [stoplight-admin][] for controlling your stoplights.
|
|
45
45
|
Add it to your Gemfile:
|
46
46
|
|
47
47
|
``` rb
|
48
|
-
gem 'stoplight'
|
48
|
+
gem 'stoplight'
|
49
49
|
```
|
50
50
|
|
51
51
|
Or install it manually:
|
52
52
|
|
53
53
|
``` sh
|
54
|
-
$ gem install stoplight
|
54
|
+
$ gem install stoplight
|
55
55
|
```
|
56
56
|
|
57
57
|
Stoplight uses [Semantic Versioning][]. Check out [the change log][] for a
|
58
58
|
detailed list of changes.
|
59
59
|
|
60
|
-
Stoplight works with all supported versions of Ruby (2.0 through 2.
|
60
|
+
Stoplight works with all supported versions of Ruby (2.0 through 2.3).
|
61
61
|
|
62
62
|
## Basic usage
|
63
63
|
|
@@ -119,13 +119,15 @@ a while. (The yellow state corresponds to the half open state for circuit
|
|
119
119
|
|
120
120
|
### Custom errors
|
121
121
|
|
122
|
+
##### Whitelisted errors
|
123
|
+
|
122
124
|
Some errors shouldn't cause your stoplight to move into the red state. Usually
|
123
125
|
these are handled elsewhere in your stack and don't represent real failures. A
|
124
126
|
good example is `ActiveRecord::RecordNotFound`.
|
125
127
|
|
126
128
|
``` rb
|
127
129
|
light = Stoplight('example-3') { User.find(123) }
|
128
|
-
.
|
130
|
+
.with_whitelisted_errors([ActiveRecord::RecordNotFound])
|
129
131
|
# => #<Stoplight::Light:...>
|
130
132
|
light.run
|
131
133
|
# ActiveRecord::RecordNotFound: Couldn't find User with ID=123
|
@@ -137,9 +139,47 @@ light.color
|
|
137
139
|
# => "green"
|
138
140
|
```
|
139
141
|
|
140
|
-
The following errors are always
|
142
|
+
The following errors are always whitelisted: `NoMemoryError`, `ScriptError`,
|
141
143
|
`SecurityError`, `SignalException`, `SystemExit`, and `SystemStackError`.
|
142
144
|
|
145
|
+
Whitelisted errors take precedence over [blacklisted errors](#blacklisted-errors).
|
146
|
+
|
147
|
+
##### Blacklisted errors
|
148
|
+
|
149
|
+
You may want only certain errors to cause your stoplight to move into the red
|
150
|
+
state.
|
151
|
+
|
152
|
+
``` rb
|
153
|
+
light = Stoplight('example-4') { 1 / 0 }
|
154
|
+
.with_blacklisted_errors([ZeroDivisionError])
|
155
|
+
# => #<Stoplight::Light:...>
|
156
|
+
light.run
|
157
|
+
# ZeroDivisionError: divided by 0
|
158
|
+
light.run
|
159
|
+
# ZeroDivisionError: divided by 0
|
160
|
+
light.run
|
161
|
+
# ZeroDivisionError: divided by 0
|
162
|
+
light.color
|
163
|
+
# => "red"
|
164
|
+
```
|
165
|
+
|
166
|
+
This will cause all other errors to be raised normally. They won't affect the
|
167
|
+
state of your stoplight.
|
168
|
+
|
169
|
+
``` rb
|
170
|
+
light = Stoplight('example-5') { fail }
|
171
|
+
.with_blacklisted_errors([ZeroDivisionError])
|
172
|
+
# => #<Stoplight::Light:...>
|
173
|
+
light.run
|
174
|
+
# RuntimeError:
|
175
|
+
light.run
|
176
|
+
# RuntimeError:
|
177
|
+
light.run
|
178
|
+
# RuntimeError:
|
179
|
+
light.color
|
180
|
+
# => "green"
|
181
|
+
```
|
182
|
+
|
143
183
|
### Custom fallback
|
144
184
|
|
145
185
|
By default, stoplights will re-raise errors when they're green. When they're
|
@@ -148,7 +188,7 @@ fallback that will be called in both of these cases. It will be passed the
|
|
148
188
|
error if the light was green.
|
149
189
|
|
150
190
|
``` rb
|
151
|
-
light = Stoplight('example-
|
191
|
+
light = Stoplight('example-6') { 1 / 0 }
|
152
192
|
.with_fallback { |e| p e; 'default' }
|
153
193
|
# => #<Stoplight::Light:..>
|
154
194
|
light.run
|
@@ -172,7 +212,7 @@ Some bits of code might be allowed to fail more or less frequently than others.
|
|
172
212
|
You can configure this by setting a custom threshold.
|
173
213
|
|
174
214
|
``` rb
|
175
|
-
light = Stoplight('example-
|
215
|
+
light = Stoplight('example-7') { fail }
|
176
216
|
.with_threshold(1)
|
177
217
|
# => #<Stoplight::Light:...>
|
178
218
|
light.run
|
@@ -191,7 +231,7 @@ time. A light in the red state for longer than the timeout will transition to
|
|
191
231
|
the yellow state. This timeout is customizable.
|
192
232
|
|
193
233
|
``` rb
|
194
|
-
light = Stoplight('example-
|
234
|
+
light = Stoplight('example-8') { fail }
|
195
235
|
.with_timeout(1)
|
196
236
|
# => #<Stoplight::Light:...>
|
197
237
|
light.run
|
@@ -227,7 +267,7 @@ class ApplicationController < ActionController::Base
|
|
227
267
|
|
228
268
|
def stoplight(&block)
|
229
269
|
Stoplight("#{params[:controller]}##{params[:action]}", &block)
|
230
|
-
.
|
270
|
+
.with_whitelisted_errors([ActiveRecord::RecordNotFound])
|
231
271
|
.with_fallback do |error|
|
232
272
|
Rails.logger.error(error)
|
233
273
|
render(nothing: true, status: :service_unavailable)
|
@@ -379,7 +419,7 @@ override the default behavior. You can lock a light in either the green or red
|
|
379
419
|
state using `set_state`.
|
380
420
|
|
381
421
|
``` rb
|
382
|
-
light = Stoplight('example-
|
422
|
+
light = Stoplight('example-9') { true }
|
383
423
|
# => #<Stoplight::Light:..>
|
384
424
|
light.run
|
385
425
|
# => true
|
@@ -418,7 +458,7 @@ give each test case a fresh data store with RSpec.
|
|
418
458
|
|
419
459
|
``` rb
|
420
460
|
before(:each) do
|
421
|
-
Stoplight::Light.
|
461
|
+
Stoplight::Light.default_data_store = Stoplight::DataStore::Memory.new
|
422
462
|
end
|
423
463
|
```
|
424
464
|
|
data/lib/stoplight/default.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Stoplight
|
4
4
|
module Default
|
5
|
-
|
5
|
+
WHITELISTED_ERRORS = [
|
6
6
|
NoMemoryError,
|
7
7
|
ScriptError,
|
8
8
|
SecurityError,
|
@@ -11,9 +11,11 @@ module Stoplight
|
|
11
11
|
SystemStackError
|
12
12
|
].freeze
|
13
13
|
|
14
|
+
BLACKLISTED_ERRORS = [].freeze
|
15
|
+
|
14
16
|
DATA_STORE = DataStore::Memory.new
|
15
17
|
|
16
|
-
ERROR_NOTIFIER = -> error { warn error }
|
18
|
+
ERROR_NOTIFIER = -> (error) { warn error }
|
17
19
|
|
18
20
|
FALLBACK = nil
|
19
21
|
|
data/lib/stoplight/light.rb
CHANGED
@@ -5,7 +5,9 @@ module Stoplight
|
|
5
5
|
include Runnable
|
6
6
|
|
7
7
|
# @return [Array<Exception>]
|
8
|
-
attr_reader :
|
8
|
+
attr_reader :whitelisted_errors
|
9
|
+
# @return [Array<Exception>]
|
10
|
+
attr_reader :blacklisted_errors
|
9
11
|
# @return [Proc]
|
10
12
|
attr_reader :code
|
11
13
|
# @return [DataStore::Base]
|
@@ -42,7 +44,8 @@ module Stoplight
|
|
42
44
|
@name = name
|
43
45
|
@code = code
|
44
46
|
|
45
|
-
@
|
47
|
+
@whitelisted_errors = Default::WHITELISTED_ERRORS
|
48
|
+
@blacklisted_errors = Default::BLACKLISTED_ERRORS
|
46
49
|
@data_store = self.class.default_data_store
|
47
50
|
@error_notifier = self.class.default_error_notifier
|
48
51
|
@fallback = Default::FALLBACK
|
@@ -51,10 +54,19 @@ module Stoplight
|
|
51
54
|
@timeout = Default::TIMEOUT
|
52
55
|
end
|
53
56
|
|
54
|
-
# @param
|
57
|
+
# @param whitelisted_errors [Array<Exception>]
|
58
|
+
# @return [self]
|
59
|
+
def with_whitelisted_errors(whitelisted_errors)
|
60
|
+
@whitelisted_errors = Default::WHITELISTED_ERRORS + whitelisted_errors
|
61
|
+
self
|
62
|
+
end
|
63
|
+
|
64
|
+
alias with_allowed_errors with_whitelisted_errors
|
65
|
+
|
66
|
+
# @param blacklisted_errors [Array<Exception>]
|
55
67
|
# @return [self]
|
56
|
-
def
|
57
|
-
@
|
68
|
+
def with_blacklisted_errors(blacklisted_errors)
|
69
|
+
@blacklisted_errors = Default::BLACKLISTED_ERRORS + blacklisted_errors
|
58
70
|
self
|
59
71
|
end
|
60
72
|
|
@@ -56,8 +56,14 @@ module Stoplight
|
|
56
56
|
handle_error(error, on_failure)
|
57
57
|
end
|
58
58
|
|
59
|
+
def not_blacklisted_error?(error)
|
60
|
+
blacklisted_errors.length > 0 &&
|
61
|
+
blacklisted_errors.none? { |klass| error.is_a?(klass) }
|
62
|
+
end
|
63
|
+
|
59
64
|
def handle_error(error, on_failure)
|
60
|
-
fail error if
|
65
|
+
fail error if whitelisted_errors.any? { |klass| error.is_a?(klass) }
|
66
|
+
fail error if not_blacklisted_error?(error)
|
61
67
|
size = record_failure(error)
|
62
68
|
on_failure.call(size, error) if on_failure
|
63
69
|
fail error unless fallback
|
@@ -84,9 +90,11 @@ module Stoplight
|
|
84
90
|
end
|
85
91
|
|
86
92
|
def safely(default = nil, &code)
|
87
|
-
return
|
93
|
+
return yield if data_store == Default::DATA_STORE
|
88
94
|
|
89
|
-
self
|
95
|
+
self
|
96
|
+
.class
|
97
|
+
.new("#{name}-safely", &code)
|
90
98
|
.with_data_store(Default::DATA_STORE)
|
91
99
|
.with_fallback do |error|
|
92
100
|
error_notifier.call(error) if error
|
data/lib/stoplight/version.rb
CHANGED
@@ -7,19 +7,33 @@ RSpec.describe Stoplight::Default do
|
|
7
7
|
expect(described_class).to be_a(Module)
|
8
8
|
end
|
9
9
|
|
10
|
-
describe '::
|
10
|
+
describe '::WHITELISTED_ERRORS' do
|
11
11
|
it 'is an array' do
|
12
|
-
expect(Stoplight::Default::
|
12
|
+
expect(Stoplight::Default::WHITELISTED_ERRORS).to be_an(Array)
|
13
13
|
end
|
14
14
|
|
15
15
|
it 'contains exception classes' do
|
16
|
-
Stoplight::Default::
|
17
|
-
expect(
|
16
|
+
Stoplight::Default::WHITELISTED_ERRORS.each do |whitelisted_error|
|
17
|
+
expect(whitelisted_error).to be < Exception
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
21
|
it 'is frozen' do
|
22
|
-
expect(Stoplight::Default::
|
22
|
+
expect(Stoplight::Default::WHITELISTED_ERRORS).to be_frozen
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '::BLACKLISTED_ERRORS' do
|
27
|
+
it 'is an array' do
|
28
|
+
expect(Stoplight::Default::BLACKLISTED_ERRORS).to be_an(Array)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'is empty' do
|
32
|
+
expect(Stoplight::Default::BLACKLISTED_ERRORS).to be_empty
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'is frozen' do
|
36
|
+
expect(Stoplight::Default::BLACKLISTED_ERRORS).to be_frozen
|
23
37
|
end
|
24
38
|
end
|
25
39
|
|
@@ -8,7 +8,7 @@ RSpec.describe Stoplight::Light::Runnable do
|
|
8
8
|
|
9
9
|
let(:code) { -> { code_result } }
|
10
10
|
let(:code_result) { random_string }
|
11
|
-
let(:fallback) { -> _ { fallback_result } }
|
11
|
+
let(:fallback) { -> (_) { fallback_result } }
|
12
12
|
let(:fallback_result) { random_string }
|
13
13
|
let(:name) { random_string }
|
14
14
|
|
@@ -119,10 +119,79 @@ RSpec.describe Stoplight::Light::Runnable do
|
|
119
119
|
expect(io.string).to_not eql('')
|
120
120
|
end
|
121
121
|
|
122
|
-
context 'when the error is
|
123
|
-
let(:
|
122
|
+
context 'when the error is whitelisted' do
|
123
|
+
let(:whitelisted_errors) { [error.class] }
|
124
124
|
|
125
|
-
before { subject.
|
125
|
+
before { subject.with_whitelisted_errors(whitelisted_errors) }
|
126
|
+
|
127
|
+
it 'does not record the failure' do
|
128
|
+
expect(subject.data_store.get_failures(subject).size).to eql(0)
|
129
|
+
begin
|
130
|
+
subject.run
|
131
|
+
rescue error.class
|
132
|
+
nil
|
133
|
+
end
|
134
|
+
expect(subject.data_store.get_failures(subject).size).to eql(0)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
context 'when the error is blacklisted' do
|
139
|
+
let(:blacklisted_errors) { [error.class] }
|
140
|
+
|
141
|
+
before { subject.with_blacklisted_errors(blacklisted_errors) }
|
142
|
+
|
143
|
+
it 'records the failure' do
|
144
|
+
expect(subject.data_store.get_failures(subject).size).to eql(0)
|
145
|
+
begin
|
146
|
+
subject.run
|
147
|
+
rescue error.class
|
148
|
+
nil
|
149
|
+
end
|
150
|
+
expect(subject.data_store.get_failures(subject).size).to eql(1)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
context 'when the error is not blacklisted' do
|
155
|
+
let(:blacklisted_errors) { [RuntimeError] }
|
156
|
+
|
157
|
+
before { subject.with_blacklisted_errors(blacklisted_errors) }
|
158
|
+
|
159
|
+
it 'does not record the failure' do
|
160
|
+
expect(subject.data_store.get_failures(subject).size).to eql(0)
|
161
|
+
begin
|
162
|
+
subject.run
|
163
|
+
rescue error.class
|
164
|
+
nil
|
165
|
+
end
|
166
|
+
expect(subject.data_store.get_failures(subject).size).to eql(0)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
context 'when the list of blacklisted errors is empty' do
|
171
|
+
let(:blacklisted_errors) { [] }
|
172
|
+
|
173
|
+
before { subject.with_blacklisted_errors(blacklisted_errors) }
|
174
|
+
|
175
|
+
it 'records the failure' do
|
176
|
+
expect(subject.data_store.get_failures(subject).size).to eql(0)
|
177
|
+
begin
|
178
|
+
subject.run
|
179
|
+
rescue error.class
|
180
|
+
nil
|
181
|
+
end
|
182
|
+
expect(subject.data_store.get_failures(subject).size).to eql(1)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
context 'when the error is both whitelisted and blacklisted' do
|
187
|
+
let(:whitelisted_errors) { [error.class] }
|
188
|
+
let(:blacklisted_errors) { [error.class] }
|
189
|
+
|
190
|
+
before do
|
191
|
+
subject
|
192
|
+
.with_whitelisted_errors(whitelisted_errors)
|
193
|
+
.with_blacklisted_errors(blacklisted_errors)
|
194
|
+
end
|
126
195
|
|
127
196
|
it 'does not record the failure' do
|
128
197
|
expect(subject.data_store.get_failures(subject).size).to eql(0)
|
@@ -154,7 +223,7 @@ RSpec.describe Stoplight::Light::Runnable do
|
|
154
223
|
|
155
224
|
context 'when the data store is failing' do
|
156
225
|
let(:data_store) { Object.new }
|
157
|
-
let(:error_notifier) { -> _ {} }
|
226
|
+
let(:error_notifier) { -> (_) {} }
|
158
227
|
|
159
228
|
before do
|
160
229
|
subject
|
@@ -42,7 +42,7 @@ RSpec.describe Stoplight::Light do
|
|
42
42
|
after { described_class.default_error_notifier = @default_error_notifier }
|
43
43
|
|
44
44
|
it 'sets the error notifier' do
|
45
|
-
default_error_notifier = -> _ {}
|
45
|
+
default_error_notifier = -> (_) {}
|
46
46
|
described_class.default_error_notifier = default_error_notifier
|
47
47
|
expect(described_class.default_error_notifier)
|
48
48
|
.to eql(default_error_notifier)
|
@@ -67,9 +67,19 @@ RSpec.describe Stoplight::Light do
|
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
|
-
describe '#
|
70
|
+
describe '#whitelisted_errors' do
|
71
71
|
it 'is initially the default' do
|
72
|
-
expect(light.
|
72
|
+
expect(light.whitelisted_errors).to eql(
|
73
|
+
Stoplight::Default::WHITELISTED_ERRORS
|
74
|
+
)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe '#blacklisted_errors' do
|
79
|
+
it 'is initially the default' do
|
80
|
+
expect(light.blacklisted_errors).to eql(
|
81
|
+
Stoplight::Default::BLACKLISTED_ERRORS
|
82
|
+
)
|
73
83
|
end
|
74
84
|
end
|
75
85
|
|
@@ -122,12 +132,30 @@ RSpec.describe Stoplight::Light do
|
|
122
132
|
end
|
123
133
|
end
|
124
134
|
|
135
|
+
describe '#with_whitelisted_errors' do
|
136
|
+
it 'adds the whitelisted errors to the default' do
|
137
|
+
whitelisted_errors = [StandardError]
|
138
|
+
light.with_whitelisted_errors(whitelisted_errors)
|
139
|
+
expect(light.whitelisted_errors)
|
140
|
+
.to eql(Stoplight::Default::WHITELISTED_ERRORS + whitelisted_errors)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
125
144
|
describe '#with_allowed_errors' do
|
126
|
-
it '
|
145
|
+
it 'sets whitelisted_errors' do
|
127
146
|
allowed_errors = [StandardError]
|
128
147
|
light.with_allowed_errors(allowed_errors)
|
129
|
-
expect(light.
|
130
|
-
.to eql(Stoplight::Default::
|
148
|
+
expect(light.whitelisted_errors)
|
149
|
+
.to eql(Stoplight::Default::WHITELISTED_ERRORS + allowed_errors)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
describe '#with_blacklisted_errors' do
|
154
|
+
it 'adds the blacklisted errors to the default' do
|
155
|
+
blacklisted_errors = [StandardError]
|
156
|
+
light.with_blacklisted_errors(blacklisted_errors)
|
157
|
+
expect(light.blacklisted_errors)
|
158
|
+
.to eql(Stoplight::Default::BLACKLISTED_ERRORS + blacklisted_errors)
|
131
159
|
end
|
132
160
|
end
|
133
161
|
|
@@ -141,7 +169,7 @@ RSpec.describe Stoplight::Light do
|
|
141
169
|
|
142
170
|
describe '#with_error_notifier' do
|
143
171
|
it 'sets the error notifier' do
|
144
|
-
error_notifier = -> _ {}
|
172
|
+
error_notifier = -> (_) {}
|
145
173
|
light.with_error_notifier(&error_notifier)
|
146
174
|
expect(light.error_notifier).to eql(error_notifier)
|
147
175
|
end
|
@@ -149,7 +177,7 @@ RSpec.describe Stoplight::Light do
|
|
149
177
|
|
150
178
|
describe '#with_fallback' do
|
151
179
|
it 'sets the fallback' do
|
152
|
-
fallback = -> _ {}
|
180
|
+
fallback = -> (_) {}
|
153
181
|
light.with_fallback(&fallback)
|
154
182
|
expect(light.fallback).to eql(fallback)
|
155
183
|
end
|
@@ -1,7 +1,10 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
|
-
|
4
|
+
|
5
|
+
# require 'bugsnag'
|
6
|
+
module Bugsnag
|
7
|
+
end
|
5
8
|
|
6
9
|
RSpec.describe Stoplight::Notifier::Bugsnag do
|
7
10
|
StoplightStatusChange = Stoplight::Notifier::Bugsnag::StoplightStatusChange
|
@@ -42,7 +45,7 @@ RSpec.describe Stoplight::Notifier::Bugsnag do
|
|
42
45
|
|
43
46
|
describe '#bugsnag' do
|
44
47
|
it 'reads the Bugsnag client' do
|
45
|
-
client =
|
48
|
+
client = Bugsnag
|
46
49
|
expect(described_class.new(client, nil).bugsnag)
|
47
50
|
.to eql(client)
|
48
51
|
end
|
@@ -55,7 +58,7 @@ RSpec.describe Stoplight::Notifier::Bugsnag do
|
|
55
58
|
let(:from_color) { Stoplight::Color::GREEN }
|
56
59
|
let(:to_color) { Stoplight::Color::RED }
|
57
60
|
let(:notifier) { described_class.new(bugsnag) }
|
58
|
-
let(:bugsnag) {
|
61
|
+
let(:bugsnag) { Bugsnag }
|
59
62
|
|
60
63
|
subject(:result) do
|
61
64
|
notifier.notify(light, from_color, to_color, error)
|
@@ -1,7 +1,14 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
|
-
|
4
|
+
|
5
|
+
# require 'slack-notifier'
|
6
|
+
module Slack
|
7
|
+
class Notifier
|
8
|
+
def initialize(*)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
5
12
|
|
6
13
|
RSpec.describe Stoplight::Notifier::Slack do
|
7
14
|
it_behaves_like 'a generic notifier'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stoplight
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cameron Desautels
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2016-01-28 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: benchmark-ips
|
@@ -32,14 +32,14 @@ dependencies:
|
|
32
32
|
requirements:
|
33
33
|
- - "~>"
|
34
34
|
- !ruby/object:Gem::Version
|
35
|
-
version: '
|
35
|
+
version: '3.0'
|
36
36
|
type: :development
|
37
37
|
prerelease: false
|
38
38
|
version_requirements: !ruby/object:Gem::Requirement
|
39
39
|
requirements:
|
40
40
|
- - "~>"
|
41
41
|
- !ruby/object:Gem::Version
|
42
|
-
version: '
|
42
|
+
version: '3.0'
|
43
43
|
- !ruby/object:Gem::Dependency
|
44
44
|
name: coveralls
|
45
45
|
requirement: !ruby/object:Gem::Requirement
|
@@ -186,14 +186,14 @@ dependencies:
|
|
186
186
|
requirements:
|
187
187
|
- - "~>"
|
188
188
|
- !ruby/object:Gem::Version
|
189
|
-
version:
|
189
|
+
version: 0.36.0
|
190
190
|
type: :development
|
191
191
|
prerelease: false
|
192
192
|
version_requirements: !ruby/object:Gem::Requirement
|
193
193
|
requirements:
|
194
194
|
- - "~>"
|
195
195
|
- !ruby/object:Gem::Version
|
196
|
-
version:
|
196
|
+
version: 0.36.0
|
197
197
|
- !ruby/object:Gem::Dependency
|
198
198
|
name: slack-notifier
|
199
199
|
requirement: !ruby/object:Gem::Requirement
|
@@ -305,7 +305,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
305
305
|
requirements:
|
306
306
|
- - ">="
|
307
307
|
- !ruby/object:Gem::Version
|
308
|
-
version:
|
308
|
+
version: '2'
|
309
309
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
310
310
|
requirements:
|
311
311
|
- - ">="
|