airbrake 9.2.1 → 9.2.2

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