|
module SpecProfiling |
|
class << self |
|
def init |
|
ruby_prof if ENV['RUBYPROF'] |
|
stack_prof if ENV['STACKPROF'] |
|
end |
|
|
|
def ruby_prof |
|
require 'ruby-prof' |
|
$stdout.puts "RubyProf enabled" |
|
|
|
profiler = RubyProf::Profile.new( |
|
merge_fibers: true, |
|
include_threads: [Thread.current] |
|
) |
|
|
|
profiler.start |
|
|
|
at_exit do |
|
result = profiler.stop |
|
|
|
# Common RSpec methods |
|
result.eliminate_methods!( |
|
[ |
|
/instance_exec/, |
|
/Example(Group)?>?#run(_examples)?/, |
|
/Procsy/, |
|
/AroundHook#execute_with/, |
|
/HookCollections/, |
|
/Array#(map|each)/ |
|
] |
|
) |
|
printer_type = ENV['RPRINTER'] || 'call_stack' |
|
printer = "RubyProf::#{printer_type.camelize}Printer".constantize |
|
path = Rails.root.join("tmp", "ruby-prof-report-#{printer_type}-#{RubyProf.measure_mode}-total.html") |
|
File.open(path.to_s, 'w') { |f| printer.new(result).print(f, min_percent: 1) } |
|
end |
|
end |
|
|
|
def stack_prof |
|
require 'stackprof' |
|
mode = ENV['RMODE'] || 'wall' |
|
$stdout.puts "StackProf enabled (mode: #{mode})" |
|
path = Rails.root.join("tmp", "stackprof-#{mode}-test-total.dump") |
|
# we use raw to make it possible to generate flamegraphs |
|
StackProf.start(mode: mode.to_sym, raw: true) |
|
|
|
at_exit do |
|
StackProf.stop |
|
StackProf.results path.to_s |
|
end |
|
end |
|
end |
|
end |
|
|
|
RSpec.configure do |config| |
|
config.around(:each, :sprof) do |ex| |
|
require 'stackprof' |
|
mode = ENV['RMODE'] || 'wall' |
|
path = Rails.root.join("tmp", "stackprof-#{mode}-test-#{ex.full_description.parameterize}.dump") |
|
StackProf.run(mode: mode, out: path.to_s, raw: true) do |
|
ex.run |
|
end |
|
end |
|
|
|
config.around(:each, :rprof) do |ex| |
|
require 'ruby-prof' |
|
|
|
result = RubyProf.profile { ex.run } |
|
|
|
printer_type = ENV['RPRINTER'] || 'call_stack' |
|
printer = "RubyProf::#{printer_type.camelize}Printer".constantize |
|
|
|
path = Rails.root.join("tmp", "ruby-prof-report-#{printer_type}-#{RubyProf.measure_mode}-#{ex.full_description.parameterize}.html") |
|
File.open(path.to_s, 'w') { |f| printer.new(result).print(f, min_percent: 1) } |
|
end |
|
end |
|
|
|
SpecProfiling.init |
See https://choosealicense.com/ for tl;dr
Please, please add a license. The fact none is listed makes using this software a legal quagmire. Currently it is not legal to use this code or its derivatives in any useful software. I may be mistaken but hopefully this is not the intended effect.
Currently no license is mentioned anywhere, what makes this code fully copyrighted, like any other creative work.
It limits usefulness of this project - and I hope that it is unintentional. For example it seems that it would solve my problem of profiling hilariously slow rspec tests (
2036.33 seconds ./spec/word_processor_spec.rb:43
), in current situation I would be unable to legally publish project that would use this solution.Obviously, please do not release it under any license if you are not the author (that would be even worse legal quagmire)