traceview 3.0.0-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.rubocop.yml +5 -0
  4. data/.travis.yml +58 -0
  5. data/Appraisals +10 -0
  6. data/CHANGELOG.md +490 -0
  7. data/CONFIG.md +16 -0
  8. data/Gemfile +95 -0
  9. data/LICENSE +199 -0
  10. data/README.md +380 -0
  11. data/Rakefile +109 -0
  12. data/examples/DNT.md +35 -0
  13. data/examples/carrying_context.rb +225 -0
  14. data/examples/instrumenting_metal_controller.rb +8 -0
  15. data/examples/puma_on_heroku_config.rb +17 -0
  16. data/examples/tracing_async_threads.rb +125 -0
  17. data/examples/tracing_background_jobs.rb +52 -0
  18. data/examples/tracing_forked_processes.rb +100 -0
  19. data/examples/unicorn_on_heroku_config.rb +28 -0
  20. data/ext/oboe_metal/extconf.rb +61 -0
  21. data/ext/oboe_metal/noop/noop.c +7 -0
  22. data/ext/oboe_metal/src/bson/bson.h +221 -0
  23. data/ext/oboe_metal/src/bson/platform_hacks.h +91 -0
  24. data/ext/oboe_metal/src/oboe.h +275 -0
  25. data/ext/oboe_metal/src/oboe.hpp +352 -0
  26. data/ext/oboe_metal/src/oboe_wrap.cxx +3886 -0
  27. data/ext/oboe_metal/tests/test.rb +11 -0
  28. data/gemfiles/mongo.gemfile +33 -0
  29. data/gemfiles/moped.gemfile +33 -0
  30. data/get_version.rb +5 -0
  31. data/init.rb +4 -0
  32. data/lib/joboe_metal.rb +206 -0
  33. data/lib/oboe/README +2 -0
  34. data/lib/oboe/backward_compatibility.rb +59 -0
  35. data/lib/oboe/inst/rack.rb +11 -0
  36. data/lib/oboe.rb +7 -0
  37. data/lib/oboe_metal.rb +151 -0
  38. data/lib/rails/generators/traceview/install_generator.rb +76 -0
  39. data/lib/rails/generators/traceview/templates/traceview_initializer.rb +159 -0
  40. data/lib/traceview/api/layerinit.rb +51 -0
  41. data/lib/traceview/api/logging.rb +209 -0
  42. data/lib/traceview/api/memcache.rb +31 -0
  43. data/lib/traceview/api/profiling.rb +50 -0
  44. data/lib/traceview/api/tracing.rb +135 -0
  45. data/lib/traceview/api/util.rb +121 -0
  46. data/lib/traceview/api.rb +18 -0
  47. data/lib/traceview/base.rb +225 -0
  48. data/lib/traceview/config.rb +238 -0
  49. data/lib/traceview/frameworks/grape.rb +97 -0
  50. data/lib/traceview/frameworks/padrino/templates.rb +58 -0
  51. data/lib/traceview/frameworks/padrino.rb +64 -0
  52. data/lib/traceview/frameworks/rails/helpers/rum/rum_ajax_header.js.erb +5 -0
  53. data/lib/traceview/frameworks/rails/helpers/rum/rum_footer.js.erb +1 -0
  54. data/lib/traceview/frameworks/rails/helpers/rum/rum_header.js.erb +3 -0
  55. data/lib/traceview/frameworks/rails/inst/action_controller.rb +216 -0
  56. data/lib/traceview/frameworks/rails/inst/action_view.rb +56 -0
  57. data/lib/traceview/frameworks/rails/inst/action_view_2x.rb +54 -0
  58. data/lib/traceview/frameworks/rails/inst/action_view_30.rb +48 -0
  59. data/lib/traceview/frameworks/rails/inst/active_record.rb +24 -0
  60. data/lib/traceview/frameworks/rails/inst/connection_adapters/mysql.rb +43 -0
  61. data/lib/traceview/frameworks/rails/inst/connection_adapters/mysql2.rb +28 -0
  62. data/lib/traceview/frameworks/rails/inst/connection_adapters/oracle.rb +18 -0
  63. data/lib/traceview/frameworks/rails/inst/connection_adapters/postgresql.rb +30 -0
  64. data/lib/traceview/frameworks/rails/inst/connection_adapters/utils.rb +117 -0
  65. data/lib/traceview/frameworks/rails.rb +145 -0
  66. data/lib/traceview/frameworks/sinatra/templates.rb +56 -0
  67. data/lib/traceview/frameworks/sinatra.rb +95 -0
  68. data/lib/traceview/inst/cassandra.rb +279 -0
  69. data/lib/traceview/inst/dalli.rb +86 -0
  70. data/lib/traceview/inst/em-http-request.rb +99 -0
  71. data/lib/traceview/inst/excon.rb +111 -0
  72. data/lib/traceview/inst/faraday.rb +73 -0
  73. data/lib/traceview/inst/http.rb +87 -0
  74. data/lib/traceview/inst/httpclient.rb +173 -0
  75. data/lib/traceview/inst/memcache.rb +102 -0
  76. data/lib/traceview/inst/memcached.rb +94 -0
  77. data/lib/traceview/inst/mongo.rb +238 -0
  78. data/lib/traceview/inst/moped.rb +474 -0
  79. data/lib/traceview/inst/rack.rb +122 -0
  80. data/lib/traceview/inst/redis.rb +271 -0
  81. data/lib/traceview/inst/resque.rb +192 -0
  82. data/lib/traceview/inst/rest-client.rb +38 -0
  83. data/lib/traceview/inst/sequel.rb +162 -0
  84. data/lib/traceview/inst/typhoeus.rb +102 -0
  85. data/lib/traceview/instrumentation.rb +21 -0
  86. data/lib/traceview/loading.rb +94 -0
  87. data/lib/traceview/logger.rb +41 -0
  88. data/lib/traceview/method_profiling.rb +84 -0
  89. data/lib/traceview/ruby.rb +36 -0
  90. data/lib/traceview/support.rb +113 -0
  91. data/lib/traceview/thread_local.rb +26 -0
  92. data/lib/traceview/util.rb +250 -0
  93. data/lib/traceview/version.rb +16 -0
  94. data/lib/traceview/xtrace.rb +90 -0
  95. data/lib/traceview.rb +62 -0
  96. data/test/frameworks/apps/grape_nested.rb +30 -0
  97. data/test/frameworks/apps/grape_simple.rb +24 -0
  98. data/test/frameworks/apps/padrino_simple.rb +45 -0
  99. data/test/frameworks/apps/sinatra_simple.rb +24 -0
  100. data/test/frameworks/grape_test.rb +142 -0
  101. data/test/frameworks/padrino_test.rb +30 -0
  102. data/test/frameworks/sinatra_test.rb +30 -0
  103. data/test/instrumentation/cassandra_test.rb +380 -0
  104. data/test/instrumentation/dalli_test.rb +171 -0
  105. data/test/instrumentation/em_http_request_test.rb +86 -0
  106. data/test/instrumentation/excon_test.rb +207 -0
  107. data/test/instrumentation/faraday_test.rb +235 -0
  108. data/test/instrumentation/http_test.rb +140 -0
  109. data/test/instrumentation/httpclient_test.rb +296 -0
  110. data/test/instrumentation/memcache_test.rb +251 -0
  111. data/test/instrumentation/memcached_test.rb +226 -0
  112. data/test/instrumentation/mongo_test.rb +462 -0
  113. data/test/instrumentation/moped_test.rb +496 -0
  114. data/test/instrumentation/rack_test.rb +116 -0
  115. data/test/instrumentation/redis_hashes_test.rb +265 -0
  116. data/test/instrumentation/redis_keys_test.rb +318 -0
  117. data/test/instrumentation/redis_lists_test.rb +310 -0
  118. data/test/instrumentation/redis_misc_test.rb +160 -0
  119. data/test/instrumentation/redis_sets_test.rb +293 -0
  120. data/test/instrumentation/redis_sortedsets_test.rb +325 -0
  121. data/test/instrumentation/redis_strings_test.rb +333 -0
  122. data/test/instrumentation/resque_test.rb +62 -0
  123. data/test/instrumentation/rest-client_test.rb +294 -0
  124. data/test/instrumentation/sequel_mysql2_test.rb +326 -0
  125. data/test/instrumentation/sequel_mysql_test.rb +326 -0
  126. data/test/instrumentation/sequel_pg_test.rb +330 -0
  127. data/test/instrumentation/typhoeus_test.rb +285 -0
  128. data/test/minitest_helper.rb +187 -0
  129. data/test/profiling/method_test.rb +198 -0
  130. data/test/servers/rackapp_8101.rb +22 -0
  131. data/test/support/backcompat_test.rb +269 -0
  132. data/test/support/config_test.rb +128 -0
  133. data/test/support/dnt_test.rb +73 -0
  134. data/test/support/liboboe_settings_test.rb +104 -0
  135. data/test/support/xtrace_test.rb +35 -0
  136. data/traceview.gemspec +29 -0
  137. metadata +248 -0
@@ -0,0 +1,187 @@
1
+ require "minitest/spec"
2
+ require "minitest/autorun"
3
+ require "minitest/reporters"
4
+ require "minitest/debugger" if ENV['DEBUG']
5
+
6
+ ENV["RACK_ENV"] = "test"
7
+ ENV["TRACEVIEW_GEM_TEST"] = "true"
8
+ ENV["TRACEVIEW_GEM_VERBOSE"] = "true"
9
+
10
+ # FIXME: Temp hack to fix padrino-core calling RUBY_ENGINE when it's
11
+ # not defined under Ruby 1.8.7 and 1.9.3
12
+ RUBY_ENGINE = "ruby" unless defined?(RUBY_ENGINE)
13
+
14
+ Minitest::Spec.new 'pry'
15
+
16
+ unless RUBY_VERSION =~ /^1.8/
17
+ MiniTest::Reporters.use! MiniTest::Reporters::SpecReporter.new
18
+ end
19
+
20
+ if defined?(JRUBY_VERSION)
21
+ ENV['JAVA_OPTS'] = "-J-javaagent:/usr/local/tracelytics/tracelyticsagent.jar"
22
+ end
23
+
24
+ require 'rubygems'
25
+ require 'bundler'
26
+
27
+ # Preload memcache-client
28
+ require 'memcache'
29
+
30
+ Bundler.require(:default, :test)
31
+
32
+ @trace_dir = "/tmp/"
33
+ $trace_file = @trace_dir + "trace_output.bson"
34
+
35
+ # Configure TraceView
36
+ TraceView::Config[:verbose] = true
37
+ TraceView::Config[:tracing_mode] = "always"
38
+ TraceView::Config[:sample_rate] = 1000000
39
+ TraceView.logger.level = Logger::DEBUG
40
+
41
+ # Our background Rack-app for http client testing
42
+ require "./test/servers/rackapp_8101"
43
+
44
+ ##
45
+ # clear_all_traces
46
+ #
47
+ # Truncates the trace output file to zero
48
+ #
49
+ def clear_all_traces
50
+ TraceView::Reporter.clear_all_traces
51
+ end
52
+
53
+ ##
54
+ # get_all_traces
55
+ #
56
+ # Retrieves all traces written to the trace file
57
+ #
58
+ def get_all_traces
59
+ TraceView::Reporter.get_all_traces
60
+ end
61
+
62
+ ##
63
+ # validate_outer_layers
64
+ #
65
+ # Validates that the KVs in kvs are present
66
+ # in event
67
+ #
68
+ def validate_outer_layers(traces, layer)
69
+ traces.first['Layer'].must_equal layer
70
+ traces.first['Label'].must_equal 'entry'
71
+ traces.last['Layer'].must_equal layer
72
+ traces.last['Label'].must_equal 'exit'
73
+ end
74
+
75
+ ##
76
+ # validate_event_keys
77
+ #
78
+ # Validates that the KVs in kvs are present
79
+ # in event
80
+ #
81
+ def validate_event_keys(event, kvs)
82
+ kvs.each do |k, v|
83
+ event.has_key?(k).must_equal true
84
+ event[k].must_equal v
85
+ end
86
+ end
87
+
88
+ ##
89
+ # has_edge?
90
+ #
91
+ # Searches the array of <tt>traces</tt> for
92
+ # <tt>edge</tt>
93
+ #
94
+ def has_edge?(edge, traces)
95
+ traces.each do |t|
96
+ if TraceView::XTrace.edge_id(t["X-Trace"]) == edge
97
+ return true
98
+ end
99
+ end
100
+ TraceView.logger.debug "[oboe/debug] edge #{edge} not found in traces."
101
+ false
102
+ end
103
+
104
+ ##
105
+ # valid_edges?
106
+ #
107
+ # Runs through the array of <tt>traces</tt> to validate
108
+ # that all edges connect.
109
+ #
110
+ # Not that this won't work for external cross-app tracing
111
+ # since we won't have those remote traces to validate
112
+ # against.
113
+ #
114
+ def valid_edges?(traces)
115
+ traces.reverse.each do |t|
116
+ if t.key?("Edge")
117
+ return false unless has_edge?(t["Edge"], traces)
118
+ end
119
+ end
120
+ true
121
+ end
122
+
123
+ ##
124
+ # layer_has_key
125
+ #
126
+ # Checks an array of trace events if a specific layer (regardless of event type)
127
+ # has he specified key
128
+ #
129
+ def layer_has_key(traces, layer, key)
130
+ return false if traces.empty?
131
+ has_key = false
132
+
133
+ traces.each do |t|
134
+ if t["Layer"] == layer and t.has_key?(key)
135
+ has_key = true
136
+
137
+ (t["Backtrace"].length > 0).must_equal true
138
+ end
139
+ end
140
+
141
+ has_key.must_equal true
142
+ end
143
+
144
+ ##
145
+ # layer_doesnt_have_key
146
+ #
147
+ # Checks an array of trace events to assure that a specific layer
148
+ # (regardless of event type) doesn't have the specified key
149
+ #
150
+ def layer_doesnt_have_key(traces, layer, key)
151
+ return false if traces.empty?
152
+ has_key = false
153
+
154
+ traces.each do |t|
155
+ has_key = true if t["Layer"] == layer and t.has_key?(key)
156
+ end
157
+
158
+ has_key.must_equal false
159
+ end
160
+
161
+ ##
162
+ # Sinatra and Padrino Related Helpers
163
+ #
164
+ # Taken from padrino-core gem
165
+ #
166
+
167
+ class Sinatra::Base
168
+ # Allow assertions in request context
169
+ include MiniTest::Assertions
170
+ end
171
+
172
+
173
+ class MiniTest::Spec
174
+ include Rack::Test::Methods
175
+
176
+ # Sets up a Sinatra::Base subclass defined with the block
177
+ # given. Used in setup or individual spec methods to establish
178
+ # the application.
179
+ def mock_app(base=Padrino::Application, &block)
180
+ @app = Sinatra.new(base, &block)
181
+ end
182
+
183
+ def app
184
+ Rack::Lint.new(@app)
185
+ end
186
+ end
187
+
@@ -0,0 +1,198 @@
1
+ require 'minitest_helper'
2
+
3
+ describe "TraceViewMethodProfiling" do
4
+ before do
5
+ clear_all_traces
6
+ # Conditionally Undefine TestWorker
7
+ # http://stackoverflow.com/questions/11503558/how-to-undefine-class-in-ruby
8
+ Object.send(:remove_const, :TestWorker) if defined?(TestWorker)
9
+ end
10
+
11
+ it 'should be loaded, defined and ready' do
12
+ defined?(::TraceViewMethodProfiling).wont_match nil
13
+ end
14
+
15
+ it 'should trace Class methods' do
16
+ class TestWorker
17
+ def self.do_work
18
+ sleep 1
19
+ end
20
+
21
+ class << self
22
+ include TraceViewMethodProfiling
23
+ profile_method :do_work, 'do_work'
24
+ end
25
+ end
26
+
27
+ ::TraceView::API.start_trace('method_profiling', '', {}) do
28
+ # Call the profiled class method
29
+ TestWorker.do_work
30
+ end
31
+
32
+ traces = get_all_traces
33
+ traces.count.must_equal 4
34
+
35
+ validate_outer_layers(traces, 'method_profiling')
36
+
37
+ kvs = {}
38
+ kvs["Label"] = 'profile_entry'
39
+ kvs["Language"] = "ruby"
40
+ kvs["ProfileName"] = "do_work"
41
+ kvs["FunctionName"] = "do_work"
42
+ kvs["Class"] = "TestWorker"
43
+
44
+ validate_event_keys(traces[1], kvs)
45
+
46
+ traces[1].has_key?("Layer").must_equal false
47
+ traces[1].has_key?("File").must_equal true
48
+ traces[1].has_key?("LineNumber").must_equal true
49
+
50
+ kvs.clear
51
+ kvs["Label"] = "profile_exit"
52
+ kvs["Language"] = "ruby"
53
+ kvs["ProfileName"] = "do_work"
54
+
55
+ validate_event_keys(traces[2], kvs)
56
+ traces[2].has_key?("Layer").must_equal false
57
+ end
58
+
59
+ it 'should trace Instance methods' do
60
+ class TestWorker
61
+ def do_work
62
+ sleep 1
63
+ end
64
+
65
+ include TraceViewMethodProfiling
66
+ profile_method :do_work, 'do_work'
67
+ end
68
+
69
+ ::TraceView::API.start_trace('method_profiling', '', {}) do
70
+ # Call the profiled class method
71
+ tw = TestWorker.new
72
+ tw.do_work
73
+ end
74
+
75
+ traces = get_all_traces
76
+ traces.count.must_equal 4
77
+
78
+ validate_outer_layers(traces, 'method_profiling')
79
+
80
+ kvs = {}
81
+ kvs["Label"] = 'profile_entry'
82
+ kvs["Language"] = "ruby"
83
+ kvs["ProfileName"] = "do_work"
84
+ kvs["FunctionName"] = "do_work"
85
+ kvs["Class"] = "TestWorker"
86
+
87
+ validate_event_keys(traces[1], kvs)
88
+
89
+ traces[1].has_key?("Layer").must_equal false
90
+ traces[1].has_key?("File").must_equal true
91
+ traces[1].has_key?("LineNumber").must_equal true
92
+
93
+ kvs.clear
94
+ kvs["Label"] = "profile_exit"
95
+ kvs["Language"] = "ruby"
96
+ kvs["ProfileName"] = "do_work"
97
+
98
+ validate_event_keys(traces[2], kvs)
99
+ traces[2].has_key?("Layer").must_equal false
100
+ end
101
+
102
+ it 'should trace Module class methods' do
103
+ module TestWorker
104
+ def self.do_work
105
+ sleep 1
106
+ end
107
+
108
+ class << self
109
+ include TraceViewMethodProfiling
110
+ profile_method :do_work, 'do_work'
111
+ end
112
+ end
113
+
114
+ ::TraceView::API.start_trace('method_profiling', '', {}) do
115
+ # Call the profiled class method
116
+ TestWorker.do_work
117
+ end
118
+
119
+ traces = get_all_traces
120
+ traces.count.must_equal 4
121
+ validate_outer_layers(traces, 'method_profiling')
122
+
123
+ kvs = {}
124
+ kvs["Label"] = 'profile_entry'
125
+ kvs["Language"] = "ruby"
126
+ kvs["ProfileName"] = "do_work"
127
+ kvs["FunctionName"] = "do_work"
128
+ kvs["Module"] = "TestWorker"
129
+
130
+ validate_event_keys(traces[1], kvs)
131
+
132
+ traces[1].has_key?("Layer").must_equal false
133
+ traces[1].has_key?("File").must_equal true
134
+ traces[1].has_key?("LineNumber").must_equal true
135
+
136
+ kvs.clear
137
+ kvs["Label"] = "profile_exit"
138
+ kvs["Language"] = "ruby"
139
+ kvs["ProfileName"] = "do_work"
140
+
141
+ validate_event_keys(traces[2], kvs)
142
+ traces[2].has_key?("Layer").must_equal false
143
+ end
144
+
145
+ it 'should not store arguments and return value by default' do
146
+ class TestWorker
147
+ def self.do_work(s, i, a, h)
148
+ sleep 1
149
+ return "the zebra is loose"
150
+ end
151
+
152
+ class << self
153
+ include TraceViewMethodProfiling
154
+ # Default call method
155
+ profile_method :do_work, 'do_work'
156
+ end
157
+ end
158
+
159
+ ::TraceView::API.start_trace('method_profiling', '', {}) do
160
+ # Call the profiled class method
161
+ TestWorker.do_work('String Argument', 203984, ["1", "2", 3], { :color => :black })
162
+ end
163
+
164
+ traces = get_all_traces
165
+ traces.count.must_equal 4
166
+
167
+ traces[1].has_key?("Args").must_equal false
168
+ traces[2].has_key?("ReturnValue").must_equal false
169
+ end
170
+
171
+ it 'should store arguments and return value when asked' do
172
+ class TestWorker
173
+ def self.do_work(s, i, a, h)
174
+ sleep 1
175
+ return "the zebra is loose"
176
+ end
177
+
178
+ class << self
179
+ include TraceViewMethodProfiling
180
+ profile_method :do_work, 'do_work', true, true
181
+ end
182
+ end
183
+
184
+ ::TraceView::API.start_trace('method_profiling', '', {}) do
185
+ # Call the profiled class method
186
+ TestWorker.do_work('String Argument', 203984, ["1", "2", 3], { :color => :black })
187
+ end
188
+
189
+ traces = get_all_traces
190
+ traces.count.must_equal 4
191
+
192
+ traces[1].has_key?("Args").must_equal true
193
+ traces[1]["Args"].must_equal "\"String Argument\"\n203984\n[\"1\", \"2\", 3]\n{:color=>:black}\n"
194
+
195
+ traces[2].has_key?("ReturnValue").must_equal true
196
+ traces[2]["ReturnValue"].must_equal "\"the zebra is loose\"\n"
197
+ end
198
+ end
@@ -0,0 +1,22 @@
1
+ # Copyright (c) 2015 AppNeta, Inc.
2
+ # All rights reserved.
3
+
4
+ require 'rack/handler/puma'
5
+ require 'traceview/inst/rack'
6
+
7
+ TraceView.logger.info "[oboe/info] Starting background utility rack app on localhost:8101."
8
+
9
+ Thread.new do
10
+ app = Rack::Builder.new {
11
+ use TraceView::Rack
12
+ run Proc.new { |env|
13
+ [200, {"Content-Type" => "text/html"}, ['Hello TraceView!']]
14
+ }
15
+ }
16
+
17
+ Rack::Handler::Puma.run(app, {:Host => '127.0.0.1', :Port => 8101})
18
+ end
19
+
20
+ # Allow Thin to boot.
21
+ sleep(2)
22
+
@@ -0,0 +1,269 @@
1
+ require 'minitest_helper'
2
+
3
+ describe "BackwardCompatibility" do
4
+
5
+ it 'should still respond to Oboe::Config' do
6
+ @verbose = Oboe::Config[:verbose]
7
+ @dalli_enabled = Oboe::Config[:dalli][:enabled]
8
+ @tm = Oboe::Config[:tracing_mode]
9
+ @sr = Oboe::Config[:sample_rate]
10
+
11
+ Oboe::Config[:verbose] = true
12
+ Oboe::Config[:verbose].must_equal true
13
+ Oboe::Config.verbose.must_equal true
14
+ TraceView::Config[:verbose].must_equal true
15
+ TraceView::Config.verbose.must_equal true
16
+
17
+ Oboe::Config[:dalli][:enabled] = false
18
+ Oboe::Config[:dalli][:enabled].must_equal false
19
+ TraceView::Config[:dalli][:enabled].must_equal false
20
+
21
+ Oboe::Config[:sample_rate] = 8e5
22
+ Oboe::Config.sample_rate.must_equal 8e5
23
+ TraceView::Config.sample_rate.must_equal 8e5
24
+
25
+ Oboe::Config[:tracing_mode] = 'always'
26
+ Oboe::Config.tracing_mode.must_equal 'always'
27
+ TraceView::Config.tracing_mode.must_equal 'always'
28
+
29
+ Oboe::Config[:sample_rate] = @sr
30
+ Oboe::Config[:tracing_mode] = @tm
31
+ Oboe::Config[:dalli][:enabled] = @dalli_enabled
32
+ Oboe::Config[:verbose] = @verbose
33
+ end
34
+
35
+ it 'should still support Oboe::API.log calls' do
36
+ clear_all_traces
37
+
38
+ Oboe::API.log_start('rack', nil, {})
39
+ Oboe::API.log_end('rack')
40
+
41
+ traces = get_all_traces
42
+ traces.count.must_equal 2
43
+ end
44
+
45
+ it 'should still support Oboe::API.trace calls' do
46
+ clear_all_traces
47
+
48
+ Oboe::API.start_trace('api_test', '', {}) do
49
+ sleep 1
50
+ end
51
+
52
+ traces = get_all_traces
53
+ traces.count.must_equal 2
54
+
55
+ validate_outer_layers(traces, 'api_test')
56
+ end
57
+
58
+ it 'should still support Oboe.profile'do
59
+ clear_all_traces
60
+
61
+ Oboe::API.start_trace('outer_profile_test') do
62
+ Oboe::API.profile('profile_test', {}, false) do
63
+ sleep 1
64
+ end
65
+ end
66
+
67
+ traces = get_all_traces
68
+ traces.count.must_equal 4
69
+ end
70
+
71
+ # Pasted in from test/profiling/method_test.rb
72
+ # Modified to use OboeMethodProfiling
73
+ describe "OboeMethodProfiling" do
74
+ before do
75
+ clear_all_traces
76
+ # Conditionally Undefine TestWorker
77
+ # http://stackoverflow.com/questions/11503558/how-to-undefine-class-in-ruby
78
+ Object.send(:remove_const, :TestWorker) if defined?(TestWorker)
79
+ end
80
+
81
+ it 'should be loaded, defined and ready' do
82
+ defined?(::OboeMethodProfiling).wont_match nil
83
+ end
84
+
85
+ it 'should trace Class methods' do
86
+ class TestWorker
87
+ def self.do_work
88
+ sleep 1
89
+ end
90
+
91
+ class << self
92
+ include OboeMethodProfiling
93
+ profile_method :do_work, 'do_work'
94
+ end
95
+ end
96
+
97
+ ::Oboe::API.start_trace('method_profiling', '', {}) do
98
+ # Call the profiled class method
99
+ TestWorker.do_work
100
+ end
101
+
102
+ traces = get_all_traces
103
+ traces.count.must_equal 4
104
+
105
+ validate_outer_layers(traces, 'method_profiling')
106
+
107
+ kvs = {}
108
+ kvs["Label"] = 'profile_entry'
109
+ kvs["Language"] = "ruby"
110
+ kvs["ProfileName"] = "do_work"
111
+ kvs["FunctionName"] = "do_work"
112
+ kvs["Class"] = "TestWorker"
113
+
114
+ validate_event_keys(traces[1], kvs)
115
+
116
+ traces[1].has_key?("Layer").must_equal false
117
+ traces[1].has_key?("File").must_equal true
118
+ traces[1].has_key?("LineNumber").must_equal true
119
+
120
+ kvs.clear
121
+ kvs["Label"] = "profile_exit"
122
+ kvs["Language"] = "ruby"
123
+ kvs["ProfileName"] = "do_work"
124
+
125
+ validate_event_keys(traces[2], kvs)
126
+ traces[2].has_key?("Layer").must_equal false
127
+ end
128
+
129
+ it 'should trace Instance methods' do
130
+ class TestWorker
131
+ def do_work
132
+ sleep 1
133
+ end
134
+
135
+ include OboeMethodProfiling
136
+ profile_method :do_work, 'do_work'
137
+ end
138
+
139
+ ::Oboe::API.start_trace('method_profiling', '', {}) do
140
+ # Call the profiled class method
141
+ tw = TestWorker.new
142
+ tw.do_work
143
+ end
144
+
145
+ traces = get_all_traces
146
+ traces.count.must_equal 4
147
+
148
+ validate_outer_layers(traces, 'method_profiling')
149
+
150
+ kvs = {}
151
+ kvs["Label"] = 'profile_entry'
152
+ kvs["Language"] = "ruby"
153
+ kvs["ProfileName"] = "do_work"
154
+ kvs["FunctionName"] = "do_work"
155
+ kvs["Class"] = "TestWorker"
156
+
157
+ validate_event_keys(traces[1], kvs)
158
+
159
+ traces[1].has_key?("Layer").must_equal false
160
+ traces[1].has_key?("File").must_equal true
161
+ traces[1].has_key?("LineNumber").must_equal true
162
+
163
+ kvs.clear
164
+ kvs["Label"] = "profile_exit"
165
+ kvs["Language"] = "ruby"
166
+ kvs["ProfileName"] = "do_work"
167
+
168
+ validate_event_keys(traces[2], kvs)
169
+ traces[2].has_key?("Layer").must_equal false
170
+ end
171
+
172
+ it 'should trace Module class methods' do
173
+ module TestWorker
174
+ def self.do_work
175
+ sleep 1
176
+ end
177
+
178
+ class << self
179
+ include OboeMethodProfiling
180
+ profile_method :do_work, 'do_work'
181
+ end
182
+ end
183
+
184
+ ::Oboe::API.start_trace('method_profiling', '', {}) do
185
+ # Call the profiled class method
186
+ TestWorker.do_work
187
+ end
188
+
189
+ traces = get_all_traces
190
+ traces.count.must_equal 4
191
+ validate_outer_layers(traces, 'method_profiling')
192
+
193
+ kvs = {}
194
+ kvs["Label"] = 'profile_entry'
195
+ kvs["Language"] = "ruby"
196
+ kvs["ProfileName"] = "do_work"
197
+ kvs["FunctionName"] = "do_work"
198
+ kvs["Module"] = "TestWorker"
199
+
200
+ validate_event_keys(traces[1], kvs)
201
+
202
+ traces[1].has_key?("Layer").must_equal false
203
+ traces[1].has_key?("File").must_equal true
204
+ traces[1].has_key?("LineNumber").must_equal true
205
+
206
+ kvs.clear
207
+ kvs["Label"] = "profile_exit"
208
+ kvs["Language"] = "ruby"
209
+ kvs["ProfileName"] = "do_work"
210
+
211
+ validate_event_keys(traces[2], kvs)
212
+ traces[2].has_key?("Layer").must_equal false
213
+ end
214
+
215
+ it 'should not store arguments and return value by default' do
216
+ class TestWorker
217
+ def self.do_work(s, i, a, h)
218
+ sleep 1
219
+ return "the zebra is loose"
220
+ end
221
+
222
+ class << self
223
+ include OboeMethodProfiling
224
+ # Default call method
225
+ profile_method :do_work, 'do_work'
226
+ end
227
+ end
228
+
229
+ ::Oboe::API.start_trace('method_profiling', '', {}) do
230
+ # Call the profiled class method
231
+ TestWorker.do_work('String Argument', 203984, ["1", "2", 3], { :color => :black })
232
+ end
233
+
234
+ traces = get_all_traces
235
+ traces.count.must_equal 4
236
+
237
+ traces[1].has_key?("Args").must_equal false
238
+ traces[2].has_key?("ReturnValue").must_equal false
239
+ end
240
+
241
+ it 'should store arguments and return value when asked' do
242
+ class TestWorker
243
+ def self.do_work(s, i, a, h)
244
+ sleep 1
245
+ return "the zebra is loose"
246
+ end
247
+
248
+ class << self
249
+ include OboeMethodProfiling
250
+ profile_method :do_work, 'do_work', true, true
251
+ end
252
+ end
253
+
254
+ ::Oboe::API.start_trace('method_profiling', '', {}) do
255
+ # Call the profiled class method
256
+ TestWorker.do_work('String Argument', 203984, ["1", "2", 3], { :color => :black })
257
+ end
258
+
259
+ traces = get_all_traces
260
+ traces.count.must_equal 4
261
+
262
+ traces[1].has_key?("Args").must_equal true
263
+ traces[1]["Args"].must_equal "\"String Argument\"\n203984\n[\"1\", \"2\", 3]\n{:color=>:black}\n"
264
+
265
+ traces[2].has_key?("ReturnValue").must_equal true
266
+ traces[2]["ReturnValue"].must_equal "\"the zebra is loose\"\n"
267
+ end
268
+ end
269
+ end