appsignal 3.9.2 → 3.9.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +3135 -0
  3. data/.rubocop.yml +28 -20
  4. data/.rubocop_todo.yml +7 -33
  5. data/CHANGELOG.md +38 -0
  6. data/Rakefile +79 -64
  7. data/appsignal.gemspec +1 -1
  8. data/build_matrix.yml +109 -179
  9. data/ext/base.rb +1 -1
  10. data/gemfiles/hanami-2.1.gemfile +7 -0
  11. data/lib/appsignal/cli/diagnose.rb +1 -1
  12. data/lib/appsignal/config.rb +1 -1
  13. data/lib/appsignal/demo.rb +0 -1
  14. data/lib/appsignal/environment.rb +5 -1
  15. data/lib/appsignal/extension/jruby.rb +1 -1
  16. data/lib/appsignal/helpers/instrumentation.rb +1 -1
  17. data/lib/appsignal/integrations/grape.rb +19 -47
  18. data/lib/appsignal/integrations/hanami.rb +8 -7
  19. data/lib/appsignal/integrations/padrino.rb +46 -43
  20. data/lib/appsignal/integrations/railtie.rb +0 -3
  21. data/lib/appsignal/integrations/sinatra.rb +0 -1
  22. data/lib/appsignal/probes/gvl.rb +24 -2
  23. data/lib/appsignal/probes/sidekiq.rb +1 -1
  24. data/lib/appsignal/probes.rb +1 -1
  25. data/lib/appsignal/rack/abstract_middleware.rb +62 -28
  26. data/lib/appsignal/rack/event_handler.rb +12 -3
  27. data/lib/appsignal/rack/grape_middleware.rb +40 -0
  28. data/lib/appsignal/rack/hanami_middleware.rb +1 -11
  29. data/lib/appsignal/rack/rails_instrumentation.rb +14 -55
  30. data/lib/appsignal/utils/integration_memory_logger.rb +78 -0
  31. data/lib/appsignal/utils.rb +1 -0
  32. data/lib/appsignal/version.rb +1 -1
  33. data/lib/appsignal.rb +34 -33
  34. data/spec/.rubocop.yml +1 -1
  35. data/spec/lib/appsignal/cli/diagnose_spec.rb +1 -1
  36. data/spec/lib/appsignal/cli/install_spec.rb +3 -3
  37. data/spec/lib/appsignal/config_spec.rb +7 -5
  38. data/spec/lib/appsignal/demo_spec.rb +38 -41
  39. data/spec/lib/appsignal/hooks/action_cable_spec.rb +86 -167
  40. data/spec/lib/appsignal/hooks/active_support_notifications/finish_with_state_shared_examples.rb +8 -20
  41. data/spec/lib/appsignal/hooks/active_support_notifications/instrument_shared_examples.rb +38 -84
  42. data/spec/lib/appsignal/hooks/active_support_notifications/start_finish_shared_examples.rb +16 -37
  43. data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +4 -4
  44. data/spec/lib/appsignal/hooks/activejob_spec.rb +111 -200
  45. data/spec/lib/appsignal/hooks/delayed_job_spec.rb +54 -91
  46. data/spec/lib/appsignal/hooks/dry_monitor_spec.rb +14 -32
  47. data/spec/lib/appsignal/hooks/excon_spec.rb +8 -12
  48. data/spec/lib/appsignal/hooks/net_http_spec.rb +7 -42
  49. data/spec/lib/appsignal/hooks/rake_spec.rb +9 -19
  50. data/spec/lib/appsignal/hooks/redis_client_spec.rb +18 -30
  51. data/spec/lib/appsignal/hooks/redis_spec.rb +10 -16
  52. data/spec/lib/appsignal/hooks/resque_spec.rb +42 -62
  53. data/spec/lib/appsignal/hooks/shoryuken_spec.rb +33 -74
  54. data/spec/lib/appsignal/integrations/hanami_spec.rb +79 -21
  55. data/spec/lib/appsignal/integrations/http_spec.rb +12 -20
  56. data/spec/lib/appsignal/integrations/net_http_spec.rb +33 -0
  57. data/spec/lib/appsignal/integrations/object_spec.rb +29 -36
  58. data/spec/lib/appsignal/integrations/padrino_spec.rb +47 -70
  59. data/spec/lib/appsignal/integrations/que_spec.rb +43 -70
  60. data/spec/lib/appsignal/integrations/railtie_spec.rb +26 -67
  61. data/spec/lib/appsignal/integrations/sidekiq_spec.rb +86 -160
  62. data/spec/lib/appsignal/integrations/sinatra_spec.rb +0 -1
  63. data/spec/lib/appsignal/integrations/webmachine_spec.rb +28 -39
  64. data/spec/lib/appsignal/probes/gvl_spec.rb +80 -3
  65. data/spec/lib/appsignal/probes_spec.rb +7 -4
  66. data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +215 -106
  67. data/spec/lib/appsignal/rack/event_handler_spec.rb +81 -78
  68. data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +2 -12
  69. data/spec/lib/appsignal/rack/grape_middleware_spec.rb +234 -0
  70. data/spec/lib/appsignal/rack/hanami_middleware_spec.rb +2 -16
  71. data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +67 -131
  72. data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +36 -44
  73. data/spec/lib/appsignal/rack/streaming_listener_spec.rb +68 -86
  74. data/spec/lib/appsignal/transaction_spec.rb +76 -90
  75. data/spec/lib/appsignal/utils/integration_memory_logger_spec.rb +163 -0
  76. data/spec/lib/appsignal_spec.rb +363 -342
  77. data/spec/support/helpers/dependency_helper.rb +6 -1
  78. data/spec/support/helpers/std_streams_helper.rb +1 -1
  79. data/spec/support/helpers/transaction_helpers.rb +8 -0
  80. data/spec/support/matchers/transaction.rb +185 -0
  81. data/spec/support/mocks/dummy_app.rb +20 -0
  82. data/spec/support/shared_examples/instrument.rb +17 -12
  83. data/spec/support/testing.rb +18 -9
  84. metadata +15 -10
  85. data/.semaphore/semaphore.yml +0 -2347
  86. data/script/lint_git +0 -22
  87. data/spec/lib/appsignal/integrations/grape_spec.rb +0 -239
  88. data/spec/support/matchers/be_completed.rb +0 -5
  89. /data/gemfiles/{hanami.gemfile → hanami-2.0.gemfile} +0 -0
@@ -64,23 +64,18 @@ describe Appsignal::Hooks::DelayedJobHook do
64
64
  context "with a normal call" do
65
65
  it "wraps it in a transaction" do
66
66
  perform
67
- transaction_data = last_transaction.to_h
68
- expect(transaction_data).to include(
69
- "action" => "TestClass#perform",
70
- "namespace" => "background_job",
71
- "error" => nil
72
- )
73
- expect(transaction_data["events"].map { |e| e["name"] })
74
- .to eql(["perform_job.delayed_job"])
75
- expect(transaction_data["sample_data"]).to include(
76
- "metadata" => {
77
- "priority" => 1,
78
- "attempts" => 1,
79
- "queue" => "default",
80
- "id" => "123"
81
- },
82
- "params" => ["argument"]
67
+ transaction = last_transaction
68
+ expect(transaction).to have_action("TestClass#perform")
69
+ expect(transaction).to have_namespace("background_job")
70
+ expect(transaction).to_not have_error
71
+ expect(transaction).to include_event(:name => "perform_job.delayed_job")
72
+ expect(transaction).to include_sample_metadata(
73
+ "priority" => 1,
74
+ "attempts" => 1,
75
+ "queue" => "default",
76
+ "id" => "123"
83
77
  )
78
+ expect(transaction).to include_params(["argument"])
84
79
  end
85
80
 
86
81
  context "with more complex params" do
@@ -93,13 +88,8 @@ describe Appsignal::Hooks::DelayedJobHook do
93
88
 
94
89
  it "adds the more complex arguments" do
95
90
  perform
96
- transaction_data = last_transaction.to_h
97
- expect(transaction_data["sample_data"]).to include(
98
- "params" => {
99
- "foo" => "Foo",
100
- "bar" => "Bar"
101
- }
102
- )
91
+
92
+ expect(last_transaction).to include_params("foo" => "Foo", "bar" => "Bar")
103
93
  end
104
94
 
105
95
  context "with parameter filtering" do
@@ -110,13 +100,8 @@ describe Appsignal::Hooks::DelayedJobHook do
110
100
 
111
101
  it "filters selected arguments" do
112
102
  perform
113
- transaction_data = last_transaction.to_h
114
- expect(transaction_data["sample_data"]).to include(
115
- "params" => {
116
- "foo" => "[FILTERED]",
117
- "bar" => "Bar"
118
- }
119
- )
103
+
104
+ expect(last_transaction).to include_params("foo" => "[FILTERED]", "bar" => "Bar")
120
105
  end
121
106
  end
122
107
  end
@@ -125,13 +110,9 @@ describe Appsignal::Hooks::DelayedJobHook do
125
110
  let(:run_at) { Time.parse("2017-01-01 10:01:00UTC") }
126
111
 
127
112
  it "reports queue_start with run_at time" do
128
- # TODO: Not available in transaction.to_h yet.
129
- # https://github.com/appsignal/appsignal-agent/issues/293
130
- expect(Appsignal).to receive(:monitor_transaction).with(
131
- "perform_job.delayed_job",
132
- a_hash_including(:queue_start => run_at)
133
- ).and_call_original
134
113
  perform
114
+
115
+ expect(last_transaction).to have_queue_start(run_at.to_i * 1000)
135
116
  end
136
117
  end
137
118
 
@@ -142,7 +123,7 @@ describe Appsignal::Hooks::DelayedJobHook do
142
123
 
143
124
  it "wraps it in a transaction using the class method job name" do
144
125
  perform
145
- expect(last_transaction.to_h["action"]).to eql("CustomClassMethod.perform")
126
+ expect(last_transaction).to have_action("CustomClassMethod.perform")
146
127
  end
147
128
  end
148
129
 
@@ -155,7 +136,7 @@ describe Appsignal::Hooks::DelayedJobHook do
155
136
  let(:payload_object) { double(:appsignal_name => "CustomClass#perform") }
156
137
 
157
138
  it "wraps it in a transaction using the custom name" do
158
- expect(last_transaction.to_h["action"]).to eql("CustomClass#perform")
139
+ expect(last_transaction).to have_action("CustomClass#perform")
159
140
  end
160
141
  end
161
142
 
@@ -163,7 +144,7 @@ describe Appsignal::Hooks::DelayedJobHook do
163
144
  let(:payload_object) { double(:appsignal_name => Object.new) }
164
145
 
165
146
  it "wraps it in a transaction using the original job name" do
166
- expect(last_transaction.to_h["action"]).to eql("TestClass#perform")
147
+ expect(last_transaction).to have_action("TestClass#perform")
167
148
  end
168
149
  end
169
150
 
@@ -172,7 +153,7 @@ describe Appsignal::Hooks::DelayedJobHook do
172
153
 
173
154
  it "wraps it in a transaction using the custom name" do
174
155
  perform
175
- expect(last_transaction.to_h["action"]).to eql("CustomClassMethod.perform")
156
+ expect(last_transaction).to have_action("CustomClassMethod.perform")
176
157
  end
177
158
  end
178
159
  end
@@ -182,7 +163,7 @@ describe Appsignal::Hooks::DelayedJobHook do
182
163
  let(:payload_object) { double(:appsignal_name => "CustomClassHash#perform") }
183
164
 
184
165
  it "wraps it in a transaction using the custom name" do
185
- expect(last_transaction.to_h["action"]).to eql("CustomClassHash#perform")
166
+ expect(last_transaction).to have_action("CustomClassHash#perform")
186
167
  end
187
168
  end
188
169
 
@@ -190,7 +171,7 @@ describe Appsignal::Hooks::DelayedJobHook do
190
171
  let(:payload_object) { double(:appsignal_name => Object.new) }
191
172
 
192
173
  it "wraps it in a transaction using the original job name" do
193
- expect(last_transaction.to_h["action"]).to eql("TestClass#perform")
174
+ expect(last_transaction).to have_action("TestClass#perform")
194
175
  end
195
176
  end
196
177
 
@@ -199,7 +180,7 @@ describe Appsignal::Hooks::DelayedJobHook do
199
180
 
200
181
  it "wraps it in a transaction using the custom name" do
201
182
  perform
202
- expect(last_transaction.to_h["action"]).to eql("CustomClassMethod.perform")
183
+ expect(last_transaction).to have_action("CustomClassMethod.perform")
203
184
  end
204
185
  end
205
186
  end
@@ -221,7 +202,7 @@ describe Appsignal::Hooks::DelayedJobHook do
221
202
  # of `self.appsignal_name`. Since this isn't a valid `String`
222
203
  # we return the default job name as action name.
223
204
  it "wraps it in a transaction using the original job name" do
224
- expect(last_transaction.to_h["action"]).to eql("TestClass#perform")
205
+ expect(last_transaction).to have_action("TestClass#perform")
225
206
  end
226
207
  end
227
208
  end
@@ -234,7 +215,7 @@ describe Appsignal::Hooks::DelayedJobHook do
234
215
 
235
216
  it "appends #perform to the class name" do
236
217
  perform
237
- expect(last_transaction.to_h["action"]).to eql("Banana#perform")
218
+ expect(last_transaction).to have_action("Banana#perform")
238
219
  end
239
220
  end
240
221
 
@@ -267,23 +248,19 @@ describe Appsignal::Hooks::DelayedJobHook do
267
248
 
268
249
  it "wraps it in a transaction with the correct params" do
269
250
  perform
270
- transaction_data = last_transaction.to_h
271
- expect(transaction_data).to include(
272
- "action" => "TestClass#perform",
273
- "namespace" => "background_job",
274
- "error" => nil
275
- )
276
- expect(transaction_data["events"].map { |e| e["name"] })
277
- .to eql(["perform_job.delayed_job"])
278
- expect(transaction_data["sample_data"]).to include(
279
- "metadata" => {
280
- "priority" => 1,
281
- "attempts" => 1,
282
- "queue" => "default",
283
- "id" => "123"
284
- },
285
- "params" => ["activejob_argument"]
251
+
252
+ transaction = last_transaction
253
+ expect(transaction).to have_namespace("background_job")
254
+ expect(transaction).to have_action("TestClass#perform")
255
+ expect(transaction).to_not have_error
256
+ expect(transaction).to include_event("name" => "perform_job.delayed_job")
257
+ expect(transaction).to include_sample_metadata(
258
+ "priority" => 1,
259
+ "attempts" => 1,
260
+ "queue" => "default",
261
+ "id" => "123"
286
262
  )
263
+ expect(transaction).to include_params(["activejob_argument"])
287
264
  end
288
265
 
289
266
  context "with more complex params" do
@@ -296,13 +273,11 @@ describe Appsignal::Hooks::DelayedJobHook do
296
273
 
297
274
  it "adds the more complex arguments" do
298
275
  perform
299
- transaction_data = last_transaction.to_h
300
- expect(transaction_data).to include("action" => "TestClass#perform")
301
- expect(transaction_data["sample_data"]).to include(
302
- "params" => {
303
- "foo" => "Foo",
304
- "bar" => "Bar"
305
- }
276
+ transaction = last_transaction
277
+ expect(transaction).to have_action("TestClass#perform")
278
+ expect(transaction).to include_params(
279
+ "foo" => "Foo",
280
+ "bar" => "Bar"
306
281
  )
307
282
  end
308
283
 
@@ -314,13 +289,11 @@ describe Appsignal::Hooks::DelayedJobHook do
314
289
 
315
290
  it "filters selected arguments" do
316
291
  perform
317
- transaction_data = last_transaction.to_h
318
- expect(transaction_data).to include("action" => "TestClass#perform")
319
- expect(transaction_data["sample_data"]).to include(
320
- "params" => {
321
- "foo" => "[FILTERED]",
322
- "bar" => "Bar"
323
- }
292
+ transaction = last_transaction
293
+ expect(transaction).to have_action("TestClass#perform")
294
+ expect(transaction).to include_params(
295
+ "foo" => "[FILTERED]",
296
+ "bar" => "Bar"
324
297
  )
325
298
  end
326
299
  end
@@ -330,11 +303,9 @@ describe Appsignal::Hooks::DelayedJobHook do
330
303
  let(:run_at) { Time.parse("2017-01-01 10:01:00UTC") }
331
304
 
332
305
  it "reports queue_start with run_at time" do
333
- expect(Appsignal).to receive(:monitor_transaction).with(
334
- "perform_job.delayed_job",
335
- a_hash_including(:queue_start => run_at)
336
- ).and_call_original
337
306
  perform
307
+
308
+ expect(last_transaction).to have_queue_start(run_at.to_i * 1000)
338
309
  end
339
310
  end
340
311
  end
@@ -352,18 +323,10 @@ describe Appsignal::Hooks::DelayedJobHook do
352
323
  perform
353
324
  end.to raise_error(error)
354
325
 
355
- transaction_data = last_transaction.to_h
356
- expect(transaction_data).to include(
357
- "action" => "TestClass#perform",
358
- "namespace" => "background_job",
359
- "error" => {
360
- "name" => "ExampleException",
361
- "message" => "uh oh",
362
- # TODO: backtrace should be an Array of Strings
363
- # https://github.com/appsignal/appsignal-agent/issues/294
364
- "backtrace" => kind_of(String)
365
- }
366
- )
326
+ transaction = last_transaction
327
+ expect(transaction).to have_namespace("background_job")
328
+ expect(transaction).to have_action("TestClass#perform")
329
+ expect(transaction).to have_error("ExampleException", "uh oh")
367
330
  end
368
331
  end
369
332
  end
@@ -53,22 +53,13 @@ if DependencyHelper.dry_monitor_present?
53
53
 
54
54
  it "creates an sql event" do
55
55
  notifications.instrument(event_id, payload)
56
- expect(transaction.to_h["events"]).to match([
57
- {
58
- "allocation_count" => kind_of(Integer),
59
- "body" => "SELECT * FROM users",
60
- "body_format" => Appsignal::EventFormatter::SQL_BODY_FORMAT,
61
- "child_allocation_count" => kind_of(Integer),
62
- "child_duration" => kind_of(Float),
63
- "child_gc_duration" => kind_of(Float),
64
- "count" => 1,
65
- "duration" => kind_of(Float),
66
- "gc_duration" => kind_of(Float),
67
- "name" => "query.postgres",
68
- "start" => kind_of(Float),
69
- "title" => "query.postgres"
70
- }
71
- ])
56
+ expect(transaction).to include_event(
57
+ "body" => "SELECT * FROM users",
58
+ "body_format" => Appsignal::EventFormatter::SQL_BODY_FORMAT,
59
+ "count" => 1,
60
+ "name" => "query.postgres",
61
+ "title" => "query.postgres"
62
+ )
72
63
  end
73
64
  end
74
65
 
@@ -82,22 +73,13 @@ if DependencyHelper.dry_monitor_present?
82
73
 
83
74
  it "creates a generic event" do
84
75
  notifications.instrument(event_id, payload)
85
- expect(transaction.to_h["events"]).to match([
86
- {
87
- "allocation_count" => kind_of(Integer),
88
- "body" => "",
89
- "body_format" => Appsignal::EventFormatter::DEFAULT,
90
- "child_allocation_count" => kind_of(Integer),
91
- "child_duration" => kind_of(Float),
92
- "child_gc_duration" => kind_of(Float),
93
- "count" => 1,
94
- "duration" => kind_of(Float),
95
- "gc_duration" => kind_of(Float),
96
- "name" => "foo",
97
- "start" => kind_of(Float),
98
- "title" => ""
99
- }
100
- ])
76
+ expect(transaction).to include_event(
77
+ "body" => "",
78
+ "body_format" => Appsignal::EventFormatter::DEFAULT,
79
+ "count" => 1,
80
+ "name" => "foo",
81
+ "title" => ""
82
+ )
101
83
  end
102
84
  end
103
85
  end
@@ -40,12 +40,10 @@ describe Appsignal::Hooks::ExconHook do
40
40
  }
41
41
  Excon.defaults[:instrumentor].instrument("excon.request", data) {} # rubocop:disable Lint/EmptyBlock
42
42
 
43
- expect(transaction.to_h["events"]).to include(
44
- hash_including(
45
- "name" => "request.excon",
46
- "title" => "GET http://www.google.com",
47
- "body" => ""
48
- )
43
+ expect(transaction).to include_event(
44
+ "name" => "request.excon",
45
+ "title" => "GET http://www.google.com",
46
+ "body" => ""
49
47
  )
50
48
  end
51
49
 
@@ -53,12 +51,10 @@ describe Appsignal::Hooks::ExconHook do
53
51
  data = { :host => "www.google.com" }
54
52
  Excon.defaults[:instrumentor].instrument("excon.response", data) {} # rubocop:disable Lint/EmptyBlock
55
53
 
56
- expect(transaction.to_h["events"]).to include(
57
- hash_including(
58
- "name" => "response.excon",
59
- "title" => "www.google.com",
60
- "body" => ""
61
- )
54
+ expect(transaction).to include_event(
55
+ "name" => "response.excon",
56
+ "title" => "www.google.com",
57
+ "body" => ""
62
58
  )
63
59
  end
64
60
  end
@@ -1,51 +1,16 @@
1
1
  describe Appsignal::Hooks::NetHttpHook do
2
- before :context do
3
- start_agent
4
- end
2
+ before(:context) { start_agent }
5
3
 
6
- context "with Net::HTTP instrumentation enabled" do
7
- describe "#dependencies_present?" do
8
- subject { described_class.new.dependencies_present? }
4
+ describe "#dependencies_present?" do
5
+ subject { described_class.new.dependencies_present? }
9
6
 
7
+ context "with Net::HTTP instrumentation enabled" do
10
8
  it { is_expected.to be_truthy }
11
9
  end
12
10
 
13
- it "should instrument a http request" do
14
- Appsignal::Transaction.create("uuid", Appsignal::Transaction::HTTP_REQUEST, "test")
15
- expect(Appsignal::Transaction.current).to receive(:start_event)
16
- .at_least(:once)
17
- expect(Appsignal::Transaction.current).to receive(:finish_event)
18
- .at_least(:once)
19
- .with("request.net_http", "GET http://www.google.com", nil, 0)
20
-
21
- stub_request(:any, "http://www.google.com/")
22
-
23
- Net::HTTP.get_response(URI.parse("http://www.google.com"))
24
- end
25
-
26
- it "should instrument a https request" do
27
- Appsignal::Transaction.create("uuid", Appsignal::Transaction::HTTP_REQUEST, "test")
28
- expect(Appsignal::Transaction.current).to receive(:start_event)
29
- .at_least(:once)
30
- expect(Appsignal::Transaction.current).to receive(:finish_event)
31
- .at_least(:once)
32
- .with("request.net_http", "GET https://www.google.com", nil, 0)
33
-
34
- stub_request(:any, "https://www.google.com/")
35
-
36
- uri = URI.parse("https://www.google.com")
37
- http = Net::HTTP.new(uri.host, uri.port)
38
- http.use_ssl = true
39
- http.get(uri.request_uri)
40
- end
41
- end
42
-
43
- context "with Net::HTTP instrumentation disabled" do
44
- before { Appsignal.config.config_hash[:instrument_net_http] = false }
45
- after { Appsignal.config.config_hash[:instrument_net_http] = true }
46
-
47
- describe "#dependencies_present?" do
48
- subject { described_class.new.dependencies_present? }
11
+ context "with Net::HTTP instrumentation disabled" do
12
+ before { Appsignal.config.config_hash[:instrument_net_http] = false }
13
+ after { Appsignal.config.config_hash[:instrument_net_http] = true }
49
14
 
50
15
  it { is_expected.to be_falsy }
51
16
  end
@@ -15,8 +15,7 @@ describe Appsignal::Hooks::RakeHook do
15
15
  end
16
16
 
17
17
  it "creates no transaction" do
18
- expect(Appsignal::Transaction).to_not receive(:new)
19
- expect { perform }.to_not(change { created_transactions })
18
+ expect { perform }.to_not(change { created_transactions.count })
20
19
  end
21
20
 
22
21
  it "calls the original task" do
@@ -42,20 +41,13 @@ describe Appsignal::Hooks::RakeHook do
42
41
  it "creates a background job transaction" do
43
42
  perform
44
43
 
45
- expect(last_transaction).to be_completed
46
- expect(last_transaction.to_h).to include(
47
- "id" => kind_of(String),
48
- "namespace" => Appsignal::Transaction::BACKGROUND_JOB,
49
- "action" => "task:name",
50
- "error" => {
51
- "name" => "ExampleException",
52
- "message" => "my error message",
53
- "backtrace" => kind_of(String)
54
- },
55
- "sample_data" => hash_including(
56
- "params" => { "foo" => "bar" }
57
- )
58
- )
44
+ transaction = last_transaction
45
+ expect(transaction).to have_id
46
+ expect(transaction).to have_namespace(Appsignal::Transaction::BACKGROUND_JOB)
47
+ expect(transaction).to have_action("task:name")
48
+ expect(transaction).to have_error("ExampleException", "my error message")
49
+ expect(transaction).to include_params("foo" => "bar")
50
+ expect(transaction).to be_completed
59
51
  end
60
52
 
61
53
  context "when first argument is not a `Rake::TaskArguments`" do
@@ -64,9 +56,7 @@ describe Appsignal::Hooks::RakeHook do
64
56
  it "does not add the params to the transaction" do
65
57
  perform
66
58
 
67
- expect(last_transaction.to_h).to include(
68
- "sample_data" => hash_excluding("params")
69
- )
59
+ expect(last_transaction).to_not include_params
70
60
  end
71
61
  end
72
62
  end
@@ -88,13 +88,10 @@ describe Appsignal::Hooks::RedisClientHook do
88
88
  connection = RedisClient::RubyConnection.new client_config
89
89
  expect(connection.write([:get, "key"])).to eql("stub_write")
90
90
 
91
- transaction_hash = transaction.to_h
92
- expect(transaction_hash["events"]).to include(
93
- hash_including(
94
- "name" => "query.redis",
95
- "body" => "get ?",
96
- "title" => "stub_id"
97
- )
91
+ expect(transaction).to include_event(
92
+ "name" => "query.redis",
93
+ "body" => "get ?",
94
+ "title" => "stub_id"
98
95
  )
99
96
  end
100
97
 
@@ -103,16 +100,13 @@ describe Appsignal::Hooks::RedisClientHook do
103
100
  script = "return redis.call('set',KEYS[1],ARGV[1])"
104
101
  keys = ["foo"]
105
102
  argv = ["bar"]
106
- expect(connection.write([:eval, script, keys.size, keys,
107
- argv])).to eql("stub_write")
103
+ expect(connection.write([:eval, script, keys.size, keys, argv]))
104
+ .to eql("stub_write")
108
105
 
109
- transaction_hash = transaction.to_h
110
- expect(transaction_hash["events"]).to include(
111
- hash_including(
112
- "name" => "query.redis",
113
- "body" => "#{script} ? ?",
114
- "title" => "stub_id"
115
- )
106
+ expect(transaction).to include_event(
107
+ "name" => "query.redis",
108
+ "body" => "#{script} ? ?",
109
+ "title" => "stub_id"
116
110
  )
117
111
  end
118
112
  end
@@ -181,13 +175,10 @@ describe Appsignal::Hooks::RedisClientHook do
181
175
  connection = RedisClient::HiredisConnection.new client_config
182
176
  expect(connection.write([:get, "key"])).to eql("stub_write")
183
177
 
184
- transaction_hash = transaction.to_h
185
- expect(transaction_hash["events"]).to include(
186
- hash_including(
187
- "name" => "query.redis",
188
- "body" => "get ?",
189
- "title" => "stub_id"
190
- )
178
+ expect(transaction).to include_event(
179
+ "name" => "query.redis",
180
+ "body" => "get ?",
181
+ "title" => "stub_id"
191
182
  )
192
183
  end
193
184
 
@@ -199,13 +190,10 @@ describe Appsignal::Hooks::RedisClientHook do
199
190
  expect(connection.write([:eval, script, keys.size, keys,
200
191
  argv])).to eql("stub_write")
201
192
 
202
- transaction_hash = transaction.to_h
203
- expect(transaction_hash["events"]).to include(
204
- hash_including(
205
- "name" => "query.redis",
206
- "body" => "#{script} ? ?",
207
- "title" => "stub_id"
208
- )
193
+ expect(transaction).to include_event(
194
+ "name" => "query.redis",
195
+ "body" => "#{script} ? ?",
196
+ "title" => "stub_id"
209
197
  )
210
198
  end
211
199
  end
@@ -81,14 +81,11 @@ describe Appsignal::Hooks::RedisHook do
81
81
  client = Redis::Client.new
82
82
  expect(client.write([:get, "key"])).to eql("stub_write")
83
83
 
84
- transaction_hash = transaction.to_h
85
- expect(transaction_hash["events"]).to include(
86
- hash_including(
87
- "name" => "query.redis",
88
- "body" => "get ?",
89
- "title" => "stub_id"
90
- )
91
- )
84
+ expect(transaction).to include_event(
85
+ "name" => "query.redis",
86
+ "body" => "get ?",
87
+ "title" => "stub_id"
88
+ )
92
89
  end
93
90
 
94
91
  it "instrument a redis script call" do
@@ -98,14 +95,11 @@ describe Appsignal::Hooks::RedisHook do
98
95
  argv = ["bar"]
99
96
  expect(client.write([:eval, script, keys.size, keys, argv])).to eql("stub_write")
100
97
 
101
- transaction_hash = transaction.to_h
102
- expect(transaction_hash["events"]).to include(
103
- hash_including(
104
- "name" => "query.redis",
105
- "body" => "#{script} ? ?",
106
- "title" => "stub_id"
107
- )
108
- )
98
+ expect(transaction).to include_event(
99
+ "name" => "query.redis",
100
+ "body" => "#{script} ? ?",
101
+ "title" => "stub_id"
102
+ )
109
103
  end
110
104
  end
111
105
  end