airbrake 9.2.1 → 9.2.2

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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/lib/airbrake/rack/middleware.rb +21 -13
  3. data/lib/airbrake/rails/action_controller_performance_breakdown_subscriber.rb +20 -2
  4. data/lib/airbrake/version.rb +1 -1
  5. metadata +5 -81
  6. data/spec/apps/rack/dummy_app.rb +0 -17
  7. data/spec/apps/rails/dummy_app.rb +0 -258
  8. data/spec/apps/rails/dummy_task.rake +0 -15
  9. data/spec/apps/rails/logs/32.log +0 -34094
  10. data/spec/apps/rails/logs/42.log +0 -1488
  11. data/spec/apps/rails/logs/52.log +0 -6321
  12. data/spec/apps/sinatra/sinatra_test_app.rb +0 -12
  13. data/spec/integration/rack/rack_spec.rb +0 -19
  14. data/spec/integration/rails/rails_spec.rb +0 -430
  15. data/spec/integration/rails/rake_spec.rb +0 -97
  16. data/spec/integration/shared_examples/rack_examples.rb +0 -110
  17. data/spec/integration/sinatra/sinatra_spec.rb +0 -30
  18. data/spec/spec_helper.rb +0 -105
  19. data/spec/support/matchers/a_notice_with.rb +0 -29
  20. data/spec/unit/logger_spec.rb +0 -125
  21. data/spec/unit/rack/context_filter_spec.rb +0 -90
  22. data/spec/unit/rack/http_headers_filter_spec.rb +0 -44
  23. data/spec/unit/rack/http_params_filter_spec.rb +0 -58
  24. data/spec/unit/rack/instrumentable_spec.rb +0 -105
  25. data/spec/unit/rack/middleware_spec.rb +0 -98
  26. data/spec/unit/rack/rack_spec.rb +0 -46
  27. data/spec/unit/rack/request_body_filter_spec.rb +0 -44
  28. data/spec/unit/rack/request_store_spec.rb +0 -36
  29. data/spec/unit/rack/route_filter_spec.rb +0 -52
  30. data/spec/unit/rack/session_filter_spec.rb +0 -44
  31. data/spec/unit/rack/user_filter_spec.rb +0 -30
  32. data/spec/unit/rack/user_spec.rb +0 -218
  33. data/spec/unit/rails/action_cable/notify_callback_spec.rb +0 -26
  34. data/spec/unit/rails/action_controller_notify_subscriber_spec.rb +0 -43
  35. data/spec/unit/rails/action_controller_performance_breakdown_subscriber_spec.rb +0 -63
  36. data/spec/unit/rails/action_controller_route_subscriber_spec.rb +0 -84
  37. data/spec/unit/rails/active_record_subscriber_spec.rb +0 -70
  38. data/spec/unit/rails/excon_spec.rb +0 -46
  39. data/spec/unit/rake/tasks_spec.rb +0 -70
  40. data/spec/unit/shoryuken_spec.rb +0 -55
  41. data/spec/unit/sidekiq/retryable_jobs_filter_spec.rb +0 -36
  42. data/spec/unit/sidekiq_spec.rb +0 -33
  43. data/spec/unit/sneakers_spec.rb +0 -83
@@ -1,63 +0,0 @@
1
- require 'airbrake/rails/action_controller_performance_breakdown_subscriber'
2
-
3
- RSpec.describe Airbrake::Rails::ActionControllerPerformanceBreakdownSubscriber do
4
- let(:app) { double(Airbrake::Rails::App) }
5
- let(:event) { double(Airbrake::Rails::Event) }
6
-
7
- before do
8
- allow(Airbrake::Rails::Event).to receive(:new).and_return(event)
9
- end
10
-
11
- after { Airbrake::Rack::RequestStore.clear }
12
-
13
- context "when routes are not set in the request store" do
14
- before { Airbrake::Rack::RequestStore[:routes] = nil }
15
-
16
- it "doesn't send performance breakdown info" do
17
- expect(Airbrake).not_to receive(:notify_performance_breakdown)
18
- subject.call([])
19
- end
20
- end
21
-
22
- context "when there are no routes in the request store" do
23
- before { Airbrake::Rack::RequestStore[:routes] = {} }
24
-
25
- it "doesn't send performance breakdown info" do
26
- expect(Airbrake).not_to receive(:notify_performance_breakdown)
27
- subject.call([])
28
- end
29
- end
30
-
31
- context "when there's a route in the request store" do
32
- before do
33
- expect(event).to receive(:groups).and_return(db: 0.5, view: 0.5)
34
- expect(event).to receive(:method).and_return('GET')
35
- expect(event).to receive(:response_type).and_return(:html)
36
- expect(event).to receive(:time).and_return(Time.new)
37
- end
38
-
39
- context "when request store routes have extra groups" do
40
- before do
41
- Airbrake::Rack::RequestStore[:routes] = {
42
- '/test-route' => {
43
- method: 'GET',
44
- response_type: :html,
45
- groups: { http: 0.5 }
46
- }
47
- }
48
- end
49
-
50
- it "sends performance info to Airbrake with extra groups" do
51
- expect(Airbrake).to receive(:notify_performance_breakdown).with(
52
- hash_including(
53
- route: '/test-route',
54
- method: 'GET',
55
- response_type: :html,
56
- groups: { db: 0.5, view: 0.5, http: 0.5 }
57
- )
58
- )
59
- subject.call([])
60
- end
61
- end
62
- end
63
- end
@@ -1,84 +0,0 @@
1
- require 'ostruct'
2
- require 'airbrake/rails/action_controller_route_subscriber'
3
-
4
- RSpec.describe Airbrake::Rails::ActionControllerRouteSubscriber do
5
- describe "#call" do
6
- let(:app) { double(Airbrake::Rails::App) }
7
- let(:event) { double(Airbrake::Rails::Event) }
8
-
9
- let(:event_params) do
10
- [
11
- 'start_processing.action_controller',
12
- Time.new,
13
- Time.new,
14
- '123',
15
- { method: 'HEAD', path: '/crash' }
16
- ]
17
- end
18
-
19
- before do
20
- allow(Airbrake::Rails::App).to receive(:new).and_return(app)
21
- allow(Airbrake::Rails::Event).to receive(:new).and_return(event)
22
- end
23
-
24
- context "when request store has the :routes key" do
25
- let(:routes) do
26
- [Airbrake::Rails::App::Route.new('/crash', 'DummyController', 'crash')]
27
- end
28
-
29
- before do
30
- allow(app).to receive(:routes).and_return(routes)
31
- allow(event).to receive(:params).and_return(params)
32
- allow(event).to receive(:method).and_return('HEAD')
33
- allow(event).to receive(:response_type).and_return(:html)
34
-
35
- Airbrake::Rack::RequestStore[:routes] = {}
36
- end
37
-
38
- after { Airbrake::Rack::RequestStore.clear }
39
-
40
- context "and when the route can be found" do
41
- let(:params) do
42
- OpenStruct.new(controller: 'DummyController', action: 'crash')
43
- end
44
-
45
- it "stores a route in the request store under :routes" do
46
- subject.call(event_params)
47
- expect(Airbrake::Rack::RequestStore[:routes])
48
- .to eq('/crash' => { method: 'HEAD', response_type: :html, groups: {} })
49
- end
50
- end
51
-
52
- context "and when the event controller can't be found" do
53
- let(:params) do
54
- OpenStruct.new(controller: 'BananaController', action: 'crash')
55
- end
56
-
57
- it "doesn't store any routes in the request store under :routes" do
58
- subject.call(event_params)
59
- expect(Airbrake::Rack::RequestStore[:routes]).to be_empty
60
- end
61
- end
62
-
63
- context "and when the event action can't be found" do
64
- let(:params) do
65
- OpenStruct.new(controller: 'DummyController', action: 'banana')
66
- end
67
-
68
- it "doesn't store any routes in the request store under :routes" do
69
- subject.call(event_params)
70
- expect(Airbrake::Rack::RequestStore[:routes]).to be_empty
71
- end
72
- end
73
- end
74
-
75
- context "when request store doesn't have the :routes key" do
76
- before { Airbrake::Rack::RequestStore.clear }
77
-
78
- it "doesn't store any routes in the request store" do
79
- subject.call(event_params)
80
- expect(Airbrake::Rack::RequestStore[:routes]).to be_nil
81
- end
82
- end
83
- end
84
- end
@@ -1,70 +0,0 @@
1
- require 'airbrake/rails/active_record_subscriber'
2
-
3
- RSpec.describe Airbrake::Rails::ActiveRecordSubscriber do
4
- after { Airbrake::Rack::RequestStore.clear }
5
-
6
- describe "#call" do
7
- let(:event) { double(Airbrake::Rails::Event) }
8
-
9
- before do
10
- allow(Airbrake::Rails::Event).to receive(:new).and_return(event)
11
- end
12
-
13
- context "when there are no routes in the request store" do
14
- it "doesn't notify requests" do
15
- expect(Airbrake).not_to receive(:notify_query)
16
- subject.call([])
17
- end
18
- end
19
-
20
- context "when there's a route in the request store" do
21
- before do
22
- Airbrake::Rack::RequestStore[:routes] = {
23
- '/test-route' => { method: 'GET', response_type: :html }
24
- }
25
-
26
- allow(event).to receive(:sql).and_return('SELECT * FROM bananas')
27
- allow(event).to receive(:time).and_return(Time.now)
28
- allow(event).to receive(:end).and_return(Time.now)
29
- allow(Airbrake::Rails::BacktraceCleaner).to receive(:clean).and_return(
30
- "/lib/pry/cli.rb:117:in `start'"
31
- )
32
- end
33
-
34
- it "sends query info to Airbrake" do
35
- expect(Airbrake).to receive(:notify_query).with(
36
- hash_including(
37
- method: 'GET',
38
- route: '/test-route',
39
- query: 'SELECT * FROM bananas',
40
- func: 'start',
41
- line: 117,
42
- file: '/lib/pry/cli.rb'
43
- )
44
- )
45
- subject.call([])
46
- end
47
-
48
- context "and when backtrace couldn't be parsed" do
49
- before do
50
- allow(Airbrake::Rails::BacktraceCleaner)
51
- .to receive(:clean).and_return([])
52
- end
53
-
54
- it "sends empty func/file/line to Airbrake" do
55
- expect(Airbrake).to receive(:notify_query).with(
56
- hash_including(
57
- method: 'GET',
58
- route: '/test-route',
59
- query: 'SELECT * FROM bananas',
60
- func: nil,
61
- line: nil,
62
- file: nil
63
- )
64
- )
65
- subject.call([])
66
- end
67
- end
68
- end
69
- end
70
- end
@@ -1,46 +0,0 @@
1
- require 'airbrake/rails/excon_subscriber'
2
-
3
- RSpec.describe Airbrake::Rails::Excon do
4
- after { Airbrake::Rack::RequestStore.clear }
5
-
6
- let(:event) { double(Airbrake::Rails::Event) }
7
-
8
- before do
9
- allow(Airbrake::Rails::Event).to receive(:new).and_return(event)
10
- end
11
-
12
- context "when there are no routes in the request store" do
13
- it "doesn't notify requests" do
14
- expect(Airbrake).not_to receive(:notify_performance_breakdown)
15
- subject.call([])
16
- end
17
- end
18
-
19
- context "when there's a route in the request store" do
20
- let(:route) { Airbrake::Rack::RequestStore[:routes]['/test-route'] }
21
-
22
- before do
23
- Airbrake::Rack::RequestStore[:routes] = {
24
- '/test-route' => { groups: {} }
25
- }
26
-
27
- expect(event).to receive(:duration).and_return(0.1)
28
- end
29
-
30
- it "sets http group value of that route" do
31
- subject.call([])
32
- expect(route[:groups][:http]).to eq(0.1)
33
- end
34
-
35
- context "and when the subscriber is called multiple times" do
36
- before { expect(event).to receive(:duration).and_return(0.1) }
37
-
38
- it "increments http group value of that route" do
39
- subject.call([])
40
- subject.call([])
41
-
42
- expect(route[:groups][:http]).to eq(0.2)
43
- end
44
- end
45
- end
46
- end
@@ -1,70 +0,0 @@
1
- RSpec.describe "airbrake/rake/tasks" do
2
- let(:endpoint) do
3
- 'https://api.airbrake.io/api/v4/projects/113743/deploys'
4
- end
5
-
6
- def wait_for_a_request_with_body(body)
7
- wait_for(a_request(:post, endpoint).with(body: body)).to have_been_made.once
8
- end
9
-
10
- before do
11
- stub_request(:post, endpoint).to_return(status: 201, body: '{}')
12
- allow(STDOUT).to receive(:puts).and_return(nil)
13
- end
14
-
15
- describe "airbrake:deploy" do
16
- let(:task) { Rake::Task['airbrake:deploy'] }
17
-
18
- after { task.reenable }
19
-
20
- shared_examples 'deploy payload' do |key, val|
21
- it "sends #{key}" do
22
- ENV[key.upcase] = val
23
- task.invoke
24
-
25
- wait_for_a_request_with_body(/{.*"#{key}":"#{val}".*}/)
26
- ENV[key.upcase] = nil
27
- end
28
- end
29
-
30
- [%w[environment production],
31
- %w[username john],
32
- %w[revision 123abcdef],
33
- %w[repository https://github.com/airbrake/airbrake'],
34
- %w[version v2.0]].each do |(key, val)|
35
- include_examples 'deploy payload', key, val
36
- end
37
-
38
- context "when Airbrake is not configured" do
39
- let(:deploy_endpoint) { 'https://api.airbrake.io/api/v3/projects/113743/notices' }
40
-
41
- before do
42
- stub_request(:post, deploy_endpoint)
43
- expect(Airbrake).to receive(:configured?).and_return(false)
44
- end
45
-
46
- it "raises error" do
47
- expect { task.invoke }
48
- .to raise_error(Airbrake::Error, 'airbrake-ruby is not configured')
49
- end
50
- end
51
- end
52
-
53
- describe "airbrake:install_heroku_deploy_hook" do
54
- let(:task) { Rake::Task['airbrake:install_heroku_deploy_hook'] }
55
-
56
- after { task.reenable }
57
-
58
- let(:airbrake_vars) { "AIRBRAKE_PROJECT_ID=1\nAIRBRAKE_API_KEY=2\nRAILS_ENV=3\n" }
59
- let(:silenced_stdout) { File.new(File::NULL, 'w') }
60
-
61
- describe "parsing environment variables" do
62
- it "does not raise when an env variable value contains '='" do
63
- heroku_config = airbrake_vars + "URL=https://airbrake.io/docs?key=11\n"
64
- expect(Bundler).to receive(:with_clean_env).twice.and_return(heroku_config)
65
-
66
- task.invoke
67
- end
68
- end
69
- end
70
- end
@@ -1,55 +0,0 @@
1
- require 'airbrake/shoryuken'
2
-
3
- RSpec.describe Airbrake::Shoryuken::ErrorHandler do
4
- let(:error) { AirbrakeTestError.new('shoryuken error') }
5
- let(:body) { { message: 'message' } }
6
- let(:queue) { 'foo_queue' }
7
-
8
- let(:worker) do
9
- Class.new do
10
- def self.to_s
11
- 'FooWorker'
12
- end
13
- end.new
14
- end
15
-
16
- let(:endpoint) { 'https://api.airbrake.io/api/v3/projects/113743/notices' }
17
-
18
- def wait_for_a_request_with_body(body)
19
- wait_for(a_request(:post, endpoint).with(body: body)).to have_been_made.once
20
- end
21
-
22
- before do
23
- stub_request(:post, endpoint).to_return(status: 201, body: '{}')
24
- end
25
-
26
- context "when there's an error" do
27
- it 'notifies' do
28
- expect do
29
- subject.call(worker, queue, nil, body) { raise error }
30
- end.to raise_error(error)
31
-
32
- wait_for_a_request_with_body(/"message":"shoryuken\serror"/)
33
- wait_for_a_request_with_body(/"params":{.*"queue":"#{queue}"/)
34
- wait_for_a_request_with_body(/"params":{.*"body":\{"message":"message"\}/)
35
- wait_for_a_request_with_body(/"component":"shoryuken","action":"FooWorker"/)
36
- end
37
-
38
- context "and it's a batch" do
39
- let(:body) { [{ message1: 'message1' }, { message2: 'message2' }] }
40
-
41
- it 'notifies' do
42
- expect do
43
- subject.call(worker, queue, nil, body) { raise error }
44
- end.to raise_error(error)
45
-
46
- wait_for_a_request_with_body(/"message":"shoryuken\serror"/)
47
- wait_for_a_request_with_body(/"params":{.*"queue":"#{queue}"/)
48
- wait_for_a_request_with_body(
49
- /"params":{.*"batch":\[\{"message1":"message1"\},\{"message2":"message2"\}\]/
50
- )
51
- wait_for_a_request_with_body(/"component":"shoryuken","action":"FooWorker"/)
52
- end
53
- end
54
- end
55
- end
@@ -1,36 +0,0 @@
1
- if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.2.2')
2
- require 'sidekiq'
3
- require 'sidekiq/cli'
4
- require 'airbrake/sidekiq'
5
-
6
- RSpec.describe "airbrake/sidekiq/retryable_jobs_filter" do
7
- subject(:filter) { Airbrake::Sidekiq::RetryableJobsFilter.new }
8
- def build_notice(job = nil)
9
- Airbrake::Notice.new(StandardError.new, job: job)
10
- end
11
-
12
- it "does not ignore notices that are not from jobs" do
13
- notice = build_notice
14
- filter.call(notice)
15
- expect(build_notice).to_not be_ignored
16
- end
17
-
18
- it "does not ignore notices from jobs that have retries disabled" do
19
- notice = build_notice('retry' => false)
20
- filter.call(notice)
21
- expect(build_notice).to_not be_ignored
22
- end
23
-
24
- it "ignore notices from jobs that will be retried" do
25
- notice = build_notice('retry' => true, 'retry_count' => 0)
26
- filter.call(notice)
27
- expect(notice).to be_ignored
28
- end
29
-
30
- it "does not ignore notices from jobs that will not be retried" do
31
- notice = build_notice('retry' => 5, 'retry_count' => 5)
32
- filter.call(notice)
33
- expect(build_notice).to_not be_ignored
34
- end
35
- end
36
- end
@@ -1,33 +0,0 @@
1
- if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.2.2')
2
- require 'sidekiq'
3
- require 'sidekiq/cli'
4
- require 'airbrake/sidekiq'
5
-
6
- RSpec.describe "airbrake/sidekiq/error_handler" do
7
- let(:endpoint) { 'https://api.airbrake.io/api/v3/projects/113743/notices' }
8
-
9
- def wait_for_a_request_with_body(body)
10
- wait_for(a_request(:post, endpoint).with(body: body)).to have_been_made.once
11
- end
12
-
13
- def call_handler
14
- handler = Sidekiq.error_handlers.last
15
- handler.call(
16
- AirbrakeTestError.new('sidekiq error'),
17
- 'class' => 'HardSidekiqWorker', 'args' => %w[bango bongo]
18
- )
19
- end
20
-
21
- before do
22
- stub_request(:post, endpoint).to_return(status: 201, body: '{}')
23
- end
24
-
25
- it "sends a notice to Airbrake" do
26
- expect(call_handler).to be_a(Airbrake::Promise)
27
-
28
- wait_for_a_request_with_body(/"message":"sidekiq\serror"/)
29
- wait_for_a_request_with_body(/"params":{.*"args":\["bango","bongo"\]/)
30
- wait_for_a_request_with_body(/"component":"sidekiq","action":"HardSidekiqWorker"/)
31
- end
32
- end
33
- end