appsignal 3.9.2-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.
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
@@ -53,20 +53,14 @@ describe Appsignal::Hooks::ResqueHook do
53
53
  perform_rescue_job(ResqueTestJob)
54
54
 
55
55
  transaction = last_transaction
56
- transaction_hash = transaction.to_h
57
- expect(transaction_hash).to include(
58
- "id" => kind_of(String),
59
- "action" => "ResqueTestJob#perform",
60
- "error" => nil,
61
- "namespace" => namespace,
62
- "metadata" => {},
63
- "sample_data" => {
64
- "breadcrumbs" => [],
65
- "tags" => { "queue" => queue }
66
- }
67
- )
68
- expect(transaction_hash["events"].map { |e| e["name"] })
69
- .to eql(["perform.resque"])
56
+ expect(transaction).to have_id
57
+ expect(transaction).to have_namespace(namespace)
58
+ expect(transaction).to have_action("ResqueTestJob#perform")
59
+ expect(transaction).to_not have_error
60
+ expect(transaction).to_not include_metadata
61
+ expect(transaction).to_not include_breadcrumbs
62
+ expect(transaction).to include_tags("queue" => queue)
63
+ expect(transaction).to include_event("name" => "perform.resque")
70
64
  end
71
65
 
72
66
  context "with error" do
@@ -76,22 +70,14 @@ describe Appsignal::Hooks::ResqueHook do
76
70
  end.to raise_error(RuntimeError, "resque job error")
77
71
 
78
72
  transaction = last_transaction
79
- transaction_hash = transaction.to_h
80
- expect(transaction_hash).to include(
81
- "id" => kind_of(String),
82
- "action" => "ResqueErrorTestJob#perform",
83
- "error" => {
84
- "name" => "RuntimeError",
85
- "message" => "resque job error",
86
- "backtrace" => kind_of(String)
87
- },
88
- "namespace" => namespace,
89
- "metadata" => {},
90
- "sample_data" => {
91
- "breadcrumbs" => [],
92
- "tags" => { "queue" => queue }
93
- }
94
- )
73
+ expect(transaction).to have_id
74
+ expect(transaction).to have_namespace(namespace)
75
+ expect(transaction).to have_action("ResqueErrorTestJob#perform")
76
+ expect(transaction).to have_error("RuntimeError", "resque job error")
77
+ expect(transaction).to_not include_metadata
78
+ expect(transaction).to_not include_breadcrumbs
79
+ expect(transaction).to include_tags("queue" => queue)
80
+ expect(transaction).to include_event("name" => "perform.resque")
95
81
  end
96
82
  end
97
83
 
@@ -115,25 +101,23 @@ describe Appsignal::Hooks::ResqueHook do
115
101
  )
116
102
 
117
103
  transaction = last_transaction
118
- transaction_hash = transaction.to_h
119
- expect(transaction_hash).to include(
120
- "id" => kind_of(String),
121
- "action" => "ResqueTestJob#perform",
122
- "error" => nil,
123
- "namespace" => namespace,
124
- "metadata" => {},
125
- "sample_data" => {
126
- "tags" => { "queue" => queue },
127
- "breadcrumbs" => [],
128
- "params" => [
129
- "foo",
130
- {
131
- "foo" => "[FILTERED]",
132
- "bar" => "Bar",
133
- "baz" => { "1" => "foo" }
134
- }
135
- ]
136
- }
104
+ expect(transaction).to have_id
105
+ expect(transaction).to have_namespace(namespace)
106
+ expect(transaction).to have_action("ResqueTestJob#perform")
107
+ expect(transaction).to_not have_error
108
+ expect(transaction).to_not include_metadata
109
+ expect(transaction).to_not include_breadcrumbs
110
+ expect(transaction).to include_tags("queue" => queue)
111
+ expect(transaction).to include_event("name" => "perform.resque")
112
+ expect(transaction).to include_params(
113
+ [
114
+ "foo",
115
+ {
116
+ "foo" => "[FILTERED]",
117
+ "bar" => "Bar",
118
+ "baz" => { "1" => "foo" }
119
+ }
120
+ ]
137
121
  )
138
122
  end
139
123
  end
@@ -173,19 +157,15 @@ describe Appsignal::Hooks::ResqueHook do
173
157
  )
174
158
 
175
159
  transaction = last_transaction
176
- transaction_hash = transaction.to_h
177
- expect(transaction_hash).to include(
178
- "id" => kind_of(String),
179
- "action" => "ResqueTestJobByActiveJob#perform",
180
- "error" => nil,
181
- "namespace" => namespace,
182
- "metadata" => {},
183
- "sample_data" => {
184
- "breadcrumbs" => [],
185
- "tags" => { "queue" => queue }
186
- # Params will be set by the ActiveJob integration
187
- }
188
- )
160
+ expect(transaction).to have_id
161
+ expect(transaction).to have_namespace(namespace)
162
+ expect(transaction).to have_action("ResqueTestJobByActiveJob#perform")
163
+ expect(transaction).to_not have_error
164
+ expect(transaction).to_not include_metadata
165
+ expect(transaction).to_not include_breadcrumbs
166
+ expect(transaction).to include_tags("queue" => queue)
167
+ expect(transaction).to include_event("name" => "perform.resque")
168
+ expect(transaction).to_not include_params
189
169
  end
190
170
  end
191
171
  end
@@ -37,37 +37,25 @@ describe Appsignal::Hooks::ShoryukenMiddleware do
37
37
  expect { perform_shoryuken_job }.to change { created_transactions.length }.by(1)
38
38
 
39
39
  transaction = last_transaction
40
- expect(transaction).to be_completed
41
- transaction_hash = transaction.to_h
42
- expect(transaction_hash).to include(
43
- "action" => "DemoShoryukenWorker#perform",
44
- "id" => kind_of(String), # AppSignal generated id
45
- "namespace" => Appsignal::Transaction::BACKGROUND_JOB,
46
- "error" => nil
47
- )
48
- expect(transaction_hash["events"].first).to include(
49
- "allocation_count" => kind_of(Integer),
40
+ expect(transaction).to have_id
41
+ expect(transaction).to have_namespace(Appsignal::Transaction::BACKGROUND_JOB)
42
+ expect(transaction).to have_action("DemoShoryukenWorker#perform")
43
+ expect(transaction).to_not have_error
44
+ expect(transaction).to include_event(
50
45
  "body" => "",
51
46
  "body_format" => Appsignal::EventFormatter::DEFAULT,
52
- "child_allocation_count" => kind_of(Integer),
53
- "child_duration" => kind_of(Float),
54
- "child_gc_duration" => kind_of(Float),
55
47
  "count" => 1,
56
- "gc_duration" => kind_of(Float),
57
- "start" => kind_of(Float),
58
- "duration" => kind_of(Float),
59
48
  "name" => "perform_job.shoryuken",
60
49
  "title" => ""
61
50
  )
62
- expect(transaction_hash["sample_data"]).to include(
63
- "params" => { "foo" => "Foo", "bar" => "Bar" },
64
- "metadata" => {
65
- "message_id" => "msg1",
66
- "queue" => queue,
67
- "SentTimestamp" => sent_timestamp
68
- }
51
+ expect(transaction).to include_params("foo" => "Foo", "bar" => "Bar")
52
+ expect(transaction).to include_sample_metadata(
53
+ "message_id" => "msg1",
54
+ "queue" => queue,
55
+ "SentTimestamp" => sent_timestamp
69
56
  )
70
- expect(transaction).to have_received(:set_queue_start).with(sent_timestamp)
57
+ expect(transaction).to have_queue_start(sent_timestamp)
58
+ expect(transaction).to be_completed
71
59
  end
72
60
 
73
61
  context "with parameter filtering" do
@@ -82,10 +70,7 @@ describe Appsignal::Hooks::ShoryukenMiddleware do
82
70
  it "filters selected arguments" do
83
71
  perform_shoryuken_job
84
72
 
85
- transaction_hash = last_transaction.to_h
86
- expect(transaction_hash["sample_data"]).to include(
87
- "params" => { "foo" => "[FILTERED]", "bar" => "Bar" }
88
- )
73
+ expect(last_transaction).to include_params("foo" => "[FILTERED]", "bar" => "Bar")
89
74
  end
90
75
  end
91
76
  end
@@ -96,10 +81,7 @@ describe Appsignal::Hooks::ShoryukenMiddleware do
96
81
  it "handles string arguments" do
97
82
  perform_shoryuken_job
98
83
 
99
- transaction_hash = last_transaction.to_h
100
- expect(transaction_hash["sample_data"]).to include(
101
- "params" => { "params" => body }
102
- )
84
+ expect(last_transaction).to include_params("params" => body)
103
85
  end
104
86
  end
105
87
 
@@ -109,10 +91,7 @@ describe Appsignal::Hooks::ShoryukenMiddleware do
109
91
  it "handles primitive types as arguments" do
110
92
  perform_shoryuken_job
111
93
 
112
- transaction_hash = last_transaction.to_h
113
- expect(transaction_hash["sample_data"]).to include(
114
- "params" => { "params" => body }
115
- )
94
+ expect(last_transaction).to include_params("params" => body)
116
95
  end
117
96
  end
118
97
  end
@@ -126,18 +105,11 @@ describe Appsignal::Hooks::ShoryukenMiddleware do
126
105
  end.to change { created_transactions.length }.by(1)
127
106
 
128
107
  transaction = last_transaction
108
+ expect(transaction).to have_id
109
+ expect(transaction).to have_action("DemoShoryukenWorker#perform")
110
+ expect(transaction).to have_namespace(Appsignal::Transaction::BACKGROUND_JOB)
111
+ expect(transaction).to have_error("ExampleException", "error message")
129
112
  expect(transaction).to be_completed
130
- transaction_hash = transaction.to_h
131
- expect(transaction_hash).to include(
132
- "action" => "DemoShoryukenWorker#perform",
133
- "id" => kind_of(String), # AppSignal generated id
134
- "namespace" => Appsignal::Transaction::BACKGROUND_JOB,
135
- "error" => {
136
- "name" => "ExampleException",
137
- "message" => "error message",
138
- "backtrace" => kind_of(String)
139
- }
140
- )
141
113
  end
142
114
  end
143
115
 
@@ -171,41 +143,28 @@ describe Appsignal::Hooks::ShoryukenMiddleware do
171
143
  end.to change { created_transactions.length }.by(1)
172
144
 
173
145
  transaction = last_transaction
174
- expect(transaction).to be_completed
175
- transaction_hash = transaction.to_h
176
- expect(transaction_hash).to include(
177
- "action" => "DemoShoryukenWorker#perform",
178
- "id" => kind_of(String), # AppSignal generated id
179
- "namespace" => Appsignal::Transaction::BACKGROUND_JOB,
180
- "error" => nil
181
- )
182
- expect(transaction_hash["events"].first).to include(
183
- "allocation_count" => kind_of(Integer),
146
+ expect(transaction).to have_id
147
+ expect(transaction).to have_action("DemoShoryukenWorker#perform")
148
+ expect(transaction).to have_namespace(Appsignal::Transaction::BACKGROUND_JOB)
149
+ expect(transaction).to_not have_error
150
+ expect(transaction).to include_event(
184
151
  "body" => "",
185
152
  "body_format" => Appsignal::EventFormatter::DEFAULT,
186
- "child_allocation_count" => kind_of(Integer),
187
- "child_duration" => kind_of(Float),
188
- "child_gc_duration" => kind_of(Float),
189
153
  "count" => 1,
190
- "gc_duration" => kind_of(Float),
191
- "start" => kind_of(Float),
192
- "duration" => kind_of(Float),
193
154
  "name" => "perform_job.shoryuken",
194
155
  "title" => ""
195
156
  )
196
- expect(transaction_hash["sample_data"]).to include(
197
- "params" => {
198
- "msg2" => "foo bar",
199
- "msg1" => { "id" => "123", "foo" => "Foo", "bar" => "Bar" }
200
- },
201
- "metadata" => {
202
- "batch" => true,
203
- "queue" => "some-funky-queue-name",
204
- "SentTimestamp" => sent_timestamp.to_s # Earliest/oldest timestamp from messages
205
- }
157
+ expect(transaction).to include_params(
158
+ "msg2" => "foo bar",
159
+ "msg1" => { "id" => "123", "foo" => "Foo", "bar" => "Bar" }
160
+ )
161
+ expect(transaction).to include_sample_metadata(
162
+ "batch" => true,
163
+ "queue" => "some-funky-queue-name",
164
+ "SentTimestamp" => sent_timestamp.to_s # Earliest/oldest timestamp from messages
206
165
  )
207
166
  # Queue time based on earliest/oldest timestamp from messages
208
- expect(transaction).to have_received(:set_queue_start).with(sent_timestamp)
167
+ expect(transaction).to have_queue_start(sent_timestamp)
209
168
  end
210
169
  end
211
170
  end
@@ -5,7 +5,12 @@ if DependencyHelper.hanami2_present?
5
5
  require "appsignal/integrations/hanami"
6
6
 
7
7
  before do
8
+ Appsignal.config = nil
9
+ allow(::Hanami::Action).to receive(:prepend)
8
10
  uninstall_hanami_middleware
11
+ ENV["APPSIGNAL_APP_NAME"] = "hanamia-test-app"
12
+ ENV["APPSIGNAL_APP_ENV"] = "test"
13
+ ENV["APPSIGNAL_PUSH_API_KEY"] = "0000"
9
14
  end
10
15
 
11
16
  def uninstall_hanami_middleware
@@ -18,35 +23,41 @@ if DependencyHelper.hanami2_present?
18
23
 
19
24
  describe Appsignal::Integrations::HanamiPlugin do
20
25
  it "starts AppSignal on init" do
21
- expect(Appsignal).to receive(:start)
22
- expect(Appsignal).to receive(:start_logger)
26
+ expect(Appsignal.active?).to be_falsey
27
+
23
28
  Appsignal::Integrations::HanamiPlugin.init
29
+
30
+ expect(Appsignal.active?).to be_truthy
24
31
  end
25
32
 
26
33
  it "prepends the integration to Hanami::Action" do
27
- allow(Appsignal).to receive(:active?).and_return(true)
28
34
  Appsignal::Integrations::HanamiPlugin.init
29
- expect(::Hanami::Action.included_modules)
30
- .to include(Appsignal::Integrations::HanamiIntegration)
35
+
36
+ expect(::Hanami::Action)
37
+ .to have_received(:prepend).with(Appsignal::Integrations::HanamiIntegration)
31
38
  end
32
39
 
33
40
  it "adds middleware to the Hanami app" do
34
- allow(Appsignal).to receive(:active?).and_return(true)
35
41
  Appsignal::Integrations::HanamiPlugin.init
36
42
 
37
43
  expect(::Hanami.app.config.middleware.stack[::Hanami::Router::DEFAULT_PREFIX])
38
44
  .to include(
39
- [Rack::Events, [[kind_of(Appsignal::Rack::EventHandler)]], nil],
40
- [Appsignal::Rack::HanamiMiddleware, [], nil]
45
+ [Rack::Events, [[kind_of(Appsignal::Rack::EventHandler)]], *hanami_middleware_options],
46
+ [Appsignal::Rack::HanamiMiddleware, [], *hanami_middleware_options]
41
47
  )
42
48
  end
43
49
 
44
50
  context "when not active" do
45
- before { allow(Appsignal).to receive(:active?).and_return(false) }
51
+ before do
52
+ ENV.delete("APPSIGNAL_APP_NAME")
53
+ ENV.delete("APPSIGNAL_APP_ENV")
54
+ ENV.delete("APPSIGNAL_PUSH_API_KEY")
55
+ end
46
56
 
47
57
  it "does not prepend the integration to Hanami::Action" do
48
58
  Appsignal::Integrations::HanamiPlugin.init
49
- expect(::Hanami::Action).to_not receive(:prepend)
59
+
60
+ expect(::Hanami::Action).to_not have_received(:prepend)
50
61
  .with(Appsignal::Integrations::HanamiIntegration)
51
62
  end
52
63
 
@@ -55,14 +66,47 @@ if DependencyHelper.hanami2_present?
55
66
 
56
67
  middleware_stack = ::Hanami.app.config.middleware.stack[::Hanami::Router::DEFAULT_PREFIX]
57
68
  expect(middleware_stack).to_not include(
58
- [Rack::Events, [[kind_of(Appsignal::Rack::EventHandler)]], nil]
69
+ [Rack::Events, [[kind_of(Appsignal::Rack::EventHandler)]], *hanami_middleware_options]
59
70
  )
60
71
  expect(middleware_stack).to_not include(
61
- [Appsignal::Rack::HanamiMiddleware, [], nil]
72
+ [Appsignal::Rack::HanamiMiddleware, [], *hanami_middleware_options]
62
73
  )
63
74
  end
64
75
  end
65
76
 
77
+ context "when AppSignal is already active" do
78
+ before do
79
+ expect(Appsignal).to receive(:active?).at_least(1).and_return(true)
80
+ end
81
+
82
+ it "does not initialize AppSignal again" do
83
+ expect(Appsignal).to_not receive(:start)
84
+
85
+ Appsignal::Integrations::HanamiPlugin.init
86
+ end
87
+
88
+ it "prepends the integration to Hanami::Action" do
89
+ Appsignal::Integrations::HanamiPlugin.init
90
+
91
+ expect(::Hanami::Action)
92
+ .to have_received(:prepend).with(Appsignal::Integrations::HanamiIntegration)
93
+ end
94
+
95
+ it "adds middleware to the Hanami app" do
96
+ Appsignal::Integrations::HanamiPlugin.init
97
+
98
+ expect(::Hanami.app.config.middleware.stack[::Hanami::Router::DEFAULT_PREFIX])
99
+ .to include(
100
+ [
101
+ Rack::Events,
102
+ [[kind_of(Appsignal::Rack::EventHandler)]],
103
+ *hanami_middleware_options
104
+ ],
105
+ [Appsignal::Rack::HanamiMiddleware, [], *hanami_middleware_options]
106
+ )
107
+ end
108
+ end
109
+
66
110
  context "when APPSIGNAL_APP_ENV ENV var is provided" do
67
111
  it "uses this as the environment" do
68
112
  ENV["APPSIGNAL_APP_ENV"] = "custom"
@@ -86,14 +130,24 @@ if DependencyHelper.hanami2_present?
86
130
 
87
131
  describe Appsignal::Integrations::HanamiIntegration do
88
132
  let(:transaction) { http_request_transaction }
133
+ let(:app) do
134
+ Class.new(HanamiApp::Actions::Books::Index) do
135
+ def self.name
136
+ "HanamiApp::Actions::Books::Index::TestClass"
137
+ end
138
+ end
139
+ end
89
140
  around { |example| keep_transactions { example.run } }
90
- before(:context) { start_agent }
91
141
  before do
92
- allow(Appsignal).to receive(:active?).and_return(true)
142
+ ENV["APPSIGNAL_APP_NAME"] = "hanamia-test-app"
143
+ ENV["APPSIGNAL_APP_ENV"] = "test"
144
+ ENV["APPSIGNAL_PUSH_API_KEY"] = "0000"
93
145
  Appsignal::Integrations::HanamiPlugin.init
146
+ allow(app).to receive(:prepend).and_call_original
147
+ app.prepend(Appsignal::Integrations::HanamiIntegration)
94
148
  end
95
149
 
96
- def make_request(env, app: HanamiApp::Actions::Books::Index)
150
+ def make_request(env)
97
151
  action = app.new
98
152
  action.call(env)
99
153
  end
@@ -105,9 +159,7 @@ if DependencyHelper.hanami2_present?
105
159
  it "does not set the action name" do
106
160
  make_request(env)
107
161
 
108
- expect(transaction.to_h).to include(
109
- "action" => nil
110
- )
162
+ expect(transaction).to_not have_action
111
163
  end
112
164
  end
113
165
 
@@ -117,12 +169,18 @@ if DependencyHelper.hanami2_present?
117
169
  it "sets action name on the transaction" do
118
170
  make_request(env)
119
171
 
120
- expect(transaction.to_h).to include(
121
- "action" => "HanamiApp::Actions::Books::Index"
122
- )
172
+ expect(transaction).to have_action("HanamiApp::Actions::Books::Index::TestClass")
123
173
  end
124
174
  end
125
175
  end
126
176
  end
177
+
178
+ def hanami_middleware_options
179
+ if DependencyHelper.hanami2_1_present?
180
+ [{}, nil]
181
+ else
182
+ [nil]
183
+ end
184
+ end
127
185
  end
128
186
  end
@@ -23,9 +23,8 @@ if DependencyHelper.http_present?
23
23
 
24
24
  HTTP.get("http://www.google.com")
25
25
 
26
- transaction_hash = transaction.to_h
27
- expect(transaction_hash).to include("namespace" => Appsignal::Transaction::HTTP_REQUEST)
28
- expect(transaction_hash["events"].first).to include(
26
+ expect(transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
27
+ expect(transaction).to include_event(
29
28
  "body" => "",
30
29
  "body_format" => Appsignal::EventFormatter::DEFAULT,
31
30
  "name" => "request.http_rb",
@@ -38,9 +37,8 @@ if DependencyHelper.http_present?
38
37
 
39
38
  HTTP.get("https://www.google.com")
40
39
 
41
- transaction_hash = transaction.to_h
42
- expect(transaction_hash).to include("namespace" => Appsignal::Transaction::HTTP_REQUEST)
43
- expect(transaction_hash["events"].first).to include(
40
+ expect(transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
41
+ expect(transaction).to include_event(
44
42
  "body" => "",
45
43
  "body_format" => Appsignal::EventFormatter::DEFAULT,
46
44
  "name" => "request.http_rb",
@@ -54,7 +52,7 @@ if DependencyHelper.http_present?
54
52
 
55
53
  HTTP.get("https://www.google.com", :params => { :q => "Appsignal" })
56
54
 
57
- expect(transaction.to_h["events"].first).to include(
55
+ expect(transaction).to include_event(
58
56
  "body" => "",
59
57
  "title" => "GET https://www.google.com"
60
58
  )
@@ -66,7 +64,7 @@ if DependencyHelper.http_present?
66
64
 
67
65
  HTTP.post("https://www.google.com", :json => { :q => "Appsignal" })
68
66
 
69
- expect(transaction.to_h["events"].first).to include(
67
+ expect(transaction).to include_event(
70
68
  "body" => "",
71
69
  "title" => "POST https://www.google.com"
72
70
  )
@@ -83,20 +81,14 @@ if DependencyHelper.http_present?
83
81
  HTTP.get("https://www.google.com")
84
82
  end.to raise_error(ExampleException)
85
83
 
86
- transaction_hash = transaction.to_h
87
- expect(transaction_hash).to include("namespace" => Appsignal::Transaction::HTTP_REQUEST)
88
- expect(transaction_hash["events"].first).to include(
84
+ expect(transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
85
+ expect(transaction).to include_event(
89
86
  "body" => "",
90
87
  "body_format" => Appsignal::EventFormatter::DEFAULT,
91
88
  "name" => "request.http_rb",
92
89
  "title" => "GET https://www.google.com"
93
90
  )
94
-
95
- expect(transaction_hash["error"]).to include(
96
- "backtrace" => kind_of(String),
97
- "name" => error.class.name,
98
- "message" => error.message
99
- )
91
+ expect(transaction).to have_error(error.class.name, error.message)
100
92
  end
101
93
  end
102
94
 
@@ -112,7 +104,7 @@ if DependencyHelper.http_present?
112
104
 
113
105
  HTTP.get(request_uri.new("http://www.google.com"))
114
106
 
115
- expect(transaction.to_h["events"].first).to include(
107
+ expect(transaction).to include_event(
116
108
  "name" => "request.http_rb",
117
109
  "title" => "GET http://www.google.com"
118
110
  )
@@ -123,7 +115,7 @@ if DependencyHelper.http_present?
123
115
 
124
116
  HTTP.get(URI("http://www.google.com"))
125
117
 
126
- expect(transaction.to_h["events"].first).to include(
118
+ expect(transaction).to include_event(
127
119
  "name" => "request.http_rb",
128
120
  "title" => "GET http://www.google.com"
129
121
  )
@@ -134,7 +126,7 @@ if DependencyHelper.http_present?
134
126
 
135
127
  HTTP.get("http://www.google.com")
136
128
 
137
- expect(transaction.to_h["events"].first).to include(
129
+ expect(transaction).to include_event(
138
130
  "name" => "request.http_rb",
139
131
  "title" => "GET http://www.google.com"
140
132
  )
@@ -0,0 +1,33 @@
1
+ require "appsignal/integrations/net_http"
2
+
3
+ describe Appsignal::Integrations::NetHttpIntegration do
4
+ let(:transaction) { http_request_transaction }
5
+ before(:context) { start_agent }
6
+ before { set_current_transaction transaction }
7
+ around { |example| keep_transactions { example.run } }
8
+
9
+ it "instruments a http request" do
10
+ stub_request(:any, "http://www.google.com/")
11
+
12
+ Net::HTTP.get_response(URI.parse("http://www.google.com"))
13
+
14
+ expect(transaction).to include_event(
15
+ "name" => "request.net_http",
16
+ "title" => "GET http://www.google.com"
17
+ )
18
+ end
19
+
20
+ it "instruments a https request" do
21
+ stub_request(:any, "https://www.google.com/")
22
+
23
+ uri = URI.parse("https://www.google.com")
24
+ http = Net::HTTP.new(uri.host, uri.port)
25
+ http.use_ssl = true
26
+ http.get(uri.request_uri)
27
+
28
+ expect(transaction).to include_event(
29
+ "name" => "request.net_http",
30
+ "title" => "GET https://www.google.com"
31
+ )
32
+ end
33
+ end