hutch 0.21.0-java → 0.25.0-java
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/.gitignore +3 -0
- data/.rspec +1 -0
- data/.travis.yml +11 -12
- data/.yardopts +5 -0
- data/CHANGELOG.md +118 -1
- data/Gemfile +15 -4
- data/Guardfile +13 -4
- data/README.md +274 -24
- data/Rakefile +8 -1
- data/hutch.gemspec +6 -7
- data/lib/hutch.rb +11 -8
- data/lib/hutch/adapters/march_hare.rb +1 -1
- data/lib/hutch/broker.rb +113 -110
- data/lib/hutch/cli.rb +42 -11
- data/lib/hutch/config.rb +209 -59
- data/lib/hutch/error_handlers.rb +1 -0
- data/lib/hutch/error_handlers/airbrake.rb +44 -16
- data/lib/hutch/error_handlers/base.rb +15 -0
- data/lib/hutch/error_handlers/honeybadger.rb +33 -18
- data/lib/hutch/error_handlers/logger.rb +12 -6
- data/lib/hutch/error_handlers/opbeat.rb +30 -0
- data/lib/hutch/error_handlers/sentry.rb +14 -6
- data/lib/hutch/logging.rb +5 -5
- data/lib/hutch/publisher.rb +75 -0
- data/lib/hutch/tracers.rb +1 -0
- data/lib/hutch/tracers/opbeat.rb +37 -0
- data/lib/hutch/version.rb +1 -1
- data/lib/hutch/waiter.rb +104 -0
- data/lib/hutch/worker.rb +50 -66
- data/lib/yard-settings/handler.rb +38 -0
- data/lib/yard-settings/yard-settings.rb +2 -0
- data/spec/hutch/broker_spec.rb +162 -77
- data/spec/hutch/cli_spec.rb +16 -3
- data/spec/hutch/config_spec.rb +83 -22
- data/spec/hutch/error_handlers/airbrake_spec.rb +25 -10
- data/spec/hutch/error_handlers/honeybadger_spec.rb +24 -2
- data/spec/hutch/error_handlers/logger_spec.rb +14 -1
- data/spec/hutch/error_handlers/opbeat_spec.rb +37 -0
- data/spec/hutch/error_handlers/sentry_spec.rb +18 -1
- data/spec/hutch/logger_spec.rb +12 -6
- data/spec/hutch/waiter_spec.rb +51 -0
- data/spec/hutch/worker_spec.rb +33 -4
- data/spec/spec_helper.rb +7 -5
- data/spec/tracers/opbeat_spec.rb +44 -0
- data/templates/default/class/html/settings.erb +0 -0
- data/templates/default/class/setup.rb +4 -0
- data/templates/default/fulldoc/html/css/hutch.css +13 -0
- data/templates/default/layout/html/setup.rb +7 -0
- data/templates/default/method_details/html/settings.erb +5 -0
- data/templates/default/method_details/setup.rb +4 -0
- data/templates/default/method_details/text/settings.erb +0 -0
- data/templates/default/module/html/settings.erb +40 -0
- data/templates/default/module/setup.rb +4 -0
- metadata +41 -38
data/spec/hutch/cli_spec.rb
CHANGED
@@ -4,6 +4,19 @@ require 'tempfile'
|
|
4
4
|
describe Hutch::CLI do
|
5
5
|
let(:cli) { Hutch::CLI.new }
|
6
6
|
|
7
|
+
describe "#start_work_loop" do
|
8
|
+
context "connection error during setup" do
|
9
|
+
let(:error) { Hutch::ConnectionError.new }
|
10
|
+
it "gets reported using error handlers" do
|
11
|
+
allow(Hutch).to receive(:connect).and_raise(error)
|
12
|
+
Hutch::Config[:error_handlers].each do |backend|
|
13
|
+
expect(backend).to receive(:handle_setup_exception).with(error)
|
14
|
+
end
|
15
|
+
cli.start_work_loop
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
7
20
|
describe "#parse_options" do
|
8
21
|
context "--config" do
|
9
22
|
context "when the config file does not exist" do
|
@@ -13,7 +26,7 @@ describe Hutch::CLI do
|
|
13
26
|
it "bails" do
|
14
27
|
expect {
|
15
28
|
cli.parse_options(["--config=#{file}"])
|
16
|
-
}.to raise_error SystemExit
|
29
|
+
}.to raise_error SystemExit, "Config file '/path/to/nonexistant/file' not found"
|
17
30
|
end
|
18
31
|
end
|
19
32
|
|
@@ -37,7 +50,7 @@ describe Hutch::CLI do
|
|
37
50
|
it "bails" do
|
38
51
|
expect {
|
39
52
|
cli.parse_options(["--mq-tls-key=#{file}"])
|
40
|
-
}.to raise_error SystemExit
|
53
|
+
}.to raise_error SystemExit, "Private key file '/path/to/nonexistant/file' not found"
|
41
54
|
end
|
42
55
|
end
|
43
56
|
|
@@ -61,7 +74,7 @@ describe Hutch::CLI do
|
|
61
74
|
it "bails" do
|
62
75
|
expect {
|
63
76
|
cli.parse_options(["--mq-tls-cert=#{file}"])
|
64
|
-
}.to raise_error SystemExit
|
77
|
+
}.to raise_error SystemExit, "Certificate file '/path/to/nonexistant/file' not found"
|
65
78
|
end
|
66
79
|
end
|
67
80
|
|
data/spec/hutch/config_spec.rb
CHANGED
@@ -4,23 +4,40 @@ require 'tempfile'
|
|
4
4
|
describe Hutch::Config do
|
5
5
|
let(:new_value) { 'not-localhost' }
|
6
6
|
|
7
|
+
before do
|
8
|
+
Hutch::Config.instance_variable_set(:@config, nil)
|
9
|
+
Hutch::Config.initialize
|
10
|
+
end
|
11
|
+
|
12
|
+
after do
|
13
|
+
Hutch::Config.instance_variable_set(:@config, nil)
|
14
|
+
end
|
15
|
+
|
7
16
|
describe '.get' do
|
8
17
|
context 'for valid attributes' do
|
9
18
|
subject { Hutch::Config.get(:mq_host) }
|
10
19
|
|
11
20
|
context 'with no overridden value' do
|
12
|
-
it { is_expected.to eq('
|
21
|
+
it { is_expected.to eq('127.0.0.1') }
|
13
22
|
end
|
14
23
|
|
15
24
|
context 'with an overridden value' do
|
16
|
-
before
|
25
|
+
before do
|
26
|
+
Hutch::Config.set(:mq_host, new_value)
|
27
|
+
end
|
28
|
+
|
17
29
|
it { is_expected.to eq(new_value) }
|
18
30
|
end
|
19
31
|
end
|
20
32
|
|
21
33
|
context 'for invalid attributes' do
|
22
|
-
let(:invalid_get)
|
23
|
-
|
34
|
+
let(:invalid_get) do
|
35
|
+
-> { Hutch::Config.get(:invalid_attr) }
|
36
|
+
end
|
37
|
+
|
38
|
+
specify do
|
39
|
+
expect(invalid_get).to raise_error Hutch::UnknownAttributeError
|
40
|
+
end
|
24
41
|
end
|
25
42
|
end
|
26
43
|
|
@@ -35,8 +52,13 @@ describe Hutch::Config do
|
|
35
52
|
end
|
36
53
|
|
37
54
|
context 'for invalid attributes' do
|
38
|
-
let(:invalid_set)
|
39
|
-
|
55
|
+
let(:invalid_set) do
|
56
|
+
-> { Hutch::Config.set(:invalid_attr, new_value) }
|
57
|
+
end
|
58
|
+
|
59
|
+
specify do
|
60
|
+
expect(invalid_set).to raise_error Hutch::UnknownAttributeError
|
61
|
+
end
|
40
62
|
end
|
41
63
|
end
|
42
64
|
|
@@ -49,9 +71,33 @@ describe Hutch::Config do
|
|
49
71
|
end
|
50
72
|
|
51
73
|
context 'for an invalid attribute' do
|
52
|
-
let(:invalid_getter) { ->{ Hutch::Config.invalid_attr } }
|
74
|
+
let(:invalid_getter) { -> { Hutch::Config.invalid_attr } }
|
53
75
|
specify { expect(invalid_getter).to raise_error NoMethodError }
|
54
76
|
end
|
77
|
+
|
78
|
+
context 'for an ENV-overriden value attribute' do
|
79
|
+
around do |example|
|
80
|
+
ENV['HUTCH_MQ_HOST'] = 'example.com'
|
81
|
+
ENV['HUTCH_MQ_PORT'] = '10001'
|
82
|
+
ENV['HUTCH_MQ_TLS'] = 'true'
|
83
|
+
example.run
|
84
|
+
ENV.delete('HUTCH_MQ_HOST')
|
85
|
+
ENV.delete('HUTCH_MQ_PORT')
|
86
|
+
ENV.delete('HUTCH_MQ_TLS')
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'returns the override' do
|
90
|
+
expect(Hutch::Config.mq_host).to eq 'example.com'
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'returns the override for integers' do
|
94
|
+
expect(Hutch::Config.mq_port).to eq 10_001
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'returns the override for booleans' do
|
98
|
+
expect(Hutch::Config.mq_tls).to eq true
|
99
|
+
end
|
100
|
+
end
|
55
101
|
end
|
56
102
|
|
57
103
|
describe 'a magic setter' do
|
@@ -63,7 +109,7 @@ describe Hutch::Config do
|
|
63
109
|
end
|
64
110
|
|
65
111
|
context 'for an invalid attribute' do
|
66
|
-
let(:invalid_setter) { ->{ Hutch::Config.invalid_attr = new_value } }
|
112
|
+
let(:invalid_setter) { -> { Hutch::Config.invalid_attr = new_value } }
|
67
113
|
specify { expect(invalid_setter).to raise_error NoMethodError }
|
68
114
|
end
|
69
115
|
end
|
@@ -81,9 +127,9 @@ describe Hutch::Config do
|
|
81
127
|
context 'when an attribute is invalid' do
|
82
128
|
let(:config_data) { { random_attribute: 'socks' } }
|
83
129
|
it 'raises an error' do
|
84
|
-
expect
|
130
|
+
expect do
|
85
131
|
Hutch::Config.load_from_file(file)
|
86
|
-
|
132
|
+
end.to raise_error(NoMethodError)
|
87
133
|
end
|
88
134
|
end
|
89
135
|
|
@@ -96,26 +142,21 @@ describe Hutch::Config do
|
|
96
142
|
expect(Hutch::Config.mq_username).to eq username
|
97
143
|
end
|
98
144
|
end
|
99
|
-
end
|
100
145
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
146
|
+
context 'when using ERB' do
|
147
|
+
let(:host) { 'localhost' }
|
148
|
+
let(:file) do
|
149
|
+
Tempfile.new('configs.yaml').tap do |t|
|
150
|
+
t.write(config_contents)
|
151
|
+
t.rewind
|
152
|
+
end
|
108
153
|
end
|
109
|
-
end
|
110
|
-
|
111
|
-
context 'when using ERb' do
|
112
154
|
let(:config_contents) do
|
113
155
|
<<-YAML
|
114
156
|
mq_host: 'localhost'
|
115
157
|
mq_username: '<%= "calvin" %>'
|
116
158
|
YAML
|
117
159
|
end
|
118
|
-
|
119
160
|
it 'loads in the config data' do
|
120
161
|
Hutch::Config.load_from_file(file)
|
121
162
|
expect(Hutch::Config.mq_host).to eq host
|
@@ -123,4 +164,24 @@ YAML
|
|
123
164
|
end
|
124
165
|
end
|
125
166
|
end
|
167
|
+
|
168
|
+
context 'developer ergonomics' do
|
169
|
+
it 'will accept strings and symbols as config keys' do
|
170
|
+
expect(Hutch::Config.get(:mq_host)).to eq '127.0.0.1'
|
171
|
+
expect(Hutch::Config.get('mq_host')).to eq '127.0.0.1'
|
172
|
+
end
|
173
|
+
|
174
|
+
describe 'it will not overwrite existing config' do
|
175
|
+
it 'with defaults' do
|
176
|
+
expect(Hutch::Config.get(:mq_host)).to eq '127.0.0.1'
|
177
|
+
Hutch::Config.initialize
|
178
|
+
|
179
|
+
Hutch::Config.set(:mq_host, 'example2.com')
|
180
|
+
|
181
|
+
expect(Hutch::Config.get(:mq_host)).to eq 'example2.com'
|
182
|
+
Hutch::Config.initialize
|
183
|
+
expect(Hutch::Config.get(:mq_host)).to eq 'example2.com'
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
126
187
|
end
|
@@ -14,21 +14,36 @@ describe Hutch::ErrorHandlers::Airbrake do
|
|
14
14
|
|
15
15
|
it "logs the error to Airbrake" do
|
16
16
|
message_id = "1"
|
17
|
+
properties = OpenStruct.new(message_id: message_id)
|
17
18
|
payload = "{}"
|
18
19
|
consumer = double
|
19
20
|
ex = error
|
20
21
|
message = {
|
21
|
-
:
|
22
|
-
:
|
23
|
-
:
|
24
|
-
:parameters => {
|
25
|
-
:payload => payload,
|
26
|
-
:consumer => consumer,
|
27
|
-
},
|
28
|
-
:cgi_data => ENV.to_hash,
|
22
|
+
payload: payload,
|
23
|
+
consumer: consumer,
|
24
|
+
cgi_data: ENV.to_hash,
|
29
25
|
}
|
30
|
-
expect(::Airbrake).to receive(:
|
31
|
-
error_handler.handle(
|
26
|
+
expect(::Airbrake).to receive(:notify).with(ex, message)
|
27
|
+
error_handler.handle(properties, payload, consumer, ex)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#handle_setup_exception' do
|
32
|
+
let(:error) do
|
33
|
+
begin
|
34
|
+
raise "Stuff went wrong"
|
35
|
+
rescue RuntimeError => err
|
36
|
+
err
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
it "logs the error to Airbrake" do
|
41
|
+
ex = error
|
42
|
+
message = {
|
43
|
+
cgi_data: ENV.to_hash,
|
44
|
+
}
|
45
|
+
expect(::Airbrake).to receive(:notify).with(ex, message)
|
46
|
+
error_handler.handle_setup_exception(ex)
|
32
47
|
end
|
33
48
|
end
|
34
49
|
end
|
@@ -14,6 +14,7 @@ describe Hutch::ErrorHandlers::Honeybadger do
|
|
14
14
|
|
15
15
|
it "logs the error to Honeybadger" do
|
16
16
|
message_id = "1"
|
17
|
+
properties = OpenStruct.new(message_id: message_id)
|
17
18
|
payload = "{}"
|
18
19
|
consumer = double
|
19
20
|
ex = error
|
@@ -29,8 +30,29 @@ describe Hutch::ErrorHandlers::Honeybadger do
|
|
29
30
|
:payload => payload
|
30
31
|
}
|
31
32
|
}
|
32
|
-
expect(
|
33
|
-
error_handler.handle(
|
33
|
+
expect(error_handler).to receive(:notify_honeybadger).with(message)
|
34
|
+
error_handler.handle(properties, payload, consumer, ex)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '#handle_setup_exception' do
|
39
|
+
let(:error) do
|
40
|
+
begin
|
41
|
+
raise "Stuff went wrong during setup"
|
42
|
+
rescue RuntimeError => err
|
43
|
+
err
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
it "logs the error to Honeybadger" do
|
48
|
+
ex = error
|
49
|
+
message = {
|
50
|
+
:error_class => ex.class.name,
|
51
|
+
:error_message => "#{ ex.class.name }: #{ ex.message }",
|
52
|
+
:backtrace => ex.backtrace,
|
53
|
+
}
|
54
|
+
expect(error_handler).to receive(:notify_honeybadger).with(message)
|
55
|
+
error_handler.handle_setup_exception(ex)
|
34
56
|
end
|
35
57
|
end
|
36
58
|
end
|
@@ -4,12 +4,25 @@ describe Hutch::ErrorHandlers::Logger do
|
|
4
4
|
let(:error_handler) { Hutch::ErrorHandlers::Logger.new }
|
5
5
|
|
6
6
|
describe '#handle' do
|
7
|
+
let(:properties) { OpenStruct.new(message_id: "1") }
|
8
|
+
let(:payload) { "{}" }
|
7
9
|
let(:error) { double(message: "Stuff went wrong", class: "RuntimeError",
|
8
10
|
backtrace: ["line 1", "line 2"]) }
|
9
11
|
|
10
12
|
it "logs three separate lines" do
|
11
13
|
expect(Hutch::Logging.logger).to receive(:error).exactly(3).times
|
12
|
-
error_handler.handle(
|
14
|
+
error_handler.handle(properties, payload, double, error)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#handle_setup_exception' do
|
19
|
+
let(:error) { double(message: "Stuff went wrong during setup",
|
20
|
+
class: "RuntimeError",
|
21
|
+
backtrace: ["line 1", "line 2"]) }
|
22
|
+
|
23
|
+
it "logs two separate lines" do
|
24
|
+
expect(Hutch::Logging.logger).to receive(:error).exactly(2).times
|
25
|
+
error_handler.handle_setup_exception(error)
|
13
26
|
end
|
14
27
|
end
|
15
28
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Hutch::ErrorHandlers::Opbeat do
|
4
|
+
let(:error_handler) { Hutch::ErrorHandlers::Opbeat.new }
|
5
|
+
|
6
|
+
describe '#handle' do
|
7
|
+
let(:properties) { OpenStruct.new(message_id: "1") }
|
8
|
+
let(:payload) { "{}" }
|
9
|
+
let(:error) do
|
10
|
+
begin
|
11
|
+
raise "Stuff went wrong"
|
12
|
+
rescue RuntimeError => err
|
13
|
+
err
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
it "logs the error to Opbeat" do
|
18
|
+
expect(Opbeat).to receive(:report).with(error, extra: { payload: payload })
|
19
|
+
error_handler.handle(properties, payload, double, error)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#handle_setup_exception' do
|
24
|
+
let(:error) do
|
25
|
+
begin
|
26
|
+
raise "Stuff went wrong during setup"
|
27
|
+
rescue RuntimeError => err
|
28
|
+
err
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
it "logs the error to Opbeat" do
|
33
|
+
expect(Opbeat).to receive(:report).with(error)
|
34
|
+
error_handler.handle_setup_exception(error)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -4,6 +4,8 @@ describe Hutch::ErrorHandlers::Sentry do
|
|
4
4
|
let(:error_handler) { Hutch::ErrorHandlers::Sentry.new }
|
5
5
|
|
6
6
|
describe '#handle' do
|
7
|
+
let(:properties) { OpenStruct.new(message_id: "1") }
|
8
|
+
let(:payload) { "{}" }
|
7
9
|
let(:error) do
|
8
10
|
begin
|
9
11
|
raise "Stuff went wrong"
|
@@ -12,9 +14,24 @@ describe Hutch::ErrorHandlers::Sentry do
|
|
12
14
|
end
|
13
15
|
end
|
14
16
|
|
17
|
+
it "logs the error to Sentry" do
|
18
|
+
expect(Raven).to receive(:capture_exception).with(error, extra: { payload: payload })
|
19
|
+
error_handler.handle(properties, payload, double, error)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#handle_setup_exception' do
|
24
|
+
let(:error) do
|
25
|
+
begin
|
26
|
+
raise "Stuff went wrong during setup"
|
27
|
+
rescue RuntimeError => err
|
28
|
+
err
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
15
32
|
it "logs the error to Sentry" do
|
16
33
|
expect(Raven).to receive(:capture_exception).with(error)
|
17
|
-
error_handler.
|
34
|
+
error_handler.handle_setup_exception(error)
|
18
35
|
end
|
19
36
|
end
|
20
37
|
end
|
data/spec/hutch/logger_spec.rb
CHANGED
@@ -3,24 +3,30 @@ require 'spec_helper'
|
|
3
3
|
describe Hutch::Logging do
|
4
4
|
let(:dummy_object) do
|
5
5
|
class DummyObject
|
6
|
-
include
|
6
|
+
include described_class
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
10
|
describe '#logger' do
|
11
|
+
around do |example|
|
12
|
+
old_logger = described_class.logger
|
13
|
+
described_class.setup_logger
|
14
|
+
example.run
|
15
|
+
described_class.logger = old_logger
|
16
|
+
end
|
17
|
+
|
11
18
|
context 'with the default logger' do
|
12
|
-
subject {
|
19
|
+
subject { described_class.logger }
|
13
20
|
|
14
21
|
it { is_expected.to be_instance_of(Logger) }
|
15
22
|
end
|
16
23
|
|
17
24
|
context 'with a custom logger' do
|
18
|
-
let(:dummy_logger) { double("Dummy logger"
|
19
|
-
after { Hutch::Logging.setup_logger }
|
25
|
+
let(:dummy_logger) { double("Dummy logger") }
|
20
26
|
|
21
27
|
it "users the custom logger" do
|
22
|
-
|
23
|
-
expect(
|
28
|
+
described_class.logger = dummy_logger
|
29
|
+
expect(described_class.logger).to eq(dummy_logger)
|
24
30
|
end
|
25
31
|
end
|
26
32
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'hutch/waiter'
|
2
|
+
|
3
|
+
RSpec.describe Hutch::Waiter do
|
4
|
+
describe '.wait_until_signaled' do
|
5
|
+
let(:pid) { Process.pid }
|
6
|
+
def start_kill_thread(signal)
|
7
|
+
Thread.new do
|
8
|
+
# sleep allows the worker time to set up the signal handling
|
9
|
+
# before the kill signal is sent.
|
10
|
+
sleep 0.001
|
11
|
+
Process.kill signal, pid
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'a QUIT signal is received', if: RSpec::Support::Ruby.mri? do
|
16
|
+
it 'logs that hutch is stopping' do
|
17
|
+
expect(Hutch::Logging.logger).to receive(:info)
|
18
|
+
.with('caught SIGQUIT, stopping hutch...')
|
19
|
+
|
20
|
+
start_kill_thread('QUIT')
|
21
|
+
described_class.wait_until_signaled
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'a TERM signal is received' do
|
26
|
+
it 'logs that hutch is stopping' do
|
27
|
+
expect(Hutch::Logging.logger).to receive(:info)
|
28
|
+
.with('caught SIGTERM, stopping hutch...')
|
29
|
+
|
30
|
+
start_kill_thread('TERM')
|
31
|
+
described_class.wait_until_signaled
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'a INT signal is received' do
|
36
|
+
it 'logs that hutch is stopping' do
|
37
|
+
expect(Hutch::Logging.logger).to receive(:info)
|
38
|
+
.with('caught SIGINT, stopping hutch...')
|
39
|
+
|
40
|
+
start_kill_thread('INT')
|
41
|
+
described_class.wait_until_signaled
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe described_class::SHUTDOWN_SIGNALS do
|
47
|
+
it 'includes only things in Signal.list.keys' do
|
48
|
+
expect(described_class).to eq(described_class & Signal.list.keys)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|