module TestProf::StackProf

StackProf wrapper.

Has 2 modes: global and per-example.

Example:

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

# or in your code
TestProf::StackProf.run

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

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

Public Class Methods

config() click to toggle source
# File lib/test_prof/stack_prof.rb, line 60
def config
  @config ||= Configuration.new
end
configure() { |config| ... } click to toggle source
# File lib/test_prof/stack_prof.rb, line 64
def configure
  yield config
end
dump(name) click to toggle source
# File lib/test_prof/stack_prof.rb, line 109
def dump(name)
  ::StackProf.stop

  path = build_path(name)

  ::StackProf.results(path)

  log :info, "StackProf report generated: #{path}"

  return unless config.raw

  send("dump_#{config.format}_report", path)
end
profile(name = nil) { || ... } click to toggle source
# File lib/test_prof/stack_prof.rb, line 81
      def profile(name = nil)
        if locked?
          log :warn, <<~MSG
            StackProf is activated globally, you cannot generate per-example report.

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

        return false unless init_stack_prof

        options = {
          mode: config.mode,
          raw: config.raw
        }

        options[:interval] = config.interval if config.interval

        if block_given?
          options[:out] = build_path(name)
          ::StackProf.run(**options) { yield }
        else
          ::StackProf.start(**options)
        end
        true
      end
run() click to toggle source

Run StackProf and automatically dump a report when the process exits or when the application is booted.

# File lib/test_prof/stack_prof.rb, line 70
def run
  return unless profile

  @locked = true

  log :info, "StackProf#{config.raw? ? " (raw)" : ""} enabled globally: " \
             "mode – #{config.mode}, target – #{config.target}"

  at_exit { dump("total") } if config.suite?
end

Private Class Methods

build_path(name) click to toggle source
# File lib/test_prof/stack_prof.rb, line 125
def build_path(name)
  TestProf.artifact_path(
    "stack-prof-report-#{config.mode}#{config.raw ? "-raw" : ""}-#{name}.dump"
  )
end
check_stack_prof_version() click to toggle source
# File lib/test_prof/stack_prof.rb, line 148
      def check_stack_prof_version
        if Utils.verify_gem_version("stackprof", at_least: "0.2.9")
          true
        else
          log :error, <<~MSG
            Please, upgrade 'stackprof' to version >= 0.2.9.
          MSG
          false
        end
      end
dump_html_report(path) click to toggle source
# File lib/test_prof/stack_prof.rb, line 159
      def dump_html_report(path)
        html_path = path.gsub(/\.dump$/, ".html")

        log :info, <<~MSG
          Run the following command to generate a flame graph report:

          stackprof --flamegraph #{path} > #{html_path} && stackprof --flamegraph-viewer=#{html_path}
        MSG
      end
dump_json_report(path) click to toggle source
# File lib/test_prof/stack_prof.rb, line 169
      def dump_json_report(path)
        report = ::StackProf::Report.new(
          Marshal.load(IO.binread(path)) # rubocop:disable Security/MarshalLoad
        )
        json_path = path.gsub(/\.dump$/, ".json")
        File.write(json_path, JSON.generate(report.data))

        log :info, <<~MSG
          StackProf JSON report generated: #{json_path}
        MSG
      end
init_stack_prof() click to toggle source
# File lib/test_prof/stack_prof.rb, line 135
      def init_stack_prof
        return @initialized if instance_variable_defined?(:@initialized)
        @locked = false
        @initialized = TestProf.require(
          "stackprof",
          <<~MSG
            Please, install 'stackprof' first:
               # Gemfile
              gem 'stackprof', '>= 0.2.9', require: false
          MSG
        ) { check_stack_prof_version }
      end
locked?() click to toggle source
# File lib/test_prof/stack_prof.rb, line 131
def locked?
  @locked == true
end