appsignal 2.5.0.alpha.1-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +33 -0
  3. data/.rspec +4 -0
  4. data/.rubocop.yml +66 -0
  5. data/.rubocop_todo.yml +124 -0
  6. data/.travis.yml +72 -0
  7. data/.yardopts +8 -0
  8. data/CHANGELOG.md +639 -0
  9. data/Gemfile +3 -0
  10. data/LICENSE +20 -0
  11. data/README.md +264 -0
  12. data/Rakefile +214 -0
  13. data/appsignal.gemspec +42 -0
  14. data/benchmark.rake +77 -0
  15. data/bin/appsignal +13 -0
  16. data/ext/Rakefile +27 -0
  17. data/ext/agent.yml +64 -0
  18. data/ext/appsignal_extension.c +692 -0
  19. data/ext/base.rb +79 -0
  20. data/ext/extconf.rb +35 -0
  21. data/gemfiles/capistrano2.gemfile +7 -0
  22. data/gemfiles/capistrano3.gemfile +7 -0
  23. data/gemfiles/grape.gemfile +7 -0
  24. data/gemfiles/no_dependencies.gemfile +5 -0
  25. data/gemfiles/padrino.gemfile +7 -0
  26. data/gemfiles/que.gemfile +5 -0
  27. data/gemfiles/rails-3.2.gemfile +6 -0
  28. data/gemfiles/rails-4.0.gemfile +6 -0
  29. data/gemfiles/rails-4.1.gemfile +6 -0
  30. data/gemfiles/rails-4.2.gemfile +10 -0
  31. data/gemfiles/rails-5.0.gemfile +5 -0
  32. data/gemfiles/rails-5.1.gemfile +5 -0
  33. data/gemfiles/resque.gemfile +12 -0
  34. data/gemfiles/sequel-435.gemfile +11 -0
  35. data/gemfiles/sequel.gemfile +11 -0
  36. data/gemfiles/sinatra.gemfile +6 -0
  37. data/gemfiles/webmachine.gemfile +5 -0
  38. data/lib/appsignal.rb +804 -0
  39. data/lib/appsignal/auth_check.rb +65 -0
  40. data/lib/appsignal/capistrano.rb +10 -0
  41. data/lib/appsignal/cli.rb +108 -0
  42. data/lib/appsignal/cli/demo.rb +63 -0
  43. data/lib/appsignal/cli/diagnose.rb +500 -0
  44. data/lib/appsignal/cli/helpers.rb +72 -0
  45. data/lib/appsignal/cli/install.rb +277 -0
  46. data/lib/appsignal/cli/notify_of_deploy.rb +113 -0
  47. data/lib/appsignal/config.rb +287 -0
  48. data/lib/appsignal/demo.rb +107 -0
  49. data/lib/appsignal/event_formatter.rb +74 -0
  50. data/lib/appsignal/event_formatter/action_view/render_formatter.rb +24 -0
  51. data/lib/appsignal/event_formatter/active_record/instantiation_formatter.rb +14 -0
  52. data/lib/appsignal/event_formatter/active_record/sql_formatter.rb +14 -0
  53. data/lib/appsignal/event_formatter/elastic_search/search_formatter.rb +32 -0
  54. data/lib/appsignal/event_formatter/faraday/request_formatter.rb +19 -0
  55. data/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter.rb +89 -0
  56. data/lib/appsignal/event_formatter/moped/query_formatter.rb +80 -0
  57. data/lib/appsignal/extension.rb +63 -0
  58. data/lib/appsignal/extension/jruby.rb +460 -0
  59. data/lib/appsignal/garbage_collection_profiler.rb +48 -0
  60. data/lib/appsignal/hooks.rb +105 -0
  61. data/lib/appsignal/hooks/action_cable.rb +113 -0
  62. data/lib/appsignal/hooks/active_support_notifications.rb +52 -0
  63. data/lib/appsignal/hooks/celluloid.rb +30 -0
  64. data/lib/appsignal/hooks/data_mapper.rb +18 -0
  65. data/lib/appsignal/hooks/delayed_job.rb +19 -0
  66. data/lib/appsignal/hooks/mongo_ruby_driver.rb +21 -0
  67. data/lib/appsignal/hooks/net_http.rb +29 -0
  68. data/lib/appsignal/hooks/passenger.rb +22 -0
  69. data/lib/appsignal/hooks/puma.rb +35 -0
  70. data/lib/appsignal/hooks/que.rb +21 -0
  71. data/lib/appsignal/hooks/rake.rb +39 -0
  72. data/lib/appsignal/hooks/redis.rb +30 -0
  73. data/lib/appsignal/hooks/sequel.rb +60 -0
  74. data/lib/appsignal/hooks/shoryuken.rb +43 -0
  75. data/lib/appsignal/hooks/sidekiq.rb +144 -0
  76. data/lib/appsignal/hooks/unicorn.rb +40 -0
  77. data/lib/appsignal/hooks/webmachine.rb +23 -0
  78. data/lib/appsignal/integrations/capistrano/appsignal.cap +39 -0
  79. data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +52 -0
  80. data/lib/appsignal/integrations/data_mapper.rb +33 -0
  81. data/lib/appsignal/integrations/delayed_job_plugin.rb +54 -0
  82. data/lib/appsignal/integrations/grape.rb +53 -0
  83. data/lib/appsignal/integrations/mongo_ruby_driver.rb +55 -0
  84. data/lib/appsignal/integrations/object.rb +35 -0
  85. data/lib/appsignal/integrations/padrino.rb +84 -0
  86. data/lib/appsignal/integrations/que.rb +43 -0
  87. data/lib/appsignal/integrations/railtie.rb +41 -0
  88. data/lib/appsignal/integrations/rake.rb +2 -0
  89. data/lib/appsignal/integrations/resque.rb +20 -0
  90. data/lib/appsignal/integrations/resque_active_job.rb +30 -0
  91. data/lib/appsignal/integrations/sinatra.rb +17 -0
  92. data/lib/appsignal/integrations/webmachine.rb +38 -0
  93. data/lib/appsignal/js_exception_transaction.rb +54 -0
  94. data/lib/appsignal/marker.rb +63 -0
  95. data/lib/appsignal/minutely.rb +42 -0
  96. data/lib/appsignal/rack/generic_instrumentation.rb +49 -0
  97. data/lib/appsignal/rack/js_exception_catcher.rb +70 -0
  98. data/lib/appsignal/rack/rails_instrumentation.rb +51 -0
  99. data/lib/appsignal/rack/sinatra_instrumentation.rb +99 -0
  100. data/lib/appsignal/rack/streaming_listener.rb +73 -0
  101. data/lib/appsignal/system.rb +81 -0
  102. data/lib/appsignal/transaction.rb +498 -0
  103. data/lib/appsignal/transmitter.rb +107 -0
  104. data/lib/appsignal/utils.rb +127 -0
  105. data/lib/appsignal/utils/params_sanitizer.rb +59 -0
  106. data/lib/appsignal/utils/query_params_sanitizer.rb +55 -0
  107. data/lib/appsignal/version.rb +3 -0
  108. data/lib/sequel/extensions/appsignal_integration.rb +3 -0
  109. data/resources/appsignal.yml.erb +39 -0
  110. data/resources/cacert.pem +3866 -0
  111. data/spec/.rubocop.yml +7 -0
  112. data/spec/lib/appsignal/auth_check_spec.rb +80 -0
  113. data/spec/lib/appsignal/capistrano2_spec.rb +224 -0
  114. data/spec/lib/appsignal/capistrano3_spec.rb +237 -0
  115. data/spec/lib/appsignal/cli/demo_spec.rb +67 -0
  116. data/spec/lib/appsignal/cli/diagnose_spec.rb +988 -0
  117. data/spec/lib/appsignal/cli/helpers_spec.rb +171 -0
  118. data/spec/lib/appsignal/cli/install_spec.rb +632 -0
  119. data/spec/lib/appsignal/cli/notify_of_deploy_spec.rb +168 -0
  120. data/spec/lib/appsignal/cli_spec.rb +56 -0
  121. data/spec/lib/appsignal/config_spec.rb +637 -0
  122. data/spec/lib/appsignal/demo_spec.rb +87 -0
  123. data/spec/lib/appsignal/event_formatter/action_view/render_formatter_spec.rb +44 -0
  124. data/spec/lib/appsignal/event_formatter/active_record/instantiation_formatter_spec.rb +21 -0
  125. data/spec/lib/appsignal/event_formatter/active_record/sql_formatter_spec.rb +21 -0
  126. data/spec/lib/appsignal/event_formatter/elastic_search/search_formatter_spec.rb +52 -0
  127. data/spec/lib/appsignal/event_formatter/faraday/request_formatter_spec.rb +21 -0
  128. data/spec/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter_spec.rb +113 -0
  129. data/spec/lib/appsignal/event_formatter/moped/query_formatter_spec.rb +112 -0
  130. data/spec/lib/appsignal/event_formatter_spec.rb +100 -0
  131. data/spec/lib/appsignal/extension/jruby_spec.rb +43 -0
  132. data/spec/lib/appsignal/extension_spec.rb +137 -0
  133. data/spec/lib/appsignal/garbage_collection_profiler_spec.rb +66 -0
  134. data/spec/lib/appsignal/hooks/action_cable_spec.rb +370 -0
  135. data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +92 -0
  136. data/spec/lib/appsignal/hooks/celluloid_spec.rb +35 -0
  137. data/spec/lib/appsignal/hooks/data_mapper_spec.rb +39 -0
  138. data/spec/lib/appsignal/hooks/delayed_job_spec.rb +358 -0
  139. data/spec/lib/appsignal/hooks/mongo_ruby_driver_spec.rb +44 -0
  140. data/spec/lib/appsignal/hooks/net_http_spec.rb +53 -0
  141. data/spec/lib/appsignal/hooks/passenger_spec.rb +30 -0
  142. data/spec/lib/appsignal/hooks/puma_spec.rb +80 -0
  143. data/spec/lib/appsignal/hooks/que_spec.rb +19 -0
  144. data/spec/lib/appsignal/hooks/rake_spec.rb +73 -0
  145. data/spec/lib/appsignal/hooks/redis_spec.rb +55 -0
  146. data/spec/lib/appsignal/hooks/sequel_spec.rb +46 -0
  147. data/spec/lib/appsignal/hooks/shoryuken_spec.rb +192 -0
  148. data/spec/lib/appsignal/hooks/sidekiq_spec.rb +419 -0
  149. data/spec/lib/appsignal/hooks/unicorn_spec.rb +52 -0
  150. data/spec/lib/appsignal/hooks/webmachine_spec.rb +35 -0
  151. data/spec/lib/appsignal/hooks_spec.rb +195 -0
  152. data/spec/lib/appsignal/integrations/data_mapper_spec.rb +65 -0
  153. data/spec/lib/appsignal/integrations/grape_spec.rb +225 -0
  154. data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +127 -0
  155. data/spec/lib/appsignal/integrations/object_spec.rb +249 -0
  156. data/spec/lib/appsignal/integrations/padrino_spec.rb +323 -0
  157. data/spec/lib/appsignal/integrations/que_spec.rb +174 -0
  158. data/spec/lib/appsignal/integrations/railtie_spec.rb +129 -0
  159. data/spec/lib/appsignal/integrations/resque_active_job_spec.rb +83 -0
  160. data/spec/lib/appsignal/integrations/resque_spec.rb +92 -0
  161. data/spec/lib/appsignal/integrations/sinatra_spec.rb +73 -0
  162. data/spec/lib/appsignal/integrations/webmachine_spec.rb +69 -0
  163. data/spec/lib/appsignal/js_exception_transaction_spec.rb +128 -0
  164. data/spec/lib/appsignal/marker_spec.rb +51 -0
  165. data/spec/lib/appsignal/minutely_spec.rb +50 -0
  166. data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +90 -0
  167. data/spec/lib/appsignal/rack/js_exception_catcher_spec.rb +147 -0
  168. data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +117 -0
  169. data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +213 -0
  170. data/spec/lib/appsignal/rack/streaming_listener_spec.rb +161 -0
  171. data/spec/lib/appsignal/system_spec.rb +131 -0
  172. data/spec/lib/appsignal/transaction_spec.rb +1146 -0
  173. data/spec/lib/appsignal/transmitter_spec.rb +152 -0
  174. data/spec/lib/appsignal/utils/params_sanitizer_spec.rb +136 -0
  175. data/spec/lib/appsignal/utils/query_params_sanitizer_spec.rb +192 -0
  176. data/spec/lib/appsignal/utils_spec.rb +150 -0
  177. data/spec/lib/appsignal_spec.rb +1049 -0
  178. data/spec/spec_helper.rb +116 -0
  179. data/spec/support/fixtures/containers/cgroups/docker +14 -0
  180. data/spec/support/fixtures/containers/cgroups/docker_systemd +8 -0
  181. data/spec/support/fixtures/containers/cgroups/lxc +10 -0
  182. data/spec/support/fixtures/containers/cgroups/no_permission +0 -0
  183. data/spec/support/fixtures/containers/cgroups/none +1 -0
  184. data/spec/support/fixtures/generated_config.yml +24 -0
  185. data/spec/support/fixtures/uploaded_file.txt +0 -0
  186. data/spec/support/helpers/api_request_helper.rb +19 -0
  187. data/spec/support/helpers/cli_helpers.rb +26 -0
  188. data/spec/support/helpers/config_helpers.rb +21 -0
  189. data/spec/support/helpers/dependency_helper.rb +73 -0
  190. data/spec/support/helpers/directory_helper.rb +27 -0
  191. data/spec/support/helpers/env_helpers.rb +33 -0
  192. data/spec/support/helpers/example_exception.rb +13 -0
  193. data/spec/support/helpers/example_standard_error.rb +13 -0
  194. data/spec/support/helpers/log_helpers.rb +22 -0
  195. data/spec/support/helpers/std_streams_helper.rb +66 -0
  196. data/spec/support/helpers/system_helpers.rb +8 -0
  197. data/spec/support/helpers/time_helpers.rb +11 -0
  198. data/spec/support/helpers/transaction_helpers.rb +37 -0
  199. data/spec/support/matchers/contains_log.rb +7 -0
  200. data/spec/support/mocks/fake_gc_profiler.rb +19 -0
  201. data/spec/support/mocks/mock_extension.rb +6 -0
  202. data/spec/support/project_fixture/config/application.rb +0 -0
  203. data/spec/support/project_fixture/config/appsignal.yml +32 -0
  204. data/spec/support/project_fixture/config/environments/development.rb +0 -0
  205. data/spec/support/project_fixture/config/environments/production.rb +0 -0
  206. data/spec/support/project_fixture/config/environments/test.rb +0 -0
  207. data/spec/support/project_fixture/log/.gitkeep +0 -0
  208. data/spec/support/rails/my_app.rb +6 -0
  209. data/spec/support/shared_examples/instrument.rb +43 -0
  210. data/spec/support/stubs/delayed_job.rb +0 -0
  211. metadata +483 -0
@@ -0,0 +1,35 @@
1
+ describe Appsignal::Hooks::WebmachineHook do
2
+ if DependencyHelper.webmachine_present?
3
+ context "with webmachine" do
4
+ let(:fsm) { Webmachine::Decision::FSM.new(double(:trace? => false), double, double) }
5
+ before(:context) { start_agent }
6
+
7
+ describe "#dependencies_present?" do
8
+ subject { described_class.new.dependencies_present? }
9
+
10
+ it { is_expected.to be_truthy }
11
+ end
12
+
13
+ it "should include the run alias methods" do
14
+ expect(fsm).to respond_to(:run_with_appsignal)
15
+ expect(fsm).to respond_to(:run_without_appsignal)
16
+ end
17
+
18
+ it "should include the handle_exceptions alias methods" do
19
+ expect(
20
+ fsm.respond_to?(:handle_exceptions_with_appsignal, true)
21
+ ).to be_truthy
22
+
23
+ expect(
24
+ fsm.respond_to?(:handle_exceptions_without_appsignal, true)
25
+ ).to be_truthy
26
+ end
27
+ end
28
+ else
29
+ describe "#dependencies_present?" do
30
+ subject { described_class.new.dependencies_present? }
31
+
32
+ it { is_expected.to be_falsy }
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,195 @@
1
+ class MockPresentHook < Appsignal::Hooks::Hook
2
+ def dependencies_present?
3
+ true
4
+ end
5
+
6
+ def install
7
+ MockPresentHook.call_something
8
+ end
9
+
10
+ def self.call_something
11
+ end
12
+ end
13
+
14
+ class MockNotPresentHook < Appsignal::Hooks::Hook
15
+ def dependencies_present?
16
+ false
17
+ end
18
+
19
+ def install
20
+ MockNotPresentHook.call_something
21
+ end
22
+ end
23
+
24
+ class MockErrorHook < Appsignal::Hooks::Hook
25
+ def dependencies_present?
26
+ true
27
+ end
28
+
29
+ def install
30
+ raise "error"
31
+ end
32
+ end
33
+
34
+ describe Appsignal::Hooks do
35
+ it "should register and install a hook once" do
36
+ Appsignal::Hooks::Hook.register(:mock_present_hook, MockPresentHook)
37
+
38
+ expect(Appsignal::Hooks.hooks[:mock_present_hook]).to be_instance_of(MockPresentHook)
39
+ expect(Appsignal::Hooks.hooks[:mock_present_hook].installed?).to be_falsy
40
+
41
+ expect(MockPresentHook).to receive(:call_something).once
42
+
43
+ Appsignal::Hooks.load_hooks
44
+ Appsignal::Hooks.load_hooks
45
+ Appsignal::Hooks.load_hooks
46
+ expect(Appsignal::Hooks.hooks[:mock_present_hook].installed?).to be_truthy
47
+ Appsignal::Hooks.hooks.delete(:mock_present_hook)
48
+ end
49
+
50
+ it "should not install if depencies are not present" do
51
+ Appsignal::Hooks::Hook.register(:mock_not_present_hook, MockNotPresentHook)
52
+
53
+ expect(Appsignal::Hooks.hooks[:mock_not_present_hook]).to be_instance_of(MockNotPresentHook)
54
+ expect(Appsignal::Hooks.hooks[:mock_not_present_hook].installed?).to be_falsy
55
+
56
+ expect(MockPresentHook).to_not receive(:call_something)
57
+
58
+ Appsignal::Hooks.load_hooks
59
+
60
+ expect(Appsignal::Hooks.hooks[:mock_not_present_hook].installed?).to be_falsy
61
+ Appsignal::Hooks.hooks.delete(:mock_not_present_hook)
62
+ end
63
+
64
+ it "should not install if there is an error while installing" do
65
+ Appsignal::Hooks::Hook.register(:mock_error_hook, MockErrorHook)
66
+
67
+ expect(Appsignal::Hooks.hooks[:mock_error_hook]).to be_instance_of(MockErrorHook)
68
+ expect(Appsignal::Hooks.hooks[:mock_error_hook].installed?).to be_falsy
69
+
70
+ expect(Appsignal.logger).to receive(:error).with("Error while installing mock_error_hook hook: error").once
71
+
72
+ Appsignal::Hooks.load_hooks
73
+
74
+ expect(Appsignal::Hooks.hooks[:mock_error_hook].installed?).to be_falsy
75
+ Appsignal::Hooks.hooks.delete(:mock_error_hook)
76
+ end
77
+ end
78
+
79
+ describe Appsignal::Hooks::Helpers do
80
+ class ClassWithHelpers
81
+ include Appsignal::Hooks::Helpers
82
+ end
83
+ let(:with_helpers) { ClassWithHelpers.new }
84
+
85
+ describe "#truncate" do
86
+ let(:very_long_text) do
87
+ "a" * 400
88
+ end
89
+
90
+ it "should truncate the text to 200 chars max" do
91
+ expect(with_helpers.truncate(very_long_text)).to eq "#{"a" * 197}..."
92
+ end
93
+ end
94
+
95
+ describe "#string_or_inspect" do
96
+ context "when string" do
97
+ it "should return the string" do
98
+ expect(with_helpers.string_or_inspect("foo")).to eq "foo"
99
+ end
100
+ end
101
+
102
+ context "when integer" do
103
+ it "should return the string" do
104
+ expect(with_helpers.string_or_inspect(1)).to eq "1"
105
+ end
106
+ end
107
+
108
+ context "when object" do
109
+ let(:object) { Object.new }
110
+
111
+ it "should return the string" do
112
+ expect(with_helpers.string_or_inspect(object)).to eq object.inspect
113
+ end
114
+ end
115
+ end
116
+
117
+ describe "#extract_value" do
118
+ context "for a hash" do
119
+ let(:hash) { { :key => "value" } }
120
+
121
+ context "when the key exists" do
122
+ subject { with_helpers.extract_value(hash, :key) }
123
+
124
+ it { is_expected.to eq "value" }
125
+ end
126
+
127
+ context "when the key does not exist" do
128
+ subject { with_helpers.extract_value(hash, :nonexistent_key) }
129
+
130
+ it { is_expected.to be_nil }
131
+
132
+ context "with a default value" do
133
+ subject { with_helpers.extract_value(hash, :nonexistent_key, 1) }
134
+
135
+ it { is_expected.to eq 1 }
136
+ end
137
+ end
138
+ end
139
+
140
+ context "for a struct" do
141
+ before :context do
142
+ TestStruct = Struct.new(:key)
143
+ end
144
+ let(:struct) { TestStruct.new("value") }
145
+
146
+ context "when the key exists" do
147
+ subject { with_helpers.extract_value(struct, :key) }
148
+
149
+ it { is_expected.to eq "value" }
150
+ end
151
+
152
+ context "when the key does not exist" do
153
+ subject { with_helpers.extract_value(struct, :nonexistent_key) }
154
+
155
+ it { is_expected.to be_nil }
156
+
157
+ context "with a default value" do
158
+ subject { with_helpers.extract_value(struct, :nonexistent_key, 1) }
159
+
160
+ it { is_expected.to eq 1 }
161
+ end
162
+ end
163
+ end
164
+
165
+ context "for an object" do
166
+ let(:object) { double(:existing_method => "value") }
167
+
168
+ context "when the method exists" do
169
+ subject { with_helpers.extract_value(object, :existing_method) }
170
+
171
+ it { is_expected.to eq "value" }
172
+ end
173
+
174
+ context "when the method does not exist" do
175
+ subject { with_helpers.extract_value(object, :nonexistent_method) }
176
+
177
+ it { is_expected.to be_nil }
178
+
179
+ context "and there is a default value" do
180
+ subject { with_helpers.extract_value(object, :nonexistent_method, 1) }
181
+
182
+ it { is_expected.to eq 1 }
183
+ end
184
+ end
185
+ end
186
+
187
+ context "when we need to call to_s on the value" do
188
+ let(:object) { double(:existing_method => 1) }
189
+
190
+ subject { with_helpers.extract_value(object, :existing_method, nil, true) }
191
+
192
+ it { is_expected.to eq "1" }
193
+ end
194
+ end
195
+ end
@@ -0,0 +1,65 @@
1
+ require "appsignal/integrations/data_mapper"
2
+
3
+ describe Appsignal::Hooks::DataMapperLogListener do
4
+ module DataMapperLog
5
+ def log(message)
6
+ end
7
+ end
8
+
9
+ describe "#log" do
10
+ let(:transaction) { double }
11
+ let(:message) do
12
+ double(
13
+ :query => "SELECT * from users",
14
+ :duration => 100
15
+ )
16
+ end
17
+ let(:connection_class) do
18
+ module DataObjects
19
+ module Sqlite3
20
+ class Connection
21
+ include DataMapperLog
22
+ include Appsignal::Hooks::DataMapperLogListener
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ before { allow(Appsignal::Transaction).to receive(:current) { transaction } }
29
+
30
+ it "should record the log entry in an event" do
31
+ expect(transaction).to receive(:record_event).with(
32
+ "query.data_mapper",
33
+ "DataMapper Query",
34
+ "SELECT * from users",
35
+ 100,
36
+ Appsignal::EventFormatter::SQL_BODY_FORMAT
37
+ )
38
+ end
39
+
40
+ context "when scheme is not sql-like" do
41
+ let(:connection_class) do
42
+ module DataObjects
43
+ module MongoDB
44
+ class Connection
45
+ include DataMapperLog
46
+ include Appsignal::Hooks::DataMapperLogListener
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ it "should record the log entry in an event without body" do
53
+ expect(transaction).to receive(:record_event).with(
54
+ "query.data_mapper",
55
+ "DataMapper Query",
56
+ "",
57
+ 100,
58
+ Appsignal::EventFormatter::DEFAULT
59
+ )
60
+ end
61
+ end
62
+
63
+ after { connection_class.new.log(message) }
64
+ end
65
+ end
@@ -0,0 +1,225 @@
1
+ if DependencyHelper.grape_present?
2
+ require "appsignal/integrations/grape"
3
+
4
+ describe Appsignal::Grape::Middleware do
5
+ let(:app) do
6
+ Class.new(::Grape::API) do
7
+ format :json
8
+ post :ping do
9
+ { :message => "Hello world!" }
10
+ end
11
+ end
12
+ end
13
+ let(:api_endpoint) { app.endpoints.first }
14
+ let(:env) do
15
+ http_request_env_with_data \
16
+ "api.endpoint" => api_endpoint,
17
+ "REQUEST_METHOD" => "POST",
18
+ :path => "/ping"
19
+ end
20
+ let(:middleware) { Appsignal::Grape::Middleware.new(api_endpoint) }
21
+ around do |example|
22
+ GrapeExample = Module.new
23
+ GrapeExample.send(:const_set, :Api, app)
24
+ example.run
25
+ Object.send(:remove_const, :GrapeExample)
26
+ end
27
+
28
+ describe "#call" do
29
+ context "when AppSignal is not active" do
30
+ before(:context) do
31
+ Appsignal.config = nil
32
+ Appsignal::Hooks.load_hooks
33
+ end
34
+
35
+ it "creates no transaction" do
36
+ expect(Appsignal::Transaction).to_not receive(:create)
37
+ end
38
+
39
+ it "calls the endpoint normally" do
40
+ expect(api_endpoint).to receive(:call).with(env)
41
+ end
42
+
43
+ after { middleware.call(env) }
44
+ end
45
+
46
+ context "when AppSignal is active" do
47
+ let(:transaction) { http_request_transaction }
48
+ before :context do
49
+ Appsignal.config = project_fixture_config
50
+ expect(Appsignal.active?).to be_truthy
51
+ end
52
+ before do
53
+ expect(Appsignal::Transaction).to receive(:create).with(
54
+ kind_of(String),
55
+ Appsignal::Transaction::HTTP_REQUEST,
56
+ kind_of(::Rack::Request)
57
+ ).and_return(transaction)
58
+ end
59
+
60
+ context "without error" do
61
+ it "calls the endpoint" do
62
+ expect(api_endpoint).to receive(:call).with(env)
63
+ end
64
+
65
+ it "sets metadata" do
66
+ expect(transaction).to receive(:set_http_or_background_queue_start)
67
+ expect(transaction).to receive(:set_action_if_nil).with("POST::GrapeExample::Api#/ping")
68
+ expect(transaction).to receive(:set_metadata).with("path", "/ping")
69
+ expect(transaction).to receive(:set_metadata).with("method", "POST")
70
+ end
71
+
72
+ after { middleware.call(env) }
73
+ end
74
+
75
+ context "with error" do
76
+ let(:app) do
77
+ Class.new(::Grape::API) do
78
+ format :json
79
+ post :ping do
80
+ raise ExampleException
81
+ end
82
+ end
83
+ end
84
+
85
+ it "sets metadata" do
86
+ expect(transaction).to receive(:set_http_or_background_queue_start)
87
+ expect(transaction).to receive(:set_action_if_nil).with("POST::GrapeExample::Api#/ping")
88
+ expect(transaction).to receive(:set_metadata).with("path", "/ping")
89
+ expect(transaction).to receive(:set_metadata).with("method", "POST")
90
+ end
91
+
92
+ it "sets the error" do
93
+ expect(transaction).to receive(:set_error).with(kind_of(ExampleException))
94
+ end
95
+
96
+ after do
97
+ expect { middleware.call(env) }.to raise_error ExampleException
98
+ end
99
+ end
100
+
101
+ context "with route" do
102
+ let(:app) do
103
+ Class.new(::Grape::API) do
104
+ route [:get, :post], "hello" do
105
+ "Hello!"
106
+ end
107
+ end
108
+ end
109
+ let(:env) do
110
+ http_request_env_with_data \
111
+ "api.endpoint" => api_endpoint,
112
+ "REQUEST_METHOD" => "GET",
113
+ :path => ""
114
+ end
115
+
116
+ it "sets non-unique route path" do
117
+ expect(transaction).to receive(:set_action).with("GET::GrapeExample::Api#/hello")
118
+ expect(transaction).to receive(:set_metadata).with("path", "/hello")
119
+ expect(transaction).to receive(:set_metadata).with("method", "GET")
120
+ end
121
+
122
+ after { middleware.call(env) }
123
+ end
124
+
125
+ context "with route_param" do
126
+ let(:app) do
127
+ Class.new(::Grape::API) do
128
+ format :json
129
+ resource :users do
130
+ route_param :id do
131
+ get do
132
+ { :name => "Tom" }
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
138
+ let(:env) do
139
+ http_request_env_with_data \
140
+ "api.endpoint" => api_endpoint,
141
+ "REQUEST_METHOD" => "GET",
142
+ :path => ""
143
+ end
144
+
145
+ it "sets non-unique route_param path" do
146
+ expect(transaction).to receive(:set_action_if_nil).with("GET::GrapeExample::Api#/users/:id/")
147
+ expect(transaction).to receive(:set_metadata).with("path", "/users/:id/")
148
+ expect(transaction).to receive(:set_metadata).with("method", "GET")
149
+ end
150
+
151
+ after { middleware.call(env) }
152
+ end
153
+
154
+ context "with namespaced path" do
155
+ context "with symbols" do
156
+ let(:app) do
157
+ Class.new(::Grape::API) do
158
+ format :json
159
+ namespace :v1 do
160
+ namespace :beta do
161
+ post :ping do
162
+ { :message => "Hello namespaced world!" }
163
+ end
164
+ end
165
+ end
166
+ end
167
+ end
168
+
169
+ it "sets namespaced path" do
170
+ expect(transaction).to receive(:set_action_if_nil).with("POST::GrapeExample::Api#/v1/beta/ping")
171
+ expect(transaction).to receive(:set_metadata).with("path", "/v1/beta/ping")
172
+ expect(transaction).to receive(:set_metadata).with("method", "POST")
173
+ end
174
+ end
175
+
176
+ context "with strings" do
177
+ context "without / prefix" do
178
+ let(:app) do
179
+ Class.new(::Grape::API) do
180
+ format :json
181
+ namespace "v1" do
182
+ namespace "beta" do
183
+ post "ping" do
184
+ { :message => "Hello namespaced world!" }
185
+ end
186
+ end
187
+ end
188
+ end
189
+ end
190
+
191
+ it "sets namespaced path" do
192
+ expect(transaction).to receive(:set_action_if_nil).with("POST::GrapeExample::Api#/v1/beta/ping")
193
+ expect(transaction).to receive(:set_metadata).with("path", "/v1/beta/ping")
194
+ expect(transaction).to receive(:set_metadata).with("method", "POST")
195
+ end
196
+ end
197
+
198
+ context "with / prefix" do
199
+ let(:app) do
200
+ Class.new(::Grape::API) do
201
+ format :json
202
+ namespace "/v1" do
203
+ namespace "/beta" do
204
+ post "/ping" do
205
+ { :message => "Hello namespaced world!" }
206
+ end
207
+ end
208
+ end
209
+ end
210
+ end
211
+
212
+ it "sets namespaced path" do
213
+ expect(transaction).to receive(:set_action_if_nil).with("POST::GrapeExample::Api#/v1/beta/ping")
214
+ expect(transaction).to receive(:set_metadata).with("path", "/v1/beta/ping")
215
+ expect(transaction).to receive(:set_metadata).with("method", "POST")
216
+ end
217
+ end
218
+ end
219
+
220
+ after { middleware.call(env) }
221
+ end
222
+ end
223
+ end
224
+ end
225
+ end