acunote-ruby-prof 0.9.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. data/CHANGES +240 -0
  2. data/LICENSE +23 -0
  3. data/README.rdoc +439 -0
  4. data/Rakefile +148 -0
  5. data/bin/ruby-prof +236 -0
  6. data/examples/empty.png +0 -0
  7. data/examples/flat.txt +55 -0
  8. data/examples/graph.dot +106 -0
  9. data/examples/graph.html +823 -0
  10. data/examples/graph.png +0 -0
  11. data/examples/graph.txt +170 -0
  12. data/examples/minus.png +0 -0
  13. data/examples/multi.flat.txt +23 -0
  14. data/examples/multi.graph.html +906 -0
  15. data/examples/multi.grind.dat +194 -0
  16. data/examples/multi.stack.html +573 -0
  17. data/examples/plus.png +0 -0
  18. data/examples/stack.html +573 -0
  19. data/ext/ruby_prof/extconf.rb +43 -0
  20. data/ext/ruby_prof/measure_allocations.h +58 -0
  21. data/ext/ruby_prof/measure_cpu_time.h +152 -0
  22. data/ext/ruby_prof/measure_gc_runs.h +76 -0
  23. data/ext/ruby_prof/measure_gc_time.h +57 -0
  24. data/ext/ruby_prof/measure_memory.h +101 -0
  25. data/ext/ruby_prof/measure_process_time.h +52 -0
  26. data/ext/ruby_prof/measure_wall_time.h +53 -0
  27. data/ext/ruby_prof/mingw/Rakefile +23 -0
  28. data/ext/ruby_prof/mingw/build.rake +38 -0
  29. data/ext/ruby_prof/ruby_prof.c +1834 -0
  30. data/ext/ruby_prof/ruby_prof.h +190 -0
  31. data/ext/ruby_prof/version.h +4 -0
  32. data/lib/ruby-prof.rb +62 -0
  33. data/lib/ruby-prof/abstract_printer.rb +41 -0
  34. data/lib/ruby-prof/aggregate_call_info.rb +68 -0
  35. data/lib/ruby-prof/call_info.rb +112 -0
  36. data/lib/ruby-prof/call_stack_printer.rb +751 -0
  37. data/lib/ruby-prof/call_tree_printer.rb +133 -0
  38. data/lib/ruby-prof/dot_printer.rb +153 -0
  39. data/lib/ruby-prof/empty.png +0 -0
  40. data/lib/ruby-prof/flat_printer.rb +78 -0
  41. data/lib/ruby-prof/flat_printer_with_line_numbers.rb +72 -0
  42. data/lib/ruby-prof/graph_html_printer.rb +278 -0
  43. data/lib/ruby-prof/graph_printer.rb +245 -0
  44. data/lib/ruby-prof/method_info.rb +131 -0
  45. data/lib/ruby-prof/minus.png +0 -0
  46. data/lib/ruby-prof/multi_printer.rb +54 -0
  47. data/lib/ruby-prof/plus.png +0 -0
  48. data/lib/ruby-prof/rack.rb +30 -0
  49. data/lib/ruby-prof/result.rb +70 -0
  50. data/lib/ruby-prof/symbol_to_proc.rb +8 -0
  51. data/lib/ruby-prof/task.rb +146 -0
  52. data/lib/ruby-prof/test.rb +148 -0
  53. data/lib/unprof.rb +8 -0
  54. data/rails/environment/profile.rb +24 -0
  55. data/rails/example/example_test.rb +9 -0
  56. data/rails/profile_test_helper.rb +21 -0
  57. data/test/aggregate_test.rb +136 -0
  58. data/test/basic_test.rb +290 -0
  59. data/test/current_failures_windows +8 -0
  60. data/test/do_nothing.rb +0 -0
  61. data/test/duplicate_names_test.rb +32 -0
  62. data/test/enumerable_test.rb +16 -0
  63. data/test/exceptions_test.rb +15 -0
  64. data/test/exclude_threads_test.rb +54 -0
  65. data/test/exec_test.rb +14 -0
  66. data/test/line_number_test.rb +73 -0
  67. data/test/measurement_test.rb +122 -0
  68. data/test/method_elimination_test.rb +74 -0
  69. data/test/module_test.rb +44 -0
  70. data/test/multi_printer_test.rb +81 -0
  71. data/test/no_method_class_test.rb +13 -0
  72. data/test/prime.rb +55 -0
  73. data/test/prime_test.rb +13 -0
  74. data/test/printers_test.rb +164 -0
  75. data/test/recursive_test.rb +236 -0
  76. data/test/ruby-prof-bin +20 -0
  77. data/test/singleton_test.rb +38 -0
  78. data/test/stack_printer_test.rb +74 -0
  79. data/test/stack_test.rb +138 -0
  80. data/test/start_stop_test.rb +112 -0
  81. data/test/test_suite.rb +32 -0
  82. data/test/thread_test.rb +173 -0
  83. data/test/unique_call_path_test.rb +225 -0
  84. metadata +185 -0
@@ -0,0 +1,290 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require 'ruby-prof'
5
+
6
+ class C1
7
+ def C1.hello
8
+ sleep(0.1)
9
+ end
10
+
11
+ def hello
12
+ sleep(0.2)
13
+ end
14
+ end
15
+
16
+ module M1
17
+ def hello
18
+ sleep(0.3)
19
+ end
20
+ end
21
+
22
+ class C2
23
+ include M1
24
+ extend M1
25
+ end
26
+
27
+ class C3
28
+ def hello
29
+ sleep(0.4)
30
+ end
31
+ end
32
+
33
+ module M4
34
+ def hello
35
+ sleep(0.5)
36
+ end
37
+ end
38
+
39
+ module M5
40
+ include M4
41
+ def goodbye
42
+ hello
43
+ end
44
+ end
45
+
46
+ class C6
47
+ include M5
48
+ def test
49
+ goodbye
50
+ end
51
+ end
52
+
53
+ class BasicTest < Test::Unit::TestCase
54
+ def setup
55
+ # Need to use wall time for this test due to the sleep calls
56
+ RubyProf::measure_mode = RubyProf::WALL_TIME
57
+ end
58
+
59
+ def test_running
60
+ assert(!RubyProf.running?)
61
+ RubyProf.start
62
+ assert(RubyProf.running?)
63
+ RubyProf.stop
64
+ assert(!RubyProf.running?)
65
+ end
66
+
67
+ def test_double_profile
68
+ RubyProf.start
69
+ assert_raise(RuntimeError) do
70
+ RubyProf.start
71
+ end
72
+
73
+ assert_raise(RuntimeError) do
74
+ RubyProf.profile do
75
+ puts 1
76
+ end
77
+ end
78
+ RubyProf.stop
79
+ end
80
+
81
+ def test_no_block
82
+ assert_raise(ArgumentError) do
83
+ RubyProf.profile
84
+ end
85
+ end
86
+
87
+ def test_class_methods
88
+ result = RubyProf.profile do
89
+ C1.hello
90
+ end
91
+
92
+ # Length should be 3:
93
+ # BasicTest#test_class_methods
94
+ # <Class::C1>#hello
95
+ # Kernel#sleep
96
+
97
+ methods = result.threads.values.first.sort.reverse
98
+ assert_equal(3, methods.length)
99
+
100
+ # Check the names
101
+ assert_equal('BasicTest#test_class_methods', methods[0].full_name)
102
+ assert_equal('<Class::C1>#hello', methods[1].full_name)
103
+ assert_equal('Kernel#sleep', methods[2].full_name)
104
+
105
+ # Check times
106
+ assert_in_delta(0.1, methods[0].total_time, 0.01)
107
+ assert_in_delta(0, methods[0].wait_time, 0.01)
108
+ assert_in_delta(0, methods[0].self_time, 0.01)
109
+
110
+ assert_in_delta(0.1, methods[1].total_time, 0.01)
111
+ assert_in_delta(0, methods[1].wait_time, 0.01)
112
+ assert_in_delta(0, methods[1].self_time, 0.01)
113
+
114
+ assert_in_delta(0.1, methods[2].total_time, 0.01)
115
+ assert_in_delta(0, methods[2].wait_time, 0.01)
116
+ assert_in_delta(0.1, methods[2].self_time, 0.01)
117
+ end
118
+
119
+ if RUBY_VERSION < '1.9'
120
+ PARENT = Object
121
+ else
122
+ PARENT = BasicObject
123
+ end
124
+
125
+ def test_instance_methods
126
+ result = RubyProf.profile do
127
+ C1.new.hello
128
+ end
129
+
130
+ # Methods called
131
+ # BasicTest#test_instance_methods
132
+ # Class.new
133
+ # Class:Object#allocate
134
+ # for Object#initialize
135
+ # C1#hello
136
+ # Kernel#sleep
137
+
138
+ methods = result.threads.values.first.sort.reverse
139
+ assert_equal(6, methods.length)
140
+ names = methods.map(&:full_name)
141
+ assert_equal('BasicTest#test_instance_methods', names[0])
142
+ assert_equal('C1#hello', names[1])
143
+ assert_equal('Kernel#sleep', names[2])
144
+ assert_equal('Class#new', names[3])
145
+ # order can differ
146
+ assert(names.include?("<Class::#{PARENT}>#allocate"))
147
+ assert(names.include?("#{PARENT}#initialize"))
148
+
149
+ # Check times
150
+ assert_in_delta(0.2, methods[0].total_time, 0.02)
151
+ assert_in_delta(0, methods[0].wait_time, 0.02)
152
+ assert_in_delta(0, methods[0].self_time, 0.02)
153
+
154
+ assert_in_delta(0.2, methods[1].total_time, 0.02)
155
+ assert_in_delta(0, methods[1].wait_time, 0.02)
156
+ assert_in_delta(0, methods[1].self_time, 0.02)
157
+
158
+ assert_in_delta(0.2, methods[2].total_time, 0.02)
159
+ assert_in_delta(0, methods[2].wait_time, 0.02)
160
+ assert_in_delta(0.2, methods[2].self_time, 0.02)
161
+
162
+ assert_in_delta(0, methods[3].total_time, 0.01)
163
+ assert_in_delta(0, methods[3].wait_time, 0.01)
164
+ assert_in_delta(0, methods[3].self_time, 0.01)
165
+
166
+ assert_in_delta(0, methods[4].total_time, 0.01)
167
+ assert_in_delta(0, methods[4].wait_time, 0.01)
168
+ assert_in_delta(0, methods[4].self_time, 0.01)
169
+
170
+ assert_in_delta(0, methods[5].total_time, 0.01)
171
+ assert_in_delta(0, methods[5].wait_time, 0.01)
172
+ assert_in_delta(0, methods[5].self_time, 0.01)
173
+ end
174
+
175
+ def test_module_methods
176
+ result = RubyProf.profile do
177
+ C2.hello
178
+ end
179
+
180
+ # Methods:
181
+ # BasicTest#test_module_methods
182
+ # M1#hello
183
+ # Kernel#sleep
184
+
185
+ methods = result.threads.values.first.sort.reverse
186
+ assert_equal(3, methods.length)
187
+
188
+ assert_equal('BasicTest#test_module_methods', methods[0].full_name)
189
+ assert_equal('M1#hello', methods[1].full_name)
190
+ assert_equal('Kernel#sleep', methods[2].full_name)
191
+
192
+ # Check times
193
+ assert_in_delta(0.3, methods[0].total_time, 0.1)
194
+ assert_in_delta(0, methods[0].wait_time, 0.02)
195
+ assert_in_delta(0, methods[0].self_time, 0.02)
196
+
197
+ assert_in_delta(0.3, methods[1].total_time, 0.1)
198
+ assert_in_delta(0, methods[1].wait_time, 0.02)
199
+ assert_in_delta(0, methods[1].self_time, 0.02)
200
+
201
+ assert_in_delta(0.3, methods[2].total_time, 0.1)
202
+ assert_in_delta(0, methods[2].wait_time, 0.02)
203
+ assert_in_delta(0.3, methods[2].self_time, 0.1)
204
+ end
205
+
206
+ def test_module_instance_methods
207
+ result = RubyProf.profile do
208
+ C2.new.hello
209
+ end
210
+
211
+ # Methods:
212
+ # BasicTest#test_module_instance_methods
213
+ # Class#new
214
+ # <Class::Object>#allocate
215
+ # Object#initialize
216
+ # M1#hello
217
+ # Kernel#sleep
218
+
219
+ methods = result.threads.values.first.sort.reverse
220
+ assert_equal(6, methods.length)
221
+ names = methods.map(&:full_name)
222
+ assert_equal('BasicTest#test_module_instance_methods', names[0])
223
+ assert_equal('M1#hello', names[1])
224
+ assert_equal('Kernel#sleep', names[2])
225
+ assert_equal('Class#new', names[3])
226
+ assert(names.include?("<Class::#{PARENT}>#allocate"))
227
+ assert(names.include?("#{PARENT}#initialize"))
228
+
229
+ # Check times
230
+ assert_in_delta(0.3, methods[0].total_time, 0.1)
231
+ assert_in_delta(0, methods[0].wait_time, 0.1)
232
+ assert_in_delta(0, methods[0].self_time, 0.1)
233
+
234
+ assert_in_delta(0.3, methods[1].total_time, 0.02)
235
+ assert_in_delta(0, methods[1].wait_time, 0.01)
236
+ assert_in_delta(0, methods[1].self_time, 0.01)
237
+
238
+ assert_in_delta(0.3, methods[2].total_time, 0.02)
239
+ assert_in_delta(0, methods[2].wait_time, 0.01)
240
+ assert_in_delta(0.3, methods[2].self_time, 0.02)
241
+
242
+ assert_in_delta(0, methods[3].total_time, 0.01)
243
+ assert_in_delta(0, methods[3].wait_time, 0.01)
244
+ assert_in_delta(0, methods[3].self_time, 0.01)
245
+
246
+ assert_in_delta(0, methods[4].total_time, 0.01)
247
+ assert_in_delta(0, methods[4].wait_time, 0.01)
248
+ assert_in_delta(0, methods[4].self_time, 0.01)
249
+
250
+ assert_in_delta(0, methods[5].total_time, 0.01)
251
+ assert_in_delta(0, methods[5].wait_time, 0.01)
252
+ assert_in_delta(0, methods[5].self_time, 0.01)
253
+ end
254
+
255
+ def test_singleton
256
+ c3 = C3.new
257
+
258
+ class << c3
259
+ def hello
260
+ end
261
+ end
262
+
263
+ result = RubyProf.profile do
264
+ c3.hello
265
+ end
266
+
267
+ methods = result.threads.values.first.sort.reverse
268
+ assert_equal(2, methods.length)
269
+
270
+ assert_equal('BasicTest#test_singleton', methods[0].full_name)
271
+ assert_equal('<Object::C3>#hello', methods[1].full_name)
272
+
273
+ assert_in_delta(0, methods[0].total_time, 0.01)
274
+ assert_in_delta(0, methods[0].wait_time, 0.01)
275
+ assert_in_delta(0, methods[0].self_time, 0.01)
276
+
277
+ assert_in_delta(0, methods[1].total_time, 0.01)
278
+ assert_in_delta(0, methods[1].wait_time, 0.01)
279
+ assert_in_delta(0, methods[1].self_time, 0.01)
280
+ end
281
+
282
+ def test_traceback
283
+ RubyProf.start
284
+ assert_raise(NoMethodError) do
285
+ RubyProf.xxx
286
+ end
287
+
288
+ RubyProf.stop
289
+ end
290
+ end
@@ -0,0 +1,8 @@
1
+ 1.8 passes, 1.9 however...
2
+
3
+ 1) Failure:
4
+ test_flat_string_with_numbers(PrintersTest) [E:/dev/ruby/ruby-prof/test/printers_test.rb:68]:
5
+ <2> expected but was
6
+ <29>.
7
+
8
+ which is expected until core backports a recent fix.
File without changes
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require 'ruby-prof'
5
+
6
+ class DuplicateNames < Test::Unit::TestCase
7
+ def test_names
8
+ result = RubyProf::profile do
9
+ str = %{module Foo; class Bar; def foo; end end end}
10
+
11
+ eval str
12
+ Foo::Bar.new.foo
13
+ DuplicateNames.class_eval {remove_const :Foo}
14
+
15
+ eval str
16
+ Foo::Bar.new.foo
17
+ DuplicateNames.class_eval {remove_const :Foo}
18
+
19
+ eval str
20
+ Foo::Bar.new.foo
21
+ end
22
+
23
+ # There should be 3 foo methods
24
+ methods = result.threads.values.first.sort.reverse
25
+
26
+ methods = methods.select do |method|
27
+ method.full_name == 'DuplicateNames::Foo::Bar#foo'
28
+ end
29
+
30
+ assert_equal(3, methods.length)
31
+ end
32
+ end
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require 'ruby-prof'
5
+
6
+ # -- Test for bug
7
+ # http://github.com/rdp/ruby-prof/issues#issue/12
8
+
9
+ class EnumerableTest < Test::Unit::TestCase
10
+ def test_enumerable
11
+ result = RubyProf.profile do
12
+ 3.times { [1,2,3].any? {|n| n} }
13
+ end
14
+ assert result.threads.to_a.first[1].length == 4
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ require 'test/unit'
3
+ require 'ruby-prof'
4
+
5
+ class ExceptionsTest < Test::Unit::TestCase
6
+ def test_profile
7
+ result = begin
8
+ RubyProf.profile do
9
+ raise(RuntimeError, 'Test error')
10
+ end
11
+ rescue => e
12
+ end
13
+ assert_not_nil(result)
14
+ end
15
+ end
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require 'ruby-prof'
5
+
6
+
7
+ # -- Tests ----
8
+ class ExcludeThreadsTest < Test::Unit::TestCase
9
+ def test_exclude_threads
10
+
11
+ def thread1_proc
12
+ sleep(0.5)
13
+ sleep(2)
14
+ end
15
+
16
+ def thread2_proc
17
+ sleep(0.5)
18
+ sleep(2)
19
+ end
20
+
21
+ thread1 = Thread.new do
22
+ thread1_proc
23
+ end
24
+
25
+ thread2 = Thread.new do
26
+ thread2_proc
27
+ end
28
+
29
+ RubyProf::exclude_threads = [ thread2 ]
30
+
31
+ RubyProf.start
32
+
33
+ thread1.join
34
+ thread2.join
35
+
36
+ result = RubyProf.stop
37
+
38
+ RubyProf::exclude_threads = nil
39
+
40
+ assert_equal(2, result.threads.length)
41
+
42
+ output = Array.new
43
+ result.threads.each do | thread_id, methods |
44
+ methods.each do | m |
45
+ if m.full_name.index("ExcludeThreadsTest#thread") == 0
46
+ output.push(m.full_name)
47
+ end
48
+ end
49
+ end
50
+
51
+ assert_equal(1, output.length)
52
+ assert_equal("ExcludeThreadsTest#thread1_proc", output[0])
53
+ end
54
+ end
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require 'os'
5
+
6
+ # -- Test for bug when it loads with no frames
7
+
8
+ class EnumerableTest < Test::Unit::TestCase
9
+ def test_being_able_to_run_its_binary
10
+ Dir.chdir(File.dirname(__FILE__)) do
11
+ assert system(OS.ruby_bin + " ruby-prof-bin do_nothing.rb")
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env ruby
2
+ require 'test/unit'
3
+ require 'ruby-prof'
4
+ require 'prime'
5
+
6
+ class LineNumbers
7
+ def method1
8
+ a = 3
9
+ end
10
+
11
+ def method2
12
+ a = 3
13
+ method1
14
+ end
15
+
16
+ def method3
17
+ sleep(1)
18
+ end
19
+ end
20
+
21
+ # -- Tests ----
22
+ class LineNumbersTest < Test::Unit::TestCase
23
+ def test_function_line_no
24
+ numbers = LineNumbers.new
25
+
26
+ result = RubyProf.profile do
27
+ numbers.method2
28
+ end
29
+
30
+ methods = result.threads.values.first.sort.reverse
31
+ assert_equal(3, methods.length)
32
+
33
+ method = methods[0]
34
+ assert_equal('LineNumbersTest#test_function_line_no', method.full_name)
35
+ assert_equal(27, method.line)
36
+
37
+ method = methods[1]
38
+ assert_equal('LineNumbers#method2', method.full_name)
39
+ assert_equal(11, method.line)
40
+
41
+ method = methods[2]
42
+ assert_equal('LineNumbers#method1', method.full_name)
43
+ assert_equal(7, method.line)
44
+ end
45
+
46
+ def test_c_function
47
+ numbers = LineNumbers.new
48
+
49
+ result = RubyProf.profile do
50
+ numbers.method3
51
+ end
52
+
53
+ methods = result.threads.values.first.sort_by {|method| method.full_name}
54
+ assert_equal(3, methods.length)
55
+
56
+ # Methods:
57
+ # LineNumbers#method3
58
+ # LineNumbersTest#test_c_function
59
+ # Kernel#sleep
60
+
61
+ method = methods[0]
62
+ assert_equal('Kernel#sleep', method.full_name)
63
+ assert_equal(0, method.line)
64
+
65
+ method = methods[1]
66
+ assert_equal('LineNumbers#method3', method.full_name)
67
+ assert_equal(16, method.line)
68
+
69
+ method = methods[2]
70
+ assert_equal('LineNumbersTest#test_c_function', method.full_name)
71
+ assert_equal(50, method.line)
72
+ end
73
+ end