appsignal 3.9.2-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 (105) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +3138 -0
  3. data/.rubocop.yml +28 -20
  4. data/.rubocop_todo.yml +7 -33
  5. data/CHANGELOG.md +130 -0
  6. data/README.md +0 -1
  7. data/Rakefile +80 -65
  8. data/appsignal.gemspec +1 -1
  9. data/build_matrix.yml +112 -184
  10. data/ext/base.rb +1 -1
  11. data/gemfiles/hanami-2.1.gemfile +7 -0
  12. data/gemfiles/webmachine1.gemfile +5 -4
  13. data/lib/appsignal/cli/diagnose.rb +1 -1
  14. data/lib/appsignal/config.rb +5 -1
  15. data/lib/appsignal/demo.rb +0 -1
  16. data/lib/appsignal/environment.rb +11 -2
  17. data/lib/appsignal/extension/jruby.rb +1 -1
  18. data/lib/appsignal/helpers/instrumentation.rb +164 -2
  19. data/lib/appsignal/hooks/active_job.rb +1 -6
  20. data/lib/appsignal/integrations/grape.rb +19 -47
  21. data/lib/appsignal/integrations/hanami.rb +8 -7
  22. data/lib/appsignal/integrations/padrino.rb +51 -52
  23. data/lib/appsignal/integrations/railtie.rb +0 -3
  24. data/lib/appsignal/integrations/rake.rb +46 -12
  25. data/lib/appsignal/integrations/sidekiq.rb +1 -11
  26. data/lib/appsignal/integrations/sinatra.rb +0 -1
  27. data/lib/appsignal/integrations/webmachine.rb +15 -9
  28. data/lib/appsignal/probes/gvl.rb +24 -2
  29. data/lib/appsignal/probes/sidekiq.rb +1 -1
  30. data/lib/appsignal/probes.rb +1 -1
  31. data/lib/appsignal/rack/abstract_middleware.rb +104 -33
  32. data/lib/appsignal/rack/body_wrapper.rb +143 -0
  33. data/lib/appsignal/rack/event_handler.rb +12 -3
  34. data/lib/appsignal/rack/generic_instrumentation.rb +5 -4
  35. data/lib/appsignal/rack/grape_middleware.rb +40 -0
  36. data/lib/appsignal/rack/hanami_middleware.rb +2 -12
  37. data/lib/appsignal/rack/instrumentation_middleware.rb +62 -0
  38. data/lib/appsignal/rack/rails_instrumentation.rb +14 -57
  39. data/lib/appsignal/rack/sinatra_instrumentation.rb +1 -3
  40. data/lib/appsignal/rack/streaming_listener.rb +13 -59
  41. data/lib/appsignal/rack.rb +31 -0
  42. data/lib/appsignal/transaction.rb +50 -8
  43. data/lib/appsignal/utils/integration_memory_logger.rb +78 -0
  44. data/lib/appsignal/utils.rb +1 -0
  45. data/lib/appsignal/version.rb +1 -1
  46. data/lib/appsignal.rb +36 -33
  47. data/spec/.rubocop.yml +1 -1
  48. data/spec/lib/appsignal/cli/diagnose_spec.rb +1 -1
  49. data/spec/lib/appsignal/cli/install_spec.rb +3 -3
  50. data/spec/lib/appsignal/config_spec.rb +8 -5
  51. data/spec/lib/appsignal/demo_spec.rb +38 -41
  52. data/spec/lib/appsignal/hooks/action_cable_spec.rb +86 -167
  53. data/spec/lib/appsignal/hooks/active_support_notifications/finish_with_state_shared_examples.rb +8 -20
  54. data/spec/lib/appsignal/hooks/active_support_notifications/instrument_shared_examples.rb +38 -84
  55. data/spec/lib/appsignal/hooks/active_support_notifications/start_finish_shared_examples.rb +16 -37
  56. data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +4 -4
  57. data/spec/lib/appsignal/hooks/activejob_spec.rb +111 -200
  58. data/spec/lib/appsignal/hooks/delayed_job_spec.rb +54 -91
  59. data/spec/lib/appsignal/hooks/dry_monitor_spec.rb +14 -32
  60. data/spec/lib/appsignal/hooks/excon_spec.rb +8 -12
  61. data/spec/lib/appsignal/hooks/net_http_spec.rb +7 -42
  62. data/spec/lib/appsignal/hooks/rake_spec.rb +107 -34
  63. data/spec/lib/appsignal/hooks/redis_client_spec.rb +18 -30
  64. data/spec/lib/appsignal/hooks/redis_spec.rb +10 -16
  65. data/spec/lib/appsignal/hooks/resque_spec.rb +42 -62
  66. data/spec/lib/appsignal/hooks/shoryuken_spec.rb +33 -74
  67. data/spec/lib/appsignal/integrations/hanami_spec.rb +79 -21
  68. data/spec/lib/appsignal/integrations/http_spec.rb +12 -20
  69. data/spec/lib/appsignal/integrations/net_http_spec.rb +33 -0
  70. data/spec/lib/appsignal/integrations/object_spec.rb +29 -36
  71. data/spec/lib/appsignal/integrations/padrino_spec.rb +190 -163
  72. data/spec/lib/appsignal/integrations/que_spec.rb +43 -70
  73. data/spec/lib/appsignal/integrations/railtie_spec.rb +26 -67
  74. data/spec/lib/appsignal/integrations/sidekiq_spec.rb +86 -160
  75. data/spec/lib/appsignal/integrations/sinatra_spec.rb +10 -3
  76. data/spec/lib/appsignal/integrations/webmachine_spec.rb +77 -40
  77. data/spec/lib/appsignal/probes/gvl_spec.rb +80 -3
  78. data/spec/lib/appsignal/probes_spec.rb +7 -4
  79. data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +302 -105
  80. data/spec/lib/appsignal/rack/body_wrapper_spec.rb +263 -0
  81. data/spec/lib/appsignal/rack/event_handler_spec.rb +81 -78
  82. data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +70 -27
  83. data/spec/lib/appsignal/rack/grape_middleware_spec.rb +234 -0
  84. data/spec/lib/appsignal/rack/hanami_middleware_spec.rb +2 -16
  85. data/spec/lib/appsignal/rack/instrumentation_middleware_spec.rb +38 -0
  86. data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +67 -131
  87. data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +36 -44
  88. data/spec/lib/appsignal/rack/streaming_listener_spec.rb +44 -139
  89. data/spec/lib/appsignal/transaction_spec.rb +239 -94
  90. data/spec/lib/appsignal/utils/integration_memory_logger_spec.rb +163 -0
  91. data/spec/lib/appsignal_spec.rb +556 -344
  92. data/spec/support/helpers/dependency_helper.rb +6 -1
  93. data/spec/support/helpers/std_streams_helper.rb +1 -1
  94. data/spec/support/helpers/transaction_helpers.rb +8 -0
  95. data/spec/support/matchers/transaction.rb +185 -0
  96. data/spec/support/mocks/dummy_app.rb +20 -0
  97. data/spec/support/shared_examples/instrument.rb +17 -12
  98. data/spec/support/testing.rb +18 -9
  99. metadata +20 -11
  100. data/.semaphore/semaphore.yml +0 -2347
  101. data/script/lint_git +0 -22
  102. data/spec/lib/appsignal/integrations/grape_spec.rb +0 -239
  103. data/spec/support/matchers/be_completed.rb +0 -5
  104. data/support/check_versions +0 -22
  105. /data/gemfiles/{hanami.gemfile → hanami-2.0.gemfile} +0 -0
@@ -2,51 +2,134 @@ if DependencyHelper.padrino_present?
2
2
  describe "Padrino integration" do
3
3
  require "appsignal/integrations/padrino"
4
4
 
5
- before do
6
- allow(Appsignal).to receive(:active?).and_return(true)
7
- allow(Appsignal).to receive(:start).and_return(true)
8
- allow(Appsignal).to receive(:start_logger).and_return(true)
9
- end
10
-
11
5
  describe Appsignal::Integrations::PadrinoPlugin do
12
- it "starts AppSignal on init" do
13
- expect(Appsignal).to receive(:start)
6
+ let(:callbacks) { { :before_load => nil } }
7
+ before do
8
+ Appsignal.config = nil
9
+ allow(Padrino).to receive(:before_load)
10
+ .and_wrap_original do |original_method, *args, &block|
11
+ callbacks[:before_load] = block
12
+ original_method.call(*args, &block)
13
+ end
14
14
  end
15
-
16
- it "starts the logger on init" do
17
- expect(Appsignal).to receive(:start_logger)
15
+ after { uninstall_padrino_integration }
16
+
17
+ def uninstall_padrino_integration
18
+ expected_middleware = [
19
+ Rack::Events,
20
+ Appsignal::Rack::SinatraBaseInstrumentation
21
+ ]
22
+ Padrino.middleware.delete_if do |middleware|
23
+ expected_middleware.include?(middleware.first)
24
+ end
18
25
  end
19
26
 
20
- context "when not active" do
21
- before { allow(Appsignal).to receive(:active?).and_return(false) }
27
+ context "when already active" do
28
+ before { allow(Appsignal).to receive(:active?).and_return(true) }
22
29
 
23
- it "does not add the listener middleware to the stack" do
24
- expect(Padrino).to_not receive(:use)
30
+ it "does not start AppSignal again" do
31
+ expect(Appsignal::Config).to_not receive(:new)
32
+ expect(Appsignal).to_not receive(:start)
33
+
34
+ Appsignal::Integrations::PadrinoPlugin.init
35
+ callbacks[:before_load].call
36
+ end
37
+
38
+ it "adds the instrumentation middleware to Sinatra::Base" do
39
+ Appsignal::Integrations::PadrinoPlugin.init
40
+ callbacks[:before_load].call
41
+
42
+ middlewares = Padrino.middleware
43
+ expect(middlewares).to include(
44
+ [Rack::Events, [[instance_of(Appsignal::Rack::EventHandler)]], nil]
45
+ )
46
+ expect(middlewares).to include(
47
+ [
48
+ Appsignal::Rack::SinatraBaseInstrumentation,
49
+ [
50
+ :instrument_event_name => "process_action.padrino"
51
+ ],
52
+ nil
53
+ ]
54
+ )
25
55
  end
26
56
  end
27
57
 
28
- context "when APPSIGNAL_APP_ENV ENV var is provided" do
29
- it "uses this as the environment" do
30
- ENV["APPSIGNAL_APP_ENV"] = "custom"
58
+ context "with active config" do
59
+ before do
60
+ ENV["APPSIGNAL_APP_NAME"] = "My Padrino app name"
61
+ ENV["APPSIGNAL_APP_ENV"] = "test"
62
+ ENV["APPSIGNAL_PUSH_API_KEY"] = "my-key"
63
+ end
64
+
65
+ it "starts AppSignal on init" do
66
+ expect(Appsignal).to_not be_active
31
67
 
32
- # Reset the plugin to pull down the latest data
33
68
  Appsignal::Integrations::PadrinoPlugin.init
69
+ callbacks[:before_load].call
70
+
71
+ expect(Appsignal).to be_active
72
+ middlewares = Padrino.middleware
73
+ expect(middlewares).to include(
74
+ [Rack::Events, [[instance_of(Appsignal::Rack::EventHandler)]], nil]
75
+ )
76
+ expect(middlewares).to include(
77
+ [
78
+ Appsignal::Rack::SinatraBaseInstrumentation,
79
+ [
80
+ :instrument_event_name => "process_action.padrino"
81
+ ],
82
+ nil
83
+ ]
84
+ )
85
+ end
86
+
87
+ context "when APPSIGNAL_APP_ENV ENV var is provided" do
88
+ it "uses this as the environment" do
89
+ ENV["APPSIGNAL_APP_ENV"] = "custom"
90
+
91
+ Appsignal::Integrations::PadrinoPlugin.init
92
+ callbacks[:before_load].call
34
93
 
35
- expect(Appsignal.config.env).to eq("custom")
94
+ expect(Appsignal.config.env).to eq("custom")
95
+ end
36
96
  end
37
- end
38
97
 
39
- context "when APPSIGNAL_APP_ENV ENV var is not provided" do
40
- it "uses the Padrino environment" do
41
- # Reset the plugin to pull down the latest data
42
- Appsignal::Integrations::PadrinoPlugin.init
98
+ context "when APPSIGNAL_APP_ENV ENV var is not provided" do
99
+ it "uses the Padrino environment" do
100
+ Appsignal::Integrations::PadrinoPlugin.init
101
+ callbacks[:before_load].call
43
102
 
44
- expect(Padrino.env.to_s).to eq("test")
45
- expect(Appsignal.config.env).to eq(Padrino.env.to_s)
103
+ expect(Padrino.env.to_s).to eq("test")
104
+ expect(Appsignal.config.env).to eq(Padrino.env.to_s)
105
+ end
46
106
  end
47
107
  end
48
108
 
49
- after { Appsignal::Integrations::PadrinoPlugin.init }
109
+ context "when not active" do
110
+ it "does not add the listener middleware to the stack" do
111
+ expect(Appsignal).to_not be_active
112
+
113
+ Appsignal::Integrations::PadrinoPlugin.init
114
+ callbacks[:before_load].call
115
+
116
+ expect(Appsignal).to_not be_active
117
+ middlewares = Padrino.middleware
118
+ expect(middlewares).to_not include(
119
+ [Rack::Events, [[instance_of(Appsignal::Rack::EventHandler)]], nil]
120
+ )
121
+ expect(middlewares).to_not include(
122
+ [
123
+ Appsignal::Rack::SinatraBaseInstrumentation,
124
+ [
125
+ :request_class => ::Sinatra::Request,
126
+ :instrument_event_name => "process_action.padrino"
127
+ ],
128
+ nil
129
+ ]
130
+ )
131
+ end
132
+ end
50
133
  end
51
134
 
52
135
  describe Padrino::Routing::InstanceMethods do
@@ -59,21 +142,10 @@ if DependencyHelper.padrino_present?
59
142
  let(:env) { {} }
60
143
  # TODO: use an instance double
61
144
  let(:settings) { double(:name => "TestApp") }
145
+ around { |example| keep_transactions { example.run } }
146
+ before { Appsignal.config = nil }
62
147
 
63
148
  describe "routes" do
64
- let(:transaction) do
65
- instance_double "Appsignal::Transaction",
66
- :set_http_or_background_action => nil,
67
- :set_http_or_background_queue_start => nil,
68
- :set_metadata => nil,
69
- :set_action => nil,
70
- :set_action_if_nil => nil,
71
- :set_error => nil,
72
- :start_event => nil,
73
- :finish_event => nil,
74
- :complete => nil
75
- end
76
- let(:request_kind) { kind_of(Sinatra::Request) }
77
149
  let(:env) do
78
150
  {
79
151
  "REQUEST_METHOD" => "GET",
@@ -90,10 +162,6 @@ if DependencyHelper.padrino_present?
90
162
  end
91
163
  end
92
164
  let(:response) { app.call(env) }
93
- before do
94
- allow(Appsignal::Transaction).to receive(:create).and_return(transaction)
95
- allow(Appsignal::Transaction).to receive(:current).and_return(transaction)
96
- end
97
165
 
98
166
  RSpec::Matchers.define :match_response do |expected_status, expected_content|
99
167
  match do |response|
@@ -108,47 +176,30 @@ if DependencyHelper.padrino_present?
108
176
  end
109
177
  end
110
178
 
111
- def expect_a_transaction_to_be_created
112
- expect(Appsignal::Transaction).to receive(:create).with(
113
- kind_of(String),
114
- Appsignal::Transaction::HTTP_REQUEST,
115
- request_kind
116
- ).and_return(transaction)
117
-
118
- expect(Appsignal).to receive(:instrument)
119
- .at_least(:once)
120
- .with("process_action.padrino")
121
- .and_call_original
122
- expect(transaction).to receive(:set_metadata).with("path", path)
123
- expect(transaction).to receive(:set_metadata).with("method", "GET")
124
- expect(transaction).to receive(:complete)
125
- end
126
-
127
- def expect_no_transaction_to_be_created
128
- expect(Appsignal::Transaction).to_not receive(:create)
129
- expect(Appsignal).to_not receive(:instrument)
130
- end
131
-
132
179
  context "when AppSignal is not active" do
133
- before { allow(Appsignal).to receive(:active?).and_return(false) }
134
180
  let(:path) { "/foo" }
135
181
  before { app.controllers { get(:foo) { "content" } } }
136
- after { expect(response).to match_response(200, "content") }
137
182
 
138
183
  it "does not instrument the request" do
139
- expect_no_transaction_to_be_created
184
+ expect do
185
+ expect(response).to match_response(200, "content")
186
+ end.to_not(change { created_transactions.count })
140
187
  end
141
188
  end
142
189
 
143
190
  context "when AppSignal is active" do
191
+ let(:transaction) { http_request_transaction }
192
+ before do
193
+ start_agent
194
+ set_current_transaction(transaction)
195
+ end
196
+
144
197
  context "with not existing route" do
145
198
  let(:path) { "/404" }
146
199
 
147
200
  it "instruments the request" do
148
- expect_a_transaction_to_be_created
149
- # Uses path for action name
150
- expect(transaction).to receive(:set_action_if_nil).with("PadrinoTestApp#unknown")
151
201
  expect(response).to match_response(404, /^GET /404/)
202
+ expect(last_transaction).to have_action("PadrinoTestApp#unknown")
152
203
  end
153
204
  end
154
205
 
@@ -158,10 +209,10 @@ if DependencyHelper.padrino_present?
158
209
  env["sinatra.static_file"] = true
159
210
  app.controllers { get(:static) { "Static!" } }
160
211
  end
161
- after { expect(response).to match_response(200, "Static!") }
162
212
 
163
213
  it "does not instrument the request" do
164
- expect_no_transaction_to_be_created
214
+ expect(response).to match_response(200, "Static!")
215
+ expect(last_transaction).to_not have_action
165
216
  end
166
217
  end
167
218
 
@@ -172,12 +223,10 @@ if DependencyHelper.padrino_present?
172
223
  allow_any_instance_of(Sinatra::Request).to receive(:action).and_return(nil)
173
224
  app.controllers { get(:my_original_path, :with => :id) { "content" } }
174
225
  end
175
- after { expect(response).to match_response(200, "content") }
176
226
 
177
227
  it "falls back on Sinatra::Request#route_obj.original_path" do
178
- expect_a_transaction_to_be_created
179
- expect(transaction)
180
- .to receive(:set_action_if_nil).with("PadrinoTestApp:/my_original_path/:id")
228
+ expect(response).to match_response(200, "content")
229
+ expect(last_transaction).to have_action("PadrinoTestApp:/my_original_path/:id")
181
230
  end
182
231
  end
183
232
 
@@ -188,117 +237,95 @@ if DependencyHelper.padrino_present?
188
237
  allow_any_instance_of(Sinatra::Request).to receive(:route_obj).and_return(nil)
189
238
  app.controllers { get(:my_original_path) { "content" } }
190
239
  end
191
- after { expect(response).to match_response(200, "content") }
192
240
 
193
241
  it "falls back on app name" do
194
- expect_a_transaction_to_be_created
195
- expect(transaction).to receive(:set_action_if_nil).with("PadrinoTestApp#unknown")
242
+ expect(response).to match_response(200, "content")
243
+ expect(last_transaction).to have_action("PadrinoTestApp#unknown")
196
244
  end
197
245
  end
198
246
 
199
247
  context "with existing route" do
200
- context "with an exception in the controller" do
201
- let(:path) { "/exception" }
202
- before do
203
- app.controllers { get(:exception) { raise ExampleException } }
204
- expect_a_transaction_to_be_created
205
- end
206
- after do
207
- expect { response }.to raise_error(ExampleException)
208
- end
248
+ let(:path) { "/" }
249
+ def make_request
250
+ expect(response).to match_response(200, "content")
251
+ end
209
252
 
210
- it "sets the action name based on the app name and action name" do
211
- expect(transaction).to receive(:set_action_if_nil).with("PadrinoTestApp:#exception")
253
+ context "with action name as symbol" do
254
+ context "with :index helper" do
255
+ before do
256
+ # :index == "/"
257
+ app.controllers { get(:index) { "content" } }
258
+ end
259
+
260
+ it "sets the action with the app name and action name" do
261
+ make_request
262
+ expect(last_transaction).to have_action("PadrinoTestApp:#index")
263
+ end
212
264
  end
213
265
 
214
- it "sets the error on the transaction" do
215
- expect(transaction).to receive(:set_error).with(ExampleException)
266
+ context "with custom action name" do
267
+ let(:path) { "/foo" }
268
+ before do
269
+ app.controllers { get(:foo) { "content" } }
270
+ end
271
+
272
+ it "sets the action with the app name and action name" do
273
+ make_request
274
+ expect(last_transaction).to have_action("PadrinoTestApp:#foo")
275
+ end
216
276
  end
217
277
  end
218
278
 
219
- context "without an exception in the controller" do
220
- let(:path) { "/" }
221
- after { expect(response).to match_response(200, "content") }
222
-
223
- context "with action name as symbol" do
224
- context "with :index helper" do
225
- before do
226
- # :index == "/"
227
- app.controllers { get(:index) { "content" } }
228
- end
229
-
230
- it "sets the action with the app name and action name" do
231
- expect_a_transaction_to_be_created
232
- expect(transaction).to receive(:set_action_if_nil).with("PadrinoTestApp:#index")
233
- end
279
+ context "with an action defined with a path" do
280
+ context "with root path" do
281
+ before do
282
+ # :index == "/"
283
+ app.controllers { get("/") { "content" } }
234
284
  end
235
285
 
236
- context "with custom action name" do
237
- let(:path) { "/foo" }
238
- before do
239
- app.controllers { get(:foo) { "content" } }
240
- end
241
-
242
- it "sets the action with the app name and action name" do
243
- expect_a_transaction_to_be_created
244
- expect(transaction).to receive(:set_action_if_nil).with("PadrinoTestApp:#foo")
245
- end
286
+ it "sets the action with the app name and action path" do
287
+ make_request
288
+ expect(last_transaction).to have_action("PadrinoTestApp:#/")
246
289
  end
247
290
  end
248
291
 
249
- context "with an action defined with a path" do
250
- context "with root path" do
251
- before do
252
- # :index == "/"
253
- app.controllers { get("/") { "content" } }
254
- end
255
-
256
- it "sets the action with the app name and action path" do
257
- expect_a_transaction_to_be_created
258
- expect(transaction).to receive(:set_action_if_nil).with("PadrinoTestApp:#/")
259
- end
292
+ context "with custom path" do
293
+ let(:path) { "/foo" }
294
+ before do
295
+ app.controllers { get("/foo") { "content" } }
260
296
  end
261
297
 
262
- context "with custom path" do
263
- let(:path) { "/foo" }
264
- before do
265
- app.controllers { get("/foo") { "content" } }
266
- end
267
-
268
- it "sets the action with the app name and action path" do
269
- expect_a_transaction_to_be_created
270
- expect(transaction).to receive(:set_action_if_nil).with("PadrinoTestApp:#/foo")
271
- end
298
+ it "sets the action with the app name and action path" do
299
+ make_request
300
+ expect(last_transaction).to have_action("PadrinoTestApp:#/foo")
272
301
  end
273
302
  end
303
+ end
304
+
305
+ context "with controller" do
306
+ let(:path) { "/my_controller" }
274
307
 
275
- context "with controller" do
276
- let(:path) { "/my_controller" }
308
+ context "with controller as name" do
309
+ before do
310
+ # :index == "/"
311
+ app.controllers(:my_controller) { get(:index) { "content" } }
312
+ end
277
313
 
278
- context "with controller as name" do
279
- before do
280
- # :index == "/"
281
- app.controllers(:my_controller) { get(:index) { "content" } }
282
- end
314
+ it "sets the action with the app name, controller name and action name" do
315
+ make_request
316
+ expect(last_transaction).to have_action("PadrinoTestApp:my_controller#index")
317
+ end
318
+ end
283
319
 
284
- it "sets the action with the app name, controller name and action name" do
285
- expect_a_transaction_to_be_created
286
- expect(transaction).to receive(:set_action_if_nil)
287
- .with("PadrinoTestApp:my_controller#index")
288
- end
320
+ context "with controller as path" do
321
+ before do
322
+ # :index == "/"
323
+ app.controllers("/my_controller") { get(:index) { "content" } }
289
324
  end
290
325
 
291
- context "with controller as path" do
292
- before do
293
- # :index == "/"
294
- app.controllers("/my_controller") { get(:index) { "content" } }
295
- end
296
-
297
- it "sets the action with the app name, controller name and action path" do
298
- expect_a_transaction_to_be_created
299
- expect(transaction).to receive(:set_action_if_nil)
300
- .with("PadrinoTestApp:/my_controller#index")
301
- end
326
+ it "sets the action with the app name, controller name and action path" do
327
+ make_request
328
+ expect(last_transaction).to have_action("PadrinoTestApp:/my_controller#index")
302
329
  end
303
330
  end
304
331
  end
@@ -53,38 +53,27 @@ if DependencyHelper.que_present?
53
53
  perform_que_job(instance)
54
54
  end.to change { created_transactions.length }.by(1)
55
55
 
56
- expect(last_transaction).to be_completed
57
- transaction_hash = last_transaction.to_h
58
- expect(transaction_hash).to include(
59
- "action" => "MyQueJob#run",
60
- "id" => instance_of(String),
61
- "namespace" => Appsignal::Transaction::BACKGROUND_JOB
62
- )
63
- expect(transaction_hash["error"]).to be_nil
64
- expect(transaction_hash["events"].first).to include(
65
- "allocation_count" => kind_of(Integer),
56
+ transaction = last_transaction
57
+ expect(transaction).to have_id
58
+ expect(transaction).to have_namespace(Appsignal::Transaction::BACKGROUND_JOB)
59
+ expect(transaction).to have_action("MyQueJob#run")
60
+ expect(transaction).to_not have_error
61
+ expect(transaction).to include_event(
66
62
  "body" => "",
67
63
  "body_format" => Appsignal::EventFormatter::DEFAULT,
68
- "child_allocation_count" => kind_of(Integer),
69
- "child_duration" => kind_of(Float),
70
- "child_gc_duration" => kind_of(Float),
71
64
  "count" => 1,
72
- "gc_duration" => kind_of(Float),
73
- "start" => kind_of(Float),
74
- "duration" => kind_of(Float),
75
65
  "name" => "perform_job.que",
76
66
  "title" => ""
77
67
  )
78
- expect(transaction_hash["sample_data"]).to include(
79
- "params" => %w[1 birds],
80
- "metadata" => {
81
- "attempts" => 0,
82
- "id" => 123,
83
- "priority" => 100,
84
- "queue" => "dfl",
85
- "run_at" => fixed_time.to_s
86
- }
68
+ expect(transaction).to include_params(%w[1 birds])
69
+ expect(transaction).to include_sample_metadata(
70
+ "attempts" => 0,
71
+ "id" => 123,
72
+ "priority" => 100,
73
+ "queue" => "dfl",
74
+ "run_at" => fixed_time.to_s
87
75
  )
76
+ expect(transaction).to be_completed
88
77
  end
89
78
  end
90
79
 
@@ -100,28 +89,20 @@ if DependencyHelper.que_present?
100
89
  end.to raise_error(ExampleException)
101
90
  end.to change { created_transactions.length }.by(1)
102
91
 
103
- expect(last_transaction).to be_completed
104
- transaction_hash = last_transaction.to_h
105
- expect(transaction_hash).to include(
106
- "action" => "MyQueJob#run",
107
- "id" => instance_of(String),
108
- "namespace" => Appsignal::Transaction::BACKGROUND_JOB
109
- )
110
- expect(transaction_hash["error"]).to include(
111
- "backtrace" => kind_of(String),
112
- "name" => error.class.name,
113
- "message" => error.message
114
- )
115
- expect(transaction_hash["sample_data"]).to include(
116
- "params" => %w[1 birds],
117
- "metadata" => {
118
- "attempts" => 0,
119
- "id" => 123,
120
- "priority" => 100,
121
- "queue" => "dfl",
122
- "run_at" => fixed_time.to_s
123
- }
92
+ transaction = last_transaction
93
+ expect(transaction).to have_id
94
+ expect(transaction).to have_action("MyQueJob#run")
95
+ expect(transaction).to have_namespace(Appsignal::Transaction::BACKGROUND_JOB)
96
+ expect(transaction).to have_error(error.class.name, error.message)
97
+ expect(transaction).to include_params(%w[1 birds])
98
+ expect(transaction).to include_sample_metadata(
99
+ "attempts" => 0,
100
+ "id" => 123,
101
+ "priority" => 100,
102
+ "queue" => "dfl",
103
+ "run_at" => fixed_time.to_s
124
104
  )
105
+ expect(transaction).to be_completed
125
106
  end
126
107
  end
127
108
 
@@ -133,28 +114,20 @@ if DependencyHelper.que_present?
133
114
 
134
115
  expect { perform_que_job(instance) }.to change { created_transactions.length }.by(1)
135
116
 
136
- expect(last_transaction).to be_completed
137
- transaction_hash = last_transaction.to_h
138
- expect(transaction_hash).to include(
139
- "action" => "MyQueJob#run",
140
- "id" => instance_of(String),
141
- "namespace" => Appsignal::Transaction::BACKGROUND_JOB
142
- )
143
- expect(transaction_hash["error"]).to include(
144
- "backtrace" => kind_of(String),
145
- "name" => error.class.name,
146
- "message" => error.message
147
- )
148
- expect(transaction_hash["sample_data"]).to include(
149
- "params" => %w[1 birds],
150
- "metadata" => {
151
- "attempts" => 0,
152
- "id" => 123,
153
- "priority" => 100,
154
- "queue" => "dfl",
155
- "run_at" => fixed_time.to_s
156
- }
117
+ transaction = last_transaction
118
+ expect(transaction).to have_id
119
+ expect(transaction).to have_action("MyQueJob#run")
120
+ expect(transaction).to have_namespace(Appsignal::Transaction::BACKGROUND_JOB)
121
+ expect(transaction).to have_error(error.class.name, error.message)
122
+ expect(transaction).to include_params(%w[1 birds])
123
+ expect(transaction).to include_sample_metadata(
124
+ "attempts" => 0,
125
+ "id" => 123,
126
+ "priority" => 100,
127
+ "queue" => "dfl",
128
+ "run_at" => fixed_time.to_s
157
129
  )
130
+ expect(transaction).to be_completed
158
131
  end
159
132
  end
160
133
 
@@ -170,9 +143,9 @@ if DependencyHelper.que_present?
170
143
  it "uses the custom action" do
171
144
  perform_que_job(instance)
172
145
 
173
- expect(last_transaction).to be_completed
174
- transaction_hash = last_transaction.to_h
175
- expect(transaction_hash).to include("action" => "MyCustomJob#perform")
146
+ transaction = last_transaction
147
+ expect(transaction).to have_action("MyCustomJob#perform")
148
+ expect(transaction).to be_completed
176
149
  end
177
150
  end
178
151
  end