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,154 +0,0 @@
1
- require "appsignal/integrations/mongo_ruby_driver"
2
- describe Appsignal::Hooks::MongoMonitorSubscriber do
3
- let(:subscriber) { Appsignal::Hooks::MongoMonitorSubscriber.new }
4
-
5
- context "with transaction" do
6
- let(:transaction) { http_request_transaction }
7
- before do
8
- start_agent
9
- set_current_transaction(transaction)
10
- end
11
-
12
- describe "#started" do
13
- let(:event) do
14
- double(
15
- :request_id => 1,
16
- :command_name => "find",
17
- :command => { "foo" => "bar" }
18
- )
19
- end
20
-
21
- it "should sanitize command" do
22
- # TODO: additional curly brackets required for issue
23
- # https://github.com/rspec/rspec-mocks/issues/1460
24
- expect(Appsignal::EventFormatter::MongoRubyDriver::QueryFormatter)
25
- .to receive(:format).with("find", { "foo" => "bar" })
26
- subscriber.started(event)
27
- end
28
-
29
- it "should store command on the transaction" do
30
- subscriber.started(event)
31
-
32
- expect(transaction.store("mongo_driver")).to eq(1 => { "foo" => "?" })
33
- end
34
-
35
- it "should start an event in the extension" do
36
- expect(transaction).to receive(:start_event)
37
-
38
- subscriber.started(event)
39
- end
40
- end
41
-
42
- describe "#succeeded" do
43
- let(:event) { double }
44
-
45
- it "should finish the event" do
46
- expect(subscriber).to receive(:finish).with("SUCCEEDED", event)
47
-
48
- subscriber.succeeded(event)
49
- end
50
- end
51
-
52
- describe "#failed" do
53
- let(:event) { double }
54
-
55
- it "should finish the event" do
56
- expect(subscriber).to receive(:finish).with("FAILED", event)
57
-
58
- subscriber.failed(event)
59
- end
60
- end
61
-
62
- describe "#finish" do
63
- let(:command) { { "foo" => "?" } }
64
- let(:event) do
65
- double(
66
- :request_id => 2,
67
- :command_name => :find,
68
- :database_name => "test",
69
- :duration => 0.9919
70
- )
71
- end
72
-
73
- before do
74
- store = transaction.store("mongo_driver")
75
- store[2] = command
76
- end
77
-
78
- it "should emit a measurement" do
79
- expect(Appsignal).to receive(:add_distribution_value).with(
80
- "mongodb_query_duration",
81
- 0.9919,
82
- :database => "test"
83
- ).and_call_original
84
-
85
- subscriber.finish("SUCCEEDED", event)
86
- end
87
-
88
- it "should get the query from the store" do
89
- expect(transaction).to receive(:store).with("mongo_driver").and_return(command)
90
-
91
- subscriber.finish("SUCCEEDED", event)
92
- end
93
-
94
- it "should finish the transaction in the extension" do
95
- expect(transaction).to receive(:finish_event).with(
96
- "query.mongodb",
97
- "find | test | SUCCEEDED",
98
- Appsignal::Utils::Data.generate("foo" => "?"),
99
- 0
100
- )
101
-
102
- subscriber.finish("SUCCEEDED", event)
103
- end
104
- end
105
- end
106
-
107
- context "without transaction" do
108
- before do
109
- allow(Appsignal::Transaction).to receive(:current)
110
- .and_return(Appsignal::Transaction::NilTransaction.new)
111
- end
112
-
113
- it "should not attempt to start an event" do
114
- expect(Appsignal::Extension).to_not receive(:start_event)
115
-
116
- subscriber.started(double)
117
- end
118
-
119
- it "should not attempt to finish an event" do
120
- expect(Appsignal::Extension).to_not receive(:finish_event)
121
-
122
- subscriber.finish("SUCCEEDED", double)
123
- end
124
-
125
- it "should not attempt to send duration metrics" do
126
- expect(Appsignal).to_not receive(:add_distribution_value)
127
-
128
- subscriber.finish("SUCCEEDED", double)
129
- end
130
- end
131
-
132
- context "when appsignal is paused" do
133
- let(:transaction) { double(:paused? => true, :nil_transaction? => false) }
134
- before { allow(Appsignal::Transaction).to receive(:current).and_return(transaction) }
135
-
136
- it "should not attempt to start an event" do
137
- expect(Appsignal::Extension).to_not receive(:start_event)
138
-
139
- subscriber.started(double)
140
- end
141
-
142
- it "should not attempt to finish an event" do
143
- expect(Appsignal::Extension).to_not receive(:finish_event)
144
-
145
- subscriber.finish("SUCCEEDED", double)
146
- end
147
-
148
- it "should not attempt to send duration metrics" do
149
- expect(Appsignal).to_not receive(:add_distribution_value)
150
-
151
- subscriber.finish("SUCCEEDED", double)
152
- end
153
- end
154
- end
@@ -1,33 +0,0 @@
1
- require "appsignal/integrations/net_http"
2
-
3
- describe Appsignal::Integrations::NetHttpIntegration do
4
- let(:transaction) { http_request_transaction }
5
- before { 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
@@ -1,347 +0,0 @@
1
- require "appsignal/integrations/object"
2
-
3
- describe Object do
4
- around { |example| keep_transactions { example.run } }
5
-
6
- describe "#instrument_method" do
7
- context "with instance method" do
8
- let(:klass) do
9
- Class.new do
10
- def foo(param1, options = {}, keyword_param: 1)
11
- [param1, options, keyword_param]
12
- end
13
- appsignal_instrument_method :foo
14
- end
15
- end
16
- let(:instance) { klass.new }
17
-
18
- def call_with_arguments
19
- instance.foo(
20
- "abc",
21
- { :foo => "bar" },
22
- :keyword_param => 2
23
- )
24
- end
25
-
26
- context "when active" do
27
- let(:transaction) { http_request_transaction }
28
- before do
29
- start_agent
30
- set_current_transaction(transaction)
31
- end
32
-
33
- context "with different kind of arguments" do
34
- let(:klass) do
35
- Class.new do
36
- def positional_arguments(param1, param2)
37
- [param1, param2]
38
- end
39
- appsignal_instrument_method :positional_arguments
40
-
41
- def positional_arguments_splat(*params)
42
- params
43
- end
44
- appsignal_instrument_method :positional_arguments_splat
45
-
46
- # rubocop:disable Naming/MethodParameterName
47
- def keyword_arguments(a: nil, b: nil)
48
- [a, b]
49
- end
50
- # rubocop:enable Naming/MethodParameterName
51
- appsignal_instrument_method :keyword_arguments
52
-
53
- def keyword_arguments_splat(**kwargs)
54
- kwargs
55
- end
56
- appsignal_instrument_method :keyword_arguments_splat
57
-
58
- def splat(*args, **kwargs)
59
- [args, kwargs]
60
- end
61
- appsignal_instrument_method :splat
62
- end
63
- end
64
-
65
- it "instruments the method and calls it" do
66
- expect(instance.positional_arguments("abc", "def")).to eq(["abc", "def"])
67
- expect(instance.positional_arguments_splat("abc", "def")).to eq(["abc", "def"])
68
- expect(instance.keyword_arguments(:a => "a", :b => "b")).to eq(["a", "b"])
69
- expect(instance.keyword_arguments_splat(:a => "a", :b => "b"))
70
- .to eq(:a => "a", :b => "b")
71
-
72
- expect(instance.splat).to eq([[], {}])
73
- expect(instance.splat(:a => "a", :b => "b")).to eq([[], { :a => "a", :b => "b" }])
74
- expect(instance.splat("abc", "def")).to eq([["abc", "def"], {}])
75
- expect(instance.splat("abc", "def", :a => "a", :b => "b"))
76
- .to eq([["abc", "def"], { :a => "a", :b => "b" }])
77
- end
78
- end
79
-
80
- context "with anonymous class" do
81
- it "instruments the method and calls it" do
82
- expect(call_with_arguments).to eq(["abc", { :foo => "bar" }, 2])
83
-
84
- expect(transaction).to include_event("name" => "foo.AnonymousClass.other")
85
- end
86
- end
87
-
88
- context "with named class" do
89
- before do
90
- class NamedClass
91
- def foo
92
- 1
93
- end
94
- appsignal_instrument_method :foo
95
- end
96
- end
97
- after { Object.send(:remove_const, :NamedClass) }
98
- let(:klass) { NamedClass }
99
-
100
- it "instruments the method and calls it" do
101
- expect(instance.foo).to eq(1)
102
-
103
- expect(transaction).to include_event("name" => "foo.NamedClass.other")
104
- end
105
- end
106
-
107
- context "with nested named class" do
108
- before do
109
- module MyModule
110
- module NestedModule
111
- class NamedClass
112
- def bar
113
- 2
114
- end
115
- appsignal_instrument_method :bar
116
- end
117
- end
118
- end
119
- end
120
- after { Object.send(:remove_const, :MyModule) }
121
- let(:klass) { MyModule::NestedModule::NamedClass }
122
-
123
- it "instruments the method and calls it" do
124
- expect(instance.bar).to eq(2)
125
-
126
- expect(transaction).to include_event(
127
- "name" => "bar.NamedClass.NestedModule.MyModule.other"
128
- )
129
- end
130
- end
131
-
132
- context "with custom name" do
133
- let(:klass) do
134
- Class.new do
135
- def foo
136
- 1
137
- end
138
- appsignal_instrument_method :foo, :name => "my_method.group"
139
- end
140
- end
141
-
142
- it "instruments with custom name" do
143
- expect(instance.foo).to eq(1)
144
-
145
- expect(transaction).to include_event(
146
- "name" => "my_method.group"
147
- )
148
- end
149
- end
150
-
151
- context "with a method given a block" do
152
- let(:klass) do
153
- Class.new do
154
- def foo
155
- yield
156
- end
157
- appsignal_instrument_method :foo
158
- end
159
- end
160
-
161
- it "yields the block" do
162
- expect(instance.foo { 42 }).to eq(42)
163
- end
164
- end
165
- end
166
-
167
- context "when not active" do
168
- let(:transaction) { Appsignal::Transaction.current }
169
-
170
- it "does not instrument, but still calls the method" do
171
- expect(Appsignal.active?).to be_falsy
172
- expect(call_with_arguments).to eq(["abc", { :foo => "bar" }, 2])
173
- end
174
- end
175
- end
176
-
177
- context "with class method" do
178
- let(:klass) do
179
- Class.new do
180
- def self.bar(param1, options = {}, keyword_param: 1)
181
- [param1, options, keyword_param]
182
- end
183
- appsignal_instrument_class_method :bar
184
- end
185
- end
186
- def call_with_arguments
187
- klass.bar(
188
- "abc",
189
- { :foo => "bar" },
190
- :keyword_param => 2
191
- )
192
- end
193
-
194
- context "when active" do
195
- let(:transaction) { http_request_transaction }
196
- before do
197
- start_agent
198
- set_current_transaction(transaction)
199
- end
200
-
201
- context "with different kind of arguments" do
202
- let(:klass) do
203
- Class.new do
204
- def self.positional_arguments(param1, param2)
205
- [param1, param2]
206
- end
207
- appsignal_instrument_class_method :positional_arguments
208
-
209
- def self.positional_arguments_splat(*params)
210
- params
211
- end
212
- appsignal_instrument_class_method :positional_arguments_splat
213
-
214
- # rubocop:disable Naming/MethodParameterName
215
- def self.keyword_arguments(a: nil, b: nil)
216
- [a, b]
217
- end
218
- # rubocop:enable Naming/MethodParameterName
219
- appsignal_instrument_class_method :keyword_arguments
220
-
221
- def self.keyword_arguments_splat(**kwargs)
222
- kwargs
223
- end
224
- appsignal_instrument_class_method :keyword_arguments_splat
225
-
226
- def self.splat(*args, **kwargs)
227
- [args, kwargs]
228
- end
229
- appsignal_instrument_class_method :splat
230
- end
231
- end
232
-
233
- it "instruments the method and calls it" do
234
- expect(klass.positional_arguments("abc", "def")).to eq(["abc", "def"])
235
- expect(klass.positional_arguments_splat("abc", "def")).to eq(["abc", "def"])
236
- expect(klass.keyword_arguments(:a => "a", :b => "b")).to eq(["a", "b"])
237
- expect(klass.keyword_arguments_splat(:a => "a", :b => "b"))
238
- .to eq(:a => "a", :b => "b")
239
-
240
- expect(klass.splat).to eq([[], {}])
241
- expect(klass.splat(:a => "a", :b => "b")).to eq([[], { :a => "a", :b => "b" }])
242
- expect(klass.splat("abc", "def")).to eq([["abc", "def"], {}])
243
- expect(klass.splat("abc", "def", :a => "a", :b => "b"))
244
- .to eq([["abc", "def"], { :a => "a", :b => "b" }])
245
- end
246
- end
247
-
248
- context "with anonymous class" do
249
- it "instruments the method and calls it" do
250
- expect(Appsignal.active?).to be_truthy
251
- expect(call_with_arguments).to eq(["abc", { :foo => "bar" }, 2])
252
-
253
- transaction._sample
254
- expect(transaction).to include_event("name" => "bar.class_method.AnonymousClass.other")
255
- end
256
- end
257
-
258
- context "with named class" do
259
- before do
260
- class NamedClass
261
- def self.bar
262
- 2
263
- end
264
- appsignal_instrument_class_method :bar
265
- end
266
- end
267
- after { Object.send(:remove_const, :NamedClass) }
268
- let(:klass) { NamedClass }
269
-
270
- it "instruments the method and calls it" do
271
- expect(Appsignal.active?).to be_truthy
272
- expect(klass.bar).to eq(2)
273
-
274
- expect(transaction).to include_event("name" => "bar.class_method.NamedClass.other")
275
- end
276
-
277
- context "with nested named class" do
278
- before do
279
- module MyModule
280
- module NestedModule
281
- class NamedClass
282
- def self.bar
283
- 2
284
- end
285
- appsignal_instrument_class_method :bar
286
- end
287
- end
288
- end
289
- end
290
- after { Object.send(:remove_const, :MyModule) }
291
- let(:klass) { MyModule::NestedModule::NamedClass }
292
-
293
- it "instruments the method and calls it" do
294
- expect(Appsignal.active?).to be_truthy
295
- expect(klass.bar).to eq(2)
296
- expect(transaction).to include_event(
297
- "name" => "bar.class_method.NamedClass.NestedModule.MyModule.other"
298
- )
299
- end
300
- end
301
- end
302
-
303
- context "with custom name" do
304
- let(:klass) do
305
- Class.new do
306
- def self.bar
307
- 2
308
- end
309
- appsignal_instrument_class_method :bar, :name => "my_method.group"
310
- end
311
- end
312
-
313
- it "instruments with custom name" do
314
- expect(Appsignal.active?).to be_truthy
315
- expect(klass.bar).to eq(2)
316
-
317
- expect(transaction).to include_event("name" => "my_method.group")
318
- end
319
- end
320
-
321
- context "with a method given a block" do
322
- let(:klass) do
323
- Class.new do
324
- def self.bar
325
- yield
326
- end
327
- appsignal_instrument_class_method :bar
328
- end
329
- end
330
-
331
- it "yields the block" do
332
- expect(klass.bar { 42 }).to eq(42)
333
- end
334
- end
335
- end
336
-
337
- context "when not active" do
338
- let(:transaction) { Appsignal::Transaction.current }
339
-
340
- it "does not instrument, but still call the method" do
341
- expect(Appsignal.active?).to be_falsy
342
- expect(call_with_arguments).to eq(["abc", { :foo => "bar" }, 2])
343
- end
344
- end
345
- end
346
- end
347
- end
@@ -1,150 +0,0 @@
1
- require "appsignal/integrations/puma"
2
-
3
- describe Appsignal::Integrations::PumaServer do
4
- describe "#lowlevel_error" do
5
- before do
6
- stub_const("Puma", PumaMock)
7
- stub_const("Puma::Server", puma_server)
8
- start_agent
9
- end
10
- let(:queue_start_time) { fixed_time * 1_000 }
11
- let(:env) do
12
- Rack::MockRequest.env_for(
13
- "/some/path",
14
- "REQUEST_METHOD" => "GET",
15
- :params => { "page" => 2, "query" => "lorem" },
16
- "rack.session" => { "session" => "data", "user_id" => 123 },
17
- "HTTP_X_REQUEST_START" => "t=#{queue_start_time.to_i}" # in milliseconds
18
- )
19
- end
20
- let(:server) { Puma::Server.new }
21
- let(:error) { ExampleException.new("error message") }
22
- around { |example| keep_transactions { example.run } }
23
- before { Appsignal::Hooks::PumaHook.new.install }
24
-
25
- def lowlevel_error(error, env, status = nil)
26
- result =
27
- if status
28
- server.lowlevel_error(error, env, status)
29
- else
30
- server.lowlevel_error(error, env)
31
- end
32
- # Transaction is normally closed by the EventHandler's RACK_AFTER_REPLY hook
33
- last_transaction&.complete
34
- result
35
- end
36
-
37
- describe "error reporting" do
38
- let(:puma_server) { default_puma_server_mock }
39
-
40
- context "with active transaction" do
41
- before { create_transaction }
42
-
43
- it "reports the error to the transaction" do
44
- expect do
45
- lowlevel_error(error, env)
46
- end.to_not(change { created_transactions.count })
47
-
48
- expect(last_transaction).to have_error("ExampleException", "error message")
49
- expect(last_transaction).to include_tags("reported_by" => "puma_lowlevel_error")
50
- end
51
- end
52
-
53
- # This shouldn't happen if the EventHandler is set up correctly, but if
54
- # it's not it will create a new transaction.
55
- context "without active transaction" do
56
- it "creates a new transaction with the error" do
57
- expect do
58
- lowlevel_error(error, env)
59
- end.to change { created_transactions.count }.by(1)
60
-
61
- expect(last_transaction).to have_error("ExampleException", "error message")
62
- expect(last_transaction).to include_tags("reported_by" => "puma_lowlevel_error")
63
- end
64
- end
65
-
66
- it "doesn't report internal Puma errors" do
67
- expect do
68
- lowlevel_error(Puma::MiniSSL::SSLError.new("error message"), env)
69
- lowlevel_error(Puma::HttpParserError.new("error message"), env)
70
- lowlevel_error(Puma::HttpParserError501.new("error message"), env)
71
- end.to_not(change { created_transactions.count })
72
- end
73
-
74
- describe "request metadata" do
75
- it "sets request metadata" do
76
- lowlevel_error(error, env)
77
-
78
- expect(last_transaction).to include_metadata(
79
- "request_method" => "GET",
80
- "method" => "GET",
81
- "request_path" => "/some/path",
82
- "path" => "/some/path"
83
- )
84
- expect(last_transaction).to include_environment(
85
- "REQUEST_METHOD" => "GET",
86
- "PATH_INFO" => "/some/path"
87
- # and more, but we don't need to test Rack mock defaults
88
- )
89
- end
90
-
91
- it "sets request parameters" do
92
- lowlevel_error(error, env)
93
-
94
- expect(last_transaction).to include_params(
95
- "page" => "2",
96
- "query" => "lorem"
97
- )
98
- end
99
-
100
- it "sets session data" do
101
- lowlevel_error(error, env)
102
-
103
- expect(last_transaction).to include_session_data("session" => "data", "user_id" => 123)
104
- end
105
-
106
- it "sets the queue start" do
107
- lowlevel_error(error, env)
108
-
109
- expect(last_transaction).to have_queue_start(queue_start_time)
110
- end
111
- end
112
- end
113
-
114
- context "with Puma::Server#lowlevel_error accepting 3 arguments" do
115
- let(:puma_server) { default_puma_server_mock }
116
-
117
- it "calls the super class with 3 arguments" do
118
- result = lowlevel_error(error, env, 501)
119
- expect(result).to eq([501, {}, ""])
120
-
121
- expect(last_transaction).to include_tags("response_status" => 501)
122
- end
123
- end
124
-
125
- context "with Puma::Server#lowlevel_error accepting 2 arguments" do
126
- let(:puma_server) do
127
- Class.new do
128
- def lowlevel_error(_error, _env)
129
- [500, {}, ""]
130
- end
131
- end
132
- end
133
-
134
- it "calls the super class with 3 arguments" do
135
- result = lowlevel_error(error, env)
136
- expect(result).to eq([500, {}, ""])
137
-
138
- expect(last_transaction).to include_tags("response_status" => 500)
139
- end
140
- end
141
- end
142
-
143
- def default_puma_server_mock
144
- Class.new do
145
- def lowlevel_error(_error, _env, status = 500)
146
- [status, {}, ""]
147
- end
148
- end
149
- end
150
- end