airbrake-ruby 4.6.0 → 6.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.
- checksums.yaml +5 -5
- data/lib/airbrake-ruby/async_sender.rb +24 -109
- data/lib/airbrake-ruby/backlog.rb +123 -0
- data/lib/airbrake-ruby/backtrace.rb +8 -7
- data/lib/airbrake-ruby/benchmark.rb +1 -1
- data/lib/airbrake-ruby/code_hunk.rb +1 -1
- data/lib/airbrake-ruby/config/processor.rb +77 -0
- data/lib/airbrake-ruby/config/validator.rb +9 -3
- data/lib/airbrake-ruby/config.rb +78 -19
- data/lib/airbrake-ruby/context.rb +51 -0
- data/lib/airbrake-ruby/deploy_notifier.rb +1 -1
- data/lib/airbrake-ruby/file_cache.rb +6 -0
- data/lib/airbrake-ruby/filter_chain.rb +18 -1
- data/lib/airbrake-ruby/filters/context_filter.rb +4 -5
- data/lib/airbrake-ruby/filters/dependency_filter.rb +1 -0
- data/lib/airbrake-ruby/filters/exception_attributes_filter.rb +3 -3
- data/lib/airbrake-ruby/filters/gem_root_filter.rb +1 -0
- data/lib/airbrake-ruby/filters/git_last_checkout_filter.rb +7 -7
- data/lib/airbrake-ruby/filters/git_repository_filter.rb +11 -2
- data/lib/airbrake-ruby/filters/git_revision_filter.rb +3 -1
- 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 +41 -22
- data/lib/airbrake-ruby/filters/root_directory_filter.rb +1 -0
- data/lib/airbrake-ruby/filters/sql_filter.rb +35 -11
- data/lib/airbrake-ruby/filters/system_exit_filter.rb +1 -0
- data/lib/airbrake-ruby/filters/thread_filter.rb +6 -5
- data/lib/airbrake-ruby/grouppable.rb +12 -0
- data/lib/airbrake-ruby/ignorable.rb +1 -2
- data/lib/airbrake-ruby/inspectable.rb +2 -2
- data/lib/airbrake-ruby/loggable.rb +1 -1
- data/lib/airbrake-ruby/mergeable.rb +12 -0
- data/lib/airbrake-ruby/monotonic_time.rb +6 -1
- data/lib/airbrake-ruby/nested_exception.rb +22 -1
- data/lib/airbrake-ruby/notice.rb +12 -17
- data/lib/airbrake-ruby/notice_notifier.rb +15 -7
- data/lib/airbrake-ruby/performance_breakdown.rb +16 -9
- data/lib/airbrake-ruby/performance_notifier.rb +106 -54
- data/lib/airbrake-ruby/promise.rb +1 -0
- data/lib/airbrake-ruby/query.rb +20 -14
- data/lib/airbrake-ruby/queue.rb +65 -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/remote_settings.rb +128 -0
- data/lib/airbrake-ruby/request.rb +14 -11
- data/lib/airbrake-ruby/response.rb +56 -5
- data/lib/airbrake-ruby/stat.rb +27 -34
- data/lib/airbrake-ruby/sync_sender.rb +43 -11
- data/lib/airbrake-ruby/tdigest.rb +52 -66
- data/lib/airbrake-ruby/thread_pool.rb +139 -0
- data/lib/airbrake-ruby/time_truncate.rb +2 -2
- data/lib/airbrake-ruby/timed_trace.rb +1 -3
- data/lib/airbrake-ruby/truncator.rb +10 -4
- data/lib/airbrake-ruby/version.rb +11 -1
- data/lib/airbrake-ruby.rb +157 -78
- metadata +122 -116
- data/spec/airbrake_spec.rb +0 -324
- data/spec/async_sender_spec.rb +0 -155
- data/spec/backtrace_spec.rb +0 -427
- data/spec/benchmark_spec.rb +0 -33
- data/spec/code_hunk_spec.rb +0 -115
- data/spec/config/validator_spec.rb +0 -184
- data/spec/config_spec.rb +0 -154
- data/spec/deploy_notifier_spec.rb +0 -48
- data/spec/file_cache.rb +0 -36
- data/spec/filter_chain_spec.rb +0 -92
- data/spec/filters/context_filter_spec.rb +0 -23
- data/spec/filters/dependency_filter_spec.rb +0 -12
- data/spec/filters/exception_attributes_filter_spec.rb +0 -50
- data/spec/filters/gem_root_filter_spec.rb +0 -41
- data/spec/filters/git_last_checkout_filter_spec.rb +0 -46
- data/spec/filters/git_repository_filter.rb +0 -61
- data/spec/filters/git_revision_filter_spec.rb +0 -126
- data/spec/filters/keys_blacklist_spec.rb +0 -225
- data/spec/filters/keys_whitelist_spec.rb +0 -194
- data/spec/filters/root_directory_filter_spec.rb +0 -39
- data/spec/filters/sql_filter_spec.rb +0 -219
- data/spec/filters/system_exit_filter_spec.rb +0 -14
- data/spec/filters/thread_filter_spec.rb +0 -277
- data/spec/fixtures/notroot.txt +0 -7
- data/spec/fixtures/project_root/code.rb +0 -221
- data/spec/fixtures/project_root/empty_file.rb +0 -0
- data/spec/fixtures/project_root/long_line.txt +0 -1
- data/spec/fixtures/project_root/short_file.rb +0 -3
- data/spec/fixtures/project_root/vendor/bundle/ignored_file.rb +0 -5
- data/spec/helpers.rb +0 -9
- data/spec/ignorable_spec.rb +0 -14
- data/spec/inspectable_spec.rb +0 -45
- data/spec/monotonic_time_spec.rb +0 -12
- data/spec/nested_exception_spec.rb +0 -73
- data/spec/notice_notifier_spec/options_spec.rb +0 -259
- data/spec/notice_notifier_spec.rb +0 -356
- data/spec/notice_spec.rb +0 -296
- data/spec/performance_breakdown_spec.rb +0 -12
- data/spec/performance_notifier_spec.rb +0 -435
- data/spec/promise_spec.rb +0 -197
- data/spec/query_spec.rb +0 -11
- data/spec/request_spec.rb +0 -11
- data/spec/response_spec.rb +0 -88
- data/spec/spec_helper.rb +0 -100
- data/spec/stashable_spec.rb +0 -23
- data/spec/stat_spec.rb +0 -47
- data/spec/sync_sender_spec.rb +0 -133
- data/spec/tdigest_spec.rb +0 -230
- data/spec/time_truncate_spec.rb +0 -13
- data/spec/timed_trace_spec.rb +0 -125
- data/spec/truncator_spec.rb +0 -238
data/spec/code_hunk_spec.rb
DELETED
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
RSpec.describe Airbrake::CodeHunk do
|
|
2
|
-
after do
|
|
3
|
-
%w[empty_file.rb code.rb banana.rb short_file.rb long_line.txt].each do |f|
|
|
4
|
-
Airbrake::FileCache[project_root_path(f)] = nil
|
|
5
|
-
end
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
describe "#to_h" do
|
|
9
|
-
context "when file is empty" do
|
|
10
|
-
subject do
|
|
11
|
-
described_class.new.get(project_root_path('empty_file.rb'), 1)
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
it { is_expected.to eq(1 => '') }
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
context "when line is nil" do
|
|
18
|
-
subject { described_class.new.get(project_root_path('code.rb'), nil) }
|
|
19
|
-
|
|
20
|
-
it { is_expected.to be_nil }
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
context "when a file doesn't exist" do
|
|
24
|
-
subject { described_class.new.get(project_root_path('banana.rb'), 1) }
|
|
25
|
-
|
|
26
|
-
it { is_expected.to be_nil }
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
context "when a file has less than NLINES lines before start line" do
|
|
30
|
-
subject { described_class.new.get(project_root_path('code.rb'), 1) }
|
|
31
|
-
|
|
32
|
-
it do
|
|
33
|
-
is_expected.to(
|
|
34
|
-
eq(
|
|
35
|
-
1 => 'module Airbrake',
|
|
36
|
-
2 => ' ##',
|
|
37
|
-
# rubocop:disable Metrics/LineLength
|
|
38
|
-
3 => ' # Represents a chunk of information that is meant to be either sent to',
|
|
39
|
-
# rubocop:enable Metrics/LineLength
|
|
40
|
-
)
|
|
41
|
-
)
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
context "when a file has less than NLINES lines after end line" do
|
|
46
|
-
subject { described_class.new.get(project_root_path('code.rb'), 222) }
|
|
47
|
-
|
|
48
|
-
it do
|
|
49
|
-
is_expected.to(
|
|
50
|
-
eq(
|
|
51
|
-
220 => ' end',
|
|
52
|
-
221 => 'end'
|
|
53
|
-
)
|
|
54
|
-
)
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
context "when a file has less than NLINES lines before and after" do
|
|
59
|
-
subject do
|
|
60
|
-
described_class.new.get(project_root_path('short_file.rb'), 2)
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
it do
|
|
64
|
-
is_expected.to(
|
|
65
|
-
eq(
|
|
66
|
-
1 => 'module Banana',
|
|
67
|
-
2 => ' attr_reader :bingo',
|
|
68
|
-
3 => 'end'
|
|
69
|
-
)
|
|
70
|
-
)
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
context "when a file has enough lines before and after" do
|
|
75
|
-
subject { described_class.new.get(project_root_path('code.rb'), 100) }
|
|
76
|
-
|
|
77
|
-
it do
|
|
78
|
-
is_expected.to(
|
|
79
|
-
eq(
|
|
80
|
-
98 => ' return json if json && json.bytesize <= MAX_NOTICE_SIZE',
|
|
81
|
-
99 => ' end',
|
|
82
|
-
100 => '',
|
|
83
|
-
101 => ' break if truncate == 0',
|
|
84
|
-
102 => ' end'
|
|
85
|
-
)
|
|
86
|
-
)
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
context "when a line exceeds the length limit" do
|
|
91
|
-
subject do
|
|
92
|
-
described_class.new.get(project_root_path('long_line.txt'), 1)
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
it "strips the line" do
|
|
96
|
-
expect(subject[1]).to eq('l' + 'o' * 196 + 'ng')
|
|
97
|
-
end
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
context "when an error occurrs while fetching code" do
|
|
101
|
-
before do
|
|
102
|
-
expect(Airbrake::FileCache).to receive(:[]).and_raise(Errno::EACCES)
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
it "logs error and returns nil" do
|
|
106
|
-
expect(Airbrake::Loggable.instance).to receive(:error).with(
|
|
107
|
-
/can't read code hunk.+Permission denied/
|
|
108
|
-
)
|
|
109
|
-
expect(subject.get(project_root_path('code.rb'), 1)).to(
|
|
110
|
-
eq(1 => '')
|
|
111
|
-
)
|
|
112
|
-
end
|
|
113
|
-
end
|
|
114
|
-
end
|
|
115
|
-
end
|
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
RSpec.describe Airbrake::Config::Validator do
|
|
2
|
-
let(:valid_id) { 123 }
|
|
3
|
-
let(:valid_key) { '123' }
|
|
4
|
-
let(:config) { Airbrake::Config.new(config_params) }
|
|
5
|
-
|
|
6
|
-
describe ".validate" do
|
|
7
|
-
context "when project_id is numerical" do
|
|
8
|
-
let(:config_params) { { project_id: valid_id, project_key: valid_key } }
|
|
9
|
-
|
|
10
|
-
it "returns a resolved promise" do
|
|
11
|
-
promise = described_class.validate(config)
|
|
12
|
-
expect(promise).to be_resolved
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
context "when project_id is a numerical String" do
|
|
17
|
-
let(:config_params) { { project_id: '123', project_key: valid_key } }
|
|
18
|
-
|
|
19
|
-
it "returns a resolved promise" do
|
|
20
|
-
promise = described_class.validate(config)
|
|
21
|
-
expect(promise).to be_resolved
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
context "when project_id is zero" do
|
|
26
|
-
let(:config_params) { { project_id: 0, project_key: valid_key } }
|
|
27
|
-
|
|
28
|
-
it "returns a rejected promise" do
|
|
29
|
-
promise = described_class.validate(config)
|
|
30
|
-
expect(promise.value).to eq('error' => ':project_id is required')
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
context "when project_id consists of letters" do
|
|
35
|
-
let(:config_params) { { project_id: 'foo', project_key: valid_key } }
|
|
36
|
-
|
|
37
|
-
it "returns a rejected promise" do
|
|
38
|
-
promise = described_class.validate(config)
|
|
39
|
-
expect(promise.value).to eq('error' => ':project_id is required')
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
context "when project_id is less than zero" do
|
|
44
|
-
let(:config_params) { { project_id: -123, project_key: valid_key } }
|
|
45
|
-
|
|
46
|
-
it "returns a rejected promise" do
|
|
47
|
-
promise = described_class.validate(config)
|
|
48
|
-
expect(promise.value).to eq('error' => ':project_id is required')
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
context "when project_key is a non-empty String" do
|
|
53
|
-
let(:config_params) { { project_id: valid_id, project_key: '123' } }
|
|
54
|
-
|
|
55
|
-
it "returns a resolved promise" do
|
|
56
|
-
promise = described_class.validate(config)
|
|
57
|
-
expect(promise).to be_resolved
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
context "when project_key is an empty String" do
|
|
62
|
-
let(:config_params) { { project_id: valid_id, project_key: '' } }
|
|
63
|
-
|
|
64
|
-
it "returns a rejected promise" do
|
|
65
|
-
promise = described_class.validate(config)
|
|
66
|
-
expect(promise.value).to eq('error' => ':project_key is required')
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
context "when project_key is a non-String" do
|
|
71
|
-
let(:config_params) { { project_id: valid_id, project_key: 123 } }
|
|
72
|
-
|
|
73
|
-
it "returns a rejected promise" do
|
|
74
|
-
promise = described_class.validate(config)
|
|
75
|
-
expect(promise.value).to eq('error' => ':project_key is required')
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
context "when environment is nil" do
|
|
80
|
-
let(:config_params) do
|
|
81
|
-
{ project_id: valid_id, project_key: valid_key, environment: nil }
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
it "returns a resolved promise" do
|
|
85
|
-
promise = described_class.validate(config)
|
|
86
|
-
expect(promise).to be_resolved
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
context "when environment is a String" do
|
|
91
|
-
let(:config_params) do
|
|
92
|
-
{ project_id: valid_id, project_key: valid_key, environment: 'test' }
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
it "returns a resolved promise" do
|
|
96
|
-
promise = described_class.validate(config)
|
|
97
|
-
expect(promise).to be_resolved
|
|
98
|
-
end
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
context "when environment is a Symbol" do
|
|
102
|
-
let(:config_params) do
|
|
103
|
-
{ project_id: valid_id, project_key: valid_key, environment: :test }
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
it "returns a resolved promise" do
|
|
107
|
-
promise = described_class.validate(config)
|
|
108
|
-
expect(promise).to be_resolved
|
|
109
|
-
end
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
context "when environment is non-String and non-Symbol" do
|
|
113
|
-
let(:config_params) do
|
|
114
|
-
{ project_id: valid_id, project_key: valid_key, environment: 1.0 }
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
it "returns a rejected promise" do
|
|
118
|
-
promise = described_class.validate(config)
|
|
119
|
-
expect(promise.value).to eq(
|
|
120
|
-
'error' => "the 'environment' option must be configured with a " \
|
|
121
|
-
"Symbol (or String), but 'Float' was provided: 1.0"
|
|
122
|
-
)
|
|
123
|
-
end
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
context "when environment is String-like" do
|
|
127
|
-
let(:string_inquirer) { Class.new(String) }
|
|
128
|
-
|
|
129
|
-
let(:config_params) do
|
|
130
|
-
{
|
|
131
|
-
project_id: valid_id,
|
|
132
|
-
project_key: valid_key,
|
|
133
|
-
environment: string_inquirer.new('test')
|
|
134
|
-
}
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
it "returns a resolved promise" do
|
|
138
|
-
promise = described_class.validate(config)
|
|
139
|
-
expect(promise).to be_resolved
|
|
140
|
-
end
|
|
141
|
-
end
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
describe "#check_notify_ability" do
|
|
145
|
-
context "when current environment is ignored" do
|
|
146
|
-
let(:config_params) do
|
|
147
|
-
{
|
|
148
|
-
project_id: valid_id,
|
|
149
|
-
project_key: valid_key,
|
|
150
|
-
environment: 'test',
|
|
151
|
-
ignore_environments: ['test']
|
|
152
|
-
}
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
it "returns a rejected promise" do
|
|
156
|
-
promise = described_class.check_notify_ability(config)
|
|
157
|
-
expect(promise.value).to eq(
|
|
158
|
-
'error' => "current environment 'test' is ignored"
|
|
159
|
-
)
|
|
160
|
-
end
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
context "when no environment is specified but ignore_environments is" do
|
|
164
|
-
let(:config_params) do
|
|
165
|
-
{
|
|
166
|
-
project_id: valid_id,
|
|
167
|
-
project_key: valid_key,
|
|
168
|
-
ignore_environments: ['test']
|
|
169
|
-
}
|
|
170
|
-
end
|
|
171
|
-
|
|
172
|
-
it "returns a rejected promise" do
|
|
173
|
-
promise = described_class.check_notify_ability(config)
|
|
174
|
-
expect(promise).to be_resolved
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
it "warns about 'no effect'" do
|
|
178
|
-
expect(config.logger).to receive(:warn)
|
|
179
|
-
.with(/'ignore_environments' has no effect/)
|
|
180
|
-
described_class.check_notify_ability(config)
|
|
181
|
-
end
|
|
182
|
-
end
|
|
183
|
-
end
|
|
184
|
-
end
|
data/spec/config_spec.rb
DELETED
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
RSpec.describe Airbrake::Config do
|
|
2
|
-
let(:resolved_promise) { Airbrake::Promise.new.resolve }
|
|
3
|
-
let(:rejected_promise) { Airbrake::Promise.new.reject }
|
|
4
|
-
|
|
5
|
-
let(:valid_params) { { project_id: 1, project_key: '2' } }
|
|
6
|
-
|
|
7
|
-
its(:project_id) { is_expected.to be_nil }
|
|
8
|
-
its(:project_key) { is_expected.to be_nil }
|
|
9
|
-
its(:logger) { is_expected.to be_a(Logger) }
|
|
10
|
-
its(:app_version) { is_expected.to be_nil }
|
|
11
|
-
its(:versions) { is_expected.to be_empty }
|
|
12
|
-
its(:host) { is_expected.to eq('https://api.airbrake.io') }
|
|
13
|
-
its(:endpoint) { is_expected.not_to be_nil }
|
|
14
|
-
its(:workers) { is_expected.to eq(1) }
|
|
15
|
-
its(:queue_size) { is_expected.to eq(100) }
|
|
16
|
-
its(:root_directory) { is_expected.to eq(Bundler.root.realpath.to_s) }
|
|
17
|
-
its(:environment) { is_expected.to be_nil }
|
|
18
|
-
its(:ignore_environments) { is_expected.to be_empty }
|
|
19
|
-
its(:timeout) { is_expected.to be_nil }
|
|
20
|
-
its(:blacklist_keys) { is_expected.to be_empty }
|
|
21
|
-
its(:whitelist_keys) { is_expected.to be_empty }
|
|
22
|
-
its(:performance_stats) { is_expected.to eq(true) }
|
|
23
|
-
its(:performance_stats_flush_period) { is_expected.to eq(15) }
|
|
24
|
-
its(:query_stats) { is_expected.to eq(false) }
|
|
25
|
-
|
|
26
|
-
describe "#new" do
|
|
27
|
-
context "when user config is passed" do
|
|
28
|
-
subject { described_class.new(logger: StringIO.new) }
|
|
29
|
-
its(:logger) { is_expected.to be_a(StringIO) }
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
describe "#valid?" do
|
|
34
|
-
context "when #validate returns a resolved promise" do
|
|
35
|
-
before { expect(subject).to receive(:validate).and_return(resolved_promise) }
|
|
36
|
-
it { is_expected.to be_valid }
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
context "when #validate returns a rejected promise" do
|
|
40
|
-
before { expect(subject).to receive(:validate).and_return(rejected_promise) }
|
|
41
|
-
it { is_expected.not_to be_valid }
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
describe "#ignored_environment?" do
|
|
46
|
-
context "when Validator returns a resolved promise" do
|
|
47
|
-
before do
|
|
48
|
-
expect(Airbrake::Config::Validator).to receive(:check_notify_ability)
|
|
49
|
-
.and_return(resolved_promise)
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
its(:ignored_environment?) { is_expected.to be_falsey }
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
context "when Validator returns a rejected promise" do
|
|
56
|
-
before do
|
|
57
|
-
expect(Airbrake::Config::Validator).to receive(:check_notify_ability)
|
|
58
|
-
.and_return(rejected_promise)
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
its(:ignored_environment?) { is_expected.to be_truthy }
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
describe "#endpoint" do
|
|
66
|
-
subject { described_class.new(valid_params.merge(user_config)) }
|
|
67
|
-
|
|
68
|
-
context "when host ends with a URL with a slug with a trailing slash" do
|
|
69
|
-
let(:user_config) { { host: 'https://localhost/bingo/' } }
|
|
70
|
-
|
|
71
|
-
its(:endpoint) do
|
|
72
|
-
is_expected.to eq(URI('https://localhost/bingo/api/v3/projects/1/notices'))
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
context "when host ends with a URL with a slug without a trailing slash" do
|
|
77
|
-
let(:user_config) { { host: 'https://localhost/bingo' } }
|
|
78
|
-
|
|
79
|
-
its(:endpoint) do
|
|
80
|
-
is_expected.to eq(URI('https://localhost/api/v3/projects/1/notices'))
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
describe "#validate" do
|
|
86
|
-
its(:validate) { is_expected.to be_an(Airbrake::Promise) }
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
describe "#check_configuration" do
|
|
90
|
-
let(:user_config) { {} }
|
|
91
|
-
|
|
92
|
-
subject { described_class.new(valid_params.merge(user_config)) }
|
|
93
|
-
|
|
94
|
-
its(:check_configuration) { is_expected.to be_an(Airbrake::Promise) }
|
|
95
|
-
|
|
96
|
-
context "when config is invalid" do
|
|
97
|
-
let(:user_config) { { project_id: nil } }
|
|
98
|
-
its(:check_configuration) { is_expected.to be_rejected }
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
context "when current environment is ignored" do
|
|
102
|
-
let(:user_config) { { environment: 'test', ignore_environments: ['test'] } }
|
|
103
|
-
its(:check_configuration) { is_expected.to be_rejected }
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
context "when config is valid and allows notifying" do
|
|
107
|
-
its(:check_configuration) { is_expected.not_to be_rejected }
|
|
108
|
-
end
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
describe "#check_performance_options" do
|
|
112
|
-
it "returns a promise" do
|
|
113
|
-
resource = Airbrake::Query.new(
|
|
114
|
-
method: '', route: '', query: '', start_time: Time.now
|
|
115
|
-
)
|
|
116
|
-
expect(subject.check_performance_options(resource))
|
|
117
|
-
.to be_an(Airbrake::Promise)
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
context "when performance stats are disabled" do
|
|
121
|
-
before { subject.performance_stats = false }
|
|
122
|
-
|
|
123
|
-
let(:resource) do
|
|
124
|
-
Airbrake::Request.new(
|
|
125
|
-
method: 'GET', route: '/foo', status_code: 200, start_time: Time.new
|
|
126
|
-
)
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
it "returns a rejected promise" do
|
|
130
|
-
promise = subject.check_performance_options(resource)
|
|
131
|
-
expect(promise.value).to eq(
|
|
132
|
-
'error' => "The Performance Stats feature is disabled"
|
|
133
|
-
)
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
context "when query stats are disabled" do
|
|
138
|
-
before { subject.query_stats = false }
|
|
139
|
-
|
|
140
|
-
let(:resource) do
|
|
141
|
-
Airbrake::Query.new(
|
|
142
|
-
method: 'GET', route: '/foo', query: '', start_time: Time.new
|
|
143
|
-
)
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
it "returns a rejected promise" do
|
|
147
|
-
promise = subject.check_performance_options(resource)
|
|
148
|
-
expect(promise.value).to eq(
|
|
149
|
-
'error' => "The Query Stats feature is disabled"
|
|
150
|
-
)
|
|
151
|
-
end
|
|
152
|
-
end
|
|
153
|
-
end
|
|
154
|
-
end
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
RSpec.describe Airbrake::DeployNotifier do
|
|
2
|
-
before do
|
|
3
|
-
Airbrake::Config.instance = Airbrake::Config.new(project_id: 1, project_key: '123')
|
|
4
|
-
end
|
|
5
|
-
|
|
6
|
-
describe "#notify" do
|
|
7
|
-
it "returns a promise" do
|
|
8
|
-
stub_request(:post, 'https://api.airbrake.io/api/v4/projects/1/deploys')
|
|
9
|
-
.to_return(status: 201, body: '{}')
|
|
10
|
-
expect(subject.notify({})).to be_an(Airbrake::Promise)
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
context "when config is invalid" do
|
|
14
|
-
before { Airbrake::Config.instance.merge(project_id: nil) }
|
|
15
|
-
|
|
16
|
-
it "returns a rejected promise" do
|
|
17
|
-
promise = subject.notify({})
|
|
18
|
-
expect(promise).to be_rejected
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
context "when environment is configured" do
|
|
23
|
-
before { Airbrake::Config.instance.merge(environment: 'fooenv') }
|
|
24
|
-
|
|
25
|
-
it "prefers the passed environment to the config env" do
|
|
26
|
-
expect_any_instance_of(Airbrake::SyncSender).to receive(:send).with(
|
|
27
|
-
{ environment: 'barenv' },
|
|
28
|
-
instance_of(Airbrake::Promise),
|
|
29
|
-
URI('https://api.airbrake.io/api/v4/projects/1/deploys')
|
|
30
|
-
)
|
|
31
|
-
subject.notify(environment: 'barenv')
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
context "when environment is not configured" do
|
|
36
|
-
before { Airbrake::Config.instance.merge(environment: 'fooenv') }
|
|
37
|
-
|
|
38
|
-
it "sets the environment from the config" do
|
|
39
|
-
expect_any_instance_of(Airbrake::SyncSender).to receive(:send).with(
|
|
40
|
-
{ environment: 'fooenv' },
|
|
41
|
-
instance_of(Airbrake::Promise),
|
|
42
|
-
URI('https://api.airbrake.io/api/v4/projects/1/deploys')
|
|
43
|
-
)
|
|
44
|
-
subject.notify({})
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
end
|
data/spec/file_cache.rb
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
RSpec.describe Airbrake::FileCache do
|
|
2
|
-
after do
|
|
3
|
-
%i[banana mango].each { |k| described_class.delete(k) }
|
|
4
|
-
expect(described_class).to be_empty
|
|
5
|
-
end
|
|
6
|
-
|
|
7
|
-
describe ".[]=" do
|
|
8
|
-
context "when cache limit isn't reached" do
|
|
9
|
-
before do
|
|
10
|
-
stub_const("#{described_class.name}::MAX_SIZE", 10)
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
it "adds objects" do
|
|
14
|
-
described_class[:banana] = 1
|
|
15
|
-
described_class[:mango] = 2
|
|
16
|
-
|
|
17
|
-
expect(described_class[:banana]).to eq(1)
|
|
18
|
-
expect(described_class[:mango]).to eq(2)
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
context "when cache limit is reached" do
|
|
23
|
-
before do
|
|
24
|
-
stub_const("#{described_class.name}::MAX_SIZE", 1)
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
it "replaces old objects with new ones" do
|
|
28
|
-
described_class[:banana] = 1
|
|
29
|
-
described_class[:mango] = 2
|
|
30
|
-
|
|
31
|
-
expect(described_class[:banana]).to be_nil
|
|
32
|
-
expect(described_class[:mango]).to eq(2)
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
end
|
data/spec/filter_chain_spec.rb
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
RSpec.describe Airbrake::FilterChain do
|
|
2
|
-
let(:notice) { Airbrake::Notice.new(AirbrakeTestError.new) }
|
|
3
|
-
|
|
4
|
-
describe "#refine" do
|
|
5
|
-
let(:filter) do
|
|
6
|
-
Class.new do
|
|
7
|
-
attr_reader :weight
|
|
8
|
-
|
|
9
|
-
def initialize(weight)
|
|
10
|
-
@weight = weight
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def call(notice)
|
|
14
|
-
notice[:params][:bingo] << @weight
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
it "executes filters from heaviest to lightest" do
|
|
20
|
-
notice[:params][:bingo] = []
|
|
21
|
-
|
|
22
|
-
(0...3).reverse_each { |i| subject.add_filter(filter.new(i)) }
|
|
23
|
-
subject.refine(notice)
|
|
24
|
-
|
|
25
|
-
expect(notice[:params][:bingo]).to eq([2, 1, 0])
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
it "stops execution once a notice was ignored" do
|
|
29
|
-
f2 = filter.new(2)
|
|
30
|
-
expect(f2).to receive(:call)
|
|
31
|
-
|
|
32
|
-
f1 = proc { |notice| notice.ignore! }
|
|
33
|
-
|
|
34
|
-
f0 = filter.new(-1)
|
|
35
|
-
expect(f0).not_to receive(:call)
|
|
36
|
-
|
|
37
|
-
[f2, f1, f0].each { |f| subject.add_filter(f) }
|
|
38
|
-
|
|
39
|
-
subject.refine(notice)
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
describe "#delete_filter" do
|
|
44
|
-
let(:filter) do
|
|
45
|
-
Class.new do
|
|
46
|
-
class << self
|
|
47
|
-
def name
|
|
48
|
-
'FooFilter'
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def initialize(foo)
|
|
53
|
-
@foo = foo
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
def call(notice)
|
|
57
|
-
notice[:params][:foo] << @foo
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
it "deletes a class filter" do
|
|
63
|
-
notice[:params][:foo] = []
|
|
64
|
-
|
|
65
|
-
f1 = filter.new(1)
|
|
66
|
-
subject.add_filter(f1)
|
|
67
|
-
|
|
68
|
-
foo_filter_mock = double
|
|
69
|
-
expect(foo_filter_mock).to(
|
|
70
|
-
receive(:name).at_least(:once).and_return('FooFilter')
|
|
71
|
-
)
|
|
72
|
-
subject.delete_filter(foo_filter_mock)
|
|
73
|
-
|
|
74
|
-
f2 = filter.new(2)
|
|
75
|
-
subject.add_filter(f2)
|
|
76
|
-
|
|
77
|
-
subject.refine(notice)
|
|
78
|
-
expect(notice[:params][:foo]).to eq([2])
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
describe "#inspect" do
|
|
83
|
-
it "returns a string representation of an empty FilterChain" do
|
|
84
|
-
expect(subject.inspect).to eq('[]')
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
it "returns a string representation of a non-empty FilterChain" do
|
|
88
|
-
subject.add_filter(proc {})
|
|
89
|
-
expect(subject.inspect).to eq('[Proc]')
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
end
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
RSpec.describe Airbrake::Filters::ContextFilter do
|
|
2
|
-
let(:notice) { Airbrake::Notice.new(AirbrakeTestError.new) }
|
|
3
|
-
|
|
4
|
-
context "when the current context is empty" do
|
|
5
|
-
it "doesn't merge anything with params" do
|
|
6
|
-
described_class.new({}).call(notice)
|
|
7
|
-
expect(notice[:params]).to be_empty
|
|
8
|
-
end
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
context "when the current context has some data" do
|
|
12
|
-
it "merges the data with params" do
|
|
13
|
-
described_class.new(apples: 'oranges').call(notice)
|
|
14
|
-
expect(notice[:params]).to eq(airbrake_context: { apples: 'oranges' })
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
it "clears the data from the provided context" do
|
|
18
|
-
context = { apples: 'oranges' }
|
|
19
|
-
described_class.new(context).call(notice)
|
|
20
|
-
expect(context).to be_empty
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
RSpec.describe Airbrake::Filters::DependencyFilter do
|
|
2
|
-
let(:notice) { Airbrake::Notice.new(AirbrakeTestError.new) }
|
|
3
|
-
|
|
4
|
-
describe "#call" do
|
|
5
|
-
it "attaches loaded dependencies to context/versions/dependencies" do
|
|
6
|
-
subject.call(notice)
|
|
7
|
-
expect(notice[:context][:versions][:dependencies]).to include(
|
|
8
|
-
'airbrake-ruby' => Airbrake::AIRBRAKE_RUBY_VERSION
|
|
9
|
-
)
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
end
|