module TestProf::RubyProf

RubyProf wrapper.

Has 2 modes: global and per-example.

Example:

# To activate global profiling you can use env variable
TEST_RUBY_PROF=1 rspec ...

# or in your code
TestProf::RubyProf.run

To profile a specific examples add :rprof tag to it:

it "is doing heavy stuff", :rprof do
  ...
end

Public Class Methods

config() click to toggle source
# File lib/test_prof/ruby_prof.rb, line 140
def config
  @config ||= Configuration.new
end
configure() { |config| ... } click to toggle source
# File lib/test_prof/ruby_prof.rb, line 144
def configure
  yield config
end
profile() click to toggle source
# File lib/test_prof/ruby_prof.rb, line 164
      def profile
        if locked?
          log :warn, <<~MSG
            RubyProf is activated globally, you cannot generate per-example report.

            Make sure you haven's set the TEST_RUBY_PROF environmental variable.
          MSG
          return
        end

        return unless init_ruby_prof

        options = {
          merge_fibers: true
        }

        options[:include_threads] = [Thread.current] unless
          config.include_threads?

        profiler = ::RubyProf::Profile.new(options)
        profiler.exclude_common_methods! if config.exclude_common_methods?

        if config.test_prof_exclusions_enabled?
          # custom test-prof exclusions
          exclude_rspec_methods(profiler)

          # custom global exclusions
          exclude_common_methods(profiler)
        end

        config.custom_exclusions.each do |klass, mids|
          profiler.exclude_methods! klass, *mids
        end

        profiler.start

        Report.new(profiler)
      end
run() click to toggle source

Run RubyProf and automatically dump a report when the process exits.

Use this method to profile the whole run.

# File lib/test_prof/ruby_prof.rb, line 152
def run
  report = profile

  return unless report

  @locked = true

  log :info, "RubyProf enabled globally"

  at_exit { report.dump("total") }
end

Private Class Methods

check_ruby_prof_version() click to toggle source
# File lib/test_prof/ruby_prof.rb, line 222
      def check_ruby_prof_version
        if Utils.verify_gem_version("ruby-prof", at_least: "0.17.0")
          true
        else
          log :error, <<~MGS
            Please, upgrade 'ruby-prof' to version >= 0.17.0.
          MGS
          false
        end
      end
exclude_common_methods(profiler) click to toggle source
# File lib/test_prof/ruby_prof.rb, line 241
def exclude_common_methods(profiler)
  if defined?(TSort)
    profiler.exclude_methods!(
      TSort,
      :tsort_each
    )

    profiler.exclude_methods!(
      TSort.singleton_class,
      :tsort_each, :each_strongly_connected_component,
      :each_strongly_connected_component_from
    )
  end

  profiler.exclude_methods!(
    BasicObject,
    :instance_exec
  )
end
exclude_rspec_methods(profiler) click to toggle source
# File lib/test_prof/ruby_prof.rb, line 233
def exclude_rspec_methods(profiler)
  return unless TestProf.rspec?

  RSpecExclusions.generate.each do |klass, mids|
    profiler.exclude_methods!(klass, *mids)
  end
end
init_ruby_prof() click to toggle source
# File lib/test_prof/ruby_prof.rb, line 209
      def init_ruby_prof
        return @initialized if instance_variable_defined?(:@initialized)
        ENV["RUBY_PROF_MEASURE_MODE"] = config.mode.to_s
        @initialized = TestProf.require(
          "ruby-prof",
          <<~MSG
            Please, install 'ruby-prof' first:
               # Gemfile
              gem 'ruby-prof', '>= 0.16.0', require: false
          MSG
        ) { check_ruby_prof_version }
      end
locked?() click to toggle source
# File lib/test_prof/ruby_prof.rb, line 205
def locked?
  @locked == true
end