appsignal 4.0.5 → 4.0.7
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/CHANGELOG.md +20 -0
- data/Rakefile +9 -9
- data/appsignal.gemspec +22 -1
- data/build_matrix.yml +2 -1
- data/ext/agent.rb +27 -27
- data/lib/appsignal/check_in/scheduler.rb +3 -4
- data/lib/appsignal/check_in.rb +1 -1
- data/lib/appsignal/config.rb +1 -3
- data/lib/appsignal/integrations/que.rb +8 -2
- data/lib/appsignal/integrations/resque.rb +1 -6
- data/lib/appsignal/utils/hash_sanitizer.rb +4 -0
- data/lib/appsignal/version.rb +1 -1
- metadata +2 -191
- data/.github/ISSUE_TEMPLATE/bug_report.md +0 -31
- data/.github/ISSUE_TEMPLATE/chore.md +0 -14
- data/.github/workflows/ci.yml +0 -3150
- data/.github/workflows/create_release_from_tag.yml +0 -62
- data/.gitignore +0 -35
- data/.gitmodules +0 -3
- data/.rspec +0 -4
- data/.yardopts +0 -8
- data/benchmark.rake +0 -139
- data/gemfiles/capistrano2.gemfile +0 -6
- data/gemfiles/capistrano3.gemfile +0 -7
- data/gemfiles/dry-monitor.gemfile +0 -5
- data/gemfiles/grape.gemfile +0 -5
- data/gemfiles/hanami-2.0.gemfile +0 -7
- data/gemfiles/hanami-2.1.gemfile +0 -7
- data/gemfiles/http5.gemfile +0 -5
- data/gemfiles/no_dependencies.gemfile +0 -10
- data/gemfiles/padrino.gemfile +0 -7
- data/gemfiles/psych-3.gemfile +0 -5
- data/gemfiles/psych-4.gemfile +0 -5
- data/gemfiles/que.gemfile +0 -5
- data/gemfiles/rails-6.0.gemfile +0 -10
- data/gemfiles/rails-6.1.gemfile +0 -11
- data/gemfiles/rails-7.0.gemfile +0 -11
- data/gemfiles/rails-7.1.gemfile +0 -11
- data/gemfiles/rails-7.2.gemfile +0 -11
- data/gemfiles/redis-4.gemfile +0 -5
- data/gemfiles/redis-5.gemfile +0 -6
- data/gemfiles/resque-2.gemfile +0 -6
- data/gemfiles/sequel.gemfile +0 -10
- data/gemfiles/sinatra.gemfile +0 -5
- data/gemfiles/webmachine1.gemfile +0 -7
- data/gemfiles/webmachine2.gemfile +0 -6
- data/mono.yml +0 -16
- data/spec/.rubocop.yml +0 -7
- data/spec/lib/appsignal/auth_check_spec.rb +0 -84
- data/spec/lib/appsignal/capistrano2_spec.rb +0 -227
- data/spec/lib/appsignal/capistrano3_spec.rb +0 -284
- data/spec/lib/appsignal/check_in/cron_spec.rb +0 -202
- data/spec/lib/appsignal/check_in/scheduler_spec.rb +0 -443
- data/spec/lib/appsignal/cli/demo_spec.rb +0 -46
- data/spec/lib/appsignal/cli/diagnose/paths_spec.rb +0 -16
- data/spec/lib/appsignal/cli/diagnose/utils_spec.rb +0 -86
- data/spec/lib/appsignal/cli/diagnose_spec.rb +0 -1553
- data/spec/lib/appsignal/cli/helpers_spec.rb +0 -179
- data/spec/lib/appsignal/cli/install_spec.rb +0 -848
- data/spec/lib/appsignal/cli_spec.rb +0 -56
- data/spec/lib/appsignal/config_spec.rb +0 -1380
- data/spec/lib/appsignal/demo_spec.rb +0 -83
- data/spec/lib/appsignal/environment_spec.rb +0 -190
- data/spec/lib/appsignal/event_formatter/action_view/render_formatter_spec.rb +0 -60
- data/spec/lib/appsignal/event_formatter/active_record/instantiation_formatter_spec.rb +0 -21
- data/spec/lib/appsignal/event_formatter/active_record/sql_formatter_spec.rb +0 -21
- data/spec/lib/appsignal/event_formatter/elastic_search/search_formatter_spec.rb +0 -52
- data/spec/lib/appsignal/event_formatter/faraday/request_formatter_spec.rb +0 -21
- data/spec/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter_spec.rb +0 -84
- data/spec/lib/appsignal/event_formatter/rom/sql_formatter_spec.rb +0 -22
- data/spec/lib/appsignal/event_formatter/sequel/sql_formatter_spec.rb +0 -30
- data/spec/lib/appsignal/event_formatter/view_component/render_formatter_spec.rb +0 -41
- data/spec/lib/appsignal/event_formatter_spec.rb +0 -193
- data/spec/lib/appsignal/extension/jruby_spec.rb +0 -46
- data/spec/lib/appsignal/extension_install_failure_spec.rb +0 -20
- data/spec/lib/appsignal/extension_spec.rb +0 -178
- data/spec/lib/appsignal/garbage_collection_spec.rb +0 -98
- data/spec/lib/appsignal/hooks/action_cable_spec.rb +0 -345
- data/spec/lib/appsignal/hooks/action_mailer_spec.rb +0 -55
- data/spec/lib/appsignal/hooks/active_support_notifications/finish_with_state_shared_examples.rb +0 -23
- data/spec/lib/appsignal/hooks/active_support_notifications/instrument_shared_examples.rb +0 -99
- data/spec/lib/appsignal/hooks/active_support_notifications/start_finish_shared_examples.rb +0 -47
- data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +0 -47
- data/spec/lib/appsignal/hooks/activejob_spec.rb +0 -650
- data/spec/lib/appsignal/hooks/at_exit_spec.rb +0 -105
- data/spec/lib/appsignal/hooks/celluloid_spec.rb +0 -40
- data/spec/lib/appsignal/hooks/data_mapper_spec.rb +0 -40
- data/spec/lib/appsignal/hooks/delayed_job_spec.rb +0 -38
- data/spec/lib/appsignal/hooks/dry_monitor_spec.rb +0 -83
- data/spec/lib/appsignal/hooks/excon_spec.rb +0 -67
- data/spec/lib/appsignal/hooks/gvl_spec.rb +0 -145
- data/spec/lib/appsignal/hooks/http_spec.rb +0 -37
- data/spec/lib/appsignal/hooks/mongo_ruby_driver_spec.rb +0 -46
- data/spec/lib/appsignal/hooks/mri_spec.rb +0 -23
- data/spec/lib/appsignal/hooks/net_http_spec.rb +0 -18
- data/spec/lib/appsignal/hooks/passenger_spec.rb +0 -30
- data/spec/lib/appsignal/hooks/puma_spec.rb +0 -80
- data/spec/lib/appsignal/hooks/que_spec.rb +0 -19
- data/spec/lib/appsignal/hooks/rake_spec.rb +0 -144
- data/spec/lib/appsignal/hooks/redis_client_spec.rb +0 -218
- data/spec/lib/appsignal/hooks/redis_spec.rb +0 -124
- data/spec/lib/appsignal/hooks/resque_spec.rb +0 -27
- data/spec/lib/appsignal/hooks/sequel_spec.rb +0 -44
- data/spec/lib/appsignal/hooks/shoryuken_spec.rb +0 -29
- data/spec/lib/appsignal/hooks/sidekiq_spec.rb +0 -115
- data/spec/lib/appsignal/hooks/unicorn_spec.rb +0 -63
- data/spec/lib/appsignal/hooks/webmachine_spec.rb +0 -24
- data/spec/lib/appsignal/hooks_spec.rb +0 -124
- data/spec/lib/appsignal/integrations/data_mapper_spec.rb +0 -74
- data/spec/lib/appsignal/integrations/delayed_job_plugin_spec.rb +0 -454
- data/spec/lib/appsignal/integrations/http_spec.rb +0 -111
- data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +0 -154
- data/spec/lib/appsignal/integrations/net_http_spec.rb +0 -33
- data/spec/lib/appsignal/integrations/object_spec.rb +0 -347
- data/spec/lib/appsignal/integrations/puma_spec.rb +0 -150
- data/spec/lib/appsignal/integrations/que_spec.rb +0 -152
- data/spec/lib/appsignal/integrations/railtie_spec.rb +0 -457
- data/spec/lib/appsignal/integrations/resque_spec.rb +0 -155
- data/spec/lib/appsignal/integrations/shoryuken_spec.rb +0 -165
- data/spec/lib/appsignal/integrations/sidekiq_spec.rb +0 -640
- data/spec/lib/appsignal/integrations/webmachine_spec.rb +0 -136
- data/spec/lib/appsignal/loaders/grape_spec.rb +0 -12
- data/spec/lib/appsignal/loaders/hanami_spec.rb +0 -92
- data/spec/lib/appsignal/loaders/padrino_spec.rb +0 -273
- data/spec/lib/appsignal/loaders/sinatra_spec.rb +0 -44
- data/spec/lib/appsignal/loaders_spec.rb +0 -144
- data/spec/lib/appsignal/logger_spec.rb +0 -205
- data/spec/lib/appsignal/marker_spec.rb +0 -51
- data/spec/lib/appsignal/probes/gvl_spec.rb +0 -164
- data/spec/lib/appsignal/probes/mri_spec.rb +0 -162
- data/spec/lib/appsignal/probes/sidekiq_spec.rb +0 -333
- data/spec/lib/appsignal/probes_spec.rb +0 -411
- data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +0 -370
- data/spec/lib/appsignal/rack/body_wrapper_spec.rb +0 -319
- data/spec/lib/appsignal/rack/event_handler_spec.rb +0 -441
- data/spec/lib/appsignal/rack/grape_middleware_spec.rb +0 -201
- data/spec/lib/appsignal/rack/hanami_middleware_spec.rb +0 -36
- data/spec/lib/appsignal/rack/instrumentation_middleware_spec.rb +0 -38
- data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +0 -126
- data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +0 -217
- data/spec/lib/appsignal/rack_spec.rb +0 -243
- data/spec/lib/appsignal/sample_data_spec.rb +0 -238
- data/spec/lib/appsignal/span_spec.rb +0 -141
- data/spec/lib/appsignal/system_spec.rb +0 -126
- data/spec/lib/appsignal/transaction_spec.rb +0 -2111
- data/spec/lib/appsignal/transmitter_spec.rb +0 -198
- data/spec/lib/appsignal/utils/data_spec.rb +0 -166
- data/spec/lib/appsignal/utils/hash_sanitizer_spec.rb +0 -182
- data/spec/lib/appsignal/utils/integration_logger_spec.rb +0 -21
- data/spec/lib/appsignal/utils/integration_memory_logger_spec.rb +0 -153
- data/spec/lib/appsignal/utils/json_spec.rb +0 -44
- data/spec/lib/appsignal/utils/query_params_sanitizer_spec.rb +0 -192
- data/spec/lib/appsignal_spec.rb +0 -1919
- data/spec/lib/puma/appsignal_spec.rb +0 -334
- data/spec/spec_helper.rb +0 -173
- data/spec/support/fixtures/generated_config.yml +0 -24
- data/spec/support/fixtures/projects/broken/config/appsignal.yml +0 -1
- data/spec/support/fixtures/projects/valid/config/appsignal.yml +0 -57
- data/spec/support/fixtures/projects/valid/log/.gitkeep +0 -0
- data/spec/support/fixtures/projects/valid_with_rails_app/config/application.rb +0 -16
- data/spec/support/fixtures/projects/valid_with_rails_app/config/appsignal.yml +0 -56
- data/spec/support/fixtures/projects/valid_with_rails_app/config/environment.rb +0 -10
- data/spec/support/fixtures/projects/valid_with_rails_app/log/.gitkeep +0 -0
- data/spec/support/fixtures/uploaded_file.txt +0 -0
- data/spec/support/hanami/hanami_app.rb +0 -29
- data/spec/support/helpers/action_mailer_helpers.rb +0 -25
- data/spec/support/helpers/activejob_helpers.rb +0 -27
- data/spec/support/helpers/api_request_helper.rb +0 -20
- data/spec/support/helpers/cli_helpers.rb +0 -40
- data/spec/support/helpers/config_helpers.rb +0 -66
- data/spec/support/helpers/dependency_helper.rb +0 -150
- data/spec/support/helpers/directory_helper.rb +0 -27
- data/spec/support/helpers/env_helpers.rb +0 -41
- data/spec/support/helpers/environment_metdata_helper.rb +0 -16
- data/spec/support/helpers/example_exception.rb +0 -13
- data/spec/support/helpers/example_standard_error.rb +0 -13
- data/spec/support/helpers/loader_helper.rb +0 -21
- data/spec/support/helpers/log_helpers.rb +0 -36
- data/spec/support/helpers/rails_helper.rb +0 -28
- data/spec/support/helpers/std_streams_helper.rb +0 -94
- data/spec/support/helpers/system_helpers.rb +0 -8
- data/spec/support/helpers/take_at_most_helper.rb +0 -21
- data/spec/support/helpers/time_helpers.rb +0 -11
- data/spec/support/helpers/transaction_helpers.rb +0 -122
- data/spec/support/helpers/wait_for_helper.rb +0 -39
- data/spec/support/matchers/contains_log.rb +0 -26
- data/spec/support/matchers/have_colorized_text.rb +0 -28
- data/spec/support/matchers/transaction.rb +0 -200
- data/spec/support/mocks/appsignal_mock.rb +0 -18
- data/spec/support/mocks/dummy_app.rb +0 -20
- data/spec/support/mocks/fake_gc_profiler.rb +0 -19
- data/spec/support/mocks/fake_gvl_tools.rb +0 -28
- data/spec/support/mocks/hash_like.rb +0 -10
- data/spec/support/mocks/mock_probe.rb +0 -13
- data/spec/support/mocks/puma_mock.rb +0 -43
- data/spec/support/shared_examples/instrument.rb +0 -48
- data/spec/support/stubs/appsignal/loaders/loader_stub.rb +0 -7
- data/spec/support/stubs/delayed_job.rb +0 -0
- data/spec/support/stubs/sidekiq/api.rb +0 -4
- data/spec/support/testing.rb +0 -194
- data/support/bundler_wrapper +0 -12
- data/support/install_deps +0 -33
@@ -1,2111 +0,0 @@
|
|
1
|
-
describe Appsignal::Transaction do
|
2
|
-
let(:options) { {} }
|
3
|
-
let(:time) { Time.at(fixed_time) }
|
4
|
-
|
5
|
-
before do
|
6
|
-
start_agent(:options => options)
|
7
|
-
Timecop.freeze(time)
|
8
|
-
end
|
9
|
-
after { Timecop.return }
|
10
|
-
around do |example|
|
11
|
-
keep_transactions do
|
12
|
-
example.run
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
describe ".create" do
|
17
|
-
context "when no transaction is running" do
|
18
|
-
it "returns the created transaction" do
|
19
|
-
mock_transaction_id = "mock-uuid"
|
20
|
-
allow(SecureRandom).to receive(:uuid).and_return(mock_transaction_id)
|
21
|
-
|
22
|
-
transaction = create_transaction
|
23
|
-
expect(transaction).to be_a Appsignal::Transaction
|
24
|
-
|
25
|
-
expect(transaction).to have_id(mock_transaction_id)
|
26
|
-
expect(transaction.transaction_id).to eq(mock_transaction_id)
|
27
|
-
|
28
|
-
expect(transaction).to have_namespace(default_namespace)
|
29
|
-
expect(transaction.namespace).to eq(default_namespace)
|
30
|
-
end
|
31
|
-
|
32
|
-
it "assigns the transaction to current" do
|
33
|
-
transaction = create_transaction
|
34
|
-
expect(transaction).to eq current_transaction
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
context "when an explicit extension transaction is passed in the initialiser" do
|
39
|
-
let(:ext) { "some_ext" }
|
40
|
-
|
41
|
-
it "assigns the extension transaction to the transaction" do
|
42
|
-
expect(described_class.new("web", :ext => ext).ext).to be(ext)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
context "when a transaction is already running" do
|
47
|
-
before do
|
48
|
-
allow(SecureRandom).to receive(:uuid)
|
49
|
-
.and_return(
|
50
|
-
"transaction_id_1",
|
51
|
-
"transaction_id_2"
|
52
|
-
)
|
53
|
-
create_transaction
|
54
|
-
end
|
55
|
-
|
56
|
-
it "does not create a new transaction, but returns the current transaction" do
|
57
|
-
expect do
|
58
|
-
new_transaction = create_transaction
|
59
|
-
|
60
|
-
expect(new_transaction).to eq(current_transaction)
|
61
|
-
end.to_not(change { current_transaction })
|
62
|
-
end
|
63
|
-
|
64
|
-
it "logs a debug message" do
|
65
|
-
logs = capture_logs { create_transaction }
|
66
|
-
|
67
|
-
expect(logs).to contains_log :warn,
|
68
|
-
"Trying to start new transaction, but a transaction with id " \
|
69
|
-
"'transaction_id_1' is already running. " \
|
70
|
-
"Using transaction 'transaction_id_1'."
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
describe ".current" do
|
76
|
-
context "when there is a current transaction" do
|
77
|
-
let!(:transaction) { create_transaction }
|
78
|
-
|
79
|
-
it "reads :appsignal_transaction from the current Thread" do
|
80
|
-
expect(current_transaction).to eq(Thread.current[:appsignal_transaction])
|
81
|
-
expect(current_transaction).to eq(transaction)
|
82
|
-
end
|
83
|
-
|
84
|
-
it "is not a NilTransaction" do
|
85
|
-
expect(current_transaction.nil_transaction?).to be(false)
|
86
|
-
expect(current_transaction).to be_a(Appsignal::Transaction)
|
87
|
-
end
|
88
|
-
|
89
|
-
it "returns true for current?" do
|
90
|
-
expect(Appsignal::Transaction.current?).to be(true)
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
context "when there is no current transaction" do
|
95
|
-
it "has no :appsignal_transaction registered on the current Thread" do
|
96
|
-
expect(Thread.current[:appsignal_transaction]).to be_nil
|
97
|
-
end
|
98
|
-
|
99
|
-
it "returns a NilTransaction stub" do
|
100
|
-
expect(current_transaction.nil_transaction?).to be(true)
|
101
|
-
expect(current_transaction).to be_a(Appsignal::Transaction::NilTransaction)
|
102
|
-
end
|
103
|
-
|
104
|
-
it "returns false for current?" do
|
105
|
-
expect(Appsignal::Transaction.current?).to be(false)
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
describe ".complete_current!" do
|
111
|
-
context "with active transaction" do
|
112
|
-
let!(:transaction) { create_transaction }
|
113
|
-
|
114
|
-
it "completes the current transaction" do
|
115
|
-
expect(transaction).to eq(current_transaction)
|
116
|
-
|
117
|
-
Appsignal::Transaction.complete_current!
|
118
|
-
|
119
|
-
expect(transaction).to be_completed
|
120
|
-
end
|
121
|
-
|
122
|
-
it "unsets the current transaction on the current Thread" do
|
123
|
-
expect do
|
124
|
-
Appsignal::Transaction.complete_current!
|
125
|
-
end.to change { Thread.current[:appsignal_transaction] }.from(transaction).to(nil)
|
126
|
-
end
|
127
|
-
|
128
|
-
context "when encountering an error while completing" do
|
129
|
-
before do
|
130
|
-
expect(transaction).to receive(:complete).and_raise ExampleStandardError
|
131
|
-
end
|
132
|
-
|
133
|
-
it "logs an error message" do
|
134
|
-
logs =
|
135
|
-
capture_logs do
|
136
|
-
Appsignal::Transaction.complete_current!
|
137
|
-
end
|
138
|
-
expect(logs).to contains_log :error,
|
139
|
-
"Failed to complete transaction ##{transaction.transaction_id}. ExampleStandardError"
|
140
|
-
end
|
141
|
-
|
142
|
-
it "clears the current transaction" do
|
143
|
-
expect do
|
144
|
-
Appsignal::Transaction.complete_current!
|
145
|
-
end.to change { Thread.current[:appsignal_transaction] }.from(transaction).to(nil)
|
146
|
-
end
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
context "without active transaction" do
|
151
|
-
it "does nothing" do
|
152
|
-
expect do
|
153
|
-
Appsignal::Transaction.complete_current!
|
154
|
-
end.to_not(change { Thread.current[:appsignal_transaction] })
|
155
|
-
end
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
describe "#complete" do
|
160
|
-
let(:transaction) { create_transaction }
|
161
|
-
|
162
|
-
context "when transaction is being sampled" do
|
163
|
-
it "samples data" do
|
164
|
-
transaction.add_tags(:foo => "bar")
|
165
|
-
keep_transactions { transaction.complete }
|
166
|
-
expect(transaction).to include_tags("foo" => "bar")
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
context "when transaction is not being sampled" do
|
171
|
-
it "does not sample data" do
|
172
|
-
keep_transactions(:sample => false) { transaction.complete }
|
173
|
-
expect(transaction.to_h["sample_data"]).to be_empty
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
context "when a transaction is marked as discarded" do
|
178
|
-
it "does not complete the transaction" do
|
179
|
-
expect do
|
180
|
-
transaction.discard!
|
181
|
-
end.to change { transaction.discarded? }.from(false).to(true)
|
182
|
-
|
183
|
-
transaction.complete
|
184
|
-
|
185
|
-
expect(transaction).to_not be_completed
|
186
|
-
end
|
187
|
-
|
188
|
-
it "logs a debug message" do
|
189
|
-
allow(SecureRandom).to receive(:uuid).and_return("mock_transaction_id")
|
190
|
-
transaction.discard!
|
191
|
-
logs = capture_logs { transaction.complete }
|
192
|
-
|
193
|
-
expect(logs).to contains_log :debug,
|
194
|
-
"Skipping transaction 'mock_transaction_id' because it was manually discarded."
|
195
|
-
end
|
196
|
-
|
197
|
-
context "when a discarded transaction is restored" do
|
198
|
-
before { transaction.discard! }
|
199
|
-
|
200
|
-
it "completes the transaction" do
|
201
|
-
expect do
|
202
|
-
transaction.restore!
|
203
|
-
end.to change { transaction.discarded? }.from(true).to(false)
|
204
|
-
|
205
|
-
transaction.complete
|
206
|
-
|
207
|
-
expect(transaction).to be_completed
|
208
|
-
end
|
209
|
-
end
|
210
|
-
end
|
211
|
-
|
212
|
-
context "when a transaction has errors" do
|
213
|
-
let(:error) do
|
214
|
-
e = ExampleStandardError.new("test message")
|
215
|
-
allow(e).to receive(:backtrace).and_return(["line 1"])
|
216
|
-
e
|
217
|
-
end
|
218
|
-
|
219
|
-
let(:other_error) do
|
220
|
-
e = ExampleStandardError.new("other test message")
|
221
|
-
allow(e).to receive(:backtrace).and_return(["line 2"])
|
222
|
-
e
|
223
|
-
end
|
224
|
-
|
225
|
-
context "when an error is already set on the transaction" do
|
226
|
-
it "reports errors as duplicate transactions" do
|
227
|
-
transaction.set_error(error)
|
228
|
-
transaction.add_error(other_error)
|
229
|
-
|
230
|
-
expect do
|
231
|
-
transaction.complete
|
232
|
-
end.to change { created_transactions.count }.from(1).to(2)
|
233
|
-
|
234
|
-
original_transaction, duplicate_transaction = created_transactions
|
235
|
-
|
236
|
-
expect(original_transaction).to have_error(
|
237
|
-
"ExampleStandardError",
|
238
|
-
"test message",
|
239
|
-
["line 1"]
|
240
|
-
)
|
241
|
-
expect(original_transaction).to be_completed
|
242
|
-
|
243
|
-
expect(duplicate_transaction).to have_error(
|
244
|
-
"ExampleStandardError",
|
245
|
-
"other test message",
|
246
|
-
["line 2"]
|
247
|
-
)
|
248
|
-
expect(duplicate_transaction).to be_completed
|
249
|
-
end
|
250
|
-
end
|
251
|
-
|
252
|
-
context "when no error is set on the transaction" do
|
253
|
-
it "reports the first error in the original transaction" do
|
254
|
-
transaction.add_error(error)
|
255
|
-
transaction.add_error(other_error)
|
256
|
-
|
257
|
-
expect do
|
258
|
-
transaction.complete
|
259
|
-
end.to change { created_transactions.count }.from(1).to(2)
|
260
|
-
|
261
|
-
original_transaction, duplicate_transaction = created_transactions
|
262
|
-
|
263
|
-
expect(original_transaction).to have_error(
|
264
|
-
"ExampleStandardError",
|
265
|
-
"test message",
|
266
|
-
["line 1"]
|
267
|
-
)
|
268
|
-
expect(original_transaction).to be_completed
|
269
|
-
|
270
|
-
expect(duplicate_transaction).to have_error(
|
271
|
-
"ExampleStandardError",
|
272
|
-
"other test message",
|
273
|
-
["line 2"]
|
274
|
-
)
|
275
|
-
expect(duplicate_transaction).to be_completed
|
276
|
-
end
|
277
|
-
end
|
278
|
-
|
279
|
-
it "stores the last reported errors" do
|
280
|
-
transaction.add_error(error)
|
281
|
-
transaction.add_error(other_error)
|
282
|
-
transaction.complete
|
283
|
-
|
284
|
-
expect(Appsignal::Transaction.last_errors).to contain_exactly(error, other_error)
|
285
|
-
end
|
286
|
-
|
287
|
-
describe "metadata" do
|
288
|
-
let(:tags) { { "tag" => "value" } }
|
289
|
-
let(:params) { { "param" => "value" } }
|
290
|
-
let(:headers) { { "REQUEST_METHOD" => "value" } }
|
291
|
-
let(:session_data) { { "session_data" => "value" } }
|
292
|
-
let(:custom_data) { { "custom_data" => "value" } }
|
293
|
-
before do
|
294
|
-
transaction.set_namespace("My namespace")
|
295
|
-
transaction.set_action("My action")
|
296
|
-
transaction.set_metadata("path", "/some/path")
|
297
|
-
transaction.set_metadata("method", "GET")
|
298
|
-
transaction.add_tags(tags)
|
299
|
-
transaction.add_params(params)
|
300
|
-
transaction.add_headers(headers)
|
301
|
-
transaction.add_session_data(session_data)
|
302
|
-
transaction.add_custom_data(custom_data)
|
303
|
-
transaction.add_breadcrumb("category", "action", "message", { "meta" => "data" })
|
304
|
-
|
305
|
-
transaction.start_event
|
306
|
-
transaction.finish_event("name", "title", "body", 1)
|
307
|
-
|
308
|
-
transaction.add_error(error)
|
309
|
-
transaction.add_error(other_error)
|
310
|
-
|
311
|
-
transaction.complete
|
312
|
-
end
|
313
|
-
|
314
|
-
it "copies the transaction metadata and sample data on the duplicate transaction" do
|
315
|
-
original_transaction, duplicate_transaction = created_transactions
|
316
|
-
|
317
|
-
duplicate_hash = duplicate_transaction.to_h.tap do |h|
|
318
|
-
h.delete("id")
|
319
|
-
h.delete("error")
|
320
|
-
end
|
321
|
-
original_hash = original_transaction.to_h.tap do |h|
|
322
|
-
h.delete("id")
|
323
|
-
h.delete("error")
|
324
|
-
end
|
325
|
-
expect(duplicate_hash).to eq(original_hash)
|
326
|
-
end
|
327
|
-
|
328
|
-
it "the duplicate transaction has a different transaction id" do
|
329
|
-
original_transaction, duplicate_transaction = created_transactions
|
330
|
-
|
331
|
-
expect(original_transaction.transaction_id)
|
332
|
-
.to_not eq(duplicate_transaction.transaction_id)
|
333
|
-
end
|
334
|
-
|
335
|
-
it "the duplicate transaction has a different extension transaction than the original" do
|
336
|
-
original_transaction, duplicate_transaction = created_transactions
|
337
|
-
|
338
|
-
expect(original_transaction.ext).to_not eq(duplicate_transaction.ext)
|
339
|
-
end
|
340
|
-
|
341
|
-
it "marks transaction as duplicate on the duplicate transaction" do
|
342
|
-
original_transaction, duplicate_transaction = created_transactions
|
343
|
-
|
344
|
-
expect(original_transaction.duplicate?).to be(false)
|
345
|
-
expect(duplicate_transaction.duplicate?).to be(true)
|
346
|
-
end
|
347
|
-
end
|
348
|
-
|
349
|
-
it "merges sample data from the original transaction in the duplicate transaction" do
|
350
|
-
transaction.add_tags("root" => "tag")
|
351
|
-
transaction.add_params("root" => "param")
|
352
|
-
transaction.add_session_data("root" => "session")
|
353
|
-
transaction.add_headers("REQUEST_METHOD" => "root")
|
354
|
-
transaction.add_custom_data("root" => "custom")
|
355
|
-
transaction.add_breadcrumb("root", "breadcrumb")
|
356
|
-
Appsignal.report_error(error) do |t|
|
357
|
-
t.add_tags("original" => "tag")
|
358
|
-
t.add_params("original" => "param")
|
359
|
-
t.add_session_data("original" => "session")
|
360
|
-
t.add_headers("REQUEST_PATH" => "/original")
|
361
|
-
t.add_custom_data("original" => "custom")
|
362
|
-
t.add_breadcrumb("original", "breadcrumb")
|
363
|
-
end
|
364
|
-
Appsignal.report_error(other_error) do |t|
|
365
|
-
t.add_tags("duplicate" => "tag")
|
366
|
-
t.add_params("duplicate" => "param")
|
367
|
-
t.add_session_data("duplicate" => "session")
|
368
|
-
t.add_headers("HTTP_ACCEPT" => "duplicate")
|
369
|
-
t.add_custom_data("duplicate" => "custom")
|
370
|
-
t.add_breadcrumb("duplicate", "breadcrumb")
|
371
|
-
end
|
372
|
-
transaction.add_tags("root2" => "tag")
|
373
|
-
transaction.add_params("root2" => "param")
|
374
|
-
transaction.add_session_data("root2" => "session")
|
375
|
-
transaction.add_headers("PATH_INFO" => "/root2")
|
376
|
-
transaction.add_custom_data("root2" => "custom")
|
377
|
-
transaction.add_breadcrumb("root2", "breadcrumb")
|
378
|
-
transaction.complete
|
379
|
-
|
380
|
-
original_transaction, duplicate_transaction = created_transactions
|
381
|
-
# Original
|
382
|
-
expect(original_transaction).to include_tags(
|
383
|
-
"root" => "tag",
|
384
|
-
"original" => "tag",
|
385
|
-
"root2" => "tag"
|
386
|
-
)
|
387
|
-
expect(original_transaction).to_not include_tags("duplicate" => anything)
|
388
|
-
expect(original_transaction).to include_params(
|
389
|
-
"root" => "param",
|
390
|
-
"original" => "param",
|
391
|
-
"root2" => "param"
|
392
|
-
)
|
393
|
-
expect(original_transaction).to_not include_params("duplicate" => anything)
|
394
|
-
expect(original_transaction).to include_session_data(
|
395
|
-
"root" => "session",
|
396
|
-
"original" => "session",
|
397
|
-
"root2" => "session"
|
398
|
-
)
|
399
|
-
expect(original_transaction).to_not include_session_data("duplicate" => anything)
|
400
|
-
expect(original_transaction).to include_environment(
|
401
|
-
"REQUEST_METHOD" => "root",
|
402
|
-
"REQUEST_PATH" => "/original",
|
403
|
-
"PATH_INFO" => "/root2"
|
404
|
-
)
|
405
|
-
expect(original_transaction).to_not include_environment("HTTP_ACCEPT" => anything)
|
406
|
-
expect(original_transaction).to include_custom_data(
|
407
|
-
"root" => "custom",
|
408
|
-
"original" => "custom",
|
409
|
-
"root2" => "custom"
|
410
|
-
)
|
411
|
-
expect(original_transaction).to_not include_custom_data("duplicate" => anything)
|
412
|
-
expect(original_transaction).to include_breadcrumb("breadcrumb", "root")
|
413
|
-
expect(original_transaction).to include_breadcrumb("breadcrumb", "original")
|
414
|
-
expect(original_transaction).to include_breadcrumb("breadcrumb", "root2")
|
415
|
-
expect(original_transaction).to_not include_breadcrumb("breadcrumb", "duplicate")
|
416
|
-
|
417
|
-
# Duplicate
|
418
|
-
expect(duplicate_transaction).to include_tags(
|
419
|
-
"root" => "tag",
|
420
|
-
"duplicate" => "tag",
|
421
|
-
"root2" => "tag"
|
422
|
-
)
|
423
|
-
expect(duplicate_transaction).to_not include_tags("original" => anything)
|
424
|
-
expect(duplicate_transaction).to include_params(
|
425
|
-
"root" => "param",
|
426
|
-
"duplicate" => "param",
|
427
|
-
"root2" => "param"
|
428
|
-
)
|
429
|
-
expect(duplicate_transaction).to_not include_params("original" => anything)
|
430
|
-
expect(duplicate_transaction).to include_session_data(
|
431
|
-
"root" => "session",
|
432
|
-
"duplicate" => "session",
|
433
|
-
"root2" => "session"
|
434
|
-
)
|
435
|
-
expect(duplicate_transaction).to_not include_session_data("original" => anything)
|
436
|
-
expect(duplicate_transaction).to include_environment(
|
437
|
-
"PATH_INFO" => "/root2",
|
438
|
-
"HTTP_ACCEPT" => "duplicate",
|
439
|
-
"REQUEST_METHOD" => "root"
|
440
|
-
)
|
441
|
-
expect(duplicate_transaction).to_not include_environment("REQUEST_PATH" => anything)
|
442
|
-
expect(duplicate_transaction).to include_custom_data(
|
443
|
-
"root" => "custom",
|
444
|
-
"duplicate" => "custom",
|
445
|
-
"root2" => "custom"
|
446
|
-
)
|
447
|
-
expect(duplicate_transaction).to_not include_custom_data("original" => anything)
|
448
|
-
expect(duplicate_transaction).to include_breadcrumb("breadcrumb", "root")
|
449
|
-
expect(duplicate_transaction).to include_breadcrumb("breadcrumb", "duplicate")
|
450
|
-
expect(duplicate_transaction).to include_breadcrumb("breadcrumb", "root2")
|
451
|
-
expect(duplicate_transaction).to_not include_breadcrumb("breadcrumb", "original")
|
452
|
-
end
|
453
|
-
|
454
|
-
it "overrides sample data from the original transaction in the duplicate transaction" do
|
455
|
-
transaction.add_tags("changeme" => "tag")
|
456
|
-
transaction.add_params("changeme" => "param")
|
457
|
-
transaction.add_session_data("changeme" => "session")
|
458
|
-
transaction.add_headers("REQUEST_METHOD" => "root")
|
459
|
-
transaction.add_custom_data("changeme" => "custom")
|
460
|
-
Appsignal.report_error(error)
|
461
|
-
Appsignal.report_error(other_error) do |t|
|
462
|
-
t.add_tags("changeme" => "duplicate_tag")
|
463
|
-
t.add_params("changeme" => "duplicate_param")
|
464
|
-
t.add_session_data("changeme" => "duplicate_session")
|
465
|
-
t.add_headers("REQUEST_METHOD" => "duplicate")
|
466
|
-
t.add_custom_data("changeme" => "duplicate_custom")
|
467
|
-
end
|
468
|
-
transaction.add_tags("changeme" => "changed_tag")
|
469
|
-
transaction.add_params("changeme" => "changed_param")
|
470
|
-
transaction.add_session_data("changeme" => "changed_session")
|
471
|
-
transaction.add_headers("REQUEST_METHOD" => "changed")
|
472
|
-
transaction.add_custom_data("changeme" => "changed_custom")
|
473
|
-
transaction.complete
|
474
|
-
|
475
|
-
original_transaction, duplicate_transaction = created_transactions
|
476
|
-
# Original
|
477
|
-
expect(original_transaction).to include_tags(
|
478
|
-
"changeme" => "changed_tag"
|
479
|
-
)
|
480
|
-
expect(original_transaction).to include_params(
|
481
|
-
"changeme" => "changed_param"
|
482
|
-
)
|
483
|
-
expect(original_transaction).to include_session_data(
|
484
|
-
"changeme" => "changed_session"
|
485
|
-
)
|
486
|
-
expect(original_transaction).to include_environment(
|
487
|
-
"REQUEST_METHOD" => "changed"
|
488
|
-
)
|
489
|
-
expect(original_transaction).to include_custom_data(
|
490
|
-
"changeme" => "changed_custom"
|
491
|
-
)
|
492
|
-
|
493
|
-
# Duplicate
|
494
|
-
expect(duplicate_transaction).to include_tags(
|
495
|
-
"changeme" => "duplicate_tag"
|
496
|
-
)
|
497
|
-
expect(duplicate_transaction).to include_params(
|
498
|
-
"changeme" => "duplicate_param"
|
499
|
-
)
|
500
|
-
expect(duplicate_transaction).to include_session_data(
|
501
|
-
"changeme" => "duplicate_session"
|
502
|
-
)
|
503
|
-
expect(duplicate_transaction).to include_environment(
|
504
|
-
"REQUEST_METHOD" => "duplicate"
|
505
|
-
)
|
506
|
-
expect(duplicate_transaction).to include_custom_data(
|
507
|
-
"changeme" => "duplicate_custom"
|
508
|
-
)
|
509
|
-
end
|
510
|
-
end
|
511
|
-
end
|
512
|
-
|
513
|
-
context "pausing" do
|
514
|
-
let(:transaction) { new_transaction }
|
515
|
-
|
516
|
-
describe "#pause!" do
|
517
|
-
it "changes the pause flag to true" do
|
518
|
-
expect do
|
519
|
-
transaction.pause!
|
520
|
-
end.to change(transaction, :paused?).from(false).to(true)
|
521
|
-
end
|
522
|
-
end
|
523
|
-
|
524
|
-
describe "#resume!" do
|
525
|
-
before { transaction.pause! }
|
526
|
-
|
527
|
-
it "changes the pause flag to false" do
|
528
|
-
expect do
|
529
|
-
transaction.resume!
|
530
|
-
end.to change(transaction, :paused?).from(true).to(false)
|
531
|
-
end
|
532
|
-
end
|
533
|
-
|
534
|
-
describe "#paused?" do
|
535
|
-
context "when not paused" do
|
536
|
-
it "return false" do
|
537
|
-
expect(transaction.paused?).to be_falsy
|
538
|
-
end
|
539
|
-
end
|
540
|
-
|
541
|
-
context "when paused" do
|
542
|
-
before { transaction.pause! }
|
543
|
-
|
544
|
-
it "returns true" do
|
545
|
-
expect(transaction.paused?).to be_truthy
|
546
|
-
end
|
547
|
-
end
|
548
|
-
end
|
549
|
-
end
|
550
|
-
|
551
|
-
context "initialization" do
|
552
|
-
let(:transaction) { new_transaction }
|
553
|
-
|
554
|
-
it "loads the AppSignal extension" do
|
555
|
-
expect(transaction.ext).to_not be_nil
|
556
|
-
end
|
557
|
-
|
558
|
-
context "when extension is not loaded", :extension_installation_failure do
|
559
|
-
around do |example|
|
560
|
-
Appsignal::Testing.without_testing { example.run }
|
561
|
-
end
|
562
|
-
|
563
|
-
it "does not error on missing extension method calls" do
|
564
|
-
expect(transaction.ext).to be_kind_of(Appsignal::Extension::MockTransaction)
|
565
|
-
transaction.start_event
|
566
|
-
transaction.finish_event(
|
567
|
-
"name",
|
568
|
-
"title",
|
569
|
-
"body",
|
570
|
-
Appsignal::EventFormatter::DEFAULT
|
571
|
-
)
|
572
|
-
end
|
573
|
-
end
|
574
|
-
|
575
|
-
it "sets the namespace to http_request" do
|
576
|
-
expect(transaction.namespace).to eq "http_request"
|
577
|
-
end
|
578
|
-
end
|
579
|
-
|
580
|
-
describe "#store" do
|
581
|
-
let(:transaction) { new_transaction }
|
582
|
-
|
583
|
-
it "returns an empty store when it's not already present" do
|
584
|
-
expect(transaction.store("test")).to eql({})
|
585
|
-
end
|
586
|
-
|
587
|
-
it "stores changes to the store" do
|
588
|
-
transaction_store = transaction.store("test")
|
589
|
-
transaction_store["transaction"] = "value"
|
590
|
-
|
591
|
-
expect(transaction.store("test")).to eql("transaction" => "value")
|
592
|
-
end
|
593
|
-
|
594
|
-
it "has a default value of a Hash for store values" do
|
595
|
-
transaction.store("abc")["def"] = "123"
|
596
|
-
|
597
|
-
expect(transaction.store("abc")).to eq("def" => "123")
|
598
|
-
expect(transaction.store("xyz")).to eq({})
|
599
|
-
end
|
600
|
-
end
|
601
|
-
|
602
|
-
describe "#add_params" do
|
603
|
-
let(:transaction) { new_transaction }
|
604
|
-
|
605
|
-
it "has a #set_params alias" do
|
606
|
-
expect(transaction.method(:add_params)).to eq(transaction.method(:set_params))
|
607
|
-
end
|
608
|
-
|
609
|
-
it "adds the params to the transaction" do
|
610
|
-
params = { "key" => "value" }
|
611
|
-
transaction.add_params(params)
|
612
|
-
|
613
|
-
transaction._sample
|
614
|
-
expect(transaction).to include_params(params)
|
615
|
-
end
|
616
|
-
|
617
|
-
it "merges the params on the transaction" do
|
618
|
-
transaction.add_params("abc" => "value")
|
619
|
-
transaction.add_params("def" => "value")
|
620
|
-
transaction.add_params { { "xyz" => "value" } }
|
621
|
-
|
622
|
-
transaction._sample
|
623
|
-
expect(transaction).to include_params(
|
624
|
-
"abc" => "value",
|
625
|
-
"def" => "value",
|
626
|
-
"xyz" => "value"
|
627
|
-
)
|
628
|
-
end
|
629
|
-
|
630
|
-
it "adds the params to the transaction with a block" do
|
631
|
-
params = { "key" => "value" }
|
632
|
-
transaction.add_params { params }
|
633
|
-
|
634
|
-
transaction._sample
|
635
|
-
expect(transaction).to include_params(params)
|
636
|
-
end
|
637
|
-
|
638
|
-
it "adds the params block value when both an argument and block are given" do
|
639
|
-
arg_params = { "argument" => "value" }
|
640
|
-
block_params = { "block" => "value" }
|
641
|
-
transaction.add_params(arg_params) { block_params }
|
642
|
-
|
643
|
-
transaction._sample
|
644
|
-
expect(transaction).to include_params(block_params)
|
645
|
-
end
|
646
|
-
|
647
|
-
it "logs an error if an error occurred storing the params" do
|
648
|
-
transaction.add_params { raise "uh oh" }
|
649
|
-
|
650
|
-
logs = capture_logs { transaction._sample }
|
651
|
-
expect(logs).to contains_log(
|
652
|
-
:error,
|
653
|
-
"Exception while fetching params: RuntimeError: uh oh"
|
654
|
-
)
|
655
|
-
end
|
656
|
-
|
657
|
-
it "does not update the params on the transaction if the given value is nil" do
|
658
|
-
params = { "key" => "value" }
|
659
|
-
transaction.add_params(params)
|
660
|
-
transaction.add_params(nil)
|
661
|
-
|
662
|
-
transaction._sample
|
663
|
-
expect(transaction).to include_params(params)
|
664
|
-
end
|
665
|
-
|
666
|
-
context "with AppSignal filtering" do
|
667
|
-
let(:options) { { :filter_parameters => %w[foo] } }
|
668
|
-
|
669
|
-
it "returns sanitized custom params" do
|
670
|
-
transaction.add_params("foo" => "value", "baz" => "bat")
|
671
|
-
|
672
|
-
transaction._sample
|
673
|
-
expect(transaction).to include_params("foo" => "[FILTERED]", "baz" => "bat")
|
674
|
-
end
|
675
|
-
end
|
676
|
-
end
|
677
|
-
|
678
|
-
describe "#add_params_if_nil" do
|
679
|
-
let(:transaction) { new_transaction }
|
680
|
-
|
681
|
-
it "has a #set_params_if_nil alias" do
|
682
|
-
expect(transaction.method(:add_params_if_nil)).to eq(transaction.method(:set_params_if_nil))
|
683
|
-
end
|
684
|
-
|
685
|
-
context "when the params are not set" do
|
686
|
-
it "adds the params to the transaction" do
|
687
|
-
params = { "key" => "value" }
|
688
|
-
transaction.add_params_if_nil(params)
|
689
|
-
|
690
|
-
transaction._sample
|
691
|
-
expect(transaction).to include_params(params)
|
692
|
-
end
|
693
|
-
|
694
|
-
it "adds the params to the transaction with a block" do
|
695
|
-
params = { "key" => "value" }
|
696
|
-
transaction.add_params_if_nil { params }
|
697
|
-
|
698
|
-
transaction._sample
|
699
|
-
expect(transaction).to include_params(params)
|
700
|
-
end
|
701
|
-
|
702
|
-
it "adds the params block value when both an argument and block are given" do
|
703
|
-
arg_params = { "argument" => "value" }
|
704
|
-
block_params = { "block" => "value" }
|
705
|
-
transaction.add_params_if_nil(arg_params) { block_params }
|
706
|
-
|
707
|
-
transaction._sample
|
708
|
-
expect(transaction).to include_params(block_params)
|
709
|
-
end
|
710
|
-
|
711
|
-
it "does not update the params on the transaction if the given value is nil" do
|
712
|
-
params = { "key" => "value" }
|
713
|
-
transaction.add_params(params)
|
714
|
-
transaction.add_params_if_nil(nil)
|
715
|
-
|
716
|
-
transaction._sample
|
717
|
-
expect(transaction).to include_params(params)
|
718
|
-
end
|
719
|
-
end
|
720
|
-
|
721
|
-
context "when the params are set" do
|
722
|
-
it "does not update the params on the transaction" do
|
723
|
-
preset_params = { "other" => "params" }
|
724
|
-
params = { "key" => "value" }
|
725
|
-
transaction.add_params(preset_params)
|
726
|
-
transaction.add_params_if_nil(params)
|
727
|
-
|
728
|
-
transaction._sample
|
729
|
-
expect(transaction).to include_params(preset_params)
|
730
|
-
end
|
731
|
-
|
732
|
-
it "does not update the params with a block on the transaction" do
|
733
|
-
preset_params = { "other" => "params" }
|
734
|
-
params = { "key" => "value" }
|
735
|
-
transaction.add_params(preset_params)
|
736
|
-
transaction.add_params_if_nil { params }
|
737
|
-
|
738
|
-
transaction._sample
|
739
|
-
expect(transaction).to include_params(preset_params)
|
740
|
-
end
|
741
|
-
end
|
742
|
-
|
743
|
-
context "when the params were set as an empty value" do
|
744
|
-
it "does not set params on the transaction" do
|
745
|
-
transaction.add_params("key1" => "value")
|
746
|
-
transaction.set_empty_params!
|
747
|
-
transaction.add_params_if_nil("key2" => "value")
|
748
|
-
|
749
|
-
transaction._sample
|
750
|
-
expect(transaction).to_not include_params
|
751
|
-
end
|
752
|
-
end
|
753
|
-
end
|
754
|
-
|
755
|
-
describe "#add_session_data" do
|
756
|
-
let(:transaction) { new_transaction }
|
757
|
-
|
758
|
-
it "has a #set_session_data alias" do
|
759
|
-
expect(transaction.method(:add_session_data)).to eq(transaction.method(:set_session_data))
|
760
|
-
end
|
761
|
-
|
762
|
-
it "adds the session data to the transaction" do
|
763
|
-
data = { "key" => "value" }
|
764
|
-
transaction.add_session_data(data)
|
765
|
-
|
766
|
-
transaction._sample
|
767
|
-
expect(transaction).to include_session_data(data)
|
768
|
-
end
|
769
|
-
|
770
|
-
it "merges the session data on the transaction" do
|
771
|
-
transaction.add_session_data("abc" => "value")
|
772
|
-
transaction.add_session_data("def" => "value")
|
773
|
-
transaction.add_session_data { { "xyz" => "value" } }
|
774
|
-
|
775
|
-
transaction._sample
|
776
|
-
expect(transaction).to include_session_data(
|
777
|
-
"abc" => "value",
|
778
|
-
"def" => "value",
|
779
|
-
"xyz" => "value"
|
780
|
-
)
|
781
|
-
end
|
782
|
-
|
783
|
-
it "adds the session data to the transaction with a block" do
|
784
|
-
data = { "key" => "value" }
|
785
|
-
transaction.add_session_data { data }
|
786
|
-
|
787
|
-
transaction._sample
|
788
|
-
expect(transaction).to include_session_data(data)
|
789
|
-
end
|
790
|
-
|
791
|
-
it "adds the session data block value when both an argument and block are given" do
|
792
|
-
arg_data = { "argument" => "value" }
|
793
|
-
block_data = { "block" => "value" }
|
794
|
-
transaction.add_session_data(arg_data) { block_data }
|
795
|
-
|
796
|
-
transaction._sample
|
797
|
-
expect(transaction).to include_session_data(block_data)
|
798
|
-
end
|
799
|
-
|
800
|
-
it "logs an error if an error occurred storing the session data" do
|
801
|
-
transaction.add_session_data { raise "uh oh" }
|
802
|
-
|
803
|
-
logs = capture_logs { transaction._sample }
|
804
|
-
expect(logs).to contains_log(
|
805
|
-
:error,
|
806
|
-
"Exception while fetching session data: RuntimeError: uh oh"
|
807
|
-
)
|
808
|
-
end
|
809
|
-
|
810
|
-
it "does not update the session data on the transaction if the given value is nil" do
|
811
|
-
data = { "key" => "value" }
|
812
|
-
transaction.add_session_data(data)
|
813
|
-
transaction.add_session_data(nil)
|
814
|
-
|
815
|
-
transaction._sample
|
816
|
-
expect(transaction).to include_session_data(data)
|
817
|
-
end
|
818
|
-
|
819
|
-
context "with filter_session_data" do
|
820
|
-
let(:options) { { :filter_session_data => ["filtered_key"] } }
|
821
|
-
|
822
|
-
it "does not include filtered out session data" do
|
823
|
-
transaction.add_session_data("data" => "value1", "filtered_key" => "filtered_value")
|
824
|
-
|
825
|
-
transaction._sample
|
826
|
-
expect(transaction).to include_session_data("data" => "value1")
|
827
|
-
end
|
828
|
-
end
|
829
|
-
end
|
830
|
-
|
831
|
-
describe "#add_session_data_if_nil" do
|
832
|
-
let(:transaction) { new_transaction }
|
833
|
-
|
834
|
-
context "when the session data is not set" do
|
835
|
-
it "sets the session data on the transaction" do
|
836
|
-
data = { "key" => "value" }
|
837
|
-
transaction.add_session_data_if_nil(data)
|
838
|
-
|
839
|
-
transaction._sample
|
840
|
-
expect(transaction).to include_session_data(data)
|
841
|
-
end
|
842
|
-
|
843
|
-
it "updates the session data on the transaction with a block" do
|
844
|
-
data = { "key" => "value" }
|
845
|
-
transaction.add_session_data_if_nil { data }
|
846
|
-
|
847
|
-
transaction._sample
|
848
|
-
expect(transaction).to include_session_data(data)
|
849
|
-
end
|
850
|
-
|
851
|
-
it "updates with the session data block when both an argument and block are given" do
|
852
|
-
arg_data = { "argument" => "value" }
|
853
|
-
block_data = { "block" => "value" }
|
854
|
-
transaction.add_session_data_if_nil(arg_data) { block_data }
|
855
|
-
|
856
|
-
transaction._sample
|
857
|
-
expect(transaction).to include_session_data(block_data)
|
858
|
-
end
|
859
|
-
|
860
|
-
it "does not update the session data on the transaction if the given value is nil" do
|
861
|
-
data = { "key" => "value" }
|
862
|
-
transaction.add_session_data(data)
|
863
|
-
transaction.add_session_data_if_nil(nil)
|
864
|
-
|
865
|
-
transaction._sample
|
866
|
-
expect(transaction).to include_session_data(data)
|
867
|
-
end
|
868
|
-
end
|
869
|
-
|
870
|
-
context "when the session data are set" do
|
871
|
-
it "does not update the session data on the transaction" do
|
872
|
-
preset_data = { "other" => "data" }
|
873
|
-
data = { "key" => "value" }
|
874
|
-
transaction.add_session_data(preset_data)
|
875
|
-
transaction.add_session_data_if_nil(data)
|
876
|
-
|
877
|
-
transaction._sample
|
878
|
-
expect(transaction).to include_session_data(preset_data)
|
879
|
-
end
|
880
|
-
|
881
|
-
it "does not update the session data with a block on the transaction" do
|
882
|
-
preset_data = { "other" => "data" }
|
883
|
-
data = { "key" => "value" }
|
884
|
-
transaction.add_session_data(preset_data)
|
885
|
-
transaction.add_session_data_if_nil { data }
|
886
|
-
|
887
|
-
transaction._sample
|
888
|
-
expect(transaction).to include_session_data(preset_data)
|
889
|
-
end
|
890
|
-
end
|
891
|
-
end
|
892
|
-
|
893
|
-
describe "#add_headers" do
|
894
|
-
let(:transaction) { new_transaction }
|
895
|
-
|
896
|
-
it "has a #set_headers alias" do
|
897
|
-
expect(transaction.method(:add_headers)).to eq(transaction.method(:set_headers))
|
898
|
-
end
|
899
|
-
|
900
|
-
it "adds the headers to the transaction" do
|
901
|
-
headers = { "PATH_INFO" => "value" }
|
902
|
-
transaction.add_headers(headers)
|
903
|
-
|
904
|
-
transaction._sample
|
905
|
-
expect(transaction).to include_environment(headers)
|
906
|
-
end
|
907
|
-
|
908
|
-
it "merges the headers on the transaction" do
|
909
|
-
transaction.add_headers("PATH_INFO" => "value")
|
910
|
-
transaction.add_headers("REQUEST_METHOD" => "value")
|
911
|
-
transaction.add_headers { { "HTTP_ACCEPT" => "value" } }
|
912
|
-
|
913
|
-
transaction._sample
|
914
|
-
expect(transaction).to include_environment(
|
915
|
-
"PATH_INFO" => "value",
|
916
|
-
"REQUEST_METHOD" => "value",
|
917
|
-
"HTTP_ACCEPT" => "value"
|
918
|
-
)
|
919
|
-
end
|
920
|
-
|
921
|
-
it "adds the headers to the transaction with a block" do
|
922
|
-
headers = { "PATH_INFO" => "value" }
|
923
|
-
transaction.add_headers { headers }
|
924
|
-
|
925
|
-
transaction._sample
|
926
|
-
expect(transaction).to include_environment(headers)
|
927
|
-
end
|
928
|
-
|
929
|
-
it "adds the headers block value when both an argument and block are given" do
|
930
|
-
arg_data = { "PATH_INFO" => "/arg-path" }
|
931
|
-
block_data = { "PATH_INFO" => "/block-path" }
|
932
|
-
transaction.add_headers(arg_data) { block_data }
|
933
|
-
|
934
|
-
transaction._sample
|
935
|
-
expect(transaction).to include_environment(block_data)
|
936
|
-
end
|
937
|
-
|
938
|
-
it "logs an error if an error occurred storing the headers" do
|
939
|
-
transaction.add_headers { raise "uh oh" }
|
940
|
-
|
941
|
-
logs = capture_logs { transaction._sample }
|
942
|
-
expect(logs).to contains_log(
|
943
|
-
:error,
|
944
|
-
"Exception while fetching headers: RuntimeError: uh oh"
|
945
|
-
)
|
946
|
-
end
|
947
|
-
|
948
|
-
it "does not update the headers on the transaction if the given value is nil" do
|
949
|
-
headers = { "PATH_INFO" => "value" }
|
950
|
-
transaction.add_headers(headers)
|
951
|
-
transaction.add_headers(nil)
|
952
|
-
|
953
|
-
transaction._sample
|
954
|
-
expect(transaction).to include_environment(headers)
|
955
|
-
end
|
956
|
-
|
957
|
-
context "with request_headers options" do
|
958
|
-
let(:options) { { :request_headers => ["MY_HEADER"] } }
|
959
|
-
|
960
|
-
it "does not include filtered out headers" do
|
961
|
-
transaction.add_headers("MY_HEADER" => "value1", "filtered_key" => "filtered_value")
|
962
|
-
|
963
|
-
transaction._sample
|
964
|
-
expect(transaction).to include_environment("MY_HEADER" => "value1")
|
965
|
-
end
|
966
|
-
end
|
967
|
-
end
|
968
|
-
|
969
|
-
describe "#add_headers_if_nil" do
|
970
|
-
let(:transaction) { new_transaction }
|
971
|
-
|
972
|
-
it "has a #set_headers_if_nil alias" do
|
973
|
-
expect(transaction.method(:add_headers_if_nil)).to eq(transaction.method(:set_headers_if_nil))
|
974
|
-
end
|
975
|
-
|
976
|
-
context "when the headers are not set" do
|
977
|
-
it "adds the headers to the transaction" do
|
978
|
-
headers = { "PATH_INFO" => "value" }
|
979
|
-
transaction.add_headers_if_nil(headers)
|
980
|
-
|
981
|
-
transaction._sample
|
982
|
-
expect(transaction).to include_environment(headers)
|
983
|
-
end
|
984
|
-
|
985
|
-
it "adds the headers to the transaction with a block" do
|
986
|
-
headers = { "PATH_INFO" => "value" }
|
987
|
-
transaction.add_headers_if_nil { headers }
|
988
|
-
|
989
|
-
transaction._sample
|
990
|
-
expect(transaction).to include_environment(headers)
|
991
|
-
end
|
992
|
-
|
993
|
-
it "adds the headers block value when both an argument and block are given" do
|
994
|
-
arg_data = { "PATH_INFO" => "/arg-path" }
|
995
|
-
block_data = { "PATH_INFO" => "/block-path" }
|
996
|
-
transaction.add_headers_if_nil(arg_data) { block_data }
|
997
|
-
|
998
|
-
transaction._sample
|
999
|
-
expect(transaction).to include_environment(block_data)
|
1000
|
-
end
|
1001
|
-
|
1002
|
-
it "does not update the headers on the transaction if the given value is nil" do
|
1003
|
-
headers = { "PATH_INFO" => "value" }
|
1004
|
-
transaction.add_headers(headers)
|
1005
|
-
transaction.add_headers_if_nil(nil)
|
1006
|
-
|
1007
|
-
transaction._sample
|
1008
|
-
expect(transaction).to include_environment(headers)
|
1009
|
-
end
|
1010
|
-
end
|
1011
|
-
|
1012
|
-
context "when the headers are set" do
|
1013
|
-
it "does not update the headers on the transaction" do
|
1014
|
-
preset_headers = { "PATH_INFO" => "/first-path" }
|
1015
|
-
headers = { "PATH_INFO" => "/other-path" }
|
1016
|
-
transaction.add_headers(preset_headers)
|
1017
|
-
transaction.add_headers_if_nil(headers)
|
1018
|
-
|
1019
|
-
transaction._sample
|
1020
|
-
expect(transaction).to include_environment(preset_headers)
|
1021
|
-
end
|
1022
|
-
|
1023
|
-
it "does not update the headers with a block on the transaction" do
|
1024
|
-
preset_headers = { "PATH_INFO" => "/first-path" }
|
1025
|
-
headers = { "PATH_INFO" => "/other-path" }
|
1026
|
-
transaction.add_headers(preset_headers)
|
1027
|
-
transaction.add_headers_if_nil { headers }
|
1028
|
-
|
1029
|
-
transaction._sample
|
1030
|
-
expect(transaction).to include_environment(preset_headers)
|
1031
|
-
end
|
1032
|
-
end
|
1033
|
-
end
|
1034
|
-
|
1035
|
-
describe "#add_tags" do
|
1036
|
-
let(:transaction) { new_transaction }
|
1037
|
-
let(:long_string) { "a" * 10_001 }
|
1038
|
-
|
1039
|
-
it "stores tags on the transaction" do
|
1040
|
-
transaction.add_tags(
|
1041
|
-
:valid_key => "valid_value",
|
1042
|
-
"valid_string_key" => "valid_value",
|
1043
|
-
:both_symbols => :valid_value,
|
1044
|
-
:integer_value => 1,
|
1045
|
-
:hash_value => { "invalid" => "hash" },
|
1046
|
-
:array_value => %w[invalid array],
|
1047
|
-
:object => Object.new,
|
1048
|
-
:too_long_value => long_string,
|
1049
|
-
long_string => "too_long_key",
|
1050
|
-
:true_tag => true,
|
1051
|
-
:false_tag => false
|
1052
|
-
)
|
1053
|
-
transaction._sample
|
1054
|
-
|
1055
|
-
expect(transaction).to include_tags(
|
1056
|
-
"valid_key" => "valid_value",
|
1057
|
-
"valid_string_key" => "valid_value",
|
1058
|
-
"both_symbols" => "valid_value",
|
1059
|
-
"integer_value" => 1,
|
1060
|
-
"too_long_value" => "#{"a" * 10_000}...",
|
1061
|
-
long_string => "too_long_key",
|
1062
|
-
"true_tag" => true,
|
1063
|
-
"false_tag" => false
|
1064
|
-
)
|
1065
|
-
end
|
1066
|
-
|
1067
|
-
it "merges the tags when called multiple times" do
|
1068
|
-
transaction.add_tags(:key1 => "value1")
|
1069
|
-
transaction.add_tags(:key2 => "value2")
|
1070
|
-
transaction._sample
|
1071
|
-
|
1072
|
-
expect(transaction).to include_tags(
|
1073
|
-
"key1" => "value1",
|
1074
|
-
"key2" => "value2"
|
1075
|
-
)
|
1076
|
-
end
|
1077
|
-
end
|
1078
|
-
|
1079
|
-
describe "#add_custom_data" do
|
1080
|
-
let(:transaction) { new_transaction }
|
1081
|
-
|
1082
|
-
it "has a #add_custom_data alias" do
|
1083
|
-
expect(transaction.method(:add_custom_data)).to eq(transaction.method(:set_custom_data))
|
1084
|
-
end
|
1085
|
-
|
1086
|
-
it "adds a custom Hash data to the transaction" do
|
1087
|
-
transaction.add_custom_data(
|
1088
|
-
:user => {
|
1089
|
-
:id => 123,
|
1090
|
-
:locale => "abc"
|
1091
|
-
},
|
1092
|
-
:organization => {
|
1093
|
-
:slug => "appsignal",
|
1094
|
-
:plan => "enterprise"
|
1095
|
-
}
|
1096
|
-
)
|
1097
|
-
|
1098
|
-
transaction._sample
|
1099
|
-
expect(transaction).to include_custom_data(
|
1100
|
-
"user" => {
|
1101
|
-
"id" => 123,
|
1102
|
-
"locale" => "abc"
|
1103
|
-
},
|
1104
|
-
"organization" => {
|
1105
|
-
"slug" => "appsignal",
|
1106
|
-
"plan" => "enterprise"
|
1107
|
-
}
|
1108
|
-
)
|
1109
|
-
end
|
1110
|
-
|
1111
|
-
it "adds a custom Array data to the transaction" do
|
1112
|
-
transaction.add_custom_data([
|
1113
|
-
[123, "abc"],
|
1114
|
-
["appsignal", "enterprise"]
|
1115
|
-
])
|
1116
|
-
|
1117
|
-
transaction._sample
|
1118
|
-
expect(transaction).to include_custom_data([
|
1119
|
-
[123, "abc"],
|
1120
|
-
["appsignal", "enterprise"]
|
1121
|
-
])
|
1122
|
-
end
|
1123
|
-
|
1124
|
-
it "does not store non Hash or Array custom data" do
|
1125
|
-
logs =
|
1126
|
-
capture_logs do
|
1127
|
-
transaction.add_custom_data("abc")
|
1128
|
-
transaction._sample
|
1129
|
-
expect(transaction).to_not include_custom_data
|
1130
|
-
|
1131
|
-
transaction.add_custom_data(123)
|
1132
|
-
transaction._sample
|
1133
|
-
expect(transaction).to_not include_custom_data
|
1134
|
-
|
1135
|
-
transaction.add_custom_data(Object.new)
|
1136
|
-
transaction._sample
|
1137
|
-
expect(transaction).to_not include_custom_data
|
1138
|
-
end
|
1139
|
-
|
1140
|
-
expect(logs).to contains_log(
|
1141
|
-
:error,
|
1142
|
-
%(Sample data 'custom_data': Unsupported data type 'String' received: "abc")
|
1143
|
-
)
|
1144
|
-
expect(logs).to contains_log(
|
1145
|
-
:error,
|
1146
|
-
%(Sample data 'custom_data': Unsupported data type 'Integer' received: 123)
|
1147
|
-
)
|
1148
|
-
expect(logs).to contains_log(
|
1149
|
-
:error,
|
1150
|
-
%(Sample data 'custom_data': Unsupported data type 'Object' received: #<Object:)
|
1151
|
-
)
|
1152
|
-
end
|
1153
|
-
|
1154
|
-
it "merges the custom data if called multiple times" do
|
1155
|
-
transaction.add_custom_data("abc" => "value")
|
1156
|
-
transaction.add_custom_data("def" => "value")
|
1157
|
-
|
1158
|
-
transaction._sample
|
1159
|
-
expect(transaction).to include_custom_data(
|
1160
|
-
"abc" => "value",
|
1161
|
-
"def" => "value"
|
1162
|
-
)
|
1163
|
-
end
|
1164
|
-
end
|
1165
|
-
|
1166
|
-
describe "#add_breadcrumb" do
|
1167
|
-
let(:transaction) { new_transaction }
|
1168
|
-
|
1169
|
-
context "when over the limit" do
|
1170
|
-
before do
|
1171
|
-
22.times do |i|
|
1172
|
-
transaction.add_breadcrumb(
|
1173
|
-
"network",
|
1174
|
-
"GET http://localhost",
|
1175
|
-
"User made external network request",
|
1176
|
-
{ :code => i + 1 },
|
1177
|
-
Time.parse("10-10-2010 10:00:00 UTC")
|
1178
|
-
)
|
1179
|
-
end
|
1180
|
-
transaction._sample
|
1181
|
-
end
|
1182
|
-
|
1183
|
-
it "stores last <LIMIT> breadcrumbs on the transaction" do
|
1184
|
-
expect(transaction.to_h["sample_data"]["breadcrumbs"].length).to eql(20)
|
1185
|
-
expect(transaction.to_h["sample_data"]["breadcrumbs"][0]).to eq(
|
1186
|
-
"action" => "GET http://localhost",
|
1187
|
-
"category" => "network",
|
1188
|
-
"message" => "User made external network request",
|
1189
|
-
"metadata" => { "code" => 3 },
|
1190
|
-
"time" => 1286704800 # rubocop:disable Style/NumericLiterals
|
1191
|
-
)
|
1192
|
-
expect(transaction.to_h["sample_data"]["breadcrumbs"][19]).to eq(
|
1193
|
-
"action" => "GET http://localhost",
|
1194
|
-
"category" => "network",
|
1195
|
-
"message" => "User made external network request",
|
1196
|
-
"metadata" => { "code" => 22 },
|
1197
|
-
"time" => 1286704800 # rubocop:disable Style/NumericLiterals
|
1198
|
-
)
|
1199
|
-
end
|
1200
|
-
end
|
1201
|
-
|
1202
|
-
context "with defaults" do
|
1203
|
-
it "stores breadcrumb with defaults on transaction" do
|
1204
|
-
timeframe_start = Time.now.utc.to_i
|
1205
|
-
transaction.add_breadcrumb("user_action", "clicked HOME")
|
1206
|
-
transaction._sample
|
1207
|
-
timeframe_end = Time.now.utc.to_i
|
1208
|
-
|
1209
|
-
expect(transaction).to include_breadcrumb(
|
1210
|
-
"clicked HOME",
|
1211
|
-
"user_action",
|
1212
|
-
"",
|
1213
|
-
{},
|
1214
|
-
be_between(timeframe_start, timeframe_end)
|
1215
|
-
)
|
1216
|
-
end
|
1217
|
-
end
|
1218
|
-
|
1219
|
-
context "with metadata argument that's not a Hash" do
|
1220
|
-
it "does not add the breadcrumb and logs and error" do
|
1221
|
-
logs =
|
1222
|
-
capture_logs do
|
1223
|
-
transaction.add_breadcrumb("category", "action", "message", "invalid metadata")
|
1224
|
-
end
|
1225
|
-
transaction._sample
|
1226
|
-
|
1227
|
-
expect(transaction).to_not include_breadcrumbs
|
1228
|
-
expect(logs).to contains_log(
|
1229
|
-
:error,
|
1230
|
-
"add_breadcrumb: Cannot add breadcrumb. The given metadata argument is not a Hash."
|
1231
|
-
)
|
1232
|
-
end
|
1233
|
-
end
|
1234
|
-
end
|
1235
|
-
|
1236
|
-
describe "#set_action" do
|
1237
|
-
let(:transaction) { new_transaction }
|
1238
|
-
|
1239
|
-
context "when the action is set" do
|
1240
|
-
it "updates the action name on the transaction" do
|
1241
|
-
action_name = "PagesController#show"
|
1242
|
-
transaction.set_action(action_name)
|
1243
|
-
|
1244
|
-
expect(transaction.action).to eq(action_name)
|
1245
|
-
expect(transaction).to have_action(action_name)
|
1246
|
-
end
|
1247
|
-
end
|
1248
|
-
|
1249
|
-
context "when the action is nil" do
|
1250
|
-
it "does not update the action name on the transaction" do
|
1251
|
-
action_name = "PagesController#show"
|
1252
|
-
transaction.set_action(action_name)
|
1253
|
-
transaction.set_action(nil)
|
1254
|
-
|
1255
|
-
expect(transaction.action).to eq(action_name)
|
1256
|
-
expect(transaction).to have_action(action_name)
|
1257
|
-
end
|
1258
|
-
end
|
1259
|
-
end
|
1260
|
-
|
1261
|
-
describe "#set_action_if_nil" do
|
1262
|
-
let(:transaction) { new_transaction }
|
1263
|
-
|
1264
|
-
context "when the action is not set" do
|
1265
|
-
it "updates the action name on the transaction" do
|
1266
|
-
expect(transaction.action).to eq(nil)
|
1267
|
-
expect(transaction).to_not have_action
|
1268
|
-
|
1269
|
-
action_name = "PagesController#show"
|
1270
|
-
transaction.set_action_if_nil(action_name)
|
1271
|
-
|
1272
|
-
expect(transaction.action).to eq(action_name)
|
1273
|
-
expect(transaction).to have_action(action_name)
|
1274
|
-
end
|
1275
|
-
|
1276
|
-
context "when the given action is nil" do
|
1277
|
-
it "does not update the action name on the transaction" do
|
1278
|
-
action_name = "something"
|
1279
|
-
transaction.set_action("something")
|
1280
|
-
transaction.set_action_if_nil(nil)
|
1281
|
-
|
1282
|
-
expect(transaction.action).to eq(action_name)
|
1283
|
-
expect(transaction).to have_action(action_name)
|
1284
|
-
end
|
1285
|
-
end
|
1286
|
-
end
|
1287
|
-
|
1288
|
-
context "when the action is set" do
|
1289
|
-
it "does not update the action name on the transaction" do
|
1290
|
-
action_name = "something"
|
1291
|
-
transaction.set_action("something")
|
1292
|
-
transaction.set_action_if_nil("something else")
|
1293
|
-
|
1294
|
-
expect(transaction.action).to eq(action_name)
|
1295
|
-
expect(transaction).to have_action(action_name)
|
1296
|
-
end
|
1297
|
-
end
|
1298
|
-
end
|
1299
|
-
|
1300
|
-
describe "#set_namespace" do
|
1301
|
-
let(:transaction) { new_transaction }
|
1302
|
-
|
1303
|
-
context "when the namespace is not nil" do
|
1304
|
-
it "updates the namespace on the transaction" do
|
1305
|
-
namespace = "custom"
|
1306
|
-
transaction.set_namespace(namespace)
|
1307
|
-
|
1308
|
-
expect(transaction.namespace).to eq namespace
|
1309
|
-
expect(transaction).to have_namespace(namespace)
|
1310
|
-
end
|
1311
|
-
end
|
1312
|
-
|
1313
|
-
context "when the namespace is nil" do
|
1314
|
-
it "does not update the namespace on the transaction" do
|
1315
|
-
namespace = "custom"
|
1316
|
-
transaction.set_namespace(namespace)
|
1317
|
-
transaction.set_namespace(nil)
|
1318
|
-
|
1319
|
-
expect(transaction.namespace).to eq(namespace)
|
1320
|
-
expect(transaction).to have_namespace(namespace)
|
1321
|
-
end
|
1322
|
-
end
|
1323
|
-
end
|
1324
|
-
|
1325
|
-
describe "#set_queue_start" do
|
1326
|
-
let(:transaction) { new_transaction }
|
1327
|
-
|
1328
|
-
it "sets the queue start in extension" do
|
1329
|
-
transaction.set_queue_start(10)
|
1330
|
-
|
1331
|
-
expect(transaction).to have_queue_start(10)
|
1332
|
-
end
|
1333
|
-
|
1334
|
-
it "does not set the queue start in extension when value is nil" do
|
1335
|
-
transaction.set_queue_start(nil)
|
1336
|
-
|
1337
|
-
expect(transaction).to_not have_queue_start
|
1338
|
-
end
|
1339
|
-
|
1340
|
-
it "does not raise an error when the queue start is too big" do
|
1341
|
-
expect(transaction.ext).to receive(:set_queue_start).and_raise(RangeError)
|
1342
|
-
|
1343
|
-
expect(Appsignal.internal_logger).to receive(:warn).with("Queue start value 10 is too big")
|
1344
|
-
|
1345
|
-
transaction.set_queue_start(10)
|
1346
|
-
end
|
1347
|
-
end
|
1348
|
-
|
1349
|
-
describe "#set_metadata" do
|
1350
|
-
let(:transaction) { new_transaction }
|
1351
|
-
|
1352
|
-
it "updates the metadata on the transaction" do
|
1353
|
-
transaction.set_metadata("request_method", "GET")
|
1354
|
-
|
1355
|
-
expect(transaction).to include_metadata("request_method" => "GET")
|
1356
|
-
end
|
1357
|
-
|
1358
|
-
context "when filter_metadata includes metadata key" do
|
1359
|
-
let(:options) { { :filter_metadata => ["filter_key"] } }
|
1360
|
-
|
1361
|
-
it "does not set the metadata on the transaction" do
|
1362
|
-
transaction.set_metadata(:filter_key, "filtered value")
|
1363
|
-
transaction.set_metadata("filter_key", "filtered value")
|
1364
|
-
|
1365
|
-
expect(transaction).to_not include_metadata("filter_key" => anything)
|
1366
|
-
end
|
1367
|
-
end
|
1368
|
-
|
1369
|
-
context "when the key is nil" do
|
1370
|
-
it "does not update the metadata on the transaction" do
|
1371
|
-
transaction.set_metadata(nil, "GET")
|
1372
|
-
|
1373
|
-
expect(transaction).to_not include_metadata
|
1374
|
-
end
|
1375
|
-
end
|
1376
|
-
|
1377
|
-
context "when the value is nil" do
|
1378
|
-
it "does not update the metadata on the transaction" do
|
1379
|
-
transaction.set_metadata("request_method", nil)
|
1380
|
-
|
1381
|
-
expect(transaction).to_not include_metadata
|
1382
|
-
end
|
1383
|
-
end
|
1384
|
-
end
|
1385
|
-
|
1386
|
-
describe "storing sample data" do
|
1387
|
-
let(:transaction) { new_transaction }
|
1388
|
-
|
1389
|
-
it "stores sample data on the transaction" do
|
1390
|
-
transaction.set_params(
|
1391
|
-
"string_param" => "string_value",
|
1392
|
-
:symbol_param => "symbol_value",
|
1393
|
-
"integer" => 123,
|
1394
|
-
"float" => 123.45,
|
1395
|
-
"array" => ["abc", 456, { "option" => true }],
|
1396
|
-
"hash" => { "hash_key" => "hash_value" }
|
1397
|
-
)
|
1398
|
-
|
1399
|
-
transaction._sample
|
1400
|
-
expect(transaction).to include_params(
|
1401
|
-
"string_param" => "string_value",
|
1402
|
-
"symbol_param" => "symbol_value",
|
1403
|
-
"integer" => 123,
|
1404
|
-
"float" => 123.45,
|
1405
|
-
"array" => ["abc", 456, { "option" => true }],
|
1406
|
-
"hash" => { "hash_key" => "hash_value" }
|
1407
|
-
)
|
1408
|
-
end
|
1409
|
-
|
1410
|
-
it "does not store non-Array and non-Hash data" do
|
1411
|
-
logs =
|
1412
|
-
capture_logs do
|
1413
|
-
transaction.set_params("some string")
|
1414
|
-
transaction._sample
|
1415
|
-
expect(transaction).to_not include_params
|
1416
|
-
|
1417
|
-
transaction.set_params(123)
|
1418
|
-
transaction._sample
|
1419
|
-
expect(transaction).to_not include_params
|
1420
|
-
|
1421
|
-
transaction.set_params(Class.new)
|
1422
|
-
transaction._sample
|
1423
|
-
expect(transaction).to_not include_params
|
1424
|
-
|
1425
|
-
set = Set.new
|
1426
|
-
set.add("some value")
|
1427
|
-
transaction.set_params(set)
|
1428
|
-
transaction._sample
|
1429
|
-
expect(transaction).to_not include_params
|
1430
|
-
end
|
1431
|
-
|
1432
|
-
expect(logs).to contains_log(
|
1433
|
-
:error,
|
1434
|
-
%(Sample data 'params': Unsupported data type 'String' received: "some string")
|
1435
|
-
)
|
1436
|
-
expect(logs).to contains_log(
|
1437
|
-
:error,
|
1438
|
-
%(Sample data 'params': Unsupported data type 'Integer' received: 123)
|
1439
|
-
)
|
1440
|
-
expect(logs).to contains_log(
|
1441
|
-
:error,
|
1442
|
-
%(Sample data 'params': Unsupported data type 'Class' received: #<Class)
|
1443
|
-
)
|
1444
|
-
expect(logs).to contains_log(
|
1445
|
-
:error,
|
1446
|
-
%(Sample data 'params': Unsupported data type 'Set' received: #<Set: {"some value"}>)
|
1447
|
-
)
|
1448
|
-
end
|
1449
|
-
|
1450
|
-
it "does not store data that can't be converted to JSON" do
|
1451
|
-
klass = Class.new do
|
1452
|
-
def initialize
|
1453
|
-
@calls = 0
|
1454
|
-
end
|
1455
|
-
|
1456
|
-
def to_s
|
1457
|
-
raise "foo" if @calls > 0 # Cause a deliberate error
|
1458
|
-
|
1459
|
-
@calls += 1
|
1460
|
-
end
|
1461
|
-
end
|
1462
|
-
|
1463
|
-
transaction.set_params(klass.new => 1)
|
1464
|
-
logs = capture_logs { transaction._sample }
|
1465
|
-
|
1466
|
-
expect(transaction).to_not include_params
|
1467
|
-
expect(logs).to contains_log :error,
|
1468
|
-
"Error generating data (RuntimeError: foo) for"
|
1469
|
-
end
|
1470
|
-
end
|
1471
|
-
|
1472
|
-
describe "#set_sample_data" do
|
1473
|
-
let(:transaction) { new_transaction }
|
1474
|
-
|
1475
|
-
it "updates the sample data on the transaction" do
|
1476
|
-
silence do
|
1477
|
-
transaction.send(
|
1478
|
-
:set_sample_data,
|
1479
|
-
"params",
|
1480
|
-
:controller => "blog_posts",
|
1481
|
-
:action => "show",
|
1482
|
-
:id => "1"
|
1483
|
-
)
|
1484
|
-
end
|
1485
|
-
|
1486
|
-
expect(transaction).to include_params(
|
1487
|
-
"action" => "show",
|
1488
|
-
"controller" => "blog_posts",
|
1489
|
-
"id" => "1"
|
1490
|
-
)
|
1491
|
-
end
|
1492
|
-
|
1493
|
-
context "when the data is no Array or Hash" do
|
1494
|
-
it "does not update the sample data on the transaction" do
|
1495
|
-
logs =
|
1496
|
-
capture_logs do
|
1497
|
-
silence { transaction.send(:set_sample_data, "params", "string") }
|
1498
|
-
end
|
1499
|
-
|
1500
|
-
expect(transaction.to_h["sample_data"]).to eq({})
|
1501
|
-
expect(logs).to contains_log :error,
|
1502
|
-
%(Invalid sample data for 'params'. Value is not an Array or Hash: '"string"')
|
1503
|
-
end
|
1504
|
-
end
|
1505
|
-
|
1506
|
-
context "when the data cannot be converted to JSON" do
|
1507
|
-
it "does not update the sample data on the transaction" do
|
1508
|
-
klass = Class.new do
|
1509
|
-
def to_s
|
1510
|
-
raise "foo" # Cause a deliberate error
|
1511
|
-
end
|
1512
|
-
end
|
1513
|
-
logs =
|
1514
|
-
capture_logs do
|
1515
|
-
silence { transaction.send(:set_sample_data, "params", klass.new => 1) }
|
1516
|
-
end
|
1517
|
-
|
1518
|
-
expect(transaction).to_not include_params
|
1519
|
-
expect(logs).to contains_log :error,
|
1520
|
-
"Error generating data (RuntimeError: foo) for"
|
1521
|
-
end
|
1522
|
-
end
|
1523
|
-
end
|
1524
|
-
|
1525
|
-
describe "#add_error" do
|
1526
|
-
let(:transaction) { create_transaction }
|
1527
|
-
|
1528
|
-
let(:error) do
|
1529
|
-
e = ExampleStandardError.new("test message")
|
1530
|
-
allow(e).to receive(:backtrace).and_return(["line 1"])
|
1531
|
-
e
|
1532
|
-
end
|
1533
|
-
|
1534
|
-
context "when error argument is not an error" do
|
1535
|
-
let(:error) { Object.new }
|
1536
|
-
|
1537
|
-
it "does not add the error" do
|
1538
|
-
logs = capture_logs { transaction.add_error(error) }
|
1539
|
-
|
1540
|
-
expect(transaction).to_not have_error
|
1541
|
-
expect(logs).to contains_log(
|
1542
|
-
:error,
|
1543
|
-
"Appsignal::Transaction#add_error: Cannot add error. " \
|
1544
|
-
"The given value is not an exception: #{error.inspect}"
|
1545
|
-
)
|
1546
|
-
end
|
1547
|
-
end
|
1548
|
-
|
1549
|
-
context "when AppSignal is not active" do
|
1550
|
-
it "does not add the error" do
|
1551
|
-
allow(Appsignal).to receive(:active?).and_return(false)
|
1552
|
-
|
1553
|
-
transaction.add_error(error)
|
1554
|
-
|
1555
|
-
expect(transaction).to_not have_error
|
1556
|
-
end
|
1557
|
-
end
|
1558
|
-
|
1559
|
-
context "when a block is given" do
|
1560
|
-
it "stores the block in the error blocks" do
|
1561
|
-
block = proc { "block" }
|
1562
|
-
|
1563
|
-
transaction.add_error(error, &block)
|
1564
|
-
|
1565
|
-
expect(transaction.error_blocks).to eq({
|
1566
|
-
error => [block]
|
1567
|
-
})
|
1568
|
-
end
|
1569
|
-
end
|
1570
|
-
|
1571
|
-
context "when no error is set in the transaction" do
|
1572
|
-
it "sets the error on the transaction" do
|
1573
|
-
transaction.add_error(error)
|
1574
|
-
|
1575
|
-
expect(transaction).to have_error(
|
1576
|
-
"ExampleStandardError",
|
1577
|
-
"test message",
|
1578
|
-
["line 1"]
|
1579
|
-
)
|
1580
|
-
end
|
1581
|
-
|
1582
|
-
it "does store the error in the errors" do
|
1583
|
-
transaction.add_error(error)
|
1584
|
-
|
1585
|
-
expect(transaction.error_blocks).to eq({ error => [] })
|
1586
|
-
end
|
1587
|
-
end
|
1588
|
-
|
1589
|
-
context "when an error is already set in the transaction" do
|
1590
|
-
let(:other_error) do
|
1591
|
-
e = ExampleStandardError.new("other test message")
|
1592
|
-
allow(e).to receive(:backtrace).and_return(["line 2"])
|
1593
|
-
e
|
1594
|
-
end
|
1595
|
-
|
1596
|
-
before { transaction.set_error(other_error) }
|
1597
|
-
|
1598
|
-
it "stores an error in the errors" do
|
1599
|
-
transaction.add_error(error)
|
1600
|
-
|
1601
|
-
expect(transaction.error_blocks).to eq({
|
1602
|
-
other_error => [],
|
1603
|
-
error => []
|
1604
|
-
})
|
1605
|
-
end
|
1606
|
-
|
1607
|
-
it "does not set the error on the extension" do
|
1608
|
-
transaction.add_error(error)
|
1609
|
-
|
1610
|
-
expect(transaction).to have_error(
|
1611
|
-
"ExampleStandardError",
|
1612
|
-
"other test message",
|
1613
|
-
["line 2"]
|
1614
|
-
)
|
1615
|
-
end
|
1616
|
-
end
|
1617
|
-
|
1618
|
-
context "when the error has already been added" do
|
1619
|
-
before { transaction.add_error(error) }
|
1620
|
-
|
1621
|
-
it "does not add the error to the errors" do
|
1622
|
-
expect(transaction.error_blocks).to eq({ error => [] })
|
1623
|
-
|
1624
|
-
transaction.add_error(error)
|
1625
|
-
|
1626
|
-
expect(transaction.error_blocks).to eq({ error => [] })
|
1627
|
-
end
|
1628
|
-
|
1629
|
-
context "when a block is given" do
|
1630
|
-
it "adds the block to the error blocks" do
|
1631
|
-
block = proc { "block" }
|
1632
|
-
|
1633
|
-
transaction.add_error(error, &block)
|
1634
|
-
|
1635
|
-
expect(transaction.error_blocks).to eq({ error => [block] })
|
1636
|
-
end
|
1637
|
-
end
|
1638
|
-
end
|
1639
|
-
|
1640
|
-
context "when the errors is at the limit" do
|
1641
|
-
let(:seen_error) { ExampleStandardError.new("error 0") }
|
1642
|
-
|
1643
|
-
before do
|
1644
|
-
transaction.add_error(seen_error)
|
1645
|
-
|
1646
|
-
9.times do |i|
|
1647
|
-
transaction.add_error(ExampleStandardError.new("error #{i}"))
|
1648
|
-
end
|
1649
|
-
end
|
1650
|
-
|
1651
|
-
it "does not add a new error to the errors" do
|
1652
|
-
expect(transaction).to have_error("ExampleStandardError", "error 0", [])
|
1653
|
-
expect(transaction.error_blocks.length).to eq(10)
|
1654
|
-
expected_error_blocks = transaction.error_blocks.dup
|
1655
|
-
|
1656
|
-
transaction.add_error(error)
|
1657
|
-
|
1658
|
-
expect(transaction).to have_error("ExampleStandardError", "error 0", [])
|
1659
|
-
expect(transaction.error_blocks).to eq(expected_error_blocks)
|
1660
|
-
end
|
1661
|
-
|
1662
|
-
it "logs a debug message" do
|
1663
|
-
logs = capture_logs { transaction.add_error(error) }
|
1664
|
-
|
1665
|
-
expect(logs).to contains_log(
|
1666
|
-
:warn,
|
1667
|
-
"Appsignal::Transaction#add_error: Transaction has more than 10 distinct errors. " \
|
1668
|
-
"Only the first 10 distinct errors will be reported."
|
1669
|
-
)
|
1670
|
-
end
|
1671
|
-
|
1672
|
-
context "when the error has already been added" do
|
1673
|
-
it "does not add the error to the errors" do
|
1674
|
-
expect(transaction.error_blocks.length).to eq(10)
|
1675
|
-
|
1676
|
-
transaction.add_error(seen_error)
|
1677
|
-
|
1678
|
-
expect(transaction.error_blocks.length).to eq(10)
|
1679
|
-
end
|
1680
|
-
|
1681
|
-
it "does add the block to the error blocks" do
|
1682
|
-
block = proc { "block" }
|
1683
|
-
|
1684
|
-
transaction.add_error(seen_error, &block)
|
1685
|
-
|
1686
|
-
expect(transaction.error_blocks[seen_error]).to eq([block])
|
1687
|
-
end
|
1688
|
-
|
1689
|
-
it "does not log a debug message" do
|
1690
|
-
logs = capture_logs { transaction.add_error(seen_error) }
|
1691
|
-
|
1692
|
-
expect(logs).to_not contains_log(
|
1693
|
-
:warn,
|
1694
|
-
"Appsignal::Transaction#add_error: Transaction has more than 10 distinct errors. " \
|
1695
|
-
"Only the first 10 distinct errors will be reported."
|
1696
|
-
)
|
1697
|
-
end
|
1698
|
-
end
|
1699
|
-
end
|
1700
|
-
end
|
1701
|
-
|
1702
|
-
describe "#_set_error" do
|
1703
|
-
let(:transaction) { new_transaction }
|
1704
|
-
let(:env) { http_request_env_with_data }
|
1705
|
-
let(:error) { ExampleStandardError.new("test message") }
|
1706
|
-
|
1707
|
-
it "responds to add_exception for backwards compatibility" do
|
1708
|
-
expect(transaction).to respond_to(:add_exception)
|
1709
|
-
end
|
1710
|
-
|
1711
|
-
it "does not add the error to the errors" do
|
1712
|
-
transaction.send(:_set_error, error)
|
1713
|
-
|
1714
|
-
expect(transaction.error_blocks).to be_empty
|
1715
|
-
end
|
1716
|
-
|
1717
|
-
context "for a http request" do
|
1718
|
-
it "sets an error on the transaction" do
|
1719
|
-
allow(error).to receive(:backtrace).and_return(["line 1"])
|
1720
|
-
transaction.send(:_set_error, error)
|
1721
|
-
|
1722
|
-
expect(transaction).to have_error(
|
1723
|
-
"ExampleStandardError",
|
1724
|
-
"test message",
|
1725
|
-
["line 1"]
|
1726
|
-
)
|
1727
|
-
end
|
1728
|
-
end
|
1729
|
-
|
1730
|
-
context "when the error has no causes" do
|
1731
|
-
it "should set an empty causes array as sample data" do
|
1732
|
-
transaction.send(:_set_error, error)
|
1733
|
-
|
1734
|
-
expect(transaction).to include_error_causes([])
|
1735
|
-
end
|
1736
|
-
end
|
1737
|
-
|
1738
|
-
context "when the error has multiple causes" do
|
1739
|
-
let(:error) do
|
1740
|
-
e = ExampleStandardError.new("test message")
|
1741
|
-
e2 = RuntimeError.new("cause message")
|
1742
|
-
e3 = StandardError.new("cause message 2")
|
1743
|
-
allow(e).to receive(:backtrace).and_return(["line 1"])
|
1744
|
-
allow(e).to receive(:cause).and_return(e2)
|
1745
|
-
allow(e2).to receive(:cause).and_return(e3)
|
1746
|
-
e
|
1747
|
-
end
|
1748
|
-
|
1749
|
-
let(:error_without_cause) do
|
1750
|
-
ExampleStandardError.new("error without cause")
|
1751
|
-
end
|
1752
|
-
|
1753
|
-
it "sends the causes information as sample data" do
|
1754
|
-
transaction.send(:_set_error, error)
|
1755
|
-
|
1756
|
-
expect(transaction).to have_error(
|
1757
|
-
"ExampleStandardError",
|
1758
|
-
"test message",
|
1759
|
-
["line 1"]
|
1760
|
-
)
|
1761
|
-
expect(transaction).to include_error_causes(
|
1762
|
-
[
|
1763
|
-
{
|
1764
|
-
"name" => "RuntimeError",
|
1765
|
-
"message" => "cause message"
|
1766
|
-
},
|
1767
|
-
{
|
1768
|
-
"name" => "StandardError",
|
1769
|
-
"message" => "cause message 2"
|
1770
|
-
}
|
1771
|
-
]
|
1772
|
-
)
|
1773
|
-
end
|
1774
|
-
|
1775
|
-
it "does not keep error causes from previously set errors" do
|
1776
|
-
transaction.send(:_set_error, error)
|
1777
|
-
transaction.send(:_set_error, error_without_cause)
|
1778
|
-
|
1779
|
-
expect(transaction).to have_error(
|
1780
|
-
"ExampleStandardError",
|
1781
|
-
"error without cause",
|
1782
|
-
[]
|
1783
|
-
)
|
1784
|
-
|
1785
|
-
expect(transaction).to include_error_causes([])
|
1786
|
-
end
|
1787
|
-
end
|
1788
|
-
|
1789
|
-
context "when the error has too many causes" do
|
1790
|
-
let(:error) do
|
1791
|
-
e = ExampleStandardError.new("root cause error")
|
1792
|
-
|
1793
|
-
11.times do |i|
|
1794
|
-
next_e = ExampleStandardError.new("wrapper error #{i}")
|
1795
|
-
allow(next_e).to receive(:cause).and_return(e)
|
1796
|
-
e = next_e
|
1797
|
-
end
|
1798
|
-
|
1799
|
-
allow(e).to receive(:backtrace).and_return(["line 1"])
|
1800
|
-
e
|
1801
|
-
end
|
1802
|
-
|
1803
|
-
it "sends only the first causes as sample data" do
|
1804
|
-
expected_error_causes =
|
1805
|
-
Array.new(10) do |i|
|
1806
|
-
{
|
1807
|
-
"name" => "ExampleStandardError",
|
1808
|
-
"message" => "wrapper error #{9 - i}"
|
1809
|
-
}
|
1810
|
-
end
|
1811
|
-
expected_error_causes.last["is_root_cause"] = false
|
1812
|
-
|
1813
|
-
logs = capture_logs { transaction.send(:_set_error, error) }
|
1814
|
-
|
1815
|
-
expect(transaction).to have_error(
|
1816
|
-
"ExampleStandardError",
|
1817
|
-
"wrapper error 10",
|
1818
|
-
["line 1"]
|
1819
|
-
)
|
1820
|
-
expect(transaction).to include_error_causes(expected_error_causes)
|
1821
|
-
expect(logs).to contains_log(
|
1822
|
-
:debug,
|
1823
|
-
"Appsignal::Transaction#add_error: Error has more " \
|
1824
|
-
"than 10 error causes. Only the first 10 " \
|
1825
|
-
"will be reported."
|
1826
|
-
)
|
1827
|
-
end
|
1828
|
-
end
|
1829
|
-
|
1830
|
-
context "when error message is nil" do
|
1831
|
-
let(:error) do
|
1832
|
-
e = ExampleStandardError.new
|
1833
|
-
allow(e).to receive(:message).and_return(nil)
|
1834
|
-
allow(e).to receive(:backtrace).and_return(["line 1"])
|
1835
|
-
e
|
1836
|
-
end
|
1837
|
-
|
1838
|
-
it "does not raise an error" do
|
1839
|
-
transaction.send(:_set_error, error)
|
1840
|
-
end
|
1841
|
-
|
1842
|
-
it "sets an error on the transaction without an error message" do
|
1843
|
-
transaction.send(:_set_error, error)
|
1844
|
-
|
1845
|
-
expect(transaction).to have_error(
|
1846
|
-
"ExampleStandardError",
|
1847
|
-
"",
|
1848
|
-
["line 1"]
|
1849
|
-
)
|
1850
|
-
end
|
1851
|
-
end
|
1852
|
-
end
|
1853
|
-
|
1854
|
-
describe "#start_event" do
|
1855
|
-
let(:transaction) { new_transaction }
|
1856
|
-
|
1857
|
-
it "starts the event in the extension" do
|
1858
|
-
expect(transaction.ext).to receive(:start_event).with(0).and_call_original
|
1859
|
-
|
1860
|
-
transaction.start_event
|
1861
|
-
end
|
1862
|
-
|
1863
|
-
context "when transaction is paused" do
|
1864
|
-
it "does not start the event" do
|
1865
|
-
transaction.pause!
|
1866
|
-
expect(transaction.ext).to_not receive(:start_event)
|
1867
|
-
|
1868
|
-
transaction.start_event
|
1869
|
-
end
|
1870
|
-
end
|
1871
|
-
end
|
1872
|
-
|
1873
|
-
describe "#finish_event" do
|
1874
|
-
let(:transaction) { new_transaction }
|
1875
|
-
let(:fake_gc_time) { 0 }
|
1876
|
-
|
1877
|
-
it "should finish the event in the extension" do
|
1878
|
-
expect(transaction.ext).to receive(:finish_event).with(
|
1879
|
-
"name",
|
1880
|
-
"title",
|
1881
|
-
"body",
|
1882
|
-
1,
|
1883
|
-
fake_gc_time
|
1884
|
-
).and_call_original
|
1885
|
-
|
1886
|
-
transaction.finish_event(
|
1887
|
-
"name",
|
1888
|
-
"title",
|
1889
|
-
"body",
|
1890
|
-
1
|
1891
|
-
)
|
1892
|
-
end
|
1893
|
-
|
1894
|
-
it "should finish the event in the extension with nil arguments" do
|
1895
|
-
expect(transaction.ext).to receive(:finish_event).with(
|
1896
|
-
"name",
|
1897
|
-
"",
|
1898
|
-
"",
|
1899
|
-
0,
|
1900
|
-
fake_gc_time
|
1901
|
-
).and_call_original
|
1902
|
-
|
1903
|
-
transaction.finish_event(
|
1904
|
-
"name",
|
1905
|
-
nil,
|
1906
|
-
nil,
|
1907
|
-
nil
|
1908
|
-
)
|
1909
|
-
end
|
1910
|
-
|
1911
|
-
context "when transaction is paused" do
|
1912
|
-
it "does not finish the event" do
|
1913
|
-
transaction.pause!
|
1914
|
-
expect(transaction.ext).to_not receive(:finish_event)
|
1915
|
-
|
1916
|
-
transaction.start_event
|
1917
|
-
end
|
1918
|
-
end
|
1919
|
-
end
|
1920
|
-
|
1921
|
-
describe "#record_event" do
|
1922
|
-
let(:transaction) { new_transaction }
|
1923
|
-
let(:fake_gc_time) { 0 }
|
1924
|
-
|
1925
|
-
it "should record the event in the extension" do
|
1926
|
-
expect(transaction.ext).to receive(:record_event).with(
|
1927
|
-
"name",
|
1928
|
-
"title",
|
1929
|
-
"body",
|
1930
|
-
1,
|
1931
|
-
1000,
|
1932
|
-
fake_gc_time
|
1933
|
-
).and_call_original
|
1934
|
-
|
1935
|
-
transaction.record_event(
|
1936
|
-
"name",
|
1937
|
-
"title",
|
1938
|
-
"body",
|
1939
|
-
1000,
|
1940
|
-
1
|
1941
|
-
)
|
1942
|
-
end
|
1943
|
-
|
1944
|
-
it "should finish the event in the extension with nil arguments" do
|
1945
|
-
expect(transaction.ext).to receive(:record_event).with(
|
1946
|
-
"name",
|
1947
|
-
"",
|
1948
|
-
"",
|
1949
|
-
0,
|
1950
|
-
1000,
|
1951
|
-
fake_gc_time
|
1952
|
-
).and_call_original
|
1953
|
-
|
1954
|
-
transaction.record_event(
|
1955
|
-
"name",
|
1956
|
-
nil,
|
1957
|
-
nil,
|
1958
|
-
1000,
|
1959
|
-
nil
|
1960
|
-
)
|
1961
|
-
end
|
1962
|
-
|
1963
|
-
context "when transaction is paused" do
|
1964
|
-
it "does not record the event" do
|
1965
|
-
transaction.pause!
|
1966
|
-
expect(transaction.ext).to_not receive(:record_event)
|
1967
|
-
|
1968
|
-
transaction.record_event(
|
1969
|
-
"name",
|
1970
|
-
nil,
|
1971
|
-
nil,
|
1972
|
-
1000,
|
1973
|
-
nil
|
1974
|
-
)
|
1975
|
-
end
|
1976
|
-
end
|
1977
|
-
end
|
1978
|
-
|
1979
|
-
describe "#instrument" do
|
1980
|
-
it_behaves_like "instrument helper" do
|
1981
|
-
let(:transaction) { new_transaction }
|
1982
|
-
let(:instrumenter) { transaction }
|
1983
|
-
end
|
1984
|
-
end
|
1985
|
-
|
1986
|
-
# private
|
1987
|
-
|
1988
|
-
describe "#cleaned_backtrace" do
|
1989
|
-
let(:transaction) { new_transaction }
|
1990
|
-
subject { transaction.send(:cleaned_backtrace, ["line 1", "line 2"]) }
|
1991
|
-
|
1992
|
-
it "returns the backtrace" do
|
1993
|
-
expect(subject).to eq ["line 1", "line 2"]
|
1994
|
-
end
|
1995
|
-
|
1996
|
-
context "with Rails module but without backtrace_cleaner method" do
|
1997
|
-
it "returns the backtrace uncleaned" do
|
1998
|
-
stub_const("Rails", Module.new)
|
1999
|
-
expect(subject).to eq ["line 1", "line 2"]
|
2000
|
-
end
|
2001
|
-
end
|
2002
|
-
|
2003
|
-
if rails_present?
|
2004
|
-
context "with rails" do
|
2005
|
-
it "cleans the backtrace with the Rails backtrace cleaner" do
|
2006
|
-
::Rails.backtrace_cleaner.add_filter do |line|
|
2007
|
-
line.tr("2", "?")
|
2008
|
-
end
|
2009
|
-
expect(subject).to eq ["line 1", "line ?"]
|
2010
|
-
end
|
2011
|
-
end
|
2012
|
-
end
|
2013
|
-
end
|
2014
|
-
|
2015
|
-
describe "#cleaned_error_message" do
|
2016
|
-
let(:transaction) { new_transaction }
|
2017
|
-
let(:error) { StandardError.new("Error message") }
|
2018
|
-
subject { transaction.send(:cleaned_error_message, error) }
|
2019
|
-
|
2020
|
-
it "returns the error message" do
|
2021
|
-
expect(subject).to eq "Error message"
|
2022
|
-
end
|
2023
|
-
|
2024
|
-
context "with a PG::UniqueViolation" do
|
2025
|
-
before do
|
2026
|
-
stub_const("PG::UniqueViolation", Class.new(StandardError))
|
2027
|
-
end
|
2028
|
-
|
2029
|
-
let(:error) do
|
2030
|
-
PG::UniqueViolation.new(
|
2031
|
-
"ERROR: duplicate key value violates unique constraint " \
|
2032
|
-
"\"index_users_on_email\" DETAIL: Key (email)=(test@test.com) already exists."
|
2033
|
-
)
|
2034
|
-
end
|
2035
|
-
|
2036
|
-
it "returns a sanizited error message" do
|
2037
|
-
expect(subject).to eq "ERROR: duplicate key value violates unique constraint " \
|
2038
|
-
"\"index_users_on_email\" DETAIL: Key (email)=(?) already exists."
|
2039
|
-
end
|
2040
|
-
end
|
2041
|
-
|
2042
|
-
context "with a ActiveRecord::RecordNotUnique" do
|
2043
|
-
before do
|
2044
|
-
stub_const("ActiveRecord::RecordNotUnique", Class.new(StandardError))
|
2045
|
-
end
|
2046
|
-
|
2047
|
-
let(:error) do
|
2048
|
-
ActiveRecord::RecordNotUnique.new(
|
2049
|
-
"PG::UniqueViolation: ERROR: duplicate key value violates unique constraint " \
|
2050
|
-
"\"example_constraint\"\nDETAIL: Key (email)=(foo@example.com) already exists."
|
2051
|
-
)
|
2052
|
-
end
|
2053
|
-
|
2054
|
-
it "returns a sanizited error message" do
|
2055
|
-
expect(subject).to eq \
|
2056
|
-
"PG::UniqueViolation: ERROR: duplicate key value violates unique constraint " \
|
2057
|
-
"\"example_constraint\"\nDETAIL: Key (email)=(?) already exists."
|
2058
|
-
end
|
2059
|
-
end
|
2060
|
-
end
|
2061
|
-
|
2062
|
-
describe ".to_hash / .to_h" do
|
2063
|
-
let(:transaction) { new_transaction }
|
2064
|
-
subject { transaction.to_hash }
|
2065
|
-
|
2066
|
-
context "when extension returns serialized JSON" do
|
2067
|
-
it "parses the result and returns a Hash" do
|
2068
|
-
expect(subject).to include(
|
2069
|
-
"action" => nil,
|
2070
|
-
"error" => nil,
|
2071
|
-
"events" => [],
|
2072
|
-
"id" => kind_of(String),
|
2073
|
-
"metadata" => {},
|
2074
|
-
"namespace" => default_namespace,
|
2075
|
-
"sample_data" => {}
|
2076
|
-
)
|
2077
|
-
end
|
2078
|
-
end
|
2079
|
-
|
2080
|
-
context "when the extension returns invalid serialized JSON" do
|
2081
|
-
before do
|
2082
|
-
expect(transaction.ext).to receive(:to_json).and_return("foo")
|
2083
|
-
end
|
2084
|
-
|
2085
|
-
it "raises a JSON parse error" do
|
2086
|
-
expect { subject }.to raise_error(JSON::ParserError)
|
2087
|
-
end
|
2088
|
-
end
|
2089
|
-
end
|
2090
|
-
|
2091
|
-
describe Appsignal::Transaction::NilTransaction do
|
2092
|
-
subject { Appsignal::Transaction::NilTransaction.new }
|
2093
|
-
|
2094
|
-
it "has method stubs" do
|
2095
|
-
subject.complete
|
2096
|
-
subject.pause!
|
2097
|
-
subject.resume!
|
2098
|
-
subject.paused?
|
2099
|
-
subject.store(:key)
|
2100
|
-
subject.add_tags(:tag => 1)
|
2101
|
-
subject.set_action("action")
|
2102
|
-
subject.set_http_or_background_action
|
2103
|
-
subject.set_queue_start(1)
|
2104
|
-
subject.set_http_or_background_queue_start
|
2105
|
-
subject.set_metadata("key", "value")
|
2106
|
-
subject.set_sample_data("key", "data")
|
2107
|
-
subject._sample
|
2108
|
-
subject.set_error("a")
|
2109
|
-
end
|
2110
|
-
end
|
2111
|
-
end
|