From 42afe2961c79398efcd391ebdba78e66110b81dc Mon Sep 17 00:00:00 2001 From: Sebastien Savater Date: Tue, 19 Sep 2023 15:54:12 +0200 Subject: [PATCH 1/4] Support parallel_tests options --- README.md | 6 ++++++ lib/turbo_tests/cli.rb | 8 ++++++-- lib/turbo_tests/runner.rb | 21 ++++++++------------- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index f5a285a..c850cb2 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,12 @@ Options: --seed SEED Seed for rspec ``` +To pass any options supported by paralell_tests, use `--` : + +```bash +bundle exec turbo_tests -n 4 -- --only-group 1 --pattern spec/system +``` + ## Development After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. diff --git a/lib/turbo_tests/cli.rb b/lib/turbo_tests/cli.rb index 6f033cc..d914060 100644 --- a/lib/turbo_tests/cli.rb +++ b/lib/turbo_tests/cli.rb @@ -98,15 +98,19 @@ def run end end + parallel_options = ParallelTests::CLI.new.send(:parse_options!, @argv.unshift("--type", "rspec")) + files = parallel_options.fetch(:files, ["spec"]) + exitstatus = TurboTests::Runner.run( formatters: formatters, tags: tags, - files: @argv.empty? ? ["spec"] : @argv, + files: files, runtime_log: runtime_log, verbose: verbose, fail_fast: fail_fast, count: count, - seed: seed + seed: seed, + parallel_options: parallel_options ) # From https://github.com/serpapi/turbo_tests/pull/20/ diff --git a/lib/turbo_tests/runner.rb b/lib/turbo_tests/runner.rb index 026d593..4475fbe 100644 --- a/lib/turbo_tests/runner.rb +++ b/lib/turbo_tests/runner.rb @@ -13,6 +13,7 @@ def self.run(opts = {}) files = opts[:files] formatters = opts[:formatters] tags = opts[:tags] + parallel_options = opts[:parallel_options] start_time = opts.fetch(:start_time) { RSpec::Core::Time.now } runtime_log = opts.fetch(:runtime_log, nil) @@ -38,6 +39,7 @@ def self.run(opts = {}) count: count, seed: seed, seed_used: seed_used, + parallel_options: parallel_options ).run end @@ -45,7 +47,6 @@ def initialize(opts) @reporter = opts[:reporter] @files = opts[:files] @tags = opts[:tags] - @runtime_log = opts[:runtime_log] || "tmp/turbo_rspec_runtime.log" @verbose = opts[:verbose] @fail_fast = opts[:fail_fast] @count = opts[:count] @@ -56,6 +57,10 @@ def initialize(opts) @load_count = 0 @failure_count = 0 + @runtime_log = opts[:runtime_log] || "tmp/turbo_rspec_runtime.log" + @parallel_options = opts.fetch(:parallel_options, {}) + @parallel_options[:runtime_log] = @runtime_log + @messages = Thread::Queue.new @threads = [] @error = false @@ -67,25 +72,15 @@ def run ParallelTests::RSpec::Runner.tests_with_size(@files, {}).size ].min - use_runtime_info = @files == ["spec"] - - group_opts = {} - - if use_runtime_info - group_opts[:runtime_log] = @runtime_log - else - group_opts[:group_by] = :filesize - end - tests_in_groups = ParallelTests::RSpec::Runner.tests_in_groups( @files, @num_processes, - **group_opts + @parallel_options ) subprocess_opts = { - record_runtime: use_runtime_info, + record_runtime: @parallel_options[:group_by] == :runtime } @reporter.report(tests_in_groups) do |reporter| From 789b7c9c951bc2894de36cb922ac04fa627e2327 Mon Sep 17 00:00:00 2001 From: Sebastien Savater Date: Thu, 11 Apr 2024 15:11:57 +0200 Subject: [PATCH 2/4] Refactor Runner & Reporter to forward arguments to `initialize` methods --- lib/turbo_tests/reporter.rb | 4 ++-- lib/turbo_tests/runner.rb | 28 ++++++++-------------------- 2 files changed, 10 insertions(+), 22 deletions(-) diff --git a/lib/turbo_tests/reporter.rb b/lib/turbo_tests/reporter.rb index 417f06a..e0dbb63 100644 --- a/lib/turbo_tests/reporter.rb +++ b/lib/turbo_tests/reporter.rb @@ -4,8 +4,8 @@ module TurboTests class Reporter attr_writer :load_time - def self.from_config(formatter_config, start_time, seed, seed_used) - reporter = new(start_time, seed, seed_used) + def self.from_config(formatter_config, *args) + reporter = new(*args) formatter_config.each do |config| name, outputs = config.values_at(:name, :outputs) diff --git a/lib/turbo_tests/runner.rb b/lib/turbo_tests/runner.rb index 4475fbe..7824f90 100644 --- a/lib/turbo_tests/runner.rb +++ b/lib/turbo_tests/runner.rb @@ -10,16 +10,8 @@ class Runner using CoreExtensions def self.run(opts = {}) - files = opts[:files] - formatters = opts[:formatters] - tags = opts[:tags] - parallel_options = opts[:parallel_options] - start_time = opts.fetch(:start_time) { RSpec::Core::Time.now } - runtime_log = opts.fetch(:runtime_log, nil) verbose = opts.fetch(:verbose, false) - fail_fast = opts.fetch(:fail_fast, nil) - count = opts.fetch(:count, nil) seed = opts.fetch(:seed) seed_used = !seed.nil? @@ -27,28 +19,22 @@ def self.run(opts = {}) warn "VERBOSE" end - reporter = Reporter.from_config(formatters, start_time, seed, seed_used) - new( - reporter: reporter, - files: files, - tags: tags, - runtime_log: runtime_log, + **opts, + start_time: start_time, verbose: verbose, - fail_fast: fail_fast, - count: count, seed: seed, - seed_used: seed_used, - parallel_options: parallel_options + seed_used: seed_used ).run end - def initialize(opts) - @reporter = opts[:reporter] + def initialize(**opts) + @formatters = opts[:formatters] @files = opts[:files] @tags = opts[:tags] @verbose = opts[:verbose] @fail_fast = opts[:fail_fast] + @start_time = opts[:start_time] @count = opts[:count] @seed = opts[:seed] @seed_used = opts[:seed_used] @@ -67,6 +53,8 @@ def initialize(opts) end def run + @reporter = Reporter.from_config(@formatters, @start_time, @seed, @seed_used) + @num_processes = [ ParallelTests.determine_number_of_processes(@count), ParallelTests::RSpec::Runner.tests_with_size(@files, {}).size From 5581fe9df8505144a369c04fdd2811c5e17eaa5a Mon Sep 17 00:00:00 2001 From: Sebastien Savater Date: Thu, 11 Apr 2024 15:13:38 +0200 Subject: [PATCH 3/4] Calculate examples count when Reporter starts --- lib/turbo_tests/reporter.rb | 19 +++++++++++++++++-- lib/turbo_tests/runner.rb | 2 +- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/lib/turbo_tests/reporter.rb b/lib/turbo_tests/reporter.rb index e0dbb63..364dae6 100644 --- a/lib/turbo_tests/reporter.rb +++ b/lib/turbo_tests/reporter.rb @@ -23,7 +23,7 @@ def self.from_config(formatter_config, *args) attr_reader :pending_examples attr_reader :failed_examples - def initialize(start_time, seed, seed_used) + def initialize(start_time, seed, seed_used, files, parallel_options) @formatters = [] @pending_examples = [] @failed_examples = [] @@ -34,6 +34,9 @@ def initialize(start_time, seed, seed_used) @seed_used = seed_used @load_time = 0 @errors_outside_of_examples_count = 0 + @files = files + @parallel_options = parallel_options + @custom_formatters = false end def add(name, outputs) @@ -45,6 +48,7 @@ def add(name, outputs) when "d", "documentation" RSpec::Core::Formatters::DocumentationFormatter else + @custom_formatters = true Kernel.const_get(name) end @@ -70,8 +74,10 @@ def start(example_groups, time=RSpec::Core::Time.now) report_number_of_tests(example_groups) expected_example_count = example_groups.flatten(1).count + examples_count = self.examples_count if @custom_formatters + delegate_to_formatters(:seed, RSpec::Core::Notifications::SeedNotification.new(@seed, @seed_used)) - delegate_to_formatters(:start, RSpec::Core::Notifications::StartNotification.new(expected_example_count, @load_time)) + delegate_to_formatters(:start, RSpec::Core::Notifications::StartNotification.new(examples_count, @load_time)) end def report_number_of_tests(groups) @@ -84,6 +90,15 @@ def report_number_of_tests(groups) puts "#{num_processes} processes for #{num_tests} #{name}s, ~ #{tests_per_process} #{name}s per process" end + def examples_count + files = ParallelTests::RSpec::Runner.send(:find_tests, @files, @parallel_options) + output_file = Tempfile.new("rspec-summary") + `#{ENV.fetch("BUNDLE_BIN_PATH")} exec rspec --dry-run --format json --out='#{output_file.path}' #{files.join(" ")}` + + json_summary = JSON.parse(output_file.read, symbolize_names: true) + json_summary.dig(:summary, :example_count) || 0 + end + def group_started(notification) delegate_to_formatters(:example_group_started, notification) end diff --git a/lib/turbo_tests/runner.rb b/lib/turbo_tests/runner.rb index 7824f90..e28ecb6 100644 --- a/lib/turbo_tests/runner.rb +++ b/lib/turbo_tests/runner.rb @@ -53,7 +53,7 @@ def initialize(**opts) end def run - @reporter = Reporter.from_config(@formatters, @start_time, @seed, @seed_used) + @reporter = Reporter.from_config(@formatters, @start_time, @seed, @seed_used, @files, @parallel_options) @num_processes = [ ParallelTests.determine_number_of_processes(@count), From 21cb9e643edbcf5c72ef211c6388f16bcf77b9ea Mon Sep 17 00:00:00 2001 From: Sebastien Savater Date: Wed, 17 Apr 2024 09:16:47 +0200 Subject: [PATCH 4/4] Add custom formatters to README --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c850cb2..a82b1e7 100644 --- a/README.md +++ b/README.md @@ -99,12 +99,18 @@ Options: --seed SEED Seed for rspec ``` -To pass any options supported by paralell_tests, use `--` : +To pass any options supported by paralell_tests, use `--`: ```bash bundle exec turbo_tests -n 4 -- --only-group 1 --pattern spec/system ``` +`turbo_tests` supports custom formatter such as Fuubar, but you might need to require it: + +```bash +bundle exec turbo_tests -r fuubar -f Fuubar spec/whatever +``` + ## Development After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.