ruby-prof 0.18.0 → 1.2.0
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 +4 -4
- data/CHANGES +44 -1
- data/LICENSE +2 -2
- data/README.rdoc +1 -483
- data/Rakefile +3 -6
- data/bin/ruby-prof +111 -128
- data/ext/ruby_prof/extconf.rb +6 -38
- data/ext/ruby_prof/rp_aggregate_call_tree.c +41 -0
- data/ext/ruby_prof/rp_aggregate_call_tree.h +13 -0
- data/ext/ruby_prof/rp_allocation.c +259 -0
- data/ext/ruby_prof/rp_allocation.h +31 -0
- data/ext/ruby_prof/rp_call_tree.c +353 -0
- data/ext/ruby_prof/rp_call_tree.h +43 -0
- data/ext/ruby_prof/rp_call_trees.c +266 -0
- data/ext/ruby_prof/rp_call_trees.h +29 -0
- data/ext/ruby_prof/rp_measure_allocations.c +25 -51
- data/ext/ruby_prof/rp_measure_memory.c +21 -56
- data/ext/ruby_prof/rp_measure_process_time.c +37 -43
- data/ext/ruby_prof/rp_measure_wall_time.c +40 -21
- data/ext/ruby_prof/rp_measurement.c +221 -0
- data/ext/ruby_prof/rp_measurement.h +50 -0
- data/ext/ruby_prof/rp_method.c +279 -439
- data/ext/ruby_prof/rp_method.h +33 -45
- data/ext/ruby_prof/rp_profile.c +902 -0
- data/ext/ruby_prof/rp_profile.h +36 -0
- data/ext/ruby_prof/rp_stack.c +163 -132
- data/ext/ruby_prof/rp_stack.h +18 -28
- data/ext/ruby_prof/rp_thread.c +192 -124
- data/ext/ruby_prof/rp_thread.h +18 -8
- data/ext/ruby_prof/ruby_prof.c +36 -778
- data/ext/ruby_prof/ruby_prof.h +11 -45
- data/ext/ruby_prof/vc/ruby_prof.vcxproj +18 -12
- data/lib/ruby-prof.rb +4 -21
- data/lib/ruby-prof/assets/call_stack_printer.html.erb +710 -0
- data/lib/ruby-prof/assets/call_stack_printer.png +0 -0
- data/lib/ruby-prof/assets/graph_printer.html.erb +355 -0
- data/lib/ruby-prof/call_tree.rb +57 -0
- data/lib/ruby-prof/call_tree_visitor.rb +36 -0
- data/lib/ruby-prof/compatibility.rb +37 -107
- data/lib/ruby-prof/exclude_common_methods.rb +198 -0
- data/lib/ruby-prof/measurement.rb +17 -0
- data/lib/ruby-prof/method_info.rb +47 -90
- data/lib/ruby-prof/printers/abstract_printer.rb +73 -50
- data/lib/ruby-prof/printers/call_info_printer.rb +24 -12
- data/lib/ruby-prof/printers/call_stack_printer.rb +66 -152
- data/lib/ruby-prof/printers/call_tree_printer.rb +20 -12
- data/lib/ruby-prof/printers/dot_printer.rb +5 -5
- data/lib/ruby-prof/printers/flat_printer.rb +6 -24
- data/lib/ruby-prof/printers/graph_html_printer.rb +6 -192
- data/lib/ruby-prof/printers/graph_printer.rb +11 -14
- data/lib/ruby-prof/printers/multi_printer.rb +66 -23
- data/lib/ruby-prof/profile.rb +10 -3
- data/lib/ruby-prof/thread.rb +5 -20
- data/lib/ruby-prof/version.rb +1 -1
- data/ruby-prof.gemspec +9 -2
- data/test/abstract_printer_test.rb +0 -27
- data/test/alias_test.rb +126 -0
- data/test/basic_test.rb +1 -86
- data/test/call_tree_visitor_test.rb +32 -0
- data/test/call_trees_test.rb +66 -0
- data/test/dynamic_method_test.rb +0 -2
- data/test/exclude_methods_test.rb +17 -12
- data/test/fiber_test.rb +214 -23
- data/test/gc_test.rb +105 -0
- data/test/inverse_call_tree_test.rb +175 -0
- data/test/line_number_test.rb +118 -40
- data/test/marshal_test.rb +115 -0
- data/test/measure_allocations.rb +30 -0
- data/test/measure_allocations_test.rb +361 -12
- data/test/measure_allocations_trace_test.rb +375 -0
- data/test/measure_memory_trace_test.rb +1101 -0
- data/test/measure_process_time_test.rb +757 -33
- data/test/measure_times.rb +56 -0
- data/test/measure_wall_time_test.rb +329 -149
- data/test/multi_printer_test.rb +1 -34
- data/test/pause_resume_test.rb +24 -15
- data/test/prime.rb +1 -1
- data/test/prime_script.rb +6 -0
- data/test/printer_call_stack_test.rb +28 -0
- data/test/printer_call_tree_test.rb +31 -0
- data/test/printer_flat_test.rb +68 -0
- data/test/printer_graph_html_test.rb +60 -0
- data/test/printer_graph_test.rb +41 -0
- data/test/printers_test.rb +32 -166
- data/test/printing_recursive_graph_test.rb +26 -72
- data/test/recursive_test.rb +68 -77
- data/test/stack_printer_test.rb +2 -15
- data/test/start_stop_test.rb +22 -25
- data/test/test_helper.rb +6 -261
- data/test/thread_test.rb +11 -54
- data/test/unique_call_path_test.rb +25 -107
- data/test/yarv_test.rb +1 -0
- metadata +43 -41
- data/examples/flat.txt +0 -50
- data/examples/graph.dot +0 -84
- data/examples/graph.html +0 -823
- data/examples/graph.txt +0 -139
- data/examples/multi.flat.txt +0 -23
- data/examples/multi.graph.html +0 -760
- data/examples/multi.grind.dat +0 -114
- data/examples/multi.stack.html +0 -547
- data/examples/stack.html +0 -547
- data/ext/ruby_prof/rp_call_info.c +0 -425
- data/ext/ruby_prof/rp_call_info.h +0 -53
- data/ext/ruby_prof/rp_measure.c +0 -40
- data/ext/ruby_prof/rp_measure.h +0 -45
- data/ext/ruby_prof/rp_measure_cpu_time.c +0 -136
- data/ext/ruby_prof/rp_measure_gc_runs.c +0 -73
- data/ext/ruby_prof/rp_measure_gc_time.c +0 -60
- data/lib/ruby-prof/aggregate_call_info.rb +0 -76
- data/lib/ruby-prof/assets/call_stack_printer.css.html +0 -117
- data/lib/ruby-prof/assets/call_stack_printer.js.html +0 -385
- data/lib/ruby-prof/call_info.rb +0 -115
- data/lib/ruby-prof/call_info_visitor.rb +0 -40
- data/lib/ruby-prof/printers/flat_printer_with_line_numbers.rb +0 -83
- data/lib/ruby-prof/profile/exclude_common_methods.rb +0 -207
- data/lib/ruby-prof/profile/legacy_method_elimination.rb +0 -50
- data/test/aggregate_test.rb +0 -136
- data/test/block_test.rb +0 -74
- data/test/call_info_test.rb +0 -78
- data/test/call_info_visitor_test.rb +0 -31
- data/test/issue137_test.rb +0 -63
- data/test/measure_cpu_time_test.rb +0 -212
- data/test/measure_gc_runs_test.rb +0 -32
- data/test/measure_gc_time_test.rb +0 -36
- data/test/measure_memory_test.rb +0 -33
- data/test/method_elimination_test.rb +0 -84
- data/test/module_test.rb +0 -45
- data/test/stack_test.rb +0 -138
data/test/test_helper.rb
CHANGED
@@ -1,267 +1,12 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
# To make testing/debugging easier, test within this source tree versus an installed gem
|
7
|
-
dir = File.dirname(__FILE__)
|
8
|
-
root = File.expand_path(File.join(dir, '..'))
|
9
|
-
lib = File.expand_path(File.join(root, 'lib'))
|
10
|
-
ext = File.expand_path(File.join(root, 'ext', 'ruby_prof'))
|
11
|
-
|
12
|
-
$LOAD_PATH << lib
|
13
|
-
$LOAD_PATH << ext
|
14
|
-
|
15
|
-
require 'ruby-prof'
|
16
|
-
|
17
|
-
# stub deprecation warnings
|
18
|
-
module RubyProf
|
19
|
-
module SuppressDeprecationWarnings
|
20
|
-
def deprecation_warning(*args)
|
21
|
-
super if ENV['SHOW_RUBY_PROF_DEPRECATION_WARNINGS'] == '1'
|
22
|
-
end
|
23
|
-
end
|
24
|
-
extend SuppressDeprecationWarnings
|
25
|
-
end
|
3
|
+
# Disable minitest parallel tests. The problem is the thread switching will cahnge test results
|
4
|
+
# (self vs wait time)
|
5
|
+
ENV["N"] = "0"
|
26
6
|
|
7
|
+
require 'bundler/setup'
|
27
8
|
require 'minitest/autorun'
|
9
|
+
require 'ruby-prof'
|
28
10
|
|
29
11
|
class TestCase < Minitest::Test
|
30
|
-
|
31
|
-
def assert_nothing_raised(*)
|
32
|
-
yield
|
33
|
-
end
|
34
|
-
|
35
|
-
def before_setup
|
36
|
-
# make sure to exclude all threads except the one running the test
|
37
|
-
# minitest allocates a thread pool and they would otherwise show
|
38
|
-
# up in the profile data, breaking tests randomly
|
39
|
-
RubyProf.exclude_threads = Thread.list.select{|t| t != Thread.current}
|
40
|
-
end
|
41
|
-
|
42
|
-
def after_teardown
|
43
|
-
# reset exclude threads after testing
|
44
|
-
RubyProf.exclude_threads = nil
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
require File.expand_path('../prime', __FILE__)
|
49
|
-
|
50
|
-
# Some classes used in measurement tests
|
51
|
-
module RubyProf
|
52
|
-
class C1
|
53
|
-
def C1.hello
|
54
|
-
sleep(0.1)
|
55
|
-
end
|
56
|
-
|
57
|
-
def hello
|
58
|
-
sleep(0.2)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
module M1
|
63
|
-
def hello
|
64
|
-
sleep(0.3)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
class C2
|
69
|
-
include M1
|
70
|
-
extend M1
|
71
|
-
end
|
72
|
-
|
73
|
-
class C3
|
74
|
-
def hello
|
75
|
-
sleep(0.4)
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
module M4
|
80
|
-
def hello
|
81
|
-
sleep(0.5)
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
module M5
|
86
|
-
include M4
|
87
|
-
def goodbye
|
88
|
-
hello
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
class C6
|
93
|
-
include M5
|
94
|
-
def test
|
95
|
-
goodbye
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
class C7
|
100
|
-
def self.busy_wait
|
101
|
-
t = Time.now.to_f
|
102
|
-
while Time.now.to_f - t < 0.1; end
|
103
|
-
end
|
104
|
-
|
105
|
-
def self.sleep_wait
|
106
|
-
sleep 0.1
|
107
|
-
end
|
108
|
-
|
109
|
-
def busy_wait
|
110
|
-
t = Time.now.to_f
|
111
|
-
while Time.now.to_f - t < 0.2; end
|
112
|
-
end
|
113
|
-
|
114
|
-
def sleep_wait
|
115
|
-
sleep 0.2
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
module M7
|
120
|
-
def busy_wait
|
121
|
-
t = Time.now.to_f
|
122
|
-
while Time.now.to_f - t < 0.3; end
|
123
|
-
end
|
124
|
-
|
125
|
-
def sleep_wait
|
126
|
-
sleep 0.3
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
class C8
|
131
|
-
include M7
|
132
|
-
extend M7
|
133
|
-
end
|
134
|
-
|
135
|
-
def self.ruby_major_version
|
136
|
-
match = RUBY_VERSION.match(/(\d)\.(\d)/)
|
137
|
-
return Integer(match[1])
|
138
|
-
end
|
139
|
-
|
140
|
-
def self.ruby_minor_version
|
141
|
-
match = RUBY_VERSION.match(/(\d)\.(\d)/)
|
142
|
-
return Integer(match[2])
|
143
|
-
end
|
144
|
-
|
145
|
-
def self.parent_object
|
146
|
-
if ruby_major_version == 1 && ruby_minor_version == 8
|
147
|
-
Object
|
148
|
-
else
|
149
|
-
BasicObject
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
def self.ruby_2?
|
154
|
-
ruby_major_version == 2
|
155
|
-
end
|
156
|
-
|
157
|
-
# store printer output in this directory
|
158
|
-
def self.tmpdir
|
159
|
-
path = File.expand_path('../../tmp', __FILE__)
|
160
|
-
unless Dir.exist?(path)
|
161
|
-
Dir.mkdir(path)
|
162
|
-
end
|
163
|
-
path
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
module MemoryTestHelper
|
168
|
-
def memory_test_helper
|
169
|
-
result = RubyProf.profile {Array.new}
|
170
|
-
total = result.threads.first.methods.inject(0) { |sum, m| sum + m.total_time }
|
171
|
-
assert(total < 1_000_000, 'Total should not have subtract overflow error')
|
172
|
-
total
|
173
|
-
end
|
174
|
-
end
|
175
|
-
|
176
|
-
module PrinterTestHelper
|
177
|
-
Metrics = Struct.new(:name, :total, :self_t, :wait, :child, :calls)
|
178
|
-
class Metrics
|
179
|
-
def pp
|
180
|
-
"%s[total: %.2f, self: %.2f, wait: %.2f, child: %.2f, calls: %s]" %
|
181
|
-
[name, total, self_t, wait, child, calls]
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
Entry = Struct.new(:total_p, :self_p, :metrics, :parents, :children)
|
186
|
-
class Entry
|
187
|
-
def child(name)
|
188
|
-
children.detect{|m| m.name == name}
|
189
|
-
end
|
190
|
-
|
191
|
-
def parent(name)
|
192
|
-
parents.detect{|m| m.name == name}
|
193
|
-
end
|
194
|
-
|
195
|
-
def pp
|
196
|
-
res = ""
|
197
|
-
res << "NODE (total%%: %.2f, self%%: %.2f) %s\n" % [total_p, self_p, metrics.pp]
|
198
|
-
res << " PARENTS:\n"
|
199
|
-
parents.each {|m| res << " " + m.pp << "\n"}
|
200
|
-
res << " CHILDREN:\n"
|
201
|
-
children.each {|m| res << " " + m.pp << "\n"}
|
202
|
-
res
|
203
|
-
end
|
204
|
-
end
|
205
|
-
|
206
|
-
class MetricsArray < Array
|
207
|
-
def metrics_for(name)
|
208
|
-
detect {|e| e.metrics.name == name}
|
209
|
-
end
|
210
|
-
|
211
|
-
def pp(io = STDOUT)
|
212
|
-
entries = map do |e|
|
213
|
-
begin
|
214
|
-
e.pp
|
215
|
-
rescue
|
216
|
-
puts $!.message + e.inspect
|
217
|
-
""
|
218
|
-
end
|
219
|
-
end
|
220
|
-
io.puts entries.join("--------------------------------------------------\n")
|
221
|
-
end
|
222
|
-
|
223
|
-
def self.parse(str)
|
224
|
-
res = new
|
225
|
-
entry = nil
|
226
|
-
relatives = []
|
227
|
-
state = :preamble
|
228
|
-
|
229
|
-
str.each_line do |l|
|
230
|
-
line = l.chomp.strip
|
231
|
-
if line =~ /-----/
|
232
|
-
if state == :preamble
|
233
|
-
state = :parsing_parents
|
234
|
-
entry = Entry.new
|
235
|
-
elsif state == :parsing_parents
|
236
|
-
entry = Entry.new
|
237
|
-
elsif state == :parsing_children
|
238
|
-
entry.children = relatives
|
239
|
-
res << entry
|
240
|
-
entry = Entry.new
|
241
|
-
relatives = []
|
242
|
-
state = :parsing_parents
|
243
|
-
end
|
244
|
-
elsif line =~ /^\s*$/ || line =~ /indicates recursively called methods/
|
245
|
-
next
|
246
|
-
elsif state != :preamble
|
247
|
-
elements = line.split(/\s+/)
|
248
|
-
method = elements.pop
|
249
|
-
numbers = elements[0..-2].map(&:to_f)
|
250
|
-
metrics = Metrics.new(method, *numbers[-4..-1], elements[-1])
|
251
|
-
if numbers.size == 6
|
252
|
-
entry.metrics = metrics
|
253
|
-
entry.total_p = numbers[0]
|
254
|
-
entry.self_p = numbers[1]
|
255
|
-
entry.parents = relatives
|
256
|
-
entry.children = relatives = []
|
257
|
-
state = :parsing_children
|
258
|
-
res << entry
|
259
|
-
else
|
260
|
-
relatives << metrics
|
261
|
-
end
|
262
|
-
end
|
263
|
-
end
|
264
|
-
res
|
265
|
-
end
|
266
|
-
end
|
267
|
-
end
|
12
|
+
end
|
data/test/thread_test.rb
CHANGED
@@ -75,10 +75,7 @@ class ThreadTest < TestCase
|
|
75
75
|
assert_in_delta(0, method.self_time, 0.05)
|
76
76
|
assert_in_delta(0, method.wait_time, 0.05)
|
77
77
|
assert_in_delta(1, method.children_time, 0.05)
|
78
|
-
assert_equal(
|
79
|
-
call_info = method.call_infos[0]
|
80
|
-
assert_equal('ThreadTest#test_thread_timings', call_info.call_sequence)
|
81
|
-
assert_equal(1, call_info.children.length)
|
78
|
+
assert_equal(0, method.call_trees.callers.length)
|
82
79
|
|
83
80
|
method = methods[1]
|
84
81
|
assert_equal('Kernel#sleep', method.full_name)
|
@@ -88,10 +85,8 @@ class ThreadTest < TestCase
|
|
88
85
|
assert_in_delta(0, method.wait_time, 0.05)
|
89
86
|
assert_in_delta(0, method.children_time, 0.05)
|
90
87
|
|
91
|
-
assert_equal(1, method.
|
92
|
-
|
93
|
-
assert_equal('ThreadTest#test_thread_timings->Kernel#sleep', call_info.call_sequence)
|
94
|
-
assert_equal(0, call_info.children.length)
|
88
|
+
assert_equal(1, method.call_trees.callers.length)
|
89
|
+
assert_equal(0, method.call_trees.callees.length)
|
95
90
|
|
96
91
|
# Check foreground thread
|
97
92
|
rp_thread = result.threads.detect {|athread| athread.id == Thread.current.object_id}
|
@@ -110,10 +105,8 @@ class ThreadTest < TestCase
|
|
110
105
|
assert_in_delta(0, method.wait_time, 0.05)
|
111
106
|
assert_in_delta(1, method.children_time, 0.05)
|
112
107
|
|
113
|
-
assert_equal(
|
114
|
-
|
115
|
-
assert_equal('ThreadTest#test_thread_timings', call_info.call_sequence)
|
116
|
-
assert_equal(2, call_info.children.length)
|
108
|
+
assert_equal(0, method.call_trees.callers.length)
|
109
|
+
assert_equal(2, method.call_trees.callees.length)
|
117
110
|
|
118
111
|
method = methods[1]
|
119
112
|
assert_equal('Thread#join', method.full_name)
|
@@ -123,10 +116,8 @@ class ThreadTest < TestCase
|
|
123
116
|
assert_in_delta(1.0, method.wait_time, 0.05)
|
124
117
|
assert_in_delta(0, method.children_time, 0.05)
|
125
118
|
|
126
|
-
assert_equal(1, method.
|
127
|
-
|
128
|
-
assert_equal('ThreadTest#test_thread_timings->Thread#join', call_info.call_sequence)
|
129
|
-
assert_equal(0, call_info.children.length)
|
119
|
+
assert_equal(1, method.call_trees.callers.length)
|
120
|
+
assert_equal(0, method.call_trees.callees.length)
|
130
121
|
|
131
122
|
method = methods[2]
|
132
123
|
assert_equal('<Class::Thread>#new', method.full_name)
|
@@ -136,10 +127,8 @@ class ThreadTest < TestCase
|
|
136
127
|
assert_in_delta(0, method.wait_time, 0.05)
|
137
128
|
assert_in_delta(0, method.children_time, 0.05)
|
138
129
|
|
139
|
-
assert_equal(1, method.
|
140
|
-
|
141
|
-
assert_equal('ThreadTest#test_thread_timings-><Class::Thread>#new', call_info.call_sequence)
|
142
|
-
assert_equal(1, call_info.children.length)
|
130
|
+
assert_equal(1, method.call_trees.callers.length)
|
131
|
+
assert_equal(1, method.call_trees.callees.length)
|
143
132
|
|
144
133
|
method = methods[3]
|
145
134
|
assert_equal('Thread#initialize', method.full_name)
|
@@ -149,39 +138,7 @@ class ThreadTest < TestCase
|
|
149
138
|
assert_in_delta(0, method.wait_time, 0.05)
|
150
139
|
assert_in_delta(0, method.children_time, 0.05)
|
151
140
|
|
152
|
-
assert_equal(1, method.
|
153
|
-
|
154
|
-
assert_equal('ThreadTest#test_thread_timings-><Class::Thread>#new->Thread#initialize', call_info.call_sequence)
|
155
|
-
assert_equal(0, call_info.children.length)
|
156
|
-
end
|
157
|
-
|
158
|
-
# useless test: what does it test?
|
159
|
-
def test_thread_back_and_forth
|
160
|
-
result = nil
|
161
|
-
seconds = Benchmark.realtime do
|
162
|
-
result = RubyProf.profile do
|
163
|
-
a = Thread.new { 100_000.times { sleep 0 }}
|
164
|
-
b = Thread.new { 100_000.times { sleep 0 }}
|
165
|
-
a.join
|
166
|
-
b.join
|
167
|
-
end
|
168
|
-
end
|
169
|
-
methods = result.threads.map {|thread| thread.methods}
|
170
|
-
timings = methods.flatten.sort
|
171
|
-
assert(timings[-1].total_time < seconds)
|
172
|
-
end
|
173
|
-
|
174
|
-
# useless test: what does it test?
|
175
|
-
def test_thread
|
176
|
-
RubyProf.profile do
|
177
|
-
begin
|
178
|
-
Timeout::timeout(2) do
|
179
|
-
while true
|
180
|
-
next
|
181
|
-
end
|
182
|
-
end
|
183
|
-
rescue Timeout::Error
|
184
|
-
end
|
185
|
-
end
|
141
|
+
assert_equal(1, method.call_trees.callers.length)
|
142
|
+
assert_equal(0, method.call_trees.callees.length)
|
186
143
|
end
|
187
144
|
end
|
@@ -27,24 +27,15 @@ end
|
|
27
27
|
|
28
28
|
# -- Tests ----
|
29
29
|
class UniqueCallPathTest < TestCase
|
30
|
-
def
|
30
|
+
def test_root
|
31
31
|
unique_call_path = UniqueCallPath.new
|
32
32
|
|
33
33
|
result = RubyProf.profile do
|
34
34
|
unique_call_path.method_a(1)
|
35
35
|
end
|
36
36
|
|
37
|
-
|
38
|
-
|
39
|
-
thread.methods.each do | m |
|
40
|
-
if m.root?
|
41
|
-
root_methods.push(m)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
assert_equal(1, root_methods.length)
|
47
|
-
assert_equal("UniqueCallPathTest#test_root_method", root_methods[0].full_name)
|
37
|
+
root_call_info = result.threads.first.call_tree
|
38
|
+
assert_equal("UniqueCallPathTest#test_root", root_call_info.target.full_name)
|
48
39
|
end
|
49
40
|
|
50
41
|
def test_root_children
|
@@ -55,25 +46,8 @@ class UniqueCallPathTest < TestCase
|
|
55
46
|
unique_call_path.method_k(2)
|
56
47
|
end
|
57
48
|
|
58
|
-
|
59
|
-
|
60
|
-
thread.methods.each do | m |
|
61
|
-
if m.root?
|
62
|
-
root_methods.push(m)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
assert_equal(1, root_methods.length)
|
68
|
-
|
69
|
-
root_children = Array.new
|
70
|
-
root_methods[0].children.each do | c |
|
71
|
-
if c.parent.target.eql?(root_methods[0])
|
72
|
-
root_children.push(c)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
children = root_children.sort do |c1, c2|
|
49
|
+
root_call_info = result.threads.first.call_tree
|
50
|
+
children = root_call_info.children.sort do |c1, c2|
|
77
51
|
c1.target.full_name <=> c2.target.full_name
|
78
52
|
end
|
79
53
|
|
@@ -90,67 +64,23 @@ class UniqueCallPathTest < TestCase
|
|
90
64
|
unique_call_path.method_k(2)
|
91
65
|
end
|
92
66
|
|
93
|
-
|
94
|
-
|
95
|
-
thread.methods.each do | m |
|
96
|
-
if m.root?
|
97
|
-
root_methods.push(m)
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
assert_equal(1, root_methods.length)
|
103
|
-
method = root_methods[0]
|
104
|
-
assert_equal('UniqueCallPathTest#test_children_of', method.full_name)
|
67
|
+
root_call_info = result.threads.first.call_tree
|
68
|
+
assert_equal("UniqueCallPathTest#test_children_of", root_call_info.target.full_name)
|
105
69
|
|
106
|
-
call_info_a =
|
107
|
-
|
108
|
-
if c.target.full_name == "UniqueCallPath#method_a"
|
109
|
-
call_info_a = c
|
110
|
-
break
|
111
|
-
end
|
70
|
+
call_info_a = root_call_info.children.detect do |call_tree|
|
71
|
+
call_tree.target.full_name == "UniqueCallPath#method_a"
|
112
72
|
end
|
73
|
+
refute_nil(call_info_a)
|
113
74
|
|
114
|
-
|
115
|
-
|
116
|
-
children_of_a = Array.new
|
117
|
-
|
118
|
-
call_info_a.children.each do | c |
|
75
|
+
children_of_a = call_info_a.children.inject(Array.new) do |array, c|
|
119
76
|
if c.parent.eql?(call_info_a)
|
120
|
-
|
77
|
+
array << c
|
121
78
|
end
|
79
|
+
array
|
122
80
|
end
|
123
81
|
|
124
|
-
assert_equal(
|
125
|
-
|
126
|
-
children_of_a = children_of_a.sort do |c1, c2|
|
127
|
-
c1.target.full_name <=> c2.target.full_name
|
128
|
-
end
|
129
|
-
|
130
|
-
assert_equal(1, children_of_a.length)
|
131
|
-
assert_equal("UniqueCallPath#method_b", children_of_a[0].target.full_name)
|
132
|
-
end
|
133
|
-
|
134
|
-
def test_id2ref
|
135
|
-
unique_call_path = UniqueCallPath.new
|
136
|
-
|
137
|
-
result = RubyProf.profile do
|
138
|
-
unique_call_path.method_a(1)
|
139
|
-
end
|
140
|
-
|
141
|
-
root_methods = Array.new
|
142
|
-
result.threads.each do |thread|
|
143
|
-
thread.methods.each do | m |
|
144
|
-
if m.root?
|
145
|
-
root_methods.push(m)
|
146
|
-
end
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
child = root_methods[0].children[0]
|
151
|
-
|
152
|
-
refute_equal(0, child.object_id)
|
153
|
-
#assert_equal(RubyProf::CallInfo.id2ref(child.id).target.full_name, child.target.full_name)
|
82
|
+
assert_equal(1, call_info_a.children.length)
|
83
|
+
assert_equal("UniqueCallPath#method_b", call_info_a.children.first.target.full_name)
|
154
84
|
end
|
155
85
|
|
156
86
|
def test_unique_path
|
@@ -161,35 +91,23 @@ class UniqueCallPathTest < TestCase
|
|
161
91
|
unique_call_path.method_k(1)
|
162
92
|
end
|
163
93
|
|
164
|
-
|
165
|
-
|
166
|
-
thread.methods.each do | m |
|
167
|
-
if m.root?
|
168
|
-
root_methods.push(m)
|
169
|
-
end
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
assert_equal(1, root_methods.length)
|
94
|
+
root_call_info = result.threads.first.call_tree
|
95
|
+
assert_equal("UniqueCallPathTest#test_unique_path", root_call_info.target.full_name)
|
174
96
|
|
175
|
-
call_info_a =
|
176
|
-
|
177
|
-
if c.target.full_name == "UniqueCallPath#method_a"
|
178
|
-
call_info_a = c
|
179
|
-
break
|
180
|
-
end
|
97
|
+
call_info_a = root_call_info.children.detect do |call_tree|
|
98
|
+
call_tree.target.full_name == "UniqueCallPath#method_a"
|
181
99
|
end
|
100
|
+
refute_nil(call_info_a)
|
182
101
|
|
183
|
-
|
184
|
-
|
185
|
-
children_of_a = Array.new
|
186
|
-
call_info_a.children.each do |c|
|
102
|
+
children_of_a = call_info_a.children.reduce(Array.new) do |array, c|
|
187
103
|
if c.parent.eql?(call_info_a)
|
188
|
-
|
104
|
+
array << c
|
189
105
|
end
|
106
|
+
array
|
190
107
|
end
|
191
108
|
|
192
|
-
assert_equal(
|
109
|
+
assert_equal(1, call_info_a.children.length)
|
110
|
+
assert_equal(1, children_of_a.length)
|
193
111
|
|
194
112
|
children_of_a = children_of_a.sort do |c1, c2|
|
195
113
|
c1.target.full_name <=> c2.target.full_name
|