acunote-ruby-prof 0.9.2

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 (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