Add stackprof profiling to test suite.

To use, run STACKPROF=1 bundle exec rspec
This commit is contained in:
Parker Moore 2018-12-13 16:08:40 -05:00
Родитель fb5c3f22a5
Коммит 71f965a448
3 изменённых файлов: 87 добавлений и 1 удалений

Просмотреть файл

@ -6,3 +6,7 @@ gemspec
# Whitelisted plugins not included in runtime dependencies.
gem "jekyll-octicons"
group :profile do
gem "stackprof", require: false
end

Просмотреть файл

@ -2,6 +2,7 @@
require File.expand_path("../lib/github-pages.rb", __dir__)
require "open3"
require_relative "spec_profiling"
RSpec.configure do |config|
config.run_all_when_everything_filtered = true
@ -19,7 +20,7 @@ def fixture_dir
end
def tmp_dir
File.expand_path "../tmp", __dir__
File.expand_path "spec/tmp", __dir__
end
RSpec::Matchers.define :be_an_existing_file do

81
spec/spec_profiling.rb Normal file
Просмотреть файл

@ -0,0 +1,81 @@
# Source: https://gist.github.com/palkan/73395cc201a565ecd3ff61aac44ad5ae
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 = File.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 = File.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 = File.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 = File.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