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,631 @@
|
|
|
1
|
+
# Copyright (c) 2016 SolarWinds, LLC.
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
require 'minitest_helper'
|
|
4
|
+
|
|
5
|
+
# APPOPTICS Method profiling only supports Ruby 1.9.3 or greater. For earlier Ruby versions
|
|
6
|
+
# see the legacy method profiling in lib/appoptics_apm/legacy_method_profiling.rb.
|
|
7
|
+
if RUBY_VERSION >= '1.9.3'
|
|
8
|
+
describe "AppOpticsAPMMethodProfiling" do
|
|
9
|
+
before do
|
|
10
|
+
clear_all_traces
|
|
11
|
+
# Conditionally Undefine TestWorker
|
|
12
|
+
# http://stackoverflow.com/questions/11503558/how-to-undefine-class-in-ruby
|
|
13
|
+
Object.send(:remove_const, :TestKlass) if defined?(TestKlass)
|
|
14
|
+
Object.send(:remove_const, :TestModule) if defined?(TestModule)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'should be loaded, defined and ready' do
|
|
18
|
+
defined?(::AppOpticsAPM::MethodProfiling).wont_match nil
|
|
19
|
+
assert_equal true, AppOpticsAPM::API.respond_to?(:profile_method), "has profile_method method"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'should return false for bad arguments' do
|
|
23
|
+
class TestKlass
|
|
24
|
+
def do_work
|
|
25
|
+
return 687
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Bad first param
|
|
30
|
+
rv = AppOpticsAPM::API.profile_method('blah', :do_work)
|
|
31
|
+
assert_equal false, rv, "Return value must be false for bad args"
|
|
32
|
+
|
|
33
|
+
# Bad first param
|
|
34
|
+
rv = AppOpticsAPM::API.profile_method(TestKlass, 52)
|
|
35
|
+
assert_equal false, rv, "Return value must be false for bad args"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it 'should profile class instance methods' do
|
|
39
|
+
class TestKlass
|
|
40
|
+
def do_work
|
|
41
|
+
return 687
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
result = AppOpticsAPM::API.profile_method(TestKlass, :do_work)
|
|
46
|
+
assert_equal true, result, "profile_method return value must be true"
|
|
47
|
+
|
|
48
|
+
result = nil
|
|
49
|
+
|
|
50
|
+
::AppOpticsAPM::API.start_trace('method_profiling', '', {}) do
|
|
51
|
+
# Call the profiled class method
|
|
52
|
+
result = TestKlass.new.do_work
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
traces = get_all_traces
|
|
56
|
+
traces.count.must_equal 4
|
|
57
|
+
assert valid_edges?(traces), "Trace edge validation"
|
|
58
|
+
|
|
59
|
+
validate_outer_layers(traces, 'method_profiling')
|
|
60
|
+
|
|
61
|
+
result.must_equal 687
|
|
62
|
+
|
|
63
|
+
kvs = {}
|
|
64
|
+
kvs["Label"] = 'profile_entry'
|
|
65
|
+
kvs["Language"] = "ruby"
|
|
66
|
+
kvs["ProfileName"] = "do_work"
|
|
67
|
+
kvs["Class"] = "TestKlass"
|
|
68
|
+
kvs["MethodName"] = "do_work"
|
|
69
|
+
|
|
70
|
+
validate_event_keys(traces[1], kvs)
|
|
71
|
+
|
|
72
|
+
traces[1].key?("Layer").must_equal false
|
|
73
|
+
traces[1].key?("Module").must_equal false
|
|
74
|
+
traces[1].key?("File").must_equal true
|
|
75
|
+
traces[1].key?("LineNumber").must_equal true
|
|
76
|
+
|
|
77
|
+
kvs.clear
|
|
78
|
+
kvs["Label"] = "profile_exit"
|
|
79
|
+
kvs["Language"] = "ruby"
|
|
80
|
+
kvs["ProfileName"] = "do_work"
|
|
81
|
+
|
|
82
|
+
validate_event_keys(traces[2], kvs)
|
|
83
|
+
traces[2].key?("Layer").must_equal false
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it 'should not double profile already profiled methods' do
|
|
87
|
+
class TestKlass
|
|
88
|
+
def do_work
|
|
89
|
+
return 687
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Attempt to double profile
|
|
94
|
+
rv = AppOpticsAPM::API.profile_method(TestKlass, :do_work)
|
|
95
|
+
assert_equal true, rv, "Return value must be true"
|
|
96
|
+
|
|
97
|
+
rv = AppOpticsAPM::API.profile_method(TestKlass, :do_work)
|
|
98
|
+
assert_equal false, rv, "Return value must be false"
|
|
99
|
+
|
|
100
|
+
with_tv = TestKlass.instance_methods.select{ |m| m == :do_work_with_appoptics }
|
|
101
|
+
assert_equal with_tv.count, 1, ":do_work_with_appoptics method count"
|
|
102
|
+
|
|
103
|
+
without_tv = TestKlass.instance_methods.select{ |m| m == :do_work_without_appoptics }
|
|
104
|
+
assert_equal without_tv.count, 1, ":do_work_without_appoptics method count"
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it 'should error out for non-existent methods' do
|
|
108
|
+
class TestKlass
|
|
109
|
+
def do_work
|
|
110
|
+
return 687
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
rv = AppOpticsAPM::API.profile_method(TestKlass, :does_not_exist)
|
|
115
|
+
assert_equal false, rv, "Return value must be false"
|
|
116
|
+
|
|
117
|
+
with_tv = TestKlass.instance_methods.select{ |m| m == :does_not_exit_with_appoptics }
|
|
118
|
+
assert_equal with_tv.count, 0, ":does_not_exit_with_appoptics method count"
|
|
119
|
+
|
|
120
|
+
without_tv = TestKlass.instance_methods.select{ |m| m == :does_not_exit_without_appoptics }
|
|
121
|
+
assert_equal without_tv.count, 0, ":does_not_exit_without_appoptics method count"
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it 'should trace class singleton methods' do
|
|
125
|
+
class TestKlass
|
|
126
|
+
def self.do_work
|
|
127
|
+
return 687
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
result = AppOpticsAPM::API.profile_method(TestKlass, :do_work)
|
|
132
|
+
assert_equal true, result, "profile_method return value must be true"
|
|
133
|
+
|
|
134
|
+
::AppOpticsAPM::API.start_trace('method_profiling', '', {}) do
|
|
135
|
+
result = TestKlass.do_work
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
traces = get_all_traces
|
|
139
|
+
traces.count.must_equal 4
|
|
140
|
+
assert valid_edges?(traces), "Trace edge validation"
|
|
141
|
+
|
|
142
|
+
validate_outer_layers(traces, 'method_profiling')
|
|
143
|
+
|
|
144
|
+
result.must_equal 687
|
|
145
|
+
|
|
146
|
+
kvs = {}
|
|
147
|
+
kvs["Label"] = 'profile_entry'
|
|
148
|
+
kvs["Language"] = "ruby"
|
|
149
|
+
kvs["ProfileName"] = "do_work"
|
|
150
|
+
kvs["Class"] = "TestKlass"
|
|
151
|
+
kvs["MethodName"] = "do_work"
|
|
152
|
+
|
|
153
|
+
validate_event_keys(traces[1], kvs)
|
|
154
|
+
|
|
155
|
+
traces[1].key?("Layer").must_equal false
|
|
156
|
+
traces[1].key?("Module").must_equal false
|
|
157
|
+
traces[1].key?("File").must_equal true
|
|
158
|
+
traces[1].key?("LineNumber").must_equal true
|
|
159
|
+
|
|
160
|
+
kvs.clear
|
|
161
|
+
kvs["Label"] = "profile_exit"
|
|
162
|
+
kvs["Language"] = "ruby"
|
|
163
|
+
kvs["ProfileName"] = "do_work"
|
|
164
|
+
|
|
165
|
+
validate_event_keys(traces[2], kvs)
|
|
166
|
+
traces[2].key?("Layer").must_equal false
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
it 'should trace class private instance methods' do
|
|
170
|
+
class TestKlass
|
|
171
|
+
private
|
|
172
|
+
def do_work_privately
|
|
173
|
+
return 687
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
result = AppOpticsAPM::API.profile_method(TestKlass, :do_work_privately)
|
|
178
|
+
assert_equal true, result, "profile_method return value must be true"
|
|
179
|
+
|
|
180
|
+
result = nil
|
|
181
|
+
|
|
182
|
+
::AppOpticsAPM::API.start_trace('method_profiling', '', {}) do
|
|
183
|
+
# Call the profiled class method
|
|
184
|
+
result = TestKlass.new.do_work_privately
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
traces = get_all_traces
|
|
188
|
+
traces.count.must_equal 4
|
|
189
|
+
assert valid_edges?(traces), "Trace edge validation"
|
|
190
|
+
|
|
191
|
+
validate_outer_layers(traces, 'method_profiling')
|
|
192
|
+
|
|
193
|
+
result.must_equal 687
|
|
194
|
+
|
|
195
|
+
kvs = {}
|
|
196
|
+
kvs["Label"] = 'profile_entry'
|
|
197
|
+
kvs["Language"] = "ruby"
|
|
198
|
+
kvs["ProfileName"] = "do_work_privately"
|
|
199
|
+
kvs["Class"] = "TestKlass"
|
|
200
|
+
kvs["MethodName"] = "do_work_privately"
|
|
201
|
+
|
|
202
|
+
validate_event_keys(traces[1], kvs)
|
|
203
|
+
|
|
204
|
+
traces[1].key?("Layer").must_equal false
|
|
205
|
+
traces[1].key?("Module").must_equal false
|
|
206
|
+
traces[1].key?("File").must_equal true
|
|
207
|
+
traces[1].key?("LineNumber").must_equal true
|
|
208
|
+
|
|
209
|
+
kvs.clear
|
|
210
|
+
kvs["Label"] = "profile_exit"
|
|
211
|
+
kvs["Language"] = "ruby"
|
|
212
|
+
kvs["ProfileName"] = "do_work_privately"
|
|
213
|
+
|
|
214
|
+
validate_event_keys(traces[2], kvs)
|
|
215
|
+
traces[2].key?("Layer").must_equal false
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
it 'should trace class private singleton methods' do
|
|
219
|
+
class TestKlass
|
|
220
|
+
private
|
|
221
|
+
def self.do_work_privately
|
|
222
|
+
return 687
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
result = AppOpticsAPM::API.profile_method(TestKlass, :do_work_privately)
|
|
227
|
+
assert_equal true, result, "profile_method return value must be true"
|
|
228
|
+
|
|
229
|
+
::AppOpticsAPM::API.start_trace('method_profiling', '', {}) do
|
|
230
|
+
result = TestKlass.do_work_privately
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
traces = get_all_traces
|
|
234
|
+
traces.count.must_equal 4
|
|
235
|
+
assert valid_edges?(traces), "Trace edge validation"
|
|
236
|
+
|
|
237
|
+
validate_outer_layers(traces, 'method_profiling')
|
|
238
|
+
|
|
239
|
+
result.must_equal 687
|
|
240
|
+
|
|
241
|
+
kvs = {}
|
|
242
|
+
kvs["Label"] = 'profile_entry'
|
|
243
|
+
kvs["Language"] = "ruby"
|
|
244
|
+
kvs["ProfileName"] = "do_work_privately"
|
|
245
|
+
kvs["Class"] = "TestKlass"
|
|
246
|
+
kvs["MethodName"] = "do_work_privately"
|
|
247
|
+
|
|
248
|
+
validate_event_keys(traces[1], kvs)
|
|
249
|
+
|
|
250
|
+
traces[1].key?("Layer").must_equal false
|
|
251
|
+
traces[1].key?("Module").must_equal false
|
|
252
|
+
traces[1].key?("File").must_equal true
|
|
253
|
+
traces[1].key?("LineNumber").must_equal true
|
|
254
|
+
|
|
255
|
+
kvs.clear
|
|
256
|
+
kvs["Label"] = "profile_exit"
|
|
257
|
+
kvs["Language"] = "ruby"
|
|
258
|
+
kvs["ProfileName"] = "do_work_privately"
|
|
259
|
+
|
|
260
|
+
validate_event_keys(traces[2], kvs)
|
|
261
|
+
traces[2].key?("Layer").must_equal false
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
it 'should trace module singleton methods' do
|
|
265
|
+
module TestModule
|
|
266
|
+
def self.do_work
|
|
267
|
+
return 687
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
result = AppOpticsAPM::API.profile_method(TestModule, :do_work)
|
|
272
|
+
assert_equal true, result, "profile_method return value must be true"
|
|
273
|
+
|
|
274
|
+
::AppOpticsAPM::API.start_trace('method_profiling', '', {}) do
|
|
275
|
+
result = TestModule.do_work
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
traces = get_all_traces
|
|
279
|
+
traces.count.must_equal 4
|
|
280
|
+
assert valid_edges?(traces), "Trace edge validation"
|
|
281
|
+
|
|
282
|
+
validate_outer_layers(traces, 'method_profiling')
|
|
283
|
+
|
|
284
|
+
result.must_equal 687
|
|
285
|
+
|
|
286
|
+
kvs = {}
|
|
287
|
+
kvs["Label"] = 'profile_entry'
|
|
288
|
+
kvs["Language"] = "ruby"
|
|
289
|
+
kvs["ProfileName"] = "do_work"
|
|
290
|
+
kvs["Module"] = "TestModule"
|
|
291
|
+
kvs["MethodName"] = "do_work"
|
|
292
|
+
|
|
293
|
+
validate_event_keys(traces[1], kvs)
|
|
294
|
+
|
|
295
|
+
traces[1].key?("Layer").must_equal false
|
|
296
|
+
traces[1].key?("Class").must_equal false
|
|
297
|
+
traces[1].key?("File").must_equal true
|
|
298
|
+
traces[1].key?("LineNumber").must_equal true
|
|
299
|
+
|
|
300
|
+
kvs.clear
|
|
301
|
+
kvs["Label"] = "profile_exit"
|
|
302
|
+
kvs["Language"] = "ruby"
|
|
303
|
+
kvs["ProfileName"] = "do_work"
|
|
304
|
+
|
|
305
|
+
validate_event_keys(traces[2], kvs)
|
|
306
|
+
traces[2].key?("Layer").must_equal false
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
it 'should trace module instance methods' do
|
|
310
|
+
module TestModule
|
|
311
|
+
def do_work
|
|
312
|
+
return 687
|
|
313
|
+
end
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
# Profile the module before including in a class
|
|
317
|
+
result = AppOpticsAPM::API.profile_method(TestModule, :do_work)
|
|
318
|
+
assert_equal true, result, "profile_method return value must be true"
|
|
319
|
+
|
|
320
|
+
class TestKlass
|
|
321
|
+
include TestModule
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
::AppOpticsAPM::API.start_trace('method_profiling', '', {}) do
|
|
325
|
+
result = TestKlass.new.do_work
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
traces = get_all_traces
|
|
329
|
+
traces.count.must_equal 4
|
|
330
|
+
assert valid_edges?(traces), "Trace edge validation"
|
|
331
|
+
|
|
332
|
+
validate_outer_layers(traces, 'method_profiling')
|
|
333
|
+
|
|
334
|
+
result.must_equal 687
|
|
335
|
+
|
|
336
|
+
kvs = {}
|
|
337
|
+
kvs["Label"] = 'profile_entry'
|
|
338
|
+
kvs["Language"] = "ruby"
|
|
339
|
+
kvs["ProfileName"] = "do_work"
|
|
340
|
+
kvs["Module"] = "TestModule"
|
|
341
|
+
kvs["MethodName"] = "do_work"
|
|
342
|
+
|
|
343
|
+
validate_event_keys(traces[1], kvs)
|
|
344
|
+
|
|
345
|
+
traces[1].key?("Layer").must_equal false
|
|
346
|
+
traces[1].key?("Class").must_equal false
|
|
347
|
+
traces[1].key?("File").must_equal true
|
|
348
|
+
traces[1].key?("LineNumber").must_equal true
|
|
349
|
+
|
|
350
|
+
kvs.clear
|
|
351
|
+
kvs["Label"] = "profile_exit"
|
|
352
|
+
kvs["Language"] = "ruby"
|
|
353
|
+
kvs["ProfileName"] = "do_work"
|
|
354
|
+
|
|
355
|
+
validate_event_keys(traces[2], kvs)
|
|
356
|
+
traces[2].key?("Layer").must_equal false
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
it 'should profile methods that use blocks' do
|
|
360
|
+
class TestKlass
|
|
361
|
+
def self.do_work(*)
|
|
362
|
+
yield
|
|
363
|
+
end
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
result = AppOpticsAPM::API.profile_method(TestKlass, :do_work)
|
|
367
|
+
assert_equal true, result, "profile_method return value must be true"
|
|
368
|
+
|
|
369
|
+
::AppOpticsAPM::API.start_trace('method_profiling', '', {}) do
|
|
370
|
+
result = TestKlass.do_work do
|
|
371
|
+
787
|
|
372
|
+
end
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
traces = get_all_traces
|
|
376
|
+
traces.count.must_equal 4
|
|
377
|
+
assert valid_edges?(traces), "Trace edge validation"
|
|
378
|
+
|
|
379
|
+
validate_outer_layers(traces, 'method_profiling')
|
|
380
|
+
|
|
381
|
+
result.must_equal 787
|
|
382
|
+
|
|
383
|
+
kvs = {}
|
|
384
|
+
kvs["Label"] = 'profile_entry'
|
|
385
|
+
kvs["Language"] = "ruby"
|
|
386
|
+
kvs["ProfileName"] = "do_work"
|
|
387
|
+
kvs["Class"] = "TestKlass"
|
|
388
|
+
kvs["MethodName"] = "do_work"
|
|
389
|
+
|
|
390
|
+
validate_event_keys(traces[1], kvs)
|
|
391
|
+
|
|
392
|
+
traces[1].key?("Layer").must_equal false
|
|
393
|
+
traces[1].key?("Module").must_equal false
|
|
394
|
+
traces[1].key?("File").must_equal true
|
|
395
|
+
traces[1].key?("LineNumber").must_equal true
|
|
396
|
+
|
|
397
|
+
kvs.clear
|
|
398
|
+
kvs["Label"] = "profile_exit"
|
|
399
|
+
kvs["Language"] = "ruby"
|
|
400
|
+
kvs["ProfileName"] = "do_work"
|
|
401
|
+
|
|
402
|
+
validate_event_keys(traces[2], kvs)
|
|
403
|
+
traces[2].key?("Layer").must_equal false
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
it 'should not store arguments and return value by default' do
|
|
407
|
+
class TestKlass
|
|
408
|
+
def do_work(*)
|
|
409
|
+
return 687
|
|
410
|
+
end
|
|
411
|
+
end
|
|
412
|
+
|
|
413
|
+
result = AppOpticsAPM::API.profile_method(TestKlass, :do_work)
|
|
414
|
+
assert_equal true, result, "profile_method return value must be true"
|
|
415
|
+
|
|
416
|
+
result = nil
|
|
417
|
+
|
|
418
|
+
::AppOpticsAPM::API.start_trace('method_profiling', '', {}) do
|
|
419
|
+
# Call the profiled class method
|
|
420
|
+
result = TestKlass.new.do_work(:ok => :blue)
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
traces = get_all_traces
|
|
424
|
+
traces.count.must_equal 4
|
|
425
|
+
assert valid_edges?(traces), "Trace edge validation"
|
|
426
|
+
|
|
427
|
+
validate_outer_layers(traces, 'method_profiling')
|
|
428
|
+
|
|
429
|
+
result.must_equal 687
|
|
430
|
+
|
|
431
|
+
kvs = {}
|
|
432
|
+
kvs["Label"] = 'profile_entry'
|
|
433
|
+
kvs["Language"] = "ruby"
|
|
434
|
+
kvs["ProfileName"] = "do_work"
|
|
435
|
+
kvs["Class"] = "TestKlass"
|
|
436
|
+
kvs["MethodName"] = "do_work"
|
|
437
|
+
|
|
438
|
+
validate_event_keys(traces[1], kvs)
|
|
439
|
+
|
|
440
|
+
traces[1].key?("Layer").must_equal false
|
|
441
|
+
traces[1].key?("Module").must_equal false
|
|
442
|
+
traces[1].key?("File").must_equal true
|
|
443
|
+
traces[1].key?("LineNumber").must_equal true
|
|
444
|
+
|
|
445
|
+
kvs.clear
|
|
446
|
+
kvs["Label"] = "profile_exit"
|
|
447
|
+
kvs["Language"] = "ruby"
|
|
448
|
+
kvs["ProfileName"] = "do_work"
|
|
449
|
+
|
|
450
|
+
validate_event_keys(traces[2], kvs)
|
|
451
|
+
traces[2].key?("Layer").must_equal false
|
|
452
|
+
|
|
453
|
+
traces[2].key?("Arguments").must_equal false
|
|
454
|
+
traces[2].key?("ReturnValue").must_equal false
|
|
455
|
+
end
|
|
456
|
+
|
|
457
|
+
it 'should store arguments and return value when asked' do
|
|
458
|
+
class TestKlass
|
|
459
|
+
def do_work(*)
|
|
460
|
+
return 687
|
|
461
|
+
end
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
opts = {}
|
|
465
|
+
opts[:arguments] = true
|
|
466
|
+
opts[:result] = true
|
|
467
|
+
|
|
468
|
+
result = AppOpticsAPM::API.profile_method(TestKlass, :do_work, opts)
|
|
469
|
+
assert_equal true, result, "profile_method return value must be true"
|
|
470
|
+
|
|
471
|
+
result = nil
|
|
472
|
+
|
|
473
|
+
::AppOpticsAPM::API.start_trace('method_profiling', '', {}) do
|
|
474
|
+
# Call the profiled class method
|
|
475
|
+
result = TestKlass.new.do_work(:ok => :blue)
|
|
476
|
+
end
|
|
477
|
+
|
|
478
|
+
traces = get_all_traces
|
|
479
|
+
traces.count.must_equal 4
|
|
480
|
+
assert valid_edges?(traces), "Trace edge validation"
|
|
481
|
+
|
|
482
|
+
validate_outer_layers(traces, 'method_profiling')
|
|
483
|
+
|
|
484
|
+
result.must_equal 687
|
|
485
|
+
|
|
486
|
+
kvs = {}
|
|
487
|
+
kvs["Label"] = 'profile_entry'
|
|
488
|
+
kvs["Language"] = "ruby"
|
|
489
|
+
kvs["ProfileName"] = "do_work"
|
|
490
|
+
kvs["Class"] = "TestKlass"
|
|
491
|
+
kvs["MethodName"] = "do_work"
|
|
492
|
+
|
|
493
|
+
validate_event_keys(traces[1], kvs)
|
|
494
|
+
|
|
495
|
+
traces[1].key?("Layer").must_equal false
|
|
496
|
+
traces[1].key?("Module").must_equal false
|
|
497
|
+
traces[1].key?("File").must_equal true
|
|
498
|
+
traces[1].key?("LineNumber").must_equal true
|
|
499
|
+
|
|
500
|
+
kvs.clear
|
|
501
|
+
kvs["Label"] = "profile_exit"
|
|
502
|
+
kvs["Language"] = "ruby"
|
|
503
|
+
kvs["ProfileName"] = "do_work"
|
|
504
|
+
|
|
505
|
+
validate_event_keys(traces[2], kvs)
|
|
506
|
+
traces[2].key?("Layer").must_equal false
|
|
507
|
+
|
|
508
|
+
traces[2].key?("Arguments").must_equal true
|
|
509
|
+
traces[2]["Arguments"].must_equal "[{:ok=>:blue}]"
|
|
510
|
+
|
|
511
|
+
traces[2].key?("ReturnValue").must_equal true
|
|
512
|
+
traces[2]["ReturnValue"].must_equal 687
|
|
513
|
+
end
|
|
514
|
+
|
|
515
|
+
it 'should not report backtraces by default' do
|
|
516
|
+
class TestKlass
|
|
517
|
+
def do_work(*)
|
|
518
|
+
return 687
|
|
519
|
+
end
|
|
520
|
+
end
|
|
521
|
+
|
|
522
|
+
result = AppOpticsAPM::API.profile_method(TestKlass, :do_work)
|
|
523
|
+
assert_equal true, result, "profile_method return value must be true"
|
|
524
|
+
|
|
525
|
+
result = nil
|
|
526
|
+
|
|
527
|
+
::AppOpticsAPM::API.start_trace('method_profiling', '', {}) do
|
|
528
|
+
# Call the profiled class method
|
|
529
|
+
result = TestKlass.new.do_work(:ok => :blue)
|
|
530
|
+
end
|
|
531
|
+
|
|
532
|
+
traces = get_all_traces
|
|
533
|
+
traces.count.must_equal 4
|
|
534
|
+
assert valid_edges?(traces), "Trace edge validation"
|
|
535
|
+
|
|
536
|
+
validate_outer_layers(traces, 'method_profiling')
|
|
537
|
+
|
|
538
|
+
result.must_equal 687
|
|
539
|
+
|
|
540
|
+
kvs = {}
|
|
541
|
+
kvs["Label"] = 'profile_entry'
|
|
542
|
+
kvs["Language"] = "ruby"
|
|
543
|
+
kvs["ProfileName"] = "do_work"
|
|
544
|
+
kvs["Class"] = "TestKlass"
|
|
545
|
+
kvs["MethodName"] = "do_work"
|
|
546
|
+
|
|
547
|
+
validate_event_keys(traces[1], kvs)
|
|
548
|
+
|
|
549
|
+
traces.each { |t|
|
|
550
|
+
t.key?("Backtrace").must_equal false, "shoudn't have backtrace"
|
|
551
|
+
}
|
|
552
|
+
end
|
|
553
|
+
|
|
554
|
+
it 'should report backtraces when requested' do
|
|
555
|
+
class TestKlass
|
|
556
|
+
def do_work(*)
|
|
557
|
+
return 687
|
|
558
|
+
end
|
|
559
|
+
end
|
|
560
|
+
|
|
561
|
+
opts = { :backtrace => true }
|
|
562
|
+
result = AppOpticsAPM::API.profile_method(TestKlass, :do_work, opts)
|
|
563
|
+
assert_equal true, result, "profile_method return value must be true"
|
|
564
|
+
|
|
565
|
+
result = nil
|
|
566
|
+
|
|
567
|
+
::AppOpticsAPM::API.start_trace('method_profiling', '', {}) do
|
|
568
|
+
# Call the profiled class method
|
|
569
|
+
result = TestKlass.new.do_work(:ok => :blue)
|
|
570
|
+
end
|
|
571
|
+
|
|
572
|
+
traces = get_all_traces
|
|
573
|
+
traces.count.must_equal 4
|
|
574
|
+
assert valid_edges?(traces), "Trace edge validation"
|
|
575
|
+
|
|
576
|
+
validate_outer_layers(traces, 'method_profiling')
|
|
577
|
+
|
|
578
|
+
result.must_equal 687
|
|
579
|
+
|
|
580
|
+
kvs = {}
|
|
581
|
+
kvs["Label"] = 'profile_entry'
|
|
582
|
+
kvs["Language"] = "ruby"
|
|
583
|
+
kvs["ProfileName"] = "do_work"
|
|
584
|
+
kvs["Class"] = "TestKlass"
|
|
585
|
+
kvs["MethodName"] = "do_work"
|
|
586
|
+
|
|
587
|
+
validate_event_keys(traces[1], kvs)
|
|
588
|
+
|
|
589
|
+
traces[1].key?("Backtrace").must_equal true, "should report a backtrace"
|
|
590
|
+
end
|
|
591
|
+
|
|
592
|
+
it 'should report extra KVs when requested' do
|
|
593
|
+
class TestKlass
|
|
594
|
+
def do_work(*)
|
|
595
|
+
return 687
|
|
596
|
+
end
|
|
597
|
+
end
|
|
598
|
+
|
|
599
|
+
opts = { :backtrace => true }
|
|
600
|
+
result = AppOpticsAPM::API.profile_method(TestKlass, :do_work, opts, :another => "value")
|
|
601
|
+
assert_equal true, result, "profile_method return value must be true"
|
|
602
|
+
|
|
603
|
+
result = nil
|
|
604
|
+
|
|
605
|
+
::AppOpticsAPM::API.start_trace('method_profiling', '', {}) do
|
|
606
|
+
# Call the profiled class method
|
|
607
|
+
result = TestKlass.new.do_work(:ok => :blue)
|
|
608
|
+
end
|
|
609
|
+
|
|
610
|
+
traces = get_all_traces
|
|
611
|
+
traces.count.must_equal 4
|
|
612
|
+
assert valid_edges?(traces), "Trace edge validation"
|
|
613
|
+
|
|
614
|
+
validate_outer_layers(traces, 'method_profiling')
|
|
615
|
+
|
|
616
|
+
result.must_equal 687
|
|
617
|
+
|
|
618
|
+
kvs = {}
|
|
619
|
+
kvs["Label"] = 'profile_entry'
|
|
620
|
+
kvs["Language"] = "ruby"
|
|
621
|
+
kvs["ProfileName"] = "do_work"
|
|
622
|
+
kvs["Class"] = "TestKlass"
|
|
623
|
+
kvs["MethodName"] = "do_work"
|
|
624
|
+
kvs["another"] = "value"
|
|
625
|
+
|
|
626
|
+
validate_event_keys(traces[1], kvs)
|
|
627
|
+
|
|
628
|
+
traces[1].key?("Backtrace").must_equal true, "should report a backtrace"
|
|
629
|
+
end
|
|
630
|
+
end
|
|
631
|
+
end
|