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,80 @@
1
+ # This test Padrino stack file was taken from the padrino-core gem.
2
+ #
3
+ PADRINO_ROOT = File.dirname(__FILE__) unless defined? PADRINO_ROOT
4
+ # Remove this comment if you want do some like this: ruby PADRINO_ENV=test app.rb
5
+ #
6
+ # require 'rubygems'
7
+ # require 'padrino-core'
8
+ #
9
+
10
+ class SimpleDemo < Padrino::Application
11
+ set :public_folder, File.dirname(__FILE__)
12
+ set :reload, false
13
+ before { true }
14
+ after { true }
15
+ error(404) { "404" }
16
+ end
17
+
18
+ SimpleDemo.controllers do
19
+ get "/" do
20
+ 'The magick number is: 2767356926488785838763860464013972991031534522105386787489885890443740254365!' # Change only the number!!!
21
+ end
22
+
23
+ get "/rand" do
24
+ rand(2 ** 256).to_s
25
+ end
26
+
27
+ get "/render" do
28
+ render :erb, "This is an erb render"
29
+ end
30
+
31
+ get "/render/:id" do
32
+ render :erb, "The Id is #{params[:id]}"
33
+ end
34
+
35
+ get "/render/:id/what" do
36
+ render :erb, "WOOT is #{params[:id]}"
37
+ end
38
+
39
+ get :symbol_route do
40
+ render :erb, "This is an erb render"
41
+ end
42
+
43
+ get :symbol_route, :with => :id do
44
+ render :erb, "The Id is #{params[:id]}"
45
+ end
46
+
47
+ get "/break" do
48
+ raise "This is a controller exception!"
49
+ end
50
+
51
+ get "/error" do
52
+ status 500
53
+ render :erb, "broken"
54
+ end
55
+ end
56
+
57
+ SimpleDemo.controllers :product, :parent => :user do
58
+ get :index do
59
+ # url is generated as "/user/#{params[:user_id]}/product"
60
+ # url_for(:product, :index, :user_id => 5) => "/user/5/product"
61
+ render :erb, "The user id is #{params[:user_id]}"
62
+ end
63
+
64
+ get :show, :with => :id do
65
+ # url is generated as "/user/#{params[:user_id]}/product/show/#{params[:id]}"
66
+ # url_for(:product, :show, :user_id => 5, :id => 10) => "/user/5/product/show/10"
67
+ render :erb, "Ids: #{params[:user_id]}, #{params[:id]}"
68
+ end
69
+ end
70
+
71
+ ## If you want use this as a standalone app uncomment:
72
+ #
73
+ # Padrino.mount("SimpleDemo").to("/")
74
+ # Padrino.run! unless Padrino.loaded? # If you enable reloader prevent to re-run the app
75
+ #
76
+ # Then run it from your console: ruby -I"lib" test/fixtures/apps/simple.rb
77
+ #
78
+
79
+ Padrino.load!
80
+
@@ -0,0 +1,55 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ require 'sinatra'
5
+
6
+ class SinatraSimple < Sinatra::Base
7
+ set :reload, true
8
+
9
+ template :layout do
10
+ # Use both the legacy and new RUM helper
11
+ # oboe_rum_header + appoptics_rum_footer
12
+ # These should be no-op methods now.
13
+ %q{
14
+ <html>
15
+ <head></head>
16
+ <body>
17
+ <%= yield %>
18
+ </body>
19
+ </html>}
20
+ end
21
+
22
+ get "/" do
23
+ 'The magick number is: 2767356926488785838763860464013972991031534522105386787489885890443740254365!' # Change only the number!!!
24
+ end
25
+
26
+ get "/rand" do
27
+ rand(2 ** 256).to_s
28
+ end
29
+
30
+ get "/render" do
31
+ render :erb, "This is an erb render"
32
+ end
33
+
34
+ get "/render/:id" do
35
+ render :erb, "The id is #{ params['id'] }"
36
+ end
37
+
38
+ get "/render/:id/what" do |id|
39
+ render :erb, "WOOT! The id is #{id} }"
40
+ end
41
+
42
+ get '/say/*/to/*' do
43
+ render :erb, "#{params['splat'][0]} #{params['splat'][1]}"
44
+ end
45
+
46
+ get /\/hello\/([\w]+)/ do
47
+ render :erb, "Hello, #{params['captures'].first}!"
48
+ end
49
+
50
+ get "/break" do
51
+ raise "This is a controller exception!"
52
+ end
53
+ end
54
+
55
+ use SinatraSimple
@@ -0,0 +1,286 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ require 'minitest_helper'
5
+ require 'mocha/mini_test'
6
+
7
+ if RUBY_VERSION >= '1.9.3' and defined?(::Grape)
8
+ require File.expand_path(File.dirname(__FILE__) + '/apps/grape_simple')
9
+ require File.expand_path(File.dirname(__FILE__) + '/apps/grape_nested')
10
+
11
+ describe Grape do
12
+ before do
13
+ clear_all_traces
14
+ end
15
+
16
+ it "should trace a request to a simple grape stack" do
17
+ @app = GrapeSimple
18
+
19
+ r = get "/json_endpoint"
20
+
21
+ r.status.must_equal 200
22
+ r.headers.key?('X-Trace').must_equal true
23
+
24
+ traces = get_all_traces
25
+ traces.count.must_equal 5
26
+
27
+ validate_outer_layers(traces, 'rack')
28
+
29
+ traces[2]['Layer'].must_equal "grape"
30
+ traces[3]['Layer'].must_equal "grape"
31
+ traces[2].has_key?('Controller').must_equal true
32
+ traces[2].has_key?('Action').must_equal true
33
+ traces[4]['Label'].must_equal "exit"
34
+
35
+ # Validate the existence of the response header
36
+ r.headers.key?('X-Trace').must_equal true
37
+ r.headers['X-Trace'].must_equal traces[4]['X-Trace']
38
+ end
39
+
40
+ it "should trace a request to a nested grape stack" do
41
+ @app = GrapeNested
42
+
43
+ r = get "/json_endpoint"
44
+
45
+ r.status.must_equal 200
46
+ r.headers.key?('X-Trace').must_equal true
47
+
48
+ traces = get_all_traces
49
+ traces.count.must_equal 5
50
+
51
+ validate_outer_layers(traces, 'rack')
52
+
53
+ traces[2]['Layer'].must_equal "grape"
54
+ traces[3]['Layer'].must_equal "grape"
55
+ traces[2].has_key?('Controller').must_equal true
56
+ traces[2].has_key?('Action').must_equal true
57
+ traces[4]['Label'].must_equal "exit"
58
+
59
+ # Validate the existence of the response header
60
+ r.headers.key?('X-Trace').must_equal true
61
+ r.headers['X-Trace'].must_equal traces[4]['X-Trace']
62
+ end
63
+
64
+ it "should trace a an error in a nested grape stack" do
65
+ @app = GrapeNested
66
+
67
+ r = get "/error"
68
+
69
+ r.status.must_equal 500
70
+ r.headers.key?('X-Trace').must_equal true
71
+
72
+ traces = get_all_traces
73
+ traces.count.must_equal 6
74
+
75
+ validate_outer_layers(traces, 'rack')
76
+
77
+ traces[2]['Layer'].must_equal "grape"
78
+ traces[2]['Label'].must_equal "entry"
79
+ traces[3]['Layer'].must_equal "grape"
80
+ traces[3]['Label'].must_equal "exit"
81
+ traces[2].has_key?('Controller').must_equal true
82
+ traces[2].has_key?('Action').must_equal true
83
+ traces[4]['Label'].must_equal "error"
84
+ traces[4]['ErrorClass'].must_equal "GrapeError"
85
+ traces[4]['ErrorMsg'].must_equal "This is a error with 'error'!"
86
+ traces[4].has_key?('Backtrace').must_equal true
87
+ traces[5]['Layer'].must_equal "rack"
88
+ traces[5]['Label'].must_equal "exit"
89
+
90
+ # Validate the existence of the response header
91
+ r.headers.key?('X-Trace').must_equal true
92
+ r.headers['X-Trace'].must_equal traces[5]['X-Trace']
93
+ end
94
+
95
+
96
+ it "should trace a request with an exception" do
97
+ @app = GrapeSimple
98
+
99
+ begin
100
+ get "/break"
101
+ rescue Exception
102
+ # Do not handle/raise this error so
103
+ # we can continue to test
104
+ end
105
+
106
+ traces = get_all_traces
107
+ traces.count.must_equal 6
108
+
109
+ validate_outer_layers(traces, 'rack')
110
+
111
+ traces[2]['Layer'].must_equal "grape"
112
+ traces[3]['Layer'].must_equal "grape"
113
+ traces[2].has_key?('Controller').must_equal true
114
+ traces[2].has_key?('Action').must_equal true
115
+ traces[4]['Label'].must_equal "error"
116
+ traces[4]['ErrorClass'].must_equal "Exception"
117
+ traces[4]['ErrorMsg'].must_equal "This should have http status code 500!"
118
+ traces[5]['Label'].must_equal "exit"
119
+ end
120
+
121
+ it "should trace a request with an error" do
122
+ @app = GrapeSimple
123
+
124
+ r = get "/error"
125
+
126
+ traces = get_all_traces
127
+ traces.count.must_equal 6
128
+
129
+ r.status.must_equal 500
130
+ r.headers.key?('X-Trace').must_equal true
131
+
132
+ validate_outer_layers(traces, 'rack')
133
+
134
+ traces[0]['Layer'].must_equal "rack"
135
+ traces[2]['Layer'].must_equal "grape"
136
+ traces[3]['Layer'].must_equal "grape"
137
+ traces[2].has_key?('Controller').must_equal true
138
+ traces[2].has_key?('Action').must_equal true
139
+ traces[4]['Label'].must_equal "error"
140
+ traces[4]['ErrorClass'].must_equal "GrapeError"
141
+ traces[4]['ErrorMsg'].must_equal "This is an error with 'error'!"
142
+ traces[5]['Layer'].must_equal "rack"
143
+ traces[5]['Label'].must_equal "exit"
144
+ traces[5]['Status'].must_equal 500
145
+ end
146
+
147
+ it "should report a simple GET path" do
148
+ @app = GrapeSimple
149
+ test_action, test_url, test_status, test_method, test_error = nil, nil, nil, nil, nil
150
+ AppOpticsAPM::Span.expects(:createHttpSpan).with do |action, url, _duration, status, method, error|
151
+ test_action = action
152
+ test_url = url
153
+ test_status = status
154
+ test_method = method
155
+ test_error = error
156
+ end.once
157
+
158
+ get "/employee_data"
159
+
160
+ assert_equal "GrapeSimple./employee_data", test_action
161
+ assert_equal "http://example.org/employee_data", test_url
162
+ assert_equal 200, test_status
163
+ assert_equal "GET", test_method
164
+ assert_equal 0, test_error
165
+
166
+ assert_controller_action(test_action)
167
+ end
168
+
169
+ it "should report a GET path with parameter" do
170
+ @app = GrapeSimple
171
+ test_action, test_url, test_status, test_method, test_error = nil, nil, nil, nil, nil
172
+ AppOpticsAPM::Span.expects(:createHttpSpan).with do |action, url, _duration, status, method, error|
173
+ test_action = action
174
+ test_url = url
175
+ test_status = status
176
+ test_method = method
177
+ test_error = error
178
+ end.once
179
+
180
+ get "/employee_data/12"
181
+
182
+ assert_equal "GrapeSimple./employee_data/:id", test_action
183
+ assert_equal "http://example.org/employee_data/12", test_url
184
+ assert_equal 200, test_status
185
+ assert_equal "GET", test_method
186
+ assert_equal 0, test_error
187
+
188
+ assert_controller_action(test_action)
189
+ end
190
+
191
+ it "should report a POST path" do
192
+ @app = GrapeSimple
193
+ test_action, test_url, test_status, test_method, test_error = nil, nil, nil, nil, nil
194
+ AppOpticsAPM::Span.expects(:createHttpSpan).with do |action, url, _duration, status, method, error|
195
+ test_action = action
196
+ test_url = url
197
+ test_status = status
198
+ test_method = method
199
+ test_error = error
200
+ end.once
201
+
202
+ data = {
203
+ :name => 'Tom',
204
+ :address => 'Street',
205
+ :age => 66
206
+ }
207
+
208
+ post '/employee_data', data
209
+
210
+ assert_equal "GrapeSimple./employee_data", test_action
211
+ assert_equal "http://example.org/employee_data", test_url
212
+ assert_equal 201, test_status
213
+ assert_equal "POST", test_method
214
+ assert_equal 0, test_error
215
+
216
+ assert_controller_action(test_action)
217
+ end
218
+
219
+ it "should report a PUT path" do
220
+ @app = GrapeSimple
221
+ test_action, test_url, test_status, test_method, test_error = nil, nil, nil, nil, nil
222
+ AppOpticsAPM::Span.expects(:createHttpSpan).with do |action, url, _duration, status, method, error|
223
+ test_action = action
224
+ test_url = url
225
+ test_status = status
226
+ test_method = method
227
+ test_error = error
228
+ end.once
229
+
230
+ put "/employee_data/12", { :address => 'Other Street' }
231
+
232
+ assert_equal "GrapeSimple./employee_data/:id", test_action
233
+ assert_equal "http://example.org/employee_data/12", test_url
234
+ assert_equal 200, test_status
235
+ assert_equal "PUT", test_method
236
+ assert_equal 0, test_error
237
+
238
+ assert_controller_action(test_action)
239
+ end
240
+
241
+ it "should report a DELETE path" do
242
+ @app = GrapeSimple
243
+ test_action, test_url, test_status, test_method, test_error = nil, nil, nil, nil, nil
244
+ AppOpticsAPM::Span.expects(:createHttpSpan).with do |action, url, _duration, status, method, error|
245
+ test_action = action
246
+ test_url = url
247
+ test_status = status
248
+ test_method = method
249
+ test_error = error
250
+ end.once
251
+
252
+ delete "/employee_data/12"
253
+
254
+ assert_equal "GrapeSimple./employee_data/:id", test_action
255
+ assert_equal "http://example.org/employee_data/12", test_url
256
+ assert_equal 200, test_status
257
+ assert_equal "DELETE", test_method
258
+ assert_equal 0, test_error
259
+
260
+ assert_controller_action(test_action)
261
+ end
262
+
263
+ it "should report a nested GET path with parameters" do
264
+ @app = GrapeSimple
265
+ test_action, test_url, test_status, test_method, test_error = nil, nil, nil, nil, nil
266
+ AppOpticsAPM::Span.expects(:createHttpSpan).with do |action, url, _duration, status, method, error|
267
+ test_action = action
268
+ test_url = url
269
+ test_status = status
270
+ test_method = method
271
+ test_error = error
272
+ end.once
273
+
274
+ get "/employee_data/12/nested/34"
275
+
276
+ assert_equal "GrapeSimple./employee_data/:id/nested/:child", test_action
277
+ assert_equal "http://example.org/employee_data/12/nested/34", test_url
278
+ assert_equal 200, test_status
279
+ assert_equal "GET", test_method
280
+ assert_equal 0, test_error
281
+
282
+ assert_controller_action(test_action)
283
+ end
284
+
285
+ end
286
+ end
@@ -0,0 +1,222 @@
1
+ # Copyright (c) 2016 SolarWinds, LLC.
2
+ # All rights reserved.
3
+
4
+ require "minitest_helper"
5
+ require "mocha/mini_test"
6
+
7
+ if RUBY_VERSION >= '1.9.3' and defined?(::Padrino)
8
+ require File.expand_path(File.dirname(__FILE__) + '/apps/padrino_simple')
9
+
10
+ describe Padrino do
11
+ before do
12
+ clear_all_traces
13
+ end
14
+
15
+ it "should trace a request to a simple padrino stack" do
16
+ @app = SimpleDemo
17
+
18
+ r = get "/render"
19
+
20
+ traces = get_all_traces
21
+
22
+ traces.count.must_equal 9
23
+ valid_edges?(traces).must_equal true
24
+ validate_outer_layers(traces, 'rack')
25
+
26
+ traces[2]['Layer'].must_equal "padrino"
27
+ traces[7]['Controller'].must_equal "SimpleDemo"
28
+ traces[8]['Label'].must_equal "exit"
29
+
30
+ # Validate the existence of the response header
31
+ r.headers.key?('X-Trace').must_equal true
32
+ r.headers['X-Trace'].must_equal traces[8]['X-Trace']
33
+ end
34
+
35
+ it "should report controller.action" do
36
+ @app = SimpleDemo
37
+ test_action, test_url, test_status, test_method, test_error = nil, nil, nil, nil, nil
38
+ AppOpticsAPM::Span.expects(:createHttpSpan).with do |action, url, _duration, status, method, error|
39
+ test_action = action
40
+ test_url = url
41
+ test_status = status
42
+ test_method = method
43
+ test_error = error
44
+ end.once
45
+
46
+ get "/render"
47
+
48
+ assert_equal "SimpleDemo./render", test_action
49
+ assert_equal "http://example.org/render", test_url
50
+ assert_equal 200, test_status
51
+ assert_equal "GET", test_method
52
+ assert_equal 0, test_error
53
+
54
+ assert_controller_action(test_action)
55
+ end
56
+
57
+ it "should report controller.action for a symbol route" do
58
+ @app = SimpleDemo
59
+ test_action, test_url, test_status, test_method, test_error = nil, nil, nil, nil, nil
60
+ AppOpticsAPM::Span.expects(:createHttpSpan).with do |action, url, _duration, status, method, error|
61
+ test_action = action
62
+ test_url = url
63
+ test_status = status
64
+ test_method = method
65
+ test_error = error
66
+ end.once
67
+
68
+ get "/symbol_route"
69
+
70
+ assert_equal "SimpleDemo./symbol_route", test_action
71
+ assert_equal "http://example.org/symbol_route", test_url
72
+ assert_equal 200, test_status
73
+ assert_equal "GET", test_method
74
+ assert_equal 0, test_error
75
+
76
+ assert_controller_action(test_action)
77
+ end
78
+
79
+ it "should report controller.action with :id" do
80
+ @app = SimpleDemo
81
+ test_action, test_url, test_status, test_method, test_error = nil, nil, nil, nil, nil
82
+ AppOpticsAPM::Span.expects(:createHttpSpan).with do |action, url, _duration, status, method, error|
83
+ test_action = action
84
+ test_url = url
85
+ test_status = status
86
+ test_method = method
87
+ test_error = error
88
+ end.once
89
+
90
+ r = get "/render/1234567890"
91
+
92
+ r.body.must_match /1234567890/
93
+
94
+ assert_equal "SimpleDemo./render/:id", test_action
95
+ assert_equal "http://example.org/render/1234567890", test_url
96
+ assert_equal 200, test_status
97
+ assert_equal "GET", test_method
98
+ assert_equal 0, test_error
99
+
100
+ assert_controller_action(test_action)
101
+ end
102
+
103
+ it "should report controller.action for a symbol route with :id" do
104
+ @app = SimpleDemo
105
+ test_action, test_url, test_status, test_method, test_error = nil, nil, nil, nil, nil
106
+ AppOpticsAPM::Span.expects(:createHttpSpan).with do |action, url, _duration, status, method, error|
107
+ test_action = action
108
+ test_url = url
109
+ test_status = status
110
+ test_method = method
111
+ test_error = error
112
+ end.once
113
+
114
+ r = get "/symbol_route/1234567890"
115
+
116
+ r.body.must_match /1234567890/
117
+
118
+ assert_equal "SimpleDemo./symbol_route/:id", test_action
119
+ assert_equal "http://example.org/symbol_route/1234567890", test_url
120
+ assert_equal 200, test_status
121
+ assert_equal "GET", test_method
122
+ assert_equal 0, test_error
123
+
124
+ assert_controller_action(test_action)
125
+ end
126
+
127
+ it "should report controller.action with :id and more" do
128
+ @app = SimpleDemo
129
+ test_action, test_url, test_status, test_method, test_error = nil, nil, nil, nil, nil
130
+ AppOpticsAPM::Span.expects(:createHttpSpan).with do |action, url, _duration, status, method, error|
131
+ test_action = action
132
+ test_url = url
133
+ test_status = status
134
+ test_method = method
135
+ test_error = error
136
+ end.once
137
+
138
+ r = get "/render/1234567890/what"
139
+
140
+ r.body.must_match /WOOT is 1234567890/
141
+
142
+ assert_equal "SimpleDemo./render/:id/what", test_action
143
+ assert_equal "http://example.org/render/1234567890/what", test_url
144
+ assert_equal 200, test_status
145
+ assert_equal "GET", test_method
146
+ assert_equal 0, test_error
147
+
148
+ assert_controller_action(test_action)
149
+ end
150
+
151
+ it "should report an error" do
152
+ @app = SimpleDemo
153
+ test_action, test_url, test_status, test_method, test_error = nil, nil, nil, nil, nil
154
+ AppOpticsAPM::Span.expects(:createHttpSpan).with do |action, url, _duration, status, method, error|
155
+ test_action = action
156
+ test_url = url
157
+ test_status = status
158
+ test_method = method
159
+ test_error = error
160
+ end.once
161
+
162
+ get "/error"
163
+
164
+ assert_equal "SimpleDemo./error", test_action
165
+ assert_equal "http://example.org/error", test_url
166
+ assert_equal 500, test_status
167
+ assert_equal "GET", test_method
168
+ assert_equal 1, test_error
169
+
170
+ assert_controller_action(test_action)
171
+ end
172
+
173
+ it "should correctly report nested routes" do
174
+ @app = SimpleDemo
175
+ test_action, test_url, test_status, test_method, test_error = nil, nil, nil, nil, nil
176
+ AppOpticsAPM::Span.expects(:createHttpSpan).with do |action, url, _duration, status, method, error|
177
+ test_action = action
178
+ test_url = url
179
+ test_status = status
180
+ test_method = method
181
+ test_error = error
182
+ end.once
183
+
184
+ r = get "/user/12345/product"
185
+
186
+ r.body.must_match /12345/
187
+
188
+ assert_equal "product./user/:user_id/product", test_action
189
+ assert_equal "http://example.org/user/12345/product", test_url
190
+ assert_equal 200, test_status
191
+ assert_equal "GET", test_method
192
+ assert_equal 0, test_error
193
+
194
+ assert_controller_action(test_action)
195
+ end
196
+
197
+ it "should correctly report nested routes with param" do
198
+ @app = SimpleDemo
199
+ test_action, test_url, test_status, test_method, test_error = nil, nil, nil, nil, nil
200
+ AppOpticsAPM::Span.expects(:createHttpSpan).with do |action, url, _duration, status, method, error|
201
+ test_action = action
202
+ test_url = url
203
+ test_status = status
204
+ test_method = method
205
+ test_error = error
206
+ end.once
207
+
208
+ r = get "/user/12345/product/show/101010"
209
+
210
+ r.body.must_match /12345/
211
+ r.body.must_match /101010/
212
+
213
+ assert_equal "product./user/:user_id/product/show/:id", test_action
214
+ assert_equal "http://example.org/user/12345/product/show/101010", test_url
215
+ assert_equal 200, test_status
216
+ assert_equal "GET", test_method
217
+ assert_equal 0, test_error
218
+
219
+ assert_controller_action(test_action)
220
+ end
221
+ end
222
+ end