airbrake-ruby 4.13.3-java → 5.0.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.rb +23 -32
- data/lib/airbrake-ruby/async_sender.rb +1 -1
- data/lib/airbrake-ruby/backtrace.rb +6 -5
- data/lib/airbrake-ruby/config.rb +37 -13
- data/lib/airbrake-ruby/config/processor.rb +84 -0
- data/lib/airbrake-ruby/config/validator.rb +6 -0
- data/lib/airbrake-ruby/file_cache.rb +1 -1
- data/lib/airbrake-ruby/filter_chain.rb +16 -1
- data/lib/airbrake-ruby/filters/dependency_filter.rb +1 -0
- data/lib/airbrake-ruby/filters/gem_root_filter.rb +1 -0
- data/lib/airbrake-ruby/filters/git_last_checkout_filter.rb +3 -3
- data/lib/airbrake-ruby/filters/git_repository_filter.rb +3 -0
- data/lib/airbrake-ruby/filters/git_revision_filter.rb +2 -0
- data/lib/airbrake-ruby/filters/{keys_whitelist.rb → keys_allowlist.rb} +3 -3
- data/lib/airbrake-ruby/filters/{keys_blacklist.rb → keys_blocklist.rb} +3 -3
- data/lib/airbrake-ruby/filters/keys_filter.rb +26 -18
- data/lib/airbrake-ruby/filters/root_directory_filter.rb +1 -0
- data/lib/airbrake-ruby/filters/sql_filter.rb +4 -4
- data/lib/airbrake-ruby/filters/system_exit_filter.rb +1 -0
- data/lib/airbrake-ruby/filters/thread_filter.rb +2 -0
- data/lib/airbrake-ruby/ignorable.rb +1 -0
- data/lib/airbrake-ruby/notice.rb +1 -8
- data/lib/airbrake-ruby/notice_notifier.rb +7 -0
- data/lib/airbrake-ruby/performance_breakdown.rb +1 -6
- data/lib/airbrake-ruby/performance_notifier.rb +2 -15
- data/lib/airbrake-ruby/promise.rb +1 -0
- data/lib/airbrake-ruby/query.rb +1 -6
- data/lib/airbrake-ruby/queue.rb +1 -8
- data/lib/airbrake-ruby/remote_settings.rb +145 -0
- data/lib/airbrake-ruby/remote_settings/settings_data.rb +120 -0
- data/lib/airbrake-ruby/request.rb +1 -8
- data/lib/airbrake-ruby/stat.rb +1 -12
- data/lib/airbrake-ruby/sync_sender.rb +3 -2
- data/lib/airbrake-ruby/tdigest.rb +2 -0
- data/lib/airbrake-ruby/thread_pool.rb +2 -0
- data/lib/airbrake-ruby/truncator.rb +8 -2
- data/lib/airbrake-ruby/version.rb +11 -1
- data/spec/airbrake_spec.rb +71 -36
- data/spec/backtrace_spec.rb +26 -26
- data/spec/code_hunk_spec.rb +2 -2
- data/spec/config/processor_spec.rb +209 -0
- data/spec/config/validator_spec.rb +18 -1
- data/spec/config_spec.rb +13 -6
- data/spec/filter_chain_spec.rb +27 -0
- data/spec/filters/gem_root_filter_spec.rb +4 -4
- data/spec/filters/git_last_checkout_filter_spec.rb +20 -3
- data/spec/filters/{keys_whitelist_spec.rb → keys_allowlist_spec.rb} +11 -10
- data/spec/filters/{keys_blacklist_spec.rb → keys_blocklist_spec.rb} +20 -10
- data/spec/filters/root_directory_filter_spec.rb +4 -4
- data/spec/filters/sql_filter_spec.rb +5 -5
- data/spec/notice_notifier/options_spec.rb +6 -6
- data/spec/notice_notifier_spec.rb +2 -2
- data/spec/notice_spec.rb +1 -1
- data/spec/performance_breakdown_spec.rb +0 -12
- data/spec/performance_notifier_spec.rb +2 -27
- data/spec/query_spec.rb +1 -11
- data/spec/queue_spec.rb +1 -13
- data/spec/remote_settings/settings_data_spec.rb +365 -0
- data/spec/remote_settings_spec.rb +230 -0
- data/spec/request_spec.rb +1 -13
- data/spec/spec_helper.rb +4 -4
- data/spec/stat_spec.rb +0 -9
- data/spec/sync_sender_spec.rb +3 -1
- data/spec/thread_pool_spec.rb +25 -5
- metadata +22 -14
@@ -0,0 +1,120 @@
|
|
1
|
+
module Airbrake
|
2
|
+
class RemoteSettings
|
3
|
+
# SettingsData is a container, which wraps JSON payload returned by the
|
4
|
+
# remote settings API. It exposes the payload via convenient methods and
|
5
|
+
# also ensures that in case some data from the payload is missing, a default
|
6
|
+
# value would be returned instead.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# # Create the object and pass initial data (empty hash).
|
10
|
+
# settings_data = SettingsData.new({})
|
11
|
+
#
|
12
|
+
# settings_data.interval #=> 600
|
13
|
+
#
|
14
|
+
# @since 5.0.0
|
15
|
+
# @api private
|
16
|
+
class SettingsData
|
17
|
+
# @return [Integer] how frequently we should poll the config API
|
18
|
+
DEFAULT_INTERVAL = 600
|
19
|
+
|
20
|
+
# @return [String] API version of the S3 API to poll
|
21
|
+
API_VER = '2020-06-18'.freeze
|
22
|
+
|
23
|
+
# @return [String] what path to poll
|
24
|
+
CONFIG_ROUTE_PATTERN =
|
25
|
+
"%<host>s/#{API_VER}/config/%<project_id>s/config.json".freeze
|
26
|
+
|
27
|
+
# @return [Hash{Symbol=>String}] the hash of all supported settings where
|
28
|
+
# the value is the name of the setting returned by the API
|
29
|
+
SETTINGS = {
|
30
|
+
errors: 'errors'.freeze,
|
31
|
+
apm: 'apm'.freeze,
|
32
|
+
}.freeze
|
33
|
+
|
34
|
+
# @param [Integer] project_id
|
35
|
+
# @param [Hash{String=>Object}] data
|
36
|
+
def initialize(project_id, data)
|
37
|
+
@project_id = project_id
|
38
|
+
@data = data
|
39
|
+
end
|
40
|
+
|
41
|
+
# Merges the given +hash+ with internal data.
|
42
|
+
#
|
43
|
+
# @param [Hash{String=>Object}] hash
|
44
|
+
# @return [self]
|
45
|
+
def merge!(hash)
|
46
|
+
@data.merge!(hash)
|
47
|
+
|
48
|
+
self
|
49
|
+
end
|
50
|
+
|
51
|
+
# @return [Integer] how frequently we should poll for the config
|
52
|
+
def interval
|
53
|
+
return DEFAULT_INTERVAL if !@data.key?('poll_sec') || !@data['poll_sec']
|
54
|
+
|
55
|
+
@data['poll_sec'] > 0 ? @data['poll_sec'] : DEFAULT_INTERVAL
|
56
|
+
end
|
57
|
+
|
58
|
+
# @param [String] remote_config_host
|
59
|
+
# @return [String] where the config is stored on S3.
|
60
|
+
def config_route(remote_config_host)
|
61
|
+
if !@data.key?('config_route') || !@data['config_route']
|
62
|
+
return format(
|
63
|
+
CONFIG_ROUTE_PATTERN,
|
64
|
+
host: remote_config_host.chomp('/'),
|
65
|
+
project_id: @project_id,
|
66
|
+
)
|
67
|
+
end
|
68
|
+
|
69
|
+
format(
|
70
|
+
CONFIG_ROUTE_PATTERN,
|
71
|
+
host: @data['config_route'].chomp('/'),
|
72
|
+
project_id: @project_id,
|
73
|
+
)
|
74
|
+
end
|
75
|
+
|
76
|
+
# @return [Boolean] whether error notifications are enabled
|
77
|
+
def error_notifications?
|
78
|
+
return true unless (s = find_setting(SETTINGS[:errors]))
|
79
|
+
|
80
|
+
s['enabled']
|
81
|
+
end
|
82
|
+
|
83
|
+
# @return [Boolean] whether APM is enabled
|
84
|
+
def performance_stats?
|
85
|
+
return true unless (s = find_setting(SETTINGS[:apm]))
|
86
|
+
|
87
|
+
s['enabled']
|
88
|
+
end
|
89
|
+
|
90
|
+
# @return [String, nil] the host, which provides the API endpoint to which
|
91
|
+
# exceptions should be sent
|
92
|
+
def error_host
|
93
|
+
return unless (s = find_setting(SETTINGS[:errors]))
|
94
|
+
|
95
|
+
s['endpoint']
|
96
|
+
end
|
97
|
+
|
98
|
+
# @return [String, nil] the host, which provides the API endpoint to which
|
99
|
+
# APM data should be sent
|
100
|
+
def apm_host
|
101
|
+
return unless (s = find_setting(SETTINGS[:apm]))
|
102
|
+
|
103
|
+
s['endpoint']
|
104
|
+
end
|
105
|
+
|
106
|
+
# @return [Hash{String=>Object}] raw representation of JSON payload
|
107
|
+
def to_h
|
108
|
+
@data.dup
|
109
|
+
end
|
110
|
+
|
111
|
+
private
|
112
|
+
|
113
|
+
def find_setting(name)
|
114
|
+
return unless @data.key?('settings')
|
115
|
+
|
116
|
+
@data['settings'].find { |s| s['name'] == name }
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -4,7 +4,6 @@ module Airbrake
|
|
4
4
|
# @see Airbrake.notify_request
|
5
5
|
# @api public
|
6
6
|
# @since v3.2.0
|
7
|
-
# rubocop:disable Metrics/ParameterLists
|
8
7
|
class Request
|
9
8
|
include HashKeyable
|
10
9
|
include Ignorable
|
@@ -12,15 +11,12 @@ module Airbrake
|
|
12
11
|
include Mergeable
|
13
12
|
include Grouppable
|
14
13
|
|
15
|
-
attr_accessor :method, :route, :status_code, :
|
16
|
-
:timing, :time
|
14
|
+
attr_accessor :method, :route, :status_code, :timing, :time
|
17
15
|
|
18
16
|
def initialize(
|
19
17
|
method:,
|
20
18
|
route:,
|
21
19
|
status_code:,
|
22
|
-
start_time: Time.now,
|
23
|
-
end_time: start_time + 1,
|
24
20
|
timing: nil,
|
25
21
|
time: Time.now
|
26
22
|
)
|
@@ -28,8 +24,6 @@ module Airbrake
|
|
28
24
|
@method = method
|
29
25
|
@route = route
|
30
26
|
@status_code = status_code
|
31
|
-
@start_time = start_time
|
32
|
-
@end_time = end_time
|
33
27
|
@timing = timing
|
34
28
|
@time = time
|
35
29
|
end
|
@@ -51,5 +45,4 @@ module Airbrake
|
|
51
45
|
}.delete_if { |_key, val| val.nil? }
|
52
46
|
end
|
53
47
|
end
|
54
|
-
# rubocop:enable Metrics/ParameterLists
|
55
48
|
end
|
data/lib/airbrake-ruby/stat.rb
CHANGED
@@ -9,7 +9,7 @@ module Airbrake
|
|
9
9
|
#
|
10
10
|
# @example
|
11
11
|
# stat = Airbrake::Stat.new
|
12
|
-
# stat.
|
12
|
+
# stat.increment_ms(2000)
|
13
13
|
# stat.to_h # Pack and serialize data so it can be transmitted.
|
14
14
|
#
|
15
15
|
# @since v3.2.0
|
@@ -41,17 +41,6 @@ module Airbrake
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
-
# Increments tdigest timings and updates tdigest with the difference between
|
45
|
-
# +end_time+ and +start_time+.
|
46
|
-
#
|
47
|
-
# @param [Date] start_time
|
48
|
-
# @param [Date] end_time
|
49
|
-
# @return [void]
|
50
|
-
def increment(start_time, end_time = nil)
|
51
|
-
end_time ||= Time.new
|
52
|
-
increment_ms((end_time - start_time) * 1000)
|
53
|
-
end
|
54
|
-
|
55
44
|
# Increments tdigest timings and updates tdigest with given +ms+ value.
|
56
45
|
#
|
57
46
|
# @param [Float] ms
|
@@ -23,7 +23,7 @@ module Airbrake
|
|
23
23
|
# @param [#to_json] data
|
24
24
|
# @param [URI::HTTPS] endpoint
|
25
25
|
# @return [Hash{String=>String}] the parsed HTTP response
|
26
|
-
def send(data, promise, endpoint = @config.
|
26
|
+
def send(data, promise, endpoint = @config.error_endpoint)
|
27
27
|
return promise if rate_limited_ip?(promise)
|
28
28
|
|
29
29
|
response = nil
|
@@ -47,6 +47,7 @@ module Airbrake
|
|
47
47
|
end
|
48
48
|
|
49
49
|
return promise.reject(parsed_resp['error']) if parsed_resp.key?('error')
|
50
|
+
|
50
51
|
promise.resolve(parsed_resp)
|
51
52
|
end
|
52
53
|
|
@@ -79,7 +80,7 @@ module Airbrake
|
|
79
80
|
req['Authorization'] = "Bearer #{@config.project_key}"
|
80
81
|
req['Content-Type'] = CONTENT_TYPE
|
81
82
|
req['User-Agent'] =
|
82
|
-
"#{Airbrake::
|
83
|
+
"#{Airbrake::NOTIFIER_INFO[:name]}/#{Airbrake::AIRBRAKE_RUBY_VERSION}" \
|
83
84
|
" Ruby/#{RUBY_VERSION}"
|
84
85
|
|
85
86
|
req
|
@@ -200,6 +200,7 @@ module Airbrake
|
|
200
200
|
unless (0..1).cover?(item)
|
201
201
|
raise ArgumentError, "p should be in [0,1], got #{item}"
|
202
202
|
end
|
203
|
+
|
203
204
|
if size == 0
|
204
205
|
nil
|
205
206
|
else
|
@@ -271,6 +272,7 @@ module Airbrake
|
|
271
272
|
shift = 7
|
272
273
|
while (v & 0x80) != 0
|
273
274
|
raise 'Shift too large in decode' if shift > 28
|
275
|
+
|
274
276
|
v = counts_bytes.shift || 0
|
275
277
|
z += (v & 0x7f) << shift
|
276
278
|
shift += 7
|
@@ -83,6 +83,7 @@ module Airbrake
|
|
83
83
|
|
84
84
|
if @pid != Process.pid && @workers.list.empty?
|
85
85
|
@pid = Process.pid
|
86
|
+
@workers = ThreadGroup.new
|
86
87
|
spawn_workers
|
87
88
|
end
|
88
89
|
|
@@ -128,6 +129,7 @@ module Airbrake
|
|
128
129
|
Thread.new do
|
129
130
|
while (message = @queue.pop)
|
130
131
|
break if message == :stop
|
132
|
+
|
131
133
|
@block.call(message)
|
132
134
|
end
|
133
135
|
end
|
@@ -12,6 +12,10 @@ module Airbrake
|
|
12
12
|
# strings with +ENCODING_OPTIONS+
|
13
13
|
TEMP_ENCODING = 'utf-16'.freeze
|
14
14
|
|
15
|
+
# @return [Array<Encoding>] encodings that are eligible for fixing invalid
|
16
|
+
# characters
|
17
|
+
SUPPORTED_ENCODINGS = [Encoding::UTF_8, Encoding::ASCII].freeze
|
18
|
+
|
15
19
|
# @return [String] what to append when something is a circular reference
|
16
20
|
CIRCULAR = '[Circular]'.freeze
|
17
21
|
|
@@ -35,6 +39,7 @@ module Airbrake
|
|
35
39
|
def truncate(object, seen = Set.new)
|
36
40
|
if seen.include?(object.object_id)
|
37
41
|
return CIRCULAR if CIRCULAR_TYPES.any? { |t| object.is_a?(t) }
|
42
|
+
|
38
43
|
return object
|
39
44
|
end
|
40
45
|
truncate_object(object, seen << object.object_id)
|
@@ -63,6 +68,7 @@ module Airbrake
|
|
63
68
|
def truncate_string(str)
|
64
69
|
fixed_str = replace_invalid_characters(str)
|
65
70
|
return fixed_str if fixed_str.length <= @max_size
|
71
|
+
|
66
72
|
(fixed_str.slice(0, @max_size) + TRUNCATED).freeze
|
67
73
|
end
|
68
74
|
|
@@ -76,6 +82,7 @@ module Airbrake
|
|
76
82
|
truncated_hash = {}
|
77
83
|
hash.each_with_index do |(key, val), idx|
|
78
84
|
break if idx + 1 > @max_size
|
85
|
+
|
79
86
|
truncated_hash[key] = truncate(val, seen)
|
80
87
|
end
|
81
88
|
|
@@ -103,8 +110,7 @@ module Airbrake
|
|
103
110
|
# @return [String] a UTF-8 encoded string
|
104
111
|
# @see https://github.com/flori/json/commit/3e158410e81f94dbbc3da6b7b35f4f64983aa4e3
|
105
112
|
def replace_invalid_characters(str)
|
106
|
-
|
107
|
-
utf8_string = (encoding == Encoding::UTF_8 || encoding == Encoding::ASCII)
|
113
|
+
utf8_string = SUPPORTED_ENCODINGS.include?(str.encoding)
|
108
114
|
return str if utf8_string && str.valid_encoding?
|
109
115
|
|
110
116
|
temp_str = str.dup
|
@@ -2,5 +2,15 @@
|
|
2
2
|
# More information: http://semver.org/
|
3
3
|
module Airbrake
|
4
4
|
# @return [String] the library version
|
5
|
-
|
5
|
+
# @api public
|
6
|
+
AIRBRAKE_RUBY_VERSION = '5.0.0'.freeze
|
7
|
+
|
8
|
+
# @return [Hash{Symbol=>String}] the information about the notifier library
|
9
|
+
# @since 5.0.0
|
10
|
+
# @api public
|
11
|
+
NOTIFIER_INFO = {
|
12
|
+
name: 'airbrake-ruby'.freeze,
|
13
|
+
version: Airbrake::AIRBRAKE_RUBY_VERSION,
|
14
|
+
url: 'https://github.com/airbrake/airbrake-ruby'.freeze,
|
15
|
+
}.freeze
|
6
16
|
end
|
data/spec/airbrake_spec.rb
CHANGED
@@ -1,4 +1,13 @@
|
|
1
1
|
RSpec.describe Airbrake do
|
2
|
+
let(:remote_settings) { instance_double(Airbrake::RemoteSettings) }
|
3
|
+
|
4
|
+
before do
|
5
|
+
allow(Airbrake::RemoteSettings).to receive(:poll).and_return(remote_settings)
|
6
|
+
allow(remote_settings).to receive(:stop_polling)
|
7
|
+
end
|
8
|
+
|
9
|
+
after { described_class.instance_variable_set(:@remote_settings, nil) }
|
10
|
+
|
2
11
|
it "gets initialized with a performance notifier" do
|
3
12
|
expect(described_class.performance_notifier).not_to be_nil
|
4
13
|
end
|
@@ -85,43 +94,55 @@ RSpec.describe Airbrake do
|
|
85
94
|
expect(described_class.notice_notifier).not_to receive(:add_filter)
|
86
95
|
10.times { described_class.configure {} }
|
87
96
|
end
|
97
|
+
|
98
|
+
it "appends some default filters" do
|
99
|
+
allow(described_class.notice_notifier).to receive(:add_filter)
|
100
|
+
expect(described_class.notice_notifier).to receive(:add_filter).with(
|
101
|
+
an_instance_of(Airbrake::Filters::RootDirectoryFilter),
|
102
|
+
)
|
103
|
+
|
104
|
+
described_class.configure do |c|
|
105
|
+
c.project_id = 1
|
106
|
+
c.project_key = '2'
|
107
|
+
end
|
108
|
+
end
|
88
109
|
end
|
89
110
|
|
90
|
-
context "when
|
91
|
-
before { allow(
|
111
|
+
context "when blocklist_keys gets configured" do
|
112
|
+
before { allow(described_class.notice_notifier).to receive(:add_filter) }
|
92
113
|
|
93
|
-
it "adds
|
94
|
-
expect(
|
95
|
-
.with(an_instance_of(Airbrake::Filters::
|
96
|
-
described_class.configure { |c| c.
|
114
|
+
it "adds blocklist filter" do
|
115
|
+
expect(described_class.notice_notifier).to receive(:add_filter)
|
116
|
+
.with(an_instance_of(Airbrake::Filters::KeysBlocklist))
|
117
|
+
described_class.configure { |c| c.blocklist_keys = %w[password] }
|
97
118
|
end
|
98
119
|
|
99
|
-
it "initializes
|
100
|
-
expect(Airbrake::Filters::
|
101
|
-
described_class.configure { |c| c.
|
120
|
+
it "initializes blocklist with specified parameters" do
|
121
|
+
expect(Airbrake::Filters::KeysBlocklist).to receive(:new).with(%w[password])
|
122
|
+
described_class.configure { |c| c.blocklist_keys = %w[password] }
|
102
123
|
end
|
103
124
|
end
|
104
125
|
|
105
|
-
context "when
|
106
|
-
before { allow(
|
126
|
+
context "when allowlist_keys gets configured" do
|
127
|
+
before { allow(described_class.notice_notifier).to receive(:add_filter) }
|
107
128
|
|
108
|
-
it "adds
|
109
|
-
expect(
|
110
|
-
.with(an_instance_of(Airbrake::Filters::
|
111
|
-
described_class.configure { |c| c.
|
129
|
+
it "adds allowlist filter" do
|
130
|
+
expect(described_class.notice_notifier).to receive(:add_filter)
|
131
|
+
.with(an_instance_of(Airbrake::Filters::KeysAllowlist))
|
132
|
+
described_class.configure { |c| c.allowlist_keys = %w[banana] }
|
112
133
|
end
|
113
134
|
|
114
|
-
it "initializes
|
115
|
-
expect(Airbrake::Filters::
|
116
|
-
described_class.configure { |c| c.
|
135
|
+
it "initializes allowlist with specified parameters" do
|
136
|
+
expect(Airbrake::Filters::KeysAllowlist).to receive(:new).with(%w[banana])
|
137
|
+
described_class.configure { |c| c.allowlist_keys = %w[banana] }
|
117
138
|
end
|
118
139
|
end
|
119
140
|
|
120
141
|
context "when root_directory gets configured" do
|
121
|
-
before { allow(
|
142
|
+
before { allow(described_class.notice_notifier).to receive(:add_filter) }
|
122
143
|
|
123
144
|
it "adds root directory filter" do
|
124
|
-
expect(
|
145
|
+
expect(described_class.notice_notifier).to receive(:add_filter)
|
125
146
|
.with(an_instance_of(Airbrake::Filters::RootDirectoryFilter))
|
126
147
|
described_class.configure { |c| c.root_directory = '/my/path' }
|
127
148
|
end
|
@@ -133,7 +154,7 @@ RSpec.describe Airbrake do
|
|
133
154
|
end
|
134
155
|
|
135
156
|
it "adds git revision filter" do
|
136
|
-
expect(
|
157
|
+
expect(described_class.notice_notifier).to receive(:add_filter)
|
137
158
|
.with(an_instance_of(Airbrake::Filters::GitRevisionFilter))
|
138
159
|
described_class.configure { |c| c.root_directory = '/my/path' }
|
139
160
|
end
|
@@ -145,7 +166,7 @@ RSpec.describe Airbrake do
|
|
145
166
|
end
|
146
167
|
|
147
168
|
it "adds git repository filter" do
|
148
|
-
expect(
|
169
|
+
expect(described_class.notice_notifier).to receive(:add_filter)
|
149
170
|
.with(an_instance_of(Airbrake::Filters::GitRepositoryFilter))
|
150
171
|
described_class.configure { |c| c.root_directory = '/my/path' }
|
151
172
|
end
|
@@ -157,7 +178,7 @@ RSpec.describe Airbrake do
|
|
157
178
|
end
|
158
179
|
|
159
180
|
it "adds git last checkout filter" do
|
160
|
-
expect(
|
181
|
+
expect(described_class.notice_notifier).to receive(:add_filter)
|
161
182
|
.with(an_instance_of(Airbrake::Filters::GitLastCheckoutFilter))
|
162
183
|
described_class.configure { |c| c.root_directory = '/my/path' }
|
163
184
|
end
|
@@ -170,7 +191,7 @@ RSpec.describe Airbrake do
|
|
170
191
|
end
|
171
192
|
end
|
172
193
|
|
173
|
-
describe "
|
194
|
+
describe ".notify_request" do
|
174
195
|
context "when :stash key is not provided" do
|
175
196
|
it "doesn't add anything to the stash of the request" do
|
176
197
|
expect(described_class.performance_notifier).to receive(:notify) do |request|
|
@@ -205,7 +226,7 @@ RSpec.describe Airbrake do
|
|
205
226
|
end
|
206
227
|
end
|
207
228
|
|
208
|
-
describe "
|
229
|
+
describe ".notify_request_sync" do
|
209
230
|
it "notifies request synchronously" do
|
210
231
|
expect(described_class.performance_notifier).to receive(:notify_sync)
|
211
232
|
|
@@ -221,7 +242,7 @@ RSpec.describe Airbrake do
|
|
221
242
|
end
|
222
243
|
end
|
223
244
|
|
224
|
-
describe "
|
245
|
+
describe ".notify_query" do
|
225
246
|
context "when :stash key is not provided" do
|
226
247
|
it "doesn't add anything to the stash of the query" do
|
227
248
|
expect(described_class.performance_notifier).to receive(:notify) do |query|
|
@@ -256,7 +277,7 @@ RSpec.describe Airbrake do
|
|
256
277
|
end
|
257
278
|
end
|
258
279
|
|
259
|
-
describe "
|
280
|
+
describe ".notify_query_sync" do
|
260
281
|
it "notifies query synchronously" do
|
261
282
|
expect(described_class.performance_notifier).to receive(:notify_sync)
|
262
283
|
|
@@ -272,7 +293,7 @@ RSpec.describe Airbrake do
|
|
272
293
|
end
|
273
294
|
end
|
274
295
|
|
275
|
-
describe "
|
296
|
+
describe ".notify_performance_breakdown" do
|
276
297
|
context "when :stash key is not provided" do
|
277
298
|
it "doesn't add anything to the stash of the performance breakdown" do
|
278
299
|
expect(described_class.performance_notifier).to receive(:notify) do |query|
|
@@ -310,7 +331,7 @@ RSpec.describe Airbrake do
|
|
310
331
|
end
|
311
332
|
end
|
312
333
|
|
313
|
-
describe "
|
334
|
+
describe ".notify_performance_breakdown_sync" do
|
314
335
|
it "notifies performance breakdown synchronously" do
|
315
336
|
expect(described_class.performance_notifier).to receive(:notify_sync)
|
316
337
|
|
@@ -327,7 +348,7 @@ RSpec.describe Airbrake do
|
|
327
348
|
end
|
328
349
|
end
|
329
350
|
|
330
|
-
describe "
|
351
|
+
describe ".notify_queue" do
|
331
352
|
context "when :stash key is not provided" do
|
332
353
|
it "doesn't add anything to the stash of the queue" do
|
333
354
|
expect(described_class.performance_notifier).to receive(:notify) do |queue|
|
@@ -358,7 +379,7 @@ RSpec.describe Airbrake do
|
|
358
379
|
end
|
359
380
|
end
|
360
381
|
|
361
|
-
describe "
|
382
|
+
describe ".notify_queue_sync" do
|
362
383
|
it "notifies queue synchronously" do
|
363
384
|
expect(described_class.performance_notifier).to receive(:notify_sync)
|
364
385
|
|
@@ -392,33 +413,47 @@ RSpec.describe Airbrake do
|
|
392
413
|
end
|
393
414
|
|
394
415
|
describe ".close" do
|
395
|
-
after {
|
416
|
+
after { described_class.reset }
|
396
417
|
|
397
418
|
context "when notice_notifier is defined" do
|
398
419
|
it "gets closed" do
|
399
|
-
expect(
|
420
|
+
expect(described_class.notice_notifier).to receive(:close)
|
400
421
|
end
|
401
422
|
end
|
402
423
|
|
403
424
|
context "when notice_notifier is undefined" do
|
404
425
|
it "doesn't get closed (because it wasn't initialized)" do
|
405
|
-
|
426
|
+
described_class.instance_variable_set(:@notice_notifier, nil)
|
406
427
|
expect_any_instance_of(Airbrake::NoticeNotifier).not_to receive(:close)
|
407
428
|
end
|
408
429
|
end
|
409
430
|
|
410
431
|
context "when performance_notifier is defined" do
|
411
432
|
it "gets closed" do
|
412
|
-
expect(
|
433
|
+
expect(described_class.performance_notifier).to receive(:close)
|
413
434
|
end
|
414
435
|
end
|
415
436
|
|
416
437
|
context "when perforance_notifier is undefined" do
|
417
438
|
it "doesn't get closed (because it wasn't initialized)" do
|
418
|
-
|
439
|
+
described_class.instance_variable_set(:@performance_notifier, nil)
|
419
440
|
expect_any_instance_of(Airbrake::PerformanceNotifier)
|
420
441
|
.not_to receive(:close)
|
421
442
|
end
|
422
443
|
end
|
444
|
+
|
445
|
+
context "when remote settings are defined" do
|
446
|
+
it "stops polling" do
|
447
|
+
described_class.instance_variable_set(:@remote_settings, remote_settings)
|
448
|
+
expect(remote_settings).to receive(:stop_polling)
|
449
|
+
end
|
450
|
+
end
|
451
|
+
|
452
|
+
context "when remote settings are undefined" do
|
453
|
+
it "doesn't stop polling (because they weren't initialized)" do
|
454
|
+
described_class.instance_variable_set(:@remote_settings, nil)
|
455
|
+
expect(remote_settings).not_to receive(:stop_polling)
|
456
|
+
end
|
457
|
+
end
|
423
458
|
end
|
424
459
|
end
|