appsignal 4.0.5 → 4.0.7

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 (203) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +20 -0
  3. data/Rakefile +9 -9
  4. data/appsignal.gemspec +22 -1
  5. data/build_matrix.yml +2 -1
  6. data/ext/agent.rb +27 -27
  7. data/lib/appsignal/check_in/scheduler.rb +3 -4
  8. data/lib/appsignal/check_in.rb +1 -1
  9. data/lib/appsignal/config.rb +1 -3
  10. data/lib/appsignal/integrations/que.rb +8 -2
  11. data/lib/appsignal/integrations/resque.rb +1 -6
  12. data/lib/appsignal/utils/hash_sanitizer.rb +4 -0
  13. data/lib/appsignal/version.rb +1 -1
  14. metadata +2 -191
  15. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -31
  16. data/.github/ISSUE_TEMPLATE/chore.md +0 -14
  17. data/.github/workflows/ci.yml +0 -3150
  18. data/.github/workflows/create_release_from_tag.yml +0 -62
  19. data/.gitignore +0 -35
  20. data/.gitmodules +0 -3
  21. data/.rspec +0 -4
  22. data/.yardopts +0 -8
  23. data/benchmark.rake +0 -139
  24. data/gemfiles/capistrano2.gemfile +0 -6
  25. data/gemfiles/capistrano3.gemfile +0 -7
  26. data/gemfiles/dry-monitor.gemfile +0 -5
  27. data/gemfiles/grape.gemfile +0 -5
  28. data/gemfiles/hanami-2.0.gemfile +0 -7
  29. data/gemfiles/hanami-2.1.gemfile +0 -7
  30. data/gemfiles/http5.gemfile +0 -5
  31. data/gemfiles/no_dependencies.gemfile +0 -10
  32. data/gemfiles/padrino.gemfile +0 -7
  33. data/gemfiles/psych-3.gemfile +0 -5
  34. data/gemfiles/psych-4.gemfile +0 -5
  35. data/gemfiles/que.gemfile +0 -5
  36. data/gemfiles/rails-6.0.gemfile +0 -10
  37. data/gemfiles/rails-6.1.gemfile +0 -11
  38. data/gemfiles/rails-7.0.gemfile +0 -11
  39. data/gemfiles/rails-7.1.gemfile +0 -11
  40. data/gemfiles/rails-7.2.gemfile +0 -11
  41. data/gemfiles/redis-4.gemfile +0 -5
  42. data/gemfiles/redis-5.gemfile +0 -6
  43. data/gemfiles/resque-2.gemfile +0 -6
  44. data/gemfiles/sequel.gemfile +0 -10
  45. data/gemfiles/sinatra.gemfile +0 -5
  46. data/gemfiles/webmachine1.gemfile +0 -7
  47. data/gemfiles/webmachine2.gemfile +0 -6
  48. data/mono.yml +0 -16
  49. data/spec/.rubocop.yml +0 -7
  50. data/spec/lib/appsignal/auth_check_spec.rb +0 -84
  51. data/spec/lib/appsignal/capistrano2_spec.rb +0 -227
  52. data/spec/lib/appsignal/capistrano3_spec.rb +0 -284
  53. data/spec/lib/appsignal/check_in/cron_spec.rb +0 -202
  54. data/spec/lib/appsignal/check_in/scheduler_spec.rb +0 -443
  55. data/spec/lib/appsignal/cli/demo_spec.rb +0 -46
  56. data/spec/lib/appsignal/cli/diagnose/paths_spec.rb +0 -16
  57. data/spec/lib/appsignal/cli/diagnose/utils_spec.rb +0 -86
  58. data/spec/lib/appsignal/cli/diagnose_spec.rb +0 -1553
  59. data/spec/lib/appsignal/cli/helpers_spec.rb +0 -179
  60. data/spec/lib/appsignal/cli/install_spec.rb +0 -848
  61. data/spec/lib/appsignal/cli_spec.rb +0 -56
  62. data/spec/lib/appsignal/config_spec.rb +0 -1380
  63. data/spec/lib/appsignal/demo_spec.rb +0 -83
  64. data/spec/lib/appsignal/environment_spec.rb +0 -190
  65. data/spec/lib/appsignal/event_formatter/action_view/render_formatter_spec.rb +0 -60
  66. data/spec/lib/appsignal/event_formatter/active_record/instantiation_formatter_spec.rb +0 -21
  67. data/spec/lib/appsignal/event_formatter/active_record/sql_formatter_spec.rb +0 -21
  68. data/spec/lib/appsignal/event_formatter/elastic_search/search_formatter_spec.rb +0 -52
  69. data/spec/lib/appsignal/event_formatter/faraday/request_formatter_spec.rb +0 -21
  70. data/spec/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter_spec.rb +0 -84
  71. data/spec/lib/appsignal/event_formatter/rom/sql_formatter_spec.rb +0 -22
  72. data/spec/lib/appsignal/event_formatter/sequel/sql_formatter_spec.rb +0 -30
  73. data/spec/lib/appsignal/event_formatter/view_component/render_formatter_spec.rb +0 -41
  74. data/spec/lib/appsignal/event_formatter_spec.rb +0 -193
  75. data/spec/lib/appsignal/extension/jruby_spec.rb +0 -46
  76. data/spec/lib/appsignal/extension_install_failure_spec.rb +0 -20
  77. data/spec/lib/appsignal/extension_spec.rb +0 -178
  78. data/spec/lib/appsignal/garbage_collection_spec.rb +0 -98
  79. data/spec/lib/appsignal/hooks/action_cable_spec.rb +0 -345
  80. data/spec/lib/appsignal/hooks/action_mailer_spec.rb +0 -55
  81. data/spec/lib/appsignal/hooks/active_support_notifications/finish_with_state_shared_examples.rb +0 -23
  82. data/spec/lib/appsignal/hooks/active_support_notifications/instrument_shared_examples.rb +0 -99
  83. data/spec/lib/appsignal/hooks/active_support_notifications/start_finish_shared_examples.rb +0 -47
  84. data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +0 -47
  85. data/spec/lib/appsignal/hooks/activejob_spec.rb +0 -650
  86. data/spec/lib/appsignal/hooks/at_exit_spec.rb +0 -105
  87. data/spec/lib/appsignal/hooks/celluloid_spec.rb +0 -40
  88. data/spec/lib/appsignal/hooks/data_mapper_spec.rb +0 -40
  89. data/spec/lib/appsignal/hooks/delayed_job_spec.rb +0 -38
  90. data/spec/lib/appsignal/hooks/dry_monitor_spec.rb +0 -83
  91. data/spec/lib/appsignal/hooks/excon_spec.rb +0 -67
  92. data/spec/lib/appsignal/hooks/gvl_spec.rb +0 -145
  93. data/spec/lib/appsignal/hooks/http_spec.rb +0 -37
  94. data/spec/lib/appsignal/hooks/mongo_ruby_driver_spec.rb +0 -46
  95. data/spec/lib/appsignal/hooks/mri_spec.rb +0 -23
  96. data/spec/lib/appsignal/hooks/net_http_spec.rb +0 -18
  97. data/spec/lib/appsignal/hooks/passenger_spec.rb +0 -30
  98. data/spec/lib/appsignal/hooks/puma_spec.rb +0 -80
  99. data/spec/lib/appsignal/hooks/que_spec.rb +0 -19
  100. data/spec/lib/appsignal/hooks/rake_spec.rb +0 -144
  101. data/spec/lib/appsignal/hooks/redis_client_spec.rb +0 -218
  102. data/spec/lib/appsignal/hooks/redis_spec.rb +0 -124
  103. data/spec/lib/appsignal/hooks/resque_spec.rb +0 -27
  104. data/spec/lib/appsignal/hooks/sequel_spec.rb +0 -44
  105. data/spec/lib/appsignal/hooks/shoryuken_spec.rb +0 -29
  106. data/spec/lib/appsignal/hooks/sidekiq_spec.rb +0 -115
  107. data/spec/lib/appsignal/hooks/unicorn_spec.rb +0 -63
  108. data/spec/lib/appsignal/hooks/webmachine_spec.rb +0 -24
  109. data/spec/lib/appsignal/hooks_spec.rb +0 -124
  110. data/spec/lib/appsignal/integrations/data_mapper_spec.rb +0 -74
  111. data/spec/lib/appsignal/integrations/delayed_job_plugin_spec.rb +0 -454
  112. data/spec/lib/appsignal/integrations/http_spec.rb +0 -111
  113. data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +0 -154
  114. data/spec/lib/appsignal/integrations/net_http_spec.rb +0 -33
  115. data/spec/lib/appsignal/integrations/object_spec.rb +0 -347
  116. data/spec/lib/appsignal/integrations/puma_spec.rb +0 -150
  117. data/spec/lib/appsignal/integrations/que_spec.rb +0 -152
  118. data/spec/lib/appsignal/integrations/railtie_spec.rb +0 -457
  119. data/spec/lib/appsignal/integrations/resque_spec.rb +0 -155
  120. data/spec/lib/appsignal/integrations/shoryuken_spec.rb +0 -165
  121. data/spec/lib/appsignal/integrations/sidekiq_spec.rb +0 -640
  122. data/spec/lib/appsignal/integrations/webmachine_spec.rb +0 -136
  123. data/spec/lib/appsignal/loaders/grape_spec.rb +0 -12
  124. data/spec/lib/appsignal/loaders/hanami_spec.rb +0 -92
  125. data/spec/lib/appsignal/loaders/padrino_spec.rb +0 -273
  126. data/spec/lib/appsignal/loaders/sinatra_spec.rb +0 -44
  127. data/spec/lib/appsignal/loaders_spec.rb +0 -144
  128. data/spec/lib/appsignal/logger_spec.rb +0 -205
  129. data/spec/lib/appsignal/marker_spec.rb +0 -51
  130. data/spec/lib/appsignal/probes/gvl_spec.rb +0 -164
  131. data/spec/lib/appsignal/probes/mri_spec.rb +0 -162
  132. data/spec/lib/appsignal/probes/sidekiq_spec.rb +0 -333
  133. data/spec/lib/appsignal/probes_spec.rb +0 -411
  134. data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +0 -370
  135. data/spec/lib/appsignal/rack/body_wrapper_spec.rb +0 -319
  136. data/spec/lib/appsignal/rack/event_handler_spec.rb +0 -441
  137. data/spec/lib/appsignal/rack/grape_middleware_spec.rb +0 -201
  138. data/spec/lib/appsignal/rack/hanami_middleware_spec.rb +0 -36
  139. data/spec/lib/appsignal/rack/instrumentation_middleware_spec.rb +0 -38
  140. data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +0 -126
  141. data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +0 -217
  142. data/spec/lib/appsignal/rack_spec.rb +0 -243
  143. data/spec/lib/appsignal/sample_data_spec.rb +0 -238
  144. data/spec/lib/appsignal/span_spec.rb +0 -141
  145. data/spec/lib/appsignal/system_spec.rb +0 -126
  146. data/spec/lib/appsignal/transaction_spec.rb +0 -2111
  147. data/spec/lib/appsignal/transmitter_spec.rb +0 -198
  148. data/spec/lib/appsignal/utils/data_spec.rb +0 -166
  149. data/spec/lib/appsignal/utils/hash_sanitizer_spec.rb +0 -182
  150. data/spec/lib/appsignal/utils/integration_logger_spec.rb +0 -21
  151. data/spec/lib/appsignal/utils/integration_memory_logger_spec.rb +0 -153
  152. data/spec/lib/appsignal/utils/json_spec.rb +0 -44
  153. data/spec/lib/appsignal/utils/query_params_sanitizer_spec.rb +0 -192
  154. data/spec/lib/appsignal_spec.rb +0 -1919
  155. data/spec/lib/puma/appsignal_spec.rb +0 -334
  156. data/spec/spec_helper.rb +0 -173
  157. data/spec/support/fixtures/generated_config.yml +0 -24
  158. data/spec/support/fixtures/projects/broken/config/appsignal.yml +0 -1
  159. data/spec/support/fixtures/projects/valid/config/appsignal.yml +0 -57
  160. data/spec/support/fixtures/projects/valid/log/.gitkeep +0 -0
  161. data/spec/support/fixtures/projects/valid_with_rails_app/config/application.rb +0 -16
  162. data/spec/support/fixtures/projects/valid_with_rails_app/config/appsignal.yml +0 -56
  163. data/spec/support/fixtures/projects/valid_with_rails_app/config/environment.rb +0 -10
  164. data/spec/support/fixtures/projects/valid_with_rails_app/log/.gitkeep +0 -0
  165. data/spec/support/fixtures/uploaded_file.txt +0 -0
  166. data/spec/support/hanami/hanami_app.rb +0 -29
  167. data/spec/support/helpers/action_mailer_helpers.rb +0 -25
  168. data/spec/support/helpers/activejob_helpers.rb +0 -27
  169. data/spec/support/helpers/api_request_helper.rb +0 -20
  170. data/spec/support/helpers/cli_helpers.rb +0 -40
  171. data/spec/support/helpers/config_helpers.rb +0 -66
  172. data/spec/support/helpers/dependency_helper.rb +0 -150
  173. data/spec/support/helpers/directory_helper.rb +0 -27
  174. data/spec/support/helpers/env_helpers.rb +0 -41
  175. data/spec/support/helpers/environment_metdata_helper.rb +0 -16
  176. data/spec/support/helpers/example_exception.rb +0 -13
  177. data/spec/support/helpers/example_standard_error.rb +0 -13
  178. data/spec/support/helpers/loader_helper.rb +0 -21
  179. data/spec/support/helpers/log_helpers.rb +0 -36
  180. data/spec/support/helpers/rails_helper.rb +0 -28
  181. data/spec/support/helpers/std_streams_helper.rb +0 -94
  182. data/spec/support/helpers/system_helpers.rb +0 -8
  183. data/spec/support/helpers/take_at_most_helper.rb +0 -21
  184. data/spec/support/helpers/time_helpers.rb +0 -11
  185. data/spec/support/helpers/transaction_helpers.rb +0 -122
  186. data/spec/support/helpers/wait_for_helper.rb +0 -39
  187. data/spec/support/matchers/contains_log.rb +0 -26
  188. data/spec/support/matchers/have_colorized_text.rb +0 -28
  189. data/spec/support/matchers/transaction.rb +0 -200
  190. data/spec/support/mocks/appsignal_mock.rb +0 -18
  191. data/spec/support/mocks/dummy_app.rb +0 -20
  192. data/spec/support/mocks/fake_gc_profiler.rb +0 -19
  193. data/spec/support/mocks/fake_gvl_tools.rb +0 -28
  194. data/spec/support/mocks/hash_like.rb +0 -10
  195. data/spec/support/mocks/mock_probe.rb +0 -13
  196. data/spec/support/mocks/puma_mock.rb +0 -43
  197. data/spec/support/shared_examples/instrument.rb +0 -48
  198. data/spec/support/stubs/appsignal/loaders/loader_stub.rb +0 -7
  199. data/spec/support/stubs/delayed_job.rb +0 -0
  200. data/spec/support/stubs/sidekiq/api.rb +0 -4
  201. data/spec/support/testing.rb +0 -194
  202. data/support/bundler_wrapper +0 -12
  203. data/support/install_deps +0 -33
@@ -1,370 +0,0 @@
1
- describe Appsignal::Rack::AbstractMiddleware do
2
- let(:app) { DummyApp.new }
3
- let(:env) do
4
- Rack::MockRequest.env_for(
5
- "/some/path",
6
- "REQUEST_METHOD" => "GET",
7
- :params => { "page" => 2, "query" => "lorem" },
8
- "rack.session" => { "session" => "data", "user_id" => 123 }
9
- )
10
- end
11
- let(:middleware) { described_class.new(app, options) }
12
-
13
- let(:appsignal_env) { :default }
14
- let(:options) { {} }
15
- before { start_agent(:env => appsignal_env) }
16
- around { |example| keep_transactions { example.run } }
17
-
18
- def make_request
19
- middleware.call(env)
20
- end
21
-
22
- def make_request_with_error(error_class, error_message)
23
- expect { make_request }.to raise_error(error_class, error_message)
24
- end
25
-
26
- describe "#call" do
27
- context "when not active" do
28
- let(:appsignal_env) { :inactive_env }
29
-
30
- it "does not instrument the request" do
31
- expect { make_request }.to_not(change { created_transactions.count })
32
- end
33
-
34
- it "calls the next middleware in the stack" do
35
- make_request
36
- expect(app).to be_called
37
- end
38
- end
39
-
40
- context "when appsignal is active" do
41
- it "creates a transaction for the request" do
42
- expect { make_request }.to(change { created_transactions.count }.by(1))
43
-
44
- expect(last_transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
45
- end
46
-
47
- it "wraps the response body in a BodyWrapper subclass" do
48
- _status, _headers, body = make_request
49
- expect(body).to be_kind_of(Appsignal::Rack::BodyWrapper)
50
- end
51
-
52
- context "without an error" do
53
- before { make_request }
54
-
55
- it "calls the next middleware in the stack" do
56
- expect(app).to be_called
57
- end
58
-
59
- it "does not record an error" do
60
- expect(last_transaction).to_not have_error
61
- end
62
-
63
- context "without :instrument_event_name option set" do
64
- let(:options) { {} }
65
-
66
- it "does not record an instrumentation event" do
67
- expect(last_transaction).to_not include_event
68
- end
69
- end
70
-
71
- context "with :instrument_event_name option set" do
72
- let(:options) { { :instrument_event_name => "event_name.category" } }
73
-
74
- it "records an instrumentation event" do
75
- expect(last_transaction).to include_event(:name => "event_name.category")
76
- end
77
- end
78
-
79
- it "completes the transaction" do
80
- expect(last_transaction).to be_completed
81
- expect(Appsignal::Transaction.current)
82
- .to be_kind_of(Appsignal::Transaction::NilTransaction)
83
- end
84
-
85
- context "when instrument_event_name option is nil" do
86
- let(:options) { { :instrument_event_name => nil } }
87
-
88
- it "does not record an instrumentation event" do
89
- expect(last_transaction).to_not include_events
90
- end
91
- end
92
- end
93
-
94
- context "with an error" do
95
- let(:error) { ExampleException.new("error message") }
96
- let(:app) { lambda { |_env| raise ExampleException, "error message" } }
97
-
98
- it "create a transaction for the request" do
99
- expect { make_request_with_error(ExampleException, "error message") }
100
- .to(change { created_transactions.count }.by(1))
101
-
102
- expect(last_transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
103
- end
104
-
105
- describe "error" do
106
- before do
107
- make_request_with_error(ExampleException, "error message")
108
- end
109
-
110
- it "records the error" do
111
- expect(last_transaction).to have_error("ExampleException", "error message")
112
- end
113
-
114
- it "completes the transaction" do
115
- expect(last_transaction).to be_completed
116
- expect(Appsignal::Transaction.current)
117
- .to be_kind_of(Appsignal::Transaction::NilTransaction)
118
- end
119
-
120
- context "with :report_errors set to false" do
121
- let(:app) { lambda { |_env| raise ExampleException, "error message" } }
122
- let(:options) { { :report_errors => false } }
123
-
124
- it "does not record the exception on the transaction" do
125
- expect(last_transaction).to_not have_error
126
- end
127
- end
128
-
129
- context "with :report_errors set to true" do
130
- let(:app) { lambda { |_env| raise ExampleException, "error message" } }
131
- let(:options) { { :report_errors => true } }
132
-
133
- it "records the exception on the transaction" do
134
- expect(last_transaction).to have_error("ExampleException", "error message")
135
- end
136
- end
137
-
138
- context "with :report_errors set to a lambda that returns false" do
139
- let(:app) { lambda { |_env| raise ExampleException, "error message" } }
140
- let(:options) { { :report_errors => lambda { |_env| false } } }
141
-
142
- it "does not record the exception on the transaction" do
143
- expect(last_transaction).to_not have_error
144
- end
145
- end
146
-
147
- context "with :report_errors set to a lambda that returns true" do
148
- let(:app) { lambda { |_env| raise ExampleException, "error message" } }
149
- let(:options) { { :report_errors => lambda { |_env| true } } }
150
-
151
- it "records the exception on the transaction" do
152
- expect(last_transaction).to have_error("ExampleException", "error message")
153
- end
154
- end
155
- end
156
- end
157
-
158
- context "without action name metadata" do
159
- it "reports no action name" do
160
- make_request
161
-
162
- expect(last_transaction).to_not have_action
163
- end
164
- end
165
-
166
- # Partial duplicate tests from Appsignal::Rack::ApplyRackRequest that
167
- # ensure the request metadata is set on via the AbstractMiddleware.
168
- describe "request metadata" do
169
- it "sets request metadata" do
170
- env.merge!("PATH_INFO" => "/some/path", "REQUEST_METHOD" => "GET")
171
- make_request
172
-
173
- expect(last_transaction).to include_metadata(
174
- "request_method" => "GET",
175
- "method" => "GET",
176
- "request_path" => "/some/path",
177
- "path" => "/some/path"
178
- )
179
- expect(last_transaction).to include_environment(
180
- "REQUEST_METHOD" => "GET",
181
- "PATH_INFO" => "/some/path"
182
- # and more, but we don't need to test Rack mock defaults
183
- )
184
- end
185
-
186
- it "sets request parameters" do
187
- make_request
188
-
189
- expect(last_transaction).to include_params(
190
- "page" => "2",
191
- "query" => "lorem"
192
- )
193
- end
194
-
195
- it "sets session data" do
196
- make_request
197
-
198
- expect(last_transaction).to include_session_data("session" => "data", "user_id" => 123)
199
- end
200
-
201
- context "with queue start header" do
202
- let(:queue_start_time) { fixed_time * 1_000 }
203
-
204
- it "sets the queue start" do
205
- env["HTTP_X_REQUEST_START"] = "t=#{queue_start_time.to_i}" # in milliseconds
206
- make_request
207
-
208
- expect(last_transaction).to have_queue_start(queue_start_time)
209
- end
210
- end
211
-
212
- class SomeFilteredRequest
213
- attr_reader :env
214
-
215
- def initialize(env)
216
- @env = env
217
- end
218
-
219
- def path
220
- "/static/path"
221
- end
222
-
223
- def request_method
224
- "GET"
225
- end
226
-
227
- def filtered_params
228
- { "abc" => "123" }
229
- end
230
-
231
- def session
232
- { "data" => "value" }
233
- end
234
- end
235
-
236
- context "with overridden request class and params method" do
237
- let(:options) do
238
- { :request_class => SomeFilteredRequest, :params_method => :filtered_params }
239
- end
240
-
241
- it "uses the overridden request class and params method to fetch params" do
242
- make_request
243
-
244
- expect(last_transaction).to include_params("abc" => "123")
245
- end
246
-
247
- it "uses the overridden request class to fetch session data" do
248
- make_request
249
-
250
- expect(last_transaction).to include_session_data("data" => "value")
251
- end
252
- end
253
- end
254
-
255
- context "with parent instrumentation" do
256
- let(:transaction) { http_request_transaction }
257
- before do
258
- env[Appsignal::Rack::APPSIGNAL_TRANSACTION] = transaction
259
- set_current_transaction(transaction)
260
- end
261
-
262
- it "uses the existing transaction" do
263
- make_request
264
-
265
- expect { make_request }.to_not(change { created_transactions.count })
266
- end
267
-
268
- it "wraps the response body in a BodyWrapper subclass" do
269
- _status, _headers, body = make_request
270
- expect(body).to be_kind_of(Appsignal::Rack::BodyWrapper)
271
-
272
- body.to_ary
273
- response_events =
274
- last_transaction.to_h["events"].count do |event|
275
- event["name"] == "process_response_body.rack"
276
- end
277
- expect(response_events).to eq(1)
278
- end
279
-
280
- context "when the response body is already instrumented" do
281
- let(:body) { Appsignal::Rack::BodyWrapper.wrap(["hello!"], transaction) }
282
- let(:app) { DummyApp.new { [200, {}, body] } }
283
-
284
- it "doesn't wrap the body again" do
285
- env[Appsignal::Rack::APPSIGNAL_RESPONSE_INSTRUMENTED] = true
286
- _status, _headers, body = make_request
287
- expect(body).to eq(body)
288
-
289
- body.to_ary
290
- response_events =
291
- last_transaction.to_h["events"].count do |event|
292
- event["name"] == "process_response_body.rack"
293
- end
294
- expect(response_events).to eq(1)
295
- end
296
- end
297
-
298
- context "with error" do
299
- let(:app) { lambda { |_env| raise ExampleException, "error message" } }
300
-
301
- it "doesn't record the error on the transaction" do
302
- make_request_with_error(ExampleException, "error message")
303
-
304
- expect(last_transaction).to_not have_error
305
- end
306
- end
307
-
308
- it "doesn't complete the existing transaction" do
309
- make_request
310
-
311
- expect(env[Appsignal::Rack::APPSIGNAL_TRANSACTION]).to_not be_completed
312
- end
313
-
314
- context "with custom set action name" do
315
- it "does not overwrite the action name" do
316
- env[Appsignal::Rack::APPSIGNAL_TRANSACTION].set_action("My custom action")
317
- env["appsignal.action"] = "POST /my-action"
318
- make_request
319
-
320
- expect(last_transaction).to have_action("My custom action")
321
- end
322
- end
323
-
324
- context "with :report_errors set to false" do
325
- let(:app) { lambda { |_env| raise ExampleException, "error message" } }
326
- let(:options) { { :report_errors => false } }
327
-
328
- it "does not record the error on the transaction" do
329
- make_request_with_error(ExampleException, "error message")
330
-
331
- expect(last_transaction).to_not have_error
332
- end
333
- end
334
-
335
- context "with :report_errors set to true" do
336
- let(:app) { lambda { |_env| raise ExampleException, "error message" } }
337
- let(:options) { { :report_errors => true } }
338
-
339
- it "records the error on the transaction" do
340
- make_request_with_error(ExampleException, "error message")
341
-
342
- expect(last_transaction).to have_error("ExampleException", "error message")
343
- end
344
- end
345
-
346
- context "with :report_errors set to a lambda that returns false" do
347
- let(:app) { lambda { |_env| raise ExampleException, "error message" } }
348
- let(:options) { { :report_errors => lambda { |_env| false } } }
349
-
350
- it "does not record the exception on the transaction" do
351
- make_request_with_error(ExampleException, "error message")
352
-
353
- expect(last_transaction).to_not have_error
354
- end
355
- end
356
-
357
- context "with :report_errors set to a lambda that returns true" do
358
- let(:app) { lambda { |_env| raise ExampleException, "error message" } }
359
- let(:options) { { :report_errors => lambda { |_env| true } } }
360
-
361
- it "records the error on the transaction" do
362
- make_request_with_error(ExampleException, "error message")
363
-
364
- expect(last_transaction).to have_error("ExampleException", "error message")
365
- end
366
- end
367
- end
368
- end
369
- end
370
- end
@@ -1,319 +0,0 @@
1
- describe Appsignal::Rack::BodyWrapper do
2
- let(:transaction) { http_request_transaction }
3
- before do
4
- start_agent
5
- set_current_transaction(transaction)
6
- end
7
-
8
- it "forwards method calls to the body if the method doesn't exist" do
9
- fake_body = double(
10
- :body => ["some body"],
11
- :some_method => :some_value
12
- )
13
-
14
- wrapped = described_class.wrap(fake_body, transaction)
15
- expect(wrapped).to respond_to(:body)
16
- expect(wrapped.body).to eq(["some body"])
17
-
18
- expect(wrapped).to respond_to(:some_method)
19
- expect(wrapped.some_method).to eq(:some_value)
20
- end
21
-
22
- it "doesn't respond to methods the Rack::BodyProxy doesn't respond to" do
23
- body = Rack::BodyProxy.new(["body"])
24
- wrapped = described_class.wrap(body, transaction)
25
-
26
- expect(wrapped).to_not respond_to(:to_str)
27
- expect { wrapped.to_str }.to raise_error(NoMethodError)
28
-
29
- expect(wrapped).to_not respond_to(:body)
30
- expect { wrapped.body }.to raise_error(NoMethodError)
31
- end
32
-
33
- describe "with a body only supporting each()" do
34
- it "wraps with appropriate class" do
35
- fake_body = double(:each => nil)
36
-
37
- wrapped = described_class.wrap(fake_body, transaction)
38
- expect(wrapped).to respond_to(:each)
39
- expect(wrapped).to_not respond_to(:to_ary)
40
- expect(wrapped).to_not respond_to(:call)
41
- expect(wrapped).to respond_to(:close)
42
- end
43
-
44
- it "reads out the body in full using each" do
45
- fake_body = double
46
- expect(fake_body).to receive(:each).once.and_yield("a").and_yield("b").and_yield("c")
47
-
48
- wrapped = described_class.wrap(fake_body, transaction)
49
- expect { |b| wrapped.each(&b) }.to yield_successive_args("a", "b", "c")
50
-
51
- expect(transaction).to include_event(
52
- "name" => "process_response_body.rack",
53
- "title" => "Process Rack response body (#each)"
54
- )
55
- end
56
-
57
- it "returns an Enumerator if each() gets called without a block" do
58
- fake_body = double
59
- expect(fake_body).to receive(:each).once.and_yield("a").and_yield("b").and_yield("c")
60
-
61
- wrapped = described_class.wrap(fake_body, transaction)
62
- enum = wrapped.each
63
- expect(enum).to be_kind_of(Enumerator)
64
- expect { |b| enum.each(&b) }.to yield_successive_args("a", "b", "c")
65
-
66
- expect(transaction).to_not include_event("name" => "process_response_body.rack")
67
- end
68
-
69
- it "sets the exception raised inside each() on the transaction" do
70
- fake_body = double
71
- expect(fake_body).to receive(:each).once.and_raise(ExampleException, "error message")
72
-
73
- wrapped = described_class.wrap(fake_body, transaction)
74
- expect do
75
- expect { |b| wrapped.each(&b) }.to yield_control
76
- end.to raise_error(ExampleException, "error message")
77
-
78
- expect(transaction).to have_error("ExampleException", "error message")
79
- end
80
-
81
- it "doesn't report EPIPE error" do
82
- fake_body = double
83
- expect(fake_body).to receive(:each).once.and_raise(Errno::EPIPE)
84
-
85
- wrapped = described_class.wrap(fake_body, transaction)
86
- expect do
87
- expect { |b| wrapped.each(&b) }.to yield_control
88
- end.to raise_error(Errno::EPIPE)
89
-
90
- expect(transaction).to_not have_error
91
- end
92
-
93
- it "closes the body and tracks an instrumentation event when it gets closed" do
94
- fake_body = double(:close => nil)
95
- expect(fake_body).to receive(:each).once.and_yield("a").and_yield("b").and_yield("c")
96
-
97
- wrapped = described_class.wrap(fake_body, transaction)
98
- expect { |b| wrapped.each(&b) }.to yield_successive_args("a", "b", "c")
99
- wrapped.close
100
-
101
- expect(transaction).to include_event("name" => "close_response_body.rack")
102
- end
103
- end
104
-
105
- describe "with a body supporting both each() and call" do
106
- it "wraps with the wrapper that exposes each" do
107
- fake_body = double(
108
- :each => true,
109
- :call => "original call"
110
- )
111
-
112
- wrapped = described_class.wrap(fake_body, transaction)
113
- expect(wrapped).to respond_to(:each)
114
- expect(wrapped).to_not respond_to(:to_ary)
115
- expect(wrapped).to respond_to(:call)
116
- expect(wrapped.call).to eq("original call")
117
- expect(wrapped).to_not respond_to(:to_path)
118
- expect(wrapped).to respond_to(:close)
119
- end
120
- end
121
-
122
- describe "with a body supporting both to_ary and each" do
123
- let(:fake_body) { double(:each => nil, :to_ary => []) }
124
-
125
- it "wraps with appropriate class" do
126
- wrapped = described_class.wrap(fake_body, transaction)
127
- expect(wrapped).to respond_to(:each)
128
- expect(wrapped).to respond_to(:to_ary)
129
- expect(wrapped).to_not respond_to(:call)
130
- expect(wrapped).to_not respond_to(:to_path)
131
- expect(wrapped).to respond_to(:close)
132
- end
133
-
134
- it "reads out the body in full using each" do
135
- expect(fake_body).to receive(:each).once.and_yield("a").and_yield("b").and_yield("c")
136
-
137
- wrapped = described_class.wrap(fake_body, transaction)
138
- expect { |b| wrapped.each(&b) }.to yield_successive_args("a", "b", "c")
139
-
140
- expect(transaction).to include_event(
141
- "name" => "process_response_body.rack",
142
- "title" => "Process Rack response body (#each)"
143
- )
144
- end
145
-
146
- it "sets the exception raised inside each() into the Appsignal transaction" do
147
- expect(fake_body).to receive(:each).once.and_raise(ExampleException, "error message")
148
-
149
- wrapped = described_class.wrap(fake_body, transaction)
150
- expect do
151
- expect { |b| wrapped.each(&b) }.to yield_control
152
- end.to raise_error(ExampleException, "error message")
153
-
154
- expect(transaction).to have_error("ExampleException", "error message")
155
- end
156
-
157
- it "doesn't report EPIPE error" do
158
- expect(fake_body).to receive(:each).once.and_raise(Errno::EPIPE)
159
-
160
- wrapped = described_class.wrap(fake_body, transaction)
161
- expect do
162
- expect { |b| wrapped.each(&b) }.to yield_control
163
- end.to raise_error(Errno::EPIPE)
164
-
165
- expect(transaction).to_not have_error
166
- end
167
-
168
- it "reads out the body in full using to_ary" do
169
- expect(fake_body).to receive(:to_ary).and_return(["one", "two", "three"])
170
-
171
- wrapped = described_class.wrap(fake_body, transaction)
172
- expect(wrapped.to_ary).to eq(["one", "two", "three"])
173
-
174
- expect(transaction).to include_event(
175
- "name" => "process_response_body.rack",
176
- "title" => "Process Rack response body (#to_ary)"
177
- )
178
- end
179
-
180
- it "sends the exception raised inside to_ary() into the Appsignal and closes transaction" do
181
- fake_body = double
182
- allow(fake_body).to receive(:each)
183
- expect(fake_body).to receive(:to_ary).once.and_raise(ExampleException, "error message")
184
- expect(fake_body).to_not receive(:close) # Per spec we expect the body has closed itself
185
-
186
- wrapped = described_class.wrap(fake_body, transaction)
187
- expect do
188
- wrapped.to_ary
189
- end.to raise_error(ExampleException, "error message")
190
-
191
- expect(transaction).to have_error("ExampleException", "error message")
192
- end
193
- end
194
-
195
- describe "with a body supporting both to_path and each" do
196
- let(:fake_body) { double(:each => nil, :to_path => nil) }
197
-
198
- it "wraps with appropriate class" do
199
- wrapped = described_class.wrap(fake_body, transaction)
200
- expect(wrapped).to respond_to(:each)
201
- expect(wrapped).to_not respond_to(:to_ary)
202
- expect(wrapped).to_not respond_to(:call)
203
- expect(wrapped).to respond_to(:to_path)
204
- expect(wrapped).to respond_to(:close)
205
- end
206
-
207
- it "reads out the body in full using each()" do
208
- expect(fake_body).to receive(:each).once.and_yield("a").and_yield("b").and_yield("c")
209
-
210
- wrapped = described_class.wrap(fake_body, transaction)
211
- expect { |b| wrapped.each(&b) }.to yield_successive_args("a", "b", "c")
212
-
213
- expect(transaction).to include_event(
214
- "name" => "process_response_body.rack",
215
- "title" => "Process Rack response body (#each)"
216
- )
217
- end
218
-
219
- it "sets the exception raised inside each() into the Appsignal transaction" do
220
- expect(fake_body).to receive(:each).once.and_raise(ExampleException, "error message")
221
-
222
- wrapped = described_class.wrap(fake_body, transaction)
223
- expect do
224
- expect { |b| wrapped.each(&b) }.to yield_control
225
- end.to raise_error(ExampleException, "error message")
226
-
227
- expect(transaction).to have_error("ExampleException", "error message")
228
- end
229
-
230
- it "sets the exception raised inside to_path() into the Appsignal transaction" do
231
- allow(fake_body).to receive(:to_path).once.and_raise(ExampleException, "error message")
232
-
233
- wrapped = described_class.wrap(fake_body, transaction)
234
- expect do
235
- wrapped.to_path
236
- end.to raise_error(ExampleException, "error message")
237
-
238
- expect(transaction).to have_error("ExampleException", "error message")
239
- end
240
-
241
- it "doesn't report EPIPE error" do
242
- expect(fake_body).to receive(:to_path).once.and_raise(Errno::EPIPE)
243
-
244
- wrapped = described_class.wrap(fake_body, transaction)
245
- expect do
246
- wrapped.to_path
247
- end.to raise_error(Errno::EPIPE)
248
-
249
- expect(transaction).to_not have_error
250
- end
251
-
252
- it "exposes to_path to the sender" do
253
- allow(fake_body).to receive(:to_path).and_return("/tmp/file.bin")
254
-
255
- wrapped = described_class.wrap(fake_body, transaction)
256
- expect(wrapped.to_path).to eq("/tmp/file.bin")
257
-
258
- expect(transaction).to include_event(
259
- "name" => "process_response_body.rack",
260
- "title" => "Process Rack response body (#to_path)"
261
- )
262
- end
263
- end
264
-
265
- describe "with a body only supporting call()" do
266
- let(:fake_body) { double(:call => nil) }
267
-
268
- it "wraps with appropriate class" do
269
- wrapped = described_class.wrap(fake_body, transaction)
270
- expect(wrapped).to_not respond_to(:each)
271
- expect(wrapped).to_not respond_to(:to_ary)
272
- expect(wrapped).to respond_to(:call)
273
- expect(wrapped).to_not respond_to(:to_path)
274
- expect(wrapped).to respond_to(:close)
275
- end
276
-
277
- it "passes the stream into the call() of the body" do
278
- fake_rack_stream = double("stream")
279
- expect(fake_body).to receive(:call).with(fake_rack_stream)
280
-
281
- wrapped = described_class.wrap(fake_body, transaction)
282
- wrapped.call(fake_rack_stream)
283
-
284
- expect(transaction).to include_event(
285
- "name" => "process_response_body.rack",
286
- "title" => "Process Rack response body (#call)"
287
- )
288
- end
289
-
290
- it "sets the exception raised inside call() into the Appsignal transaction" do
291
- fake_rack_stream = double
292
- allow(fake_body).to receive(:call)
293
- .with(fake_rack_stream)
294
- .and_raise(ExampleException, "error message")
295
-
296
- wrapped = described_class.wrap(fake_body, transaction)
297
-
298
- expect do
299
- wrapped.call(fake_rack_stream)
300
- end.to raise_error(ExampleException, "error message")
301
-
302
- expect(transaction).to have_error("ExampleException", "error message")
303
- end
304
-
305
- it "doesn't report EPIPE error" do
306
- fake_rack_stream = double
307
- expect(fake_body).to receive(:call)
308
- .with(fake_rack_stream)
309
- .and_raise(Errno::EPIPE)
310
-
311
- wrapped = described_class.wrap(fake_body, transaction)
312
- expect do
313
- wrapped.call(fake_rack_stream)
314
- end.to raise_error(Errno::EPIPE)
315
-
316
- expect(transaction).to_not have_error
317
- end
318
- end
319
- end