ruby-prof 0.17.0 → 0.18.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (185) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGES +500 -482
  3. data/LICENSE +24 -24
  4. data/README.rdoc +487 -485
  5. data/Rakefile +113 -113
  6. data/bin/ruby-prof +345 -345
  7. data/bin/ruby-prof-check-trace +45 -45
  8. data/examples/flat.txt +50 -50
  9. data/examples/graph.dot +84 -84
  10. data/examples/graph.html +823 -823
  11. data/examples/graph.txt +139 -139
  12. data/examples/multi.flat.txt +23 -23
  13. data/examples/multi.graph.html +760 -760
  14. data/examples/multi.grind.dat +114 -114
  15. data/examples/multi.stack.html +547 -547
  16. data/examples/stack.html +547 -547
  17. data/ext/ruby_prof/extconf.rb +68 -68
  18. data/ext/ruby_prof/rp_call_info.c +425 -425
  19. data/ext/ruby_prof/rp_call_info.h +53 -53
  20. data/ext/ruby_prof/rp_measure.c +40 -40
  21. data/ext/ruby_prof/rp_measure.h +45 -45
  22. data/ext/ruby_prof/rp_measure_allocations.c +76 -76
  23. data/ext/ruby_prof/rp_measure_cpu_time.c +136 -136
  24. data/ext/ruby_prof/rp_measure_gc_runs.c +73 -73
  25. data/ext/ruby_prof/rp_measure_gc_time.c +60 -60
  26. data/ext/ruby_prof/rp_measure_memory.c +77 -77
  27. data/ext/ruby_prof/rp_measure_process_time.c +71 -71
  28. data/ext/ruby_prof/rp_measure_wall_time.c +45 -45
  29. data/ext/ruby_prof/rp_method.c +630 -636
  30. data/ext/ruby_prof/rp_method.h +75 -75
  31. data/ext/ruby_prof/rp_stack.c +173 -173
  32. data/ext/ruby_prof/rp_stack.h +63 -63
  33. data/ext/ruby_prof/rp_thread.c +277 -276
  34. data/ext/ruby_prof/rp_thread.h +27 -27
  35. data/ext/ruby_prof/ruby_prof.c +794 -774
  36. data/ext/ruby_prof/ruby_prof.h +60 -59
  37. data/ext/ruby_prof/vc/ruby_prof.sln +20 -21
  38. data/ext/ruby_prof/vc/{ruby_prof_20.vcxproj → ruby_prof.vcxproj} +31 -0
  39. data/lib/ruby-prof.rb +68 -68
  40. data/lib/ruby-prof/aggregate_call_info.rb +76 -76
  41. data/lib/ruby-prof/assets/call_stack_printer.css.html +116 -116
  42. data/lib/ruby-prof/assets/call_stack_printer.js.html +384 -384
  43. data/lib/ruby-prof/call_info.rb +115 -115
  44. data/lib/ruby-prof/call_info_visitor.rb +40 -40
  45. data/lib/ruby-prof/compatibility.rb +179 -178
  46. data/lib/ruby-prof/method_info.rb +121 -121
  47. data/lib/ruby-prof/printers/abstract_printer.rb +104 -103
  48. data/lib/ruby-prof/printers/call_info_printer.rb +41 -41
  49. data/lib/ruby-prof/printers/call_stack_printer.rb +265 -265
  50. data/lib/ruby-prof/printers/call_tree_printer.rb +143 -143
  51. data/lib/ruby-prof/printers/dot_printer.rb +132 -132
  52. data/lib/ruby-prof/printers/flat_printer.rb +70 -70
  53. data/lib/ruby-prof/printers/flat_printer_with_line_numbers.rb +83 -83
  54. data/lib/ruby-prof/printers/graph_html_printer.rb +249 -249
  55. data/lib/ruby-prof/printers/graph_printer.rb +116 -116
  56. data/lib/ruby-prof/printers/multi_printer.rb +84 -84
  57. data/lib/ruby-prof/profile.rb +26 -26
  58. data/lib/ruby-prof/profile/exclude_common_methods.rb +207 -201
  59. data/lib/ruby-prof/profile/legacy_method_elimination.rb +50 -49
  60. data/lib/ruby-prof/rack.rb +174 -174
  61. data/lib/ruby-prof/task.rb +147 -147
  62. data/lib/ruby-prof/thread.rb +35 -35
  63. data/lib/ruby-prof/version.rb +3 -3
  64. data/lib/unprof.rb +10 -10
  65. data/ruby-prof.gemspec +58 -58
  66. data/test/abstract_printer_test.rb +53 -0
  67. data/test/aggregate_test.rb +136 -136
  68. data/test/basic_test.rb +128 -128
  69. data/test/block_test.rb +74 -74
  70. data/test/call_info_test.rb +78 -78
  71. data/test/call_info_visitor_test.rb +31 -31
  72. data/test/duplicate_names_test.rb +32 -32
  73. data/test/dynamic_method_test.rb +55 -55
  74. data/test/enumerable_test.rb +21 -21
  75. data/test/exceptions_test.rb +24 -16
  76. data/test/exclude_methods_test.rb +146 -146
  77. data/test/exclude_threads_test.rb +53 -53
  78. data/test/fiber_test.rb +79 -79
  79. data/test/issue137_test.rb +63 -63
  80. data/test/line_number_test.rb +80 -80
  81. data/test/measure_allocations_test.rb +26 -26
  82. data/test/measure_cpu_time_test.rb +212 -213
  83. data/test/measure_gc_runs_test.rb +32 -32
  84. data/test/measure_gc_time_test.rb +36 -36
  85. data/test/measure_memory_test.rb +33 -33
  86. data/test/measure_process_time_test.rb +61 -63
  87. data/test/measure_wall_time_test.rb +255 -255
  88. data/test/method_elimination_test.rb +84 -84
  89. data/test/module_test.rb +45 -45
  90. data/test/multi_printer_test.rb +104 -104
  91. data/test/no_method_class_test.rb +15 -15
  92. data/test/pause_resume_test.rb +166 -166
  93. data/test/prime.rb +54 -54
  94. data/test/printers_test.rb +275 -275
  95. data/test/printing_recursive_graph_test.rb +127 -127
  96. data/test/rack_test.rb +157 -157
  97. data/test/recursive_test.rb +215 -215
  98. data/test/singleton_test.rb +38 -38
  99. data/test/stack_printer_test.rb +77 -78
  100. data/test/stack_test.rb +138 -138
  101. data/test/start_stop_test.rb +112 -112
  102. data/test/test_helper.rb +267 -275
  103. data/test/thread_test.rb +187 -187
  104. data/test/unique_call_path_test.rb +202 -202
  105. data/test/yarv_test.rb +55 -55
  106. metadata +17 -96
  107. data/doc/LICENSE.html +0 -115
  108. data/doc/README_rdoc.html +0 -637
  109. data/doc/Rack.html +0 -96
  110. data/doc/Rack/RubyProf.html +0 -233
  111. data/doc/Rack/RubyProf/RackProfiler.html +0 -343
  112. data/doc/RubyProf.html +0 -974
  113. data/doc/RubyProf/AbstractPrinter.html +0 -625
  114. data/doc/RubyProf/AggregateCallInfo.html +0 -552
  115. data/doc/RubyProf/CallInfo.html +0 -579
  116. data/doc/RubyProf/CallInfoPrinter.html +0 -121
  117. data/doc/RubyProf/CallInfoVisitor.html +0 -199
  118. data/doc/RubyProf/CallStackPrinter.html +0 -1127
  119. data/doc/RubyProf/CallTreePrinter.html +0 -725
  120. data/doc/RubyProf/Cmd.html +0 -637
  121. data/doc/RubyProf/DeprecationWarnings.html +0 -148
  122. data/doc/RubyProf/DotPrinter.html +0 -258
  123. data/doc/RubyProf/FlatPrinter.html +0 -164
  124. data/doc/RubyProf/FlatPrinterWithLineNumbers.html +0 -210
  125. data/doc/RubyProf/GraphHtmlPrinter.html +0 -558
  126. data/doc/RubyProf/GraphPrinter.html +0 -140
  127. data/doc/RubyProf/MethodInfo.html +0 -676
  128. data/doc/RubyProf/MultiPrinter.html +0 -574
  129. data/doc/RubyProf/Profile.html +0 -908
  130. data/doc/RubyProf/Profile/ExcludeCommonMethods.html +0 -411
  131. data/doc/RubyProf/Profile/LegacyMethodElimination.html +0 -158
  132. data/doc/RubyProf/ProfileTask.html +0 -491
  133. data/doc/RubyProf/Thread.html +0 -275
  134. data/doc/created.rid +0 -33
  135. data/doc/css/fonts.css +0 -167
  136. data/doc/css/rdoc.css +0 -590
  137. data/doc/examples/flat_txt.html +0 -139
  138. data/doc/examples/graph_html.html +0 -910
  139. data/doc/examples/graph_txt.html +0 -248
  140. data/doc/fonts/Lato-Light.ttf +0 -0
  141. data/doc/fonts/Lato-LightItalic.ttf +0 -0
  142. data/doc/fonts/Lato-Regular.ttf +0 -0
  143. data/doc/fonts/Lato-RegularItalic.ttf +0 -0
  144. data/doc/fonts/SourceCodePro-Bold.ttf +0 -0
  145. data/doc/fonts/SourceCodePro-Regular.ttf +0 -0
  146. data/doc/images/add.png +0 -0
  147. data/doc/images/arrow_up.png +0 -0
  148. data/doc/images/brick.png +0 -0
  149. data/doc/images/brick_link.png +0 -0
  150. data/doc/images/bug.png +0 -0
  151. data/doc/images/bullet_black.png +0 -0
  152. data/doc/images/bullet_toggle_minus.png +0 -0
  153. data/doc/images/bullet_toggle_plus.png +0 -0
  154. data/doc/images/date.png +0 -0
  155. data/doc/images/delete.png +0 -0
  156. data/doc/images/find.png +0 -0
  157. data/doc/images/loadingAnimation.gif +0 -0
  158. data/doc/images/macFFBgHack.png +0 -0
  159. data/doc/images/package.png +0 -0
  160. data/doc/images/page_green.png +0 -0
  161. data/doc/images/page_white_text.png +0 -0
  162. data/doc/images/page_white_width.png +0 -0
  163. data/doc/images/plugin.png +0 -0
  164. data/doc/images/ruby.png +0 -0
  165. data/doc/images/tag_blue.png +0 -0
  166. data/doc/images/tag_green.png +0 -0
  167. data/doc/images/transparent.png +0 -0
  168. data/doc/images/wrench.png +0 -0
  169. data/doc/images/wrench_orange.png +0 -0
  170. data/doc/images/zoom.png +0 -0
  171. data/doc/index.html +0 -666
  172. data/doc/js/darkfish.js +0 -161
  173. data/doc/js/jquery.js +0 -4
  174. data/doc/js/navigation.js +0 -142
  175. data/doc/js/navigation.js.gz +0 -0
  176. data/doc/js/search.js +0 -109
  177. data/doc/js/search_index.js +0 -1
  178. data/doc/js/search_index.js.gz +0 -0
  179. data/doc/js/searcher.js +0 -229
  180. data/doc/js/searcher.js.gz +0 -0
  181. data/doc/table_of_contents.html +0 -1052
  182. data/examples/cachegrind.out.1 +0 -114
  183. data/examples/cachegrind.out.1.32313213 +0 -114
  184. data/ext/ruby_prof/vc/ruby_prof_18.vcxproj +0 -108
  185. data/ext/ruby_prof/vc/ruby_prof_19.vcxproj +0 -110
@@ -1,174 +1,174 @@
1
- # encoding: utf-8
2
- require 'tmpdir'
3
-
4
- module Rack
5
- class RubyProf
6
- def initialize(app, options = {})
7
- @app = app
8
-
9
- options[:min_percent] ||= 1
10
-
11
- options[:path] ||= Dir.tmpdir
12
- FileUtils.mkdir_p(options[:path])
13
-
14
- @skip_paths = options[:skip_paths] || [%r{^/assets}, %r{\.(css|js|png|jpeg|jpg|gif)$}]
15
- @only_paths = options[:only_paths]
16
-
17
- @max_requests = options[:max_requests]
18
-
19
- @options = options
20
- end
21
-
22
- def call(env)
23
- request = Rack::Request.new(env)
24
-
25
- if should_profile?(request.path)
26
- profiler.resume
27
- begin
28
- result = @app.call(env)
29
- ensure
30
- profiler.pause
31
- end
32
-
33
- if profiler.max_requests_reached?
34
- prefix = if aggregate_requests?
35
- nil
36
- else
37
- request.path.gsub('/', '-')[1..-1]
38
- end
39
-
40
- profiler.print!(prefix)
41
- delete_profiler!
42
- end
43
-
44
- result
45
- else
46
- @app.call(env)
47
- end
48
- end
49
-
50
- private
51
-
52
- class RackProfiler
53
- def initialize(options)
54
- @options = options
55
-
56
- @profile = ::RubyProf::Profile.new(profiling_options)
57
- @profile.start
58
- @profile.pause
59
-
60
- @printer_klasses = options[:printers] || default_printers
61
-
62
- @tmpdir = options[:path]
63
-
64
- @max_requests = options[:max_requests] || 1
65
- @requests_count = 0
66
-
67
- @printed = false
68
- # if running across multiple requests, we want to make sure that the
69
- # ongoing profile is not lost if the process shuts down before the
70
- # max request count is reached
71
- ObjectSpace.define_finalizer(self, proc { print! })
72
- end
73
-
74
- def resume
75
- @profile.resume
76
- end
77
-
78
- def pause
79
- @profile.pause
80
- @requests_count += 1
81
- end
82
-
83
- def max_requests_reached?
84
- @requests_count >= @max_requests
85
- end
86
-
87
- def print!(prefix = nil)
88
- return false if @printed || @requests_count == 0
89
-
90
- data = @profile.stop
91
-
92
- prefix ||= "multi-requests-#{@requests_count}"
93
-
94
- @printer_klasses.each do |printer_klass, base_name|
95
- printer = printer_klass.new(data)
96
-
97
- if base_name.respond_to?(:call)
98
- base_name = base_name.call
99
- end
100
-
101
- if printer_klass == ::RubyProf::MultiPrinter \
102
- || printer_klass == ::RubyProf::CallTreePrinter
103
- printer.print(@options.merge(:profile => "#{prefix}-#{base_name}"))
104
- else
105
- file_name = ::File.join(@tmpdir, "#{prefix}-#{base_name}")
106
- ::File.open(file_name, 'wb') do |file|
107
- printer.print(file, @options)
108
- end
109
- end
110
- end
111
-
112
- @printed = true
113
- end
114
-
115
- private
116
-
117
- def profiling_options
118
- options = {}
119
- options[:measure_mode] = ::RubyProf.measure_mode
120
- options[:exclude_threads] =
121
- if @options[:ignore_existing_threads]
122
- Thread.list.select{|t| t != Thread.current}
123
- else
124
- ::RubyProf.exclude_threads
125
- end
126
- if @options[:request_thread_only]
127
- options[:include_threads] = [Thread.current]
128
- end
129
- if @options[:merge_fibers]
130
- options[:merge_fibers] = true
131
- end
132
- options
133
- end
134
-
135
- def default_printers
136
- {::RubyProf::FlatPrinter => 'flat.txt',
137
- ::RubyProf::GraphPrinter => 'graph.txt',
138
- ::RubyProf::GraphHtmlPrinter => 'graph.html',
139
- ::RubyProf::CallStackPrinter => 'call_stack.html'}
140
- end
141
- end
142
-
143
- def profiler
144
- if aggregate_requests?
145
- @@_shared_profiler ||= RackProfiler.new(@options)
146
- else
147
- @_profiler ||= RackProfiler.new(@options)
148
- end
149
- end
150
-
151
- def delete_profiler!
152
- if aggregate_requests?
153
- @@_shared_profiler.print! if @@_shared_profiler
154
- @@_shared_profiler = nil
155
- else
156
- @_profiler = nil
157
- end
158
- end
159
-
160
- def aggregate_requests?
161
- !@max_requests.nil?
162
- end
163
-
164
- def should_profile?(path)
165
- return false if paths_match?(path, @skip_paths)
166
-
167
- @only_paths ? paths_match?(path, @only_paths) : true
168
- end
169
-
170
- def paths_match?(path, paths)
171
- paths.any? { |skip_path| skip_path =~ path }
172
- end
173
- end
174
- end
1
+ # encoding: utf-8
2
+ require 'tmpdir'
3
+
4
+ module Rack
5
+ class RubyProf
6
+ def initialize(app, options = {})
7
+ @app = app
8
+
9
+ options[:min_percent] ||= 1
10
+
11
+ options[:path] ||= Dir.tmpdir
12
+ FileUtils.mkdir_p(options[:path])
13
+
14
+ @skip_paths = options[:skip_paths] || [%r{^/assets}, %r{\.(css|js|png|jpeg|jpg|gif)$}]
15
+ @only_paths = options[:only_paths]
16
+
17
+ @max_requests = options[:max_requests]
18
+
19
+ @options = options
20
+ end
21
+
22
+ def call(env)
23
+ request = Rack::Request.new(env)
24
+
25
+ if should_profile?(request.path)
26
+ profiler.resume
27
+ begin
28
+ result = @app.call(env)
29
+ ensure
30
+ profiler.pause
31
+ end
32
+
33
+ if profiler.max_requests_reached?
34
+ prefix = if aggregate_requests?
35
+ nil
36
+ else
37
+ request.path.gsub('/', '-')[1..-1]
38
+ end
39
+
40
+ profiler.print!(prefix)
41
+ delete_profiler!
42
+ end
43
+
44
+ result
45
+ else
46
+ @app.call(env)
47
+ end
48
+ end
49
+
50
+ private
51
+
52
+ class RackProfiler
53
+ def initialize(options)
54
+ @options = options
55
+
56
+ @profile = ::RubyProf::Profile.new(profiling_options)
57
+ @profile.start
58
+ @profile.pause
59
+
60
+ @printer_klasses = options[:printers] || default_printers
61
+
62
+ @tmpdir = options[:path]
63
+
64
+ @max_requests = options[:max_requests] || 1
65
+ @requests_count = 0
66
+
67
+ @printed = false
68
+ # if running across multiple requests, we want to make sure that the
69
+ # ongoing profile is not lost if the process shuts down before the
70
+ # max request count is reached
71
+ ObjectSpace.define_finalizer(self, proc { print! })
72
+ end
73
+
74
+ def resume
75
+ @profile.resume
76
+ end
77
+
78
+ def pause
79
+ @profile.pause
80
+ @requests_count += 1
81
+ end
82
+
83
+ def max_requests_reached?
84
+ @requests_count >= @max_requests
85
+ end
86
+
87
+ def print!(prefix = nil)
88
+ return false if @printed || @requests_count == 0
89
+
90
+ data = @profile.stop
91
+
92
+ prefix ||= "multi-requests-#{@requests_count}"
93
+
94
+ @printer_klasses.each do |printer_klass, base_name|
95
+ printer = printer_klass.new(data)
96
+
97
+ if base_name.respond_to?(:call)
98
+ base_name = base_name.call
99
+ end
100
+
101
+ if printer_klass == ::RubyProf::MultiPrinter \
102
+ || printer_klass == ::RubyProf::CallTreePrinter
103
+ printer.print(@options.merge(:profile => "#{prefix}-#{base_name}"))
104
+ else
105
+ file_name = ::File.join(@tmpdir, "#{prefix}-#{base_name}")
106
+ ::File.open(file_name, 'wb') do |file|
107
+ printer.print(file, @options)
108
+ end
109
+ end
110
+ end
111
+
112
+ @printed = true
113
+ end
114
+
115
+ private
116
+
117
+ def profiling_options
118
+ options = {}
119
+ options[:measure_mode] = ::RubyProf.measure_mode
120
+ options[:exclude_threads] =
121
+ if @options[:ignore_existing_threads]
122
+ Thread.list.select{|t| t != Thread.current}
123
+ else
124
+ ::RubyProf.exclude_threads
125
+ end
126
+ if @options[:request_thread_only]
127
+ options[:include_threads] = [Thread.current]
128
+ end
129
+ if @options[:merge_fibers]
130
+ options[:merge_fibers] = true
131
+ end
132
+ options
133
+ end
134
+
135
+ def default_printers
136
+ {::RubyProf::FlatPrinter => 'flat.txt',
137
+ ::RubyProf::GraphPrinter => 'graph.txt',
138
+ ::RubyProf::GraphHtmlPrinter => 'graph.html',
139
+ ::RubyProf::CallStackPrinter => 'call_stack.html'}
140
+ end
141
+ end
142
+
143
+ def profiler
144
+ if aggregate_requests?
145
+ @@_shared_profiler ||= RackProfiler.new(@options)
146
+ else
147
+ @_profiler ||= RackProfiler.new(@options)
148
+ end
149
+ end
150
+
151
+ def delete_profiler!
152
+ if aggregate_requests?
153
+ @@_shared_profiler.print! if @@_shared_profiler
154
+ @@_shared_profiler = nil
155
+ else
156
+ @_profiler = nil
157
+ end
158
+ end
159
+
160
+ def aggregate_requests?
161
+ !@max_requests.nil?
162
+ end
163
+
164
+ def should_profile?(path)
165
+ return false if paths_match?(path, @skip_paths)
166
+
167
+ @only_paths ? paths_match?(path, @only_paths) : true
168
+ end
169
+
170
+ def paths_match?(path, paths)
171
+ paths.any? { |skip_path| skip_path =~ path }
172
+ end
173
+ end
174
+ end
@@ -1,147 +1,147 @@
1
- #!/usr/bin/env ruby
2
- # encoding: utf-8
3
-
4
- require 'rake'
5
- require 'rake/testtask'
6
- require 'fileutils'
7
-
8
- module RubyProf
9
-
10
- # Define a task library for profiling unit tests with ruby-prof.
11
- #
12
- # All of the options provided by
13
- # the Rake:TestTask are supported except the loader
14
- # which is set to ruby-prof. For detailed information
15
- # please refer to the Rake:TestTask documentation.
16
- #
17
- # ruby-prof specific options include:
18
- #
19
- # output_dir - For each file specified an output
20
- # file with profile information will be
21
- # written to the output directory.
22
- # By default, the output directory is
23
- # called "profile" and is created underneath
24
- # the current working directory.
25
- #
26
- # printer - Specifies the output printer. Valid values include
27
- # :flat, :graph, :graph_html and :call_tree.
28
- #
29
- # min_percent - Methods that take less than the specified percent
30
- # will not be written out.
31
- #
32
- # Example:
33
- #
34
- # require 'ruby-prof/task'
35
- #
36
- # RubyProf::ProfileTask.new do |t|
37
- # t.test_files = FileList['test/test*.rb']
38
- # t.output_dir = "c:/temp"
39
- # t.printer = :graph
40
- # t.min_percent = 10
41
- # end
42
- #
43
- # If rake is invoked with a "TEST=filename" command line option,
44
- # then the list of test files will be overridden to include only the
45
- # filename specified on the command line. This provides an easy way
46
- # to run just one test.
47
- #
48
- # If rake is invoked with a "TESTOPTS=options" command line option,
49
- # then the given options are passed to the test process after a
50
- # '--'. This allows Test::Unit options to be passed to the test
51
- # suite.
52
- #
53
- # Examples:
54
- #
55
- # rake profile # run tests normally
56
- # rake profile TEST=just_one_file.rb # run just one test file.
57
- # rake profile TESTOPTS="-v" # run in verbose mode
58
- # rake profile TESTOPTS="--runner=fox" # use the fox test runner
59
-
60
- class ProfileTask < Rake::TestTask
61
- attr_accessor :output_dir
62
- attr_accessor :min_percent
63
- attr_accessor :printer
64
-
65
- def initialize(name = :profile)
66
- super(name)
67
- end
68
-
69
- # Create the tasks defined by this task lib.
70
- def define
71
- lib_path = @libs.join(File::PATH_SEPARATOR)
72
- desc "Profile" + (@name==:profile ? "" : " for #{@name}")
73
-
74
- task @name do
75
- create_output_directory
76
-
77
- @ruby_opts.unshift( "-I#{lib_path}" )
78
- @ruby_opts.unshift( "-w" ) if @warning
79
- @ruby_opts.push("-S ruby-prof")
80
- @ruby_opts.push("--printer #{@printer}")
81
- @ruby_opts.push("--min_percent #{@min_percent}")
82
-
83
- file_list.each do |file_path|
84
- run_script(file_path)
85
- end
86
- end
87
- self
88
- end
89
-
90
- # Run script
91
- def run_script(script_path)
92
- run_code = ''
93
- RakeFileUtils.verbose(@verbose) do
94
- file_name = File.basename(script_path, File.extname(script_path))
95
- case @printer
96
- when :flat, :graph, :call_tree
97
- file_name += ".txt"
98
- when :graph_html
99
- file_name += ".html"
100
- else
101
- file_name += ".txt"
102
- end
103
-
104
- output_file_path = File.join(output_directory, file_name)
105
-
106
- command_line = @ruby_opts.join(" ") +
107
- " --file=" + output_file_path +
108
- " " + script_path
109
-
110
- puts "ruby " + command_line
111
- # We have to catch the exeption to continue on. However,
112
- # the error message will have been output to STDERR
113
- # already by the time we get here so we don't have to
114
- # do that again
115
- begin
116
- ruby command_line
117
- rescue => e
118
- STDOUT << e << "\n"
119
- STDOUT.flush
120
- end
121
- puts ""
122
- puts ""
123
- end
124
- end
125
-
126
- def output_directory
127
- File.expand_path(@output_dir)
128
- end
129
-
130
- def create_output_directory
131
- if not File.exist?(output_directory)
132
- Dir.mkdir(output_directory)
133
- end
134
- end
135
-
136
- def clean_output_directory
137
- if File.exist?(output_directory)
138
- files = Dir.glob(output_directory + '/*')
139
- FileUtils.rm(files)
140
- end
141
- end
142
-
143
- def option_list # :nodoc:
144
- ENV['OPTIONS'] || @options.join(" ") || ""
145
- end
146
- end
147
- end
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ require 'rake'
5
+ require 'rake/testtask'
6
+ require 'fileutils'
7
+
8
+ module RubyProf
9
+
10
+ # Define a task library for profiling unit tests with ruby-prof.
11
+ #
12
+ # All of the options provided by
13
+ # the Rake:TestTask are supported except the loader
14
+ # which is set to ruby-prof. For detailed information
15
+ # please refer to the Rake:TestTask documentation.
16
+ #
17
+ # ruby-prof specific options include:
18
+ #
19
+ # output_dir - For each file specified an output
20
+ # file with profile information will be
21
+ # written to the output directory.
22
+ # By default, the output directory is
23
+ # called "profile" and is created underneath
24
+ # the current working directory.
25
+ #
26
+ # printer - Specifies the output printer. Valid values include
27
+ # :flat, :graph, :graph_html and :call_tree.
28
+ #
29
+ # min_percent - Methods that take less than the specified percent
30
+ # will not be written out.
31
+ #
32
+ # Example:
33
+ #
34
+ # require 'ruby-prof/task'
35
+ #
36
+ # RubyProf::ProfileTask.new do |t|
37
+ # t.test_files = FileList['test/test*.rb']
38
+ # t.output_dir = "c:/temp"
39
+ # t.printer = :graph
40
+ # t.min_percent = 10
41
+ # end
42
+ #
43
+ # If rake is invoked with a "TEST=filename" command line option,
44
+ # then the list of test files will be overridden to include only the
45
+ # filename specified on the command line. This provides an easy way
46
+ # to run just one test.
47
+ #
48
+ # If rake is invoked with a "TESTOPTS=options" command line option,
49
+ # then the given options are passed to the test process after a
50
+ # '--'. This allows Test::Unit options to be passed to the test
51
+ # suite.
52
+ #
53
+ # Examples:
54
+ #
55
+ # rake profile # run tests normally
56
+ # rake profile TEST=just_one_file.rb # run just one test file.
57
+ # rake profile TESTOPTS="-v" # run in verbose mode
58
+ # rake profile TESTOPTS="--runner=fox" # use the fox test runner
59
+
60
+ class ProfileTask < Rake::TestTask
61
+ attr_accessor :output_dir
62
+ attr_accessor :min_percent
63
+ attr_accessor :printer
64
+
65
+ def initialize(name = :profile)
66
+ super(name)
67
+ end
68
+
69
+ # Create the tasks defined by this task lib.
70
+ def define
71
+ lib_path = @libs.join(File::PATH_SEPARATOR)
72
+ desc "Profile" + (@name==:profile ? "" : " for #{@name}")
73
+
74
+ task @name do
75
+ create_output_directory
76
+
77
+ @ruby_opts.unshift( "-I#{lib_path}" )
78
+ @ruby_opts.unshift( "-w" ) if @warning
79
+ @ruby_opts.push("-S ruby-prof")
80
+ @ruby_opts.push("--printer #{@printer}")
81
+ @ruby_opts.push("--min_percent #{@min_percent}")
82
+
83
+ file_list.each do |file_path|
84
+ run_script(file_path)
85
+ end
86
+ end
87
+ self
88
+ end
89
+
90
+ # Run script
91
+ def run_script(script_path)
92
+ run_code = ''
93
+ RakeFileUtils.verbose(@verbose) do
94
+ file_name = File.basename(script_path, File.extname(script_path))
95
+ case @printer
96
+ when :flat, :graph, :call_tree
97
+ file_name += ".txt"
98
+ when :graph_html
99
+ file_name += ".html"
100
+ else
101
+ file_name += ".txt"
102
+ end
103
+
104
+ output_file_path = File.join(output_directory, file_name)
105
+
106
+ command_line = @ruby_opts.join(" ") +
107
+ " --file=" + output_file_path +
108
+ " " + script_path
109
+
110
+ puts "ruby " + command_line
111
+ # We have to catch the exeption to continue on. However,
112
+ # the error message will have been output to STDERR
113
+ # already by the time we get here so we don't have to
114
+ # do that again
115
+ begin
116
+ ruby command_line
117
+ rescue => e
118
+ STDOUT << e << "\n"
119
+ STDOUT.flush
120
+ end
121
+ puts ""
122
+ puts ""
123
+ end
124
+ end
125
+
126
+ def output_directory
127
+ File.expand_path(@output_dir)
128
+ end
129
+
130
+ def create_output_directory
131
+ if not File.exist?(output_directory)
132
+ Dir.mkdir(output_directory)
133
+ end
134
+ end
135
+
136
+ def clean_output_directory
137
+ if File.exist?(output_directory)
138
+ files = Dir.glob(output_directory + '/*')
139
+ FileUtils.rm(files)
140
+ end
141
+ end
142
+
143
+ def option_list # :nodoc:
144
+ ENV['OPTIONS'] || @options.join(" ") || ""
145
+ end
146
+ end
147
+ end