mirror of
https://gh.wpcy.net/https://github.com/discourse/discourse.git
synced 2026-06-18 23:39:11 +08:00
Adds `RspecPerformanceFormatter`, an RSpec formatter that captures the SQL queries, Redis commands, and outbound network calls each example performs and emits them as NDJSON with one object per test. It gives an AI model (or a developer) concrete per-test context for spotting N+1s, redundant queries, or unexpected outbound calls. Off unless the formatter is selected, so normal runs and production are unaffected. Works with both `bin/rspec` and `bin/turbo_rspec`.
138 lines
3.7 KiB
Ruby
Executable file
Vendored
138 lines
3.7 KiB
Ruby
Executable file
Vendored
#!/usr/bin/env ruby
|
|
# frozen_string_literal: true
|
|
|
|
ENV["RAILS_ENV"] ||= "test"
|
|
|
|
require "./lib/turbo_tests"
|
|
require "optparse"
|
|
|
|
requires = []
|
|
formatters = []
|
|
verbose = false
|
|
fail_fast = nil
|
|
seed = rand(2**16)
|
|
profile = false
|
|
profile_print_slowest_examples_count = 10
|
|
use_runtime_info = nil
|
|
enable_system_tests = nil
|
|
retry_and_log_flaky_tests = ENV["DISCOURSE_TURBO_RSPEC_RETRY_AND_LOG_FLAKY_TESTS"].to_s == "1"
|
|
exclude_patterns = []
|
|
|
|
OptionParser
|
|
.new do |opts|
|
|
opts.on("-r", "--require PATH", "Require a file.") { |filename| requires << filename }
|
|
|
|
opts.on("-f", "--format FORMATTER", "Choose a formatter.") do |name|
|
|
formatters << { name: name, outputs: [] }
|
|
end
|
|
|
|
opts.on("-o", "--out FILE", "Write output to a file instead of $stdout") do |filename|
|
|
formatters << { name: "progress", outputs: [] } if formatters.empty?
|
|
formatters.last[:outputs] << filename
|
|
end
|
|
|
|
opts.on("-v", "--verbose", "More output") { verbose = true }
|
|
|
|
opts.on(
|
|
"-p",
|
|
"--profile=[COUNT]",
|
|
"Benchmark the runtime of each example and list the slowest examples (default: 10)",
|
|
) do |count|
|
|
profile = true
|
|
profile_print_slowest_examples_count = count.to_i if count
|
|
end
|
|
|
|
opts.on("--fail-fast=[N]") do |n|
|
|
n =
|
|
begin
|
|
Integer(n)
|
|
rescue StandardError
|
|
nil
|
|
end
|
|
fail_fast = (n.nil? || n < 1) ? 1 : n
|
|
end
|
|
|
|
opts.on(
|
|
"--retry-and-log-flaky-tests",
|
|
"Retry failed tests and log if test is deemed to be flaky",
|
|
) { retry_and_log_flaky_tests = true }
|
|
|
|
opts.on("--seed SEED", "The seed for the random order") { |s| seed = s.to_i }
|
|
|
|
opts.on("--use-runtime-info", "Use runtime info for tests group splitting") do
|
|
use_runtime_info = true
|
|
end
|
|
|
|
opts.on("--enable-system-tests", "Run the system tests (defaults false)") do
|
|
enable_system_tests = true
|
|
end
|
|
|
|
opts.on(
|
|
"--exclude-pattern=pattern",
|
|
"Exclude files that matches against the pattern using unix-style pattern matching (comma-separated for multiple patterns)",
|
|
) { |pattern| exclude_patterns.concat(pattern.split(",").map(&:strip)) }
|
|
end
|
|
.parse!(ARGV)
|
|
|
|
# OptionParser modifies ARGV, leaving the leftover arguments in ARGV
|
|
if ARGV.empty?
|
|
files = Dir.glob("spec/**/*_spec.rb")
|
|
files.reject! { |file| File.fnmatch("*spec/system*", file) } if !enable_system_tests
|
|
|
|
use_runtime_info = true if use_runtime_info.nil?
|
|
else
|
|
STDERR.puts "Ignoring system test options since files were specified" if enable_system_tests
|
|
|
|
files =
|
|
ARGV.flat_map do |arg|
|
|
if File.directory?(arg)
|
|
Dir.glob("#{arg}/**/*_spec.rb")
|
|
else
|
|
arg
|
|
end
|
|
end
|
|
|
|
use_runtime_info = false if use_runtime_info.nil?
|
|
end
|
|
|
|
if exclude_patterns.any?
|
|
files.reject! { |file| exclude_patterns.any? { |pattern| File.fnmatch(pattern, file) } }
|
|
end
|
|
|
|
requires.each { |f| require(f) }
|
|
|
|
formatters << { name: "progress", outputs: [] } if formatters.empty?
|
|
|
|
formatters.each { |formatter| formatter[:outputs] << "-" if formatter[:outputs].empty? }
|
|
|
|
if formatters.any? { |formatter| formatter[:name] == "RspecPerformanceFormatter" }
|
|
ENV["DISCOURSE_RSPEC_PERFORMANCE_FORMATTER"] = "1"
|
|
require "./spec/support/rspec_performance_formatter"
|
|
end
|
|
|
|
puts "::group::Run turbo_rspec" if ENV["GITHUB_ACTIONS"]
|
|
if files.size > 5
|
|
puts "Running turbo_rspec on #{files.size} files"
|
|
else
|
|
puts "Running turbo_rspec on: #{files.join(", ")}"
|
|
end
|
|
puts "::endgroup::" if ENV["GITHUB_ACTIONS"]
|
|
|
|
success =
|
|
TurboTests::Runner.run(
|
|
formatters: formatters,
|
|
files: files,
|
|
verbose: verbose,
|
|
fail_fast: fail_fast,
|
|
use_runtime_info: use_runtime_info,
|
|
seed: seed.to_s,
|
|
profile:,
|
|
profile_print_slowest_examples_count:,
|
|
retry_and_log_flaky_tests:,
|
|
)
|
|
|
|
if success
|
|
exit 0
|
|
else
|
|
exit 1
|
|
end
|