airbrake-ruby 6.1.0-java → 6.1.1-java

Sign up to get free protection for your applications and to get access to all the features.
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