airbrake-ruby 6.1.0-java → 6.1.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.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/lib/airbrake-ruby/filters/git_last_checkout_filter.rb +1 -1
  3. data/lib/airbrake-ruby/nested_exception.rb +10 -1
  4. data/lib/airbrake-ruby/notice.rb +5 -3
  5. data/lib/airbrake-ruby/version.rb +1 -1
  6. metadata +4 -122
  7. data/spec/airbrake_spec.rb +0 -522
  8. data/spec/async_sender_spec.rb +0 -65
  9. data/spec/backtrace_spec.rb +0 -430
  10. data/spec/benchmark_spec.rb +0 -35
  11. data/spec/code_hunk_spec.rb +0 -124
  12. data/spec/config/processor_spec.rb +0 -167
  13. data/spec/config/validator_spec.rb +0 -204
  14. data/spec/config_spec.rb +0 -188
  15. data/spec/context_spec.rb +0 -54
  16. data/spec/deploy_notifier_spec.rb +0 -50
  17. data/spec/file_cache_spec.rb +0 -35
  18. data/spec/filter_chain_spec.rb +0 -124
  19. data/spec/filters/context_filter_spec.rb +0 -32
  20. data/spec/filters/dependency_filter_spec.rb +0 -14
  21. data/spec/filters/exception_attributes_filter_spec.rb +0 -52
  22. data/spec/filters/gem_root_filter_spec.rb +0 -44
  23. data/spec/filters/git_last_checkout_filter_spec.rb +0 -61
  24. data/spec/filters/git_repository_filter_spec.rb +0 -72
  25. data/spec/filters/git_revision_filter_spec.rb +0 -126
  26. data/spec/filters/keys_allowlist_spec.rb +0 -204
  27. data/spec/filters/keys_blocklist_spec.rb +0 -242
  28. data/spec/filters/root_directory_filter_spec.rb +0 -39
  29. data/spec/filters/sql_filter_spec.rb +0 -274
  30. data/spec/filters/system_exit_filter_spec.rb +0 -16
  31. data/spec/filters/thread_filter_spec.rb +0 -281
  32. data/spec/fixtures/notroot.txt +0 -7
  33. data/spec/fixtures/project_root/code.rb +0 -221
  34. data/spec/fixtures/project_root/empty_file.rb +0 -0
  35. data/spec/fixtures/project_root/long_line.txt +0 -1
  36. data/spec/fixtures/project_root/short_file.rb +0 -3
  37. data/spec/fixtures/project_root/vendor/bundle/ignored_file.rb +0 -5
  38. data/spec/helpers.rb +0 -9
  39. data/spec/ignorable_spec.rb +0 -14
  40. data/spec/inspectable_spec.rb +0 -45
  41. data/spec/loggable_spec.rb +0 -17
  42. data/spec/monotonic_time_spec.rb +0 -25
  43. data/spec/nested_exception_spec.rb +0 -73
  44. data/spec/notice_notifier/options_spec.rb +0 -269
  45. data/spec/notice_notifier_spec.rb +0 -361
  46. data/spec/notice_spec.rb +0 -300
  47. data/spec/performance_breakdown_spec.rb +0 -11
  48. data/spec/performance_notifier_spec.rb +0 -645
  49. data/spec/promise_spec.rb +0 -203
  50. data/spec/query_spec.rb +0 -11
  51. data/spec/queue_spec.rb +0 -18
  52. data/spec/remote_settings/callback_spec.rb +0 -162
  53. data/spec/remote_settings/settings_data_spec.rb +0 -348
  54. data/spec/remote_settings_spec.rb +0 -201
  55. data/spec/request_spec.rb +0 -9
  56. data/spec/response_spec.rb +0 -110
  57. data/spec/spec_helper.rb +0 -100
  58. data/spec/stashable_spec.rb +0 -23
  59. data/spec/stat_spec.rb +0 -39
  60. data/spec/sync_sender_spec.rb +0 -168
  61. data/spec/tdigest_spec.rb +0 -235
  62. data/spec/thread_pool_spec.rb +0 -196
  63. data/spec/time_truncate_spec.rb +0 -30
  64. data/spec/timed_trace_spec.rb +0 -127
  65. data/spec/truncator_spec.rb +0 -267
@@ -1,196 +0,0 @@
1
- RSpec.describe Airbrake::ThreadPool do
2
- subject(:thread_pool) do
3
- described_class.new(
4
- worker_size: worker_size,
5
- queue_size: queue_size,
6
- block: proc { |message| tasks << message },
7
- )
8
- end
9
-
10
- let(:tasks) { [] }
11
- let(:worker_size) { 1 }
12
- let(:queue_size) { 2 }
13
-
14
- describe "#<<" do
15
- it "returns true" do
16
- retval = thread_pool << 1
17
- thread_pool.close
18
- expect(retval).to be(true)
19
- end
20
-
21
- it "performs work in background" do
22
- thread_pool << 2
23
- thread_pool << 1
24
- thread_pool.close
25
-
26
- expect(tasks).to eq([2, 1])
27
- end
28
-
29
- context "when the queue is full" do
30
- subject(:full_thread_pool) do
31
- described_class.new(
32
- worker_size: 1,
33
- queue_size: 1,
34
- block: proc { |message| tasks << message },
35
- )
36
- end
37
-
38
- before do
39
- # rubocop:disable RSpec/SubjectStub
40
- allow(full_thread_pool).to receive(:backlog).and_return(queue_size)
41
- # rubocop:enable RSpec/SubjectStub
42
- end
43
-
44
- it "returns false" do
45
- retval = full_thread_pool << 1
46
- full_thread_pool.close
47
- expect(retval).to be(false)
48
- end
49
-
50
- it "discards tasks" do
51
- 200.times { full_thread_pool << 1 }
52
- full_thread_pool.close
53
-
54
- expect(tasks.size).to be_zero
55
- end
56
-
57
- it "logs discarded tasks" do
58
- allow(Airbrake::Loggable.instance).to receive(:info)
59
-
60
- 15.times { full_thread_pool << 1 }
61
- full_thread_pool.close
62
-
63
- expect(Airbrake::Loggable.instance)
64
- .to have_received(:info).exactly(15).times
65
- end
66
- end
67
- end
68
-
69
- describe "#backlog" do
70
- let(:worker_size) { 0 }
71
-
72
- it "returns the size of the queue" do
73
- thread_pool << 1
74
- expect(thread_pool.backlog).to eq(1)
75
- end
76
- end
77
-
78
- describe "#has_workers?" do
79
- it "returns false when the thread pool is not closed, but has 0 workers" do
80
- thread_pool.workers.list.each do |worker|
81
- worker.kill.join
82
- end
83
- expect(thread_pool).not_to have_workers
84
- end
85
-
86
- it "returns false when the thread pool is closed" do
87
- thread_pool.close
88
- expect(thread_pool).not_to have_workers
89
- end
90
-
91
- describe "forking behavior" do
92
- before do
93
- skip('fork() is unsupported on JRuby') if %w[jruby].include?(RUBY_ENGINE)
94
- unless Process.respond_to?(:last_status)
95
- skip('Process.last_status is unsupported on this Ruby')
96
- end
97
- end
98
-
99
- # rubocop:disable RSpec/MultipleExpectations
100
- it "respawns workers on fork()" do
101
- pid = fork { expect(thread_pool).to have_workers }
102
- Process.wait(pid)
103
- thread_pool.close
104
-
105
- expect(Process.last_status).to be_success
106
- expect(thread_pool).not_to have_workers
107
- end
108
- # rubocop:enable RSpec/MultipleExpectations
109
-
110
- it "ensures that a new thread group is created per process" do
111
- thread_pool << 1
112
- pid = fork { thread_pool.has_workers? }
113
- Process.wait(pid)
114
- thread_pool.close
115
-
116
- expect(Process.last_status).to be_success
117
- end
118
- end
119
- end
120
-
121
- describe "#close" do
122
- context "when there's no work to do" do
123
- it "joins the spawned thread" do
124
- workers = thread_pool.workers.list
125
- expect(workers).to all(be_alive)
126
-
127
- thread_pool.close
128
- expect(workers).to all(be_stop)
129
- end
130
- end
131
-
132
- context "when there's some work to do" do
133
- it "logs how many tasks are left to process" do
134
- allow(Airbrake::Loggable.instance).to receive(:debug)
135
-
136
- thread_pool = described_class.new(
137
- name: 'foo', worker_size: 0, queue_size: 2, block: proc {},
138
- )
139
-
140
- 2.times { thread_pool << 1 }
141
- thread_pool.close
142
-
143
- expect(Airbrake::Loggable.instance).to have_received(:debug).with(
144
- /waiting to process \d+ task\(s\)/,
145
- )
146
- expect(Airbrake::Loggable.instance).to have_received(:debug).with(/foo.+closed/)
147
- end
148
-
149
- it "waits until the queue gets empty" do
150
- thread_pool = described_class.new(
151
- worker_size: 1, queue_size: 2, block: proc {},
152
- )
153
-
154
- 10.times { thread_pool << 1 }
155
- thread_pool.close
156
- expect(thread_pool.backlog).to be_zero
157
- end
158
- end
159
-
160
- context "when it was already closed" do
161
- it "doesn't increase the queue size" do
162
- begin
163
- thread_pool.close
164
- rescue Airbrake::Error
165
- nil
166
- end
167
-
168
- expect(thread_pool.backlog).to be_zero
169
- end
170
-
171
- it "raises error" do
172
- thread_pool.close
173
- expect { thread_pool.close }.to raise_error(
174
- Airbrake::Error, 'this thread pool is closed already'
175
- )
176
- end
177
- end
178
- end
179
-
180
- describe "#spawn_workers" do
181
- after { thread_pool.close }
182
-
183
- it "spawns an enclosed thread group" do
184
- expect(thread_pool.workers).to be_a(ThreadGroup)
185
- expect(thread_pool.workers).to be_enclosed
186
- end
187
-
188
- it "spawns threads that are alive" do
189
- expect(thread_pool.workers.list).to all(be_alive)
190
- end
191
-
192
- it "spawns exactly `workers_size` workers" do
193
- expect(thread_pool.workers.list.size).to eq(worker_size)
194
- end
195
- end
196
- end
@@ -1,30 +0,0 @@
1
- RSpec.describe Airbrake::TimeTruncate do
2
- time = Time.new(2018, 1, 1, 0, 0, 20, 0)
3
- time_with_zone = Time.new(2018, 1, 1, 0, 0, 20, '-05:00')
4
-
5
- describe "#utc_truncate_minutes" do
6
- shared_examples 'time conversion' do |t|
7
- it "truncates the time to the floor minute and returns an RFC3339 timestamp" do
8
- expect(described_class.utc_truncate_minutes(t))
9
- .to eq('2018-01-01T00:00:00+00:00')
10
- end
11
-
12
- it "converts time with zone to UTC" do
13
- expect(described_class.utc_truncate_minutes(time_with_zone))
14
- .to eq('2018-01-01T05:00:00+00:00')
15
- end
16
- end
17
-
18
- context "when the time argument is a Time object" do
19
- include_examples 'time conversion', time
20
- end
21
-
22
- context "when the time argument is a Float" do
23
- include_examples 'time conversion', time.to_f
24
- end
25
-
26
- context "when the time argument is an Integer" do
27
- include_examples 'time conversion', time.to_i
28
- end
29
- end
30
- end
@@ -1,127 +0,0 @@
1
- RSpec.describe Airbrake::TimedTrace do
2
- subject(:timed_trace) { described_class.new }
3
-
4
- describe ".span" do
5
- it "returns a timed trace" do
6
- expect(described_class.span('operation') { anything }).to be_a(described_class)
7
- end
8
-
9
- it "returns a timed trace with a stopped span" do
10
- timed_trace = described_class.span('operation') { anything }
11
- expect(timed_trace.spans).to match('operation' => be > 0)
12
- end
13
- end
14
-
15
- describe "#span" do
16
- it "captures a span" do
17
- timed_trace.span('operation') { anything }
18
- expect(timed_trace.spans).to match('operation' => be > 0)
19
- end
20
- end
21
-
22
- describe "#start_span" do
23
- context "when called once" do
24
- it "returns true" do
25
- expect(timed_trace.start_span('operation')).to be(true)
26
- end
27
- end
28
-
29
- context "when called multiple times" do
30
- before { timed_trace.start_span('operation') }
31
-
32
- it "returns false" do
33
- expect(timed_trace.start_span('operation')).to be(false)
34
- end
35
- end
36
-
37
- context "when another span was started" do
38
- before { timed_trace.start_span('operation') }
39
-
40
- it "returns true" do
41
- expect(timed_trace.start_span('another operation')).to be(true)
42
- end
43
- end
44
-
45
- context "when #spans was called" do
46
- before { timed_trace.start_span('operation') }
47
-
48
- it "returns spans with zero values" do
49
- expect(timed_trace.spans).to eq('operation' => 0.0)
50
- end
51
- end
52
- end
53
-
54
- describe "#stop_span" do
55
- context "when #start_span wasn't invoked" do
56
- it "returns false" do
57
- expect(timed_trace.stop_span('operation')).to be(false)
58
- end
59
- end
60
-
61
- context "when #start_span was invoked" do
62
- before { timed_trace.start_span('operation') }
63
-
64
- it "returns true" do
65
- expect(timed_trace.stop_span('operation')).to be(true)
66
- end
67
- end
68
-
69
- context "when multiple spans were started" do
70
- before do
71
- timed_trace.start_span('operation')
72
- timed_trace.start_span('another operation')
73
- end
74
-
75
- context "and when stopping in LIFO order" do
76
- it "returns true for all spans" do
77
- expect(timed_trace.stop_span('another operation')).to be(true)
78
- expect(timed_trace.stop_span('operation')).to be(true)
79
- end
80
- end
81
-
82
- context "and when stopping in FIFO order" do
83
- it "returns true for all spans" do
84
- expect(timed_trace.stop_span('operation')).to be(true)
85
- expect(timed_trace.stop_span('another operation')).to be(true)
86
- end
87
- end
88
- end
89
- end
90
-
91
- describe "#spans" do
92
- context "when no spans were captured" do
93
- it "returns an empty hash" do
94
- expect(timed_trace.spans).to eq({})
95
- end
96
- end
97
-
98
- context "when a span was captured" do
99
- before do
100
- timed_trace.start_span('operation')
101
- timed_trace.stop_span('operation')
102
- end
103
-
104
- it "returns a Hash with the corresponding span" do
105
- timed_trace.stop_span('operation')
106
- expect(timed_trace.spans).to match('operation' => be > 0)
107
- end
108
- end
109
-
110
- context "when multiple spans were captured" do
111
- before do
112
- timed_trace.start_span('operation')
113
- timed_trace.stop_span('operation')
114
-
115
- timed_trace.start_span('another operation')
116
- timed_trace.stop_span('another operation')
117
- end
118
-
119
- it "returns a Hash with all spans" do
120
- expect(timed_trace.spans).to match(
121
- 'operation' => be > 0,
122
- 'another operation' => be > 0,
123
- )
124
- end
125
- end
126
- end
127
- end
@@ -1,267 +0,0 @@
1
- RSpec.describe Airbrake::Truncator do
2
- def multiply_by_2_max_len(chr)
3
- chr * 2 * max_len
4
- end
5
-
6
- describe "#truncate" do
7
- subject(:truncator) { described_class.new(max_size).truncate(object) }
8
-
9
- let(:max_size) { 3 }
10
- let(:truncated) { '[Truncated]' }
11
- let(:max_len) { max_size + truncated.length }
12
-
13
- context "given a frozen string" do
14
- let(:object) { multiply_by_2_max_len('a') }
15
-
16
- it "returns a new truncated frozen string" do
17
- expect(truncator.length).to eq(max_len)
18
- expect(truncator).to be_frozen
19
- end
20
- end
21
-
22
- context "given a frozen hash of strings" do
23
- let(:object) do
24
- {
25
- banana: multiply_by_2_max_len('a'),
26
- kiwi: multiply_by_2_max_len('b'),
27
- strawberry: 'c',
28
- shrimp: 'd',
29
- }.freeze
30
- end
31
-
32
- it "returns a hash of the same size" do
33
- expect(truncator.size).to eq(max_size)
34
- end
35
-
36
- it "returns a frozen hash" do
37
- expect(truncator).to be_frozen
38
- end
39
-
40
- it "returns a hash with truncated values" do
41
- expect(truncator).to eq(
42
- banana: 'aaa[Truncated]', kiwi: 'bbb[Truncated]', strawberry: 'c',
43
- )
44
- end
45
-
46
- it "returns a hash with truncated strings that are frozen" do
47
- expect(truncator[:banana]).to be_frozen
48
- expect(truncator[:kiwi]).to be_frozen
49
- end
50
-
51
- it "returns a hash unfrozen untruncated strings" do
52
- expect(truncator[:strawberry]).not_to be_frozen
53
- end
54
- end
55
-
56
- context "given a frozen array of strings" do
57
- let(:object) do
58
- [
59
- multiply_by_2_max_len('a'),
60
- 'b',
61
- multiply_by_2_max_len('c'),
62
- 'd',
63
- ].freeze
64
- end
65
-
66
- it "returns an array of the same size" do
67
- expect(truncator.size).to eq(max_size)
68
- end
69
-
70
- it "returns a frozen array" do
71
- expect(truncator).to be_frozen
72
- end
73
-
74
- it "returns an array with truncated values" do
75
- expect(truncator).to eq(['aaa[Truncated]', 'b', 'ccc[Truncated]'])
76
- end
77
-
78
- it "returns an array with truncated strings that are frozen" do
79
- expect(truncator[0]).to be_frozen
80
- expect(truncator[2]).to be_frozen
81
- end
82
-
83
- it "returns an array with unfrozen untruncated strings" do
84
- expect(truncator[1]).not_to be_frozen
85
- end
86
- end
87
-
88
- context "given a frozen set of strings" do
89
- let(:object) do
90
- Set.new([
91
- multiply_by_2_max_len('a'),
92
- 'b',
93
- multiply_by_2_max_len('c'),
94
- 'd',
95
- ]).freeze
96
- end
97
-
98
- it "returns a set of the same size" do
99
- expect(truncator.size).to eq(max_size)
100
- end
101
-
102
- it "returns a frozen set" do
103
- expect(truncator).to be_frozen
104
- end
105
-
106
- it "returns a set with truncated values" do
107
- expect(truncator).to eq(Set.new(['aaa[Truncated]', 'b', 'ccc[Truncated]']))
108
- end
109
- end
110
-
111
- context "given an arbitrary frozen object that responds to #to_json" do
112
- let(:object) do
113
- obj = Object.new
114
- def obj.to_json
115
- '{"object":"shrimp"}'
116
- end
117
- obj.freeze
118
- end
119
-
120
- it "returns a string of a max len size" do
121
- expect(truncator.length).to eq(max_len)
122
- end
123
-
124
- it "returns a frozen object" do
125
- expect(truncator).to be_frozen
126
- end
127
-
128
- it "converts the object to truncated JSON" do
129
- expect(truncator).to eq('{"o[Truncated]')
130
- end
131
- end
132
-
133
- context "given an arbitrary object that doesn't respond to #to_json" do
134
- let(:object) do
135
- obj = Object.new
136
- allow(obj).to receive(:to_json)
137
- .and_raise(Airbrake::Notice::JSON_EXCEPTIONS.first)
138
- obj
139
- end
140
-
141
- it "converts the object to a truncated string" do
142
- expect(truncator.length).to eq(max_len)
143
- expect(truncator).to eq('#<O[Truncated]')
144
- end
145
- end
146
-
147
- shared_examples 'self returning objects' do |object|
148
- it "returns the passed object" do
149
- expect(described_class.new(max_size).truncate(object)).to eql(object)
150
- end
151
- end
152
-
153
- [1, true, false, :symbol, nil].each do |object|
154
- include_examples 'self returning objects', object
155
- end
156
-
157
- context "given a recursive array" do
158
- let(:object) do
159
- a = %w[aaaaa bb]
160
- a << a
161
- a << 'c'
162
- a
163
- end
164
-
165
- it "prevents recursion" do
166
- expect(truncator).to eq(['aaa[Truncated]', 'bb', '[Circular]'])
167
- end
168
- end
169
-
170
- context "given a recursive array with recursive hashes" do
171
- let(:object) do
172
- a = []
173
- a << a
174
-
175
- h = {}
176
- h[:k] = h
177
- a << h << 'aaaa'
178
- end
179
-
180
- it "prevents recursion" do
181
- expect(truncator).to eq(['[Circular]', { k: '[Circular]' }, 'aaa[Truncated]'])
182
- expect(truncator).to be_frozen
183
- end
184
- end
185
-
186
- context "given a recursive set with recursive arrays" do
187
- let(:object) do
188
- s = Set.new
189
- s << s
190
-
191
- h = {}
192
- h[:k] = h
193
- s << h << 'aaaa'
194
- end
195
-
196
- it "prevents recursion" do
197
- expect(truncator).to eq(
198
- Set.new(['[Circular]', { k: '[Circular]' }, 'aaa[Truncated]']),
199
- )
200
- expect(truncator).to be_frozen
201
- end
202
- end
203
-
204
- context "given a hash with long strings" do
205
- let(:object) do
206
- {
207
- a: multiply_by_2_max_len('a'),
208
- b: multiply_by_2_max_len('b'),
209
- c: { d: multiply_by_2_max_len('d'), e: 'e' },
210
- }
211
- end
212
-
213
- it "truncates the long strings" do
214
- expect(truncator).to eq(
215
- a: 'aaa[Truncated]', b: 'bbb[Truncated]', c: { d: 'ddd[Truncated]', e: 'e' },
216
- )
217
- expect(truncator).to be_frozen
218
- end
219
- end
220
-
221
- context "given a string with valid unicode characters" do
222
- let(:object) { "€€€€€" }
223
-
224
- it "truncates the string" do
225
- expect(truncator).to eq("€€€[Truncated]")
226
- end
227
- end
228
-
229
- context "given an ASCII-8BIT string with invalid characters" do
230
- let(:object) do
231
- # Shenanigans to get a bad ASCII-8BIT string. Direct conversion raises error.
232
- encoded = Base64.encode64("\xD3\xE6\xBC\x9D\xBA").encode!('ASCII-8BIT')
233
- Base64.decode64(encoded).freeze
234
- end
235
-
236
- it "converts and truncates the string to UTF-8" do
237
- expect(truncator).to eq("���[Truncated]")
238
- expect(truncator).to be_frozen
239
- end
240
- end
241
-
242
- context "given an array with hashes and hash-like objects with identical keys" do
243
- let(:hashie) { Class.new(Hash) }
244
-
245
- let(:object) do
246
- {
247
- errors: [
248
- { file: 'a' },
249
- { file: 'a' },
250
- hashie.new.merge(file: 'bcde'),
251
- ],
252
- }
253
- end
254
-
255
- it "truncates values" do
256
- expect(truncator).to eq(
257
- errors: [
258
- { file: 'a' },
259
- { file: 'a' },
260
- hashie.new.merge(file: 'bcd[Truncated]'),
261
- ],
262
- )
263
- expect(truncator).to be_frozen
264
- end
265
- end
266
- end
267
- end