ruby-prof-danielhoey 0.8.1
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.
- data/CHANGES +221 -0
- data/LICENSE +23 -0
- data/README +432 -0
- data/Rakefile +158 -0
- data/bin/ruby-prof +224 -0
- data/examples/flat.txt +55 -0
- data/examples/graph.html +823 -0
- data/examples/graph.txt +170 -0
- data/ext/ruby_prof/call_tree.c +392 -0
- data/ext/ruby_prof/call_tree.h +32 -0
- data/ext/ruby_prof/extconf.rb +40 -0
- data/ext/ruby_prof/list.c +66 -0
- data/ext/ruby_prof/list.h +10 -0
- data/ext/ruby_prof/measure_allocations.h +58 -0
- data/ext/ruby_prof/measure_cpu_time.h +152 -0
- data/ext/ruby_prof/measure_gc_runs.h +76 -0
- data/ext/ruby_prof/measure_gc_time.h +57 -0
- data/ext/ruby_prof/measure_memory.h +101 -0
- data/ext/ruby_prof/measure_process_time.h +52 -0
- data/ext/ruby_prof/measure_wall_time.h +53 -0
- data/ext/ruby_prof/measurement.h +13 -0
- data/ext/ruby_prof/mingw/Rakefile +23 -0
- data/ext/ruby_prof/mingw/build.rake +38 -0
- data/ext/ruby_prof/ruby_prof.c +1943 -0
- data/ext/ruby_prof/ruby_prof.h +183 -0
- data/ext/ruby_prof/version.h +4 -0
- data/lib/ruby-prof.rb +59 -0
- data/lib/ruby-prof/abstract_printer.rb +41 -0
- data/lib/ruby-prof/aggregate_call_info.rb +62 -0
- data/lib/ruby-prof/call_info.rb +47 -0
- data/lib/ruby-prof/call_tree/abstract_printer.rb +24 -0
- data/lib/ruby-prof/call_tree/html_printer.rb +89 -0
- data/lib/ruby-prof/call_tree/html_printer_output.html.erb +99 -0
- data/lib/ruby-prof/call_tree/text_printer.rb +28 -0
- data/lib/ruby-prof/call_tree_printer.rb +84 -0
- data/lib/ruby-prof/flat_printer.rb +78 -0
- data/lib/ruby-prof/flat_printer_with_line_numbers.rb +72 -0
- data/lib/ruby-prof/graph_html_printer.rb +256 -0
- data/lib/ruby-prof/graph_printer.rb +157 -0
- data/lib/ruby-prof/method_info.rb +111 -0
- data/lib/ruby-prof/symbol_to_proc.rb +8 -0
- data/lib/ruby-prof/task.rb +146 -0
- data/lib/ruby-prof/test.rb +148 -0
- data/lib/unprof.rb +8 -0
- data/rails/environment/profile.rb +24 -0
- data/rails/example/example_test.rb +9 -0
- data/rails/profile_test_helper.rb +21 -0
- data/test/aggregate_test.rb +121 -0
- data/test/basic_test.rb +290 -0
- data/test/current_failures_windows +8 -0
- data/test/do_nothing.rb +0 -0
- data/test/duplicate_names_test.rb +32 -0
- data/test/enumerable_test.rb +16 -0
- data/test/exceptions_test.rb +15 -0
- data/test/exclude_threads_test.rb +54 -0
- data/test/exec_test.rb +14 -0
- data/test/line_number_test.rb +73 -0
- data/test/measurement_test.rb +121 -0
- data/test/module_test.rb +54 -0
- data/test/no_method_class_test.rb +14 -0
- data/test/prime.rb +58 -0
- data/test/prime_test.rb +13 -0
- data/test/printers_test.rb +130 -0
- data/test/recursive_test.rb +275 -0
- data/test/ruby-prof-bin +20 -0
- data/test/singleton_test.rb +37 -0
- data/test/stack_test.rb +138 -0
- data/test/start_stop_test.rb +95 -0
- data/test/test_suite.rb +23 -0
- data/test/thread_test.rb +173 -0
- data/test/unique_call_path_test.rb +225 -0
- metadata +163 -0
data/lib/unprof.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# Settings specified here will take precedence over those in config/environment.rb
|
2
|
+
# The profile environment should match the same settings
|
3
|
+
# as the production environment to give a reasonalbe
|
4
|
+
# approximation of performance. However, it should
|
5
|
+
# definitely not use the production databse!
|
6
|
+
|
7
|
+
|
8
|
+
# Cache classes - otherwise your code
|
9
|
+
# will run approximately 5 times slower and the
|
10
|
+
# profiling results will be overwhelmed by Rails
|
11
|
+
# dependency loading mechanism
|
12
|
+
config.cache_classes = true
|
13
|
+
|
14
|
+
# Don't check template timestamps - once again this
|
15
|
+
# is to avoid IO times overwhelming profile results
|
16
|
+
config.action_view.cache_template_loading = true
|
17
|
+
|
18
|
+
# This is debatable, but turn off action controller
|
19
|
+
# caching to see how long it really takes to run
|
20
|
+
# queries and render templates
|
21
|
+
config.action_controller.perform_caching = false
|
22
|
+
|
23
|
+
# Turn off most logging
|
24
|
+
config.log_level = :info
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# Load profile environment
|
2
|
+
env = ENV["RAILS_ENV"] = "profile"
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
|
4
|
+
|
5
|
+
# Load Rails testing infrastructure
|
6
|
+
require 'test_help'
|
7
|
+
|
8
|
+
# Now we can load test_helper since we've already loaded the
|
9
|
+
# profile RAILS environment.
|
10
|
+
require File.expand_path(File.join(RAILS_ROOT, 'test', 'test_helper'))
|
11
|
+
|
12
|
+
# Reset the current environment back to profile
|
13
|
+
# since test_helper reset it to test
|
14
|
+
ENV["RAILS_ENV"] = env
|
15
|
+
|
16
|
+
# Now load ruby-prof and away we go
|
17
|
+
require 'ruby-prof'
|
18
|
+
|
19
|
+
# Setup output directory to Rails tmp directory
|
20
|
+
RubyProf::Test::PROFILE_OPTIONS[:output_dir] =
|
21
|
+
File.expand_path(File.join(RAILS_ROOT, 'tmp', 'profile'))
|
@@ -0,0 +1,121 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'ruby-prof'
|
5
|
+
|
6
|
+
# Test data
|
7
|
+
# A B C
|
8
|
+
# | | |
|
9
|
+
# Z A A
|
10
|
+
# | |
|
11
|
+
# Z Z
|
12
|
+
|
13
|
+
class AggClass
|
14
|
+
def z
|
15
|
+
sleep 1
|
16
|
+
end
|
17
|
+
|
18
|
+
def a
|
19
|
+
z
|
20
|
+
end
|
21
|
+
|
22
|
+
def b
|
23
|
+
a
|
24
|
+
end
|
25
|
+
|
26
|
+
def c
|
27
|
+
a
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class AggregateTest < Test::Unit::TestCase
|
32
|
+
def setup
|
33
|
+
# Need to use wall time for this test due to the sleep calls
|
34
|
+
RubyProf::measure_mode = RubyProf::WALL_TIME
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_call_infos
|
38
|
+
c1 = AggClass.new
|
39
|
+
result = RubyProf.profile do
|
40
|
+
c1.a
|
41
|
+
c1.b
|
42
|
+
c1.c
|
43
|
+
end
|
44
|
+
|
45
|
+
methods = result.threads.values.first.sort.reverse
|
46
|
+
method = methods.find {|method| method.full_name == 'AggClass#z'}
|
47
|
+
|
48
|
+
# Check AggClass#z
|
49
|
+
assert_equal('AggClass#z', method.full_name)
|
50
|
+
assert_equal(3, method.called)
|
51
|
+
assert_in_delta(3, method.total_time, 0.01)
|
52
|
+
assert_in_delta(0, method.wait_time, 0.01)
|
53
|
+
assert_in_delta(0, method.self_time, 0.01)
|
54
|
+
assert_in_delta(3, method.children_time, 0.01)
|
55
|
+
assert_equal(3, method.call_infos.length)
|
56
|
+
|
57
|
+
call_info = method.call_infos[0]
|
58
|
+
assert_equal('AggregateTest#test_call_infos->AggClass#a->AggClass#z', call_info.call_sequence)
|
59
|
+
assert_equal(1, call_info.children.length)
|
60
|
+
|
61
|
+
call_info = method.call_infos[1]
|
62
|
+
assert_equal('AggregateTest#test_call_infos->AggClass#b->AggClass#a->AggClass#z', call_info.call_sequence)
|
63
|
+
assert_equal(1, call_info.children.length)
|
64
|
+
|
65
|
+
call_info = method.call_infos[2]
|
66
|
+
assert_equal('AggregateTest#test_call_infos->AggClass#c->AggClass#a->AggClass#z', call_info.call_sequence)
|
67
|
+
assert_equal(1, call_info.children.length)
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_aggregates_parents
|
71
|
+
c1 = AggClass.new
|
72
|
+
result = RubyProf.profile do
|
73
|
+
c1.a
|
74
|
+
c1.b
|
75
|
+
c1.c
|
76
|
+
end
|
77
|
+
|
78
|
+
methods = result.threads.values.first.sort.reverse
|
79
|
+
method = methods.find {|method| method.full_name == 'AggClass#z'}
|
80
|
+
|
81
|
+
# Check AggClass#z
|
82
|
+
assert_equal('AggClass#z', method.full_name)
|
83
|
+
|
84
|
+
call_infos = method.aggregate_parents
|
85
|
+
assert_equal(1, call_infos.length)
|
86
|
+
|
87
|
+
call_info = call_infos.first
|
88
|
+
assert_equal('AggClass#a', call_info.parent.target.full_name)
|
89
|
+
assert_in_delta(3, call_info.total_time, 0.05)
|
90
|
+
assert_in_delta(0, call_info.wait_time, 0.01)
|
91
|
+
assert_in_delta(0, call_info.self_time, 0.05)
|
92
|
+
assert_in_delta(3, call_info.children_time, 0.05)
|
93
|
+
assert_equal(3, call_info.called)
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_aggregates_children
|
97
|
+
c1 = AggClass.new
|
98
|
+
result = RubyProf.profile do
|
99
|
+
c1.a
|
100
|
+
c1.b
|
101
|
+
c1.c
|
102
|
+
end
|
103
|
+
|
104
|
+
methods = result.threads.values.first.sort.reverse
|
105
|
+
method = methods.find {|method| method.full_name == 'AggClass#a'}
|
106
|
+
|
107
|
+
# Check AggClass#a
|
108
|
+
assert_equal('AggClass#a', method.full_name)
|
109
|
+
|
110
|
+
call_infos = method.aggregate_children
|
111
|
+
assert_equal(1, call_infos.length)
|
112
|
+
|
113
|
+
call_info = call_infos.first
|
114
|
+
assert_equal('AggClass#z', call_info.target.full_name)
|
115
|
+
assert_in_delta(3, call_info.total_time, 0.05)
|
116
|
+
assert_in_delta(0, call_info.wait_time, 0.01)
|
117
|
+
assert_in_delta(0, call_info.self_time, 0.05)
|
118
|
+
assert_in_delta(3, call_info.children_time, 0.05)
|
119
|
+
assert_equal(3, call_info.called)
|
120
|
+
end
|
121
|
+
end
|
data/test/basic_test.rb
ADDED
@@ -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
|