appsignal 3.9.2-java → 3.9.3-java

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
@@ -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