airbrake-ruby 4.15.0-java → 5.0.0.rc.1-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 +4 -4
- data/lib/airbrake-ruby.rb +21 -33
- data/lib/airbrake-ruby/async_sender.rb +1 -1
- data/lib/airbrake-ruby/config.rb +34 -6
- data/lib/airbrake-ruby/config/processor.rb +80 -0
- data/lib/airbrake-ruby/config/validator.rb +4 -0
- data/lib/airbrake-ruby/performance_notifier.rb +1 -1
- data/lib/airbrake-ruby/remote_settings.rb +128 -0
- data/lib/airbrake-ruby/remote_settings/settings_data.rb +116 -0
- data/lib/airbrake-ruby/sync_sender.rb +1 -1
- data/lib/airbrake-ruby/version.rb +1 -1
- data/spec/airbrake_spec.rb +45 -22
- data/spec/config/processor_spec.rb +223 -0
- data/spec/config/validator_spec.rb +18 -1
- data/spec/config_spec.rb +8 -4
- data/spec/remote_settings/settings_data_spec.rb +327 -0
- data/spec/remote_settings_spec.rb +212 -0
- data/spec/sync_sender_spec.rb +3 -1
- metadata +13 -4
@@ -23,7 +23,7 @@ module Airbrake
|
|
23
23
|
# @param [#to_json] data
|
24
24
|
# @param [URI::HTTPS] endpoint
|
25
25
|
# @return [Hash{String=>String}] the parsed HTTP response
|
26
|
-
def send(data, promise, endpoint = @config.
|
26
|
+
def send(data, promise, endpoint = @config.error_endpoint)
|
27
27
|
return promise if rate_limited_ip?(promise)
|
28
28
|
|
29
29
|
response = nil
|
data/spec/airbrake_spec.rb
CHANGED
@@ -1,4 +1,13 @@
|
|
1
1
|
RSpec.describe Airbrake do
|
2
|
+
let(:remote_settings) { instance_double(Airbrake::RemoteSettings) }
|
3
|
+
|
4
|
+
before do
|
5
|
+
allow(Airbrake::RemoteSettings).to receive(:poll).and_return(remote_settings)
|
6
|
+
allow(remote_settings).to receive(:stop_polling)
|
7
|
+
end
|
8
|
+
|
9
|
+
after { described_class.instance_variable_set(:@remote_settings, nil) }
|
10
|
+
|
2
11
|
it "gets initialized with a performance notifier" do
|
3
12
|
expect(described_class.performance_notifier).not_to be_nil
|
4
13
|
end
|
@@ -100,10 +109,10 @@ RSpec.describe Airbrake do
|
|
100
109
|
end
|
101
110
|
|
102
111
|
context "when blocklist_keys gets configured" do
|
103
|
-
before { allow(
|
112
|
+
before { allow(described_class.notice_notifier).to receive(:add_filter) }
|
104
113
|
|
105
114
|
it "adds blocklist filter" do
|
106
|
-
expect(
|
115
|
+
expect(described_class.notice_notifier).to receive(:add_filter)
|
107
116
|
.with(an_instance_of(Airbrake::Filters::KeysBlocklist))
|
108
117
|
described_class.configure { |c| c.blocklist_keys = %w[password] }
|
109
118
|
end
|
@@ -115,10 +124,10 @@ RSpec.describe Airbrake do
|
|
115
124
|
end
|
116
125
|
|
117
126
|
context "when allowlist_keys gets configured" do
|
118
|
-
before { allow(
|
127
|
+
before { allow(described_class.notice_notifier).to receive(:add_filter) }
|
119
128
|
|
120
129
|
it "adds allowlist filter" do
|
121
|
-
expect(
|
130
|
+
expect(described_class.notice_notifier).to receive(:add_filter)
|
122
131
|
.with(an_instance_of(Airbrake::Filters::KeysAllowlist))
|
123
132
|
described_class.configure { |c| c.allowlist_keys = %w[banana] }
|
124
133
|
end
|
@@ -130,10 +139,10 @@ RSpec.describe Airbrake do
|
|
130
139
|
end
|
131
140
|
|
132
141
|
context "when root_directory gets configured" do
|
133
|
-
before { allow(
|
142
|
+
before { allow(described_class.notice_notifier).to receive(:add_filter) }
|
134
143
|
|
135
144
|
it "adds root directory filter" do
|
136
|
-
expect(
|
145
|
+
expect(described_class.notice_notifier).to receive(:add_filter)
|
137
146
|
.with(an_instance_of(Airbrake::Filters::RootDirectoryFilter))
|
138
147
|
described_class.configure { |c| c.root_directory = '/my/path' }
|
139
148
|
end
|
@@ -145,7 +154,7 @@ RSpec.describe Airbrake do
|
|
145
154
|
end
|
146
155
|
|
147
156
|
it "adds git revision filter" do
|
148
|
-
expect(
|
157
|
+
expect(described_class.notice_notifier).to receive(:add_filter)
|
149
158
|
.with(an_instance_of(Airbrake::Filters::GitRevisionFilter))
|
150
159
|
described_class.configure { |c| c.root_directory = '/my/path' }
|
151
160
|
end
|
@@ -157,7 +166,7 @@ RSpec.describe Airbrake do
|
|
157
166
|
end
|
158
167
|
|
159
168
|
it "adds git repository filter" do
|
160
|
-
expect(
|
169
|
+
expect(described_class.notice_notifier).to receive(:add_filter)
|
161
170
|
.with(an_instance_of(Airbrake::Filters::GitRepositoryFilter))
|
162
171
|
described_class.configure { |c| c.root_directory = '/my/path' }
|
163
172
|
end
|
@@ -169,7 +178,7 @@ RSpec.describe Airbrake do
|
|
169
178
|
end
|
170
179
|
|
171
180
|
it "adds git last checkout filter" do
|
172
|
-
expect(
|
181
|
+
expect(described_class.notice_notifier).to receive(:add_filter)
|
173
182
|
.with(an_instance_of(Airbrake::Filters::GitLastCheckoutFilter))
|
174
183
|
described_class.configure { |c| c.root_directory = '/my/path' }
|
175
184
|
end
|
@@ -182,7 +191,7 @@ RSpec.describe Airbrake do
|
|
182
191
|
end
|
183
192
|
end
|
184
193
|
|
185
|
-
describe "
|
194
|
+
describe ".notify_request" do
|
186
195
|
context "when :stash key is not provided" do
|
187
196
|
it "doesn't add anything to the stash of the request" do
|
188
197
|
expect(described_class.performance_notifier).to receive(:notify) do |request|
|
@@ -217,7 +226,7 @@ RSpec.describe Airbrake do
|
|
217
226
|
end
|
218
227
|
end
|
219
228
|
|
220
|
-
describe "
|
229
|
+
describe ".notify_request_sync" do
|
221
230
|
it "notifies request synchronously" do
|
222
231
|
expect(described_class.performance_notifier).to receive(:notify_sync)
|
223
232
|
|
@@ -233,7 +242,7 @@ RSpec.describe Airbrake do
|
|
233
242
|
end
|
234
243
|
end
|
235
244
|
|
236
|
-
describe "
|
245
|
+
describe ".notify_query" do
|
237
246
|
context "when :stash key is not provided" do
|
238
247
|
it "doesn't add anything to the stash of the query" do
|
239
248
|
expect(described_class.performance_notifier).to receive(:notify) do |query|
|
@@ -268,7 +277,7 @@ RSpec.describe Airbrake do
|
|
268
277
|
end
|
269
278
|
end
|
270
279
|
|
271
|
-
describe "
|
280
|
+
describe ".notify_query_sync" do
|
272
281
|
it "notifies query synchronously" do
|
273
282
|
expect(described_class.performance_notifier).to receive(:notify_sync)
|
274
283
|
|
@@ -284,7 +293,7 @@ RSpec.describe Airbrake do
|
|
284
293
|
end
|
285
294
|
end
|
286
295
|
|
287
|
-
describe "
|
296
|
+
describe ".notify_performance_breakdown" do
|
288
297
|
context "when :stash key is not provided" do
|
289
298
|
it "doesn't add anything to the stash of the performance breakdown" do
|
290
299
|
expect(described_class.performance_notifier).to receive(:notify) do |query|
|
@@ -322,7 +331,7 @@ RSpec.describe Airbrake do
|
|
322
331
|
end
|
323
332
|
end
|
324
333
|
|
325
|
-
describe "
|
334
|
+
describe ".notify_performance_breakdown_sync" do
|
326
335
|
it "notifies performance breakdown synchronously" do
|
327
336
|
expect(described_class.performance_notifier).to receive(:notify_sync)
|
328
337
|
|
@@ -339,7 +348,7 @@ RSpec.describe Airbrake do
|
|
339
348
|
end
|
340
349
|
end
|
341
350
|
|
342
|
-
describe "
|
351
|
+
describe ".notify_queue" do
|
343
352
|
context "when :stash key is not provided" do
|
344
353
|
it "doesn't add anything to the stash of the queue" do
|
345
354
|
expect(described_class.performance_notifier).to receive(:notify) do |queue|
|
@@ -370,7 +379,7 @@ RSpec.describe Airbrake do
|
|
370
379
|
end
|
371
380
|
end
|
372
381
|
|
373
|
-
describe "
|
382
|
+
describe ".notify_queue_sync" do
|
374
383
|
it "notifies queue synchronously" do
|
375
384
|
expect(described_class.performance_notifier).to receive(:notify_sync)
|
376
385
|
|
@@ -404,33 +413,47 @@ RSpec.describe Airbrake do
|
|
404
413
|
end
|
405
414
|
|
406
415
|
describe ".close" do
|
407
|
-
after {
|
416
|
+
after { described_class.reset }
|
408
417
|
|
409
418
|
context "when notice_notifier is defined" do
|
410
419
|
it "gets closed" do
|
411
|
-
expect(
|
420
|
+
expect(described_class.notice_notifier).to receive(:close)
|
412
421
|
end
|
413
422
|
end
|
414
423
|
|
415
424
|
context "when notice_notifier is undefined" do
|
416
425
|
it "doesn't get closed (because it wasn't initialized)" do
|
417
|
-
|
426
|
+
described_class.instance_variable_set(:@notice_notifier, nil)
|
418
427
|
expect_any_instance_of(Airbrake::NoticeNotifier).not_to receive(:close)
|
419
428
|
end
|
420
429
|
end
|
421
430
|
|
422
431
|
context "when performance_notifier is defined" do
|
423
432
|
it "gets closed" do
|
424
|
-
expect(
|
433
|
+
expect(described_class.performance_notifier).to receive(:close)
|
425
434
|
end
|
426
435
|
end
|
427
436
|
|
428
437
|
context "when perforance_notifier is undefined" do
|
429
438
|
it "doesn't get closed (because it wasn't initialized)" do
|
430
|
-
|
439
|
+
described_class.instance_variable_set(:@performance_notifier, nil)
|
431
440
|
expect_any_instance_of(Airbrake::PerformanceNotifier)
|
432
441
|
.not_to receive(:close)
|
433
442
|
end
|
434
443
|
end
|
444
|
+
|
445
|
+
context "when remote settings are defined" do
|
446
|
+
it "stops polling" do
|
447
|
+
described_class.instance_variable_set(:@remote_settings, remote_settings)
|
448
|
+
expect(remote_settings).to receive(:stop_polling)
|
449
|
+
end
|
450
|
+
end
|
451
|
+
|
452
|
+
context "when remote settings are undefined" do
|
453
|
+
it "doesn't stop polling (because they weren't initialized)" do
|
454
|
+
described_class.instance_variable_set(:@remote_settings, nil)
|
455
|
+
expect(remote_settings).not_to receive(:stop_polling)
|
456
|
+
end
|
457
|
+
end
|
435
458
|
end
|
436
459
|
end
|
@@ -0,0 +1,223 @@
|
|
1
|
+
RSpec.describe Airbrake::Config::Processor do
|
2
|
+
let(:notifier) { Airbrake::NoticeNotifier.new }
|
3
|
+
|
4
|
+
describe "#process_blocklist" do
|
5
|
+
let(:config) { Airbrake::Config.new(blocklist_keys: %w[a b c]) }
|
6
|
+
|
7
|
+
context "when there ARE blocklist keys" do
|
8
|
+
it "adds the blocklist filter" do
|
9
|
+
described_class.new(config).process_blocklist(notifier)
|
10
|
+
expect(notifier.has_filter?(Airbrake::Filters::KeysBlocklist)).to eq(true)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context "when there are NO blocklist keys" do
|
15
|
+
let(:config) { Airbrake::Config.new(blocklist_keys: %w[]) }
|
16
|
+
|
17
|
+
it "doesn't add the blocklist filter" do
|
18
|
+
described_class.new(config).process_blocklist(notifier)
|
19
|
+
expect(notifier.has_filter?(Airbrake::Filters::KeysBlocklist))
|
20
|
+
.to eq(false)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "#process_allowlist" do
|
26
|
+
let(:config) { Airbrake::Config.new(allowlist_keys: %w[a b c]) }
|
27
|
+
|
28
|
+
context "when there ARE allowlist keys" do
|
29
|
+
it "adds the allowlist filter" do
|
30
|
+
described_class.new(config).process_allowlist(notifier)
|
31
|
+
expect(notifier.has_filter?(Airbrake::Filters::KeysAllowlist)).to eq(true)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context "when there are NO allowlist keys" do
|
36
|
+
let(:config) { Airbrake::Config.new(allowlist_keys: %w[]) }
|
37
|
+
|
38
|
+
it "doesn't add the allowlist filter" do
|
39
|
+
described_class.new(config).process_allowlist(notifier)
|
40
|
+
expect(notifier.has_filter?(Airbrake::Filters::KeysAllowlist))
|
41
|
+
.to eq(false)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "#process_remote_configuration" do
|
47
|
+
context "when the config doesn't define a project_id" do
|
48
|
+
let(:config) { Airbrake::Config.new(project_id: nil) }
|
49
|
+
|
50
|
+
it "doesn't set remote settings" do
|
51
|
+
expect(Airbrake::RemoteSettings).not_to receive(:poll)
|
52
|
+
described_class.new(config).process_remote_configuration
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context "when the config defines a project_id" do
|
57
|
+
context "and when remote configuration is false" do
|
58
|
+
let(:config) do
|
59
|
+
Airbrake::Config.new(project_id: 123, __remote_configuration: false)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "doesn't set remote settings" do
|
63
|
+
expect(Airbrake::RemoteSettings).not_to receive(:poll)
|
64
|
+
described_class.new(config).process_remote_configuration
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context "and when remote configuration is true" do
|
69
|
+
let(:config) do
|
70
|
+
Airbrake::Config.new(project_id: 123, __remote_configuration: true)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "sets remote settings" do
|
74
|
+
expect(Airbrake::RemoteSettings).to receive(:poll)
|
75
|
+
described_class.new(config).process_remote_configuration
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "#add_filters" do
|
82
|
+
context "when there's a root directory" do
|
83
|
+
let(:config) { Airbrake::Config.new(root_directory: '/abc') }
|
84
|
+
|
85
|
+
it "adds RootDirectoryFilter" do
|
86
|
+
described_class.new(config).add_filters(notifier)
|
87
|
+
expect(notifier.has_filter?(Airbrake::Filters::RootDirectoryFilter))
|
88
|
+
.to eq(true)
|
89
|
+
end
|
90
|
+
|
91
|
+
it "adds GitRevisionFilter" do
|
92
|
+
described_class.new(config).add_filters(notifier)
|
93
|
+
expect(notifier.has_filter?(Airbrake::Filters::GitRevisionFilter))
|
94
|
+
.to eq(true)
|
95
|
+
end
|
96
|
+
|
97
|
+
it "adds GitRepositoryFilter" do
|
98
|
+
described_class.new(config).add_filters(notifier)
|
99
|
+
expect(notifier.has_filter?(Airbrake::Filters::GitRepositoryFilter))
|
100
|
+
.to eq(true)
|
101
|
+
end
|
102
|
+
|
103
|
+
it "adds GitLastCheckoutFilter" do
|
104
|
+
described_class.new(config).add_filters(notifier)
|
105
|
+
expect(notifier.has_filter?(Airbrake::Filters::GitLastCheckoutFilter))
|
106
|
+
.to eq(true)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context "when there's NO root directory" do
|
111
|
+
let(:config) { Airbrake::Config.new(root_directory: nil) }
|
112
|
+
|
113
|
+
it "doesn't add RootDirectoryFilter" do
|
114
|
+
described_class.new(config).add_filters(notifier)
|
115
|
+
expect(notifier.has_filter?(Airbrake::Filters::RootDirectoryFilter))
|
116
|
+
.to eq(false)
|
117
|
+
end
|
118
|
+
|
119
|
+
it "doesn't add GitRevisionFilter" do
|
120
|
+
described_class.new(config).add_filters(notifier)
|
121
|
+
expect(notifier.has_filter?(Airbrake::Filters::GitRevisionFilter))
|
122
|
+
.to eq(false)
|
123
|
+
end
|
124
|
+
|
125
|
+
it "doesn't add GitRepositoryFilter" do
|
126
|
+
described_class.new(config).add_filters(notifier)
|
127
|
+
expect(notifier.has_filter?(Airbrake::Filters::GitRepositoryFilter))
|
128
|
+
.to eq(false)
|
129
|
+
end
|
130
|
+
|
131
|
+
it "doesn't add GitLastCheckoutFilter" do
|
132
|
+
described_class.new(config).add_filters(notifier)
|
133
|
+
expect(notifier.has_filter?(Airbrake::Filters::GitLastCheckoutFilter))
|
134
|
+
.to eq(false)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
describe "#poll_callback" do
|
140
|
+
let(:logger) { Logger.new(File::NULL) }
|
141
|
+
|
142
|
+
let(:config) do
|
143
|
+
Airbrake::Config.new(
|
144
|
+
project_id: 123,
|
145
|
+
__remote_configuration: true,
|
146
|
+
logger: logger,
|
147
|
+
)
|
148
|
+
end
|
149
|
+
|
150
|
+
let(:data) do
|
151
|
+
instance_double(Airbrake::RemoteSettings::SettingsData)
|
152
|
+
end
|
153
|
+
|
154
|
+
before do
|
155
|
+
allow(data).to receive(:to_h)
|
156
|
+
allow(data).to receive(:error_host)
|
157
|
+
allow(data).to receive(:apm_host)
|
158
|
+
allow(data).to receive(:error_notifications?)
|
159
|
+
allow(data).to receive(:performance_stats?)
|
160
|
+
end
|
161
|
+
|
162
|
+
it "logs given data" do
|
163
|
+
expect(logger).to receive(:debug).with(/applying remote settings/)
|
164
|
+
described_class.new(config).poll_callback(data)
|
165
|
+
end
|
166
|
+
|
167
|
+
it "sets the error_notifications option" do
|
168
|
+
config.error_notifications = false
|
169
|
+
expect(data).to receive(:error_notifications?).and_return(true)
|
170
|
+
|
171
|
+
described_class.new(config).poll_callback(data)
|
172
|
+
expect(config.error_notifications).to eq(true)
|
173
|
+
end
|
174
|
+
|
175
|
+
it "sets the performance_stats option" do
|
176
|
+
config.performance_stats = false
|
177
|
+
expect(data).to receive(:performance_stats?).and_return(true)
|
178
|
+
|
179
|
+
described_class.new(config).poll_callback(data)
|
180
|
+
expect(config.performance_stats).to eq(true)
|
181
|
+
end
|
182
|
+
|
183
|
+
context "when error_host returns a value" do
|
184
|
+
it "sets the error_host option" do
|
185
|
+
config.error_host = 'http://api.airbrake.io'
|
186
|
+
allow(data).to receive(:error_host).and_return('https://api.example.com')
|
187
|
+
|
188
|
+
described_class.new(config).poll_callback(data)
|
189
|
+
expect(config.error_host).to eq('https://api.example.com')
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
context "when error_host returns nil" do
|
194
|
+
it "doesn't modify the error_host option" do
|
195
|
+
config.error_host = 'http://api.airbrake.io'
|
196
|
+
allow(data).to receive(:error_host).and_return(nil)
|
197
|
+
|
198
|
+
described_class.new(config).poll_callback(data)
|
199
|
+
expect(config.error_host).to eq('http://api.airbrake.io')
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
context "when apm_host returns a value" do
|
204
|
+
it "sets the apm_host option" do
|
205
|
+
config.apm_host = 'http://api.airbrake.io'
|
206
|
+
allow(data).to receive(:apm_host).and_return('https://api.example.com')
|
207
|
+
|
208
|
+
described_class.new(config).poll_callback(data)
|
209
|
+
expect(config.apm_host).to eq('https://api.example.com')
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
context "when apm_host returns nil" do
|
214
|
+
it "doesn't modify the apm_host option" do
|
215
|
+
config.apm_host = 'http://api.airbrake.io'
|
216
|
+
allow(data).to receive(:apm_host).and_return(nil)
|
217
|
+
|
218
|
+
described_class.new(config).poll_callback(data)
|
219
|
+
expect(config.apm_host).to eq('http://api.airbrake.io')
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
@@ -169,7 +169,7 @@ RSpec.describe Airbrake::Config::Validator do
|
|
169
169
|
}
|
170
170
|
end
|
171
171
|
|
172
|
-
it "returns a
|
172
|
+
it "returns a resolved promise" do
|
173
173
|
promise = described_class.check_notify_ability(config)
|
174
174
|
expect(promise).to be_resolved
|
175
175
|
end
|
@@ -180,5 +180,22 @@ RSpec.describe Airbrake::Config::Validator do
|
|
180
180
|
described_class.check_notify_ability(config)
|
181
181
|
end
|
182
182
|
end
|
183
|
+
|
184
|
+
context "when the error_notifications option is false" do
|
185
|
+
let(:config_params) do
|
186
|
+
{
|
187
|
+
project_id: valid_id,
|
188
|
+
project_key: valid_key,
|
189
|
+
error_notifications: false,
|
190
|
+
}
|
191
|
+
end
|
192
|
+
|
193
|
+
it "returns a rejected promise" do
|
194
|
+
promise = described_class.check_notify_ability(config)
|
195
|
+
expect(promise.value).to eq(
|
196
|
+
'error' => "error notifications are disabled",
|
197
|
+
)
|
198
|
+
end
|
199
|
+
end
|
183
200
|
end
|
184
201
|
end
|