From 6e1b83603c553cb8525d01f226e19ae40612e0fa Mon Sep 17 00:00:00 2001 From: Agis Anastasopoulos Date: Sun, 20 Sep 2020 23:50:07 +0300 Subject: [PATCH] Split spec files programmatically Instead of shelling out to rspec, we now split spec files into individual examples programmatically, using the RSpec Core API. This is arguably faster and more robust. Closes #6 --- lib/rspecq/worker.rb | 37 ++++++++++++++----------------------- test/test_scheduling.rb | 2 +- test/test_worker.rb | 4 ++-- 3 files changed, 17 insertions(+), 26 deletions(-) diff --git a/lib/rspecq/worker.rb b/lib/rspecq/worker.rb index a999698..10e7437 100644 --- a/lib/rspecq/worker.rb +++ b/lib/rspecq/worker.rb @@ -168,33 +168,24 @@ def try_publish_queue!(queue) # falling back to scheduling them as whole files. Their errors will be # reported in the normal flow when they're eventually picked up by a worker. def files_to_example_ids(files) - cmd = "DISABLE_SPRING=1 bundle exec rspec --dry-run --format json #{files.join(' ')} 2>&1" - out = `#{cmd}` - cmd_result = $? + out = StringIO.new - if !cmd_result.success? - rspec_output = begin - JSON.parse(out) - rescue JSON::ParserError - out - end + reset_rspec_state! - log_event( - "Failed to split slow files, falling back to regular scheduling", - "error", - rspec_output: rspec_output, - cmd_result: cmd_result.inspect, - ) - - pp rspec_output - - return files - end - - JSON.parse(out)["examples"].map { |e| e["id"] } + RSpec.configuration.add_formatter(RSpec::Core::Formatters::JsonFormatter.new(out)) + RSpec.configuration.files_or_directories_to_run = files_or_dirs_to_run + RSpec.configuration.dry_run = true + + opts = RSpec::Core::ConfigurationOptions.new(files) + result = RSpec::Core::Runner.new(opts).run($stderr, $stdout) + return files if result != 0 + JSON.parse(out.string)["examples"].map { |e| e["id"] } + ensure + RSpec.configuration.dry_run = false + # clear formatters + reset_rspec_state! end - private def reset_rspec_state! diff --git a/test/test_scheduling.rb b/test/test_scheduling.rb index 0a2f0ed..1b33609 100644 --- a/test/test_scheduling.rb +++ b/test/test_scheduling.rb @@ -47,7 +47,7 @@ def test_scheduling_with_timings_and_splitting worker = new_worker("scheduling") worker.populate_timings = true worker.file_split_threshold = 0.2 - silent { worker.try_publish_queue!(worker.queue) } + worker.try_publish_queue!(worker.queue) assert_equal [ "./test/sample_suites/scheduling/spec/foo_spec.rb[1:2:1]", diff --git a/test/test_worker.rb b/test/test_worker.rb index 146fc82..b9884b8 100644 --- a/test/test_worker.rb +++ b/test/test_worker.rb @@ -18,7 +18,7 @@ def test_files_to_example_ids ] ) - assert_equal expected, actual + assert_equal expected.sort, actual.sort end def test_files_to_example_ids_failure_fallback @@ -36,6 +36,6 @@ def test_files_to_example_ids_failure_fallback ] ) - assert_equal expected, actual + assert_equal expected.sort, actual.sort end end