aboutsummaryrefslogblamecommitdiffstats
path: root/railties/Rakefile
blob: 51f46d18176c369024618672368a516025588f90 (plain) (tree)
1
2
3
4
5
6
7
8
9

                             
                       
 
                   
 
             
 
                         
                          
 

                   


























                                                                    
















                                                    


                                                   

                      
                                                                   

                                                      

                                                              
                                                                                        
       
 



                                                  










                                                                                                               



                             







                                                                                        











                                                                        

                        
                             
                      
         
       
 
                                  
                               
                    






                                  
            
       
     

   
                                         
                                                       
                                 
                  
                  
                                                    
   
# 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

      if Process.respond_to?(:fork)
        # 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
        }
      else
        Process.wait spawn(fake_command)
      end

      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