ruby-prof 0.8.1-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
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