1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
# 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
|