airbrake-ruby 6.1.0-java → 6.2.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.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/lib/airbrake-ruby/async_sender.rb +11 -15
  3. data/lib/airbrake-ruby/backlog.rb +123 -0
  4. data/lib/airbrake-ruby/config.rb +7 -0
  5. data/lib/airbrake-ruby/filters/git_last_checkout_filter.rb +1 -1
  6. data/lib/airbrake-ruby/nested_exception.rb +22 -1
  7. data/lib/airbrake-ruby/notice.rb +5 -3
  8. data/lib/airbrake-ruby/notice_notifier.rb +1 -0
  9. data/lib/airbrake-ruby/performance_notifier.rb +1 -0
  10. data/lib/airbrake-ruby/response.rb +56 -5
  11. data/lib/airbrake-ruby/sync_sender.rb +41 -10
  12. data/lib/airbrake-ruby/version.rb +1 -1
  13. data/lib/airbrake-ruby.rb +2 -1
  14. metadata +5 -122
  15. data/spec/airbrake_spec.rb +0 -522
  16. data/spec/async_sender_spec.rb +0 -65
  17. data/spec/backtrace_spec.rb +0 -430
  18. data/spec/benchmark_spec.rb +0 -35
  19. data/spec/code_hunk_spec.rb +0 -124
  20. data/spec/config/processor_spec.rb +0 -167
  21. data/spec/config/validator_spec.rb +0 -204
  22. data/spec/config_spec.rb +0 -188
  23. data/spec/context_spec.rb +0 -54
  24. data/spec/deploy_notifier_spec.rb +0 -50
  25. data/spec/file_cache_spec.rb +0 -35
  26. data/spec/filter_chain_spec.rb +0 -124
  27. data/spec/filters/context_filter_spec.rb +0 -32
  28. data/spec/filters/dependency_filter_spec.rb +0 -14
  29. data/spec/filters/exception_attributes_filter_spec.rb +0 -52
  30. data/spec/filters/gem_root_filter_spec.rb +0 -44
  31. data/spec/filters/git_last_checkout_filter_spec.rb +0 -61
  32. data/spec/filters/git_repository_filter_spec.rb +0 -72
  33. data/spec/filters/git_revision_filter_spec.rb +0 -126
  34. data/spec/filters/keys_allowlist_spec.rb +0 -204
  35. data/spec/filters/keys_blocklist_spec.rb +0 -242
  36. data/spec/filters/root_directory_filter_spec.rb +0 -39
  37. data/spec/filters/sql_filter_spec.rb +0 -274
  38. data/spec/filters/system_exit_filter_spec.rb +0 -16
  39. data/spec/filters/thread_filter_spec.rb +0 -281
  40. data/spec/fixtures/notroot.txt +0 -7
  41. data/spec/fixtures/project_root/code.rb +0 -221
  42. data/spec/fixtures/project_root/empty_file.rb +0 -0
  43. data/spec/fixtures/project_root/long_line.txt +0 -1
  44. data/spec/fixtures/project_root/short_file.rb +0 -3
  45. data/spec/fixtures/project_root/vendor/bundle/ignored_file.rb +0 -5
  46. data/spec/helpers.rb +0 -9
  47. data/spec/ignorable_spec.rb +0 -14
  48. data/spec/inspectable_spec.rb +0 -45
  49. data/spec/loggable_spec.rb +0 -17
  50. data/spec/monotonic_time_spec.rb +0 -25
  51. data/spec/nested_exception_spec.rb +0 -73
  52. data/spec/notice_notifier/options_spec.rb +0 -269
  53. data/spec/notice_notifier_spec.rb +0 -361
  54. data/spec/notice_spec.rb +0 -300
  55. data/spec/performance_breakdown_spec.rb +0 -11
  56. data/spec/performance_notifier_spec.rb +0 -645
  57. data/spec/promise_spec.rb +0 -203
  58. data/spec/query_spec.rb +0 -11
  59. data/spec/queue_spec.rb +0 -18
  60. data/spec/remote_settings/callback_spec.rb +0 -162
  61. data/spec/remote_settings/settings_data_spec.rb +0 -348
  62. data/spec/remote_settings_spec.rb +0 -201
  63. data/spec/request_spec.rb +0 -9
  64. data/spec/response_spec.rb +0 -110
  65. data/spec/spec_helper.rb +0 -100
  66. data/spec/stashable_spec.rb +0 -23
  67. data/spec/stat_spec.rb +0 -39
  68. data/spec/sync_sender_spec.rb +0 -168
  69. data/spec/tdigest_spec.rb +0 -235
  70. data/spec/thread_pool_spec.rb +0 -196
  71. data/spec/time_truncate_spec.rb +0 -30
  72. data/spec/timed_trace_spec.rb +0 -127
  73. data/spec/truncator_spec.rb +0 -267
@@ -1,65 +0,0 @@
1
- RSpec.describe Airbrake::AsyncSender do
2
- let(:endpoint) { 'https://api.airbrake.io/api/v3/projects/1/notices' }
3
- let(:queue_size) { 10 }
4
- let(:notice) { Airbrake::Notice.new(AirbrakeTestError.new) }
5
-
6
- before do
7
- stub_request(:post, endpoint).to_return(status: 201, body: '{}')
8
- Airbrake::Config.instance = Airbrake::Config.new(
9
- project_id: '1',
10
- workers: 3,
11
- queue_size: 10,
12
- )
13
- end
14
-
15
- describe "#send" do
16
- subject(:async_sender) { described_class.new }
17
-
18
- context "when sender has the capacity to send" do
19
- it "sends notices to Airbrake" do
20
- 2.times { async_sender.send(notice, Airbrake::Promise.new) }
21
- async_sender.close
22
-
23
- expect(a_request(:post, endpoint)).to have_been_made.twice
24
- end
25
-
26
- it "returns a resolved promise" do
27
- promise = Airbrake::Promise.new
28
- async_sender.send(notice, promise)
29
- async_sender.close
30
-
31
- expect(promise).to be_resolved
32
- end
33
- end
34
-
35
- context "when sender has exceeded the capacity to send" do
36
- before do
37
- Airbrake::Config.instance = Airbrake::Config.new(
38
- project_id: '1',
39
- workers: 0,
40
- queue_size: 1,
41
- )
42
- end
43
-
44
- it "doesn't send the exceeded notices to Airbrake" do
45
- 15.times { async_sender.send(notice, Airbrake::Promise.new) }
46
- async_sender.close
47
-
48
- expect(a_request(:post, endpoint)).not_to have_been_made
49
- end
50
-
51
- it "returns a rejected promise" do
52
- promise = nil
53
- 15.times do
54
- promise = async_sender.send(notice, Airbrake::Promise.new)
55
- end
56
- async_sender.close
57
-
58
- expect(promise).to be_rejected
59
- expect(promise.value).to eq(
60
- 'error' => "AsyncSender has reached its capacity of 1",
61
- )
62
- end
63
- end
64
- end
65
- end
@@ -1,430 +0,0 @@
1
- RSpec.describe Airbrake::Backtrace do
2
- describe ".parse" do
3
- context "UNIX backtrace" do
4
- let(:parsed_backtrace) do
5
- # rubocop:disable Layout/LineLength, Style/HashSyntax, Layout/SpaceAroundOperators, Layout/SpaceInsideHashLiteralBraces
6
- [{:file=>"/home/kyrylo/code/airbrake/ruby/spec/spec_helper.rb", :line=>23, :function=>"<top (required)>"},
7
- {:file=>"/opt/rubies/ruby-2.2.2/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb", :line=>54, :function=>"require"},
8
- {:file=>"/opt/rubies/ruby-2.2.2/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb", :line=>54, :function=>"require"},
9
- {:file=>"/home/kyrylo/code/airbrake/ruby/spec/airbrake_spec.rb", :line=>1, :function=>"<top (required)>"},
10
- {:file=>"/home/kyrylo/.gem/ruby/2.2.2/gems/rspec-core-3.3.2/lib/rspec/core/configuration.rb", :line=>1327, :function=>"load"},
11
- {:file=>"/home/kyrylo/.gem/ruby/2.2.2/gems/rspec-core-3.3.2/lib/rspec/core/configuration.rb", :line=>1327, :function=>"block in load_spec_files"},
12
- {:file=>"/home/kyrylo/.gem/ruby/2.2.2/gems/rspec-core-3.3.2/lib/rspec/core/configuration.rb", :line=>1325, :function=>"each"},
13
- {:file=>"/home/kyrylo/.gem/ruby/2.2.2/gems/rspec-core-3.3.2/lib/rspec/core/configuration.rb", :line=>1325, :function=>"load_spec_files"},
14
- {:file=>"/home/kyrylo/.gem/ruby/2.2.2/gems/rspec-core-3.3.2/lib/rspec/core/runner.rb", :line=>102, :function=>"setup"},
15
- {:file=>"/home/kyrylo/.gem/ruby/2.2.2/gems/rspec-core-3.3.2/lib/rspec/core/runner.rb", :line=>88, :function=>"run"},
16
- {:file=>"/home/kyrylo/.gem/ruby/2.2.2/gems/rspec-core-3.3.2/lib/rspec/core/runner.rb", :line=>73, :function=>"run"},
17
- {:file=>"/home/kyrylo/.gem/ruby/2.2.2/gems/rspec-core-3.3.2/lib/rspec/core/runner.rb", :line=>41, :function=>"invoke"},
18
- {:file=>"/home/kyrylo/.gem/ruby/2.2.2/gems/rspec-core-3.3.2/exe/rspec", :line=>4, :function=>"<main>"}]
19
- # rubocop:enable Layout/LineLength, Style/HashSyntax, Layout/SpaceAroundOperators, Layout/SpaceInsideHashLiteralBraces
20
- end
21
-
22
- it "returns a properly formatted array of hashes" do
23
- expect(described_class.parse(AirbrakeTestError.new))
24
- .to eq(parsed_backtrace)
25
- end
26
- end
27
-
28
- context "Windows backtrace" do
29
- let(:windows_bt) do
30
- ["C:/Program Files/Server/app/models/user.rb:13:in `magic'",
31
- "C:/Program Files/Server/app/controllers/users_controller.rb:8:in `index'"]
32
- end
33
-
34
- let(:ex) { AirbrakeTestError.new.tap { |e| e.set_backtrace(windows_bt) } }
35
-
36
- let(:parsed_backtrace) do
37
- # rubocop:disable Layout/LineLength, Style/HashSyntax, Layout/SpaceInsideHashLiteralBraces, Layout/SpaceAroundOperators
38
- [{:file=>"C:/Program Files/Server/app/models/user.rb", :line=>13, :function=>"magic"},
39
- {:file=>"C:/Program Files/Server/app/controllers/users_controller.rb", :line=>8, :function=>"index"}]
40
- # rubocop:enable Layout/LineLength, Style/HashSyntax, Layout/SpaceInsideHashLiteralBraces, Layout/SpaceAroundOperators
41
- end
42
-
43
- it "returns a properly formatted array of hashes" do
44
- expect(described_class.parse(ex)).to eq(parsed_backtrace)
45
- end
46
- end
47
-
48
- context "JRuby Java exceptions" do
49
- let(:backtrace_array) do
50
- # rubocop:disable Layout/LineLength, Style/HashSyntax, Layout/SpaceInsideHashLiteralBraces, Layout/SpaceAroundOperators
51
- [{:file=>"InstanceMethodInvoker.java", :line=>26, :function=>"org.jruby.java.invokers.InstanceMethodInvoker.call"},
52
- {:file=>"Interpreter.java", :line=>126, :function=>"org.jruby.ir.interpreter.Interpreter.INTERPRET_EVAL"},
53
- {:file=>"RubyKernel$INVOKER$s$0$3$eval19.gen", :line=>nil, :function=>"org.jruby.RubyKernel$INVOKER$s$0$3$eval19.call"},
54
- {:file=>"RubyKernel$INVOKER$s$0$0$loop.gen", :line=>nil, :function=>"org.jruby.RubyKernel$INVOKER$s$0$0$loop.call"},
55
- {:file=>"IRBlockBody.java", :line=>139, :function=>"org.jruby.runtime.IRBlockBody.doYield"},
56
- {:file=>"RubyKernel$INVOKER$s$rbCatch19.gen", :line=>nil, :function=>"org.jruby.RubyKernel$INVOKER$s$rbCatch19.call"},
57
- {:file=>"/opt/rubies/jruby-9.0.0.0/bin/irb", :line=>nil, :function=>"opt.rubies.jruby_minus_9_dot_0_dot_0_dot_0.bin.irb.invokeOther4:start"},
58
- {:file=>"/opt/rubies/jruby-9.0.0.0/bin/irb", :line=>13, :function=>"opt.rubies.jruby_minus_9_dot_0_dot_0_dot_0.bin.irb.RUBY$script"},
59
- {:file=>"Compiler.java", :line=>111, :function=>"org.jruby.ir.Compiler$1.load"},
60
- {:file=>"Main.java", :line=>225, :function=>"org.jruby.Main.run"},
61
- {:file=>"Main.java", :line=>197, :function=>"org.jruby.Main.main"}]
62
- # rubocop:enable Layout/LineLength, Style/HashSyntax, Layout/SpaceInsideHashLiteralBraces, Layout/SpaceAroundOperators
63
- end
64
-
65
- it "returns a properly formatted array of hashes" do
66
- allow(described_class).to receive(:java_exception?).and_return(true)
67
-
68
- expect(described_class.parse(JavaAirbrakeTestError.new))
69
- .to eq(backtrace_array)
70
- end
71
- end
72
-
73
- context "JRuby classloader exceptions" do
74
- let(:backtrace) do
75
- # rubocop:disable Layout/LineLength
76
- ['uri_3a_classloader_3a_.META_minus_INF.jruby_dot_home.lib.ruby.stdlib.net.protocol.rbuf_fill(uri:classloader:/META-INF/jruby.home/lib/ruby/stdlib/net/protocol.rb:158)',
77
- 'bin.processors.image_uploader.block in make_streams(bin/processors/image_uploader.rb:21)',
78
- 'uri_3a_classloader_3a_.gems.faye_minus_websocket_minus_0_dot_10_dot_5.lib.faye.websocket.api.invokeOther13:dispatch_event(uri_3a_classloader_3a_/gems/faye_minus_websocket_minus_0_dot_10_dot_5/lib/faye/websocket/uri:classloader:/gems/faye-websocket-0.10.5/lib/faye/websocket/api.rb:109)',
79
- 'tmp.jruby9022301782566983632extract.$dot.META_minus_INF.rails.file(/tmp/jruby9022301782566983632extract/./META-INF/rails.rb:13)']
80
- # rubocop:enable Layout/LineLength
81
- end
82
-
83
- let(:parsed_backtrace) do
84
- # rubocop:disable Layout/LineLength
85
- [{ file: 'uri:classloader:/META-INF/jruby.home/lib/ruby/stdlib/net/protocol.rb', line: 158, function: 'uri_3a_classloader_3a_.META_minus_INF.jruby_dot_home.lib.ruby.stdlib.net.protocol.rbuf_fill' },
86
- { file: 'bin/processors/image_uploader.rb', line: 21, function: 'bin.processors.image_uploader.block in make_streams' },
87
- { file: 'uri_3a_classloader_3a_/gems/faye_minus_websocket_minus_0_dot_10_dot_5/lib/faye/websocket/uri:classloader:/gems/faye-websocket-0.10.5/lib/faye/websocket/api.rb', line: 109, function: 'uri_3a_classloader_3a_.gems.faye_minus_websocket_minus_0_dot_10_dot_5.lib.faye.websocket.api.invokeOther13:dispatch_event' },
88
- { file: '/tmp/jruby9022301782566983632extract/./META-INF/rails.rb', line: 13, function: 'tmp.jruby9022301782566983632extract.$dot.META_minus_INF.rails.file' }]
89
- # rubocop:enable Layout/LineLength
90
- end
91
-
92
- let(:ex) { JavaAirbrakeTestError.new.tap { |e| e.set_backtrace(backtrace) } }
93
-
94
- it "returns a properly formatted array of hashes" do
95
- allow(described_class).to receive(:java_exception?).and_return(true)
96
- expect(described_class.parse(ex)).to eq(parsed_backtrace)
97
- end
98
- end
99
-
100
- context "JRuby non-throwable exceptions" do
101
- let(:backtrace) do
102
- # rubocop:disable Layout/LineLength
103
- ['org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(org/postgresql/core/v3/ConnectionFactoryImpl.java:257)',
104
- 'org.postgresql.core.ConnectionFactory.openConnection(org/postgresql/core/ConnectionFactory.java:65)',
105
- 'org.postgresql.jdbc2.AbstractJdbc2Connection.<init>(org/postgresql/jdbc2/AbstractJdbc2Connection.java:149)']
106
- # rubocop:enable Layout/LineLength
107
- end
108
-
109
- let(:parsed_backtrace) do
110
- # rubocop:disable Layout/LineLength
111
- [{ file: 'org/postgresql/core/v3/ConnectionFactoryImpl.java', line: 257, function: 'org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl' },
112
- { file: 'org/postgresql/core/ConnectionFactory.java', line: 65, function: 'org.postgresql.core.ConnectionFactory.openConnection' },
113
- { file: 'org/postgresql/jdbc2/AbstractJdbc2Connection.java', line: 149, function: 'org.postgresql.jdbc2.AbstractJdbc2Connection.<init>' }]
114
- # rubocop:enable Layout/LineLength
115
- end
116
-
117
- let(:ex) { AirbrakeTestError.new.tap { |e| e.set_backtrace(backtrace) } }
118
-
119
- it "returns a properly formatted array of hashes" do
120
- expect(described_class.parse(ex)).to eq(parsed_backtrace)
121
- end
122
- end
123
-
124
- context "generic backtrace" do
125
- context "when function is absent" do
126
- # rubocop:disable Layout/LineLength
127
- let(:generic_bt) do
128
- ["/home/bingo/bango/assets/stylesheets/error_pages.scss:139:in `animation'",
129
- "/home/bingo/bango/assets/stylesheets/error_pages.scss:139",
130
- "/home/bingo/.gem/ruby/2.2.2/gems/sass-3.4.20/lib/sass/tree/visitors/perform.rb:349:in `block in visit_mixin'"]
131
- end
132
- # rubocop:enable Layout/LineLength
133
-
134
- let(:ex) { AirbrakeTestError.new.tap { |e| e.set_backtrace(generic_bt) } }
135
-
136
- let(:parsed_backtrace) do
137
- # rubocop:disable Layout/LineLength, Style/HashSyntax, Layout/SpaceInsideHashLiteralBraces, Layout/SpaceAroundOperators
138
- [{:file=>"/home/bingo/bango/assets/stylesheets/error_pages.scss", :line=>139, :function=>"animation"},
139
- {:file=>"/home/bingo/bango/assets/stylesheets/error_pages.scss", :line=>139, :function=>nil},
140
- {:file=>"/home/bingo/.gem/ruby/2.2.2/gems/sass-3.4.20/lib/sass/tree/visitors/perform.rb", :line=>349, :function=>"block in visit_mixin"}]
141
- # rubocop:enable Layout/LineLength, Style/HashSyntax, Layout/SpaceInsideHashLiteralBraces, Layout/SpaceAroundOperators
142
- end
143
-
144
- it "returns a properly formatted array of hashes" do
145
- expect(described_class.parse(ex)).to eq(parsed_backtrace)
146
- end
147
- end
148
-
149
- context "when line is absent" do
150
- let(:generic_bt) do
151
- ["/Users/grammakov/repositories/weintervene/config.ru:in `new'"]
152
- end
153
-
154
- let(:ex) { AirbrakeTestError.new.tap { |e| e.set_backtrace(generic_bt) } }
155
-
156
- let(:parsed_backtrace) do
157
- [{ file: '/Users/grammakov/repositories/weintervene/config.ru',
158
- line: nil,
159
- function: 'new' }]
160
- end
161
-
162
- it "returns a properly formatted array of hashes" do
163
- expect(described_class.parse(ex)).to eq(parsed_backtrace)
164
- end
165
- end
166
- end
167
-
168
- context "unknown backtrace" do
169
- let(:unknown_bt) { ['a b c 1 23 321 .rb'] }
170
-
171
- let(:ex) { AirbrakeTestError.new.tap { |e| e.set_backtrace(unknown_bt) } }
172
-
173
- it "returns array of hashes where each unknown frame is marked as 'function'" do
174
- expect(
175
- described_class.parse(ex),
176
- ).to eq([file: nil, line: nil, function: 'a b c 1 23 321 .rb'])
177
- end
178
-
179
- it "logs frames that cannot be parsed" do
180
- allow(Airbrake::Loggable.instance).to receive(:error)
181
-
182
- described_class.parse(ex)
183
-
184
- expect(Airbrake::Loggable.instance).to have_received(:error).with(
185
- /can't parse 'a b c 1 23 321 .rb'/,
186
- )
187
- end
188
- end
189
-
190
- context "given a backtrace with an empty function" do
191
- let(:bt) do
192
- ["/airbrake-ruby/vendor/jruby/1.9/gems/rspec-core-3.4.1/exe/rspec:3:in `'"]
193
- end
194
-
195
- let(:ex) { AirbrakeTestError.new.tap { |e| e.set_backtrace(bt) } }
196
-
197
- let(:parsed_backtrace) do
198
- [{ file: '/airbrake-ruby/vendor/jruby/1.9/gems/rspec-core-3.4.1/exe/rspec',
199
- line: 3,
200
- function: '' }]
201
- end
202
-
203
- it "returns a properly formatted array of hashes" do
204
- expect(described_class.parse(ex)).to eq(parsed_backtrace)
205
- end
206
- end
207
-
208
- context "given an Oracle backtrace" do
209
- let(:bt) do
210
- ['ORA-06512: at "STORE.LI_LICENSES_PACK", line 1945',
211
- 'ORA-06512: at "ACTIVATION.LI_ACT_LICENSES_PACK", line 101',
212
- 'ORA-06512: at line 2',
213
- 'from stmt.c:243:in oci8lib_220.bundle']
214
- end
215
-
216
- let(:ex) { OCIError.new.tap { |e| e.set_backtrace(bt) } }
217
-
218
- let(:parsed_backtrace) do
219
- [{ file: nil, line: 1945, function: 'STORE.LI_LICENSES_PACK' },
220
- { file: nil, line: 101, function: 'ACTIVATION.LI_ACT_LICENSES_PACK' },
221
- { file: nil, line: 2, function: nil },
222
- { file: 'stmt.c', line: 243, function: 'oci8lib_220.bundle' }]
223
- end
224
-
225
- it "returns a properly formatted array of hashes" do
226
- stub_const('OCIError', AirbrakeTestError)
227
- expect(described_class.parse(ex)).to eq(parsed_backtrace)
228
- end
229
- end
230
-
231
- context "given an ExecJS exception" do
232
- let(:bt) do
233
- ['compile ((execjs):6692:19)',
234
- 'eval (<anonymous>:1:10)',
235
- '(execjs):6703:8',
236
- 'require../helpers.exports ((execjs):1:102)',
237
- 'Object.<anonymous> ((execjs):1:120)',
238
- 'Object.Module._extensions..js (module.js:550:10)',
239
- 'bootstrap_node.js:467:3',
240
- "/opt/rubies/ruby-2.3.1/lib/ruby/2.3.0/benchmark.rb:308:in `realtime'"]
241
- end
242
-
243
- let(:ex) { ExecJS::RuntimeError.new.tap { |e| e.set_backtrace(bt) } }
244
-
245
- let(:parsed_backtrace) do
246
- [{ file: '(execjs)', line: 6692, function: 'compile' },
247
- { file: '<anonymous>', line: 1, function: 'eval' },
248
- { file: '(execjs)', line: 6703, function: '' },
249
- { file: '(execjs)', line: 1, function: 'require../helpers.exports' },
250
- { file: '(execjs)', line: 1, function: 'Object.<anonymous>' },
251
- { file: 'module.js', line: 550, function: 'Object.Module._extensions..js' },
252
- { file: 'bootstrap_node.js', line: 467, function: '' },
253
- { file: '/opt/rubies/ruby-2.3.1/lib/ruby/2.3.0/benchmark.rb',
254
- line: 308,
255
- function: 'realtime' }]
256
- end
257
-
258
- it "returns a properly formatted array of hashes" do
259
- stub_const('ExecJS::RuntimeError', AirbrakeTestError)
260
- expect(described_class.parse(ex)).to eq(parsed_backtrace)
261
- end
262
- end
263
-
264
- context "when code hunks are enabled" do
265
- before { Airbrake::Config.instance.merge(code_hunks: true) }
266
-
267
- context "and when root_directory is configured" do
268
- before do
269
- Airbrake::Config.instance.merge(root_directory: project_root_path(''))
270
- end
271
-
272
- let(:parsed_backtrace) do
273
- [
274
- {
275
- file: project_root_path('code.rb'),
276
- line: 94,
277
- function: 'to_json',
278
- code: {
279
- 92 => ' loop do',
280
- 93 => ' begin',
281
- 94 => ' json = @payload.to_json',
282
- 95 => ' rescue *JSON_EXCEPTIONS => ex',
283
- # rubocop:disable Layout/LineLength,Lint/InterpolationCheck
284
- 96 => ' @config.logger.debug("#{LOG_LABEL} `notice.to_json` failed: #{ex.class}: #{ex}")',
285
- # rubocop:enable Layout/LineLength,Lint/InterpolationCheck
286
- },
287
- },
288
- {
289
- file: fixture_path('notroot.txt'),
290
- line: 3,
291
- function: 'pineapple',
292
- },
293
- {
294
- file: project_root_path('vendor/bundle/ignored_file.rb'),
295
- line: 2,
296
- function: 'ignore_me',
297
- },
298
- ]
299
- end
300
-
301
- it "attaches code to those frames files of which match root_directory" do
302
- ex = RuntimeError.new
303
- backtrace = [
304
- "#{project_root_path('code.rb')}:94:in `to_json'",
305
- fixture_path("notroot.txt:3:in `pineapple'"),
306
- "#{project_root_path('vendor/bundle/ignored_file.rb')}:2:in `ignore_me'",
307
- ]
308
- ex.set_backtrace(backtrace)
309
- expect(described_class.parse(ex)).to eq(parsed_backtrace)
310
- end
311
- end
312
-
313
- context "and when root_directory is a Pathname" do
314
- before do
315
- Airbrake::Config.instance.merge(
316
- root_directory: Pathname.new(project_root_path('')),
317
- )
318
- end
319
-
320
- let(:parsed_backtrace) do
321
- [
322
- {
323
- file: project_root_path('code.rb'),
324
- line: 94,
325
- function: 'to_json',
326
- code: {
327
- 92 => ' loop do',
328
- 93 => ' begin',
329
- 94 => ' json = @payload.to_json',
330
- 95 => ' rescue *JSON_EXCEPTIONS => ex',
331
- # rubocop:disable Layout/LineLength,Lint/InterpolationCheck
332
- 96 => ' @config.logger.debug("#{LOG_LABEL} `notice.to_json` failed: #{ex.class}: #{ex}")',
333
- # rubocop:enable Layout/LineLength,Lint/InterpolationCheck
334
- },
335
- },
336
- ]
337
- end
338
-
339
- it "attaches code to those frames files of which match root_directory" do
340
- ex = RuntimeError.new
341
- ex.set_backtrace(["#{project_root_path('code.rb')}:94:in `to_json'"])
342
- expect(described_class.parse(ex)).to eq(parsed_backtrace)
343
- end
344
- end
345
-
346
- context "and when root_directory isn't configured" do
347
- before do
348
- Airbrake::Config.instance.merge(root_directory: nil)
349
- stub_const('Airbrake::Backtrace::CODE_FRAME_LIMIT', 2)
350
- end
351
-
352
- let(:parsed_backtrace) do
353
- [
354
- {
355
- file: project_root_path('code.rb'),
356
- line: 94,
357
- function: 'to_json',
358
- code: {
359
- 92 => ' loop do',
360
- 93 => ' begin',
361
- 94 => ' json = @payload.to_json',
362
- 95 => ' rescue *JSON_EXCEPTIONS => ex',
363
- # rubocop:disable Layout/LineLength,Lint/InterpolationCheck
364
- 96 => ' @config.logger.debug("#{LOG_LABEL} `notice.to_json` failed: #{ex.class}: #{ex}")',
365
- # rubocop:enable Layout/LineLength,Lint/InterpolationCheck
366
- },
367
- },
368
- {
369
- file: project_root_path('code.rb'),
370
- line: 95,
371
- function: 'to_json',
372
- code: {
373
- 93 => ' begin',
374
- 94 => ' json = @payload.to_json',
375
- 95 => ' rescue *JSON_EXCEPTIONS => ex',
376
- # rubocop:disable Layout/LineLength,Lint/InterpolationCheck
377
- 96 => ' @config.logger.debug("#{LOG_LABEL} `notice.to_json` failed: #{ex.class}: #{ex}")',
378
- # rubocop:enable Layout/LineLength,Lint/InterpolationCheck
379
- 97 => ' else',
380
- },
381
- },
382
- {
383
- file: project_root_path('code.rb'),
384
- line: 96,
385
- function: 'to_json',
386
- },
387
- ]
388
- end
389
-
390
- it "attaches code to first N frames" do
391
- ex = RuntimeError.new
392
- backtrace = [
393
- "#{project_root_path('code.rb')}:94:in `to_json'",
394
- "#{project_root_path('code.rb')}:95:in `to_json'",
395
- "#{project_root_path('code.rb')}:96:in `to_json'",
396
- ]
397
- ex.set_backtrace(backtrace)
398
- expect(described_class.parse(ex)).to eq(parsed_backtrace)
399
- end
400
- end
401
- end
402
-
403
- context "when code hunks are disabled" do
404
- before { Airbrake::Config.instance.merge(code_hunks: false) }
405
-
406
- context "and when root_directory is configured" do
407
- before do
408
- Airbrake::Config.instance.merge(root_directory: project_root_path(''))
409
- end
410
-
411
- let(:parsed_backtrace) do
412
- [
413
- {
414
- file: project_root_path('code.rb'),
415
- line: 94,
416
- function: 'to_json',
417
- },
418
- ]
419
- end
420
-
421
- it "doesn't attach code to frames" do
422
- ex = RuntimeError.new
423
- backtrace = ["#{project_root_path('code.rb')}:94:in `to_json'"]
424
- ex.set_backtrace(backtrace)
425
- expect(described_class.parse(ex)).to eq(parsed_backtrace)
426
- end
427
- end
428
- end
429
- end
430
- end
@@ -1,35 +0,0 @@
1
- RSpec.describe Airbrake::Benchmark do
2
- subject(:benchmark) { described_class.new }
3
-
4
- describe ".measure" do
5
- it "returns measured performance time" do
6
- expect(described_class.measure { '10' * 10 }).to be_kind_of(Numeric)
7
- end
8
- end
9
-
10
- describe "#stop" do
11
- before { benchmark }
12
-
13
- context "when called one time" do
14
- its(:stop) { is_expected.to be(true) }
15
- end
16
-
17
- context "when called twice or more" do
18
- before { benchmark.stop }
19
-
20
- its(:stop) { is_expected.to be(false) }
21
- end
22
- end
23
-
24
- describe "#duration" do
25
- context "when #stop wasn't called yet" do
26
- its(:duration) { is_expected.to be_zero }
27
- end
28
-
29
- context "when #stop was called" do
30
- before { benchmark.stop }
31
-
32
- its(:duration) { is_expected.to be > 0 }
33
- end
34
- end
35
- end
@@ -1,124 +0,0 @@
1
- RSpec.describe Airbrake::CodeHunk do
2
- subject(:code_hunk) { described_class.new }
3
-
4
- after do
5
- %w[empty_file.rb code.rb banana.rb short_file.rb long_line.txt].each do |f|
6
- Airbrake::FileCache[project_root_path(f)] = nil
7
- end
8
- end
9
-
10
- describe "#to_h" do
11
- context "when file is empty" do
12
- subject do
13
- described_class.new.get(project_root_path('empty_file.rb'), 1)
14
- end
15
-
16
- it { is_expected.to eq(1 => '') }
17
- end
18
-
19
- context "when line is nil" do
20
- subject { described_class.new.get(project_root_path('code.rb'), nil) }
21
-
22
- it { is_expected.to be_nil }
23
- end
24
-
25
- context "when a file doesn't exist" do
26
- subject { described_class.new.get(project_root_path('banana.rb'), 1) }
27
-
28
- it { is_expected.to be_nil }
29
- end
30
-
31
- context "when a file has less than NLINES lines before start line" do
32
- subject(:code_hunk) do
33
- described_class.new.get(project_root_path('code.rb'), 1)
34
- end
35
-
36
- it do
37
- expect(code_hunk).to(
38
- eq(
39
- 1 => 'module Airbrake',
40
- 2 => ' ##',
41
- # rubocop:disable Layout/LineLength
42
- 3 => ' # Represents a chunk of information that is meant to be either sent to',
43
- # rubocop:enable Layout/LineLength
44
- ),
45
- )
46
- end
47
- end
48
-
49
- context "when a file has less than NLINES lines after end line" do
50
- subject(:code_hunk) do
51
- described_class.new.get(project_root_path('code.rb'), 222)
52
- end
53
-
54
- it do
55
- expect(code_hunk).to(
56
- eq(
57
- 220 => ' end',
58
- 221 => 'end',
59
- ),
60
- )
61
- end
62
- end
63
-
64
- context "when a file has less than NLINES lines before and after" do
65
- subject(:code_hunk) do
66
- described_class.new.get(project_root_path('short_file.rb'), 2)
67
- end
68
-
69
- it do
70
- expect(code_hunk).to(
71
- eq(
72
- 1 => 'module Banana',
73
- 2 => ' attr_reader :bingo',
74
- 3 => 'end',
75
- ),
76
- )
77
- end
78
- end
79
-
80
- context "when a file has enough lines before and after" do
81
- subject(:code_hunk) do
82
- described_class.new.get(project_root_path('code.rb'), 100)
83
- end
84
-
85
- it do
86
- expect(code_hunk).to(
87
- eq(
88
- 98 => ' return json if json && json.bytesize <= MAX_NOTICE_SIZE',
89
- 99 => ' end',
90
- 100 => '',
91
- 101 => ' break if truncate == 0',
92
- 102 => ' end',
93
- ),
94
- )
95
- end
96
- end
97
-
98
- context "when a line exceeds the length limit" do
99
- subject(:code_hunk) do
100
- described_class.new.get(project_root_path('long_line.txt'), 1)
101
- end
102
-
103
- it "strips the line" do
104
- expect(code_hunk[1]).to eq("l#{'o' * 196}ng")
105
- end
106
- end
107
-
108
- context "when an error occurrs while fetching code" do
109
- before do
110
- allow(Airbrake::Loggable.instance).to receive(:error)
111
- allow(Airbrake::FileCache).to receive(:[]).and_raise(Errno::EACCES)
112
- end
113
-
114
- it "logs error and returns nil" do
115
- expect(code_hunk.get(project_root_path('code.rb'), 1)).to(
116
- eq(1 => ''),
117
- )
118
- expect(Airbrake::Loggable.instance).to have_received(:error).with(
119
- /can't read code hunk.+Permission denied/,
120
- )
121
- end
122
- end
123
- end
124
- end