ruby-prof 0.8.1-x86-mswin32

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 (64) hide show
  1. data/CHANGES +221 -0
  2. data/LICENSE +23 -0
  3. data/README +432 -0
  4. data/Rakefile +159 -0
  5. data/bin/ruby-prof +224 -0
  6. data/examples/flat.txt +55 -0
  7. data/examples/graph.html +823 -0
  8. data/examples/graph.txt +170 -0
  9. data/ext/ruby_prof/measure_allocations.h +58 -0
  10. data/ext/ruby_prof/measure_cpu_time.h +152 -0
  11. data/ext/ruby_prof/measure_gc_runs.h +76 -0
  12. data/ext/ruby_prof/measure_gc_time.h +57 -0
  13. data/ext/ruby_prof/measure_memory.h +101 -0
  14. data/ext/ruby_prof/measure_process_time.h +52 -0
  15. data/ext/ruby_prof/measure_wall_time.h +53 -0
  16. data/ext/ruby_prof/mingw/Rakefile +23 -0
  17. data/ext/ruby_prof/mingw/build.rake +38 -0
  18. data/ext/ruby_prof/ruby_prof.c +1747 -0
  19. data/ext/ruby_prof/ruby_prof.h +188 -0
  20. data/ext/ruby_prof/version.h +4 -0
  21. data/lib/1.8/ruby_prof.so +0 -0
  22. data/lib/1.9/ruby_prof.so +0 -0
  23. data/lib/ruby-prof.rb +56 -0
  24. data/lib/ruby-prof/abstract_printer.rb +41 -0
  25. data/lib/ruby-prof/aggregate_call_info.rb +62 -0
  26. data/lib/ruby-prof/call_info.rb +47 -0
  27. data/lib/ruby-prof/call_tree_printer.rb +84 -0
  28. data/lib/ruby-prof/flat_printer.rb +78 -0
  29. data/lib/ruby-prof/flat_printer_with_line_numbers.rb +72 -0
  30. data/lib/ruby-prof/graph_html_printer.rb +256 -0
  31. data/lib/ruby-prof/graph_printer.rb +157 -0
  32. data/lib/ruby-prof/method_info.rb +111 -0
  33. data/lib/ruby-prof/symbol_to_proc.rb +8 -0
  34. data/lib/ruby-prof/task.rb +146 -0
  35. data/lib/ruby-prof/test.rb +148 -0
  36. data/lib/unprof.rb +8 -0
  37. data/rails/environment/profile.rb +24 -0
  38. data/rails/example/example_test.rb +9 -0
  39. data/rails/profile_test_helper.rb +21 -0
  40. data/test/aggregate_test.rb +121 -0
  41. data/test/basic_test.rb +290 -0
  42. data/test/current_failures_windows +8 -0
  43. data/test/do_nothing.rb +0 -0
  44. data/test/duplicate_names_test.rb +32 -0
  45. data/test/enumerable_test.rb +16 -0
  46. data/test/exceptions_test.rb +15 -0
  47. data/test/exclude_threads_test.rb +54 -0
  48. data/test/exec_test.rb +14 -0
  49. data/test/line_number_test.rb +73 -0
  50. data/test/measurement_test.rb +121 -0
  51. data/test/module_test.rb +54 -0
  52. data/test/no_method_class_test.rb +13 -0
  53. data/test/prime.rb +58 -0
  54. data/test/prime_test.rb +13 -0
  55. data/test/printers_test.rb +130 -0
  56. data/test/recursive_test.rb +275 -0
  57. data/test/ruby-prof-bin +20 -0
  58. data/test/singleton_test.rb +37 -0
  59. data/test/stack_test.rb +138 -0
  60. data/test/start_stop_test.rb +95 -0
  61. data/test/test_suite.rb +23 -0
  62. data/test/thread_test.rb +173 -0
  63. data/test/unique_call_path_test.rb +225 -0
  64. metadata +143 -0
@@ -0,0 +1,138 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require 'ruby-prof'
5
+
6
+ # Test data
7
+ # A
8
+ # / \
9
+ # B C
10
+ # \
11
+ # B
12
+
13
+ class StackClass
14
+ def a
15
+ sleep 1
16
+ b
17
+ c
18
+ end
19
+
20
+ def b
21
+ sleep 2
22
+ end
23
+
24
+ def c
25
+ sleep 3
26
+ b
27
+ end
28
+ end
29
+
30
+ class StackTest < Test::Unit::TestCase
31
+ def setup
32
+ # Need to use wall time for this test due to the sleep calls
33
+ RubyProf::measure_mode = RubyProf::WALL_TIME
34
+ end
35
+
36
+ def test_call_sequence
37
+ c = StackClass.new
38
+ result = RubyProf.profile do
39
+ c.a
40
+ end
41
+
42
+ # Length should be 5:
43
+ # StackTest#test_call_sequence
44
+ # StackClass#a
45
+ # Kernel#sleep
46
+ # StackClass#c
47
+ # StackClass#b
48
+
49
+ methods = result.threads.values.first.sort.reverse
50
+ assert_equal(5, methods.length)
51
+
52
+ # Check StackTest#test_call_sequence
53
+ method = methods[0]
54
+ assert_equal('StackTest#test_call_sequence', method.full_name)
55
+ assert_equal(1, method.called)
56
+ assert_in_delta(8, method.total_time, 0.25)
57
+ assert_in_delta(0, method.wait_time, 0.01)
58
+ assert_in_delta(0, method.self_time, 0.01)
59
+ assert_in_delta(8, method.children_time, 0.25)
60
+ assert_equal(1, method.call_infos.length)
61
+
62
+ call_info = method.call_infos[0]
63
+ assert_equal('StackTest#test_call_sequence', call_info.call_sequence)
64
+ assert_equal(1, call_info.children.length)
65
+
66
+ # Check StackClass#a
67
+ method = methods[1]
68
+ assert_equal('StackClass#a', method.full_name)
69
+ assert_equal(1, method.called)
70
+ assert_in_delta(8, method.total_time, 0.15)
71
+ assert_in_delta(0, method.wait_time, 0.01)
72
+ assert_in_delta(0, method.self_time, 0.01)
73
+ assert_in_delta(8, method.children_time, 0.05)
74
+ assert_equal(1, method.call_infos.length)
75
+
76
+ call_info = method.call_infos[0]
77
+ assert_equal('StackTest#test_call_sequence->StackClass#a', call_info.call_sequence)
78
+ assert_equal(3, call_info.children.length)
79
+
80
+ # Check Kernel#sleep
81
+ method = methods[2]
82
+ assert_equal('Kernel#sleep', method.full_name)
83
+ assert_equal(4, method.called)
84
+ assert_in_delta(8, method.total_time, 0.05)
85
+ assert_in_delta(0, method.wait_time, 0.01)
86
+ assert_in_delta(8, method.self_time, 0.05)
87
+ assert_in_delta(0, method.children_time, 0.05)
88
+ assert_equal(4, method.call_infos.length)
89
+
90
+ call_info = method.call_infos[0]
91
+ assert_equal('StackTest#test_call_sequence->StackClass#a->Kernel#sleep', call_info.call_sequence)
92
+ assert_equal(0, call_info.children.length)
93
+
94
+ call_info = method.call_infos[1]
95
+ assert_equal('StackTest#test_call_sequence->StackClass#a->StackClass#b->Kernel#sleep', call_info.call_sequence)
96
+ assert_equal(0, call_info.children.length)
97
+
98
+ call_info = method.call_infos[2]
99
+ assert_equal('StackTest#test_call_sequence->StackClass#a->StackClass#c->Kernel#sleep', call_info.call_sequence)
100
+ assert_equal(0, call_info.children.length)
101
+
102
+ call_info = method.call_infos[3]
103
+ assert_equal('StackTest#test_call_sequence->StackClass#a->StackClass#c->StackClass#b->Kernel#sleep', call_info.call_sequence)
104
+ assert_equal(0, call_info.children.length)
105
+
106
+ # Check StackClass#c
107
+ method = methods[3]
108
+ assert_equal('StackClass#c', method.full_name)
109
+ assert_equal(1, method.called)
110
+ assert_in_delta(5, method.total_time, 0.01)
111
+ assert_in_delta(0, method.wait_time, 0.01)
112
+ assert_in_delta(0, method.self_time, 0.01)
113
+ assert_in_delta(5, method.children_time, 0.01)
114
+ assert_equal(1, method.call_infos.length)
115
+
116
+ call_info = method.call_infos[0]
117
+ assert_equal('StackTest#test_call_sequence->StackClass#a->StackClass#c', call_info.call_sequence)
118
+ assert_equal(2, call_info.children.length)
119
+
120
+ # Check StackClass#b
121
+ method = methods[4]
122
+ assert_equal('StackClass#b', method.full_name)
123
+ assert_equal(2, method.called)
124
+ assert_in_delta(4, method.total_time, 0.01)
125
+ assert_in_delta(0, method.wait_time, 0.01)
126
+ assert_in_delta(0, method.self_time, 0.01)
127
+ assert_in_delta(4, method.children_time, 0.01)
128
+ assert_equal(2, method.call_infos.length)
129
+
130
+ call_info = method.call_infos[0]
131
+ assert_equal('StackTest#test_call_sequence->StackClass#a->StackClass#b', call_info.call_sequence)
132
+ assert_equal(1, call_info.children.length)
133
+
134
+ call_info = method.call_infos[1]
135
+ assert_equal('StackTest#test_call_sequence->StackClass#a->StackClass#c->StackClass#b', call_info.call_sequence)
136
+ assert_equal(1, call_info.children.length)
137
+ end
138
+ end
@@ -0,0 +1,95 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require 'ruby-prof'
5
+
6
+ class StartStopTest < Test::Unit::TestCase
7
+ def setup
8
+ # Need to use wall time for this test due to the sleep calls
9
+ RubyProf::measure_mode = RubyProf::WALL_TIME
10
+ end
11
+
12
+ def method1
13
+ RubyProf.start
14
+ method2
15
+ end
16
+
17
+ def method2
18
+ method3
19
+ end
20
+
21
+ def method3
22
+ sleep(2)
23
+ @result = RubyProf.stop
24
+ end
25
+
26
+ def test_different_methods
27
+ method1
28
+
29
+ # Ruby prof should be stopped
30
+ assert_equal(false, RubyProf.running?)
31
+
32
+
33
+ # Length should be 4:
34
+ # StartStopTest#method1
35
+ # StartStopTest#method2
36
+ # StartStopTest#method3
37
+ # Kernel#sleep
38
+
39
+ methods = @result.threads.values.first.sort.reverse
40
+ assert_equal(4, methods.length)
41
+
42
+ # Check StackTest#test_call_sequence
43
+ method = methods[0]
44
+ assert_equal('StartStopTest#method1', method.full_name)
45
+ assert_equal(1, method.called)
46
+ assert_in_delta(2, method.total_time, 0.05)
47
+ assert_in_delta(0, method.wait_time, 0.01)
48
+ assert_in_delta(0, method.self_time, 0.01)
49
+ assert_in_delta(2, method.children_time, 0.05)
50
+ assert_equal(1, method.call_infos.length)
51
+
52
+ call_info = method.call_infos[0]
53
+ assert_equal('StartStopTest#method1', call_info.call_sequence)
54
+ assert_equal(1, call_info.children.length)
55
+
56
+ method = methods[1]
57
+ assert_equal('StartStopTest#method2', method.full_name)
58
+ assert_equal(1, method.called)
59
+ assert_in_delta(2, method.total_time, 0.01)
60
+ assert_in_delta(0, method.wait_time, 0.01)
61
+ assert_in_delta(0, method.self_time, 0.01)
62
+ assert_in_delta(2, method.children_time, 0.01)
63
+ assert_equal(1, method.call_infos.length)
64
+
65
+ call_info = method.call_infos[0]
66
+ assert_equal('StartStopTest#method1->StartStopTest#method2', call_info.call_sequence)
67
+ assert_equal(1, call_info.children.length)
68
+
69
+ method = methods[2]
70
+ assert_equal('StartStopTest#method3', method.full_name)
71
+ assert_equal(1, method.called)
72
+ assert_in_delta(2, method.total_time, 0.01)
73
+ assert_in_delta(0, method.wait_time, 0.01)
74
+ assert_in_delta(0, method.self_time, 0.01)
75
+ assert_in_delta(2, method.children_time, 0.01)
76
+ assert_equal(1, method.call_infos.length)
77
+
78
+ call_info = method.call_infos[0]
79
+ assert_equal('StartStopTest#method1->StartStopTest#method2->StartStopTest#method3', call_info.call_sequence)
80
+ assert_equal(1, call_info.children.length)
81
+
82
+ method = methods[3]
83
+ assert_equal('Kernel#sleep', method.full_name)
84
+ assert_equal(1, method.called)
85
+ assert_in_delta(2, method.total_time, 0.01)
86
+ assert_in_delta(0, method.wait_time, 0.01)
87
+ assert_in_delta(2, method.self_time, 0.01)
88
+ assert_in_delta(0, method.children_time, 0.01)
89
+ assert_equal(1, method.call_infos.length)
90
+
91
+ call_info = method.call_infos[0]
92
+ assert_equal('StartStopTest#method1->StartStopTest#method2->StartStopTest#method3->Kernel#sleep', call_info.call_sequence)
93
+ assert_equal(0, call_info.children.length)
94
+ end
95
+ end
@@ -0,0 +1,23 @@
1
+ require 'test/unit'
2
+
3
+ require 'aggregate_test'
4
+ require 'basic_test'
5
+ require 'duplicate_names_test'
6
+ require 'exceptions_test'
7
+ require 'line_number_test'
8
+ require 'measurement_test'
9
+ require 'module_test'
10
+ require 'no_method_class_test'
11
+ require 'prime_test'
12
+ require 'printers_test'
13
+ require 'recursive_test'
14
+ require 'singleton_test'
15
+ require 'stack_test'
16
+ require 'start_stop_test'
17
+ require 'thread_test'
18
+ require 'unique_call_path_test'
19
+
20
+ # Can't use this one here cause it breaks
21
+ # the rest of the unit tets (Ruby Prof gets
22
+ # started twice).
23
+ #require 'profile_unit_test'
@@ -0,0 +1,173 @@
1
+ #!/usr/bin/env ruby
2
+ require 'test/unit'
3
+ require 'ruby-prof'
4
+ require 'timeout'
5
+
6
+ # -- Tests ----
7
+ class ThreadTest < Test::Unit::TestCase
8
+ def setup
9
+ # Need to use wall time for this test due to the sleep calls
10
+ RubyProf::measure_mode = RubyProf::WALL_TIME
11
+ end
12
+
13
+ def test_thread_count
14
+ RubyProf.start
15
+
16
+ thread = Thread.new do
17
+ sleep(1)
18
+ end
19
+
20
+ thread.join
21
+ result = RubyProf.stop
22
+ assert_equal(2, result.threads.keys.length) # this should pass...
23
+ end
24
+
25
+ def test_thread_identity
26
+ RubyProf.start
27
+ thread = Thread.new do
28
+ sleep(1)
29
+ end
30
+ thread.join
31
+ result = RubyProf.stop
32
+
33
+ thread_ids = result.threads.keys.sort
34
+ threads = [Thread.current, thread]
35
+ assert_equal(2, thread_ids.length) # should pass
36
+
37
+ assert(thread_ids.include?(threads[0].object_id))
38
+ assert(thread_ids.include?(threads[1].object_id))
39
+
40
+ assert_instance_of(Thread, ObjectSpace._id2ref(thread_ids[0]))
41
+ assert(threads.include?(ObjectSpace._id2ref(thread_ids[0])))
42
+
43
+ assert_instance_of(Thread, ObjectSpace._id2ref(thread_ids[1]))
44
+ assert(threads.include?(ObjectSpace._id2ref(thread_ids[1])))
45
+ end
46
+
47
+ def test_thread_timings
48
+ RubyProf.start
49
+ thread = Thread.new do
50
+ sleep 0 # force it to hit thread.join, below, first
51
+ # thus forcing sleep(1), below, to be counted as (wall) self_time
52
+ # since we currently count time "in some other thread" as self.wait_time
53
+ # for whatever reason
54
+ sleep(1)
55
+ end
56
+ thread.join
57
+ result = RubyProf.stop
58
+
59
+ # Check background thread
60
+ assert_equal(2, result.threads.length)
61
+ methods = result.threads[thread.object_id].sort.reverse
62
+ assert_equal(2, methods.length)
63
+
64
+ method = methods[0]
65
+ assert_equal('ThreadTest#test_thread_timings', method.full_name)
66
+ assert_equal(1, method.called)
67
+ assert_in_delta(1, method.total_time, 0.05)
68
+ assert_in_delta(0, method.self_time, 0.01)
69
+ assert_in_delta(0, method.wait_time, 0.01)
70
+ assert_in_delta(1, method.children_time, 0.01)
71
+ assert_equal(1, method.call_infos.length)
72
+ call_info = method.call_infos[0]
73
+ assert_equal('ThreadTest#test_thread_timings', call_info.call_sequence)
74
+ assert_equal(1, call_info.children.length)
75
+
76
+ method = methods[1]
77
+ assert_equal('Kernel#sleep', method.full_name)
78
+ assert_equal(2, method.called)
79
+ assert_in_delta(1, method.total_time, 0.01)
80
+ assert_in_delta(1.0, method.self_time, 0.01)
81
+ assert_in_delta(0, method.wait_time, 0.01)
82
+ assert_in_delta(0, method.children_time, 0.01)
83
+
84
+ assert_equal(1, method.call_infos.length)
85
+ call_info = method.call_infos[0]
86
+ assert_equal('ThreadTest#test_thread_timings->Kernel#sleep', call_info.call_sequence)
87
+ assert_equal(0, call_info.children.length)
88
+
89
+ # Check foreground thread
90
+ methods = result.threads[Thread.current.object_id].sort.reverse
91
+ assert_equal(4, methods.length)
92
+ methods = methods.sort.reverse
93
+
94
+ method = methods[0]
95
+ assert_equal('ThreadTest#test_thread_timings', method.full_name)
96
+ # the sub calls to Object#new, when popped,
97
+ # cause the parent frame to be created for method #test_thread_timings, which means a +1 when it's popped in the end
98
+ # xxxx a test that shows it the other way, too (never creates parent frame--if that's even possible)
99
+ assert_equal(1, method.called)
100
+ assert_in_delta(1, method.total_time, 0.01)
101
+ assert_in_delta(0, method.self_time, 0.05)
102
+ assert_in_delta(0, method.wait_time, 0.05)
103
+ assert_in_delta(1, method.children_time, 0.01)
104
+
105
+ assert_equal(1, method.call_infos.length)
106
+ call_info = method.call_infos[0]
107
+ assert_equal('ThreadTest#test_thread_timings', call_info.call_sequence)
108
+ assert_equal(2, call_info.children.length)
109
+
110
+ method = methods[1]
111
+ assert_equal('Thread#join', method.full_name)
112
+ assert_equal(1, method.called)
113
+ assert_in_delta(1, method.total_time, 0.01)
114
+ assert_in_delta(0, method.self_time, 0.01)
115
+ assert_in_delta(1.0, method.wait_time, 0.01)
116
+ assert_in_delta(0, method.children_time, 0.01)
117
+
118
+ assert_equal(1, method.call_infos.length)
119
+ call_info = method.call_infos[0]
120
+ assert_equal('ThreadTest#test_thread_timings->Thread#join', call_info.call_sequence)
121
+ assert_equal(0, call_info.children.length)
122
+
123
+ method = methods[2]
124
+ assert_equal('<Class::Thread>#new', method.full_name)
125
+ assert_equal(1, method.called)
126
+ assert_in_delta(0, method.total_time, 0.01)
127
+ assert_in_delta(0, method.self_time, 0.01)
128
+ assert_in_delta(0, method.wait_time, 0.01)
129
+ assert_in_delta(0, method.children_time, 0.01)
130
+
131
+ assert_equal(1, method.call_infos.length)
132
+ call_info = method.call_infos[0]
133
+ assert_equal('ThreadTest#test_thread_timings-><Class::Thread>#new', call_info.call_sequence)
134
+ assert_equal(1, call_info.children.length)
135
+
136
+ method = methods[3]
137
+ assert_equal('Thread#initialize', method.full_name)
138
+ assert_equal(1, method.called)
139
+ assert_in_delta(0, method.total_time, 0.01)
140
+ assert_in_delta(0, method.self_time, 0.01)
141
+ assert_in_delta(0, method.wait_time, 0.01)
142
+ assert_in_delta(0, method.children_time, 0.01)
143
+
144
+ assert_equal(1, method.call_infos.length)
145
+ call_info = method.call_infos[0]
146
+ assert_equal('ThreadTest#test_thread_timings-><Class::Thread>#new->Thread#initialize', call_info.call_sequence)
147
+ assert_equal(0, call_info.children.length)
148
+ end
149
+
150
+ # useless test
151
+ def test_thread_back_and_forth
152
+ result = RubyProf.profile do
153
+ a = Thread.new { 100_000.times { sleep 0 }}
154
+ b = Thread.new { 100_000.times { sleep 0 }}
155
+ a.join
156
+ b.join
157
+ end
158
+ assert result.threads.values.flatten.sort[-1].total_time < 10 # 10s
159
+ end
160
+
161
+ def test_thread
162
+ result = RubyProf.profile do
163
+ begin
164
+ status = Timeout::timeout(2) do
165
+ while true
166
+ next
167
+ end
168
+ end
169
+ rescue Timeout::Error
170
+ end
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,225 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require 'ruby-prof'
5
+
6
+ class UniqueCallPath
7
+ def method_a(i)
8
+ if i==1
9
+ method_b
10
+ else
11
+ method_c
12
+ end
13
+ end
14
+
15
+ def method_b
16
+ method_c
17
+ end
18
+
19
+ def method_c
20
+ c = 3
21
+ end
22
+
23
+ def method_k(i)
24
+ method_a(i)
25
+ end
26
+ end
27
+
28
+
29
+ # -- Tests ----
30
+ class UniqueCallPathTest < Test::Unit::TestCase
31
+ def test_root_method
32
+ unique_call_path = UniqueCallPath.new
33
+
34
+ result = RubyProf.profile do
35
+ unique_call_path.method_a(1)
36
+ end
37
+
38
+ root_methods = Array.new
39
+ result.threads.each do | thread_id, methods |
40
+ methods.each do | m |
41
+ if m.root?
42
+ root_methods.push(m)
43
+ end
44
+ end
45
+ end
46
+
47
+ assert_equal(1, root_methods.length)
48
+ assert_equal("UniqueCallPathTest#test_root_method", root_methods[0].full_name)
49
+ end
50
+
51
+ def test_root_children
52
+ unique_call_path = UniqueCallPath.new
53
+
54
+ result = RubyProf.profile do
55
+ unique_call_path.method_a(1)
56
+ unique_call_path.method_k(2)
57
+ end
58
+
59
+ root_methods = Array.new
60
+ result.threads.each do | thread_id, methods |
61
+ methods.each do | m |
62
+ if m.root?
63
+ root_methods.push(m)
64
+ end
65
+ end
66
+ end
67
+
68
+ assert_equal(1, root_methods.length)
69
+
70
+ root_children = Array.new
71
+ root_methods[0].children.each do | c |
72
+ if c.parent.target.eql?(root_methods[0])
73
+ root_children.push(c)
74
+ end
75
+ end
76
+
77
+ children = root_children.sort do |c1, c2|
78
+ c1.target.full_name <=> c2.target.full_name
79
+ end
80
+
81
+ assert_equal(2, children.length)
82
+ assert_equal("UniqueCallPath#method_a", children[0].target.full_name)
83
+ assert_equal("UniqueCallPath#method_k", children[1].target.full_name)
84
+ end
85
+
86
+ def test_children_of
87
+ unique_call_path = UniqueCallPath.new
88
+
89
+ result = RubyProf.profile do
90
+ unique_call_path.method_a(1)
91
+ unique_call_path.method_k(2)
92
+ end
93
+
94
+ root_methods = Array.new
95
+ result.threads.each do | thread_id, methods |
96
+ methods.each do | m |
97
+ if m.root?
98
+ root_methods.push(m)
99
+ end
100
+ end
101
+ end
102
+
103
+ assert_equal(1, root_methods.length)
104
+ method = root_methods[0]
105
+ assert_equal('UniqueCallPathTest#test_children_of', method.full_name)
106
+
107
+ call_info_a = nil
108
+ root_methods[0].children.each do | c |
109
+ if c.target.full_name == "UniqueCallPath#method_a"
110
+ call_info_a = c
111
+ break
112
+ end
113
+ end
114
+
115
+ assert !call_info_a.nil?
116
+
117
+ children_of_a = Array.new
118
+
119
+ call_info_a.children.each do | c |
120
+ if c.parent.eql?(call_info_a)
121
+ children_of_a.push(c)
122
+ end
123
+ end
124
+
125
+ if RUBY_VERSION < '1.9'
126
+ assert_equal(4, call_info_a.target.children.length)
127
+ else
128
+ assert_equal(2, call_info_a.target.children.length)
129
+ end
130
+
131
+ children_of_a = children_of_a.sort do |c1, c2|
132
+ c1.target.full_name <=> c2.target.full_name
133
+ end
134
+ if RUBY_VERSION < '1.9'
135
+ assert_equal(2, children_of_a.length)
136
+ assert_equal("Fixnum#==", children_of_a[0].target.full_name)
137
+ assert_equal("UniqueCallPath#method_b", children_of_a[1].target.full_name)
138
+ else
139
+ assert_equal(1, children_of_a.length)
140
+ assert_equal("UniqueCallPath#method_b", children_of_a[0].target.full_name)
141
+ end
142
+
143
+ end
144
+
145
+ def test_id2ref
146
+ unique_call_path = UniqueCallPath.new
147
+
148
+ result = RubyProf.profile do
149
+ unique_call_path.method_a(1)
150
+ end
151
+
152
+ root_methods = Array.new
153
+ result.threads.each do | thread_id, methods |
154
+ methods.each do | m |
155
+ if m.root?
156
+ root_methods.push(m)
157
+ end
158
+ end
159
+ end
160
+
161
+ child = root_methods[0].children[0]
162
+
163
+ assert_not_equal(0, child.object_id)
164
+ #assert_equal(RubyProf::CallInfo.id2ref(child.id).target.full_name, child.target.full_name)
165
+ end
166
+
167
+ def test_unique_path
168
+ unique_call_path = UniqueCallPath.new
169
+
170
+ result = RubyProf.profile do
171
+ unique_call_path.method_a(1)
172
+ unique_call_path.method_k(1)
173
+ end
174
+
175
+ root_methods = Array.new
176
+ result.threads.each do | thread_id, methods |
177
+ methods.each do | m |
178
+ if m.root?
179
+ root_methods.push(m)
180
+ end
181
+ end
182
+ end
183
+
184
+ assert_equal(1, root_methods.length)
185
+
186
+ call_info_a = nil
187
+ root_methods[0].children.each do | c |
188
+ if c.target.full_name == "UniqueCallPath#method_a"
189
+ call_info_a = c
190
+ break
191
+ end
192
+ end
193
+
194
+ assert !call_info_a.nil?
195
+
196
+ children_of_a = Array.new
197
+ call_info_a.children.each do |c|
198
+ if c.parent.eql?(call_info_a)
199
+ children_of_a.push(c)
200
+ end
201
+ end
202
+
203
+ if RUBY_VERSION < '1.9'
204
+ assert_equal(4, call_info_a.target.children.length)
205
+ else
206
+ assert_equal(2, call_info_a.target.children.length)
207
+ end
208
+
209
+ children_of_a = children_of_a.sort do |c1, c2|
210
+ c1.target.full_name <=> c2.target.full_name
211
+ end
212
+
213
+ if RUBY_VERSION < '1.9'
214
+ assert_equal(2, children_of_a.length)
215
+ assert_equal(1, children_of_a[0].called)
216
+ assert_equal("Fixnum#==", children_of_a[0].target.full_name)
217
+ assert_equal(1, children_of_a[1].called)
218
+ assert_equal("UniqueCallPath#method_b", children_of_a[1].target.full_name)
219
+ else
220
+ assert_equal(1, children_of_a.length)
221
+ assert_equal(1, children_of_a[0].called)
222
+ assert_equal("UniqueCallPath#method_b", children_of_a[0].target.full_name)
223
+ end
224
+ end
225
+ end