appsignal 3.9.1-java → 3.9.3-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 +3135 -0
- data/.rubocop.yml +28 -20
- data/.rubocop_todo.yml +7 -33
- data/CHANGELOG.md +58 -0
- data/Rakefile +79 -64
- data/appsignal.gemspec +1 -1
- data/build_matrix.yml +109 -179
- data/ext/base.rb +1 -1
- data/gemfiles/hanami-2.1.gemfile +7 -0
- data/lib/appsignal/cli/diagnose.rb +1 -1
- data/lib/appsignal/config.rb +1 -1
- data/lib/appsignal/demo.rb +0 -1
- data/lib/appsignal/environment.rb +5 -1
- data/lib/appsignal/extension/jruby.rb +1 -1
- data/lib/appsignal/helpers/instrumentation.rb +3 -3
- data/lib/appsignal/hooks/active_job.rb +2 -1
- data/lib/appsignal/integrations/action_cable.rb +1 -1
- data/lib/appsignal/integrations/grape.rb +19 -47
- data/lib/appsignal/integrations/hanami.rb +27 -41
- data/lib/appsignal/integrations/padrino.rb +46 -43
- data/lib/appsignal/integrations/railtie.rb +1 -4
- data/lib/appsignal/integrations/resque.rb +1 -1
- data/lib/appsignal/integrations/sidekiq.rb +2 -4
- data/lib/appsignal/integrations/sinatra.rb +7 -2
- data/lib/appsignal/probes/gvl.rb +24 -2
- data/lib/appsignal/probes/sidekiq.rb +1 -1
- data/lib/appsignal/probes.rb +1 -1
- data/lib/appsignal/rack/abstract_middleware.rb +62 -28
- data/lib/appsignal/rack/event_handler.rb +37 -26
- data/lib/appsignal/rack/grape_middleware.rb +40 -0
- data/lib/appsignal/rack/hanami_middleware.rb +20 -0
- data/lib/appsignal/rack/rails_instrumentation.rb +14 -56
- data/lib/appsignal/utils/integration_memory_logger.rb +78 -0
- data/lib/appsignal/utils.rb +1 -0
- data/lib/appsignal/version.rb +1 -1
- data/lib/appsignal.rb +34 -33
- data/spec/.rubocop.yml +1 -1
- data/spec/lib/appsignal/cli/diagnose_spec.rb +1 -1
- data/spec/lib/appsignal/cli/install_spec.rb +3 -3
- data/spec/lib/appsignal/config_spec.rb +7 -5
- data/spec/lib/appsignal/demo_spec.rb +38 -41
- data/spec/lib/appsignal/hooks/action_cable_spec.rb +86 -167
- data/spec/lib/appsignal/hooks/active_support_notifications/finish_with_state_shared_examples.rb +8 -20
- data/spec/lib/appsignal/hooks/active_support_notifications/instrument_shared_examples.rb +38 -84
- data/spec/lib/appsignal/hooks/active_support_notifications/start_finish_shared_examples.rb +16 -37
- data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +4 -4
- data/spec/lib/appsignal/hooks/activejob_spec.rb +111 -200
- data/spec/lib/appsignal/hooks/delayed_job_spec.rb +54 -91
- data/spec/lib/appsignal/hooks/dry_monitor_spec.rb +14 -32
- data/spec/lib/appsignal/hooks/excon_spec.rb +8 -12
- data/spec/lib/appsignal/hooks/net_http_spec.rb +7 -42
- data/spec/lib/appsignal/hooks/rake_spec.rb +9 -19
- data/spec/lib/appsignal/hooks/redis_client_spec.rb +18 -30
- data/spec/lib/appsignal/hooks/redis_spec.rb +10 -16
- data/spec/lib/appsignal/hooks/resque_spec.rb +42 -62
- data/spec/lib/appsignal/hooks/shoryuken_spec.rb +33 -74
- data/spec/lib/appsignal/integrations/hanami_spec.rb +126 -64
- data/spec/lib/appsignal/integrations/http_spec.rb +12 -20
- data/spec/lib/appsignal/integrations/net_http_spec.rb +33 -0
- data/spec/lib/appsignal/integrations/object_spec.rb +29 -36
- data/spec/lib/appsignal/integrations/padrino_spec.rb +47 -70
- data/spec/lib/appsignal/integrations/que_spec.rb +43 -70
- data/spec/lib/appsignal/integrations/railtie_spec.rb +26 -67
- data/spec/lib/appsignal/integrations/sidekiq_spec.rb +86 -160
- data/spec/lib/appsignal/integrations/sinatra_spec.rb +8 -3
- data/spec/lib/appsignal/integrations/webmachine_spec.rb +28 -39
- data/spec/lib/appsignal/probes/gvl_spec.rb +80 -3
- data/spec/lib/appsignal/probes_spec.rb +7 -4
- data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +215 -106
- data/spec/lib/appsignal/rack/event_handler_spec.rb +151 -69
- data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +2 -12
- data/spec/lib/appsignal/rack/grape_middleware_spec.rb +234 -0
- data/spec/lib/appsignal/rack/hanami_middleware_spec.rb +36 -0
- data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +67 -131
- data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +36 -44
- data/spec/lib/appsignal/rack/streaming_listener_spec.rb +68 -86
- data/spec/lib/appsignal/transaction_spec.rb +79 -93
- data/spec/lib/appsignal/utils/integration_memory_logger_spec.rb +163 -0
- data/spec/lib/appsignal_spec.rb +363 -342
- data/spec/support/hanami/hanami_app.rb +1 -3
- data/spec/support/helpers/dependency_helper.rb +6 -1
- data/spec/support/helpers/std_streams_helper.rb +1 -1
- data/spec/support/helpers/transaction_helpers.rb +8 -0
- data/spec/support/matchers/transaction.rb +185 -0
- data/spec/support/mocks/dummy_app.rb +20 -0
- data/spec/support/shared_examples/instrument.rb +17 -12
- data/spec/support/testing.rb +18 -9
- metadata +17 -10
- data/.semaphore/semaphore.yml +0 -2347
- data/script/lint_git +0 -22
- data/spec/lib/appsignal/integrations/grape_spec.rb +0 -239
- data/spec/support/matchers/be_completed.rb +0 -5
- /data/gemfiles/{hanami.gemfile → hanami-2.0.gemfile} +0 -0
|
@@ -22,17 +22,19 @@ describe Appsignal::Rack::EventHandler do
|
|
|
22
22
|
event_handler_instance.on_start(request, response)
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
+
def on_error(error)
|
|
26
|
+
event_handler_instance.on_error(request, response, error)
|
|
27
|
+
end
|
|
28
|
+
|
|
25
29
|
describe "#on_start" do
|
|
26
30
|
it "creates a new transaction" do
|
|
27
31
|
expect { on_start }.to change { created_transactions.length }.by(1)
|
|
28
32
|
|
|
29
33
|
transaction = last_transaction
|
|
30
|
-
expect(transaction
|
|
31
|
-
|
|
32
|
-
"namespace" => Appsignal::Transaction::HTTP_REQUEST
|
|
33
|
-
)
|
|
34
|
+
expect(transaction).to have_id
|
|
35
|
+
expect(transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
|
|
34
36
|
|
|
35
|
-
expect(Appsignal::Transaction.current).to eq(
|
|
37
|
+
expect(Appsignal::Transaction.current).to eq(transaction)
|
|
36
38
|
end
|
|
37
39
|
|
|
38
40
|
context "when the handler is nested in another EventHandler" do
|
|
@@ -66,6 +68,30 @@ describe Appsignal::Rack::EventHandler do
|
|
|
66
68
|
expect(last_transaction.ext.queue_start).to eq(queue_start_time)
|
|
67
69
|
end
|
|
68
70
|
|
|
71
|
+
context "with error inside rack.after_reply handler" do
|
|
72
|
+
before do
|
|
73
|
+
on_start
|
|
74
|
+
# A random spot we can access to raise an error for this test
|
|
75
|
+
expect(request.env[Appsignal::Rack::APPSIGNAL_TRANSACTION])
|
|
76
|
+
.to receive(:finish_event)
|
|
77
|
+
.and_raise(ExampleStandardError, "oh no")
|
|
78
|
+
callback = request.env[Appsignal::Rack::RACK_AFTER_REPLY].first
|
|
79
|
+
callback.call
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it "completes the transaction" do
|
|
83
|
+
expect(last_transaction).to be_completed
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it "logs an error" do
|
|
87
|
+
expect(log).to contains_log(
|
|
88
|
+
:error,
|
|
89
|
+
"Error occurred in Appsignal::Rack::EventHandler's after_reply: " \
|
|
90
|
+
"ExampleStandardError: oh no"
|
|
91
|
+
)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
69
95
|
it "logs errors from rack.after_reply callbacks" do
|
|
70
96
|
on_start
|
|
71
97
|
|
|
@@ -95,21 +121,11 @@ describe Appsignal::Rack::EventHandler do
|
|
|
95
121
|
end
|
|
96
122
|
|
|
97
123
|
describe "#on_error" do
|
|
98
|
-
def on_error(error)
|
|
99
|
-
event_handler_instance.on_error(request, response, error)
|
|
100
|
-
end
|
|
101
|
-
|
|
102
124
|
it "reports the error" do
|
|
103
125
|
on_start
|
|
104
126
|
on_error(ExampleStandardError.new("the error"))
|
|
105
127
|
|
|
106
|
-
expect(last_transaction
|
|
107
|
-
"error" => {
|
|
108
|
-
"name" => "ExampleStandardError",
|
|
109
|
-
"message" => "the error",
|
|
110
|
-
"backtrace" => kind_of(String)
|
|
111
|
-
}
|
|
112
|
-
)
|
|
128
|
+
expect(last_transaction).to have_error("ExampleStandardError", "the error")
|
|
113
129
|
end
|
|
114
130
|
|
|
115
131
|
context "when the handler is nested in another EventHandler" do
|
|
@@ -117,7 +133,7 @@ describe Appsignal::Rack::EventHandler do
|
|
|
117
133
|
on_start
|
|
118
134
|
described_class.new.on_error(request, response, ExampleStandardError.new("the error"))
|
|
119
135
|
|
|
120
|
-
expect(last_transaction
|
|
136
|
+
expect(last_transaction).to_not have_error
|
|
121
137
|
end
|
|
122
138
|
end
|
|
123
139
|
|
|
@@ -139,8 +155,8 @@ describe Appsignal::Rack::EventHandler do
|
|
|
139
155
|
describe "#on_finish" do
|
|
140
156
|
let(:response) { Rack::Events::BufferedResponse.new(200, {}, ["body"]) }
|
|
141
157
|
|
|
142
|
-
def on_finish
|
|
143
|
-
event_handler_instance.on_finish(
|
|
158
|
+
def on_finish(given_request = request, given_response = response)
|
|
159
|
+
event_handler_instance.on_finish(given_request, given_response)
|
|
144
160
|
end
|
|
145
161
|
|
|
146
162
|
it "doesn't do anything without a transaction" do
|
|
@@ -150,30 +166,92 @@ describe Appsignal::Rack::EventHandler do
|
|
|
150
166
|
|
|
151
167
|
on_finish
|
|
152
168
|
|
|
153
|
-
expect(last_transaction
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
)
|
|
169
|
+
expect(last_transaction).to_not have_action
|
|
170
|
+
expect(last_transaction).to_not include_events
|
|
171
|
+
expect(last_transaction).to include("sample_data" => {})
|
|
172
|
+
expect(last_transaction).to_not be_completed
|
|
158
173
|
end
|
|
159
174
|
|
|
160
175
|
it "completes the transaction" do
|
|
161
176
|
on_start
|
|
162
177
|
on_finish
|
|
163
178
|
|
|
164
|
-
expect(last_transaction
|
|
179
|
+
expect(last_transaction).to_not have_action
|
|
180
|
+
expect(last_transaction).to include_environment(
|
|
181
|
+
"REQUEST_METHOD" => "GET",
|
|
182
|
+
"PATH_INFO" => "/path"
|
|
183
|
+
)
|
|
184
|
+
expect(last_transaction).to have_queue_start(queue_start_time)
|
|
185
|
+
expect(last_transaction).to be_completed
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
context "without a response" do
|
|
189
|
+
it "completes the transaction" do
|
|
190
|
+
on_start
|
|
191
|
+
on_finish(request, nil)
|
|
192
|
+
|
|
165
193
|
# The action is not set on purpose, as we can't set a normalized route
|
|
166
194
|
# It requires the app to set an action name
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
"
|
|
170
|
-
|
|
171
|
-
"PATH_INFO" => "/path"
|
|
172
|
-
}
|
|
195
|
+
expect(last_transaction).to_not have_action
|
|
196
|
+
expect(last_transaction).to include_environment(
|
|
197
|
+
"REQUEST_METHOD" => "GET",
|
|
198
|
+
"PATH_INFO" => "/path"
|
|
173
199
|
)
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
200
|
+
expect(last_transaction).to have_queue_start(queue_start_time)
|
|
201
|
+
expect(last_transaction).to be_completed
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
it "does not set a response_status tag" do
|
|
205
|
+
on_start
|
|
206
|
+
on_finish(request, nil)
|
|
207
|
+
|
|
208
|
+
expect(last_transaction).to_not include_tags("response_status" => anything)
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
it "does not report a response_status counter metric" do
|
|
212
|
+
expect(Appsignal).to_not receive(:increment_counter)
|
|
213
|
+
.with(:response_status, anything, anything)
|
|
214
|
+
|
|
215
|
+
on_start
|
|
216
|
+
on_finish(request, nil)
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
context "with an error previously recorded by on_error" do
|
|
220
|
+
it "sets response status 500 as a tag" do
|
|
221
|
+
on_start
|
|
222
|
+
on_error(ExampleStandardError.new("the error"))
|
|
223
|
+
on_finish(request, nil)
|
|
224
|
+
|
|
225
|
+
expect(last_transaction).to include_tags("response_status" => 500)
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
it "increments the response status counter for response status 500" do
|
|
229
|
+
expect(Appsignal).to receive(:increment_counter)
|
|
230
|
+
.with(:response_status, 1, :status => 500, :namespace => :web)
|
|
231
|
+
|
|
232
|
+
on_start
|
|
233
|
+
on_error(ExampleStandardError.new("the error"))
|
|
234
|
+
on_finish(request, nil)
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
context "with error inside on_finish handler" do
|
|
240
|
+
before do
|
|
241
|
+
on_start
|
|
242
|
+
# A random spot we can access to raise an error for this test
|
|
243
|
+
expect(Appsignal).to receive(:increment_counter).and_raise(ExampleStandardError, "oh no")
|
|
244
|
+
on_finish
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
it "completes the transaction" do
|
|
248
|
+
expect(last_transaction).to be_completed
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
it "logs an error" do
|
|
252
|
+
expect(log).to contains_log(:error,
|
|
253
|
+
"Error occurred in Appsignal::Rack::EventHandler#on_finish: ExampleStandardError: oh no")
|
|
254
|
+
end
|
|
177
255
|
end
|
|
178
256
|
|
|
179
257
|
context "when the handler is nested in another EventHandler" do
|
|
@@ -181,12 +259,10 @@ describe Appsignal::Rack::EventHandler do
|
|
|
181
259
|
on_start
|
|
182
260
|
described_class.new.on_finish(request, response)
|
|
183
261
|
|
|
184
|
-
expect(last_transaction
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
"events" => []
|
|
189
|
-
)
|
|
262
|
+
expect(last_transaction).to_not have_action
|
|
263
|
+
expect(last_transaction).to_not include_metadata
|
|
264
|
+
expect(last_transaction).to_not include_events
|
|
265
|
+
expect(last_transaction.to_h).to include("sample_data" => {})
|
|
190
266
|
expect(last_transaction).to_not be_completed
|
|
191
267
|
end
|
|
192
268
|
end
|
|
@@ -196,49 +272,55 @@ describe Appsignal::Rack::EventHandler do
|
|
|
196
272
|
last_transaction.set_action("My action")
|
|
197
273
|
on_finish
|
|
198
274
|
|
|
199
|
-
expect(last_transaction
|
|
200
|
-
"action" => "My action"
|
|
201
|
-
)
|
|
275
|
+
expect(last_transaction).to have_action("My action")
|
|
202
276
|
end
|
|
203
277
|
|
|
204
278
|
it "finishes the process_request.rack event" do
|
|
205
279
|
on_start
|
|
206
280
|
on_finish
|
|
207
281
|
|
|
208
|
-
expect(last_transaction
|
|
209
|
-
"events" => [
|
|
210
|
-
hash_including(
|
|
211
|
-
"name" => "process_request.rack",
|
|
212
|
-
"title" => "",
|
|
213
|
-
"body" => "",
|
|
214
|
-
"body_format" => Appsignal::EventFormatter::DEFAULT
|
|
215
|
-
)
|
|
216
|
-
]
|
|
217
|
-
)
|
|
282
|
+
expect(last_transaction).to include_event("name" => "process_request.rack")
|
|
218
283
|
end
|
|
219
284
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
285
|
+
context "with response" do
|
|
286
|
+
it "sets the response status as a tag" do
|
|
287
|
+
on_start
|
|
288
|
+
on_finish
|
|
223
289
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
"tags" => { "response_status" => 200 }
|
|
227
|
-
)
|
|
228
|
-
)
|
|
229
|
-
end
|
|
290
|
+
expect(last_transaction).to include_tags("response_status" => 200)
|
|
291
|
+
end
|
|
230
292
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
293
|
+
it "increments the response status counter for response status" do
|
|
294
|
+
expect(Appsignal).to receive(:increment_counter)
|
|
295
|
+
.with(:response_status, 1, :status => 200, :namespace => :web)
|
|
234
296
|
|
|
235
|
-
|
|
236
|
-
|
|
297
|
+
on_start
|
|
298
|
+
on_finish
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
context "with an error previously recorded by on_error" do
|
|
302
|
+
it "sets response status from the response as a tag" do
|
|
303
|
+
on_start
|
|
304
|
+
on_error(ExampleStandardError.new("the error"))
|
|
305
|
+
on_finish
|
|
306
|
+
|
|
307
|
+
expect(last_transaction).to include_tags("response_status" => 200)
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
it "increments the response status counter based on the response" do
|
|
311
|
+
expect(Appsignal).to receive(:increment_counter)
|
|
312
|
+
.with(:response_status, 1, :status => 200, :namespace => :web)
|
|
313
|
+
|
|
314
|
+
on_start
|
|
315
|
+
on_error(ExampleStandardError.new("the error"))
|
|
316
|
+
on_finish
|
|
317
|
+
end
|
|
318
|
+
end
|
|
237
319
|
end
|
|
238
320
|
|
|
239
321
|
it "logs an error in case of an error" do
|
|
240
|
-
|
|
241
|
-
|
|
322
|
+
# A random spot we can access to raise an error for this test
|
|
323
|
+
expect(Appsignal).to receive(:increment_counter).and_raise(ExampleStandardError, "oh no")
|
|
242
324
|
|
|
243
325
|
on_start
|
|
244
326
|
on_finish
|
|
@@ -14,17 +14,7 @@ describe Appsignal::Rack::GenericInstrumentation do
|
|
|
14
14
|
it "reports a process_action.generic event" do
|
|
15
15
|
make_request(env)
|
|
16
16
|
|
|
17
|
-
expect(last_transaction
|
|
18
|
-
"events" => [
|
|
19
|
-
hash_including(
|
|
20
|
-
"body" => "",
|
|
21
|
-
"body_format" => Appsignal::EventFormatter::DEFAULT,
|
|
22
|
-
"count" => 1,
|
|
23
|
-
"name" => "process_action.generic",
|
|
24
|
-
"title" => ""
|
|
25
|
-
)
|
|
26
|
-
]
|
|
27
|
-
)
|
|
17
|
+
expect(last_transaction).to include_event("name" => "process_action.generic")
|
|
28
18
|
end
|
|
29
19
|
end
|
|
30
20
|
|
|
@@ -32,7 +22,7 @@ describe Appsignal::Rack::GenericInstrumentation do
|
|
|
32
22
|
it "reports 'unknown' as the action name" do
|
|
33
23
|
make_request(env)
|
|
34
24
|
|
|
35
|
-
expect(last_transaction
|
|
25
|
+
expect(last_transaction).to have_action("unknown")
|
|
36
26
|
end
|
|
37
27
|
end
|
|
38
28
|
end
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
if DependencyHelper.grape_present?
|
|
2
|
+
require "appsignal/integrations/grape"
|
|
3
|
+
|
|
4
|
+
context "Appsignal::Grape::Middleware constant" do
|
|
5
|
+
let(:err_stream) { std_stream }
|
|
6
|
+
let(:stderr) { err_stream.read }
|
|
7
|
+
|
|
8
|
+
it "returns the Probes constant calling the Minutely constant" do
|
|
9
|
+
silence { expect(Appsignal::Grape::Middleware).to be(Appsignal::Rack::GrapeMiddleware) }
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "prints a deprecation warning to STDERR" do
|
|
13
|
+
capture_std_streams(std_stream, err_stream) do
|
|
14
|
+
expect(Appsignal::Grape::Middleware).to be(Appsignal::Rack::GrapeMiddleware)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
expect(stderr).to include(
|
|
18
|
+
"appsignal WARNING: The constant Appsignal::Grape::Middleware has been deprecated."
|
|
19
|
+
)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "logs a warning" do
|
|
23
|
+
logs =
|
|
24
|
+
capture_logs do
|
|
25
|
+
silence do
|
|
26
|
+
expect(Appsignal::Grape::Middleware).to be(Appsignal::Rack::GrapeMiddleware)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
expect(logs).to contains_log(
|
|
31
|
+
:warn,
|
|
32
|
+
"The constant Appsignal::Grape::Middleware has been deprecated."
|
|
33
|
+
)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
describe Appsignal::Rack::GrapeMiddleware do
|
|
38
|
+
let(:app) do
|
|
39
|
+
Class.new(::Grape::API) do
|
|
40
|
+
format :json
|
|
41
|
+
post :ping do
|
|
42
|
+
{ :message => "Hello world!" }
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
let(:api_endpoint) { app.endpoints.first }
|
|
47
|
+
let(:env) do
|
|
48
|
+
http_request_env_with_data \
|
|
49
|
+
"api.endpoint" => api_endpoint,
|
|
50
|
+
"REQUEST_METHOD" => "POST",
|
|
51
|
+
:path => "/ping"
|
|
52
|
+
end
|
|
53
|
+
let(:middleware) { Appsignal::Rack::GrapeMiddleware.new(api_endpoint) }
|
|
54
|
+
let(:transaction) { http_request_transaction }
|
|
55
|
+
before(:context) { start_agent }
|
|
56
|
+
around do |example|
|
|
57
|
+
GrapeExample = Module.new
|
|
58
|
+
GrapeExample.send(:const_set, :Api, app)
|
|
59
|
+
keep_transactions { example.run }
|
|
60
|
+
Object.send(:remove_const, :GrapeExample)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def make_request(env)
|
|
64
|
+
middleware.call(env)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def make_request_with_exception(env, exception_class, exception_message)
|
|
68
|
+
expect do
|
|
69
|
+
middleware.call(env)
|
|
70
|
+
end.to raise_error(exception_class, exception_message)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
context "with error" do
|
|
74
|
+
let(:app) do
|
|
75
|
+
Class.new(::Grape::API) do
|
|
76
|
+
format :json
|
|
77
|
+
post :ping do
|
|
78
|
+
raise ExampleException, "error message"
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it "sets the error" do
|
|
84
|
+
make_request_with_exception(env, ExampleException, "error message")
|
|
85
|
+
|
|
86
|
+
expect(last_transaction).to have_error("ExampleException", "error message")
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
context "with env['grape.skip_appsignal_error'] = true" do
|
|
90
|
+
let(:app) do
|
|
91
|
+
Class.new(::Grape::API) do
|
|
92
|
+
format :json
|
|
93
|
+
post :ping do
|
|
94
|
+
env["grape.skip_appsignal_error"] = true
|
|
95
|
+
raise ExampleException, "error message"
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
it "does not add the error" do
|
|
101
|
+
make_request_with_exception(env, ExampleException, "error message")
|
|
102
|
+
|
|
103
|
+
expect(last_transaction).to_not have_error
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
context "with route" do
|
|
109
|
+
let(:app) do
|
|
110
|
+
Class.new(::Grape::API) do
|
|
111
|
+
route([:get, :post], "hello") do
|
|
112
|
+
"Hello!"
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
let(:env) do
|
|
117
|
+
http_request_env_with_data \
|
|
118
|
+
"api.endpoint" => api_endpoint,
|
|
119
|
+
"REQUEST_METHOD" => "GET",
|
|
120
|
+
:path => ""
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it "sets non-unique route path" do
|
|
124
|
+
make_request(env)
|
|
125
|
+
|
|
126
|
+
expect(last_transaction).to have_action("GET::GrapeExample::Api#/hello")
|
|
127
|
+
expect(last_transaction).to include_metadata("path" => "/hello", "method" => "GET")
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
context "with route_param" do
|
|
132
|
+
let(:app) do
|
|
133
|
+
Class.new(::Grape::API) do
|
|
134
|
+
format :json
|
|
135
|
+
resource :users do
|
|
136
|
+
route_param :id do
|
|
137
|
+
get do
|
|
138
|
+
{ :name => "Tom" }
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
let(:env) do
|
|
145
|
+
http_request_env_with_data \
|
|
146
|
+
"api.endpoint" => api_endpoint,
|
|
147
|
+
"REQUEST_METHOD" => "GET",
|
|
148
|
+
:path => ""
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
it "sets non-unique route_param path" do
|
|
152
|
+
make_request(env)
|
|
153
|
+
|
|
154
|
+
expect(last_transaction).to have_action("GET::GrapeExample::Api#/users/:id/")
|
|
155
|
+
expect(last_transaction).to include_metadata("path" => "/users/:id/", "method" => "GET")
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
context "with namespaced path" do
|
|
160
|
+
context "with symbols" do
|
|
161
|
+
let(:app) do
|
|
162
|
+
Class.new(::Grape::API) do
|
|
163
|
+
format :json
|
|
164
|
+
namespace :v1 do
|
|
165
|
+
namespace :beta do
|
|
166
|
+
post :ping do
|
|
167
|
+
{ :message => "Hello namespaced world!" }
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
it "sets namespaced path" do
|
|
175
|
+
make_request(env)
|
|
176
|
+
|
|
177
|
+
expect(last_transaction).to have_action("POST::GrapeExample::Api#/v1/beta/ping")
|
|
178
|
+
expect(last_transaction).to include_metadata("path" => "/v1/beta/ping",
|
|
179
|
+
"method" => "POST")
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
context "with strings" do
|
|
184
|
+
context "without / prefix" do
|
|
185
|
+
let(:app) do
|
|
186
|
+
Class.new(::Grape::API) do
|
|
187
|
+
format :json
|
|
188
|
+
namespace "v1" do
|
|
189
|
+
namespace "beta" do
|
|
190
|
+
post "ping" do
|
|
191
|
+
{ :message => "Hello namespaced world!" }
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
it "sets namespaced path" do
|
|
199
|
+
make_request(env)
|
|
200
|
+
|
|
201
|
+
expect(last_transaction).to have_action("POST::GrapeExample::Api#/v1/beta/ping")
|
|
202
|
+
expect(last_transaction).to include_metadata(
|
|
203
|
+
"path" => "/v1/beta/ping",
|
|
204
|
+
"method" => "POST"
|
|
205
|
+
)
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
context "with / prefix" do
|
|
210
|
+
let(:app) do
|
|
211
|
+
Class.new(::Grape::API) do
|
|
212
|
+
format :json
|
|
213
|
+
namespace "/v1" do
|
|
214
|
+
namespace "/beta" do
|
|
215
|
+
post "/ping" do
|
|
216
|
+
{ :message => "Hello namespaced world!" }
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
it "sets namespaced path" do
|
|
224
|
+
make_request(env)
|
|
225
|
+
|
|
226
|
+
expect(last_transaction).to have_action("POST::GrapeExample::Api#/v1/beta/ping")
|
|
227
|
+
expect(last_transaction).to include_metadata("path" => "/v1/beta/ping",
|
|
228
|
+
"method" => "POST")
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
require "appsignal/rack/hanami_middleware"
|
|
2
|
+
|
|
3
|
+
if DependencyHelper.hanami2_present?
|
|
4
|
+
describe Appsignal::Rack::HanamiMiddleware do
|
|
5
|
+
let(:app) { double(:call => true) }
|
|
6
|
+
let(:router_params) { { "param1" => "value1", "param2" => "value2" } }
|
|
7
|
+
let(:env) do
|
|
8
|
+
Rack::MockRequest.env_for(
|
|
9
|
+
"/some/path",
|
|
10
|
+
"router.params" => router_params
|
|
11
|
+
)
|
|
12
|
+
end
|
|
13
|
+
let(:middleware) { Appsignal::Rack::HanamiMiddleware.new(app, {}) }
|
|
14
|
+
|
|
15
|
+
before(:context) { start_agent }
|
|
16
|
+
around { |example| keep_transactions { example.run } }
|
|
17
|
+
|
|
18
|
+
def make_request(env)
|
|
19
|
+
middleware.call(env)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
context "with params" do
|
|
23
|
+
it "sets request parameters on the transaction" do
|
|
24
|
+
make_request(env)
|
|
25
|
+
|
|
26
|
+
expect(last_transaction).to include_params("param1" => "value1", "param2" => "value2")
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "reports a process_action.hanami event" do
|
|
31
|
+
make_request(env)
|
|
32
|
+
|
|
33
|
+
expect(last_transaction).to include_event("name" => "process_action.hanami")
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|