appsignal 3.9.3-java → 3.10.0-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +22 -19
  3. data/CHANGELOG.md +92 -0
  4. data/README.md +0 -1
  5. data/Rakefile +1 -1
  6. data/build_matrix.yml +10 -12
  7. data/gemfiles/webmachine1.gemfile +5 -4
  8. data/lib/appsignal/config.rb +4 -0
  9. data/lib/appsignal/environment.rb +6 -1
  10. data/lib/appsignal/helpers/instrumentation.rb +163 -1
  11. data/lib/appsignal/hooks/active_job.rb +1 -6
  12. data/lib/appsignal/integrations/padrino.rb +21 -25
  13. data/lib/appsignal/integrations/rake.rb +46 -12
  14. data/lib/appsignal/integrations/sidekiq.rb +1 -11
  15. data/lib/appsignal/integrations/webmachine.rb +15 -9
  16. data/lib/appsignal/rack/abstract_middleware.rb +49 -12
  17. data/lib/appsignal/rack/body_wrapper.rb +143 -0
  18. data/lib/appsignal/rack/generic_instrumentation.rb +5 -4
  19. data/lib/appsignal/rack/grape_middleware.rb +1 -1
  20. data/lib/appsignal/rack/hanami_middleware.rb +1 -1
  21. data/lib/appsignal/rack/instrumentation_middleware.rb +62 -0
  22. data/lib/appsignal/rack/rails_instrumentation.rb +1 -3
  23. data/lib/appsignal/rack/sinatra_instrumentation.rb +1 -3
  24. data/lib/appsignal/rack/streaming_listener.rb +13 -59
  25. data/lib/appsignal/rack.rb +31 -0
  26. data/lib/appsignal/transaction.rb +50 -8
  27. data/lib/appsignal/version.rb +1 -1
  28. data/lib/appsignal.rb +3 -1
  29. data/spec/lib/appsignal/config_spec.rb +1 -0
  30. data/spec/lib/appsignal/hooks/rake_spec.rb +100 -17
  31. data/spec/lib/appsignal/integrations/padrino_spec.rb +181 -131
  32. data/spec/lib/appsignal/integrations/sinatra_spec.rb +10 -2
  33. data/spec/lib/appsignal/integrations/webmachine_spec.rb +65 -17
  34. data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +96 -8
  35. data/spec/lib/appsignal/rack/body_wrapper_spec.rb +263 -0
  36. data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +70 -17
  37. data/spec/lib/appsignal/rack/grape_middleware_spec.rb +1 -1
  38. data/spec/lib/appsignal/rack/instrumentation_middleware_spec.rb +38 -0
  39. data/spec/lib/appsignal/rack/streaming_listener_spec.rb +43 -120
  40. data/spec/lib/appsignal/transaction_spec.rb +163 -4
  41. data/spec/lib/appsignal_spec.rb +197 -6
  42. data/spec/support/mocks/dummy_app.rb +1 -1
  43. metadata +8 -4
  44. data/support/check_versions +0 -22
@@ -1,146 +1,69 @@
1
- require "appsignal/rack/streaming_listener"
2
-
3
- describe Appsignal::Rack::StreamingListener do
4
- let(:env) do
5
- {
6
- "rack.input" => StringIO.new,
7
- "REQUEST_METHOD" => "GET",
8
- "PATH_INFO" => "/homepage",
9
- "QUERY_STRING" => "param=something"
10
- }
1
+ describe "Appsignal::Rack::StreamingListener" do
2
+ def load_middleware
3
+ load "lib/appsignal/rack/streaming_listener.rb"
11
4
  end
12
- let(:app) { DummyApp.new }
13
- let(:listener) { Appsignal::Rack::StreamingListener.new(app, {}) }
14
- before(:context) { start_agent }
15
- around { |example| keep_transactions { example.run } }
16
5
 
17
- describe "#call" do
18
- context "when Appsignal is not active" do
19
- before { allow(Appsignal).to receive(:active?).and_return(false) }
6
+ describe "loading the streaming_listener integrations file" do
7
+ let(:err_stream) { std_stream }
8
+ let(:stderr) { err_stream.read }
9
+ after { Appsignal::Rack.send(:remove_const, :StreamingListener) }
20
10
 
21
- it "does not create a transaction" do
22
- expect do
23
- listener.call(env)
24
- end.to_not(change { created_transactions.count })
11
+ it "prints a deprecation warning to STDERR" do
12
+ capture_std_streams(std_stream, err_stream) do
13
+ load_middleware
25
14
  end
26
15
 
27
- it "calls the app" do
28
- listener.call(env)
29
-
30
- expect(app).to be_called
31
- end
16
+ expect(stderr).to include(
17
+ "appsignal WARNING: The constant Appsignal::Rack::StreamingListener " \
18
+ "has been deprecated."
19
+ )
32
20
  end
33
21
 
34
- context "when Appsignal is active" do
35
- before { allow(Appsignal).to receive(:active?).and_return(true) }
36
-
37
- let(:wrapper) { Appsignal::StreamWrapper.new("body", transaction) }
38
- let(:raw_payload) { { :foo => :bar } }
39
- before { allow(listener).to receive(:raw_payload).and_return(raw_payload) }
40
-
41
- it "creates a transaction" do
42
- expect do
43
- listener.call(env)
44
- end.to(change { created_transactions.count }.by(1))
45
- end
46
-
47
- it "instruments the call" do
48
- listener.call(env)
49
-
50
- expect(last_transaction).to include_event("name" => "process_action.rack")
51
- end
52
-
53
- it "set `appsignal.action` to the action name" do
54
- env["appsignal.action"] = "Action"
55
-
56
- listener.call(env)
57
-
58
- expect(last_transaction).to have_action("Action")
59
- end
60
-
61
- it "adds the path, method and queue start to the transaction" do
62
- listener.call(env)
63
-
64
- expect(last_transaction).to include_metadata(
65
- "path" => "/homepage",
66
- "method" => "GET"
67
- )
68
- expect(last_transaction).to have_queue_start
69
- end
70
-
71
- context "with an exception in the instrumentation call" do
72
- let(:error) { ExampleException.new("error message") }
73
- let(:app) { DummyApp.new { raise error } }
74
-
75
- it "adds the exception to the transaction" do
76
- expect do
77
- listener.call(env)
78
- end.to raise_error(error)
79
-
80
- expect(last_transaction).to have_error("ExampleException", "error message")
22
+ it "logs a warning" do
23
+ logs =
24
+ capture_logs do
25
+ silence do
26
+ load_middleware
27
+ end
81
28
  end
82
- end
83
29
 
84
- it "wraps the body in a wrapper" do
85
- _, _, body = listener.call(env)
86
-
87
- expect(body).to be_a(Appsignal::StreamWrapper)
88
- end
30
+ expect(logs).to contains_log(
31
+ :warn,
32
+ "The constant Appsignal::Rack::StreamingListener has been deprecated."
33
+ )
89
34
  end
90
35
  end
91
- end
92
-
93
- describe Appsignal::StreamWrapper do
94
- let(:stream) { double }
95
- let(:transaction) { http_request_transaction }
96
- let(:wrapper) { Appsignal::StreamWrapper.new(stream, transaction) }
97
- before do
98
- start_agent
99
- set_current_transaction(transaction)
100
- end
101
- around { |example| keep_transactions { example.run } }
102
36
 
103
- describe "#each" do
104
- it "calls the original stream" do
105
- expect(stream).to receive(:each)
37
+ describe "middleware" do
38
+ let(:env) { {} }
39
+ let(:app) { DummyApp.new }
40
+ let(:middleware) { Appsignal::Rack::StreamingListener.new(app, {}) }
41
+ around { |example| keep_transactions { example.run } }
42
+ before(:context) { load_middleware }
43
+ before { start_agent }
106
44
 
107
- wrapper.each
45
+ def make_request
46
+ middleware.call(env)
108
47
  end
109
48
 
110
- context "when #each raises an error" do
111
- let(:error) { ExampleException.new("error message") }
112
-
113
- it "records the exception" do
114
- allow(stream).to receive(:each).and_raise(error)
49
+ it "instruments the call" do
50
+ make_request
115
51
 
116
- expect { wrapper.send(:each) }.to raise_error(error)
117
-
118
- expect(transaction).to have_error("ExampleException", "error message")
119
- end
52
+ expect(last_transaction).to include_event("name" => "process_streaming_request.rack")
120
53
  end
121
- end
122
-
123
- describe "#close" do
124
- it "closes the original stream and completes the transaction" do
125
- expect(stream).to receive(:close)
126
54
 
127
- wrapper.close
55
+ it "set no action by default" do
56
+ make_request
128
57
 
129
- expect(current_transaction?).to be_falsy
130
- expect(transaction).to be_completed
58
+ expect(last_transaction).to_not have_action
131
59
  end
132
60
 
133
- context "when #close raises an error" do
134
- let(:error) { ExampleException.new("error message") }
61
+ it "set `appsignal.action` to the action name" do
62
+ env["appsignal.action"] = "Action"
135
63
 
136
- it "records the exception and completes the transaction" do
137
- allow(stream).to receive(:close).and_raise(error)
64
+ make_request
138
65
 
139
- expect { wrapper.send(:close) }.to raise_error(error)
140
-
141
- expect(transaction).to have_error("ExampleException", "error message")
142
- expect(transaction).to be_completed
143
- end
66
+ expect(last_transaction).to have_action("Action")
144
67
  end
145
68
  end
146
69
  end
@@ -326,6 +326,16 @@ describe Appsignal::Transaction do
326
326
  it "returns custom parameters" do
327
327
  expect(subject).to eq(:foo => "bar")
328
328
  end
329
+
330
+ context "when params is a callable object" do
331
+ it "calls the params object and sets the return value as parametesr" do
332
+ transaction.set_params { { "param1" => "value1" } }
333
+
334
+ expect(transaction.params).to eq(
335
+ "param1" => "value1"
336
+ )
337
+ end
338
+ end
329
339
  end
330
340
 
331
341
  context "without custom params set on transaction" do
@@ -374,6 +384,25 @@ describe Appsignal::Transaction do
374
384
  expect(transaction.params).to eq(params)
375
385
  expect(transaction).to include_params(params)
376
386
  end
387
+
388
+ it "updates the params on the transaction with a block" do
389
+ params = { "key" => "value" }
390
+ transaction.set_params { params }
391
+
392
+ transaction._sample
393
+ expect(transaction.params).to eq(params)
394
+ expect(transaction).to include_params(params)
395
+ end
396
+
397
+ it "updates with the params argument when both an argument and block are given" do
398
+ arg_params = { "argument" => "value" }
399
+ block_params = { "block" => "value" }
400
+ transaction.set_params(arg_params) { block_params }
401
+
402
+ transaction._sample
403
+ expect(transaction.params).to eq(arg_params)
404
+ expect(transaction).to include_params(arg_params)
405
+ end
377
406
  end
378
407
 
379
408
  context "when the given params is nil" do
@@ -402,6 +431,25 @@ describe Appsignal::Transaction do
402
431
  expect(transaction).to include_params(params)
403
432
  end
404
433
 
434
+ it "updates the params on the transaction with a block" do
435
+ params = { "key" => "value" }
436
+ transaction.set_params_if_nil { params }
437
+
438
+ transaction._sample
439
+ expect(transaction.params).to eq(params)
440
+ expect(transaction).to include_params(params)
441
+ end
442
+
443
+ it "updates with the params argument when both an argument and block are given" do
444
+ arg_params = { "argument" => "value" }
445
+ block_params = { "block" => "value" }
446
+ transaction.set_params_if_nil(arg_params) { block_params }
447
+
448
+ transaction._sample
449
+ expect(transaction.params).to eq(arg_params)
450
+ expect(transaction).to include_params(arg_params)
451
+ end
452
+
405
453
  context "when the given params is nil" do
406
454
  it "does not update the params on the transaction" do
407
455
  params = { "key" => "value" }
@@ -426,12 +474,24 @@ describe Appsignal::Transaction do
426
474
  expect(transaction.params).to eq(preset_params)
427
475
  expect(transaction).to include_params(preset_params)
428
476
  end
477
+
478
+ it "does not update the params with a block on the transaction" do
479
+ preset_params = { "other" => "params" }
480
+ params = { "key" => "value" }
481
+ transaction.set_params(preset_params)
482
+ transaction.set_params_if_nil { params }
483
+
484
+ transaction._sample
485
+ expect(transaction.params).to eq(preset_params)
486
+ expect(transaction).to include_params(preset_params)
487
+ end
429
488
  end
430
489
  end
431
490
 
432
491
  describe "#set_tags" do
433
492
  let(:long_string) { "a" * 10_001 }
434
- before do
493
+
494
+ it "stores tags on the transaction" do
435
495
  transaction.set_tags(
436
496
  :valid_key => "valid_value",
437
497
  "valid_string_key" => "valid_value",
@@ -443,10 +503,8 @@ describe Appsignal::Transaction do
443
503
  :too_long_value => long_string,
444
504
  long_string => "too_long_key"
445
505
  )
446
- transaction.sample_data
447
- end
506
+ transaction._sample
448
507
 
449
- it "stores tags on the transaction" do
450
508
  expect(transaction).to include_tags(
451
509
  "valid_key" => "valid_value",
452
510
  "valid_string_key" => "valid_value",
@@ -456,6 +514,96 @@ describe Appsignal::Transaction do
456
514
  long_string => "too_long_key"
457
515
  )
458
516
  end
517
+
518
+ it "merges the tags when called multiple times" do
519
+ transaction.set_tags(:key1 => "value1")
520
+ transaction.set_tags(:key2 => "value2")
521
+ transaction._sample
522
+
523
+ expect(transaction).to include_tags(
524
+ "key1" => "value1",
525
+ "key2" => "value2"
526
+ )
527
+ end
528
+ end
529
+
530
+ describe "#set_custom_data" do
531
+ let(:log_stream) { std_stream }
532
+ let(:logs) { log_contents(log_stream) }
533
+ around { |example| use_logger_with(log_stream) { example.run } }
534
+
535
+ it "stores custom Hash data on the transaction" do
536
+ transaction.set_custom_data(
537
+ :user => {
538
+ :id => 123,
539
+ :locale => "abc"
540
+ },
541
+ :organization => {
542
+ :slug => "appsignal",
543
+ :plan => "enterprise"
544
+ }
545
+ )
546
+
547
+ transaction._sample
548
+ expect(transaction).to include_custom_data(
549
+ "user" => {
550
+ "id" => 123,
551
+ "locale" => "abc"
552
+ },
553
+ "organization" => {
554
+ "slug" => "appsignal",
555
+ "plan" => "enterprise"
556
+ }
557
+ )
558
+ end
559
+
560
+ it "stores custom Array data on the transaction" do
561
+ transaction.set_custom_data([
562
+ [123, "abc"],
563
+ ["appsignal", "enterprise"]
564
+ ])
565
+
566
+ transaction._sample
567
+ expect(transaction).to include_custom_data([
568
+ [123, "abc"],
569
+ ["appsignal", "enterprise"]
570
+ ])
571
+ end
572
+
573
+ it "does not store non Hash or Array custom data" do
574
+ transaction.set_custom_data("abc")
575
+ transaction._sample
576
+ expect(transaction).to_not include_custom_data
577
+
578
+ transaction.set_custom_data(123)
579
+ transaction._sample
580
+ expect(transaction).to_not include_custom_data
581
+
582
+ transaction.set_custom_data(Object.new)
583
+ transaction._sample
584
+ expect(transaction).to_not include_custom_data
585
+
586
+ expect(logs).to contains_log(
587
+ :error,
588
+ "set_custom_data: Unsupported data type String received."
589
+ )
590
+ expect(logs).to contains_log(
591
+ :error,
592
+ "set_custom_data: Unsupported data type Integer received."
593
+ )
594
+ expect(logs).to contains_log(
595
+ :error,
596
+ "set_custom_data: Unsupported data type String received."
597
+ )
598
+ end
599
+
600
+ it "overwrites the custom data if called multiple times" do
601
+ transaction.set_custom_data("user" => { "id" => 123 })
602
+ transaction.set_custom_data("user" => { "id" => 456 })
603
+
604
+ transaction._sample
605
+ expect(transaction).to include_custom_data("user" => { "id" => 456 })
606
+ end
459
607
  end
460
608
 
461
609
  describe "#add_breadcrumb" do
@@ -811,6 +959,17 @@ describe Appsignal::Transaction do
811
959
  kind_of(Integer)
812
960
  )
813
961
  end
962
+
963
+ context "when params is a callable object" do
964
+ it "calls the params object and sets the return value as parametesr" do
965
+ transaction.set_params { { "param1" => "value1" } }
966
+
967
+ transaction.sample_data
968
+ expect(transaction).to include_params(
969
+ "param1" => "value1"
970
+ )
971
+ end
972
+ end
814
973
  end
815
974
 
816
975
  describe "#set_error" do
@@ -321,6 +321,20 @@ describe Appsignal do
321
321
  end
322
322
  end
323
323
 
324
+ describe ".report_error" do
325
+ let(:error) { ExampleException.new("specific error") }
326
+
327
+ it "does not raise an error" do
328
+ Appsignal.report_error(error)
329
+ end
330
+
331
+ it "does not create a transaction" do
332
+ expect do
333
+ Appsignal.report_error(error)
334
+ end.to_not(change { created_transactions.count })
335
+ end
336
+ end
337
+
324
338
  describe ".set_namespace" do
325
339
  it "does not raise an error" do
326
340
  Appsignal.set_namespace("custom")
@@ -332,6 +346,12 @@ describe Appsignal do
332
346
  Appsignal.tag_request(:tag => "tag")
333
347
  end
334
348
  end
349
+
350
+ describe ".set_custom_data" do
351
+ it "does not raise an error" do
352
+ Appsignal.set_custom_data(:data => "value")
353
+ end
354
+ end
335
355
  end
336
356
 
337
357
  context "with config and started" do
@@ -466,15 +486,13 @@ describe Appsignal do
466
486
  end
467
487
 
468
488
  describe ".tag_request" do
469
- around do |example|
470
- start_agent
471
- with_current_transaction(transaction) { example.run }
472
- end
489
+ before { start_agent }
473
490
 
474
491
  context "with transaction" do
475
492
  let(:transaction) { http_request_transaction }
493
+ before { set_current_transaction(transaction) }
476
494
 
477
- it "calls set_tags on the current transaction" do
495
+ it "sets tags on the current transaction" do
478
496
  Appsignal.tag_request("a" => "b")
479
497
 
480
498
  transaction._sample
@@ -494,7 +512,85 @@ describe Appsignal do
494
512
  end
495
513
 
496
514
  it "also listens to tag_job" do
497
- expect(Appsignal).to respond_to(:tag_job)
515
+ expect(Appsignal.method(:tag_job)).to eq(Appsignal.method(:tag_request))
516
+ end
517
+
518
+ it "also listens to set_tags" do
519
+ expect(Appsignal.method(:set_tags)).to eq(Appsignal.method(:tag_request))
520
+ end
521
+ end
522
+
523
+ describe ".set_params" do
524
+ before do
525
+ start_agent
526
+ end
527
+
528
+ context "with transaction" do
529
+ let(:transaction) { http_request_transaction }
530
+ before { set_current_transaction(transaction) }
531
+
532
+ it "sets parameters on the transaction" do
533
+ Appsignal.set_params("param1" => "value1")
534
+
535
+ transaction._sample
536
+ expect(transaction).to include_params("param1" => "value1")
537
+ end
538
+
539
+ it "overwrites the params if called multiple times" do
540
+ Appsignal.set_params("param1" => "value1")
541
+ Appsignal.set_params("param2" => "value2")
542
+
543
+ transaction._sample
544
+ expect(transaction).to include_params("param2" => "value2")
545
+ end
546
+
547
+ it "sets parameters with a block on the transaction" do
548
+ Appsignal.set_params { { "param1" => "value1" } }
549
+
550
+ transaction._sample
551
+ expect(transaction).to include_params("param1" => "value1")
552
+ end
553
+ end
554
+
555
+ context "without transaction" do
556
+ it "does not set tags on the transaction" do
557
+ Appsignal.set_params("a" => "b")
558
+
559
+ expect_any_instance_of(Appsignal::Transaction).to_not receive(:set_params)
560
+ end
561
+ end
562
+ end
563
+
564
+ describe ".set_custom_data" do
565
+ before { start_agent }
566
+
567
+ context "with transaction" do
568
+ let(:transaction) { http_request_transaction }
569
+ before { set_current_transaction transaction }
570
+
571
+ it "sets custom data on the current transaction" do
572
+ Appsignal.set_custom_data(
573
+ :user => { :id => 123 },
574
+ :organization => { :slug => "appsignal" }
575
+ )
576
+
577
+ transaction._sample
578
+ expect(transaction).to include_custom_data(
579
+ "user" => { "id" => 123 },
580
+ "organization" => { "slug" => "appsignal" }
581
+ )
582
+ end
583
+ end
584
+
585
+ context "without transaction" do
586
+ it "does not set tags on the transaction" do
587
+ Appsignal.set_custom_data(
588
+ :user => { :id => 123 },
589
+ :organization => { :slug => "appsignal" }
590
+ )
591
+
592
+ expect_any_instance_of(Appsignal::Transaction).to_not receive(:set_custom_data)
593
+ end
498
594
  end
499
595
  end
500
596
 
@@ -993,6 +1089,101 @@ describe Appsignal do
993
1089
  end
994
1090
  end
995
1091
 
1092
+ describe ".report_error" do
1093
+ let(:err_stream) { std_stream }
1094
+ let(:stderr) { err_stream.read }
1095
+ let(:error) { ExampleException.new("error message") }
1096
+ before { start_agent }
1097
+ around { |example| keep_transactions { example.run } }
1098
+
1099
+ context "when the error is not an Exception" do
1100
+ let(:error) { Object.new }
1101
+
1102
+ it "does not set an error" do
1103
+ silence { Appsignal.report_error(error) }
1104
+
1105
+ expect(last_transaction).to_not have_error
1106
+ end
1107
+
1108
+ it "logs an error" do
1109
+ logs = capture_logs { Appsignal.report_error(error) }
1110
+ expect(logs).to contains_log(
1111
+ :error,
1112
+ "Appsignal.report_error: Cannot set error. " \
1113
+ "The given value is not an exception: #{error.inspect}"
1114
+ )
1115
+ end
1116
+ end
1117
+
1118
+ context "when there is no active transaction" do
1119
+ it "creates a new transaction" do
1120
+ expect do
1121
+ Appsignal.report_error(error)
1122
+ end.to(change { created_transactions.count }.by(1))
1123
+ end
1124
+
1125
+ it "completes the transaction" do
1126
+ Appsignal.report_error(error)
1127
+
1128
+ expect(last_transaction).to be_completed
1129
+ end
1130
+
1131
+ context "when given a block" do
1132
+ it "yields the transaction and allows additional metadata to be set" do
1133
+ Appsignal.report_error(error) do |t|
1134
+ t.set_action("my_action")
1135
+ t.set_namespace("my_namespace")
1136
+ t.set_tags(:tag1 => "value1")
1137
+ end
1138
+
1139
+ transaction = last_transaction
1140
+ expect(transaction).to have_namespace("my_namespace")
1141
+ expect(transaction).to have_action("my_action")
1142
+ expect(transaction).to have_error("ExampleException", "error message")
1143
+ expect(transaction).to include_tags("tag1" => "value1")
1144
+ expect(transaction).to be_completed
1145
+ end
1146
+ end
1147
+ end
1148
+
1149
+ context "when there is an active transaction" do
1150
+ let(:transaction) { http_request_transaction }
1151
+ before { set_current_transaction(transaction) }
1152
+
1153
+ it "adds the error to the active transaction" do
1154
+ Appsignal.report_error(error)
1155
+
1156
+ expect(last_transaction).to eq(transaction)
1157
+ transaction._sample
1158
+ expect(transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
1159
+ expect(transaction).to have_error("ExampleException", "error message")
1160
+ end
1161
+
1162
+ it "does not complete the transaction" do
1163
+ Appsignal.report_error(error)
1164
+
1165
+ expect(last_transaction).to_not be_completed
1166
+ end
1167
+
1168
+ context "when given a block" do
1169
+ it "yields the transaction and allows additional metadata to be set" do
1170
+ Appsignal.report_error(error) do |t|
1171
+ t.set_action("my_action")
1172
+ t.set_namespace("my_namespace")
1173
+ t.set_tags(:tag1 => "value1")
1174
+ end
1175
+
1176
+ transaction._sample
1177
+ expect(transaction).to have_namespace("my_namespace")
1178
+ expect(transaction).to have_action("my_action")
1179
+ expect(transaction).to have_error("ExampleException", "error message")
1180
+ expect(transaction).to include_tags("tag1" => "value1")
1181
+ expect(transaction).to_not be_completed
1182
+ end
1183
+ end
1184
+ end
1185
+ end
1186
+
996
1187
  describe ".set_action" do
997
1188
  around { |example| keep_transactions { example.run } }
998
1189
 
@@ -8,7 +8,7 @@ class DummyApp
8
8
  if @app
9
9
  @app&.call(env)
10
10
  else
11
- [200, {}, "body"]
11
+ [200, {}, ["body"]]
12
12
  end
13
13
  ensure
14
14
  @called = true