airbrake-ruby 4.15.0-java → 5.0.2-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 +22 -33
- data/lib/airbrake-ruby/async_sender.rb +1 -1
- data/lib/airbrake-ruby/backtrace.rb +6 -5
- data/lib/airbrake-ruby/config.rb +30 -30
- data/lib/airbrake-ruby/config/processor.rb +69 -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 +1 -0
- 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 +1 -2
- 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_filter.rb +21 -13
- 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 +1 -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/callback.rb +44 -0
- data/lib/airbrake-ruby/remote_settings/settings_data.rb +116 -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 +1 -0
- data/lib/airbrake-ruby/truncator.rb +8 -2
- data/lib/airbrake-ruby/version.rb +11 -1
- data/spec/airbrake_spec.rb +45 -22
- data/spec/backtrace_spec.rb +26 -26
- data/spec/code_hunk_spec.rb +2 -2
- data/spec/config/processor_spec.rb +125 -0
- data/spec/config/validator_spec.rb +18 -1
- data/spec/config_spec.rb +11 -32
- data/spec/filters/gem_root_filter_spec.rb +4 -4
- data/spec/filters/keys_allowlist_spec.rb +1 -0
- data/spec/filters/keys_blocklist_spec.rb +10 -0
- data/spec/filters/root_directory_filter_spec.rb +4 -4
- data/spec/filters/sql_filter_spec.rb +2 -2
- data/spec/notice_notifier/options_spec.rb +2 -2
- 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 +0 -25
- data/spec/query_spec.rb +1 -11
- data/spec/queue_spec.rb +1 -13
- data/spec/remote_settings/callback_spec.rb +141 -0
- data/spec/remote_settings/settings_data_spec.rb +348 -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
- metadata +18 -6
@@ -0,0 +1,44 @@
|
|
1
|
+
module Airbrake
|
2
|
+
class RemoteSettings
|
3
|
+
# Callback is a class that provides a callback for the config poller, which
|
4
|
+
# updates the local config according to the data.
|
5
|
+
#
|
6
|
+
# @api private
|
7
|
+
# @since 5.0.2
|
8
|
+
class Callback
|
9
|
+
def initialize(config)
|
10
|
+
@config = config
|
11
|
+
@orig_error_notifications = config.error_notifications
|
12
|
+
@orig_performance_stats = config.performance_stats
|
13
|
+
end
|
14
|
+
|
15
|
+
# @param [Airbrake::RemoteSettings::SettingsData] data
|
16
|
+
# @return [void]
|
17
|
+
def call(data)
|
18
|
+
@config.logger.debug(
|
19
|
+
"#{LOG_LABEL} applying remote settings: #{data.to_h}",
|
20
|
+
)
|
21
|
+
|
22
|
+
@config.error_host = data.error_host if data.error_host
|
23
|
+
@config.apm_host = data.apm_host if data.apm_host
|
24
|
+
|
25
|
+
process_error_notifications(data)
|
26
|
+
process_performance_stats(data)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def process_error_notifications(data)
|
32
|
+
return unless @orig_error_notifications
|
33
|
+
|
34
|
+
@config.error_notifications = data.error_notifications?
|
35
|
+
end
|
36
|
+
|
37
|
+
def process_performance_stats(data)
|
38
|
+
return unless @orig_performance_stats
|
39
|
+
|
40
|
+
@config.performance_stats = data.performance_stats?
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,116 @@
|
|
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['config_route'] && !@data['config_route'].empty?
|
62
|
+
return remote_config_host.chomp('/') + '/' + @data['config_route']
|
63
|
+
end
|
64
|
+
|
65
|
+
format(
|
66
|
+
CONFIG_ROUTE_PATTERN,
|
67
|
+
host: remote_config_host.chomp('/'),
|
68
|
+
project_id: @project_id,
|
69
|
+
)
|
70
|
+
end
|
71
|
+
|
72
|
+
# @return [Boolean] whether error notifications are enabled
|
73
|
+
def error_notifications?
|
74
|
+
return true unless (s = find_setting(SETTINGS[:errors]))
|
75
|
+
|
76
|
+
s['enabled']
|
77
|
+
end
|
78
|
+
|
79
|
+
# @return [Boolean] whether APM is enabled
|
80
|
+
def performance_stats?
|
81
|
+
return true unless (s = find_setting(SETTINGS[:apm]))
|
82
|
+
|
83
|
+
s['enabled']
|
84
|
+
end
|
85
|
+
|
86
|
+
# @return [String, nil] the host, which provides the API endpoint to which
|
87
|
+
# exceptions should be sent
|
88
|
+
def error_host
|
89
|
+
return unless (s = find_setting(SETTINGS[:errors]))
|
90
|
+
|
91
|
+
s['endpoint']
|
92
|
+
end
|
93
|
+
|
94
|
+
# @return [String, nil] the host, which provides the API endpoint to which
|
95
|
+
# APM data should be sent
|
96
|
+
def apm_host
|
97
|
+
return unless (s = find_setting(SETTINGS[:apm]))
|
98
|
+
|
99
|
+
s['endpoint']
|
100
|
+
end
|
101
|
+
|
102
|
+
# @return [Hash{String=>Object}] raw representation of JSON payload
|
103
|
+
def to_h
|
104
|
+
@data.dup
|
105
|
+
end
|
106
|
+
|
107
|
+
private
|
108
|
+
|
109
|
+
def find_setting(name)
|
110
|
+
return unless @data.key?('settings')
|
111
|
+
|
112
|
+
@data['settings'].find { |s| s['name'] == name }
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
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
|
@@ -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.2'.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
|
@@ -100,10 +109,10 @@ RSpec.describe Airbrake do
|
|
100
109
|
end
|
101
110
|
|
102
111
|
context "when blocklist_keys gets configured" do
|
103
|
-
before { allow(
|
112
|
+
before { allow(described_class.notice_notifier).to receive(:add_filter) }
|
104
113
|
|
105
114
|
it "adds blocklist filter" do
|
106
|
-
expect(
|
115
|
+
expect(described_class.notice_notifier).to receive(:add_filter)
|
107
116
|
.with(an_instance_of(Airbrake::Filters::KeysBlocklist))
|
108
117
|
described_class.configure { |c| c.blocklist_keys = %w[password] }
|
109
118
|
end
|
@@ -115,10 +124,10 @@ RSpec.describe Airbrake do
|
|
115
124
|
end
|
116
125
|
|
117
126
|
context "when allowlist_keys gets configured" do
|
118
|
-
before { allow(
|
127
|
+
before { allow(described_class.notice_notifier).to receive(:add_filter) }
|
119
128
|
|
120
129
|
it "adds allowlist filter" do
|
121
|
-
expect(
|
130
|
+
expect(described_class.notice_notifier).to receive(:add_filter)
|
122
131
|
.with(an_instance_of(Airbrake::Filters::KeysAllowlist))
|
123
132
|
described_class.configure { |c| c.allowlist_keys = %w[banana] }
|
124
133
|
end
|
@@ -130,10 +139,10 @@ RSpec.describe Airbrake do
|
|
130
139
|
end
|
131
140
|
|
132
141
|
context "when root_directory gets configured" do
|
133
|
-
before { allow(
|
142
|
+
before { allow(described_class.notice_notifier).to receive(:add_filter) }
|
134
143
|
|
135
144
|
it "adds root directory filter" do
|
136
|
-
expect(
|
145
|
+
expect(described_class.notice_notifier).to receive(:add_filter)
|
137
146
|
.with(an_instance_of(Airbrake::Filters::RootDirectoryFilter))
|
138
147
|
described_class.configure { |c| c.root_directory = '/my/path' }
|
139
148
|
end
|
@@ -145,7 +154,7 @@ RSpec.describe Airbrake do
|
|
145
154
|
end
|
146
155
|
|
147
156
|
it "adds git revision filter" do
|
148
|
-
expect(
|
157
|
+
expect(described_class.notice_notifier).to receive(:add_filter)
|
149
158
|
.with(an_instance_of(Airbrake::Filters::GitRevisionFilter))
|
150
159
|
described_class.configure { |c| c.root_directory = '/my/path' }
|
151
160
|
end
|
@@ -157,7 +166,7 @@ RSpec.describe Airbrake do
|
|
157
166
|
end
|
158
167
|
|
159
168
|
it "adds git repository filter" do
|
160
|
-
expect(
|
169
|
+
expect(described_class.notice_notifier).to receive(:add_filter)
|
161
170
|
.with(an_instance_of(Airbrake::Filters::GitRepositoryFilter))
|
162
171
|
described_class.configure { |c| c.root_directory = '/my/path' }
|
163
172
|
end
|
@@ -169,7 +178,7 @@ RSpec.describe Airbrake do
|
|
169
178
|
end
|
170
179
|
|
171
180
|
it "adds git last checkout filter" do
|
172
|
-
expect(
|
181
|
+
expect(described_class.notice_notifier).to receive(:add_filter)
|
173
182
|
.with(an_instance_of(Airbrake::Filters::GitLastCheckoutFilter))
|
174
183
|
described_class.configure { |c| c.root_directory = '/my/path' }
|
175
184
|
end
|
@@ -182,7 +191,7 @@ RSpec.describe Airbrake do
|
|
182
191
|
end
|
183
192
|
end
|
184
193
|
|
185
|
-
describe "
|
194
|
+
describe ".notify_request" do
|
186
195
|
context "when :stash key is not provided" do
|
187
196
|
it "doesn't add anything to the stash of the request" do
|
188
197
|
expect(described_class.performance_notifier).to receive(:notify) do |request|
|
@@ -217,7 +226,7 @@ RSpec.describe Airbrake do
|
|
217
226
|
end
|
218
227
|
end
|
219
228
|
|
220
|
-
describe "
|
229
|
+
describe ".notify_request_sync" do
|
221
230
|
it "notifies request synchronously" do
|
222
231
|
expect(described_class.performance_notifier).to receive(:notify_sync)
|
223
232
|
|
@@ -233,7 +242,7 @@ RSpec.describe Airbrake do
|
|
233
242
|
end
|
234
243
|
end
|
235
244
|
|
236
|
-
describe "
|
245
|
+
describe ".notify_query" do
|
237
246
|
context "when :stash key is not provided" do
|
238
247
|
it "doesn't add anything to the stash of the query" do
|
239
248
|
expect(described_class.performance_notifier).to receive(:notify) do |query|
|
@@ -268,7 +277,7 @@ RSpec.describe Airbrake do
|
|
268
277
|
end
|
269
278
|
end
|
270
279
|
|
271
|
-
describe "
|
280
|
+
describe ".notify_query_sync" do
|
272
281
|
it "notifies query synchronously" do
|
273
282
|
expect(described_class.performance_notifier).to receive(:notify_sync)
|
274
283
|
|
@@ -284,7 +293,7 @@ RSpec.describe Airbrake do
|
|
284
293
|
end
|
285
294
|
end
|
286
295
|
|
287
|
-
describe "
|
296
|
+
describe ".notify_performance_breakdown" do
|
288
297
|
context "when :stash key is not provided" do
|
289
298
|
it "doesn't add anything to the stash of the performance breakdown" do
|
290
299
|
expect(described_class.performance_notifier).to receive(:notify) do |query|
|
@@ -322,7 +331,7 @@ RSpec.describe Airbrake do
|
|
322
331
|
end
|
323
332
|
end
|
324
333
|
|
325
|
-
describe "
|
334
|
+
describe ".notify_performance_breakdown_sync" do
|
326
335
|
it "notifies performance breakdown synchronously" do
|
327
336
|
expect(described_class.performance_notifier).to receive(:notify_sync)
|
328
337
|
|
@@ -339,7 +348,7 @@ RSpec.describe Airbrake do
|
|
339
348
|
end
|
340
349
|
end
|
341
350
|
|
342
|
-
describe "
|
351
|
+
describe ".notify_queue" do
|
343
352
|
context "when :stash key is not provided" do
|
344
353
|
it "doesn't add anything to the stash of the queue" do
|
345
354
|
expect(described_class.performance_notifier).to receive(:notify) do |queue|
|
@@ -370,7 +379,7 @@ RSpec.describe Airbrake do
|
|
370
379
|
end
|
371
380
|
end
|
372
381
|
|
373
|
-
describe "
|
382
|
+
describe ".notify_queue_sync" do
|
374
383
|
it "notifies queue synchronously" do
|
375
384
|
expect(described_class.performance_notifier).to receive(:notify_sync)
|
376
385
|
|
@@ -404,33 +413,47 @@ RSpec.describe Airbrake do
|
|
404
413
|
end
|
405
414
|
|
406
415
|
describe ".close" do
|
407
|
-
after {
|
416
|
+
after { described_class.reset }
|
408
417
|
|
409
418
|
context "when notice_notifier is defined" do
|
410
419
|
it "gets closed" do
|
411
|
-
expect(
|
420
|
+
expect(described_class.notice_notifier).to receive(:close)
|
412
421
|
end
|
413
422
|
end
|
414
423
|
|
415
424
|
context "when notice_notifier is undefined" do
|
416
425
|
it "doesn't get closed (because it wasn't initialized)" do
|
417
|
-
|
426
|
+
described_class.instance_variable_set(:@notice_notifier, nil)
|
418
427
|
expect_any_instance_of(Airbrake::NoticeNotifier).not_to receive(:close)
|
419
428
|
end
|
420
429
|
end
|
421
430
|
|
422
431
|
context "when performance_notifier is defined" do
|
423
432
|
it "gets closed" do
|
424
|
-
expect(
|
433
|
+
expect(described_class.performance_notifier).to receive(:close)
|
425
434
|
end
|
426
435
|
end
|
427
436
|
|
428
437
|
context "when perforance_notifier is undefined" do
|
429
438
|
it "doesn't get closed (because it wasn't initialized)" do
|
430
|
-
|
439
|
+
described_class.instance_variable_set(:@performance_notifier, nil)
|
431
440
|
expect_any_instance_of(Airbrake::PerformanceNotifier)
|
432
441
|
.not_to receive(:close)
|
433
442
|
end
|
434
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
|
435
458
|
end
|
436
459
|
end
|