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.
- checksums.yaml +7 -0
- data/.codeclimate.yml +43 -0
- data/.dockerignore +5 -0
- data/.gitignore +23 -0
- data/.rubocop.yml +5 -0
- data/.travis.yml +82 -0
- data/CHANGELOG.md +769 -0
- data/CONFIG.md +33 -0
- data/Dockerfile +41 -0
- data/Dockerfile_test +66 -0
- data/Gemfile +41 -0
- data/LICENSE +193 -0
- data/README.md +351 -0
- data/Rakefile +202 -0
- data/Vagrantfile +67 -0
- data/appoptics_apm.gemspec +55 -0
- data/build_gems.sh +15 -0
- data/docker-compose.yml +73 -0
- data/examples/DNT.md +35 -0
- data/examples/carrying_context.rb +220 -0
- data/examples/instrumenting_metal_controller.rb +8 -0
- data/examples/puma_on_heroku_config.rb +17 -0
- data/examples/tracing_async_threads.rb +124 -0
- data/examples/tracing_background_jobs.rb +53 -0
- data/examples/tracing_forked_processes.rb +99 -0
- data/examples/unicorn_on_heroku_config.rb +28 -0
- data/ext/oboe_metal/extconf.rb +54 -0
- data/ext/oboe_metal/lib/.keep +0 -0
- data/ext/oboe_metal/lib/liboboe-1.0.so.0.0.0 +0 -0
- data/ext/oboe_metal/noop/noop.c +7 -0
- data/ext/oboe_metal/src/VERSION +1 -0
- data/ext/oboe_metal/src/bson/bson.h +221 -0
- data/ext/oboe_metal/src/bson/platform_hacks.h +91 -0
- data/ext/oboe_metal/src/oboe.h +883 -0
- data/ext/oboe_metal/src/oboe.hpp +793 -0
- data/ext/oboe_metal/src/oboe_debug.h +50 -0
- data/ext/oboe_metal/src/oboe_wrap.cxx +6088 -0
- data/ext/oboe_metal/tests/test.rb +11 -0
- data/gemfiles/delayed_job.gemfile +36 -0
- data/gemfiles/frameworks.gemfile +44 -0
- data/gemfiles/instrumentation_mocked.gemfile +29 -0
- data/gemfiles/libraries.gemfile +85 -0
- data/gemfiles/rails23.gemfile +39 -0
- data/gemfiles/rails30.gemfile +42 -0
- data/gemfiles/rails31.gemfile +44 -0
- data/gemfiles/rails32.gemfile +54 -0
- data/gemfiles/rails40.gemfile +27 -0
- data/gemfiles/rails41.gemfile +27 -0
- data/gemfiles/rails42.gemfile +35 -0
- data/gemfiles/rails50.gemfile +44 -0
- data/gemfiles/rails51.gemfile +44 -0
- data/get_version.rb +5 -0
- data/init.rb +4 -0
- data/lib/appoptics_apm/api/layerinit.rb +39 -0
- data/lib/appoptics_apm/api/logging.rb +359 -0
- data/lib/appoptics_apm/api/memcache.rb +34 -0
- data/lib/appoptics_apm/api/profiling.rb +201 -0
- data/lib/appoptics_apm/api/tracing.rb +152 -0
- data/lib/appoptics_apm/api/util.rb +128 -0
- data/lib/appoptics_apm/api.rb +18 -0
- data/lib/appoptics_apm/base.rb +252 -0
- data/lib/appoptics_apm/config.rb +281 -0
- data/lib/appoptics_apm/frameworks/grape.rb +93 -0
- data/lib/appoptics_apm/frameworks/padrino/templates.rb +58 -0
- data/lib/appoptics_apm/frameworks/padrino.rb +52 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller.rb +106 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller2.rb +61 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller3.rb +58 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller4.rb +48 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller5.rb +50 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_controller_api.rb +50 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_view.rb +58 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_view_2x.rb +56 -0
- data/lib/appoptics_apm/frameworks/rails/inst/action_view_30.rb +50 -0
- data/lib/appoptics_apm/frameworks/rails/inst/active_record.rb +27 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/mysql.rb +43 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/mysql2.rb +28 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/postgresql.rb +30 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils.rb +120 -0
- data/lib/appoptics_apm/frameworks/rails/inst/connection_adapters/utils5x.rb +101 -0
- data/lib/appoptics_apm/frameworks/rails.rb +116 -0
- data/lib/appoptics_apm/frameworks/sinatra/templates.rb +56 -0
- data/lib/appoptics_apm/frameworks/sinatra.rb +71 -0
- data/lib/appoptics_apm/inst/bunny-client.rb +148 -0
- data/lib/appoptics_apm/inst/bunny-consumer.rb +92 -0
- data/lib/appoptics_apm/inst/curb.rb +329 -0
- data/lib/appoptics_apm/inst/dalli.rb +85 -0
- data/lib/appoptics_apm/inst/delayed_job.rb +92 -0
- data/lib/appoptics_apm/inst/em-http-request.rb +105 -0
- data/lib/appoptics_apm/inst/excon.rb +130 -0
- data/lib/appoptics_apm/inst/faraday.rb +77 -0
- data/lib/appoptics_apm/inst/http.rb +83 -0
- data/lib/appoptics_apm/inst/httpclient.rb +176 -0
- data/lib/appoptics_apm/inst/memcache.rb +102 -0
- data/lib/appoptics_apm/inst/memcached.rb +94 -0
- data/lib/appoptics_apm/inst/mongo.rb +242 -0
- data/lib/appoptics_apm/inst/mongo2.rb +225 -0
- data/lib/appoptics_apm/inst/moped.rb +466 -0
- data/lib/appoptics_apm/inst/rack.rb +146 -0
- data/lib/appoptics_apm/inst/redis.rb +275 -0
- data/lib/appoptics_apm/inst/resque.rb +151 -0
- data/lib/appoptics_apm/inst/rest-client.rb +50 -0
- data/lib/appoptics_apm/inst/sequel.rb +178 -0
- data/lib/appoptics_apm/inst/sidekiq-client.rb +53 -0
- data/lib/appoptics_apm/inst/sidekiq-worker.rb +67 -0
- data/lib/appoptics_apm/inst/twitter-cassandra.rb +294 -0
- data/lib/appoptics_apm/inst/typhoeus.rb +113 -0
- data/lib/appoptics_apm/instrumentation.rb +22 -0
- data/lib/appoptics_apm/legacy_method_profiling.rb +97 -0
- data/lib/appoptics_apm/loading.rb +66 -0
- data/lib/appoptics_apm/logger.rb +41 -0
- data/lib/appoptics_apm/method_profiling.rb +33 -0
- data/lib/appoptics_apm/ruby.rb +35 -0
- data/lib/appoptics_apm/support.rb +135 -0
- data/lib/appoptics_apm/test.rb +94 -0
- data/lib/appoptics_apm/thread_local.rb +26 -0
- data/lib/appoptics_apm/util.rb +312 -0
- data/lib/appoptics_apm/version.rb +15 -0
- data/lib/appoptics_apm/xtrace.rb +103 -0
- data/lib/appoptics_apm.rb +72 -0
- data/lib/joboe_metal.rb +214 -0
- data/lib/oboe/README +2 -0
- data/lib/oboe/backward_compatibility.rb +80 -0
- data/lib/oboe/inst/rack.rb +11 -0
- data/lib/oboe.rb +7 -0
- data/lib/oboe_metal.rb +187 -0
- data/lib/rails/generators/appoptics_apm/install_generator.rb +45 -0
- data/lib/rails/generators/appoptics_apm/templates/appoptics_apm_initializer.rb +222 -0
- data/ruby_setup.sh +47 -0
- data/run_docker_build_gem_upload_to_packagecloud.sh +20 -0
- data/run_tests_docker.rb +32 -0
- data/test/benchmark/README.md +65 -0
- data/test/benchmark/logging_bench.rb +54 -0
- data/test/benchmark/with_libraries_gemfile/bunny_bench.rb +69 -0
- data/test/benchmark/with_rails5x_gemfile/action_controller5x_bench.rb +43 -0
- data/test/frameworks/apps/grape_nested.rb +33 -0
- data/test/frameworks/apps/grape_simple.rb +80 -0
- data/test/frameworks/apps/padrino_simple.rb +80 -0
- data/test/frameworks/apps/sinatra_simple.rb +55 -0
- data/test/frameworks/grape_test.rb +286 -0
- data/test/frameworks/padrino_test.rb +222 -0
- data/test/frameworks/rails3x_test.rb +554 -0
- data/test/frameworks/rails4x_test.rb +570 -0
- data/test/frameworks/rails5x_api_test.rb +210 -0
- data/test/frameworks/rails5x_test.rb +376 -0
- data/test/frameworks/rails_shared_tests.rb +172 -0
- data/test/frameworks/sinatra_test.rb +140 -0
- data/test/instrumentation/bunny_client_test.rb +276 -0
- data/test/instrumentation/bunny_consumer_test.rb +204 -0
- data/test/instrumentation/curb_test.rb +398 -0
- data/test/instrumentation/dalli_test.rb +177 -0
- data/test/instrumentation/em_http_request_test.rb +89 -0
- data/test/instrumentation/excon_test.rb +231 -0
- data/test/instrumentation/faraday_test.rb +228 -0
- data/test/instrumentation/http_test.rb +143 -0
- data/test/instrumentation/httpclient_test.rb +320 -0
- data/test/instrumentation/memcache_test.rb +260 -0
- data/test/instrumentation/memcached_test.rb +229 -0
- data/test/instrumentation/mongo_v1_test.rb +479 -0
- data/test/instrumentation/mongo_v2_index_test.rb +124 -0
- data/test/instrumentation/mongo_v2_test.rb +584 -0
- data/test/instrumentation/mongo_v2_view_test.rb +435 -0
- data/test/instrumentation/moped_test.rb +517 -0
- data/test/instrumentation/rack_test.rb +165 -0
- data/test/instrumentation/redis_hashes_test.rb +268 -0
- data/test/instrumentation/redis_keys_test.rb +321 -0
- data/test/instrumentation/redis_lists_test.rb +310 -0
- data/test/instrumentation/redis_misc_test.rb +163 -0
- data/test/instrumentation/redis_sets_test.rb +296 -0
- data/test/instrumentation/redis_sortedsets_test.rb +328 -0
- data/test/instrumentation/redis_strings_test.rb +349 -0
- data/test/instrumentation/resque_test.rb +185 -0
- data/test/instrumentation/rest-client_test.rb +288 -0
- data/test/instrumentation/sequel_mysql2_test.rb +353 -0
- data/test/instrumentation/sequel_mysql_test.rb +334 -0
- data/test/instrumentation/sequel_pg_test.rb +336 -0
- data/test/instrumentation/sidekiq-client_test.rb +159 -0
- data/test/instrumentation/sidekiq-worker_test.rb +180 -0
- data/test/instrumentation/twitter-cassandra_test.rb +424 -0
- data/test/instrumentation/typhoeus_test.rb +284 -0
- data/test/jobs/delayed_job/db_worker_job.rb +29 -0
- data/test/jobs/delayed_job/error_worker_job.rb +10 -0
- data/test/jobs/delayed_job/remote_call_worker_job.rb +20 -0
- data/test/jobs/resque/db_worker_job.rb +29 -0
- data/test/jobs/resque/error_worker_job.rb +10 -0
- data/test/jobs/resque/remote_call_worker_job.rb +20 -0
- data/test/jobs/sidekiq/db_worker_job.rb +29 -0
- data/test/jobs/sidekiq/error_worker_job.rb +10 -0
- data/test/jobs/sidekiq/remote_call_worker_job.rb +20 -0
- data/test/minitest_helper.rb +276 -0
- data/test/mocked/curb_mocked_test.rb +311 -0
- data/test/mocked/excon_mocked_test.rb +166 -0
- data/test/mocked/faraday_mocked_test.rb +93 -0
- data/test/mocked/http_mocked_test.rb +129 -0
- data/test/mocked/httpclient_mocked_test.rb +245 -0
- data/test/mocked/rest_client_mocked_test.rb +103 -0
- data/test/mocked/typhoeus_mocked_test.rb +192 -0
- data/test/models/widget.rb +36 -0
- data/test/profiling/legacy_method_profiling_test.rb +201 -0
- data/test/profiling/method_profiling_test.rb +631 -0
- data/test/queues/delayed_job-client_test.rb +95 -0
- data/test/queues/delayed_job-worker_test.rb +91 -0
- data/test/reporter/reporter_test.rb +14 -0
- data/test/servers/delayed_job.rb +107 -0
- data/test/servers/rackapp_8101.rb +29 -0
- data/test/servers/rails3x_8140.rb +96 -0
- data/test/servers/rails4x_8140.rb +96 -0
- data/test/servers/rails5x_8140.rb +95 -0
- data/test/servers/rails5x_api_8150.rb +78 -0
- data/test/servers/sidekiq.rb +29 -0
- data/test/servers/sidekiq.yml +7 -0
- data/test/servers/sidekiq_initializer.rb +25 -0
- data/test/settings +0 -0
- data/test/support/auto_tracing_test.rb +50 -0
- data/test/support/backcompat_test.rb +276 -0
- data/test/support/config_test.rb +149 -0
- data/test/support/dnt_test.rb +98 -0
- data/test/support/init_report_test.rb +25 -0
- data/test/support/liboboe_settings_test.rb +110 -0
- data/test/support/logging_test.rb +130 -0
- data/test/support/noop_test.rb +88 -0
- data/test/support/sql_sanitize_test.rb +55 -0
- data/test/support/tracing_mode_test.rb +33 -0
- data/test/support/tvalias_test.rb +15 -0
- data/test/support/xtrace_test.rb +41 -0
- metadata +475 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
# Copyright (c) 2016 SolarWinds, LLC.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
require "minitest_helper"
|
|
5
|
+
|
|
6
|
+
if defined?(::Rails)
|
|
7
|
+
|
|
8
|
+
describe "Rails5xAPI" do
|
|
9
|
+
before do
|
|
10
|
+
clear_all_traces
|
|
11
|
+
AppOpticsAPM.config_lock.synchronize {
|
|
12
|
+
@tm = AppOpticsAPM::Config[:tracing_mode]
|
|
13
|
+
@collect_backtraces = AppOpticsAPM::Config[:action_controller_api][:collect_backtraces]
|
|
14
|
+
@sample_rate = AppOpticsAPM::Config[:sample_rate]
|
|
15
|
+
}
|
|
16
|
+
ENV['DBTYPE'] = "postgresql" unless ENV['DBTYPE']
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
after do
|
|
20
|
+
AppOpticsAPM.config_lock.synchronize {
|
|
21
|
+
AppOpticsAPM::Config[:action_controller_api][:collect_backtraces] = @collect_backtraces
|
|
22
|
+
AppOpticsAPM::Config[:tracing_mode] = @tm
|
|
23
|
+
AppOpticsAPM::Config[:sample_rate] = @sample_rate
|
|
24
|
+
}
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "should trace a request to a rails api stack" do
|
|
28
|
+
uri = URI.parse('http://127.0.0.1:8150/monkey/hello')
|
|
29
|
+
r = Net::HTTP.get_response(uri)
|
|
30
|
+
|
|
31
|
+
traces = get_all_traces
|
|
32
|
+
|
|
33
|
+
traces.count.must_equal 7
|
|
34
|
+
unless defined?(JRUBY_VERSION)
|
|
35
|
+
# We don't test this under JRuby because the Java instrumentation
|
|
36
|
+
# for the DB drivers doesn't use our test reporter hence we won't
|
|
37
|
+
# see all trace events. :-( To be improved.
|
|
38
|
+
valid_edges?(traces).must_equal true
|
|
39
|
+
end
|
|
40
|
+
validate_outer_layers(traces, 'rack')
|
|
41
|
+
|
|
42
|
+
traces[0]['Layer'].must_equal "rack"
|
|
43
|
+
traces[0]['Label'].must_equal "entry"
|
|
44
|
+
traces[0]['URL'].must_equal "/monkey/hello"
|
|
45
|
+
|
|
46
|
+
traces[1]['Layer'].must_equal "rack"
|
|
47
|
+
traces[1]['Label'].must_equal "info"
|
|
48
|
+
|
|
49
|
+
traces[2]['Layer'].must_equal "rails-api"
|
|
50
|
+
traces[2]['Label'].must_equal "entry"
|
|
51
|
+
traces[2]['Controller'].must_equal "MonkeyController"
|
|
52
|
+
traces[2]['Action'].must_equal "hello"
|
|
53
|
+
|
|
54
|
+
traces[3]['Layer'].must_equal "actionview"
|
|
55
|
+
traces[3]['Label'].must_equal "entry"
|
|
56
|
+
|
|
57
|
+
traces[4]['Layer'].must_equal "actionview"
|
|
58
|
+
traces[4]['Label'].must_equal "exit"
|
|
59
|
+
|
|
60
|
+
traces[5]['Layer'].must_equal "rails-api"
|
|
61
|
+
traces[5]['Label'].must_equal "exit"
|
|
62
|
+
|
|
63
|
+
traces[6]['Layer'].must_equal "rack"
|
|
64
|
+
traces[6]['Label'].must_equal "exit"
|
|
65
|
+
|
|
66
|
+
# Validate the existence of the response header
|
|
67
|
+
r.header.key?('X-Trace').must_equal true
|
|
68
|
+
r.header['X-Trace'].must_equal traces[6]['X-Trace']
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it "should capture errors" do
|
|
72
|
+
uri = URI.parse('http://127.0.0.1:8150/monkey/error')
|
|
73
|
+
r = Net::HTTP.get_response(uri)
|
|
74
|
+
|
|
75
|
+
traces = get_all_traces
|
|
76
|
+
|
|
77
|
+
traces.count.must_equal 6
|
|
78
|
+
unless defined?(JRUBY_VERSION)
|
|
79
|
+
# We don't test this under JRuby because the Java instrumentation
|
|
80
|
+
# for the DB drivers doesn't use our test reporter hence we won't
|
|
81
|
+
# see all trace events. :-( To be improved.
|
|
82
|
+
valid_edges?(traces).must_equal true
|
|
83
|
+
end
|
|
84
|
+
validate_outer_layers(traces, 'rack')
|
|
85
|
+
|
|
86
|
+
traces[0]['Layer'].must_equal "rack"
|
|
87
|
+
traces[0]['Label'].must_equal "entry"
|
|
88
|
+
traces[0]['URL'].must_equal "/monkey/error"
|
|
89
|
+
|
|
90
|
+
traces[1]['Layer'].must_equal "rack"
|
|
91
|
+
traces[1]['Label'].must_equal "info"
|
|
92
|
+
|
|
93
|
+
traces[2]['Layer'].must_equal "rails-api"
|
|
94
|
+
traces[2]['Label'].must_equal "entry"
|
|
95
|
+
traces[2]['Controller'].must_equal "MonkeyController"
|
|
96
|
+
traces[2]['Action'].must_equal "error"
|
|
97
|
+
|
|
98
|
+
traces[3]['Label'].must_equal "error"
|
|
99
|
+
traces[3]['ErrorClass'].must_equal "RuntimeError"
|
|
100
|
+
traces[3]['ErrorMsg'].must_equal "Rails API fake error from controller"
|
|
101
|
+
traces[3].key?('Backtrace').must_equal true
|
|
102
|
+
|
|
103
|
+
traces[4]['Layer'].must_equal "rails-api"
|
|
104
|
+
traces[4]['Label'].must_equal "exit"
|
|
105
|
+
|
|
106
|
+
traces[5]['Layer'].must_equal "rack"
|
|
107
|
+
traces[5]['Label'].must_equal "exit"
|
|
108
|
+
|
|
109
|
+
# Validate the existence of the response header
|
|
110
|
+
r.header.key?('X-Trace').must_equal true
|
|
111
|
+
r.header['X-Trace'].must_equal traces[5]['X-Trace']
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
it "should collect backtraces when true" do
|
|
115
|
+
AppOpticsAPM::Config[:action_controller_api][:collect_backtraces] = true
|
|
116
|
+
|
|
117
|
+
uri = URI.parse('http://127.0.0.1:8150/monkey/hello')
|
|
118
|
+
r = Net::HTTP.get_response(uri)
|
|
119
|
+
|
|
120
|
+
traces = get_all_traces
|
|
121
|
+
|
|
122
|
+
traces.count.must_equal 7
|
|
123
|
+
unless defined?(JRUBY_VERSION)
|
|
124
|
+
# We don't test this under JRuby because the Java instrumentation
|
|
125
|
+
# for the DB drivers doesn't use our test reporter hence we won't
|
|
126
|
+
# see all trace events. :-( To be improved.
|
|
127
|
+
valid_edges?(traces).must_equal true
|
|
128
|
+
end
|
|
129
|
+
validate_outer_layers(traces, 'rack')
|
|
130
|
+
|
|
131
|
+
traces[0]['Layer'].must_equal "rack"
|
|
132
|
+
traces[0]['Label'].must_equal "entry"
|
|
133
|
+
traces[0]['URL'].must_equal "/monkey/hello"
|
|
134
|
+
|
|
135
|
+
traces[1]['Layer'].must_equal "rack"
|
|
136
|
+
traces[1]['Label'].must_equal "info"
|
|
137
|
+
|
|
138
|
+
traces[2]['Layer'].must_equal "rails-api"
|
|
139
|
+
traces[2]['Label'].must_equal "entry"
|
|
140
|
+
traces[2]['Controller'].must_equal "MonkeyController"
|
|
141
|
+
traces[2]['Action'].must_equal "hello"
|
|
142
|
+
traces[2].key?('Backtrace').must_equal true
|
|
143
|
+
|
|
144
|
+
traces[3]['Layer'].must_equal "actionview"
|
|
145
|
+
traces[3]['Label'].must_equal "entry"
|
|
146
|
+
|
|
147
|
+
traces[4]['Layer'].must_equal "actionview"
|
|
148
|
+
traces[4]['Label'].must_equal "exit"
|
|
149
|
+
|
|
150
|
+
traces[5]['Layer'].must_equal "rails-api"
|
|
151
|
+
traces[5]['Label'].must_equal "exit"
|
|
152
|
+
|
|
153
|
+
traces[6]['Layer'].must_equal "rack"
|
|
154
|
+
traces[6]['Label'].must_equal "exit"
|
|
155
|
+
|
|
156
|
+
# Validate the existence of the response header
|
|
157
|
+
r.header.key?('X-Trace').must_equal true
|
|
158
|
+
r.header['X-Trace'].must_equal traces[6]['X-Trace']
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
it "should NOT collect backtraces when false" do
|
|
162
|
+
AppOpticsAPM::Config[:action_controller_api][:collect_backtraces] = false
|
|
163
|
+
|
|
164
|
+
uri = URI.parse('http://127.0.0.1:8150/monkey/hello')
|
|
165
|
+
r = Net::HTTP.get_response(uri)
|
|
166
|
+
|
|
167
|
+
traces = get_all_traces
|
|
168
|
+
|
|
169
|
+
traces.count.must_equal 7
|
|
170
|
+
unless defined?(JRUBY_VERSION)
|
|
171
|
+
# We don't test this under JRuby because the Java instrumentation
|
|
172
|
+
# for the DB drivers doesn't use our test reporter hence we won't
|
|
173
|
+
# see all trace events. :-( To be improved.
|
|
174
|
+
valid_edges?(traces).must_equal true
|
|
175
|
+
end
|
|
176
|
+
validate_outer_layers(traces, 'rack')
|
|
177
|
+
|
|
178
|
+
traces[0]['Layer'].must_equal "rack"
|
|
179
|
+
traces[0]['Label'].must_equal "entry"
|
|
180
|
+
traces[0]['URL'].must_equal "/monkey/hello"
|
|
181
|
+
|
|
182
|
+
traces[1]['Layer'].must_equal "rack"
|
|
183
|
+
traces[1]['Label'].must_equal "info"
|
|
184
|
+
|
|
185
|
+
traces[2]['Layer'].must_equal "rails-api"
|
|
186
|
+
traces[2]['Label'].must_equal "entry"
|
|
187
|
+
traces[2]['Controller'].must_equal "MonkeyController"
|
|
188
|
+
traces[2]['Action'].must_equal "hello"
|
|
189
|
+
traces[2].key?('Backtrace').must_equal false
|
|
190
|
+
|
|
191
|
+
traces[3]['Layer'].must_equal "actionview"
|
|
192
|
+
traces[3]['Label'].must_equal "entry"
|
|
193
|
+
|
|
194
|
+
traces[4]['Layer'].must_equal "actionview"
|
|
195
|
+
traces[4]['Label'].must_equal "exit"
|
|
196
|
+
|
|
197
|
+
traces[5]['Layer'].must_equal "rails-api"
|
|
198
|
+
traces[5]['Label'].must_equal "exit"
|
|
199
|
+
|
|
200
|
+
traces[6]['Layer'].must_equal "rack"
|
|
201
|
+
traces[6]['Label'].must_equal "exit"
|
|
202
|
+
|
|
203
|
+
# Validate the existence of the response header
|
|
204
|
+
r.header.key?('X-Trace').must_equal true
|
|
205
|
+
r.header['X-Trace'].must_equal traces[6]['X-Trace']
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
require_relative "rails_shared_tests"
|
|
209
|
+
end
|
|
210
|
+
end
|
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
# Copyright (c) 2016 SolarWinds, LLC.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
|
|
4
|
+
require "minitest_helper"
|
|
5
|
+
|
|
6
|
+
if defined?(::Rails)
|
|
7
|
+
|
|
8
|
+
describe "Rails5x" do
|
|
9
|
+
before do
|
|
10
|
+
clear_all_traces
|
|
11
|
+
AppOpticsAPM.config_lock.synchronize {
|
|
12
|
+
@tm = AppOpticsAPM::Config[:tracing_mode]
|
|
13
|
+
@collect_backtraces = AppOpticsAPM::Config[:action_controller][:collect_backtraces]
|
|
14
|
+
@sample_rate = AppOpticsAPM::Config[:sample_rate]
|
|
15
|
+
@sanitize_sql = AppOpticsAPM::Config[:sanitize_sql]
|
|
16
|
+
}
|
|
17
|
+
ENV['DBTYPE'] = "postgresql" unless ENV['DBTYPE']
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
after do
|
|
21
|
+
AppOpticsAPM.config_lock.synchronize {
|
|
22
|
+
AppOpticsAPM::Config[:action_controller][:collect_backtraces] = @collect_backtraces
|
|
23
|
+
AppOpticsAPM::Config[:tracing_mode] = @tm
|
|
24
|
+
AppOpticsAPM::Config[:sample_rate] = @sample_rate
|
|
25
|
+
AppOpticsAPM::Config[:sanitize_sql] = @sanitize_sql
|
|
26
|
+
}
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "should trace a request to a rails stack" do
|
|
30
|
+
uri = URI.parse('http://127.0.0.1:8140/hello/world')
|
|
31
|
+
r = Net::HTTP.get_response(uri)
|
|
32
|
+
|
|
33
|
+
traces = get_all_traces
|
|
34
|
+
|
|
35
|
+
traces.count.must_equal 7
|
|
36
|
+
unless defined?(JRUBY_VERSION)
|
|
37
|
+
# We don't test this under JRuby because the Java instrumentation
|
|
38
|
+
# for the DB drivers doesn't use our test reporter hence we won't
|
|
39
|
+
# see all trace events. :-( To be improved.
|
|
40
|
+
valid_edges?(traces).must_equal true
|
|
41
|
+
end
|
|
42
|
+
validate_outer_layers(traces, 'rack')
|
|
43
|
+
|
|
44
|
+
traces[0]['Layer'].must_equal "rack"
|
|
45
|
+
traces[0]['Label'].must_equal "entry"
|
|
46
|
+
traces[0]['URL'].must_equal "/hello/world"
|
|
47
|
+
|
|
48
|
+
traces[1]['Layer'].must_equal "rack"
|
|
49
|
+
traces[1]['Label'].must_equal "info"
|
|
50
|
+
|
|
51
|
+
traces[2]['Layer'].must_equal "rails"
|
|
52
|
+
traces[2]['Label'].must_equal "entry"
|
|
53
|
+
traces[2]['Controller'].must_equal "HelloController"
|
|
54
|
+
traces[2]['Action'].must_equal "world"
|
|
55
|
+
|
|
56
|
+
traces[3]['Layer'].must_equal "actionview"
|
|
57
|
+
traces[3]['Label'].must_equal "entry"
|
|
58
|
+
|
|
59
|
+
traces[4]['Layer'].must_equal "actionview"
|
|
60
|
+
traces[4]['Label'].must_equal "exit"
|
|
61
|
+
|
|
62
|
+
traces[5]['Layer'].must_equal "rails"
|
|
63
|
+
traces[5]['Label'].must_equal "exit"
|
|
64
|
+
|
|
65
|
+
traces[6]['Layer'].must_equal "rack"
|
|
66
|
+
traces[6]['Label'].must_equal "exit"
|
|
67
|
+
|
|
68
|
+
# Validate the existence of the response header
|
|
69
|
+
r.header.key?('X-Trace').must_equal true
|
|
70
|
+
r.header['X-Trace'].must_equal traces[6]['X-Trace']
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it "should trace rails postgres db calls" do
|
|
74
|
+
# Skip for JRuby since the java instrumentation
|
|
75
|
+
# handles DB instrumentation for JRuby
|
|
76
|
+
skip if defined?(JRUBY_VERSION) || ENV['DBTYPE'] != 'postgresql'
|
|
77
|
+
|
|
78
|
+
uri = URI.parse('http://127.0.0.1:8140/hello/db')
|
|
79
|
+
r = Net::HTTP.get_response(uri)
|
|
80
|
+
|
|
81
|
+
traces = get_all_traces
|
|
82
|
+
|
|
83
|
+
traces.count.must_equal 13
|
|
84
|
+
valid_edges?(traces).must_equal true
|
|
85
|
+
validate_outer_layers(traces, 'rack')
|
|
86
|
+
|
|
87
|
+
traces[3]['Layer'].must_equal "activerecord"
|
|
88
|
+
traces[3]['Label'].must_equal "entry"
|
|
89
|
+
traces[3]['Flavor'].must_equal "postgresql"
|
|
90
|
+
traces[3]['Query'].must_equal "INSERT INTO \"widgets\" (\"name\", \"description\", \"created_at\", \"updated_at\") VALUES ($?, $?, $?, $?) RETURNING \"id\""
|
|
91
|
+
traces[3]['Name'].must_equal "SQL"
|
|
92
|
+
traces[3].key?('Backtrace').must_equal true
|
|
93
|
+
|
|
94
|
+
traces[4]['Layer'].must_equal "activerecord"
|
|
95
|
+
traces[4]['Label'].must_equal "exit"
|
|
96
|
+
|
|
97
|
+
traces[5]['Layer'].must_equal "activerecord"
|
|
98
|
+
traces[5]['Label'].must_equal "entry"
|
|
99
|
+
traces[5]['Flavor'].must_equal "postgresql"
|
|
100
|
+
traces[5]['Query'].must_equal "SELECT \"widgets\".* FROM \"widgets\" WHERE \"widgets\".\"name\" = $? ORDER BY \"widgets\".\"id\" ASC LIMIT $?"
|
|
101
|
+
traces[5]['Name'].must_equal "Widget Load"
|
|
102
|
+
traces[5].key?('Backtrace').must_equal true
|
|
103
|
+
traces[5].key?('QueryArgs').must_equal false
|
|
104
|
+
|
|
105
|
+
traces[6]['Layer'].must_equal "activerecord"
|
|
106
|
+
traces[6]['Label'].must_equal "exit"
|
|
107
|
+
|
|
108
|
+
traces[7]['Layer'].must_equal "activerecord"
|
|
109
|
+
traces[7]['Label'].must_equal "entry"
|
|
110
|
+
traces[7]['Flavor'].must_equal "postgresql"
|
|
111
|
+
traces[7]['Query'].must_equal "DELETE FROM \"widgets\" WHERE \"widgets\".\"id\" = $?"
|
|
112
|
+
traces[7]['Name'].must_equal "SQL"
|
|
113
|
+
traces[7].key?('Backtrace').must_equal true
|
|
114
|
+
traces[7].key?('QueryArgs').must_equal false
|
|
115
|
+
|
|
116
|
+
traces[8]['Layer'].must_equal "activerecord"
|
|
117
|
+
traces[8]['Label'].must_equal "exit"
|
|
118
|
+
|
|
119
|
+
# Validate the existence of the response header
|
|
120
|
+
r.header.key?('X-Trace').must_equal true
|
|
121
|
+
r.header['X-Trace'].must_equal traces[12]['X-Trace']
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it "should trace rails mysql2 db calls" do
|
|
125
|
+
# Skip for JRuby since the java instrumentation
|
|
126
|
+
# handles DB instrumentation for JRuby
|
|
127
|
+
skip if defined?(JRUBY_VERSION) || ENV['DBTYPE'] != 'mysql2'
|
|
128
|
+
|
|
129
|
+
AppOpticsAPM::Config[:sanitize_sql] = false
|
|
130
|
+
|
|
131
|
+
uri = URI.parse('http://127.0.0.1:8140/hello/db')
|
|
132
|
+
r = Net::HTTP.get_response(uri)
|
|
133
|
+
|
|
134
|
+
traces = get_all_traces
|
|
135
|
+
|
|
136
|
+
traces.count.must_equal 15
|
|
137
|
+
valid_edges?(traces).must_equal true
|
|
138
|
+
validate_outer_layers(traces, 'rack')
|
|
139
|
+
|
|
140
|
+
entry_traces = traces.select { |tr| tr['Label'] == 'entry' }
|
|
141
|
+
entry_traces.count.must_equal 7
|
|
142
|
+
|
|
143
|
+
exit_traces = traces.select { |tr| tr['Label'] == 'exit' }
|
|
144
|
+
exit_traces.count.must_equal 7
|
|
145
|
+
|
|
146
|
+
entry_traces[2]['Layer'].must_equal "activerecord"
|
|
147
|
+
entry_traces[2]['Flavor'].must_equal "mysql"
|
|
148
|
+
entry_traces[2]['Query'].gsub!(/\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d/, 'the_date')
|
|
149
|
+
entry_traces[2]['Query'].must_equal "INSERT INTO `widgets` (`name`, `description`, `created_at`, `updated_at`) VALUES ('blah', 'This is an amazing widget.', 'the_date', 'the_date')"
|
|
150
|
+
entry_traces[2]['Name'].must_equal "SQL"
|
|
151
|
+
entry_traces[2].key?('Backtrace').must_equal true
|
|
152
|
+
entry_traces[2].key?('QueryArgs').must_equal true
|
|
153
|
+
|
|
154
|
+
entry_traces[3]['Layer'].must_equal "activerecord"
|
|
155
|
+
entry_traces[3]['Flavor'].must_equal "mysql"
|
|
156
|
+
entry_traces[3]['Query'].gsub!(/\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d/, 'the_date')
|
|
157
|
+
entry_traces[3]['Query'].must_equal "INSERT INTO `widgets` (`name`, `description`, `created_at`, `updated_at`) VALUES ('blah', 'This is an amazing widget.', 'the_date', 'the_date')"
|
|
158
|
+
entry_traces[3]['Name'].must_equal "SQL"
|
|
159
|
+
entry_traces[3].key?('Backtrace').must_equal true
|
|
160
|
+
entry_traces[3].key?('QueryArgs').must_equal true
|
|
161
|
+
|
|
162
|
+
entry_traces[4]['Layer'].must_equal "activerecord"
|
|
163
|
+
entry_traces[4]['Flavor'].must_equal "mysql"
|
|
164
|
+
entry_traces[4]['Query'].must_equal "SELECT `widgets`.* FROM `widgets` WHERE `widgets`.`name` = 'blah' ORDER BY `widgets`.`id` ASC LIMIT 1"
|
|
165
|
+
entry_traces[4]['Name'].must_equal "Widget Load"
|
|
166
|
+
entry_traces[4].key?('Backtrace').must_equal true
|
|
167
|
+
entry_traces[4].key?('QueryArgs').must_equal true
|
|
168
|
+
|
|
169
|
+
entry_traces[5]['Layer'].must_equal "activerecord"
|
|
170
|
+
entry_traces[5]['Flavor'].must_equal "mysql"
|
|
171
|
+
entry_traces[5]['Query'].gsub!(/\d+/, 'ID')
|
|
172
|
+
entry_traces[5]['Query'].must_equal "DELETE FROM `widgets` WHERE `widgets`.`id` = ID"
|
|
173
|
+
entry_traces[5]['Name'].must_equal "SQL"
|
|
174
|
+
entry_traces[5].key?('Backtrace').must_equal true
|
|
175
|
+
entry_traces[5].key?('QueryArgs').must_equal true
|
|
176
|
+
|
|
177
|
+
# Validate the existence of the response header
|
|
178
|
+
r.header.key?('X-Trace').must_equal true
|
|
179
|
+
r.header['X-Trace'].must_equal traces[14]['X-Trace']
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
it "should trace rails mysql2 db calls with sanitize sql" do
|
|
183
|
+
# Skip for JRuby since the java instrumentation
|
|
184
|
+
# handles DB instrumentation for JRuby
|
|
185
|
+
skip if defined?(JRUBY_VERSION) || ENV['DBTYPE'] != 'mysql2'
|
|
186
|
+
|
|
187
|
+
AppOpticsAPM::Config[:sanitize_sql] = true
|
|
188
|
+
|
|
189
|
+
uri = URI.parse('http://127.0.0.1:8140/hello/db')
|
|
190
|
+
r = Net::HTTP.get_response(uri)
|
|
191
|
+
|
|
192
|
+
traces = get_all_traces
|
|
193
|
+
|
|
194
|
+
traces.count.must_equal 15
|
|
195
|
+
valid_edges?(traces).must_equal true
|
|
196
|
+
validate_outer_layers(traces, 'rack')
|
|
197
|
+
|
|
198
|
+
entry_traces = traces.select { |tr| tr['Label'] == 'entry' }
|
|
199
|
+
entry_traces.count.must_equal 7
|
|
200
|
+
|
|
201
|
+
exit_traces = traces.select { |tr| tr['Label'] == 'exit' }
|
|
202
|
+
exit_traces.count.must_equal 7
|
|
203
|
+
|
|
204
|
+
entry_traces[2]['Layer'].must_equal "activerecord"
|
|
205
|
+
entry_traces[2]['Flavor'].must_equal "mysql"
|
|
206
|
+
entry_traces[2]['Query'].must_equal "INSERT INTO `widgets` (`name`, `description`, `created_at`, `updated_at`) VALUES (?, ?, ?, ?)"
|
|
207
|
+
entry_traces[2]['Name'].must_equal "SQL"
|
|
208
|
+
entry_traces[2].key?('Backtrace').must_equal true
|
|
209
|
+
entry_traces[2].key?('QueryArgs').must_equal false
|
|
210
|
+
|
|
211
|
+
entry_traces[3]['Layer'].must_equal "activerecord"
|
|
212
|
+
entry_traces[3]['Flavor'].must_equal "mysql"
|
|
213
|
+
entry_traces[3]['Query'].must_equal "INSERT INTO `widgets` (`name`, `description`, `created_at`, `updated_at`) VALUES (?, ?, ?, ?)"
|
|
214
|
+
entry_traces[3]['Name'].must_equal "SQL"
|
|
215
|
+
entry_traces[3].key?('Backtrace').must_equal true
|
|
216
|
+
entry_traces[3].key?('QueryArgs').must_equal false
|
|
217
|
+
|
|
218
|
+
entry_traces[4]['Layer'].must_equal "activerecord"
|
|
219
|
+
entry_traces[4]['Flavor'].must_equal "mysql"
|
|
220
|
+
entry_traces[4]['Query'].must_equal "SELECT `widgets`.* FROM `widgets` WHERE `widgets`.`name` = ? ORDER BY `widgets`.`id` ASC LIMIT ?"
|
|
221
|
+
entry_traces[4]['Name'].must_equal "Widget Load"
|
|
222
|
+
entry_traces[4].key?('Backtrace').must_equal true
|
|
223
|
+
entry_traces[4].key?('QueryArgs').must_equal false
|
|
224
|
+
|
|
225
|
+
entry_traces[5]['Layer'].must_equal "activerecord"
|
|
226
|
+
entry_traces[5]['Flavor'].must_equal "mysql"
|
|
227
|
+
entry_traces[5]['Query'].must_equal "DELETE FROM `widgets` WHERE `widgets`.`id` = ?"
|
|
228
|
+
entry_traces[5]['Name'].must_equal "SQL"
|
|
229
|
+
entry_traces[5].key?('Backtrace').must_equal true
|
|
230
|
+
entry_traces[5].key?('QueryArgs').must_equal false
|
|
231
|
+
|
|
232
|
+
# Validate the existence of the response header
|
|
233
|
+
r.header.key?('X-Trace').must_equal true
|
|
234
|
+
r.header['X-Trace'].must_equal traces[14]['X-Trace']
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
it "should trace a request to a rails metal stack" do
|
|
238
|
+
|
|
239
|
+
uri = URI.parse('http://127.0.0.1:8140/hello/metal')
|
|
240
|
+
r = Net::HTTP.get_response(uri)
|
|
241
|
+
|
|
242
|
+
traces = get_all_traces
|
|
243
|
+
|
|
244
|
+
traces.count.must_equal 5
|
|
245
|
+
unless defined?(JRUBY_VERSION)
|
|
246
|
+
# We don't test this under JRuby because the Java instrumentation
|
|
247
|
+
# for the DB drivers doesn't use our test reporter hence we won't
|
|
248
|
+
# see all trace events. :-( To be improved.
|
|
249
|
+
valid_edges?(traces).must_equal true
|
|
250
|
+
end
|
|
251
|
+
validate_outer_layers(traces, 'rack')
|
|
252
|
+
|
|
253
|
+
traces[0]['Layer'].must_equal "rack"
|
|
254
|
+
traces[0]['Label'].must_equal "entry"
|
|
255
|
+
traces[0]['URL'].must_equal "/hello/metal"
|
|
256
|
+
|
|
257
|
+
traces[1]['Layer'].must_equal "rack"
|
|
258
|
+
traces[1]['Label'].must_equal "info"
|
|
259
|
+
|
|
260
|
+
traces[2]['Label'].must_equal "profile_entry"
|
|
261
|
+
traces[2]['Language'].must_equal "ruby"
|
|
262
|
+
traces[2]['ProfileName'].must_equal "world"
|
|
263
|
+
traces[2]['MethodName'].must_equal "world"
|
|
264
|
+
traces[2]['Class'].must_equal "FerroController"
|
|
265
|
+
traces[2]['Controller'].must_equal "FerroController"
|
|
266
|
+
traces[2]['Action'].must_equal "world"
|
|
267
|
+
|
|
268
|
+
traces[3]['Label'].must_equal "profile_exit"
|
|
269
|
+
traces[3]['Language'].must_equal "ruby"
|
|
270
|
+
traces[3]['ProfileName'].must_equal "world"
|
|
271
|
+
|
|
272
|
+
traces[4]['Layer'].must_equal "rack"
|
|
273
|
+
traces[4]['Label'].must_equal "exit"
|
|
274
|
+
|
|
275
|
+
# Validate the existence of the response header
|
|
276
|
+
r.header.key?('X-Trace').must_equal true
|
|
277
|
+
r.header['X-Trace'].must_equal traces[4]['X-Trace']
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
it "should collect backtraces when true" do
|
|
281
|
+
AppOpticsAPM::Config[:action_controller][:collect_backtraces] = true
|
|
282
|
+
|
|
283
|
+
uri = URI.parse('http://127.0.0.1:8140/hello/world')
|
|
284
|
+
r = Net::HTTP.get_response(uri)
|
|
285
|
+
|
|
286
|
+
traces = get_all_traces
|
|
287
|
+
|
|
288
|
+
traces.count.must_equal 7
|
|
289
|
+
unless defined?(JRUBY_VERSION)
|
|
290
|
+
# We don't test this under JRuby because the Java instrumentation
|
|
291
|
+
# for the DB drivers doesn't use our test reporter hence we won't
|
|
292
|
+
# see all trace events. :-( To be improved.
|
|
293
|
+
valid_edges?(traces).must_equal true
|
|
294
|
+
end
|
|
295
|
+
validate_outer_layers(traces, 'rack')
|
|
296
|
+
|
|
297
|
+
traces[0]['Layer'].must_equal "rack"
|
|
298
|
+
traces[0]['Label'].must_equal "entry"
|
|
299
|
+
traces[0]['URL'].must_equal "/hello/world"
|
|
300
|
+
|
|
301
|
+
traces[1]['Layer'].must_equal "rack"
|
|
302
|
+
traces[1]['Label'].must_equal "info"
|
|
303
|
+
|
|
304
|
+
traces[2]['Layer'].must_equal "rails"
|
|
305
|
+
traces[2]['Label'].must_equal "entry"
|
|
306
|
+
traces[2]['Controller'].must_equal "HelloController"
|
|
307
|
+
traces[2]['Action'].must_equal "world"
|
|
308
|
+
traces[2].key?('Backtrace').must_equal true
|
|
309
|
+
|
|
310
|
+
traces[3]['Layer'].must_equal "actionview"
|
|
311
|
+
traces[3]['Label'].must_equal "entry"
|
|
312
|
+
|
|
313
|
+
traces[4]['Layer'].must_equal "actionview"
|
|
314
|
+
traces[4]['Label'].must_equal "exit"
|
|
315
|
+
|
|
316
|
+
traces[5]['Layer'].must_equal "rails"
|
|
317
|
+
traces[5]['Label'].must_equal "exit"
|
|
318
|
+
|
|
319
|
+
traces[6]['Layer'].must_equal "rack"
|
|
320
|
+
traces[6]['Label'].must_equal "exit"
|
|
321
|
+
|
|
322
|
+
# Validate the existence of the response header
|
|
323
|
+
r.header.key?('X-Trace').must_equal true
|
|
324
|
+
r.header['X-Trace'].must_equal traces[6]['X-Trace']
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
it "should NOT collect backtraces when false" do
|
|
328
|
+
AppOpticsAPM::Config[:action_controller][:collect_backtraces] = false
|
|
329
|
+
|
|
330
|
+
uri = URI.parse('http://127.0.0.1:8140/hello/world')
|
|
331
|
+
r = Net::HTTP.get_response(uri)
|
|
332
|
+
|
|
333
|
+
traces = get_all_traces
|
|
334
|
+
|
|
335
|
+
traces.count.must_equal 7
|
|
336
|
+
unless defined?(JRUBY_VERSION)
|
|
337
|
+
# We don't test this under JRuby because the Java instrumentation
|
|
338
|
+
# for the DB drivers doesn't use our test reporter hence we won't
|
|
339
|
+
# see all trace events. :-( To be improved.
|
|
340
|
+
valid_edges?(traces).must_equal true
|
|
341
|
+
end
|
|
342
|
+
validate_outer_layers(traces, 'rack')
|
|
343
|
+
|
|
344
|
+
traces[0]['Layer'].must_equal "rack"
|
|
345
|
+
traces[0]['Label'].must_equal "entry"
|
|
346
|
+
traces[0]['URL'].must_equal "/hello/world"
|
|
347
|
+
|
|
348
|
+
traces[1]['Layer'].must_equal "rack"
|
|
349
|
+
traces[1]['Label'].must_equal "info"
|
|
350
|
+
|
|
351
|
+
traces[2]['Layer'].must_equal "rails"
|
|
352
|
+
traces[2]['Label'].must_equal "entry"
|
|
353
|
+
traces[2]['Controller'].must_equal "HelloController"
|
|
354
|
+
traces[2]['Action'].must_equal "world"
|
|
355
|
+
traces[2].key?('Backtrace').must_equal false
|
|
356
|
+
|
|
357
|
+
traces[3]['Layer'].must_equal "actionview"
|
|
358
|
+
traces[3]['Label'].must_equal "entry"
|
|
359
|
+
|
|
360
|
+
traces[4]['Layer'].must_equal "actionview"
|
|
361
|
+
traces[4]['Label'].must_equal "exit"
|
|
362
|
+
|
|
363
|
+
traces[5]['Layer'].must_equal "rails"
|
|
364
|
+
traces[5]['Label'].must_equal "exit"
|
|
365
|
+
|
|
366
|
+
traces[6]['Layer'].must_equal "rack"
|
|
367
|
+
traces[6]['Label'].must_equal "exit"
|
|
368
|
+
|
|
369
|
+
# Validate the existence of the response header
|
|
370
|
+
r.header.key?('X-Trace').must_equal true
|
|
371
|
+
r.header['X-Trace'].must_equal traces[6]['X-Trace']
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
require_relative "rails_shared_tests"
|
|
375
|
+
end
|
|
376
|
+
end
|