appsignal 3.13.0-java → 4.0.0.beta.2-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +499 -487
- data/CHANGELOG.md +121 -0
- data/Rakefile +31 -7
- data/benchmark.rake +4 -6
- data/build_matrix.yml +45 -39
- data/ext/agent.rb +27 -27
- data/ext/appsignal_extension.c +25 -0
- data/gemfiles/rails-7.2.gemfile +11 -0
- data/lib/appsignal/check_in/cron.rb +2 -15
- data/lib/appsignal/cli/diagnose.rb +37 -28
- data/lib/appsignal/cli/install.rb +5 -1
- data/lib/appsignal/config.rb +57 -119
- data/lib/appsignal/demo.rb +2 -2
- data/lib/appsignal/extension/jruby.rb +14 -0
- data/lib/appsignal/helpers/instrumentation.rb +152 -416
- data/lib/appsignal/helpers/metrics.rb +0 -16
- data/lib/appsignal/hooks/action_cable.rb +8 -8
- data/lib/appsignal/hooks/active_job.rb +2 -2
- data/lib/appsignal/hooks/at_exit.rb +37 -0
- data/lib/appsignal/hooks.rb +1 -16
- data/lib/appsignal/integrations/action_cable.rb +2 -2
- data/lib/appsignal/integrations/capistrano/appsignal.cap +2 -4
- data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +1 -4
- data/lib/appsignal/integrations/delayed_job_plugin.rb +3 -3
- data/lib/appsignal/integrations/que.rb +2 -2
- data/lib/appsignal/integrations/railtie.rb +26 -59
- data/lib/appsignal/integrations/rake.rb +2 -2
- data/lib/appsignal/integrations/resque.rb +2 -2
- data/lib/appsignal/integrations/shoryuken.rb +4 -4
- data/lib/appsignal/integrations/sidekiq.rb +3 -3
- data/lib/appsignal/integrations/webmachine.rb +2 -2
- data/lib/appsignal/loaders.rb +1 -1
- data/lib/appsignal/probes.rb +0 -9
- data/lib/appsignal/rack/abstract_middleware.rb +4 -26
- data/lib/appsignal/rack/event_handler.rb +4 -4
- data/lib/appsignal/rack/rails_instrumentation.rb +1 -1
- data/lib/appsignal/rack.rb +0 -25
- data/lib/appsignal/sample_data.rb +108 -0
- data/lib/appsignal/transaction.rb +241 -359
- data/lib/appsignal/utils/rails_helper.rb +4 -0
- data/lib/appsignal/version.rb +1 -1
- data/lib/appsignal.rb +19 -71
- data/spec/lib/appsignal/auth_check_spec.rb +1 -1
- data/spec/lib/appsignal/capistrano2_spec.rb +1 -1
- data/spec/lib/appsignal/capistrano3_spec.rb +53 -13
- data/spec/lib/appsignal/check_in_spec.rb +1 -207
- data/spec/lib/appsignal/cli/demo_spec.rb +7 -27
- data/spec/lib/appsignal/cli/diagnose_spec.rb +145 -110
- data/spec/lib/appsignal/config_spec.rb +304 -379
- data/spec/lib/appsignal/extension_install_failure_spec.rb +5 -1
- data/spec/lib/appsignal/extension_spec.rb +5 -1
- data/spec/lib/appsignal/hooks/active_support_notifications/instrument_shared_examples.rb +1 -1
- data/spec/lib/appsignal/hooks/active_support_notifications/start_finish_shared_examples.rb +1 -2
- data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +1 -0
- data/spec/lib/appsignal/hooks/activejob_spec.rb +7 -12
- data/spec/lib/appsignal/hooks/at_exit_spec.rb +72 -0
- data/spec/lib/appsignal/hooks/gvl_spec.rb +10 -5
- data/spec/lib/appsignal/hooks/http_spec.rb +3 -3
- data/spec/lib/appsignal/hooks/net_http_spec.rb +3 -3
- data/spec/lib/appsignal/hooks/rake_spec.rb +6 -9
- data/spec/lib/appsignal/hooks/redis_client_spec.rb +5 -10
- data/spec/lib/appsignal/hooks/redis_spec.rb +4 -7
- data/spec/lib/appsignal/hooks/resque_spec.rb +3 -5
- data/spec/lib/appsignal/hooks_spec.rb +0 -41
- data/spec/lib/appsignal/integrations/data_mapper_spec.rb +29 -20
- data/spec/lib/appsignal/integrations/delayed_job_plugin_spec.rb +4 -9
- data/spec/lib/appsignal/integrations/railtie_spec.rb +179 -157
- data/spec/lib/appsignal/integrations/shoryuken_spec.rb +3 -5
- data/spec/lib/appsignal/integrations/sidekiq_spec.rb +48 -62
- data/spec/lib/appsignal/loaders/hanami_spec.rb +6 -9
- data/spec/lib/appsignal/loaders/padrino_spec.rb +6 -10
- data/spec/lib/appsignal/loaders/sinatra_spec.rb +6 -9
- data/spec/lib/appsignal/loaders_spec.rb +8 -1
- data/spec/lib/appsignal/marker_spec.rb +1 -1
- data/spec/lib/appsignal/probes_spec.rb +4 -83
- data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +4 -63
- data/spec/lib/appsignal/rack/event_handler_spec.rb +18 -15
- data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +3 -11
- data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +4 -5
- data/spec/lib/appsignal/sample_data_spec.rb +213 -0
- data/spec/lib/appsignal/transaction_spec.rb +817 -1046
- data/spec/lib/appsignal/transmitter_spec.rb +6 -8
- data/spec/lib/appsignal_spec.rb +311 -643
- data/spec/spec_helper.rb +1 -3
- data/spec/support/fixtures/projects/valid/config/appsignal.yml +4 -7
- data/spec/support/fixtures/projects/valid_with_rails_app/config/application.rb +16 -0
- data/spec/support/fixtures/projects/valid_with_rails_app/config/appsignal.yml +56 -0
- data/spec/support/fixtures/projects/valid_with_rails_app/config/environment.rb +5 -0
- data/spec/support/helpers/api_request_helper.rb +3 -2
- data/spec/support/helpers/config_helpers.rb +41 -11
- data/spec/support/helpers/dependency_helper.rb +8 -0
- data/spec/support/helpers/log_helpers.rb +1 -0
- data/spec/support/helpers/rails_helper.rb +6 -6
- data/spec/support/helpers/transaction_helpers.rb +2 -24
- data/spec/support/matchers/transaction.rb +3 -3
- data/spec/support/mocks/appsignal_mock.rb +3 -3
- data/spec/support/mocks/mock_probe.rb +2 -0
- data/spec/support/testing.rb +2 -2
- metadata +12 -22
- data/gemfiles/que_beta.gemfile +0 -5
- data/lib/appsignal/helpers/heartbeat.rb +0 -20
- data/lib/appsignal/integrations/grape.rb +0 -35
- data/lib/appsignal/integrations/hanami.rb +0 -13
- data/lib/appsignal/integrations/padrino.rb +0 -13
- data/lib/appsignal/integrations/sinatra.rb +0 -13
- data/lib/appsignal/rack/generic_instrumentation.rb +0 -22
- data/lib/appsignal/rack/streaming_listener.rb +0 -28
- data/spec/lib/appsignal/integrations/grape_spec.rb +0 -36
- data/spec/lib/appsignal/integrations/hanami_spec.rb +0 -17
- data/spec/lib/appsignal/integrations/padrino_spec.rb +0 -15
- data/spec/lib/appsignal/integrations/sinatra_spec.rb +0 -15
- data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +0 -81
- data/spec/lib/appsignal/rack/streaming_listener_spec.rb +0 -69
- data/spec/support/fixtures/projects/valid/config/environments/development.rb +0 -0
- data/spec/support/fixtures/projects/valid/config/environments/production.rb +0 -0
- data/spec/support/fixtures/projects/valid/config/environments/test.rb +0 -0
- data/spec/support/rails/my_app.rb +0 -6
- /data/spec/support/fixtures/projects/{valid/config/application.rb → valid_with_rails_app/log/.gitkeep} +0 -0
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
describe Appsignal::Transaction do
|
|
2
|
+
let(:options) { {} }
|
|
2
3
|
let(:time) { Time.at(fixed_time) }
|
|
3
4
|
|
|
4
5
|
before do
|
|
5
|
-
start_agent
|
|
6
|
+
start_agent(:options => options)
|
|
6
7
|
Timecop.freeze(time)
|
|
7
8
|
end
|
|
8
9
|
after { Timecop.return }
|
|
@@ -32,86 +33,13 @@ describe Appsignal::Transaction do
|
|
|
32
33
|
transaction = create_transaction
|
|
33
34
|
expect(transaction).to eq current_transaction
|
|
34
35
|
end
|
|
36
|
+
end
|
|
35
37
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
transaction_id = "mock-id"
|
|
39
|
-
namespace = "my_namespace"
|
|
40
|
-
transaction = legacy_create_transaction(
|
|
41
|
-
:id => transaction_id,
|
|
42
|
-
:namespace => namespace
|
|
43
|
-
)
|
|
44
|
-
expect(transaction).to be_a(Appsignal::Transaction)
|
|
45
|
-
|
|
46
|
-
expect(transaction).to have_id(transaction_id)
|
|
47
|
-
expect(transaction.transaction_id).to eq(transaction_id)
|
|
48
|
-
|
|
49
|
-
expect(transaction).to have_namespace(namespace)
|
|
50
|
-
expect(transaction.namespace).to eq(namespace)
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
it "logs deprecation warnings" do
|
|
54
|
-
logs =
|
|
55
|
-
capture_logs do
|
|
56
|
-
legacy_create_transaction(
|
|
57
|
-
:id => "mock-id",
|
|
58
|
-
:namespace => "my_namespace",
|
|
59
|
-
:request => Appsignal::Transaction::InternalGenericRequest.new({}),
|
|
60
|
-
:options => { :force => true }
|
|
61
|
-
)
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
expect(logs).to contains_log(
|
|
65
|
-
:warn,
|
|
66
|
-
"Appsignal::Transaction.create: " \
|
|
67
|
-
"A new Transaction is created using the transaction ID argument."
|
|
68
|
-
)
|
|
69
|
-
expect(logs).to contains_log(
|
|
70
|
-
:warn,
|
|
71
|
-
"Appsignal::Transaction.create: " \
|
|
72
|
-
"A Transaction is created using the namespace argument."
|
|
73
|
-
)
|
|
74
|
-
expect(logs).to contains_log(
|
|
75
|
-
:warn,
|
|
76
|
-
"Appsignal::Transaction.create: " \
|
|
77
|
-
"A Transaction is created using the request argument."
|
|
78
|
-
)
|
|
79
|
-
expect(logs).to contains_log(
|
|
80
|
-
:warn,
|
|
81
|
-
"Appsignal::Transaction.create: " \
|
|
82
|
-
"A Transaction is created using the `:force => true` option argument. "
|
|
83
|
-
)
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
it "prints deprecation warnings" do
|
|
87
|
-
err_stream = std_stream
|
|
88
|
-
capture_std_streams(std_stream, err_stream) do
|
|
89
|
-
legacy_create_transaction(
|
|
90
|
-
:id => "mock-id",
|
|
91
|
-
:namespace => "my_namespace",
|
|
92
|
-
:request => Appsignal::Transaction::InternalGenericRequest.new({}),
|
|
93
|
-
:options => { :force => true }
|
|
94
|
-
)
|
|
95
|
-
end
|
|
38
|
+
context "when an explicit extension transaction is passed in the initialiser" do
|
|
39
|
+
let(:ext) { "some_ext" }
|
|
96
40
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
"appsignal WARNING: Appsignal::Transaction.create: " \
|
|
100
|
-
"A new Transaction is created using the transaction ID argument."
|
|
101
|
-
)
|
|
102
|
-
expect(stderr).to include(
|
|
103
|
-
"appsignal WARNING: Appsignal::Transaction.create: " \
|
|
104
|
-
"A Transaction is created using the namespace argument."
|
|
105
|
-
)
|
|
106
|
-
expect(stderr).to include(
|
|
107
|
-
"appsignal WARNING: Appsignal::Transaction.create: " \
|
|
108
|
-
"A Transaction is created using the request argument."
|
|
109
|
-
)
|
|
110
|
-
expect(stderr).to include(
|
|
111
|
-
"appsignal WARNING: Appsignal::Transaction.create: " \
|
|
112
|
-
"A Transaction is created using the `:force => true` option argument. "
|
|
113
|
-
)
|
|
114
|
-
end
|
|
41
|
+
it "assigns the extension transaction to the transaction" do
|
|
42
|
+
expect(new_transaction(:ext => ext).ext).to be(ext)
|
|
115
43
|
end
|
|
116
44
|
end
|
|
117
45
|
|
|
@@ -137,28 +65,9 @@ describe Appsignal::Transaction do
|
|
|
137
65
|
logs = capture_logs { create_transaction }
|
|
138
66
|
|
|
139
67
|
expect(logs).to contains_log :warn,
|
|
140
|
-
"Trying to start new transaction
|
|
141
|
-
"
|
|
142
|
-
"
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
context "with option :force => true" do
|
|
146
|
-
it "returns the newly created (and current) transaction" do
|
|
147
|
-
original_transaction = create_transaction
|
|
148
|
-
|
|
149
|
-
expect(original_transaction).to be_a(Appsignal::Transaction)
|
|
150
|
-
expect(current_transaction).to have_id("transaction_id_1")
|
|
151
|
-
|
|
152
|
-
new_transaction = legacy_create_transaction(
|
|
153
|
-
:id => "transaction_id_2",
|
|
154
|
-
:options => { :force => true }
|
|
155
|
-
)
|
|
156
|
-
|
|
157
|
-
expect(new_transaction).to be_a(Appsignal::Transaction)
|
|
158
|
-
expect(new_transaction).to_not eq(original_transaction)
|
|
159
|
-
expect(new_transaction).to have_id("transaction_id_2")
|
|
160
|
-
expect(current_transaction).to eq(new_transaction)
|
|
161
|
-
end
|
|
68
|
+
"Trying to start new transaction, but a transaction with id " \
|
|
69
|
+
"'transaction_id_1' is already running. " \
|
|
70
|
+
"Using transaction 'transaction_id_1'."
|
|
162
71
|
end
|
|
163
72
|
end
|
|
164
73
|
end
|
|
@@ -252,7 +161,7 @@ describe Appsignal::Transaction do
|
|
|
252
161
|
|
|
253
162
|
context "when transaction is being sampled" do
|
|
254
163
|
it "samples data" do
|
|
255
|
-
transaction.
|
|
164
|
+
transaction.add_tags(:foo => "bar")
|
|
256
165
|
keep_transactions { transaction.complete }
|
|
257
166
|
expect(transaction).to include_tags("foo" => "bar")
|
|
258
167
|
end
|
|
@@ -299,6 +208,306 @@ describe Appsignal::Transaction do
|
|
|
299
208
|
end
|
|
300
209
|
end
|
|
301
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 "sets is_duplicate set to true on the duplicate transaction" do
|
|
342
|
+
original_transaction, duplicate_transaction = created_transactions
|
|
343
|
+
|
|
344
|
+
expect(original_transaction.is_duplicate).to be(false)
|
|
345
|
+
expect(duplicate_transaction.is_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
|
|
302
511
|
end
|
|
303
512
|
|
|
304
513
|
context "pausing" do
|
|
@@ -363,49 +572,9 @@ describe Appsignal::Transaction do
|
|
|
363
572
|
end
|
|
364
573
|
end
|
|
365
574
|
|
|
366
|
-
context "transaction id" do
|
|
367
|
-
before do
|
|
368
|
-
allow(SecureRandom).to receive(:uuid).and_return("mock_transaction_id")
|
|
369
|
-
end
|
|
370
|
-
|
|
371
|
-
it "sets the transaction id" do
|
|
372
|
-
expect(transaction).to have_id("mock_transaction_id")
|
|
373
|
-
end
|
|
374
|
-
end
|
|
375
|
-
|
|
376
575
|
it "sets the namespace to http_request" do
|
|
377
576
|
expect(transaction.namespace).to eq "http_request"
|
|
378
577
|
end
|
|
379
|
-
|
|
380
|
-
it "sets the request" do
|
|
381
|
-
expect(transaction.request).to be_a(Appsignal::Transaction::InternalGenericRequest)
|
|
382
|
-
end
|
|
383
|
-
|
|
384
|
-
it "sets the request not to paused" do
|
|
385
|
-
expect(transaction.paused?).to be_falsy
|
|
386
|
-
end
|
|
387
|
-
|
|
388
|
-
it "sets no tags by default" do
|
|
389
|
-
expect(transaction.tags).to be_empty
|
|
390
|
-
end
|
|
391
|
-
|
|
392
|
-
describe "#options" do
|
|
393
|
-
let(:options) { transaction.options }
|
|
394
|
-
|
|
395
|
-
it "sets the default :params_method" do
|
|
396
|
-
expect(options[:params_method]).to eq :params
|
|
397
|
-
end
|
|
398
|
-
|
|
399
|
-
context "with overridden options" do
|
|
400
|
-
let(:transaction) do
|
|
401
|
-
legacy_new_transaction(:options => { :params_method => :filtered_params })
|
|
402
|
-
end
|
|
403
|
-
|
|
404
|
-
it "sets the overridden :params_method" do
|
|
405
|
-
expect(options[:params_method]).to eq :filtered_params
|
|
406
|
-
end
|
|
407
|
-
end
|
|
408
|
-
end
|
|
409
578
|
end
|
|
410
579
|
|
|
411
580
|
describe "#store" do
|
|
@@ -423,209 +592,242 @@ describe Appsignal::Transaction do
|
|
|
423
592
|
end
|
|
424
593
|
end
|
|
425
594
|
|
|
426
|
-
describe "#
|
|
595
|
+
describe "#add_params" do
|
|
427
596
|
let(:transaction) { new_transaction }
|
|
428
|
-
let(:params) { transaction.params }
|
|
429
597
|
|
|
430
|
-
|
|
431
|
-
|
|
598
|
+
it "has a #set_params alias" do
|
|
599
|
+
expect(transaction.method(:add_params)).to eq(transaction.method(:set_params))
|
|
600
|
+
end
|
|
601
|
+
|
|
602
|
+
it "adds the params to the transaction" do
|
|
603
|
+
params = { "key" => "value" }
|
|
604
|
+
transaction.add_params(params)
|
|
432
605
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
606
|
+
transaction._sample
|
|
607
|
+
expect(transaction).to include_params(params)
|
|
608
|
+
end
|
|
436
609
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
610
|
+
it "merges the params on the transaction" do
|
|
611
|
+
transaction.add_params("abc" => "value")
|
|
612
|
+
transaction.add_params("def" => "value")
|
|
613
|
+
transaction.add_params { { "xyz" => "value" } }
|
|
440
614
|
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
615
|
+
transaction._sample
|
|
616
|
+
expect(transaction).to include_params(
|
|
617
|
+
"abc" => "value",
|
|
618
|
+
"def" => "value",
|
|
619
|
+
"xyz" => "value"
|
|
620
|
+
)
|
|
444
621
|
end
|
|
445
622
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
:request => legacy_request(
|
|
450
|
-
:params => {
|
|
451
|
-
"action" => "show",
|
|
452
|
-
"controller" => "blog_posts",
|
|
453
|
-
"id" => "1"
|
|
623
|
+
it "adds the params to the transaction with a block" do
|
|
624
|
+
params = { "key" => "value" }
|
|
625
|
+
transaction.add_params { params }
|
|
454
626
|
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
end
|
|
627
|
+
transaction._sample
|
|
628
|
+
expect(transaction).to include_params(params)
|
|
629
|
+
end
|
|
459
630
|
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
631
|
+
it "adds the params block value when both an argument and block are given" do
|
|
632
|
+
arg_params = { "argument" => "value" }
|
|
633
|
+
block_params = { "block" => "value" }
|
|
634
|
+
transaction.add_params(arg_params) { block_params }
|
|
635
|
+
|
|
636
|
+
transaction._sample
|
|
637
|
+
expect(transaction).to include_params(block_params)
|
|
467
638
|
end
|
|
468
|
-
end
|
|
469
639
|
|
|
470
|
-
|
|
471
|
-
|
|
640
|
+
it "logs an error if an error occurred storing the params" do
|
|
641
|
+
transaction.add_params { raise "uh oh" }
|
|
642
|
+
|
|
643
|
+
logs = capture_logs { transaction._sample }
|
|
644
|
+
expect(logs).to contains_log(
|
|
645
|
+
:error,
|
|
646
|
+
"Exception while fetching params: RuntimeError: uh oh"
|
|
647
|
+
)
|
|
648
|
+
end
|
|
472
649
|
|
|
473
|
-
it "
|
|
474
|
-
params = { "
|
|
475
|
-
|
|
650
|
+
it "does not update the params on the transaction if the given value is nil" do
|
|
651
|
+
params = { "key" => "value" }
|
|
652
|
+
transaction.add_params(params)
|
|
653
|
+
transaction.add_params(nil)
|
|
476
654
|
|
|
477
655
|
transaction._sample
|
|
478
|
-
expect(transaction.params).to eq(params)
|
|
479
656
|
expect(transaction).to include_params(params)
|
|
480
657
|
end
|
|
481
658
|
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
capture_logs do
|
|
485
|
-
transaction.params = { "foo" => "bar" }
|
|
486
|
-
end
|
|
659
|
+
context "with AppSignal filtering" do
|
|
660
|
+
let(:options) { { :filter_parameters => %w[foo] } }
|
|
487
661
|
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
662
|
+
it "returns sanitized custom params" do
|
|
663
|
+
transaction.add_params("foo" => "value", "baz" => "bat")
|
|
664
|
+
|
|
665
|
+
transaction._sample
|
|
666
|
+
expect(transaction).to include_params("foo" => "[FILTERED]", "baz" => "bat")
|
|
667
|
+
end
|
|
493
668
|
end
|
|
494
669
|
end
|
|
495
670
|
|
|
496
|
-
describe "#
|
|
671
|
+
describe "#add_params_if_nil" do
|
|
497
672
|
let(:transaction) { new_transaction }
|
|
498
673
|
|
|
499
|
-
|
|
500
|
-
|
|
674
|
+
it "has a #set_params_if_nil alias" do
|
|
675
|
+
expect(transaction.method(:add_params_if_nil)).to eq(transaction.method(:set_params_if_nil))
|
|
676
|
+
end
|
|
677
|
+
|
|
678
|
+
context "when the params are not set" do
|
|
679
|
+
it "adds the params to the transaction" do
|
|
501
680
|
params = { "key" => "value" }
|
|
502
|
-
transaction.
|
|
681
|
+
transaction.add_params_if_nil(params)
|
|
503
682
|
|
|
504
683
|
transaction._sample
|
|
505
|
-
expect(transaction.params).to eq(params)
|
|
506
684
|
expect(transaction).to include_params(params)
|
|
507
685
|
end
|
|
508
686
|
|
|
509
|
-
it "
|
|
687
|
+
it "adds the params to the transaction with a block" do
|
|
510
688
|
params = { "key" => "value" }
|
|
511
|
-
transaction.
|
|
689
|
+
transaction.add_params_if_nil { params }
|
|
512
690
|
|
|
513
691
|
transaction._sample
|
|
514
|
-
expect(transaction.params).to eq(params)
|
|
515
692
|
expect(transaction).to include_params(params)
|
|
516
693
|
end
|
|
517
694
|
|
|
518
|
-
it "
|
|
695
|
+
it "adds the params block value when both an argument and block are given" do
|
|
519
696
|
arg_params = { "argument" => "value" }
|
|
520
697
|
block_params = { "block" => "value" }
|
|
521
|
-
transaction.
|
|
698
|
+
transaction.add_params_if_nil(arg_params) { block_params }
|
|
522
699
|
|
|
523
700
|
transaction._sample
|
|
524
|
-
expect(transaction
|
|
525
|
-
expect(transaction).to include_params(arg_params)
|
|
526
|
-
end
|
|
527
|
-
|
|
528
|
-
it "logs an error if an error occurred storing the params" do
|
|
529
|
-
transaction.set_params { raise "uh oh" }
|
|
530
|
-
|
|
531
|
-
logs = capture_logs { transaction._sample }
|
|
532
|
-
expect(logs).to contains_log(
|
|
533
|
-
:error,
|
|
534
|
-
"Exception while fetching params: RuntimeError: uh oh"
|
|
535
|
-
)
|
|
701
|
+
expect(transaction).to include_params(block_params)
|
|
536
702
|
end
|
|
537
|
-
end
|
|
538
703
|
|
|
539
|
-
|
|
540
|
-
it "does not update the params on the transaction" do
|
|
704
|
+
it "does not update the params on the transaction if the given value is nil" do
|
|
541
705
|
params = { "key" => "value" }
|
|
542
|
-
transaction.
|
|
543
|
-
transaction.
|
|
706
|
+
transaction.add_params(params)
|
|
707
|
+
transaction.add_params_if_nil(nil)
|
|
544
708
|
|
|
545
709
|
transaction._sample
|
|
546
|
-
expect(transaction.params).to eq(params)
|
|
547
710
|
expect(transaction).to include_params(params)
|
|
548
711
|
end
|
|
549
712
|
end
|
|
550
|
-
end
|
|
551
|
-
|
|
552
|
-
describe "#set_params_if_nil" do
|
|
553
|
-
let(:transaction) { new_transaction }
|
|
554
713
|
|
|
555
|
-
context "when the params are
|
|
556
|
-
it "
|
|
714
|
+
context "when the params are set" do
|
|
715
|
+
it "does not update the params on the transaction" do
|
|
716
|
+
preset_params = { "other" => "params" }
|
|
557
717
|
params = { "key" => "value" }
|
|
558
|
-
transaction.
|
|
718
|
+
transaction.add_params(preset_params)
|
|
719
|
+
transaction.add_params_if_nil(params)
|
|
559
720
|
|
|
560
721
|
transaction._sample
|
|
561
|
-
expect(transaction
|
|
562
|
-
expect(transaction).to include_params(params)
|
|
722
|
+
expect(transaction).to include_params(preset_params)
|
|
563
723
|
end
|
|
564
724
|
|
|
565
|
-
it "
|
|
725
|
+
it "does not update the params with a block on the transaction" do
|
|
726
|
+
preset_params = { "other" => "params" }
|
|
566
727
|
params = { "key" => "value" }
|
|
567
|
-
transaction.
|
|
728
|
+
transaction.add_params(preset_params)
|
|
729
|
+
transaction.add_params_if_nil { params }
|
|
568
730
|
|
|
569
731
|
transaction._sample
|
|
570
|
-
expect(transaction
|
|
571
|
-
expect(transaction).to include_params(params)
|
|
732
|
+
expect(transaction).to include_params(preset_params)
|
|
572
733
|
end
|
|
734
|
+
end
|
|
573
735
|
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
transaction.
|
|
736
|
+
context "when the params were set as an empty value" do
|
|
737
|
+
it "does not set params on the transaction" do
|
|
738
|
+
transaction.add_params("key1" => "value")
|
|
739
|
+
transaction.set_empty_params!
|
|
740
|
+
transaction.add_params_if_nil("key2" => "value")
|
|
578
741
|
|
|
579
742
|
transaction._sample
|
|
580
|
-
expect(transaction
|
|
581
|
-
expect(transaction).to include_params(arg_params)
|
|
743
|
+
expect(transaction).to_not include_params
|
|
582
744
|
end
|
|
745
|
+
end
|
|
746
|
+
end
|
|
583
747
|
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
params = { "key" => "value" }
|
|
587
|
-
transaction.set_params(params)
|
|
588
|
-
transaction.set_params_if_nil(nil)
|
|
748
|
+
describe "#add_session_data" do
|
|
749
|
+
let(:transaction) { new_transaction }
|
|
589
750
|
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
expect(transaction).to include_params(params)
|
|
593
|
-
end
|
|
594
|
-
end
|
|
751
|
+
it "has a #set_session_data alias" do
|
|
752
|
+
expect(transaction.method(:add_session_data)).to eq(transaction.method(:set_session_data))
|
|
595
753
|
end
|
|
596
754
|
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
params = { "key" => "value" }
|
|
601
|
-
transaction.set_params(preset_params)
|
|
602
|
-
transaction.set_params_if_nil(params)
|
|
755
|
+
it "adds the session data to the transaction" do
|
|
756
|
+
data = { "key" => "value" }
|
|
757
|
+
transaction.add_session_data(data)
|
|
603
758
|
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
end
|
|
759
|
+
transaction._sample
|
|
760
|
+
expect(transaction).to include_session_data(data)
|
|
761
|
+
end
|
|
608
762
|
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
763
|
+
it "merges the session data on the transaction" do
|
|
764
|
+
transaction.add_session_data("abc" => "value")
|
|
765
|
+
transaction.add_session_data("def" => "value")
|
|
766
|
+
transaction.add_session_data { { "xyz" => "value" } }
|
|
767
|
+
|
|
768
|
+
transaction._sample
|
|
769
|
+
expect(transaction).to include_session_data(
|
|
770
|
+
"abc" => "value",
|
|
771
|
+
"def" => "value",
|
|
772
|
+
"xyz" => "value"
|
|
773
|
+
)
|
|
774
|
+
end
|
|
775
|
+
|
|
776
|
+
it "adds the session data to the transaction with a block" do
|
|
777
|
+
data = { "key" => "value" }
|
|
778
|
+
transaction.add_session_data { data }
|
|
779
|
+
|
|
780
|
+
transaction._sample
|
|
781
|
+
expect(transaction).to include_session_data(data)
|
|
782
|
+
end
|
|
783
|
+
|
|
784
|
+
it "adds the session data block value when both an argument and block are given" do
|
|
785
|
+
arg_data = { "argument" => "value" }
|
|
786
|
+
block_data = { "block" => "value" }
|
|
787
|
+
transaction.add_session_data(arg_data) { block_data }
|
|
788
|
+
|
|
789
|
+
transaction._sample
|
|
790
|
+
expect(transaction).to include_session_data(block_data)
|
|
791
|
+
end
|
|
792
|
+
|
|
793
|
+
it "logs an error if an error occurred storing the session data" do
|
|
794
|
+
transaction.add_session_data { raise "uh oh" }
|
|
795
|
+
|
|
796
|
+
logs = capture_logs { transaction._sample }
|
|
797
|
+
expect(logs).to contains_log(
|
|
798
|
+
:error,
|
|
799
|
+
"Exception while fetching session data: RuntimeError: uh oh"
|
|
800
|
+
)
|
|
801
|
+
end
|
|
802
|
+
|
|
803
|
+
it "does not update the session data on the transaction if the given value is nil" do
|
|
804
|
+
data = { "key" => "value" }
|
|
805
|
+
transaction.add_session_data(data)
|
|
806
|
+
transaction.add_session_data(nil)
|
|
807
|
+
|
|
808
|
+
transaction._sample
|
|
809
|
+
expect(transaction).to include_session_data(data)
|
|
810
|
+
end
|
|
811
|
+
|
|
812
|
+
context "with filter_session_data" do
|
|
813
|
+
let(:options) { { :filter_session_data => ["filtered_key"] } }
|
|
814
|
+
|
|
815
|
+
it "does not include filtered out session data" do
|
|
816
|
+
transaction.add_session_data("data" => "value1", "filtered_key" => "filtered_value")
|
|
614
817
|
|
|
615
818
|
transaction._sample
|
|
616
|
-
expect(transaction
|
|
617
|
-
expect(transaction).to include_params(preset_params)
|
|
819
|
+
expect(transaction).to include_session_data("data" => "value1")
|
|
618
820
|
end
|
|
619
821
|
end
|
|
620
822
|
end
|
|
621
823
|
|
|
622
|
-
describe "#
|
|
824
|
+
describe "#add_session_data_if_nil" do
|
|
623
825
|
let(:transaction) { new_transaction }
|
|
624
826
|
|
|
625
|
-
context "when the session data is set" do
|
|
626
|
-
it "
|
|
827
|
+
context "when the session data is not set" do
|
|
828
|
+
it "sets the session data on the transaction" do
|
|
627
829
|
data = { "key" => "value" }
|
|
628
|
-
transaction.
|
|
830
|
+
transaction.add_session_data_if_nil(data)
|
|
629
831
|
|
|
630
832
|
transaction._sample
|
|
631
833
|
expect(transaction).to include_session_data(data)
|
|
@@ -633,109 +835,47 @@ describe Appsignal::Transaction do
|
|
|
633
835
|
|
|
634
836
|
it "updates the session data on the transaction with a block" do
|
|
635
837
|
data = { "key" => "value" }
|
|
636
|
-
transaction.
|
|
838
|
+
transaction.add_session_data_if_nil { data }
|
|
637
839
|
|
|
638
840
|
transaction._sample
|
|
639
841
|
expect(transaction).to include_session_data(data)
|
|
640
842
|
end
|
|
641
843
|
|
|
642
|
-
it "updates with the session data
|
|
844
|
+
it "updates with the session data block when both an argument and block are given" do
|
|
643
845
|
arg_data = { "argument" => "value" }
|
|
644
846
|
block_data = { "block" => "value" }
|
|
645
|
-
transaction.
|
|
847
|
+
transaction.add_session_data_if_nil(arg_data) { block_data }
|
|
646
848
|
|
|
647
849
|
transaction._sample
|
|
648
|
-
expect(transaction).to include_session_data(
|
|
850
|
+
expect(transaction).to include_session_data(block_data)
|
|
649
851
|
end
|
|
650
852
|
|
|
651
|
-
it "does not
|
|
652
|
-
|
|
653
|
-
transaction.
|
|
853
|
+
it "does not update the session data on the transaction if the given value is nil" do
|
|
854
|
+
data = { "key" => "value" }
|
|
855
|
+
transaction.add_session_data(data)
|
|
856
|
+
transaction.add_session_data_if_nil(nil)
|
|
654
857
|
|
|
655
858
|
transaction._sample
|
|
656
|
-
expect(transaction).to include_session_data(
|
|
657
|
-
end
|
|
658
|
-
|
|
659
|
-
it "logs an error if an error occurred storing the session data" do
|
|
660
|
-
transaction.set_session_data { raise "uh oh" }
|
|
661
|
-
|
|
662
|
-
logs = capture_logs { transaction._sample }
|
|
663
|
-
expect(logs).to contains_log(
|
|
664
|
-
:error,
|
|
665
|
-
"Exception while fetching session data: RuntimeError: uh oh"
|
|
666
|
-
)
|
|
859
|
+
expect(transaction).to include_session_data(data)
|
|
667
860
|
end
|
|
668
861
|
end
|
|
669
862
|
|
|
670
|
-
context "when the
|
|
863
|
+
context "when the session data are set" do
|
|
671
864
|
it "does not update the session data on the transaction" do
|
|
672
|
-
data = { "key" => "value" }
|
|
673
|
-
transaction.set_session_data(data)
|
|
674
|
-
transaction.set_session_data(nil)
|
|
675
|
-
|
|
676
|
-
transaction._sample
|
|
677
|
-
expect(transaction).to include_session_data(data)
|
|
678
|
-
end
|
|
679
|
-
end
|
|
680
|
-
end
|
|
681
|
-
|
|
682
|
-
describe "#set_session_data_if_nil" do
|
|
683
|
-
let(:transaction) { new_transaction }
|
|
684
|
-
|
|
685
|
-
context "when the params are not set" do
|
|
686
|
-
it "sets the params on the transaction" do
|
|
687
|
-
data = { "key" => "value" }
|
|
688
|
-
transaction.set_session_data_if_nil(data)
|
|
689
|
-
|
|
690
|
-
transaction._sample
|
|
691
|
-
expect(transaction).to include_session_data(data)
|
|
692
|
-
end
|
|
693
|
-
|
|
694
|
-
it "updates the params on the transaction with a block" do
|
|
695
|
-
data = { "key" => "value" }
|
|
696
|
-
transaction.set_session_data_if_nil { data }
|
|
697
|
-
|
|
698
|
-
transaction._sample
|
|
699
|
-
expect(transaction).to include_session_data(data)
|
|
700
|
-
end
|
|
701
|
-
|
|
702
|
-
it "updates with the params argument when both an argument and block are given" do
|
|
703
|
-
arg_data = { "argument" => "value" }
|
|
704
|
-
block_data = { "block" => "value" }
|
|
705
|
-
transaction.set_session_data_if_nil(arg_data) { block_data }
|
|
706
|
-
|
|
707
|
-
transaction._sample
|
|
708
|
-
expect(transaction).to include_session_data(arg_data)
|
|
709
|
-
end
|
|
710
|
-
|
|
711
|
-
context "when the given params is nil" do
|
|
712
|
-
it "does not update the params on the transaction" do
|
|
713
|
-
data = { "key" => "value" }
|
|
714
|
-
transaction.set_session_data(data)
|
|
715
|
-
transaction.set_session_data_if_nil(nil)
|
|
716
|
-
|
|
717
|
-
transaction._sample
|
|
718
|
-
expect(transaction).to include_session_data(data)
|
|
719
|
-
end
|
|
720
|
-
end
|
|
721
|
-
end
|
|
722
|
-
|
|
723
|
-
context "when the params are set" do
|
|
724
|
-
it "does not update the params on the transaction" do
|
|
725
865
|
preset_data = { "other" => "data" }
|
|
726
866
|
data = { "key" => "value" }
|
|
727
|
-
transaction.
|
|
728
|
-
transaction.
|
|
867
|
+
transaction.add_session_data(preset_data)
|
|
868
|
+
transaction.add_session_data_if_nil(data)
|
|
729
869
|
|
|
730
870
|
transaction._sample
|
|
731
871
|
expect(transaction).to include_session_data(preset_data)
|
|
732
872
|
end
|
|
733
873
|
|
|
734
|
-
it "does not update the
|
|
874
|
+
it "does not update the session data with a block on the transaction" do
|
|
735
875
|
preset_data = { "other" => "data" }
|
|
736
876
|
data = { "key" => "value" }
|
|
737
|
-
transaction.
|
|
738
|
-
transaction.
|
|
877
|
+
transaction.add_session_data(preset_data)
|
|
878
|
+
transaction.add_session_data_if_nil { data }
|
|
739
879
|
|
|
740
880
|
transaction._sample
|
|
741
881
|
expect(transaction).to include_session_data(preset_data)
|
|
@@ -743,123 +883,141 @@ describe Appsignal::Transaction do
|
|
|
743
883
|
end
|
|
744
884
|
end
|
|
745
885
|
|
|
746
|
-
describe "#
|
|
886
|
+
describe "#add_headers" do
|
|
747
887
|
let(:transaction) { new_transaction }
|
|
748
888
|
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
transaction.set_headers(headers)
|
|
889
|
+
it "has a #set_headers alias" do
|
|
890
|
+
expect(transaction.method(:add_headers)).to eq(transaction.method(:set_headers))
|
|
891
|
+
end
|
|
753
892
|
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
893
|
+
it "adds the headers to the transaction" do
|
|
894
|
+
headers = { "PATH_INFO" => "value" }
|
|
895
|
+
transaction.add_headers(headers)
|
|
757
896
|
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
897
|
+
transaction._sample
|
|
898
|
+
expect(transaction).to include_environment(headers)
|
|
899
|
+
end
|
|
761
900
|
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
901
|
+
it "merges the headers on the transaction" do
|
|
902
|
+
transaction.add_headers("PATH_INFO" => "value")
|
|
903
|
+
transaction.add_headers("REQUEST_METHOD" => "value")
|
|
904
|
+
transaction.add_headers { { "HTTP_ACCEPT" => "value" } }
|
|
765
905
|
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
906
|
+
transaction._sample
|
|
907
|
+
expect(transaction).to include_environment(
|
|
908
|
+
"PATH_INFO" => "value",
|
|
909
|
+
"REQUEST_METHOD" => "value",
|
|
910
|
+
"HTTP_ACCEPT" => "value"
|
|
911
|
+
)
|
|
912
|
+
end
|
|
770
913
|
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
914
|
+
it "adds the headers to the transaction with a block" do
|
|
915
|
+
headers = { "PATH_INFO" => "value" }
|
|
916
|
+
transaction.add_headers { headers }
|
|
774
917
|
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
918
|
+
transaction._sample
|
|
919
|
+
expect(transaction).to include_environment(headers)
|
|
920
|
+
end
|
|
778
921
|
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
922
|
+
it "adds the headers block value when both an argument and block are given" do
|
|
923
|
+
arg_data = { "PATH_INFO" => "/arg-path" }
|
|
924
|
+
block_data = { "PATH_INFO" => "/block-path" }
|
|
925
|
+
transaction.add_headers(arg_data) { block_data }
|
|
782
926
|
|
|
783
|
-
|
|
784
|
-
|
|
927
|
+
transaction._sample
|
|
928
|
+
expect(transaction).to include_environment(block_data)
|
|
929
|
+
end
|
|
785
930
|
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
931
|
+
it "logs an error if an error occurred storing the headers" do
|
|
932
|
+
transaction.add_headers { raise "uh oh" }
|
|
933
|
+
|
|
934
|
+
logs = capture_logs { transaction._sample }
|
|
935
|
+
expect(logs).to contains_log(
|
|
936
|
+
:error,
|
|
937
|
+
"Exception while fetching headers: RuntimeError: uh oh"
|
|
938
|
+
)
|
|
792
939
|
end
|
|
793
940
|
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
941
|
+
it "does not update the headers on the transaction if the given value is nil" do
|
|
942
|
+
headers = { "PATH_INFO" => "value" }
|
|
943
|
+
transaction.add_headers(headers)
|
|
944
|
+
transaction.add_headers(nil)
|
|
945
|
+
|
|
946
|
+
transaction._sample
|
|
947
|
+
expect(transaction).to include_environment(headers)
|
|
948
|
+
end
|
|
949
|
+
|
|
950
|
+
context "with request_headers options" do
|
|
951
|
+
let(:options) { { :request_headers => ["MY_HEADER"] } }
|
|
952
|
+
|
|
953
|
+
it "does not include filtered out headers" do
|
|
954
|
+
transaction.add_headers("MY_HEADER" => "value1", "filtered_key" => "filtered_value")
|
|
799
955
|
|
|
800
956
|
transaction._sample
|
|
801
|
-
expect(transaction).to include_environment(
|
|
957
|
+
expect(transaction).to include_environment("MY_HEADER" => "value1")
|
|
802
958
|
end
|
|
803
959
|
end
|
|
804
960
|
end
|
|
805
961
|
|
|
806
|
-
describe "#
|
|
962
|
+
describe "#add_headers_if_nil" do
|
|
807
963
|
let(:transaction) { new_transaction }
|
|
808
964
|
|
|
809
|
-
|
|
810
|
-
|
|
965
|
+
it "has a #set_headers_if_nil alias" do
|
|
966
|
+
expect(transaction.method(:add_headers_if_nil)).to eq(transaction.method(:set_headers_if_nil))
|
|
967
|
+
end
|
|
968
|
+
|
|
969
|
+
context "when the headers are not set" do
|
|
970
|
+
it "adds the headers to the transaction" do
|
|
811
971
|
headers = { "PATH_INFO" => "value" }
|
|
812
|
-
transaction.
|
|
972
|
+
transaction.add_headers_if_nil(headers)
|
|
813
973
|
|
|
814
974
|
transaction._sample
|
|
815
975
|
expect(transaction).to include_environment(headers)
|
|
816
976
|
end
|
|
817
977
|
|
|
818
|
-
it "
|
|
978
|
+
it "adds the headers to the transaction with a block" do
|
|
819
979
|
headers = { "PATH_INFO" => "value" }
|
|
820
|
-
transaction.
|
|
980
|
+
transaction.add_headers_if_nil { headers }
|
|
821
981
|
|
|
822
982
|
transaction._sample
|
|
823
983
|
expect(transaction).to include_environment(headers)
|
|
824
984
|
end
|
|
825
985
|
|
|
826
|
-
it "
|
|
986
|
+
it "adds the headers block value when both an argument and block are given" do
|
|
827
987
|
arg_data = { "PATH_INFO" => "/arg-path" }
|
|
828
988
|
block_data = { "PATH_INFO" => "/block-path" }
|
|
829
|
-
transaction.
|
|
989
|
+
transaction.add_headers_if_nil(arg_data) { block_data }
|
|
830
990
|
|
|
831
991
|
transaction._sample
|
|
832
|
-
expect(transaction).to include_environment(
|
|
992
|
+
expect(transaction).to include_environment(block_data)
|
|
833
993
|
end
|
|
834
994
|
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
transaction.set_headers_if_nil(nil)
|
|
995
|
+
it "does not update the headers on the transaction if the given value is nil" do
|
|
996
|
+
headers = { "PATH_INFO" => "value" }
|
|
997
|
+
transaction.add_headers(headers)
|
|
998
|
+
transaction.add_headers_if_nil(nil)
|
|
840
999
|
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
end
|
|
1000
|
+
transaction._sample
|
|
1001
|
+
expect(transaction).to include_environment(headers)
|
|
844
1002
|
end
|
|
845
1003
|
end
|
|
846
1004
|
|
|
847
|
-
context "when the
|
|
848
|
-
it "does not update the
|
|
1005
|
+
context "when the headers are set" do
|
|
1006
|
+
it "does not update the headers on the transaction" do
|
|
849
1007
|
preset_headers = { "PATH_INFO" => "/first-path" }
|
|
850
1008
|
headers = { "PATH_INFO" => "/other-path" }
|
|
851
|
-
transaction.
|
|
852
|
-
transaction.
|
|
1009
|
+
transaction.add_headers(preset_headers)
|
|
1010
|
+
transaction.add_headers_if_nil(headers)
|
|
853
1011
|
|
|
854
1012
|
transaction._sample
|
|
855
1013
|
expect(transaction).to include_environment(preset_headers)
|
|
856
1014
|
end
|
|
857
1015
|
|
|
858
|
-
it "does not update the
|
|
1016
|
+
it "does not update the headers with a block on the transaction" do
|
|
859
1017
|
preset_headers = { "PATH_INFO" => "/first-path" }
|
|
860
1018
|
headers = { "PATH_INFO" => "/other-path" }
|
|
861
|
-
transaction.
|
|
862
|
-
transaction.
|
|
1019
|
+
transaction.add_headers(preset_headers)
|
|
1020
|
+
transaction.add_headers_if_nil { headers }
|
|
863
1021
|
|
|
864
1022
|
transaction._sample
|
|
865
1023
|
expect(transaction).to include_environment(preset_headers)
|
|
@@ -867,12 +1025,12 @@ describe Appsignal::Transaction do
|
|
|
867
1025
|
end
|
|
868
1026
|
end
|
|
869
1027
|
|
|
870
|
-
describe "#
|
|
1028
|
+
describe "#add_tags" do
|
|
871
1029
|
let(:transaction) { new_transaction }
|
|
872
1030
|
let(:long_string) { "a" * 10_001 }
|
|
873
1031
|
|
|
874
1032
|
it "stores tags on the transaction" do
|
|
875
|
-
transaction.
|
|
1033
|
+
transaction.add_tags(
|
|
876
1034
|
:valid_key => "valid_value",
|
|
877
1035
|
"valid_string_key" => "valid_value",
|
|
878
1036
|
:both_symbols => :valid_value,
|
|
@@ -900,8 +1058,8 @@ describe Appsignal::Transaction do
|
|
|
900
1058
|
end
|
|
901
1059
|
|
|
902
1060
|
it "merges the tags when called multiple times" do
|
|
903
|
-
transaction.
|
|
904
|
-
transaction.
|
|
1061
|
+
transaction.add_tags(:key1 => "value1")
|
|
1062
|
+
transaction.add_tags(:key2 => "value2")
|
|
905
1063
|
transaction._sample
|
|
906
1064
|
|
|
907
1065
|
expect(transaction).to include_tags(
|
|
@@ -911,11 +1069,15 @@ describe Appsignal::Transaction do
|
|
|
911
1069
|
end
|
|
912
1070
|
end
|
|
913
1071
|
|
|
914
|
-
describe "#
|
|
1072
|
+
describe "#add_custom_data" do
|
|
915
1073
|
let(:transaction) { new_transaction }
|
|
916
1074
|
|
|
917
|
-
it "
|
|
918
|
-
transaction.set_custom_data
|
|
1075
|
+
it "has a #add_custom_data alias" do
|
|
1076
|
+
expect(transaction.method(:add_custom_data)).to eq(transaction.method(:set_custom_data))
|
|
1077
|
+
end
|
|
1078
|
+
|
|
1079
|
+
it "adds a custom Hash data to the transaction" do
|
|
1080
|
+
transaction.add_custom_data(
|
|
919
1081
|
:user => {
|
|
920
1082
|
:id => 123,
|
|
921
1083
|
:locale => "abc"
|
|
@@ -939,8 +1101,8 @@ describe Appsignal::Transaction do
|
|
|
939
1101
|
)
|
|
940
1102
|
end
|
|
941
1103
|
|
|
942
|
-
it "
|
|
943
|
-
transaction.
|
|
1104
|
+
it "adds a custom Array data to the transaction" do
|
|
1105
|
+
transaction.add_custom_data([
|
|
944
1106
|
[123, "abc"],
|
|
945
1107
|
["appsignal", "enterprise"]
|
|
946
1108
|
])
|
|
@@ -955,39 +1117,42 @@ describe Appsignal::Transaction do
|
|
|
955
1117
|
it "does not store non Hash or Array custom data" do
|
|
956
1118
|
logs =
|
|
957
1119
|
capture_logs do
|
|
958
|
-
transaction.
|
|
1120
|
+
transaction.add_custom_data("abc")
|
|
959
1121
|
transaction._sample
|
|
960
1122
|
expect(transaction).to_not include_custom_data
|
|
961
1123
|
|
|
962
|
-
transaction.
|
|
1124
|
+
transaction.add_custom_data(123)
|
|
963
1125
|
transaction._sample
|
|
964
1126
|
expect(transaction).to_not include_custom_data
|
|
965
1127
|
|
|
966
|
-
transaction.
|
|
1128
|
+
transaction.add_custom_data(Object.new)
|
|
967
1129
|
transaction._sample
|
|
968
1130
|
expect(transaction).to_not include_custom_data
|
|
969
1131
|
end
|
|
970
1132
|
|
|
971
1133
|
expect(logs).to contains_log(
|
|
972
1134
|
:error,
|
|
973
|
-
|
|
1135
|
+
%(Sample data 'custom_data': Unsupported data type 'String' received: "abc")
|
|
974
1136
|
)
|
|
975
1137
|
expect(logs).to contains_log(
|
|
976
1138
|
:error,
|
|
977
|
-
|
|
1139
|
+
%(Sample data 'custom_data': Unsupported data type 'Integer' received: 123)
|
|
978
1140
|
)
|
|
979
1141
|
expect(logs).to contains_log(
|
|
980
1142
|
:error,
|
|
981
|
-
|
|
1143
|
+
%(Sample data 'custom_data': Unsupported data type 'Object' received: #<Object:)
|
|
982
1144
|
)
|
|
983
1145
|
end
|
|
984
1146
|
|
|
985
|
-
it "
|
|
986
|
-
transaction.
|
|
987
|
-
transaction.
|
|
1147
|
+
it "merges the custom data if called multiple times" do
|
|
1148
|
+
transaction.add_custom_data("abc" => "value")
|
|
1149
|
+
transaction.add_custom_data("def" => "value")
|
|
988
1150
|
|
|
989
1151
|
transaction._sample
|
|
990
|
-
expect(transaction).to include_custom_data(
|
|
1152
|
+
expect(transaction).to include_custom_data(
|
|
1153
|
+
"abc" => "value",
|
|
1154
|
+
"def" => "value"
|
|
1155
|
+
)
|
|
991
1156
|
end
|
|
992
1157
|
end
|
|
993
1158
|
|
|
@@ -1150,42 +1315,6 @@ describe Appsignal::Transaction do
|
|
|
1150
1315
|
end
|
|
1151
1316
|
end
|
|
1152
1317
|
|
|
1153
|
-
describe "#set_http_or_background_action" do
|
|
1154
|
-
let(:transaction) { new_transaction }
|
|
1155
|
-
|
|
1156
|
-
context "for a hash with controller and action" do
|
|
1157
|
-
it "sets the action" do
|
|
1158
|
-
transaction.set_http_or_background_action(
|
|
1159
|
-
:controller => "HomeController",
|
|
1160
|
-
:action => "show"
|
|
1161
|
-
)
|
|
1162
|
-
expect(transaction).to have_action("HomeController#show")
|
|
1163
|
-
end
|
|
1164
|
-
end
|
|
1165
|
-
|
|
1166
|
-
context "for a hash with just action" do
|
|
1167
|
-
it "sets the action" do
|
|
1168
|
-
transaction.set_http_or_background_action(:action => "show")
|
|
1169
|
-
expect(transaction).to have_action("show")
|
|
1170
|
-
end
|
|
1171
|
-
end
|
|
1172
|
-
|
|
1173
|
-
context "for a hash with class and method" do
|
|
1174
|
-
it "sets the action" do
|
|
1175
|
-
transaction.set_http_or_background_action(:class => "Worker", :method => "perform")
|
|
1176
|
-
expect(transaction).to have_action("Worker#perform")
|
|
1177
|
-
end
|
|
1178
|
-
end
|
|
1179
|
-
|
|
1180
|
-
context "when action is already set" do
|
|
1181
|
-
it "does not overwrite the set action" do
|
|
1182
|
-
transaction.set_action("MyCustomAction#perform")
|
|
1183
|
-
transaction.set_http_or_background_action(:class => "Worker", :method => "perform")
|
|
1184
|
-
expect(transaction).to have_action("MyCustomAction#perform")
|
|
1185
|
-
end
|
|
1186
|
-
end
|
|
1187
|
-
end
|
|
1188
|
-
|
|
1189
1318
|
describe "#set_queue_start" do
|
|
1190
1319
|
let(:transaction) { new_transaction }
|
|
1191
1320
|
|
|
@@ -1210,75 +1339,6 @@ describe Appsignal::Transaction do
|
|
|
1210
1339
|
end
|
|
1211
1340
|
end
|
|
1212
1341
|
|
|
1213
|
-
describe "#set_http_or_background_queue_start" do
|
|
1214
|
-
let(:transaction) { legacy_new_transaction(:request => legacy_request(env)) }
|
|
1215
|
-
let(:err_stream) { std_stream }
|
|
1216
|
-
let(:stderr) { err_stream.read }
|
|
1217
|
-
let(:header_factor) { 1_000 }
|
|
1218
|
-
let(:env_queue_start) { fixed_time + 20 } # in seconds
|
|
1219
|
-
|
|
1220
|
-
def set_http_or_background_queue_start
|
|
1221
|
-
capture_std_streams(std_stream, err_stream) do
|
|
1222
|
-
transaction.set_http_or_background_queue_start
|
|
1223
|
-
end
|
|
1224
|
-
end
|
|
1225
|
-
|
|
1226
|
-
context "when a queue time is found in a request header" do
|
|
1227
|
-
let(:header_time) { ((fixed_time + 10) * header_factor).to_i } # in milliseconds
|
|
1228
|
-
let(:env) { { "HTTP_X_REQUEST_START" => "t=#{header_time}" } }
|
|
1229
|
-
|
|
1230
|
-
it "sets the http header value in milliseconds on the transaction" do
|
|
1231
|
-
set_http_or_background_queue_start
|
|
1232
|
-
|
|
1233
|
-
expect(transaction).to have_queue_start(1_389_783_610_000)
|
|
1234
|
-
end
|
|
1235
|
-
|
|
1236
|
-
it "logs a deprecation message" do
|
|
1237
|
-
logs = capture_logs { set_http_or_background_queue_start }
|
|
1238
|
-
|
|
1239
|
-
expect(logs).to contains_log(
|
|
1240
|
-
:warn,
|
|
1241
|
-
"The Appsignal::Transaction#set_http_or_background_queue_start " \
|
|
1242
|
-
"method has been deprecated."
|
|
1243
|
-
)
|
|
1244
|
-
end
|
|
1245
|
-
|
|
1246
|
-
it "prints a deprecation message" do
|
|
1247
|
-
set_http_or_background_queue_start
|
|
1248
|
-
|
|
1249
|
-
expect(stderr).to include(
|
|
1250
|
-
"The Appsignal::Transaction#set_http_or_background_queue_start " \
|
|
1251
|
-
"method has been deprecated."
|
|
1252
|
-
)
|
|
1253
|
-
end
|
|
1254
|
-
|
|
1255
|
-
context "when a :queue_start key is found in the transaction environment" do
|
|
1256
|
-
let(:env) do
|
|
1257
|
-
{
|
|
1258
|
-
"HTTP_X_REQUEST_START" => "t=#{header_time}",
|
|
1259
|
-
:queue_start => env_queue_start
|
|
1260
|
-
}
|
|
1261
|
-
end
|
|
1262
|
-
|
|
1263
|
-
it "sets the http header value in milliseconds on the transaction" do
|
|
1264
|
-
set_http_or_background_queue_start
|
|
1265
|
-
|
|
1266
|
-
expect(transaction).to have_queue_start(1_389_783_610_000)
|
|
1267
|
-
end
|
|
1268
|
-
end
|
|
1269
|
-
end
|
|
1270
|
-
|
|
1271
|
-
context "when a :queue_start key is found in the transaction environment" do
|
|
1272
|
-
let(:env) { { :queue_start => env_queue_start } } # in seconds
|
|
1273
|
-
|
|
1274
|
-
it "sets the :queue_start value in milliseconds on the transaction" do
|
|
1275
|
-
set_http_or_background_queue_start
|
|
1276
|
-
|
|
1277
|
-
expect(transaction).to have_queue_start(1_389_783_620_000)
|
|
1278
|
-
end
|
|
1279
|
-
end
|
|
1280
|
-
end
|
|
1281
|
-
|
|
1282
1342
|
describe "#set_metadata" do
|
|
1283
1343
|
let(:transaction) { new_transaction }
|
|
1284
1344
|
|
|
@@ -1289,8 +1349,7 @@ describe Appsignal::Transaction do
|
|
|
1289
1349
|
end
|
|
1290
1350
|
|
|
1291
1351
|
context "when filter_metadata includes metadata key" do
|
|
1292
|
-
|
|
1293
|
-
after { Appsignal.config[:filter_metadata] = [] }
|
|
1352
|
+
let(:options) { { :filter_metadata => ["filter_key"] } }
|
|
1294
1353
|
|
|
1295
1354
|
it "does not set the metadata on the transaction" do
|
|
1296
1355
|
transaction.set_metadata(:filter_key, "filtered value")
|
|
@@ -1363,14 +1422,22 @@ describe Appsignal::Transaction do
|
|
|
1363
1422
|
expect(transaction).to_not include_params
|
|
1364
1423
|
end
|
|
1365
1424
|
|
|
1366
|
-
expect(logs).to contains_log
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
expect(logs).to contains_log
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1425
|
+
expect(logs).to contains_log(
|
|
1426
|
+
:error,
|
|
1427
|
+
%(Sample data 'params': Unsupported data type 'String' received: "some string")
|
|
1428
|
+
)
|
|
1429
|
+
expect(logs).to contains_log(
|
|
1430
|
+
:error,
|
|
1431
|
+
%(Sample data 'params': Unsupported data type 'Integer' received: 123)
|
|
1432
|
+
)
|
|
1433
|
+
expect(logs).to contains_log(
|
|
1434
|
+
:error,
|
|
1435
|
+
%(Sample data 'params': Unsupported data type 'Class' received: #<Class)
|
|
1436
|
+
)
|
|
1437
|
+
expect(logs).to contains_log(
|
|
1438
|
+
:error,
|
|
1439
|
+
%(Sample data 'params': Unsupported data type 'Set' received: #<Set: {"some value"}>)
|
|
1440
|
+
)
|
|
1374
1441
|
end
|
|
1375
1442
|
|
|
1376
1443
|
it "does not store data that can't be converted to JSON" do
|
|
@@ -1400,7 +1467,8 @@ describe Appsignal::Transaction do
|
|
|
1400
1467
|
|
|
1401
1468
|
it "updates the sample data on the transaction" do
|
|
1402
1469
|
silence do
|
|
1403
|
-
transaction.
|
|
1470
|
+
transaction.send(
|
|
1471
|
+
:set_sample_data,
|
|
1404
1472
|
"params",
|
|
1405
1473
|
:controller => "blog_posts",
|
|
1406
1474
|
:action => "show",
|
|
@@ -1419,7 +1487,7 @@ describe Appsignal::Transaction do
|
|
|
1419
1487
|
it "does not update the sample data on the transaction" do
|
|
1420
1488
|
logs =
|
|
1421
1489
|
capture_logs do
|
|
1422
|
-
silence { transaction.set_sample_data
|
|
1490
|
+
silence { transaction.send(:set_sample_data, "params", "string") }
|
|
1423
1491
|
end
|
|
1424
1492
|
|
|
1425
1493
|
expect(transaction.to_h["sample_data"]).to eq({})
|
|
@@ -1437,7 +1505,7 @@ describe Appsignal::Transaction do
|
|
|
1437
1505
|
end
|
|
1438
1506
|
logs =
|
|
1439
1507
|
capture_logs do
|
|
1440
|
-
silence { transaction.set_sample_data
|
|
1508
|
+
silence { transaction.send(:set_sample_data, "params", klass.new => 1) }
|
|
1441
1509
|
end
|
|
1442
1510
|
|
|
1443
1511
|
expect(transaction).to_not include_params
|
|
@@ -1447,91 +1515,202 @@ describe Appsignal::Transaction do
|
|
|
1447
1515
|
end
|
|
1448
1516
|
end
|
|
1449
1517
|
|
|
1450
|
-
describe "#
|
|
1451
|
-
let(:transaction) {
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
"SERVER_PORT" => "80",
|
|
1458
|
-
"PATH_INFO" => "/blog",
|
|
1459
|
-
"rack.session" => { "session" => "value" },
|
|
1460
|
-
:params => {
|
|
1461
|
-
"controller" => "blog_posts",
|
|
1462
|
-
"action" => "show",
|
|
1463
|
-
"id" => "1"
|
|
1464
|
-
}
|
|
1465
|
-
).merge(
|
|
1466
|
-
:metadata => { "metadata" => "value" }
|
|
1467
|
-
)
|
|
1518
|
+
describe "#add_error" do
|
|
1519
|
+
let(:transaction) { create_transaction }
|
|
1520
|
+
|
|
1521
|
+
let(:error) do
|
|
1522
|
+
e = ExampleStandardError.new("test message")
|
|
1523
|
+
allow(e).to receive(:backtrace).and_return(["line 1"])
|
|
1524
|
+
e
|
|
1468
1525
|
end
|
|
1469
1526
|
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
transaction.add_breadcrumb "category", "action", "message", "key" => "value"
|
|
1473
|
-
silence { transaction.sample_data }
|
|
1527
|
+
context "when error argument is not an error" do
|
|
1528
|
+
let(:error) { Object.new }
|
|
1474
1529
|
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
"id" => "1"
|
|
1486
|
-
)
|
|
1487
|
-
expect(transaction).to include_sample_metadata("metadata" => "value")
|
|
1488
|
-
expect(transaction).to include_tags("tag" => "value")
|
|
1489
|
-
expect(transaction).to include_breadcrumb(
|
|
1490
|
-
"action",
|
|
1491
|
-
"category",
|
|
1492
|
-
"message",
|
|
1493
|
-
{ "key" => "value" },
|
|
1494
|
-
kind_of(Integer)
|
|
1495
|
-
)
|
|
1530
|
+
it "does not add the error" do
|
|
1531
|
+
logs = capture_logs { transaction.add_error(error) }
|
|
1532
|
+
|
|
1533
|
+
expect(transaction).to_not have_error
|
|
1534
|
+
expect(logs).to contains_log(
|
|
1535
|
+
:error,
|
|
1536
|
+
"Appsignal::Transaction#add_error: Cannot add error. " \
|
|
1537
|
+
"The given value is not an exception: #{error.inspect}"
|
|
1538
|
+
)
|
|
1539
|
+
end
|
|
1496
1540
|
end
|
|
1497
|
-
end
|
|
1498
1541
|
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
let(:error) { ExampleStandardError.new("test message") }
|
|
1542
|
+
context "when AppSignal is not active" do
|
|
1543
|
+
it "does not add the error" do
|
|
1544
|
+
allow(Appsignal).to receive(:active?).and_return(false)
|
|
1503
1545
|
|
|
1504
|
-
|
|
1505
|
-
|
|
1546
|
+
transaction.add_error(error)
|
|
1547
|
+
|
|
1548
|
+
expect(transaction).to_not have_error
|
|
1549
|
+
end
|
|
1506
1550
|
end
|
|
1507
1551
|
|
|
1508
|
-
|
|
1509
|
-
|
|
1552
|
+
context "when a block is given" do
|
|
1553
|
+
it "stores the block in the error blocks" do
|
|
1554
|
+
block = proc { "block" }
|
|
1510
1555
|
|
|
1511
|
-
|
|
1556
|
+
transaction.add_error(error, &block)
|
|
1512
1557
|
|
|
1513
|
-
|
|
1558
|
+
expect(transaction.error_blocks).to eq({
|
|
1559
|
+
error => [block]
|
|
1560
|
+
})
|
|
1561
|
+
end
|
|
1514
1562
|
end
|
|
1515
1563
|
|
|
1516
|
-
context "when error
|
|
1517
|
-
|
|
1564
|
+
context "when no error is set in the transaction" do
|
|
1565
|
+
it "sets the error on the transaction" do
|
|
1566
|
+
transaction.add_error(error)
|
|
1518
1567
|
|
|
1519
|
-
|
|
1520
|
-
|
|
1568
|
+
expect(transaction).to have_error(
|
|
1569
|
+
"ExampleStandardError",
|
|
1570
|
+
"test message",
|
|
1571
|
+
["line 1"]
|
|
1572
|
+
)
|
|
1573
|
+
end
|
|
1574
|
+
|
|
1575
|
+
it "does store the error in the errors" do
|
|
1576
|
+
transaction.add_error(error)
|
|
1577
|
+
|
|
1578
|
+
expect(transaction.error_blocks).to eq({ error => [] })
|
|
1579
|
+
end
|
|
1580
|
+
end
|
|
1581
|
+
|
|
1582
|
+
context "when an error is already set in the transaction" do
|
|
1583
|
+
let(:other_error) do
|
|
1584
|
+
e = ExampleStandardError.new("other test message")
|
|
1585
|
+
allow(e).to receive(:backtrace).and_return(["line 2"])
|
|
1586
|
+
e
|
|
1587
|
+
end
|
|
1588
|
+
|
|
1589
|
+
before { transaction.set_error(other_error) }
|
|
1590
|
+
|
|
1591
|
+
it "stores an error in the errors" do
|
|
1592
|
+
transaction.add_error(error)
|
|
1593
|
+
|
|
1594
|
+
expect(transaction.error_blocks).to eq({
|
|
1595
|
+
other_error => [],
|
|
1596
|
+
error => []
|
|
1597
|
+
})
|
|
1598
|
+
end
|
|
1599
|
+
|
|
1600
|
+
it "does not set the error on the extension" do
|
|
1601
|
+
transaction.add_error(error)
|
|
1602
|
+
|
|
1603
|
+
expect(transaction).to have_error(
|
|
1604
|
+
"ExampleStandardError",
|
|
1605
|
+
"other test message",
|
|
1606
|
+
["line 2"]
|
|
1607
|
+
)
|
|
1608
|
+
end
|
|
1609
|
+
end
|
|
1610
|
+
|
|
1611
|
+
context "when the error has already been added" do
|
|
1612
|
+
before { transaction.add_error(error) }
|
|
1613
|
+
|
|
1614
|
+
it "does not add the error to the errors" do
|
|
1615
|
+
expect(transaction.error_blocks).to eq({ error => [] })
|
|
1616
|
+
|
|
1617
|
+
transaction.add_error(error)
|
|
1618
|
+
|
|
1619
|
+
expect(transaction.error_blocks).to eq({ error => [] })
|
|
1620
|
+
end
|
|
1621
|
+
|
|
1622
|
+
context "when a block is given" do
|
|
1623
|
+
it "adds the block to the error blocks" do
|
|
1624
|
+
block = proc { "block" }
|
|
1625
|
+
|
|
1626
|
+
transaction.add_error(error, &block)
|
|
1627
|
+
|
|
1628
|
+
expect(transaction.error_blocks).to eq({ error => [block] })
|
|
1629
|
+
end
|
|
1630
|
+
end
|
|
1631
|
+
end
|
|
1632
|
+
|
|
1633
|
+
context "when the errors is at the limit" do
|
|
1634
|
+
let(:seen_error) { ExampleStandardError.new("error 0") }
|
|
1635
|
+
|
|
1636
|
+
before do
|
|
1637
|
+
transaction.add_error(seen_error)
|
|
1638
|
+
|
|
1639
|
+
9.times do |i|
|
|
1640
|
+
transaction.add_error(ExampleStandardError.new("error #{i}"))
|
|
1641
|
+
end
|
|
1642
|
+
end
|
|
1643
|
+
|
|
1644
|
+
it "does not add a new error to the errors" do
|
|
1645
|
+
expect(transaction).to have_error("ExampleStandardError", "error 0", [])
|
|
1646
|
+
expect(transaction.error_blocks.length).to eq(10)
|
|
1647
|
+
expected_error_blocks = transaction.error_blocks.dup
|
|
1648
|
+
|
|
1649
|
+
transaction.add_error(error)
|
|
1650
|
+
|
|
1651
|
+
expect(transaction).to have_error("ExampleStandardError", "error 0", [])
|
|
1652
|
+
expect(transaction.error_blocks).to eq(expected_error_blocks)
|
|
1653
|
+
end
|
|
1654
|
+
|
|
1655
|
+
it "logs a debug message" do
|
|
1656
|
+
logs = capture_logs { transaction.add_error(error) }
|
|
1521
1657
|
|
|
1522
|
-
expect(transaction).to_not have_error
|
|
1523
1658
|
expect(logs).to contains_log(
|
|
1524
|
-
:
|
|
1525
|
-
"Appsignal::Transaction#
|
|
1526
|
-
"
|
|
1659
|
+
:warn,
|
|
1660
|
+
"Appsignal::Transaction#add_error: Transaction has more than 10 distinct errors. " \
|
|
1661
|
+
"Only the first 10 distinct errors will be reported."
|
|
1527
1662
|
)
|
|
1528
1663
|
end
|
|
1664
|
+
|
|
1665
|
+
context "when the error has already been added" do
|
|
1666
|
+
it "does not add the error to the errors" do
|
|
1667
|
+
expect(transaction.error_blocks.length).to eq(10)
|
|
1668
|
+
|
|
1669
|
+
transaction.add_error(seen_error)
|
|
1670
|
+
|
|
1671
|
+
expect(transaction.error_blocks.length).to eq(10)
|
|
1672
|
+
end
|
|
1673
|
+
|
|
1674
|
+
it "does add the block to the error blocks" do
|
|
1675
|
+
block = proc { "block" }
|
|
1676
|
+
|
|
1677
|
+
transaction.add_error(seen_error, &block)
|
|
1678
|
+
|
|
1679
|
+
expect(transaction.error_blocks[seen_error]).to eq([block])
|
|
1680
|
+
end
|
|
1681
|
+
|
|
1682
|
+
it "does not log a debug message" do
|
|
1683
|
+
logs = capture_logs { transaction.add_error(seen_error) }
|
|
1684
|
+
|
|
1685
|
+
expect(logs).to_not contains_log(
|
|
1686
|
+
:warn,
|
|
1687
|
+
"Appsignal::Transaction#add_error: Transaction has more than 10 distinct errors. " \
|
|
1688
|
+
"Only the first 10 distinct errors will be reported."
|
|
1689
|
+
)
|
|
1690
|
+
end
|
|
1691
|
+
end
|
|
1692
|
+
end
|
|
1693
|
+
end
|
|
1694
|
+
|
|
1695
|
+
describe "#_set_error" do
|
|
1696
|
+
let(:transaction) { new_transaction }
|
|
1697
|
+
let(:env) { http_request_env_with_data }
|
|
1698
|
+
let(:error) { ExampleStandardError.new("test message") }
|
|
1699
|
+
|
|
1700
|
+
it "responds to add_exception for backwards compatibility" do
|
|
1701
|
+
expect(transaction).to respond_to(:add_exception)
|
|
1702
|
+
end
|
|
1703
|
+
|
|
1704
|
+
it "does not add the error to the errors" do
|
|
1705
|
+
transaction.send(:_set_error, error)
|
|
1706
|
+
|
|
1707
|
+
expect(transaction.error_blocks).to be_empty
|
|
1529
1708
|
end
|
|
1530
1709
|
|
|
1531
1710
|
context "for a http request" do
|
|
1532
1711
|
it "sets an error on the transaction" do
|
|
1533
1712
|
allow(error).to receive(:backtrace).and_return(["line 1"])
|
|
1534
|
-
transaction.
|
|
1713
|
+
transaction.send(:_set_error, error)
|
|
1535
1714
|
|
|
1536
1715
|
expect(transaction).to have_error(
|
|
1537
1716
|
"ExampleStandardError",
|
|
@@ -1542,10 +1721,10 @@ describe Appsignal::Transaction do
|
|
|
1542
1721
|
end
|
|
1543
1722
|
|
|
1544
1723
|
context "when the error has no causes" do
|
|
1545
|
-
it "
|
|
1546
|
-
transaction.
|
|
1724
|
+
it "should set an empty causes array as sample data" do
|
|
1725
|
+
transaction.send(:_set_error, error)
|
|
1547
1726
|
|
|
1548
|
-
expect(transaction).
|
|
1727
|
+
expect(transaction).to include_error_causes([])
|
|
1549
1728
|
end
|
|
1550
1729
|
end
|
|
1551
1730
|
|
|
@@ -1560,8 +1739,12 @@ describe Appsignal::Transaction do
|
|
|
1560
1739
|
e
|
|
1561
1740
|
end
|
|
1562
1741
|
|
|
1742
|
+
let(:error_without_cause) do
|
|
1743
|
+
ExampleStandardError.new("error without cause")
|
|
1744
|
+
end
|
|
1745
|
+
|
|
1563
1746
|
it "sends the causes information as sample data" do
|
|
1564
|
-
transaction.
|
|
1747
|
+
transaction.send(:_set_error, error)
|
|
1565
1748
|
|
|
1566
1749
|
expect(transaction).to have_error(
|
|
1567
1750
|
"ExampleStandardError",
|
|
@@ -1581,6 +1764,19 @@ describe Appsignal::Transaction do
|
|
|
1581
1764
|
]
|
|
1582
1765
|
)
|
|
1583
1766
|
end
|
|
1767
|
+
|
|
1768
|
+
it "does not keep error causes from previously set errors" do
|
|
1769
|
+
transaction.send(:_set_error, error)
|
|
1770
|
+
transaction.send(:_set_error, error_without_cause)
|
|
1771
|
+
|
|
1772
|
+
expect(transaction).to have_error(
|
|
1773
|
+
"ExampleStandardError",
|
|
1774
|
+
"error without cause",
|
|
1775
|
+
[]
|
|
1776
|
+
)
|
|
1777
|
+
|
|
1778
|
+
expect(transaction).to include_error_causes([])
|
|
1779
|
+
end
|
|
1584
1780
|
end
|
|
1585
1781
|
|
|
1586
1782
|
context "when the error has too many causes" do
|
|
@@ -1607,7 +1803,7 @@ describe Appsignal::Transaction do
|
|
|
1607
1803
|
end
|
|
1608
1804
|
expected_error_causes.last["is_root_cause"] = false
|
|
1609
1805
|
|
|
1610
|
-
logs = capture_logs { transaction.
|
|
1806
|
+
logs = capture_logs { transaction.send(:_set_error, error) }
|
|
1611
1807
|
|
|
1612
1808
|
expect(transaction).to have_error(
|
|
1613
1809
|
"ExampleStandardError",
|
|
@@ -1617,7 +1813,7 @@ describe Appsignal::Transaction do
|
|
|
1617
1813
|
expect(transaction).to include_error_causes(expected_error_causes)
|
|
1618
1814
|
expect(logs).to contains_log(
|
|
1619
1815
|
:debug,
|
|
1620
|
-
"Appsignal::Transaction#
|
|
1816
|
+
"Appsignal::Transaction#add_error: Error has more " \
|
|
1621
1817
|
"than 10 error causes. Only the first 10 " \
|
|
1622
1818
|
"will be reported."
|
|
1623
1819
|
)
|
|
@@ -1633,11 +1829,11 @@ describe Appsignal::Transaction do
|
|
|
1633
1829
|
end
|
|
1634
1830
|
|
|
1635
1831
|
it "does not raise an error" do
|
|
1636
|
-
transaction.
|
|
1832
|
+
transaction.send(:_set_error, error)
|
|
1637
1833
|
end
|
|
1638
1834
|
|
|
1639
1835
|
it "sets an error on the transaction without an error message" do
|
|
1640
|
-
transaction.
|
|
1836
|
+
transaction.send(:_set_error, error)
|
|
1641
1837
|
|
|
1642
1838
|
expect(transaction).to have_error(
|
|
1643
1839
|
"ExampleStandardError",
|
|
@@ -1780,433 +1976,8 @@ describe Appsignal::Transaction do
|
|
|
1780
1976
|
end
|
|
1781
1977
|
end
|
|
1782
1978
|
|
|
1783
|
-
context "GenericRequest" do
|
|
1784
|
-
let(:env) { {} }
|
|
1785
|
-
subject { Appsignal::Transaction::GenericRequest.new(env) }
|
|
1786
|
-
|
|
1787
|
-
it "prints a deprecation warning on use" do
|
|
1788
|
-
err_stream = std_stream
|
|
1789
|
-
capture_std_streams(std_stream, err_stream) { subject }
|
|
1790
|
-
|
|
1791
|
-
expect(err_stream.read).to include(
|
|
1792
|
-
"appsignal WARNING: The use of Appsignal::Transaction::GenericRequest is deprecated."
|
|
1793
|
-
)
|
|
1794
|
-
end
|
|
1795
|
-
|
|
1796
|
-
it "logs a deprecation warning on use" do
|
|
1797
|
-
logs = capture_logs { silence { subject } }
|
|
1798
|
-
|
|
1799
|
-
expect(logs).to contains_log(
|
|
1800
|
-
:warn,
|
|
1801
|
-
"The use of Appsignal::Transaction::GenericRequest is deprecated."
|
|
1802
|
-
)
|
|
1803
|
-
end
|
|
1804
|
-
|
|
1805
|
-
it "initializes with an empty env" do
|
|
1806
|
-
expect(subject.env).to be_empty
|
|
1807
|
-
end
|
|
1808
|
-
|
|
1809
|
-
context "when given an env" do
|
|
1810
|
-
let(:env) do
|
|
1811
|
-
{
|
|
1812
|
-
:params => { :id => 1 },
|
|
1813
|
-
:queue_start => 10
|
|
1814
|
-
}
|
|
1815
|
-
end
|
|
1816
|
-
|
|
1817
|
-
it "sets the given env" do
|
|
1818
|
-
expect(subject.env).to eq env
|
|
1819
|
-
end
|
|
1820
|
-
|
|
1821
|
-
it "sets the params present in the env" do
|
|
1822
|
-
expect(subject.params).to eq(:id => 1)
|
|
1823
|
-
end
|
|
1824
|
-
end
|
|
1825
|
-
end
|
|
1826
|
-
|
|
1827
1979
|
# private
|
|
1828
1980
|
|
|
1829
|
-
describe "#background_queue_start" do
|
|
1830
|
-
let(:transaction) { legacy_new_transaction(:request => request) }
|
|
1831
|
-
let(:request) { rack_request(env) }
|
|
1832
|
-
let(:env) { {} }
|
|
1833
|
-
subject { transaction.send(:background_queue_start) }
|
|
1834
|
-
|
|
1835
|
-
context "when request is nil" do
|
|
1836
|
-
let(:request) { nil }
|
|
1837
|
-
|
|
1838
|
-
it { is_expected.to eq nil }
|
|
1839
|
-
end
|
|
1840
|
-
|
|
1841
|
-
context "when env is nil" do
|
|
1842
|
-
before { expect(request).to receive(:env).and_return(nil) }
|
|
1843
|
-
|
|
1844
|
-
it { is_expected.to eq nil }
|
|
1845
|
-
end
|
|
1846
|
-
|
|
1847
|
-
context "when queue start is nil" do
|
|
1848
|
-
it { is_expected.to eq nil }
|
|
1849
|
-
end
|
|
1850
|
-
|
|
1851
|
-
context "when queue start is set" do
|
|
1852
|
-
before do
|
|
1853
|
-
env[:queue_start] = fixed_time
|
|
1854
|
-
end
|
|
1855
|
-
|
|
1856
|
-
it { is_expected.to eq 1_389_783_600_000 }
|
|
1857
|
-
end
|
|
1858
|
-
end
|
|
1859
|
-
|
|
1860
|
-
describe "#http_queue_start" do
|
|
1861
|
-
let(:transaction) { legacy_new_transaction(:request => request) }
|
|
1862
|
-
let(:request) { rack_request(env) }
|
|
1863
|
-
let(:env) { {} }
|
|
1864
|
-
let(:slightly_earlier_time) { fixed_time - 0.4 }
|
|
1865
|
-
let(:slightly_earlier_time_value) { (slightly_earlier_time * factor).to_i }
|
|
1866
|
-
subject { transaction.send(:http_queue_start) }
|
|
1867
|
-
|
|
1868
|
-
shared_examples "http queue start" do
|
|
1869
|
-
context "when request is nil" do
|
|
1870
|
-
let(:request) { nil }
|
|
1871
|
-
|
|
1872
|
-
it { is_expected.to be_nil }
|
|
1873
|
-
end
|
|
1874
|
-
|
|
1875
|
-
context "when env is nil" do
|
|
1876
|
-
before { expect(request).to receive(:env).and_return(nil) }
|
|
1877
|
-
|
|
1878
|
-
it { is_expected.to be_nil }
|
|
1879
|
-
end
|
|
1880
|
-
|
|
1881
|
-
context "with no relevant header set" do
|
|
1882
|
-
let(:env) { {} }
|
|
1883
|
-
|
|
1884
|
-
it { is_expected.to be_nil }
|
|
1885
|
-
end
|
|
1886
|
-
|
|
1887
|
-
context "with the HTTP_X_REQUEST_START header set" do
|
|
1888
|
-
let(:env) { { "HTTP_X_REQUEST_START" => "t=#{slightly_earlier_time_value}" } }
|
|
1889
|
-
|
|
1890
|
-
it { is_expected.to eq 1_389_783_599_600 }
|
|
1891
|
-
|
|
1892
|
-
context "with unparsable content" do
|
|
1893
|
-
let(:env) { { "HTTP_X_REQUEST_START" => "something" } }
|
|
1894
|
-
|
|
1895
|
-
it { is_expected.to be_nil }
|
|
1896
|
-
end
|
|
1897
|
-
|
|
1898
|
-
context "with unparsable content at the end" do
|
|
1899
|
-
let(:env) { { "HTTP_X_REQUEST_START" => "t=#{slightly_earlier_time_value}aaaa" } }
|
|
1900
|
-
|
|
1901
|
-
it { is_expected.to eq 1_389_783_599_600 }
|
|
1902
|
-
end
|
|
1903
|
-
|
|
1904
|
-
context "with a really low number" do
|
|
1905
|
-
let(:env) { { "HTTP_X_REQUEST_START" => "t=100" } }
|
|
1906
|
-
|
|
1907
|
-
it { is_expected.to be_nil }
|
|
1908
|
-
end
|
|
1909
|
-
|
|
1910
|
-
context "with the alternate HTTP_X_QUEUE_START header set" do
|
|
1911
|
-
let(:env) { { "HTTP_X_QUEUE_START" => "t=#{slightly_earlier_time_value}" } }
|
|
1912
|
-
|
|
1913
|
-
it { is_expected.to eq 1_389_783_599_600 }
|
|
1914
|
-
end
|
|
1915
|
-
end
|
|
1916
|
-
end
|
|
1917
|
-
|
|
1918
|
-
context "time in milliseconds" do
|
|
1919
|
-
let(:factor) { 1_000 }
|
|
1920
|
-
|
|
1921
|
-
it_should_behave_like "http queue start"
|
|
1922
|
-
end
|
|
1923
|
-
|
|
1924
|
-
context "time in microseconds" do
|
|
1925
|
-
let(:factor) { 1_000_000 }
|
|
1926
|
-
|
|
1927
|
-
it_should_behave_like "http queue start"
|
|
1928
|
-
end
|
|
1929
|
-
end
|
|
1930
|
-
|
|
1931
|
-
describe "#sanitized_params" do
|
|
1932
|
-
let(:transaction) { new_transaction }
|
|
1933
|
-
subject { transaction.send(:sanitized_params) }
|
|
1934
|
-
|
|
1935
|
-
context "with params" do
|
|
1936
|
-
before do
|
|
1937
|
-
transaction.set_params(:foo => "bar", :baz => :bat)
|
|
1938
|
-
end
|
|
1939
|
-
|
|
1940
|
-
it "returns params" do
|
|
1941
|
-
is_expected.to eq(:foo => "bar", :baz => :bat)
|
|
1942
|
-
end
|
|
1943
|
-
|
|
1944
|
-
context "with AppSignal filtering" do
|
|
1945
|
-
before { Appsignal.config.config_hash[:filter_parameters] = %w[foo] }
|
|
1946
|
-
after { Appsignal.config.config_hash[:filter_parameters] = [] }
|
|
1947
|
-
|
|
1948
|
-
it "returns sanitized custom params" do
|
|
1949
|
-
expect(subject).to eq(:foo => "[FILTERED]", :baz => :bat)
|
|
1950
|
-
end
|
|
1951
|
-
end
|
|
1952
|
-
end
|
|
1953
|
-
|
|
1954
|
-
context "params from request" do
|
|
1955
|
-
let(:transaction) { legacy_new_transaction(:request => request, :options => options) }
|
|
1956
|
-
let(:options) { {} }
|
|
1957
|
-
let(:request) { rack_request(env) }
|
|
1958
|
-
let(:env) { {} }
|
|
1959
|
-
|
|
1960
|
-
context "without request params" do
|
|
1961
|
-
before { allow(transaction.request).to receive(:params).and_return(nil) }
|
|
1962
|
-
|
|
1963
|
-
it { is_expected.to be_nil }
|
|
1964
|
-
end
|
|
1965
|
-
|
|
1966
|
-
context "when request params crashes" do
|
|
1967
|
-
before { expect(request).to receive(:params).and_raise(NoMethodError) }
|
|
1968
|
-
|
|
1969
|
-
it { is_expected.to be_nil }
|
|
1970
|
-
end
|
|
1971
|
-
|
|
1972
|
-
context "when request params method does not exist" do
|
|
1973
|
-
let(:options) { { :params_method => :nonsense } }
|
|
1974
|
-
|
|
1975
|
-
it { is_expected.to be_nil }
|
|
1976
|
-
end
|
|
1977
|
-
|
|
1978
|
-
context "when not sending params" do
|
|
1979
|
-
before { Appsignal.config.config_hash[:send_params] = false }
|
|
1980
|
-
after { Appsignal.config.config_hash[:send_params] = true }
|
|
1981
|
-
|
|
1982
|
-
it { is_expected.to be_nil }
|
|
1983
|
-
end
|
|
1984
|
-
|
|
1985
|
-
context "with an array" do
|
|
1986
|
-
let(:request) { legacy_request(:params => %w[arg1 arg2]) }
|
|
1987
|
-
|
|
1988
|
-
it { is_expected.to eq %w[arg1 arg2] }
|
|
1989
|
-
|
|
1990
|
-
context "with AppSignal filtering" do
|
|
1991
|
-
before { Appsignal.config.config_hash[:filter_parameters] = %w[foo] }
|
|
1992
|
-
after { Appsignal.config.config_hash[:filter_parameters] = [] }
|
|
1993
|
-
|
|
1994
|
-
it { is_expected.to eq %w[arg1 arg2] }
|
|
1995
|
-
end
|
|
1996
|
-
end
|
|
1997
|
-
|
|
1998
|
-
context "with env" do
|
|
1999
|
-
context "with sanitization" do
|
|
2000
|
-
let(:request) { legacy_request(:params => { :foo => :bar }) }
|
|
2001
|
-
|
|
2002
|
-
it "should call the params sanitizer" do
|
|
2003
|
-
expect(subject).to eq(:foo => :bar)
|
|
2004
|
-
end
|
|
2005
|
-
end
|
|
2006
|
-
|
|
2007
|
-
context "with AppSignal filtering" do
|
|
2008
|
-
let(:request) { legacy_request(:params => { :foo => :bar, :baz => :bat }) }
|
|
2009
|
-
before { Appsignal.config.config_hash[:filter_parameters] = %w[foo] }
|
|
2010
|
-
after { Appsignal.config.config_hash[:filter_parameters] = [] }
|
|
2011
|
-
|
|
2012
|
-
it "should call the params sanitizer with filtering" do
|
|
2013
|
-
expect(subject).to eq(:foo => "[FILTERED]", :baz => :bat)
|
|
2014
|
-
end
|
|
2015
|
-
end
|
|
2016
|
-
end
|
|
2017
|
-
end
|
|
2018
|
-
end
|
|
2019
|
-
|
|
2020
|
-
describe "#sanitized_environment" do
|
|
2021
|
-
let(:transaction) { legacy_new_transaction(:request => request) }
|
|
2022
|
-
let(:request) { rack_request(env) }
|
|
2023
|
-
let(:env) { {} }
|
|
2024
|
-
let(:allowlisted_keys) { Appsignal.config[:request_headers] }
|
|
2025
|
-
subject { transaction.send(:sanitized_environment) }
|
|
2026
|
-
|
|
2027
|
-
context "when request is nil" do
|
|
2028
|
-
let(:request) { nil }
|
|
2029
|
-
|
|
2030
|
-
it { is_expected.to be_nil }
|
|
2031
|
-
end
|
|
2032
|
-
|
|
2033
|
-
context "when env is nil" do
|
|
2034
|
-
before { expect(request).to receive(:env).and_return(nil) }
|
|
2035
|
-
|
|
2036
|
-
it { is_expected.to be_nil }
|
|
2037
|
-
end
|
|
2038
|
-
|
|
2039
|
-
context "when env is present" do
|
|
2040
|
-
let(:env) do
|
|
2041
|
-
{}.tap do |hash|
|
|
2042
|
-
allowlisted_keys.each { |o| hash[o] = 1 } # use all allowlisted keys
|
|
2043
|
-
hash[allowlisted_keys] = nil # don't add if nil
|
|
2044
|
-
hash[:not_allowlisted] = "I will be sanitized"
|
|
2045
|
-
end
|
|
2046
|
-
end
|
|
2047
|
-
|
|
2048
|
-
it "only sets allowlisted keys" do
|
|
2049
|
-
expect(subject.keys).to match_array(allowlisted_keys)
|
|
2050
|
-
end
|
|
2051
|
-
|
|
2052
|
-
context "with configured request_headers" do
|
|
2053
|
-
before do
|
|
2054
|
-
Appsignal.config.config_hash[:request_headers] = %w[CONTENT_LENGTH]
|
|
2055
|
-
end
|
|
2056
|
-
|
|
2057
|
-
it "only sets allowlisted keys" do
|
|
2058
|
-
expect(subject.keys).to match_array(%w[CONTENT_LENGTH])
|
|
2059
|
-
end
|
|
2060
|
-
end
|
|
2061
|
-
end
|
|
2062
|
-
end
|
|
2063
|
-
|
|
2064
|
-
describe "#sanitized_session_data" do
|
|
2065
|
-
let(:transaction) { legacy_new_transaction(:request => request) }
|
|
2066
|
-
let(:request) { rack_request(env) }
|
|
2067
|
-
let(:env) { {} }
|
|
2068
|
-
subject { transaction.send(:sanitized_session_data) }
|
|
2069
|
-
|
|
2070
|
-
context "when request is nil" do
|
|
2071
|
-
let(:request) { nil }
|
|
2072
|
-
|
|
2073
|
-
it { is_expected.to be_nil }
|
|
2074
|
-
end
|
|
2075
|
-
|
|
2076
|
-
context "when session is nil" do
|
|
2077
|
-
before { expect(transaction.request).to receive(:session).and_return(nil) }
|
|
2078
|
-
|
|
2079
|
-
it { is_expected.to be_nil }
|
|
2080
|
-
end
|
|
2081
|
-
|
|
2082
|
-
context "when session is empty" do
|
|
2083
|
-
before { expect(transaction.request).to receive(:session).and_return({}) }
|
|
2084
|
-
|
|
2085
|
-
it { is_expected.to eq({}) }
|
|
2086
|
-
end
|
|
2087
|
-
|
|
2088
|
-
context "when request class does not have a session method" do
|
|
2089
|
-
let(:request) { Appsignal::Transaction::GenericRequest.new({}) }
|
|
2090
|
-
|
|
2091
|
-
it { is_expected.to be_nil }
|
|
2092
|
-
end
|
|
2093
|
-
|
|
2094
|
-
context "with a session" do
|
|
2095
|
-
let(:session_data_filter) { [] }
|
|
2096
|
-
before { Appsignal.config[:filter_session_data] = session_data_filter }
|
|
2097
|
-
after { Appsignal.config[:filter_session_data] = [] }
|
|
2098
|
-
|
|
2099
|
-
context "with generic session object" do
|
|
2100
|
-
before do
|
|
2101
|
-
expect(transaction).to respond_to(:request)
|
|
2102
|
-
allow(transaction).to receive_message_chain(
|
|
2103
|
-
:request,
|
|
2104
|
-
:session => { :foo => :bar, :abc => :def }
|
|
2105
|
-
)
|
|
2106
|
-
allow(transaction).to receive_message_chain(:request, :fullpath => :bar)
|
|
2107
|
-
end
|
|
2108
|
-
|
|
2109
|
-
context "without session filtering" do
|
|
2110
|
-
it "keeps the session data intact" do
|
|
2111
|
-
expect(subject).to eq(:foo => :bar, :abc => :def)
|
|
2112
|
-
end
|
|
2113
|
-
end
|
|
2114
|
-
|
|
2115
|
-
context "with session filtering" do
|
|
2116
|
-
let(:session_data_filter) { %w[foo] }
|
|
2117
|
-
|
|
2118
|
-
it "filters the session data" do
|
|
2119
|
-
expect(subject).to eq(:foo => "[FILTERED]", :abc => :def)
|
|
2120
|
-
end
|
|
2121
|
-
end
|
|
2122
|
-
end
|
|
2123
|
-
|
|
2124
|
-
if defined? ActionDispatch::Request::Session
|
|
2125
|
-
context "with ActionDispatch::Request::Session" do
|
|
2126
|
-
let(:action_dispatch_session) do
|
|
2127
|
-
store = Class.new do
|
|
2128
|
-
def load_session(_env)
|
|
2129
|
-
[1, { :foo => :bar, :abc => :def }]
|
|
2130
|
-
end
|
|
2131
|
-
|
|
2132
|
-
def session_exists?(_env)
|
|
2133
|
-
true
|
|
2134
|
-
end
|
|
2135
|
-
end.new
|
|
2136
|
-
ActionDispatch::Request::Session.create(store,
|
|
2137
|
-
ActionDispatch::Request.new("rack.input" => StringIO.new), {})
|
|
2138
|
-
end
|
|
2139
|
-
before do
|
|
2140
|
-
expect(transaction).to respond_to(:request)
|
|
2141
|
-
allow(transaction).to receive_message_chain(
|
|
2142
|
-
:request,
|
|
2143
|
-
:session => action_dispatch_session
|
|
2144
|
-
)
|
|
2145
|
-
allow(transaction).to receive_message_chain(:request, :fullpath => :bar)
|
|
2146
|
-
end
|
|
2147
|
-
|
|
2148
|
-
context "without session filtering" do
|
|
2149
|
-
it "keeps the session data intact" do
|
|
2150
|
-
expect(subject).to eq("foo" => :bar, "abc" => :def)
|
|
2151
|
-
end
|
|
2152
|
-
end
|
|
2153
|
-
|
|
2154
|
-
context "with session filtering" do
|
|
2155
|
-
let(:session_data_filter) { %w[foo] }
|
|
2156
|
-
|
|
2157
|
-
it "filters the session data" do
|
|
2158
|
-
expect(subject).to eq("foo" => "[FILTERED]", "abc" => :def)
|
|
2159
|
-
end
|
|
2160
|
-
end
|
|
2161
|
-
end
|
|
2162
|
-
end
|
|
2163
|
-
|
|
2164
|
-
context "when not sending session data" do
|
|
2165
|
-
before { Appsignal.config[:send_session_data] = false }
|
|
2166
|
-
|
|
2167
|
-
it "does not set any session data on the transaction" do
|
|
2168
|
-
expect(subject).to be_nil
|
|
2169
|
-
end
|
|
2170
|
-
end
|
|
2171
|
-
end
|
|
2172
|
-
end
|
|
2173
|
-
|
|
2174
|
-
describe "#sanitized_metadata" do
|
|
2175
|
-
let(:transaction) { legacy_new_transaction(:request => request) }
|
|
2176
|
-
let(:request) { rack_request(env) }
|
|
2177
|
-
let(:env) { {} }
|
|
2178
|
-
subject { transaction.send(:sanitized_metadata) }
|
|
2179
|
-
|
|
2180
|
-
context "when request is nil" do
|
|
2181
|
-
let(:request) { nil }
|
|
2182
|
-
|
|
2183
|
-
it { is_expected.to be_nil }
|
|
2184
|
-
end
|
|
2185
|
-
|
|
2186
|
-
context "when env is nil" do
|
|
2187
|
-
before { expect(request).to receive(:env).and_return(nil) }
|
|
2188
|
-
|
|
2189
|
-
it { is_expected.to be_nil }
|
|
2190
|
-
end
|
|
2191
|
-
|
|
2192
|
-
context "when env is present" do
|
|
2193
|
-
let(:env) { { :metadata => { "key" => "value" } } }
|
|
2194
|
-
|
|
2195
|
-
it do
|
|
2196
|
-
is_expected.to eq("key" => "value")
|
|
2197
|
-
end
|
|
2198
|
-
|
|
2199
|
-
context "with filter_metadata option set" do
|
|
2200
|
-
before { Appsignal.config[:filter_metadata] = ["key"] }
|
|
2201
|
-
after { Appsignal.config[:filter_metadata] = [] }
|
|
2202
|
-
|
|
2203
|
-
it "filters out keys listed in the filter_metadata option" do
|
|
2204
|
-
expect(subject.keys).to_not include("key")
|
|
2205
|
-
end
|
|
2206
|
-
end
|
|
2207
|
-
end
|
|
2208
|
-
end
|
|
2209
|
-
|
|
2210
1981
|
describe "#cleaned_backtrace" do
|
|
2211
1982
|
let(:transaction) { new_transaction }
|
|
2212
1983
|
subject { transaction.send(:cleaned_backtrace, ["line 1", "line 2"]) }
|
|
@@ -2313,13 +2084,13 @@ describe Appsignal::Transaction do
|
|
|
2313
2084
|
describe Appsignal::Transaction::NilTransaction do
|
|
2314
2085
|
subject { Appsignal::Transaction::NilTransaction.new }
|
|
2315
2086
|
|
|
2316
|
-
it "
|
|
2087
|
+
it "has method stubs" do
|
|
2317
2088
|
subject.complete
|
|
2318
2089
|
subject.pause!
|
|
2319
2090
|
subject.resume!
|
|
2320
2091
|
subject.paused?
|
|
2321
2092
|
subject.store(:key)
|
|
2322
|
-
subject.
|
|
2093
|
+
subject.add_tags(:tag => 1)
|
|
2323
2094
|
subject.set_action("action")
|
|
2324
2095
|
subject.set_http_or_background_action
|
|
2325
2096
|
subject.set_queue_start(1)
|