# frozen_string_literal: true
require "rake/testtask"
task default: :test
task :package
desc "Run all unit tests"
task test: "test:isolated"
namespace :test do
task :isolated do
estimated_duration = {
"test/application/test_runner_test.rb" => 201,
"test/application/assets_test.rb" => 131,
"test/application/rake/migrations_test.rb" => 65,
"test/generators/scaffold_generator_test.rb" => 57,
"test/generators/plugin_test_runner_test.rb" => 57,
"test/application/test_test.rb" => 52,
"test/application/configuration_test.rb" => 49,
"test/generators/app_generator_test.rb" => 43,
"test/application/rake/dbs_test.rb" => 43,
"test/application/rake_test.rb" => 33,
"test/generators/plugin_generator_test.rb" => 30,
"test/railties/engine_test.rb" => 27,
"test/generators/scaffold_controller_generator_test.rb" => 23,
"test/railties/generators_test.rb" => 19,
"test/application/console_test.rb" => 16,
"test/engine/commands_test.rb" => 15,
"test/application/routing_test.rb" => 15,
"test/application/mailer_previews_test.rb" => 15,
"test/application/rake/multi_dbs_test.rb" => 13,
"test/application/asset_debugging_test.rb" => 12,
"test/application/bin_setup_test.rb" => 11,
"test/engine/test_test.rb" => 10,
"test/application/runner_test.rb" => 10,
}
estimated_duration.default = 1
dash_i = [
"test",
"lib",
"../activesupport/lib",
"../actionpack/lib",
"../actionview/lib",
"../activemodel/lib"
].map { |dir| File.expand_path(dir, __dir__) }
dash_i.reverse_each do |x|
$:.unshift(x) unless $:.include?(x)
end
$-w = true
require "bundler/setup" unless defined?(Bundler)
require "active_support"
# Only generate the template app once.
require_relative "test/isolation/abstract_unit"
failing_files = []
dirs = (ENV["TEST_DIR"] || ENV["TEST_DIRS"] || "**").split(",")
test_options = ENV["TESTOPTS"].to_s.split(/[\s]+/)
test_patterns = dirs.map { |dir| "test/#{dir}/*_test.rb" }
test_files = Dir[*test_patterns].select do |file|
!file.start_with?("test/fixtures/") && !file.start_with?("test/isolation/assets/")
end
if ENV["BUILDKITE_PARALLEL_JOB_COUNT"]
n = ENV["BUILDKITE_PARALLEL_JOB"].to_i
m = ENV["BUILDKITE_PARALLEL_JOB_COUNT"].to_i
buckets = Array.new(m) { [] }
allocations = Array.new(m) { 0 }
test_files.sort_by { |file| [-estimated_duration[file], file] }.each do |file|
idx = allocations.index(allocations.min)
buckets[idx] << file
allocations[idx] += estimated_duration[file]
end
puts "Running #{buckets[n].size} of #{test_files.size} test files, estimated duration #{allocations[n]}s"
test_files = buckets[n]
end
test_files.each do |file|
puts "--- #{file}"
fake_command = Shellwords.join([
FileUtils::RUBY,
"-w",
*dash_i.map { |dir| "-I#{Pathname.new(dir).relative_path_from(Pathname.pwd)}" },
file,
])
puts fake_command
# We could run these in parallel, but pretty much all of the
# railties tests already run in parallel, so ¯\_(⊙︿⊙)_/¯
Process.waitpid fork {
ARGV.clear.concat test_options
Rake.application = nil
load file
}
unless $?.success?
failing_files << file
puts "^^^ +++"
end
end
puts "--- All tests completed"
unless failing_files.empty?
puts "^^^ +++"
puts
puts "Failed in:"
failing_files.each do |file|
puts " #{file}"
end
puts
exit 1
end
end
end
Rake::TestTask.new("test:regular") do |t|
t.libs << "test" << "#{__dir__}/../activesupport/lib"
t.pattern = "test/**/*_test.rb"
t.warning = true
t.verbose = true
t.ruby_opts = ["--dev"] if defined?(JRUBY_VERSION)
end