appoptics_apm 4.0.2

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 (226) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +43 -0
  3. data/.dockerignore +5 -0
  4. data/.gitignore +23 -0
  5. data/.rubocop.yml +5 -0
  6. data/.travis.yml +82 -0
  7. data/CHANGELOG.md +769 -0
  8. data/CONFIG.md +33 -0
  9. data/Dockerfile +41 -0
  10. data/Dockerfile_test +66 -0
  11. data/Gemfile +41 -0
  12. data/LICENSE +193 -0
  13. data/README.md +351 -0
  14. data/Rakefile +202 -0
  15. data/Vagrantfile +67 -0
  16. data/appoptics_apm.gemspec +55 -0
  17. data/build_gems.sh +15 -0
  18. data/docker-compose.yml +73 -0
  19. data/examples/DNT.md +35 -0
  20. data/examples/carrying_context.rb +220 -0
  21. data/examples/instrumenting_metal_controller.rb +8 -0
  22. data/examples/puma_on_heroku_config.rb +17 -0
  23. data/examples/tracing_async_threads.rb +124 -0
  24. data/examples/tracing_background_jobs.rb +53 -0
  25. data/examples/tracing_forked_processes.rb +99 -0
  26. data/examples/unicorn_on_heroku_config.rb +28 -0
  27. data/ext/oboe_metal/extconf.rb +54 -0
  28. data/ext/oboe_metal/lib/.keep +0 -0
  29. data/ext/oboe_metal/lib/liboboe-1.0.so.0.0.0 +0 -0
  30. data/ext/oboe_metal/noop/noop.c +7 -0
  31. data/ext/oboe_metal/src/VERSION +1 -0
  32. data/ext/oboe_metal/src/bson/bson.h +221 -0
  33. data/ext/oboe_metal/src/bson/platform_hacks.h +91 -0
  34. data/ext/oboe_metal/src/oboe.h +883 -0
  35. data/ext/oboe_metal/src/oboe.hpp +793 -0
  36. data/ext/oboe_metal/src/oboe_debug.h +50 -0
  37. data/ext/oboe_metal/src/oboe_wrap.cxx +6088 -0
  38. data/ext/oboe_metal/tests/test.rb +11 -0
  39. data/gemfiles/delayed_job.gemfile +36 -0
  40. data/gemfiles/frameworks.gemfile +44 -0
  41. data/gemfiles/instrumentation_mocked.gemfile +29 -0
  42. data/gemfiles/libraries.gemfile +85 -0
  43. data/gemfiles/rails23.gemfile +39 -0
  44. data/gemfiles/rails30.gemfile +42 -0
  45. data/gemfiles/rails31.gemfile +44 -0
  46. data/gemfiles/rails32.gemfile +54 -0
  47. data/gemfiles/rails40.gemfile +27 -0
  48. data/gemfiles/rails41.gemfile +27 -0
  49. data/gemfiles/rails42.gemfile +35 -0
  50. data/gemfiles/rails50.gemfile +44 -0
  51. data/gemfiles/rails51.gemfile +44 -0
  52. data/get_version.rb +5 -0
  53. data/init.rb +4 -0
  54. data/lib/appoptics_apm/api/layerinit.rb +39 -0
  55. data/lib/appoptics_apm/api/logging.rb +359 -0
  56. data/lib/appoptics_apm/api/memcache.rb +34 -0
  57. data/lib/appoptics_apm/api/profiling.rb +201 -0
  58. data/lib/appoptics_apm/api/tracing.rb +152 -0
  59. data/lib/appoptics_apm/api/util.rb +128 -0
  60. data/lib/appoptics_apm/api.rb +18 -0
  61. data/lib/appoptics_apm/base.rb +252 -0
  62. data/lib/appoptics_apm/config.rb +281 -0
  63. data/lib/appoptics_apm/frameworks/grape.rb +93 -0
  64. data/lib/appoptics_apm/frameworks/padrino/templates.rb +58 -0
  65. data/lib/appoptics_apm/frameworks/padrino.rb +52 -0
  66. data/lib/appoptics_apm/frameworks/rails/inst/action_controller.rb +106 -0
  67. data/lib/appoptics_apm/frameworks/rails/inst/action_controller2.rb +61 -0
  68. data/lib/appoptics_apm/frameworks/rails/inst/action_controller3.rb +58 -0
  69. data/lib/appoptics_apm/frameworks/rails/inst/action_controller4.rb +48 -0
  70. data/lib/appoptics_apm/frameworks/rails/inst/action_controller5.rb +50 -0
  71. data/lib/appoptics_apm/frameworks/rails/inst/action_controller_api.rb +50 -0
  72. data/lib/appoptics_apm/frameworks/rails/inst/action_view.rb +58 -0
  73. data/lib/appoptics_apm/frameworks/rails/inst/action_view_2x.rb +56 -0
  74. data/lib/appoptics_apm/frameworks/rails/inst/action_view_30.rb +50 -0
  75. data/lib/appoptics_apm/frameworks/rails/inst/active_record.rb +27 -0
  76. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/mysql.rb +43 -0
  77. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/mysql2.rb +28 -0
  78. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/postgresql.rb +30 -0
  79. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils.rb +120 -0
  80. data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils5x.rb +101 -0
  81. data/lib/appoptics_apm/frameworks/rails.rb +116 -0
  82. data/lib/appoptics_apm/frameworks/sinatra/templates.rb +56 -0
  83. data/lib/appoptics_apm/frameworks/sinatra.rb +71 -0
  84. data/lib/appoptics_apm/inst/bunny-client.rb +148 -0
  85. data/lib/appoptics_apm/inst/bunny-consumer.rb +92 -0
  86. data/lib/appoptics_apm/inst/curb.rb +329 -0
  87. data/lib/appoptics_apm/inst/dalli.rb +85 -0
  88. data/lib/appoptics_apm/inst/delayed_job.rb +92 -0
  89. data/lib/appoptics_apm/inst/em-http-request.rb +105 -0
  90. data/lib/appoptics_apm/inst/excon.rb +130 -0
  91. data/lib/appoptics_apm/inst/faraday.rb +77 -0
  92. data/lib/appoptics_apm/inst/http.rb +83 -0
  93. data/lib/appoptics_apm/inst/httpclient.rb +176 -0
  94. data/lib/appoptics_apm/inst/memcache.rb +102 -0
  95. data/lib/appoptics_apm/inst/memcached.rb +94 -0
  96. data/lib/appoptics_apm/inst/mongo.rb +242 -0
  97. data/lib/appoptics_apm/inst/mongo2.rb +225 -0
  98. data/lib/appoptics_apm/inst/moped.rb +466 -0
  99. data/lib/appoptics_apm/inst/rack.rb +146 -0
  100. data/lib/appoptics_apm/inst/redis.rb +275 -0
  101. data/lib/appoptics_apm/inst/resque.rb +151 -0
  102. data/lib/appoptics_apm/inst/rest-client.rb +50 -0
  103. data/lib/appoptics_apm/inst/sequel.rb +178 -0
  104. data/lib/appoptics_apm/inst/sidekiq-client.rb +53 -0
  105. data/lib/appoptics_apm/inst/sidekiq-worker.rb +67 -0
  106. data/lib/appoptics_apm/inst/twitter-cassandra.rb +294 -0
  107. data/lib/appoptics_apm/inst/typhoeus.rb +113 -0
  108. data/lib/appoptics_apm/instrumentation.rb +22 -0
  109. data/lib/appoptics_apm/legacy_method_profiling.rb +97 -0
  110. data/lib/appoptics_apm/loading.rb +66 -0
  111. data/lib/appoptics_apm/logger.rb +41 -0
  112. data/lib/appoptics_apm/method_profiling.rb +33 -0
  113. data/lib/appoptics_apm/ruby.rb +35 -0
  114. data/lib/appoptics_apm/support.rb +135 -0
  115. data/lib/appoptics_apm/test.rb +94 -0
  116. data/lib/appoptics_apm/thread_local.rb +26 -0
  117. data/lib/appoptics_apm/util.rb +312 -0
  118. data/lib/appoptics_apm/version.rb +15 -0
  119. data/lib/appoptics_apm/xtrace.rb +103 -0
  120. data/lib/appoptics_apm.rb +72 -0
  121. data/lib/joboe_metal.rb +214 -0
  122. data/lib/oboe/README +2 -0
  123. data/lib/oboe/backward_compatibility.rb +80 -0
  124. data/lib/oboe/inst/rack.rb +11 -0
  125. data/lib/oboe.rb +7 -0
  126. data/lib/oboe_metal.rb +187 -0
  127. data/lib/rails/generators/appoptics_apm/install_generator.rb +45 -0
  128. data/lib/rails/generators/appoptics_apm/templates/appoptics_apm_initializer.rb +222 -0
  129. data/ruby_setup.sh +47 -0
  130. data/run_docker_build_gem_upload_to_packagecloud.sh +20 -0
  131. data/run_tests_docker.rb +32 -0
  132. data/test/benchmark/README.md +65 -0
  133. data/test/benchmark/logging_bench.rb +54 -0
  134. data/test/benchmark/with_libraries_gemfile/bunny_bench.rb +69 -0
  135. data/test/benchmark/with_rails5x_gemfile/action_controller5x_bench.rb +43 -0
  136. data/test/frameworks/apps/grape_nested.rb +33 -0
  137. data/test/frameworks/apps/grape_simple.rb +80 -0
  138. data/test/frameworks/apps/padrino_simple.rb +80 -0
  139. data/test/frameworks/apps/sinatra_simple.rb +55 -0
  140. data/test/frameworks/grape_test.rb +286 -0
  141. data/test/frameworks/padrino_test.rb +222 -0
  142. data/test/frameworks/rails3x_test.rb +554 -0
  143. data/test/frameworks/rails4x_test.rb +570 -0
  144. data/test/frameworks/rails5x_api_test.rb +210 -0
  145. data/test/frameworks/rails5x_test.rb +376 -0
  146. data/test/frameworks/rails_shared_tests.rb +172 -0
  147. data/test/frameworks/sinatra_test.rb +140 -0
  148. data/test/instrumentation/bunny_client_test.rb +276 -0
  149. data/test/instrumentation/bunny_consumer_test.rb +204 -0
  150. data/test/instrumentation/curb_test.rb +398 -0
  151. data/test/instrumentation/dalli_test.rb +177 -0
  152. data/test/instrumentation/em_http_request_test.rb +89 -0
  153. data/test/instrumentation/excon_test.rb +231 -0
  154. data/test/instrumentation/faraday_test.rb +228 -0
  155. data/test/instrumentation/http_test.rb +143 -0
  156. data/test/instrumentation/httpclient_test.rb +320 -0
  157. data/test/instrumentation/memcache_test.rb +260 -0
  158. data/test/instrumentation/memcached_test.rb +229 -0
  159. data/test/instrumentation/mongo_v1_test.rb +479 -0
  160. data/test/instrumentation/mongo_v2_index_test.rb +124 -0
  161. data/test/instrumentation/mongo_v2_test.rb +584 -0
  162. data/test/instrumentation/mongo_v2_view_test.rb +435 -0
  163. data/test/instrumentation/moped_test.rb +517 -0
  164. data/test/instrumentation/rack_test.rb +165 -0
  165. data/test/instrumentation/redis_hashes_test.rb +268 -0
  166. data/test/instrumentation/redis_keys_test.rb +321 -0
  167. data/test/instrumentation/redis_lists_test.rb +310 -0
  168. data/test/instrumentation/redis_misc_test.rb +163 -0
  169. data/test/instrumentation/redis_sets_test.rb +296 -0
  170. data/test/instrumentation/redis_sortedsets_test.rb +328 -0
  171. data/test/instrumentation/redis_strings_test.rb +349 -0
  172. data/test/instrumentation/resque_test.rb +185 -0
  173. data/test/instrumentation/rest-client_test.rb +288 -0
  174. data/test/instrumentation/sequel_mysql2_test.rb +353 -0
  175. data/test/instrumentation/sequel_mysql_test.rb +334 -0
  176. data/test/instrumentation/sequel_pg_test.rb +336 -0
  177. data/test/instrumentation/sidekiq-client_test.rb +159 -0
  178. data/test/instrumentation/sidekiq-worker_test.rb +180 -0
  179. data/test/instrumentation/twitter-cassandra_test.rb +424 -0
  180. data/test/instrumentation/typhoeus_test.rb +284 -0
  181. data/test/jobs/delayed_job/db_worker_job.rb +29 -0
  182. data/test/jobs/delayed_job/error_worker_job.rb +10 -0
  183. data/test/jobs/delayed_job/remote_call_worker_job.rb +20 -0
  184. data/test/jobs/resque/db_worker_job.rb +29 -0
  185. data/test/jobs/resque/error_worker_job.rb +10 -0
  186. data/test/jobs/resque/remote_call_worker_job.rb +20 -0
  187. data/test/jobs/sidekiq/db_worker_job.rb +29 -0
  188. data/test/jobs/sidekiq/error_worker_job.rb +10 -0
  189. data/test/jobs/sidekiq/remote_call_worker_job.rb +20 -0
  190. data/test/minitest_helper.rb +276 -0
  191. data/test/mocked/curb_mocked_test.rb +311 -0
  192. data/test/mocked/excon_mocked_test.rb +166 -0
  193. data/test/mocked/faraday_mocked_test.rb +93 -0
  194. data/test/mocked/http_mocked_test.rb +129 -0
  195. data/test/mocked/httpclient_mocked_test.rb +245 -0
  196. data/test/mocked/rest_client_mocked_test.rb +103 -0
  197. data/test/mocked/typhoeus_mocked_test.rb +192 -0
  198. data/test/models/widget.rb +36 -0
  199. data/test/profiling/legacy_method_profiling_test.rb +201 -0
  200. data/test/profiling/method_profiling_test.rb +631 -0
  201. data/test/queues/delayed_job-client_test.rb +95 -0
  202. data/test/queues/delayed_job-worker_test.rb +91 -0
  203. data/test/reporter/reporter_test.rb +14 -0
  204. data/test/servers/delayed_job.rb +107 -0
  205. data/test/servers/rackapp_8101.rb +29 -0
  206. data/test/servers/rails3x_8140.rb +96 -0
  207. data/test/servers/rails4x_8140.rb +96 -0
  208. data/test/servers/rails5x_8140.rb +95 -0
  209. data/test/servers/rails5x_api_8150.rb +78 -0
  210. data/test/servers/sidekiq.rb +29 -0
  211. data/test/servers/sidekiq.yml +7 -0
  212. data/test/servers/sidekiq_initializer.rb +25 -0
  213. data/test/settings +0 -0
  214. data/test/support/auto_tracing_test.rb +50 -0
  215. data/test/support/backcompat_test.rb +276 -0
  216. data/test/support/config_test.rb +149 -0
  217. data/test/support/dnt_test.rb +98 -0
  218. data/test/support/init_report_test.rb +25 -0
  219. data/test/support/liboboe_settings_test.rb +110 -0
  220. data/test/support/logging_test.rb +130 -0
  221. data/test/support/noop_test.rb +88 -0
  222. data/test/support/sql_sanitize_test.rb +55 -0
  223. data/test/support/tracing_mode_test.rb +33 -0
  224. data/test/support/tvalias_test.rb +15 -0
  225. data/test/support/xtrace_test.rb +41 -0
  226. metadata +475 -0
@@ -0,0 +1,228 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ require 'minitest_helper'
5
+
6
+ describe "Faraday" do
7
+ before do
8
+ clear_all_traces
9
+ @collect_backtraces = AppOpticsAPM::Config[:faraday][:collect_backtraces]
10
+ end
11
+
12
+ after do
13
+ AppOpticsAPM::Config[:faraday][:collect_backtraces] = @collect_backtraces
14
+ end
15
+
16
+ it 'Faraday should be defined and ready' do
17
+ defined?(::Faraday).wont_match nil
18
+ end
19
+
20
+ it 'Faraday should have appoptics_apm methods defined' do
21
+ [ :run_request_with_appoptics ].each do |m|
22
+ ::Faraday::Connection.method_defined?(m).must_equal true
23
+ end
24
+ end
25
+
26
+ it "should trace cross-app request" do
27
+ AppOpticsAPM::API.start_trace('faraday_test') do
28
+ conn = Faraday.new(:url => 'http://127.0.0.1:8101') do |faraday|
29
+ faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
30
+ end
31
+ response = conn.get '/games?q=1'
32
+ response.headers["x-trace"].wont_match nil
33
+ end
34
+
35
+ traces = get_all_traces
36
+ traces.count.must_equal 11
37
+
38
+ validate_outer_layers(traces, 'faraday_test')
39
+
40
+ traces[1]['Layer'].must_equal 'faraday'
41
+ traces[1].key?('Backtrace').must_equal AppOpticsAPM::Config[:faraday][:collect_backtraces]
42
+
43
+ traces[6]['Layer'].must_equal 'net-http'
44
+ traces[6]['IsService'].must_equal 1
45
+ traces[6]['RemoteProtocol'].must_equal 'HTTP'
46
+ traces[6]['RemoteHost'].must_equal '127.0.0.1:8101'
47
+ traces[6]['ServiceArg'].must_equal '/games?q=1'
48
+ traces[6]['HTTPMethod'].must_equal 'GET'
49
+ traces[6]['HTTPStatus'].must_equal '200'
50
+
51
+ traces[7]['Layer'].must_equal 'net-http'
52
+ traces[7]['Label'].must_equal 'exit'
53
+
54
+ traces[8]['Layer'].must_equal 'faraday'
55
+ traces[9]['Label'].must_equal 'exit'
56
+ end
57
+
58
+ it 'should trace a Faraday request' do
59
+ AppOpticsAPM::API.start_trace('faraday_test') do
60
+ conn = Faraday.new(:url => 'http://127.0.0.1:8101') do |faraday|
61
+ faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
62
+ end
63
+ conn.get '/?q=ruby_test_suite'
64
+ end
65
+
66
+ traces = get_all_traces
67
+ traces.count.must_equal 11
68
+
69
+ assert valid_edges?(traces), "Invalid edge in traces"
70
+ validate_outer_layers(traces, 'faraday_test')
71
+
72
+ traces[1]['Layer'].must_equal 'faraday'
73
+ traces[1].key?('Backtrace').must_equal AppOpticsAPM::Config[:faraday][:collect_backtraces]
74
+
75
+ traces[6]['Layer'].must_equal 'net-http'
76
+ traces[6]['Label'].must_equal 'info'
77
+ traces[6]['IsService'].must_equal 1
78
+ traces[6]['RemoteProtocol'].must_equal 'HTTP'
79
+ traces[6]['RemoteHost'].must_equal '127.0.0.1:8101'
80
+ traces[6]['ServiceArg'].must_equal '/?q=ruby_test_suite'
81
+ traces[6]['HTTPMethod'].must_equal 'GET'
82
+ traces[6]['HTTPStatus'].must_equal '200'
83
+
84
+ traces[7]['Layer'].must_equal 'net-http'
85
+ traces[7]['Label'].must_equal 'exit'
86
+
87
+ traces[8]['Layer'].must_equal 'faraday'
88
+ traces[8]['Label'].must_equal 'info'
89
+
90
+ traces[9]['Layer'].must_equal 'faraday'
91
+ traces[9]['Label'].must_equal 'exit'
92
+ end
93
+
94
+ it 'should trace a Faraday class style request' do
95
+ AppOpticsAPM::API.start_trace('faraday_test') do
96
+ Faraday.get('http://127.0.0.1:8101/', {:a => 1})
97
+ end
98
+
99
+ traces = get_all_traces
100
+ traces.count.must_equal 11
101
+
102
+ assert valid_edges?(traces), "Invalid edge in traces"
103
+ validate_outer_layers(traces, 'faraday_test')
104
+
105
+ traces[1]['Layer'].must_equal 'faraday'
106
+ traces[1].key?('Backtrace').must_equal AppOpticsAPM::Config[:faraday][:collect_backtraces]
107
+
108
+ traces[6]['Layer'].must_equal 'net-http'
109
+ traces[6]['Label'].must_equal 'info'
110
+ traces[6]['IsService'].must_equal 1
111
+ traces[6]['RemoteProtocol'].must_equal 'HTTP'
112
+ traces[6]['RemoteHost'].must_equal '127.0.0.1:8101'
113
+ traces[6]['ServiceArg'].must_equal '/?a=1'
114
+ traces[6]['HTTPMethod'].must_equal 'GET'
115
+ traces[6]['HTTPStatus'].must_equal '200'
116
+
117
+ traces[7]['Layer'].must_equal 'net-http'
118
+ traces[7]['Label'].must_equal 'exit'
119
+
120
+ traces[8]['Layer'].must_equal 'faraday'
121
+ traces[8]['Label'].must_equal 'info'
122
+
123
+ traces[9]['Layer'].must_equal 'faraday'
124
+ traces[9]['Label'].must_equal 'exit'
125
+ end
126
+
127
+ it 'should trace a Faraday with the excon adapter' do
128
+ AppOpticsAPM::API.start_trace('faraday_test') do
129
+ conn = Faraday.new(:url => 'http://127.0.0.1:8101') do |faraday|
130
+ faraday.adapter :excon
131
+ end
132
+ conn.get '/?q=1'
133
+ end
134
+
135
+ traces = get_all_traces
136
+ traces.count.must_equal 10
137
+
138
+ assert valid_edges?(traces), "Invalid edge in traces"
139
+ validate_outer_layers(traces, 'faraday_test')
140
+
141
+ traces[1]['Layer'].must_equal 'faraday'
142
+ traces[1].key?('Backtrace').must_equal AppOpticsAPM::Config[:faraday][:collect_backtraces]
143
+
144
+ traces[2]['Layer'].must_equal 'excon'
145
+ traces[2]['Label'].must_equal 'entry'
146
+ traces[2]['IsService'].must_equal 1
147
+ traces[2]['RemoteProtocol'].must_equal 'HTTP'
148
+ traces[2]['RemoteHost'].must_equal '127.0.0.1'
149
+ traces[2]['ServiceArg'].must_equal '/?q=1'
150
+ traces[2]['HTTPMethod'].must_equal 'GET'
151
+
152
+ traces[6]['Layer'].must_equal 'excon'
153
+ traces[6]['Label'].must_equal 'exit'
154
+ traces[6]['HTTPStatus'].must_equal 200
155
+
156
+ traces[7]['Layer'].must_equal 'faraday'
157
+ traces[7]['Label'].must_equal 'info'
158
+ traces[7]['Middleware'].must_equal '[Faraday::Adapter::Excon]'
159
+
160
+ traces[8]['Layer'].must_equal 'faraday'
161
+ traces[8]['Label'].must_equal 'exit'
162
+ end
163
+
164
+ it 'should trace a Faraday with the httpclient adapter' do
165
+ AppOpticsAPM::API.start_trace('faraday_test') do
166
+ conn = Faraday.new(:url => 'http://127.0.0.1:8101') do |faraday|
167
+ faraday.adapter :httpclient
168
+ end
169
+ conn.get '/?q=1'
170
+ end
171
+
172
+ traces = get_all_traces
173
+ traces.count.must_equal 10
174
+
175
+ assert valid_edges?(traces), "Invalid edge in traces"
176
+ validate_outer_layers(traces, 'faraday_test')
177
+
178
+ traces[1]['Layer'].must_equal 'faraday'
179
+ traces[1].key?('Backtrace').must_equal AppOpticsAPM::Config[:faraday][:collect_backtraces]
180
+
181
+ traces[2]['Layer'].must_equal 'httpclient'
182
+ traces[2]['Label'].must_equal 'entry'
183
+ traces[2]['IsService'].must_equal 1
184
+ traces[2]['RemoteProtocol'].must_equal 'HTTP'
185
+ traces[2]['RemoteHost'].must_equal '127.0.0.1:8101'
186
+ traces[2]['ServiceArg'].must_equal '/?q=1'
187
+ traces[2]['HTTPMethod'].must_equal 'GET'
188
+
189
+ traces[6]['Layer'].must_equal 'httpclient'
190
+ traces[6]['Label'].must_equal 'exit'
191
+ traces[6]['HTTPStatus'].must_equal 200
192
+
193
+ traces[7]['Layer'].must_equal 'faraday'
194
+ traces[7]['Label'].must_equal 'info'
195
+ traces[7]['Middleware'].must_equal '[Faraday::Adapter::HTTPClient]'
196
+
197
+ traces[8]['Layer'].must_equal 'faraday'
198
+ traces[8]['Label'].must_equal 'exit'
199
+ end
200
+
201
+ it 'should obey :collect_backtraces setting when true' do
202
+ AppOpticsAPM::Config[:faraday][:collect_backtraces] = true
203
+
204
+ AppOpticsAPM::API.start_trace('faraday_test') do
205
+ conn = Faraday.new(:url => 'http://127.0.0.1:8101') do |faraday|
206
+ faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
207
+ end
208
+ conn.get '/?q=ruby_test_suite'
209
+ end
210
+
211
+ traces = get_all_traces
212
+ layer_has_key(traces, 'faraday', 'Backtrace')
213
+ end
214
+
215
+ it 'should obey :collect_backtraces setting when false' do
216
+ AppOpticsAPM::Config[:faraday][:collect_backtraces] = false
217
+
218
+ AppOpticsAPM::API.start_trace('faraday_test') do
219
+ conn = Faraday.new(:url => 'http://127.0.0.1:8101') do |faraday|
220
+ faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
221
+ end
222
+ conn.get '/?q=ruby_test_suite'
223
+ end
224
+
225
+ traces = get_all_traces
226
+ layer_doesnt_have_key(traces, 'faraday', 'Backtrace')
227
+ end
228
+ end
@@ -0,0 +1,143 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ require 'minitest_helper'
5
+ require 'net/http'
6
+
7
+ describe "Net::HTTP" do
8
+ before do
9
+ clear_all_traces
10
+ @collect_backtraces = AppOpticsAPM::Config[:nethttp][:collect_backtraces]
11
+ @log_args = AppOpticsAPM::Config[:nethttp][:log_args]
12
+ end
13
+
14
+ after do
15
+ AppOpticsAPM::Config[:nethttp][:collect_backtraces] = @collect_backtraces
16
+ AppOpticsAPM::Config[:nethttp][:log_args] = @log_args
17
+ end
18
+
19
+ it 'Net::HTTP should be defined and ready' do
20
+ defined?(::Net::HTTP).wont_match nil
21
+ end
22
+
23
+ it 'Net::HTTP should have appoptics_apm methods defined' do
24
+ [ :request_with_appoptics ].each do |m|
25
+ ::Net::HTTP.method_defined?(m).must_equal true
26
+ end
27
+ end
28
+
29
+ it "should trace a Net::HTTP request to an instr'd app" do
30
+ AppOpticsAPM::API.start_trace('net-http_test', '', {}) do
31
+ uri = URI('http://127.0.0.1:8101/?q=1')
32
+ http = Net::HTTP.new(uri.host, uri.port)
33
+ request = Net::HTTP::Get.new(uri.request_uri)
34
+ response = http.request(request)
35
+ # The HTTP response should have an X-Trace header inside of it
36
+ response["x-trace"].wont_match nil
37
+ end
38
+
39
+ traces = get_all_traces
40
+ traces.count.must_equal 8
41
+ valid_edges?(traces).must_equal true
42
+ validate_outer_layers(traces, 'net-http_test')
43
+
44
+ traces[1]['Layer'].must_equal 'net-http'
45
+ traces[1]['Label'].must_equal 'entry'
46
+
47
+ traces[2]['Layer'].must_equal 'rack'
48
+ traces[2]['Label'].must_equal 'entry'
49
+
50
+ traces[3]['Layer'].must_equal 'rack'
51
+ traces[3]['Label'].must_equal 'info'
52
+
53
+ traces[4]['Layer'].must_equal 'rack'
54
+ traces[4]['Label'].must_equal 'exit'
55
+
56
+ traces[5]['IsService'].must_equal 1
57
+ traces[5]['RemoteProtocol'].must_equal "HTTP"
58
+ traces[5]['RemoteHost'].must_equal "127.0.0.1:8101"
59
+ traces[5]['ServiceArg'].must_equal "/?q=1"
60
+ traces[5]['HTTPMethod'].must_equal "GET"
61
+ traces[5]['HTTPStatus'].must_equal "200"
62
+ traces[5].has_key?('Backtrace').must_equal AppOpticsAPM::Config[:nethttp][:collect_backtraces]
63
+ end
64
+
65
+ it "should trace a GET request" do
66
+ AppOpticsAPM::API.start_trace('net-http_test', '', {}) do
67
+ uri = URI('http://127.0.0.1:8101/')
68
+ http = Net::HTTP.new(uri.host, uri.port)
69
+ http.get('/?q=1').read_body
70
+ end
71
+
72
+ traces = get_all_traces
73
+ traces.count.must_equal 8
74
+ valid_edges?(traces).must_equal true
75
+
76
+ validate_outer_layers(traces, 'net-http_test')
77
+
78
+ traces[1]['Layer'].must_equal 'net-http'
79
+ traces[5]['IsService'].must_equal 1
80
+ traces[5]['RemoteProtocol'].must_equal "HTTP"
81
+ traces[5]['RemoteHost'].must_equal "127.0.0.1:8101"
82
+ traces[5]['ServiceArg'].must_equal "/?q=1"
83
+ traces[5]['HTTPMethod'].must_equal "GET"
84
+ traces[5]['HTTPStatus'].must_equal "200"
85
+ traces[5].has_key?('Backtrace').must_equal AppOpticsAPM::Config[:nethttp][:collect_backtraces]
86
+ end
87
+
88
+ it "should obey :log_args setting when true" do
89
+ AppOpticsAPM::Config[:nethttp][:log_args] = true
90
+
91
+ AppOpticsAPM::API.start_trace('nethttp_test', '', {}) do
92
+ uri = URI('http://127.0.0.1:8101/')
93
+ http = Net::HTTP.new(uri.host, uri.port)
94
+ http.use_ssl = false
95
+ http.get('/?q=ruby_test_suite').read_body
96
+ end
97
+
98
+ traces = get_all_traces
99
+ traces[5]['ServiceArg'].must_equal '/?q=ruby_test_suite'
100
+ end
101
+
102
+ it "should obey :log_args setting when false" do
103
+ AppOpticsAPM::Config[:nethttp][:log_args] = false
104
+
105
+ AppOpticsAPM::API.start_trace('nethttp_test', '', {}) do
106
+ uri = URI('http://127.0.0.1:8101/')
107
+ http = Net::HTTP.new(uri.host, uri.port)
108
+ http.use_ssl = false
109
+ http.get('/?q=ruby_test_suite').read_body
110
+ end
111
+
112
+ traces = get_all_traces
113
+ traces[5]['ServiceArg'].must_equal '/'
114
+ end
115
+
116
+ it "should obey :collect_backtraces setting when true" do
117
+ AppOpticsAPM::Config[:nethttp][:collect_backtraces] = true
118
+
119
+ AppOpticsAPM::API.start_trace('nethttp_test', '', {}) do
120
+ uri = URI('http://127.0.0.1:8101/')
121
+ http = Net::HTTP.new(uri.host, uri.port)
122
+ http.use_ssl = false
123
+ http.get('/?q=ruby_test_suite').read_body
124
+ end
125
+
126
+ traces = get_all_traces
127
+ layer_has_key(traces, 'net-http', 'Backtrace')
128
+ end
129
+
130
+ it "should obey :collect_backtraces setting when false" do
131
+ AppOpticsAPM::Config[:nethttp][:collect_backtraces] = false
132
+
133
+ AppOpticsAPM::API.start_trace('nethttp_test', '', {}) do
134
+ uri = URI('http://127.0.0.1:8101/')
135
+ http = Net::HTTP.new(uri.host, uri.port)
136
+ http.use_ssl = false
137
+ http.get('/?q=ruby_test_suite').read_body
138
+ end
139
+
140
+ traces = get_all_traces
141
+ layer_doesnt_have_key(traces, 'net-http', 'Backtrace')
142
+ end
143
+ end
@@ -0,0 +1,320 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ unless defined?(JRUBY_VERSION)
5
+ require 'minitest_helper'
6
+ require 'appoptics_apm/inst/rack'
7
+ require File.expand_path(File.dirname(__FILE__) + '../../frameworks/apps/sinatra_simple')
8
+
9
+ class HTTPClientTest < Minitest::Test
10
+ include Rack::Test::Methods
11
+
12
+ def app
13
+ SinatraSimple
14
+ end
15
+
16
+ def setup
17
+ clear_all_traces
18
+ AppOpticsAPM::Config[:tracing_mode] = :always
19
+ end
20
+
21
+ def test_reports_version_init
22
+ init_kvs = ::AppOpticsAPM::Util.build_init_report
23
+ assert init_kvs.key?('Ruby.httpclient.Version')
24
+ assert_equal ::HTTPClient::VERSION, init_kvs['Ruby.httpclient.Version']
25
+ end
26
+
27
+ def test_get_request
28
+ clear_all_traces
29
+
30
+ response = nil
31
+
32
+ AppOpticsAPM::API.start_trace('httpclient_tests') do
33
+ clnt = HTTPClient.new
34
+ response = clnt.get('http://127.0.0.1:8101/', :query => { :keyword => 'ruby', :lang => 'en' })
35
+ end
36
+
37
+ traces = get_all_traces
38
+
39
+ # Validate returned xtrace
40
+ assert response.headers.key?("X-Trace")
41
+ assert AppOpticsAPM::XTrace.valid?(response.headers["X-Trace"])
42
+
43
+ assert_equal traces.count, 7
44
+ assert valid_edges?(traces), "Invalid edge in traces"
45
+ validate_outer_layers(traces, "httpclient_tests")
46
+
47
+ assert_equal traces[1]['IsService'], 1
48
+ assert_equal traces[1]['RemoteURL'], 'http://127.0.0.1:8101/?keyword=ruby&lang=en'
49
+ assert_equal traces[1]['HTTPMethod'], 'GET'
50
+ assert traces[1].key?('Backtrace')
51
+
52
+ assert_equal traces[5]['Layer'], 'httpclient'
53
+ assert_equal traces[5]['Label'], 'exit'
54
+ assert_equal traces[5]['HTTPStatus'], 200
55
+ end
56
+
57
+ def test_get_with_header_hash
58
+ clear_all_traces
59
+
60
+ response = nil
61
+
62
+ AppOpticsAPM::API.start_trace('httpclient_tests') do
63
+ clnt = HTTPClient.new
64
+ response = clnt.get('http://127.0.0.1:8101/', nil, { "SOAPAction" => "HelloWorld" })
65
+ end
66
+
67
+ traces = get_all_traces
68
+
69
+ xtrace = response.headers['X-Trace']
70
+ assert xtrace
71
+ assert AppOpticsAPM::XTrace.valid?(xtrace)
72
+
73
+ assert_equal traces.count, 7
74
+ assert valid_edges?(traces), "Invalid edge in traces"
75
+ validate_outer_layers(traces, "httpclient_tests")
76
+
77
+ assert_equal traces[1]['IsService'], 1
78
+ assert_equal traces[1]['RemoteURL'], 'http://127.0.0.1:8101/'
79
+ assert_equal traces[1]['HTTPMethod'], 'GET'
80
+ assert traces[1].key?('Backtrace')
81
+
82
+ assert_equal traces[5]['Layer'], 'httpclient'
83
+ assert_equal traces[5]['Label'], 'exit'
84
+ assert_equal traces[5]['HTTPStatus'], 200
85
+ end
86
+
87
+ def test_get_with_header_array
88
+ clear_all_traces
89
+
90
+ response = nil
91
+
92
+ AppOpticsAPM::API.start_trace('httpclient_tests') do
93
+ clnt = HTTPClient.new
94
+ response = clnt.get('http://127.0.0.1:8101/', nil, [["Accept", "text/plain"], ["Accept", "text/html"]])
95
+ end
96
+
97
+ traces = get_all_traces
98
+
99
+ xtrace = response.headers['X-Trace']
100
+ assert xtrace
101
+ assert AppOpticsAPM::XTrace.valid?(xtrace)
102
+
103
+ assert_equal traces.count, 7
104
+ assert valid_edges?(traces), "Invalid edge in traces"
105
+ validate_outer_layers(traces, "httpclient_tests")
106
+
107
+ assert_equal traces[1]['IsService'], 1
108
+ assert_equal traces[1]['RemoteURL'], 'http://127.0.0.1:8101/'
109
+ assert_equal traces[1]['HTTPMethod'], 'GET'
110
+ assert traces[1].key?('Backtrace')
111
+
112
+ assert_equal traces[5]['Layer'], 'httpclient'
113
+ assert_equal traces[5]['Label'], 'exit'
114
+ assert_equal traces[5]['HTTPStatus'], 200
115
+ end
116
+
117
+ def test_post_request
118
+ clear_all_traces
119
+
120
+ response = nil
121
+
122
+ AppOpticsAPM::API.start_trace('httpclient_tests') do
123
+ clnt = HTTPClient.new
124
+ response = clnt.post('http://127.0.0.1:8101/')
125
+ end
126
+
127
+ traces = get_all_traces
128
+
129
+ xtrace = response.headers['X-Trace']
130
+ assert xtrace
131
+ assert AppOpticsAPM::XTrace.valid?(xtrace)
132
+
133
+ assert_equal traces.count, 7
134
+ assert valid_edges?(traces), "Invalid edge in traces"
135
+ validate_outer_layers(traces, "httpclient_tests")
136
+
137
+ assert_equal traces[1]['IsService'], 1
138
+ assert_equal traces[1]['RemoteURL'], 'http://127.0.0.1:8101/'
139
+ assert_equal traces[1]['HTTPMethod'], 'POST'
140
+ assert traces[1].key?('Backtrace')
141
+
142
+ assert_equal traces[5]['Layer'], 'httpclient'
143
+ assert_equal traces[5]['Label'], 'exit'
144
+ assert_equal traces[5]['HTTPStatus'], 200
145
+ end
146
+
147
+ def test_async_get
148
+ clear_all_traces
149
+
150
+ conn = nil
151
+
152
+ AppOpticsAPM::API.start_trace('httpclient_tests') do
153
+ clnt = HTTPClient.new
154
+ conn = clnt.get_async('http://127.0.0.1:8101/?blah=1')
155
+ end
156
+
157
+ # Allow async request to finish
158
+ Thread.pass until conn.finished?
159
+
160
+ traces = get_all_traces
161
+
162
+ assert_equal traces.count, 7
163
+ assert valid_edges?(traces), "Invalid edge in traces"
164
+
165
+ # In the case of async the layers are not always ordered the same
166
+ # validate_outer_layers is not applicable, so we make sure we get the pair for 'httpclient_tests'
167
+ assert_equal 2, traces.select { |trace| trace['Layer'] == 'httpclient_tests' }.size
168
+
169
+ # because of possible different ordering of traces we can't rely on an index and need to use find
170
+ async_entry = traces.find { |trace| trace['Layer'] == 'httpclient' && trace['Label'] == 'entry' }
171
+ assert_equal 1, async_entry['Async']
172
+ assert_equal 1, async_entry['IsService']
173
+ assert_equal 'http://127.0.0.1:8101/?blah=1', async_entry['RemoteURL']
174
+ assert_equal 'GET', async_entry['HTTPMethod']
175
+ assert async_entry.key?('Backtrace')
176
+
177
+ assert_equal 'httpclient', traces[6]['Layer']
178
+ assert_equal 'exit', traces[6]['Label']
179
+ assert_equal 200, traces[6]['HTTPStatus']
180
+ end
181
+
182
+ def test_cross_app_tracing
183
+ clear_all_traces
184
+
185
+ response = nil
186
+
187
+ AppOpticsAPM::API.start_trace('httpclient_tests') do
188
+ clnt = HTTPClient.new
189
+ response = clnt.get('http://127.0.0.1:8101/', :query => { :keyword => 'ruby', :lang => 'en' })
190
+ end
191
+
192
+ xtrace = response.headers['X-Trace']
193
+ assert xtrace
194
+ assert AppOpticsAPM::XTrace.valid?(xtrace)
195
+
196
+ traces = get_all_traces
197
+
198
+ assert_equal traces.count, 7
199
+ assert valid_edges?(traces), "Invalid edge in traces"
200
+ validate_outer_layers(traces, "httpclient_tests")
201
+
202
+ assert_equal 1, traces[1]['IsService']
203
+ assert_equal 'http://127.0.0.1:8101/?keyword=ruby&lang=en', traces[1]['RemoteURL']
204
+ assert_equal 'GET', traces[1]['HTTPMethod']
205
+ assert traces[1].key?('Backtrace')
206
+
207
+ assert_equal 'rack', traces[2]['Layer']
208
+ assert_equal 'entry', traces[2]['Label']
209
+ assert_equal 'rack', traces[3]['Layer']
210
+ assert_equal 'info', traces[3]['Label']
211
+ assert_equal 'rack', traces[4]['Layer']
212
+ assert_equal 'exit', traces[4]['Label']
213
+
214
+ assert_equal 'httpclient', traces[5]['Layer']
215
+ assert_equal 'exit', traces[5]['Label']
216
+ assert_equal 200, traces[5]['HTTPStatus']
217
+ end
218
+
219
+ def test_requests_with_errors
220
+ clear_all_traces
221
+
222
+ result = nil
223
+ begin
224
+ AppOpticsAPM::API.start_trace('httpclient_tests') do
225
+ clnt = HTTPClient.new
226
+ result = clnt.get('http://asfjalkfjlajfljkaljf/')
227
+ end
228
+ rescue
229
+ end
230
+
231
+ traces = get_all_traces
232
+ assert_equal 5, traces.count
233
+ assert valid_edges?(traces), "Invalid edge in traces"
234
+ validate_outer_layers(traces, "httpclient_tests")
235
+
236
+ assert_equal 1, traces[1]['IsService']
237
+ assert_equal 'http://asfjalkfjlajfljkaljf/', traces[1]['RemoteURL']
238
+ assert_equal 'GET', traces[1]['HTTPMethod']
239
+ assert traces[1].key?('Backtrace')
240
+
241
+ assert_equal 'httpclient', traces[2]['Layer']
242
+ assert_equal 'error', traces[2]['Label']
243
+ assert_equal "SocketError", traces[2]['ErrorClass']
244
+ assert traces[2].key?('ErrorMsg')
245
+ assert traces[2].key?('Backtrace')
246
+
247
+ assert_equal 'httpclient', traces[3]['Layer']
248
+ assert_equal 'exit', traces[3]['Label']
249
+ end
250
+
251
+ def test_log_args_when_true
252
+ clear_all_traces
253
+
254
+ @log_args = AppOpticsAPM::Config[:httpclient][:log_args]
255
+ AppOpticsAPM::Config[:httpclient][:log_args] = true
256
+
257
+ response = nil
258
+
259
+ AppOpticsAPM::API.start_trace('httpclient_tests') do
260
+ clnt = HTTPClient.new
261
+ response = clnt.get('http://127.0.0.1:8101/', :query => { :keyword => 'ruby', :lang => 'en' })
262
+ end
263
+
264
+ traces = get_all_traces
265
+
266
+ xtrace = response.headers['X-Trace']
267
+ assert xtrace
268
+ assert AppOpticsAPM::XTrace.valid?(xtrace)
269
+
270
+ assert_equal 7, traces.count
271
+ assert valid_edges?(traces), "Invalid edge in traces"
272
+
273
+ assert_equal 'http://127.0.0.1:8101/?keyword=ruby&lang=en', traces[1]['RemoteURL']
274
+
275
+ AppOpticsAPM::Config[:httpclient][:log_args] = @log_args
276
+ end
277
+
278
+ def test_log_args_when_false
279
+ clear_all_traces
280
+
281
+ @log_args = AppOpticsAPM::Config[:httpclient][:log_args]
282
+ AppOpticsAPM::Config[:httpclient][:log_args] = false
283
+
284
+ response = nil
285
+
286
+ AppOpticsAPM::API.start_trace('httpclient_tests') do
287
+ clnt = HTTPClient.new
288
+ response = clnt.get('http://127.0.0.1:8101/', :query => { :keyword => 'ruby', :lang => 'en' })
289
+ end
290
+
291
+ traces = get_all_traces
292
+
293
+ xtrace = response.headers['X-Trace']
294
+ assert xtrace
295
+ assert AppOpticsAPM::XTrace.valid?(xtrace)
296
+
297
+ assert_equal 7, traces.count
298
+ assert valid_edges?(traces), "Invalid edge in traces"
299
+
300
+ assert_equal 'http://127.0.0.1:8101/', traces[1]['RemoteURL']
301
+
302
+ AppOpticsAPM::Config[:httpclient][:log_args] = @log_args
303
+ end
304
+
305
+ def test_without_tracing
306
+ clear_all_traces
307
+
308
+ clnt = HTTPClient.new
309
+ clnt.get('http://127.0.0.1:8101/', :query => { :keyword => 'ruby', :lang => 'en' })
310
+
311
+ traces = get_all_traces
312
+ # we only get traces from rack
313
+ assert_equal 3, traces.count
314
+ traces.each do |trace|
315
+ assert_equal 'rack', trace["Layer"]
316
+ end
317
+
318
+ end
319
+ end
320
+ end