appsignal 3.9.2-java → 3.10.0-java

Sign up to get free protection for your applications and to get access to all the features.
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