appsignal 4.0.5 → 4.0.7

Sign up to get free protection for your applications and to get access to all the features.
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