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.
- checksums.yaml +4 -4
- data/lib/airbrake-ruby/async_sender.rb +11 -15
- data/lib/airbrake-ruby/backlog.rb +123 -0
- data/lib/airbrake-ruby/config.rb +7 -0
- data/lib/airbrake-ruby/filters/git_last_checkout_filter.rb +1 -1
- data/lib/airbrake-ruby/nested_exception.rb +22 -1
- data/lib/airbrake-ruby/notice.rb +5 -3
- data/lib/airbrake-ruby/notice_notifier.rb +1 -0
- data/lib/airbrake-ruby/performance_notifier.rb +1 -0
- data/lib/airbrake-ruby/response.rb +56 -5
- data/lib/airbrake-ruby/sync_sender.rb +41 -10
- data/lib/airbrake-ruby/version.rb +1 -1
- data/lib/airbrake-ruby.rb +2 -1
- metadata +5 -122
- data/spec/airbrake_spec.rb +0 -522
- data/spec/async_sender_spec.rb +0 -65
- data/spec/backtrace_spec.rb +0 -430
- data/spec/benchmark_spec.rb +0 -35
- data/spec/code_hunk_spec.rb +0 -124
- data/spec/config/processor_spec.rb +0 -167
- data/spec/config/validator_spec.rb +0 -204
- data/spec/config_spec.rb +0 -188
- data/spec/context_spec.rb +0 -54
- data/spec/deploy_notifier_spec.rb +0 -50
- data/spec/file_cache_spec.rb +0 -35
- data/spec/filter_chain_spec.rb +0 -124
- data/spec/filters/context_filter_spec.rb +0 -32
- data/spec/filters/dependency_filter_spec.rb +0 -14
- data/spec/filters/exception_attributes_filter_spec.rb +0 -52
- data/spec/filters/gem_root_filter_spec.rb +0 -44
- data/spec/filters/git_last_checkout_filter_spec.rb +0 -61
- data/spec/filters/git_repository_filter_spec.rb +0 -72
- data/spec/filters/git_revision_filter_spec.rb +0 -126
- data/spec/filters/keys_allowlist_spec.rb +0 -204
- data/spec/filters/keys_blocklist_spec.rb +0 -242
- data/spec/filters/root_directory_filter_spec.rb +0 -39
- data/spec/filters/sql_filter_spec.rb +0 -274
- data/spec/filters/system_exit_filter_spec.rb +0 -16
- data/spec/filters/thread_filter_spec.rb +0 -281
- data/spec/fixtures/notroot.txt +0 -7
- data/spec/fixtures/project_root/code.rb +0 -221
- data/spec/fixtures/project_root/empty_file.rb +0 -0
- data/spec/fixtures/project_root/long_line.txt +0 -1
- data/spec/fixtures/project_root/short_file.rb +0 -3
- data/spec/fixtures/project_root/vendor/bundle/ignored_file.rb +0 -5
- data/spec/helpers.rb +0 -9
- data/spec/ignorable_spec.rb +0 -14
- data/spec/inspectable_spec.rb +0 -45
- data/spec/loggable_spec.rb +0 -17
- data/spec/monotonic_time_spec.rb +0 -25
- data/spec/nested_exception_spec.rb +0 -73
- data/spec/notice_notifier/options_spec.rb +0 -269
- data/spec/notice_notifier_spec.rb +0 -361
- data/spec/notice_spec.rb +0 -300
- data/spec/performance_breakdown_spec.rb +0 -11
- data/spec/performance_notifier_spec.rb +0 -645
- data/spec/promise_spec.rb +0 -203
- data/spec/query_spec.rb +0 -11
- data/spec/queue_spec.rb +0 -18
- data/spec/remote_settings/callback_spec.rb +0 -162
- data/spec/remote_settings/settings_data_spec.rb +0 -348
- data/spec/remote_settings_spec.rb +0 -201
- data/spec/request_spec.rb +0 -9
- data/spec/response_spec.rb +0 -110
- data/spec/spec_helper.rb +0 -100
- data/spec/stashable_spec.rb +0 -23
- data/spec/stat_spec.rb +0 -39
- data/spec/sync_sender_spec.rb +0 -168
- data/spec/tdigest_spec.rb +0 -235
- data/spec/thread_pool_spec.rb +0 -196
- data/spec/time_truncate_spec.rb +0 -30
- data/spec/timed_trace_spec.rb +0 -127
- data/spec/truncator_spec.rb +0 -267
data/spec/async_sender_spec.rb
DELETED
@@ -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
|
data/spec/backtrace_spec.rb
DELETED
@@ -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
|
data/spec/benchmark_spec.rb
DELETED
@@ -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
|
data/spec/code_hunk_spec.rb
DELETED
@@ -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
|