stoplight 2.1.3 → 3.0.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.
- checksums.yaml +5 -5
- data/README.md +48 -16
- data/lib/stoplight/color.rb +4 -4
- data/lib/stoplight/data_store/base.rb +1 -1
- data/lib/stoplight/data_store/memory.rb +1 -1
- data/lib/stoplight/data_store/redis.rb +23 -25
- data/lib/stoplight/data_store.rb +1 -1
- data/lib/stoplight/default.rb +3 -3
- data/lib/stoplight/error.rb +1 -1
- data/lib/stoplight/failure.rb +11 -7
- data/lib/stoplight/light/runnable.rb +7 -5
- data/lib/stoplight/light.rb +1 -1
- data/lib/stoplight/notifier/base.rb +1 -1
- data/lib/stoplight/notifier/bugsnag.rb +1 -1
- data/lib/stoplight/notifier/generic.rb +1 -1
- data/lib/stoplight/notifier/hip_chat.rb +1 -1
- data/lib/stoplight/notifier/honeybadger.rb +2 -2
- data/lib/stoplight/notifier/io.rb +1 -1
- data/lib/stoplight/notifier/logger.rb +1 -1
- data/lib/stoplight/notifier/pagerduty.rb +21 -0
- data/lib/stoplight/notifier/raven.rb +2 -2
- data/lib/stoplight/notifier/rollbar.rb +39 -0
- data/lib/stoplight/notifier/slack.rb +1 -1
- data/lib/stoplight/notifier.rb +1 -1
- data/lib/stoplight/state.rb +4 -4
- data/lib/stoplight/version.rb +2 -2
- data/lib/stoplight.rb +3 -1
- data/spec/spec_helper.rb +2 -3
- data/spec/stoplight/color_spec.rb +1 -1
- data/spec/stoplight/data_store/base_spec.rb +1 -1
- data/spec/stoplight/data_store/memory_spec.rb +1 -1
- data/spec/stoplight/data_store/redis_spec.rb +1 -1
- data/spec/stoplight/data_store_spec.rb +1 -1
- data/spec/stoplight/default_spec.rb +2 -2
- data/spec/stoplight/error_spec.rb +1 -1
- data/spec/stoplight/failure_spec.rb +6 -1
- data/spec/stoplight/light/runnable_spec.rb +7 -9
- data/spec/stoplight/light_spec.rb +5 -5
- data/spec/stoplight/notifier/base_spec.rb +1 -1
- data/spec/stoplight/notifier/bugsnag_spec.rb +2 -4
- data/spec/stoplight/notifier/generic_spec.rb +1 -1
- data/spec/stoplight/notifier/hip_chat_spec.rb +2 -3
- data/spec/stoplight/notifier/honeybadger_spec.rb +1 -1
- data/spec/stoplight/notifier/io_spec.rb +1 -1
- data/spec/stoplight/notifier/logger_spec.rb +1 -1
- data/spec/stoplight/notifier/pagerduty_spec.rb +40 -0
- data/spec/stoplight/notifier/raven_spec.rb +1 -1
- data/spec/stoplight/notifier/rollbar_spec.rb +90 -0
- data/spec/stoplight/notifier/slack_spec.rb +2 -3
- data/spec/stoplight/notifier_spec.rb +1 -1
- data/spec/stoplight/state_spec.rb +1 -1
- data/spec/stoplight/version_spec.rb +1 -1
- data/spec/stoplight_spec.rb +1 -1
- metadata +80 -47
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 2f7c163955f261ad3eeca89a851a06a15f5734d78d045695297f29c143532a58
|
4
|
+
data.tar.gz: 9ff3e5911bf7e9f198c714ce1eb0f10c6ba09834e96a8c8c2d16dd3e184ed0ce
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5e42cd0050cdbf9440e80d68d70091e6c22c574c64cf06a29aa9dca320f5f4915dca48e5582ebf18db757fde4ad295c20af05bc6a879695d726afa65ff50dea8
|
7
|
+
data.tar.gz: a5088d9ba81a5578cbc078d0671c601fd13738f07f6a67dd12936df3e8a7927053314538d50c1e65ce6913607e9764ff09d6c05f931c4be8984e2e6744399288
|
data/README.md
CHANGED
@@ -4,7 +4,6 @@
|
|
4
4
|
[![Build badge][]][build]
|
5
5
|
[![Coverage badge][]][coverage]
|
6
6
|
[![Climate badge][]][climate]
|
7
|
-
[![Dependencies badge][]][dependencies]
|
8
7
|
|
9
8
|
Stoplight is traffic control for code. It's an implementation of the circuit
|
10
9
|
breaker pattern in Ruby.
|
@@ -32,6 +31,8 @@ Check out [stoplight-admin][] for controlling your stoplights.
|
|
32
31
|
- [HipChat](#hipchat)
|
33
32
|
- [Honeybadger](#honeybadger)
|
34
33
|
- [Logger](#logger)
|
34
|
+
- [Pagerduty](#pagerduty)
|
35
|
+
- [Rollbar](#rollbar)
|
35
36
|
- [Sentry](#sentry)
|
36
37
|
- [Slack](#slack)
|
37
38
|
- [Rails](#rails-1)
|
@@ -204,7 +205,7 @@ The default threshold is `3`.
|
|
204
205
|
### Custom cool off time
|
205
206
|
|
206
207
|
Stoplights will automatically attempt to recover after a certain amount of
|
207
|
-
time. A light in the red state for longer than the cool
|
208
|
+
time. A light in the red state for longer than the cool off period will
|
208
209
|
transition to the yellow state. This cool off time is customizable.
|
209
210
|
|
210
211
|
``` rb
|
@@ -356,6 +357,36 @@ Stoplight::Light.default_notifiers += [notifier]
|
|
356
357
|
# => [#<Stoplight::Notifier::IO:...>, #<Stoplight::Notifier::Logger:...>]
|
357
358
|
```
|
358
359
|
|
360
|
+
#### Pagerduty
|
361
|
+
|
362
|
+
Make sure you have [the Pagerduty gem][] (`~> 2.1`) installed before configuring
|
363
|
+
Stoplight.
|
364
|
+
|
365
|
+
``` rb
|
366
|
+
require 'pagerduty'
|
367
|
+
# => true
|
368
|
+
pagerduty = Pagerduty.new('http://www.example.com/webhook-url')
|
369
|
+
# => #<Pagerduty:...>
|
370
|
+
notifier = Stoplight::Notifier::Pagerduty.new(pagerduty)
|
371
|
+
# => #<Stoplight::Notifier::Pagerduty:...>
|
372
|
+
Stoplight::Light.default_notifiers += [notifier]
|
373
|
+
# => [#<Stoplight::Notifier::IO:...>, #<Stoplight::Notifier::Pagerduty:...>]
|
374
|
+
```
|
375
|
+
|
376
|
+
#### Rollbar
|
377
|
+
|
378
|
+
Make sure you have [the Rollbar gem][] (`~> 2.0`) installed before configuring
|
379
|
+
Stoplight.
|
380
|
+
|
381
|
+
``` rb
|
382
|
+
require 'rollbar'
|
383
|
+
# => true
|
384
|
+
notifier = Stoplight::Notifier::Rollbar.new(Rollbar)
|
385
|
+
# => #<Stoplight::Notifier::Rollbar:...>
|
386
|
+
Stoplight::Light.default_notifiers += [notifier]
|
387
|
+
# => [#<Stoplight::Notifier::IO:...>, #<Stoplight::Notifier::Rollbar:...>]
|
388
|
+
```
|
389
|
+
|
359
390
|
#### Sentry
|
360
391
|
|
361
392
|
Make sure you have [the Sentry gem][] (`~> 1.2`) installed before configuring
|
@@ -463,24 +494,22 @@ stoplight = Stoplight("test-#{rand}") { ... }
|
|
463
494
|
|
464
495
|
## Credits
|
465
496
|
|
466
|
-
Stoplight is brought to you by [@camdez][] and [@tfausak][] from [@OrgSync][].
|
467
|
-
A [complete list of contributors][] is available on GitHub. We were inspired by
|
468
|
-
Martin Fowler's [CircuitBreaker][] article.
|
497
|
+
Stoplight is brought to you by [@camdez][] and [@tfausak][] from [@OrgSync][]. [@bolshakov][] is the current
|
498
|
+
maintainer of the gem. A [complete list of contributors][] is available on GitHub. We were inspired by
|
499
|
+
Martin Fowler's [CircuitBreaker][] article.
|
469
500
|
|
470
501
|
Stoplight is licensed under [the MIT License][].
|
471
502
|
|
472
|
-
[Stoplight]: https://github.com/
|
503
|
+
[Stoplight]: https://github.com/bolshakov/stoplight
|
473
504
|
[Version badge]: https://img.shields.io/gem/v/stoplight.svg?label=version
|
474
505
|
[version]: https://rubygems.org/gems/stoplight
|
475
|
-
[Build badge]: https://
|
476
|
-
[build]: https://
|
477
|
-
[Coverage badge]: https://img.shields.io/coveralls/
|
478
|
-
[coverage]: https://coveralls.io/r/
|
479
|
-
[Climate badge]: https://
|
480
|
-
[climate]: https://codeclimate.com/github/
|
481
|
-
[
|
482
|
-
[dependencies]: https://gemnasium.com/orgsync/stoplight
|
483
|
-
[stoplight-admin]: https://github.com/orgsync/stoplight-admin
|
506
|
+
[Build badge]: https://github.com/bolshakov/stoplight/workflows/Specs/badge.svg
|
507
|
+
[build]: https://github.com/bolshakov/stoplight/actions?query=branch%3Amaster
|
508
|
+
[Coverage badge]: https://img.shields.io/coveralls/bolshakov/stoplight/master.svg?label=coverage
|
509
|
+
[coverage]: https://coveralls.io/r/bolshakov/stoplight
|
510
|
+
[Climate badge]: https://api.codeclimate.com/v1/badges/3451c2d281ffa345441a/maintainability
|
511
|
+
[climate]: https://codeclimate.com/github/bolshakov/stoplight
|
512
|
+
[stoplight-admin]: https://github.com/bolshakov/stoplight-admin
|
484
513
|
[Semantic Versioning]: http://semver.org/spec/v2.0.0.html
|
485
514
|
[the change log]: CHANGELOG.md
|
486
515
|
[the notifiers section]: #notifiers
|
@@ -490,11 +519,14 @@ Stoplight is licensed under [the MIT License][].
|
|
490
519
|
[the HipChat gem]: https://rubygems.org/gems/hipchat
|
491
520
|
[the Honeybadger gem]: https://rubygems.org/gems/honeybadger
|
492
521
|
[the Logger class]: http://ruby-doc.org/stdlib-2.2.3/libdoc/logger/rdoc/Logger.html
|
522
|
+
[the Rollbar gem]: https://rubygems.org/gems/rollbar
|
493
523
|
[the Sentry gem]: https://rubygems.org/gems/sentry-raven
|
494
524
|
[the Slack gem]: https://rubygems.org/gems/slack-notifier
|
525
|
+
[the Pagerduty gem]: https://rubygems.org/gems/pagerduty
|
495
526
|
[@camdez]: https://github.com/camdez
|
496
527
|
[@tfausak]: https://github.com/tfausak
|
497
528
|
[@orgsync]: https://github.com/OrgSync
|
498
|
-
[
|
529
|
+
[@bolshakov]: https://github.com/bolshakov
|
530
|
+
[complete list of contributors]: https://github.com/bolshakov/stoplight/graphs/contributors
|
499
531
|
[CircuitBreaker]: http://martinfowler.com/bliki/CircuitBreaker.html
|
500
532
|
[the MIT license]: LICENSE.md
|
data/lib/stoplight/color.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Stoplight
|
4
4
|
module DataStore
|
5
5
|
# @see Base
|
6
6
|
class Redis < Base
|
7
|
-
KEY_PREFIX = 'stoplight'
|
8
|
-
KEY_SEPARATOR = ':'
|
7
|
+
KEY_PREFIX = 'stoplight'
|
8
|
+
KEY_SEPARATOR = ':'
|
9
9
|
|
10
10
|
# @param redis [::Redis]
|
11
11
|
def initialize(redis)
|
@@ -25,9 +25,9 @@ module Stoplight
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def get_all(light)
|
28
|
-
failures, state = @redis.multi do
|
29
|
-
query_failures(light)
|
30
|
-
|
28
|
+
failures, state = @redis.multi do |transaction|
|
29
|
+
query_failures(light, transaction: transaction)
|
30
|
+
transaction.hget(states_key, light.name)
|
31
31
|
end
|
32
32
|
|
33
33
|
[
|
@@ -41,18 +41,18 @@ module Stoplight
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def record_failure(light, failure)
|
44
|
-
size, = @redis.multi do
|
45
|
-
|
46
|
-
|
44
|
+
size, = @redis.multi do |transaction|
|
45
|
+
transaction.lpush(failures_key(light), failure.to_json)
|
46
|
+
transaction.ltrim(failures_key(light), 0, light.threshold - 1)
|
47
47
|
end
|
48
48
|
|
49
49
|
size
|
50
50
|
end
|
51
51
|
|
52
52
|
def clear_failures(light)
|
53
|
-
failures, = @redis.multi do
|
54
|
-
query_failures(light)
|
55
|
-
|
53
|
+
failures, = @redis.multi do |transaction|
|
54
|
+
query_failures(light, transaction: transaction)
|
55
|
+
transaction.del(failures_key(light))
|
56
56
|
end
|
57
57
|
|
58
58
|
normalize_failures(failures, light.error_notifier)
|
@@ -68,9 +68,9 @@ module Stoplight
|
|
68
68
|
end
|
69
69
|
|
70
70
|
def clear_state(light)
|
71
|
-
state, = @redis.multi do
|
72
|
-
query_state(light)
|
73
|
-
|
71
|
+
state, = @redis.multi do |transaction|
|
72
|
+
query_state(light, transaction: transaction)
|
73
|
+
transaction.hdel(states_key, light.name)
|
74
74
|
end
|
75
75
|
|
76
76
|
normalize_state(state)
|
@@ -78,23 +78,21 @@ module Stoplight
|
|
78
78
|
|
79
79
|
private
|
80
80
|
|
81
|
-
def query_failures(light)
|
82
|
-
|
81
|
+
def query_failures(light, transaction: @redis)
|
82
|
+
transaction.lrange(failures_key(light), 0, -1)
|
83
83
|
end
|
84
84
|
|
85
85
|
def normalize_failures(failures, error_notifier)
|
86
86
|
failures.map do |json|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
Failure.from_error(error)
|
92
|
-
end
|
87
|
+
Failure.from_json(json)
|
88
|
+
rescue StandardError => e
|
89
|
+
error_notifier.call(e)
|
90
|
+
Failure.from_error(e)
|
93
91
|
end
|
94
92
|
end
|
95
93
|
|
96
|
-
def query_state(light)
|
97
|
-
|
94
|
+
def query_state(light, transaction: @redis)
|
95
|
+
transaction.hget(states_key, light.name)
|
98
96
|
end
|
99
97
|
|
100
98
|
def normalize_state(state)
|
data/lib/stoplight/data_store.rb
CHANGED
data/lib/stoplight/default.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Stoplight
|
4
4
|
module Default
|
@@ -6,9 +6,9 @@ module Stoplight
|
|
6
6
|
|
7
7
|
DATA_STORE = DataStore::Memory.new
|
8
8
|
|
9
|
-
ERROR_HANDLER = ->
|
9
|
+
ERROR_HANDLER = ->(error, handler) { handler.call(error) }
|
10
10
|
|
11
|
-
ERROR_NOTIFIER = ->
|
11
|
+
ERROR_NOTIFIER = ->(error) { warn error }
|
12
12
|
|
13
13
|
FALLBACK = nil
|
14
14
|
|
data/lib/stoplight/error.rb
CHANGED
data/lib/stoplight/failure.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'json'
|
4
4
|
require 'time'
|
5
5
|
|
6
6
|
module Stoplight
|
7
7
|
class Failure # rubocop:disable Style/Documentation
|
8
|
-
TIME_FORMAT = '%Y-%m-%dT%H:%M:%S.%N%:z'
|
8
|
+
TIME_FORMAT = '%Y-%m-%dT%H:%M:%S.%N%:z'
|
9
9
|
|
10
10
|
# @return [String]
|
11
11
|
attr_reader :error_class
|
@@ -52,14 +52,18 @@ module Stoplight
|
|
52
52
|
time == other.time
|
53
53
|
end
|
54
54
|
|
55
|
+
# @param options [Object, nil]
|
55
56
|
# @return [String]
|
56
|
-
def to_json
|
57
|
+
def to_json(options = nil)
|
57
58
|
JSON.generate(
|
58
|
-
|
59
|
-
|
60
|
-
|
59
|
+
{
|
60
|
+
error: {
|
61
|
+
class: error_class,
|
62
|
+
message: error_message
|
63
|
+
},
|
64
|
+
time: time.strftime(TIME_FORMAT)
|
61
65
|
},
|
62
|
-
|
66
|
+
options
|
63
67
|
)
|
64
68
|
end
|
65
69
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Stoplight
|
4
4
|
class Light
|
@@ -44,23 +44,25 @@ module Stoplight
|
|
44
44
|
|
45
45
|
def run_red
|
46
46
|
raise Error::RedLight, name unless fallback
|
47
|
+
|
47
48
|
fallback.call(nil)
|
48
49
|
end
|
49
50
|
|
50
51
|
def run_code(on_success, on_failure)
|
51
52
|
result = code.call
|
52
53
|
failures = clear_failures
|
53
|
-
on_success
|
54
|
+
on_success&.call(failures)
|
54
55
|
result
|
55
|
-
rescue Exception =>
|
56
|
-
handle_error(
|
56
|
+
rescue Exception => e # rubocop:disable Lint/RescueException
|
57
|
+
handle_error(e, on_failure)
|
57
58
|
end
|
58
59
|
|
59
60
|
def handle_error(error, on_failure)
|
60
61
|
error_handler.call(error, Error::HANDLER)
|
61
62
|
size = record_failure(error)
|
62
|
-
on_failure
|
63
|
+
on_failure&.call(size, error)
|
63
64
|
raise error unless fallback
|
65
|
+
|
64
66
|
fallback.call(error)
|
65
67
|
end
|
66
68
|
|
data/lib/stoplight/light.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Stoplight
|
4
4
|
module Notifier
|
@@ -34,7 +34,7 @@ module Stoplight
|
|
34
34
|
h = options.merge(
|
35
35
|
api_key: api_key,
|
36
36
|
error_message: message,
|
37
|
-
backtrace:
|
37
|
+
backtrace: error&.backtrace
|
38
38
|
)
|
39
39
|
::Honeybadger.notify(h)
|
40
40
|
message
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Stoplight
|
4
|
+
module Notifier
|
5
|
+
# @see Base
|
6
|
+
class Pagerduty < Base
|
7
|
+
include Generic
|
8
|
+
|
9
|
+
# @return [::Pagerduty]
|
10
|
+
def pagerduty
|
11
|
+
@object
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def put(message)
|
17
|
+
pagerduty.trigger(message)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Stoplight
|
4
4
|
module Notifier
|
@@ -30,7 +30,7 @@ module Stoplight
|
|
30
30
|
|
31
31
|
h = options.merge(
|
32
32
|
configuration: configuration,
|
33
|
-
backtrace:
|
33
|
+
backtrace: error&.backtrace
|
34
34
|
)
|
35
35
|
::Raven.capture_message(message, h)
|
36
36
|
message
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Stoplight
|
4
|
+
module Notifier
|
5
|
+
# @see Base
|
6
|
+
class Rollbar < Base
|
7
|
+
DEFAULT_OPTIONS = {
|
8
|
+
severity: 'info'
|
9
|
+
}.freeze
|
10
|
+
|
11
|
+
StoplightStatusChange = Class.new(Error::Base)
|
12
|
+
|
13
|
+
# @return [Proc]
|
14
|
+
attr_reader :formatter
|
15
|
+
# @return [::Rollbar]
|
16
|
+
attr_reader :rollbar
|
17
|
+
# @return [Hash{Symbol => Object}]
|
18
|
+
attr_reader :options
|
19
|
+
|
20
|
+
# @param rollbar [::Rollbar]
|
21
|
+
# @param formatter [Proc, nil]
|
22
|
+
# @param options [Hash{Symbol => Object}]
|
23
|
+
# @option options [String] :severity
|
24
|
+
def initialize(rollbar, formatter = nil, options = {})
|
25
|
+
@rollbar = rollbar
|
26
|
+
@formatter = formatter || Default::FORMATTER
|
27
|
+
@options = DEFAULT_OPTIONS.merge(options)
|
28
|
+
end
|
29
|
+
|
30
|
+
def notify(light, from_color, to_color, error)
|
31
|
+
formatter.call(light, from_color, to_color, error).tap do |message|
|
32
|
+
severity = options.fetch(:severity)
|
33
|
+
exception = StoplightStatusChange.new(message)
|
34
|
+
rollbar.__send__(severity, exception)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/stoplight/notifier.rb
CHANGED
data/lib/stoplight/state.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Stoplight
|
4
4
|
module State
|
5
|
-
UNLOCKED = 'unlocked'
|
6
|
-
LOCKED_GREEN = 'locked_green'
|
7
|
-
LOCKED_RED = 'locked_red'
|
5
|
+
UNLOCKED = 'unlocked'
|
6
|
+
LOCKED_GREEN = 'locked_green'
|
7
|
+
LOCKED_RED = 'locked_red'
|
8
8
|
end
|
9
9
|
end
|
data/lib/stoplight/version.rb
CHANGED
data/lib/stoplight.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Stoplight # rubocop:disable Style/Documentation
|
4
4
|
end
|
@@ -24,7 +24,9 @@ require 'stoplight/notifier/hip_chat'
|
|
24
24
|
require 'stoplight/notifier/honeybadger'
|
25
25
|
require 'stoplight/notifier/io'
|
26
26
|
require 'stoplight/notifier/logger'
|
27
|
+
require 'stoplight/notifier/pagerduty'
|
27
28
|
require 'stoplight/notifier/raven'
|
29
|
+
require 'stoplight/notifier/rollbar'
|
28
30
|
require 'stoplight/notifier/slack'
|
29
31
|
|
30
32
|
require 'stoplight/default'
|
data/spec/spec_helper.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
@@ -74,7 +74,7 @@ RSpec.describe Stoplight::Default do
|
|
74
74
|
|
75
75
|
describe '::THRESHOLD' do
|
76
76
|
it 'is an integer' do
|
77
|
-
expect(Stoplight::Default::THRESHOLD).to be_a(
|
77
|
+
expect(Stoplight::Default::THRESHOLD).to be_a(Integer)
|
78
78
|
end
|
79
79
|
end
|
80
80
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
@@ -89,6 +89,11 @@ RSpec.describe Stoplight::Failure do
|
|
89
89
|
expect(described_class.new(error_class, error_message, time).to_json)
|
90
90
|
.to eql(json)
|
91
91
|
end
|
92
|
+
|
93
|
+
it 'generates JSON with options' do
|
94
|
+
expect(described_class.new(error_class, error_message, time).to_json({}))
|
95
|
+
.to eql(json)
|
96
|
+
end
|
92
97
|
end
|
93
98
|
|
94
99
|
describe '::TIME_FORMAT' do
|
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
require 'stringio'
|
@@ -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) { ->
|
11
|
+
let(:fallback) { ->(_) { fallback_result } }
|
12
12
|
let(:fallback_result) { random_string }
|
13
13
|
let(:name) { random_string }
|
14
14
|
|
@@ -123,12 +123,10 @@ RSpec.describe Stoplight::Light::Runnable do
|
|
123
123
|
|
124
124
|
context 'with an error handler' do
|
125
125
|
let(:result) do
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
expect(true).to be(true)
|
131
|
-
end
|
126
|
+
subject.run
|
127
|
+
expect(false).to be(true)
|
128
|
+
rescue error.class
|
129
|
+
expect(true).to be(true)
|
132
130
|
end
|
133
131
|
|
134
132
|
it 'records the failure when the handler does nothing' do
|
@@ -171,7 +169,7 @@ RSpec.describe Stoplight::Light::Runnable do
|
|
171
169
|
|
172
170
|
context 'when the data store is failing' do
|
173
171
|
let(:data_store) { Object.new }
|
174
|
-
let(:error_notifier) { ->
|
172
|
+
let(:error_notifier) { ->(_) {} }
|
175
173
|
|
176
174
|
before do
|
177
175
|
subject
|
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
require 'stringio'
|
@@ -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)
|
@@ -140,7 +140,7 @@ RSpec.describe Stoplight::Light do
|
|
140
140
|
|
141
141
|
describe '#with_error_handler' do
|
142
142
|
it 'sets the error handler' do
|
143
|
-
error_handler = ->
|
143
|
+
error_handler = ->(_, _) {}
|
144
144
|
light.with_error_handler(&error_handler)
|
145
145
|
expect(light.error_handler).to eql(error_handler)
|
146
146
|
end
|
@@ -148,7 +148,7 @@ RSpec.describe Stoplight::Light do
|
|
148
148
|
|
149
149
|
describe '#with_error_notifier' do
|
150
150
|
it 'sets the error notifier' do
|
151
|
-
error_notifier = ->
|
151
|
+
error_notifier = ->(_) {}
|
152
152
|
light.with_error_notifier(&error_notifier)
|
153
153
|
expect(light.error_notifier).to eql(error_notifier)
|
154
154
|
end
|
@@ -156,7 +156,7 @@ RSpec.describe Stoplight::Light do
|
|
156
156
|
|
157
157
|
describe '#with_fallback' do
|
158
158
|
it 'sets the fallback' do
|
159
|
-
fallback = ->
|
159
|
+
fallback = ->(_) {}
|
160
160
|
light.with_fallback(&fallback)
|
161
161
|
expect(light.fallback).to eql(fallback)
|
162
162
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
@@ -7,8 +7,6 @@ module Bugsnag
|
|
7
7
|
end
|
8
8
|
|
9
9
|
RSpec.describe Stoplight::Notifier::Bugsnag do
|
10
|
-
StoplightStatusChange = Stoplight::Notifier::Bugsnag::StoplightStatusChange
|
11
|
-
|
12
10
|
it 'is a class' do
|
13
11
|
expect(described_class).to be_a(Class)
|
14
12
|
end
|
@@ -65,7 +63,7 @@ RSpec.describe Stoplight::Notifier::Bugsnag do
|
|
65
63
|
end
|
66
64
|
|
67
65
|
before do
|
68
|
-
status_change = StoplightStatusChange.new(message)
|
66
|
+
status_change = described_class::StoplightStatusChange.new(message)
|
69
67
|
expect(bugsnag).to receive(:notify).with(status_change, severity: 'info')
|
70
68
|
end
|
71
69
|
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'pagerduty'
|
5
|
+
|
6
|
+
RSpec.describe Stoplight::Notifier::Pagerduty do
|
7
|
+
it_behaves_like 'a generic notifier'
|
8
|
+
|
9
|
+
it 'is a class' do
|
10
|
+
expect(described_class).to be_a(Class)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'is a subclass of Base' do
|
14
|
+
expect(described_class).to be < Stoplight::Notifier::Base
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#pagerduty' do
|
18
|
+
it 'reads Pagerduty client' do
|
19
|
+
pagerduty = Pagerduty.new('WEBHOOK_URL')
|
20
|
+
expect(described_class.new(pagerduty).pagerduty).to eql(pagerduty)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#notify' do
|
25
|
+
let(:light) { Stoplight::Light.new(name, &code) }
|
26
|
+
let(:name) { ('a'..'z').to_a.shuffle.join }
|
27
|
+
let(:code) { -> {} }
|
28
|
+
let(:from_color) { Stoplight::Color::GREEN }
|
29
|
+
let(:to_color) { Stoplight::Color::RED }
|
30
|
+
let(:notifier) { described_class.new(pagerduty) }
|
31
|
+
let(:pagerduty) { double(Pagerduty).as_null_object }
|
32
|
+
|
33
|
+
it 'pings Pagerduty' do
|
34
|
+
error = nil
|
35
|
+
message = notifier.formatter.call(light, from_color, to_color, error)
|
36
|
+
expect(pagerduty).to receive(:trigger).with(message)
|
37
|
+
notifier.notify(light, from_color, to_color, error)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
# require 'rollbar'
|
6
|
+
module Rollbar
|
7
|
+
end
|
8
|
+
|
9
|
+
RSpec.describe Stoplight::Notifier::Rollbar do
|
10
|
+
it 'is a class' do
|
11
|
+
expect(described_class).to be_a(Class)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'is a subclass of Base' do
|
15
|
+
expect(described_class).to be < Stoplight::Notifier::Base
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#formatter' do
|
19
|
+
it 'is initially the default' do
|
20
|
+
expect(described_class.new(nil, nil).formatter)
|
21
|
+
.to eql(Stoplight::Default::FORMATTER)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'reads the formatter' do
|
25
|
+
formatter = proc {}
|
26
|
+
expect(described_class.new(nil, formatter).formatter)
|
27
|
+
.to eql(formatter)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#options' do
|
32
|
+
it 'is initially the default' do
|
33
|
+
expect(described_class.new(nil, nil).options)
|
34
|
+
.to eql(Stoplight::Notifier::Rollbar::DEFAULT_OPTIONS)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'reads the options' do
|
38
|
+
options = { key: :value }
|
39
|
+
expect(described_class.new(nil, nil, options).options)
|
40
|
+
.to eql(Stoplight::Notifier::Rollbar::DEFAULT_OPTIONS.merge(options))
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '#rollbar' do
|
45
|
+
it 'reads the Rollbar client' do
|
46
|
+
client = Rollbar
|
47
|
+
expect(described_class.new(client, nil).rollbar)
|
48
|
+
.to eql(client)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '#notify' do
|
53
|
+
let(:light) { Stoplight::Light.new(name, &code) }
|
54
|
+
let(:name) { ('a'..'z').to_a.shuffle.join }
|
55
|
+
let(:code) { -> {} }
|
56
|
+
let(:from_color) { Stoplight::Color::GREEN }
|
57
|
+
let(:to_color) { Stoplight::Color::RED }
|
58
|
+
let(:notifier) { described_class.new(rollbar) }
|
59
|
+
let(:rollbar) { Rollbar }
|
60
|
+
|
61
|
+
subject(:result) do
|
62
|
+
notifier.notify(light, from_color, to_color, error)
|
63
|
+
end
|
64
|
+
|
65
|
+
before do
|
66
|
+
status_change = described_class::StoplightStatusChange.new(message)
|
67
|
+
expect(rollbar).to receive(:info).with(status_change)
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'when no error given' do
|
71
|
+
let(:error) { nil }
|
72
|
+
|
73
|
+
it 'logs message' do
|
74
|
+
expect(result).to eq(message)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'when message with an error given' do
|
79
|
+
let(:error) { ZeroDivisionError.new('divided by 0') }
|
80
|
+
|
81
|
+
it 'logs message' do
|
82
|
+
expect(result).to eq(message)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def message
|
87
|
+
notifier.formatter.call(light, from_color, to_color, error)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
data/spec/stoplight_spec.rb
CHANGED
metadata
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stoplight
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cameron Desautels
|
8
8
|
- Taylor Fausak
|
9
9
|
- Justin Steffy
|
10
|
-
autorequire:
|
10
|
+
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2022-02-23 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: benchmark-ips
|
@@ -40,20 +40,6 @@ dependencies:
|
|
40
40
|
- - "~>"
|
41
41
|
- !ruby/object:Gem::Version
|
42
42
|
version: '4.0'
|
43
|
-
- !ruby/object:Gem::Dependency
|
44
|
-
name: coveralls
|
45
|
-
requirement: !ruby/object:Gem::Requirement
|
46
|
-
requirements:
|
47
|
-
- - "~>"
|
48
|
-
- !ruby/object:Gem::Version
|
49
|
-
version: '0.8'
|
50
|
-
type: :development
|
51
|
-
prerelease: false
|
52
|
-
version_requirements: !ruby/object:Gem::Requirement
|
53
|
-
requirements:
|
54
|
-
- - "~>"
|
55
|
-
- !ruby/object:Gem::Version
|
56
|
-
version: '0.8'
|
57
43
|
- !ruby/object:Gem::Dependency
|
58
44
|
name: fakeredis
|
59
45
|
requirement: !ruby/object:Gem::Requirement
|
@@ -97,33 +83,33 @@ dependencies:
|
|
97
83
|
- !ruby/object:Gem::Version
|
98
84
|
version: '2.5'
|
99
85
|
- !ruby/object:Gem::Dependency
|
100
|
-
name:
|
86
|
+
name: pagerduty
|
101
87
|
requirement: !ruby/object:Gem::Requirement
|
102
88
|
requirements:
|
103
89
|
- - "~>"
|
104
90
|
- !ruby/object:Gem::Version
|
105
|
-
version:
|
91
|
+
version: 2.1.1
|
106
92
|
type: :development
|
107
93
|
prerelease: false
|
108
94
|
version_requirements: !ruby/object:Gem::Requirement
|
109
95
|
requirements:
|
110
96
|
- - "~>"
|
111
97
|
- !ruby/object:Gem::Version
|
112
|
-
version:
|
98
|
+
version: 2.1.1
|
113
99
|
- !ruby/object:Gem::Dependency
|
114
100
|
name: rake
|
115
101
|
requirement: !ruby/object:Gem::Requirement
|
116
102
|
requirements:
|
117
103
|
- - "~>"
|
118
104
|
- !ruby/object:Gem::Version
|
119
|
-
version: '
|
105
|
+
version: '13.0'
|
120
106
|
type: :development
|
121
107
|
prerelease: false
|
122
108
|
version_requirements: !ruby/object:Gem::Requirement
|
123
109
|
requirements:
|
124
110
|
- - "~>"
|
125
111
|
- !ruby/object:Gem::Version
|
126
|
-
version: '
|
112
|
+
version: '13.0'
|
127
113
|
- !ruby/object:Gem::Dependency
|
128
114
|
name: redis
|
129
115
|
requirement: !ruby/object:Gem::Requirement
|
@@ -158,14 +144,56 @@ dependencies:
|
|
158
144
|
requirements:
|
159
145
|
- - "~>"
|
160
146
|
- !ruby/object:Gem::Version
|
161
|
-
version: 0.
|
147
|
+
version: 1.0.0
|
148
|
+
type: :development
|
149
|
+
prerelease: false
|
150
|
+
version_requirements: !ruby/object:Gem::Requirement
|
151
|
+
requirements:
|
152
|
+
- - "~>"
|
153
|
+
- !ruby/object:Gem::Version
|
154
|
+
version: 1.0.0
|
155
|
+
- !ruby/object:Gem::Dependency
|
156
|
+
name: sentry-raven
|
157
|
+
requirement: !ruby/object:Gem::Requirement
|
158
|
+
requirements:
|
159
|
+
- - "~>"
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
version: '1.2'
|
162
|
+
type: :development
|
163
|
+
prerelease: false
|
164
|
+
version_requirements: !ruby/object:Gem::Requirement
|
165
|
+
requirements:
|
166
|
+
- - "~>"
|
167
|
+
- !ruby/object:Gem::Version
|
168
|
+
version: '1.2'
|
169
|
+
- !ruby/object:Gem::Dependency
|
170
|
+
name: simplecov
|
171
|
+
requirement: !ruby/object:Gem::Requirement
|
172
|
+
requirements:
|
173
|
+
- - "~>"
|
174
|
+
- !ruby/object:Gem::Version
|
175
|
+
version: '0.21'
|
176
|
+
type: :development
|
177
|
+
prerelease: false
|
178
|
+
version_requirements: !ruby/object:Gem::Requirement
|
179
|
+
requirements:
|
180
|
+
- - "~>"
|
181
|
+
- !ruby/object:Gem::Version
|
182
|
+
version: '0.21'
|
183
|
+
- !ruby/object:Gem::Dependency
|
184
|
+
name: simplecov-lcov
|
185
|
+
requirement: !ruby/object:Gem::Requirement
|
186
|
+
requirements:
|
187
|
+
- - "~>"
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: '0.8'
|
162
190
|
type: :development
|
163
191
|
prerelease: false
|
164
192
|
version_requirements: !ruby/object:Gem::Requirement
|
165
193
|
requirements:
|
166
194
|
- - "~>"
|
167
195
|
- !ruby/object:Gem::Version
|
168
|
-
version: 0.
|
196
|
+
version: '0.8'
|
169
197
|
- !ruby/object:Gem::Dependency
|
170
198
|
name: slack-notifier
|
171
199
|
requirement: !ruby/object:Gem::Requirement
|
@@ -225,7 +253,9 @@ files:
|
|
225
253
|
- lib/stoplight/notifier/honeybadger.rb
|
226
254
|
- lib/stoplight/notifier/io.rb
|
227
255
|
- lib/stoplight/notifier/logger.rb
|
256
|
+
- lib/stoplight/notifier/pagerduty.rb
|
228
257
|
- lib/stoplight/notifier/raven.rb
|
258
|
+
- lib/stoplight/notifier/rollbar.rb
|
229
259
|
- lib/stoplight/notifier/slack.rb
|
230
260
|
- lib/stoplight/state.rb
|
231
261
|
- lib/stoplight/version.rb
|
@@ -247,17 +277,19 @@ files:
|
|
247
277
|
- spec/stoplight/notifier/honeybadger_spec.rb
|
248
278
|
- spec/stoplight/notifier/io_spec.rb
|
249
279
|
- spec/stoplight/notifier/logger_spec.rb
|
280
|
+
- spec/stoplight/notifier/pagerduty_spec.rb
|
250
281
|
- spec/stoplight/notifier/raven_spec.rb
|
282
|
+
- spec/stoplight/notifier/rollbar_spec.rb
|
251
283
|
- spec/stoplight/notifier/slack_spec.rb
|
252
284
|
- spec/stoplight/notifier_spec.rb
|
253
285
|
- spec/stoplight/state_spec.rb
|
254
286
|
- spec/stoplight/version_spec.rb
|
255
287
|
- spec/stoplight_spec.rb
|
256
|
-
homepage: https://github.com/
|
288
|
+
homepage: https://github.com/bolshakov/stoplight
|
257
289
|
licenses:
|
258
290
|
- MIT
|
259
291
|
metadata: {}
|
260
|
-
post_install_message:
|
292
|
+
post_install_message:
|
261
293
|
rdoc_options: []
|
262
294
|
require_paths:
|
263
295
|
- lib
|
@@ -265,40 +297,41 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
265
297
|
requirements:
|
266
298
|
- - ">="
|
267
299
|
- !ruby/object:Gem::Version
|
268
|
-
version: '2.
|
300
|
+
version: '2.6'
|
269
301
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
270
302
|
requirements:
|
271
303
|
- - ">="
|
272
304
|
- !ruby/object:Gem::Version
|
273
305
|
version: '0'
|
274
306
|
requirements: []
|
275
|
-
|
276
|
-
|
277
|
-
signing_key:
|
307
|
+
rubygems_version: 3.2.3
|
308
|
+
signing_key:
|
278
309
|
specification_version: 4
|
279
310
|
summary: Traffic control for code.
|
280
311
|
test_files:
|
281
312
|
- spec/spec_helper.rb
|
282
|
-
- spec/
|
313
|
+
- spec/stoplight/color_spec.rb
|
314
|
+
- spec/stoplight/data_store/base_spec.rb
|
315
|
+
- spec/stoplight/data_store/memory_spec.rb
|
316
|
+
- spec/stoplight/data_store/redis_spec.rb
|
317
|
+
- spec/stoplight/data_store_spec.rb
|
318
|
+
- spec/stoplight/default_spec.rb
|
283
319
|
- spec/stoplight/error_spec.rb
|
284
320
|
- spec/stoplight/failure_spec.rb
|
285
|
-
- spec/stoplight/
|
286
|
-
- spec/stoplight/
|
287
|
-
- spec/stoplight/notifier/logger_spec.rb
|
288
|
-
- spec/stoplight/notifier/honeybadger_spec.rb
|
289
|
-
- spec/stoplight/notifier/generic_spec.rb
|
290
|
-
- spec/stoplight/notifier/slack_spec.rb
|
321
|
+
- spec/stoplight/light/runnable_spec.rb
|
322
|
+
- spec/stoplight/light_spec.rb
|
291
323
|
- spec/stoplight/notifier/base_spec.rb
|
292
324
|
- spec/stoplight/notifier/bugsnag_spec.rb
|
325
|
+
- spec/stoplight/notifier/generic_spec.rb
|
293
326
|
- spec/stoplight/notifier/hip_chat_spec.rb
|
294
|
-
- spec/stoplight/
|
295
|
-
- spec/stoplight/
|
327
|
+
- spec/stoplight/notifier/honeybadger_spec.rb
|
328
|
+
- spec/stoplight/notifier/io_spec.rb
|
329
|
+
- spec/stoplight/notifier/logger_spec.rb
|
330
|
+
- spec/stoplight/notifier/pagerduty_spec.rb
|
331
|
+
- spec/stoplight/notifier/raven_spec.rb
|
332
|
+
- spec/stoplight/notifier/rollbar_spec.rb
|
333
|
+
- spec/stoplight/notifier/slack_spec.rb
|
296
334
|
- spec/stoplight/notifier_spec.rb
|
297
|
-
- spec/stoplight/
|
298
|
-
- spec/stoplight/
|
299
|
-
- spec/
|
300
|
-
- spec/stoplight/data_store/memory_spec.rb
|
301
|
-
- spec/stoplight/data_store/redis_spec.rb
|
302
|
-
- spec/stoplight/data_store/base_spec.rb
|
303
|
-
- spec/stoplight/light/runnable_spec.rb
|
304
|
-
- spec/stoplight/light_spec.rb
|
335
|
+
- spec/stoplight/state_spec.rb
|
336
|
+
- spec/stoplight/version_spec.rb
|
337
|
+
- spec/stoplight_spec.rb
|