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,97 +0,0 @@
1
- RSpec.describe "Rake integration" do
2
- let(:task) { Rake::Task['bingo:bango'] }
3
-
4
- before { Rails.application.load_tasks }
5
-
6
- after do
7
- expect { task.invoke }.to raise_error(AirbrakeTestError)
8
-
9
- # Rake ensures that each task is executed only once per session. For testing
10
- # purposes, we run the task multiple times.
11
- task.reenable
12
- end
13
-
14
- it "sends the exception to Airbrake" do
15
- expect(Airbrake).to receive(:notify_sync)
16
- .with(an_instance_of(Airbrake::Notice))
17
- end
18
-
19
- describe "contains the context payload, which" do
20
- it "includes correct component" do
21
- expect(Airbrake).to receive(:notify_sync)
22
- .with(a_notice_with(%i[context component], 'rake'))
23
- end
24
-
25
- it "includes correct action" do
26
- expect(Airbrake).to receive(:notify_sync)
27
- .with(a_notice_with(%i[context action], 'bingo:bango'))
28
- end
29
- end
30
-
31
- describe "contains the params payload, which" do
32
- it "includes a task name" do
33
- expect(Airbrake).to receive(:notify_sync)
34
- .with(a_notice_with(%i[params rake_task name], 'bingo:bango'))
35
- end
36
-
37
- it "includes a timestamp" do
38
- expected_notice = a_notice_with(
39
- %i[params rake_task timestamp], /20\d\d\-\d\d-\d\d.+/
40
- )
41
- expect(Airbrake).to receive(:notify_sync).with(expected_notice)
42
- end
43
-
44
- it "includes investigation" do
45
- expected_notice = a_notice_with(
46
- %i[params rake_task investigation], /Investigating bingo:bango/
47
- )
48
- expect(Airbrake).to receive(:notify_sync).with(expected_notice)
49
- end
50
-
51
- it "includes full comment" do
52
- expect(Airbrake).to receive(:notify_sync)
53
- .with(a_notice_with(%i[params rake_task full_comment], 'Dummy description'))
54
- end
55
-
56
- it "includes arg names" do
57
- expect(Airbrake).to receive(:notify_sync)
58
- .with(a_notice_with(%i[params rake_task arg_names], [:dummy_arg]))
59
- end
60
-
61
- it "includes arg description" do
62
- expect(Airbrake).to receive(:notify_sync)
63
- .with(a_notice_with(%i[params rake_task arg_description], '[dummy_arg]'))
64
- end
65
-
66
- it "includes locations" do
67
- expect(Airbrake).to receive(:notify_sync) do |notice|
68
- expect(notice[:params][:rake_task][:locations])
69
- .to match(array_including(%r{spec/apps/rails/dummy_task.rake:\d+:in}))
70
- end
71
- end
72
-
73
- it "includes sources" do
74
- expect(Airbrake).to receive(:notify_sync)
75
- .with(a_notice_with(%i[params rake_task sources], ['environment']))
76
- end
77
-
78
- it "includes prerequisite tasks" do
79
- expect(Airbrake).to receive(:notify_sync) do |notice|
80
- expect(notice[:params][:rake_task][:prerequisite_tasks])
81
- .to match(array_including(hash_including(name: 'bingo:environment')))
82
- end
83
- end
84
-
85
- it "includes argv info" do
86
- expect(Airbrake).to receive(:notify_sync)
87
- .with(a_notice_with(%i[params argv], %r{spec/integration/rails/.+_spec.rb}))
88
- end
89
-
90
- it "includes execute args" do
91
- expect(Airbrake).to receive(:notify_sync) do |notice|
92
- expect(notice[:params][:execute_args])
93
- .to be_an_instance_of(Rake::TaskArguments)
94
- end
95
- end
96
- end
97
- end
@@ -1,110 +0,0 @@
1
- RSpec.shared_examples 'rack examples' do
2
- include Warden::Test::Helpers
3
-
4
- let(:endpoint) { 'https://api.airbrake.io/api/v3/projects/113743/notices' }
5
-
6
- before do
7
- stub_request(:post, endpoint).to_return(status: 200, body: '')
8
- Airbrake::Config.instance.merge(performance_stats: false)
9
- end
10
-
11
- after { Warden.test_reset! }
12
-
13
- describe "application routes" do
14
- describe "/index" do
15
- it "successfully returns 200 and body" do
16
- expect(Airbrake).not_to receive(:notify)
17
-
18
- get '/'
19
-
20
- expect(last_response.status).to eq(200)
21
- expect(last_response.body).to eq('Hello from index')
22
- end
23
- end
24
-
25
- describe "/crash" do
26
- it "returns 500 and sends a notice to Airbrake" do
27
- expect(Airbrake).to receive(:notify).with(
28
- an_instance_of(Airbrake::Notice)
29
- ) do |notice|
30
- expect(notice[:errors].first[:type]).to eq('AirbrakeTestError')
31
- end
32
-
33
- get '/crash'
34
- end
35
- end
36
- end
37
-
38
- describe "user payload" do
39
- let(:user) do
40
- OpenStruct.new(
41
- id: 1,
42
- email: 'qa@example.com',
43
- username: 'qa-dept',
44
- first_name: 'John',
45
- last_name: 'Doe'
46
- )
47
- end
48
-
49
- before { login_as(user) }
50
-
51
- it "reports user info" do
52
- get '/crash'
53
- sleep 2
54
-
55
- body = /
56
- "context":{.*
57
- "user":{
58
- "id":"1",
59
- "name":"John\sDoe",
60
- "username":"qa-dept",
61
- "email":"qa@example.com"}
62
- /x
63
- expect(a_request(:post, endpoint).with(body: body))
64
- .to have_been_made.at_least_once
65
- end
66
- end
67
-
68
- context "when additional parameters are present" do
69
- before do
70
- get '/crash', nil, 'HTTP_USER_AGENT' => 'Bot', 'HTTP_REFERER' => 'bingo.com'
71
- sleep 2
72
- end
73
-
74
- it "contains url" do
75
- body = %r("context":{.*"url":"http://example\.org/crash".*})
76
- expect(a_request(:post, endpoint).with(body: body))
77
- .to have_been_made.at_least_once
78
- end
79
-
80
- it "contains hostname" do
81
- body = /"context":{.*"hostname":".+".*}/
82
- expect(a_request(:post, endpoint).with(body: body))
83
- .to have_been_made.at_least_once
84
- end
85
-
86
- it "contains userAgent" do
87
- body = /"context":{.*"userAgent":"Bot".*}/
88
- expect(a_request(:post, endpoint).with(body: body))
89
- .to have_been_made.at_least_once
90
- end
91
-
92
- it "contains referer" do
93
- body = /"context":{.*"referer":"bingo.com".*}/
94
- expect(a_request(:post, endpoint).with(body: body))
95
- .to have_been_made.at_least_once
96
- end
97
-
98
- it "contains HTTP headers" do
99
- body = /"context":{.*"headers":{.*"CONTENT_LENGTH":"0".*}/
100
- expect(a_request(:post, endpoint).with(body: body))
101
- .to have_been_made.at_least_once
102
- end
103
-
104
- it "contains HTTP method" do
105
- body = /"context":{.*"httpMethod":"GET".*}/
106
- expect(a_request(:post, endpoint).with(body: body))
107
- .to have_been_made.at_least_once
108
- end
109
- end
110
- end
@@ -1,30 +0,0 @@
1
- require 'sinatra'
2
-
3
- require 'apps/sinatra/sinatra_test_app'
4
- require 'integration/shared_examples/rack_examples'
5
-
6
- RSpec.describe "Sinatra integration specs" do
7
- let(:app) { SinatraTestApp }
8
-
9
- include_examples 'rack examples'
10
-
11
- describe "context payload" do
12
- before { stub_request(:post, endpoint).to_return(status: 200, body: '') }
13
-
14
- it "includes version" do
15
- get '/crash'
16
- sleep 2
17
-
18
- body = /"context":{.*"versions":{"sinatra":"\d\./
19
- expect(a_request(:post, endpoint).with(body: body)).to have_been_made
20
- end
21
-
22
- it "includes route" do
23
- get '/crash'
24
- sleep 2
25
-
26
- body = %r("context":{.*"route":"\/crash".*})
27
- expect(a_request(:post, endpoint).with(body: body)).to have_been_made
28
- end
29
- end
30
- end
@@ -1,105 +0,0 @@
1
- # Gems from the gemspec.
2
- require 'webmock'
3
- require 'webmock/rspec'
4
- require 'rspec/wait'
5
- require 'rack'
6
- require 'rack/test'
7
- require 'rake'
8
- require 'pry'
9
-
10
- require 'airbrake'
11
- require 'airbrake/rake/tasks'
12
-
13
- Dir[
14
- File.expand_path(File.join(File.dirname(__FILE__), 'support', '**', '*.rb'))
15
- ].each do |file|
16
- require file
17
- end
18
-
19
- Airbrake.configure do |c|
20
- c.project_id = 113743
21
- c.project_key = 'fd04e13d806a90f96614ad8e529b2822'
22
- c.app_version = '1.2.3'
23
- c.workers = 5
24
- c.performance_stats = true
25
- c.performance_stats_flush_period = 1
26
- end
27
-
28
- RSpec.configure do |c|
29
- c.order = 'random'
30
- c.color = true
31
- c.disable_monkey_patching!
32
- c.wait_timeout = 3
33
-
34
- c.include Rack::Test::Methods
35
- end
36
-
37
- # Load integration tests only when they're run through appraisals.
38
- if ENV['APPRAISAL_INITIALIZED']
39
- # Gems from appraisals that every application uses.
40
- require 'warden'
41
-
42
- # Load a Rails app or skip.
43
- begin
44
- ENV['RAILS_ENV'] = 'test'
45
-
46
- if RUBY_ENGINE == 'jruby'
47
- require 'activerecord-jdbcsqlite3-adapter'
48
- else
49
- require 'sqlite3'
50
- end
51
-
52
- require 'rails'
53
-
54
- rails_vsn = Gem::Version.new(Rails.version)
55
-
56
- ENV['DATABASE_URL'] = if rails_vsn <= Gem::Version.new('4.2')
57
- 'sqlite3:///:memory:'
58
- else
59
- 'sqlite3::memory:'
60
- end
61
-
62
- require 'action_controller'
63
- require 'action_view'
64
- require 'action_view/testing/resolvers'
65
- require 'active_record/railtie'
66
- if rails_vsn >= Gem::Version.new('4.2')
67
- require 'active_job'
68
-
69
- # Silence logger.
70
- ActiveJob::Base.logger.level = 99
71
- end
72
-
73
- require 'resque'
74
- require 'resque_spec'
75
- require 'airbrake/resque'
76
- Resque::Failure.backend = Resque::Failure::Airbrake
77
-
78
- require 'delayed_job'
79
- require 'delayed_job_active_record'
80
- require 'airbrake/delayed_job'
81
- Delayed::Worker.delay_jobs = false
82
-
83
- require 'airbrake/rails'
84
-
85
- load 'apps/rails/dummy_task.rake'
86
- require 'apps/rails/dummy_app'
87
- rescue LoadError
88
- puts '** Skipped Rails specs'
89
- end
90
-
91
- # Load a Rack app or skip.
92
- begin
93
- # Don't load the Rack app since we want to test Sinatra if it's loaded.
94
- raise LoadError if defined?(Sinatra)
95
-
96
- require 'apps/rack/dummy_app'
97
- rescue LoadError
98
- puts '** Skipped Rack specs'
99
- end
100
- end
101
-
102
- # Make sure tests that use async requests fail.
103
- Thread.abort_on_exception = true
104
-
105
- AirbrakeTestError = Class.new(StandardError)
@@ -1,29 +0,0 @@
1
- RSpec::Matchers.define :a_notice_with do |access_keys, expected_val|
2
- match do |notice|
3
- payload = notice[access_keys.shift]
4
- break(false) unless payload
5
-
6
- actual_val =
7
- if payload.respond_to?(:dig)
8
- payload.dig(*access_keys)
9
- else
10
- dig_pre_23(payload, *access_keys)
11
- end
12
-
13
- if expected_val.is_a?(Regexp)
14
- actual_val =~ expected_val
15
- else
16
- actual_val == expected_val
17
- end
18
- end
19
-
20
- # TODO: Use the normal "dig" version once we support Ruby 2.3 and above.
21
- def dig_pre_23(hash, *keys)
22
- v = hash[keys.shift]
23
- while keys.any?
24
- return unless v.is_a?(Hash)
25
- v = v[keys.shift]
26
- end
27
- v
28
- end
29
- end
@@ -1,125 +0,0 @@
1
- RSpec.describe Airbrake::AirbrakeLogger do
2
- let(:project_id) { 113743 }
3
- let(:project_key) { 'fd04e13d806a90f96614ad8e529b2822' }
4
- let(:endpoint) { "https://api.airbrake.io/api/v3/projects/#{project_id}/notices" }
5
- let(:airbrake) { Airbrake::NoticeNotifier.new }
6
- let(:logger) { Logger.new('/dev/null') }
7
-
8
- subject { described_class.new(logger) }
9
-
10
- def wait_for_a_request_with_body(body)
11
- wait_for(a_request(:post, endpoint).with(body: body)).to have_been_made.once
12
- end
13
-
14
- before do
15
- stub_request(:post, endpoint).to_return(status: 201, body: '{}')
16
- end
17
-
18
- describe "#airbrake_notifier" do
19
- it "installs Airbrake notifier" do
20
- notifier_id = airbrake.object_id
21
- expect(subject.airbrake_notifier.object_id).not_to eq(notifier_id)
22
-
23
- subject.airbrake_notifier = airbrake
24
- expect(subject.airbrake_notifier.object_id).to eq(notifier_id)
25
- end
26
-
27
- context "when Airbrake is installed explicitly" do
28
- let(:out) { StringIO.new }
29
- let(:logger) { Logger.new(out) }
30
-
31
- before do
32
- subject.airbrake_notifier = airbrake
33
- end
34
-
35
- it "both logs and notifies" do
36
- msg = 'bingo'
37
- subject.fatal(msg)
38
-
39
- wait_for_a_request_with_body(/"message":"#{msg}"/)
40
- expect(out.string).to match(/FATAL -- : #{msg}/)
41
- end
42
-
43
- it "sets the correct severity" do
44
- subject.fatal('bango')
45
- wait_for_a_request_with_body(/"context":{.*"severity":"critical".*}/)
46
- end
47
-
48
- it "sets the correct component" do
49
- subject.fatal('bingo')
50
- wait_for_a_request_with_body(/"component":"log"/)
51
- end
52
-
53
- it "strips out internal logger frames" do
54
- subject.fatal('bongo')
55
-
56
- wait_for(
57
- a_request(:post, endpoint)
58
- .with(body: %r{"file":".+/logger.rb"})
59
- ).not_to have_been_made
60
- wait_for(a_request(:post, endpoint)).to have_been_made.once
61
- end
62
- end
63
-
64
- context "when Airbrake is not installed" do
65
- it "only logs, never notifies" do
66
- out = StringIO.new
67
- l = described_class.new(Logger.new(out))
68
- l.airbrake_notifier = nil
69
- msg = 'bango'
70
-
71
- l.fatal(msg)
72
-
73
- wait_for(a_request(:post, endpoint)).not_to have_been_made
74
- expect(out.string).to match('FATAL -- : bango')
75
- end
76
- end
77
- end
78
-
79
- describe "#airbrake_level" do
80
- context "when not set" do
81
- it "defaults to Logger::WARN" do
82
- expect(subject.airbrake_level).to eq(Logger::WARN)
83
- end
84
- end
85
-
86
- context "when set" do
87
- before do
88
- subject.airbrake_level = Logger::FATAL
89
- end
90
-
91
- it "does not notify below the specified level" do
92
- subject.error('bingo')
93
- wait_for(a_request(:post, endpoint)).not_to have_been_made
94
- end
95
-
96
- it "notifies in the current or above level" do
97
- subject.fatal('bingo')
98
- wait_for(a_request(:post, endpoint)).to have_been_made
99
- end
100
-
101
- it "raises error when below the allowed level" do
102
- expect do
103
- subject.airbrake_level = Logger::DEBUG
104
- end.to raise_error(/severity level \d is not allowed/)
105
- end
106
- end
107
- end
108
-
109
- describe "#level=" do
110
- it "sets logger level" do
111
- subject.level = Logger::FATAL
112
- expect(subject.level).to eq(Logger::FATAL)
113
- end
114
-
115
- it "sets airbrake level" do
116
- subject.level = Logger::FATAL
117
- expect(subject.airbrake_level).to eq(Logger::FATAL)
118
- end
119
-
120
- it "normalizes airbrake logger level when provided level is below WARN" do
121
- subject.level = Logger::DEBUG
122
- expect(subject.airbrake_level).to eq(Logger::WARN)
123
- end
124
- end
125
- end