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 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292
|
# frozen_string_literal: true
require "shellwords"
require "rake/testtask"
require_relative "test/config"
require_relative "test/support/config"
def run_without_aborting(*tasks)
errors = []
tasks.each do |task|
Rake::Task[task].invoke
rescue Exception
errors << task
end
abort "Errors running #{errors.join(', ')}" if errors.any?
end
desc "Run mysql2, trilogy, sqlite, and postgresql tests by default"
task default: :test
desc "Run mysql2, trilogy, sqlite, and postgresql tests"
task :test do
tasks = defined?(JRUBY_VERSION) ?
%w(test_jdbcmysql test_jdbcsqlite3 test_jdbcpostgresql) :
%w(test_mysql2 test_trilogy test_sqlite3 test_postgresql)
run_without_aborting(*tasks)
end
namespace :test do
task :isolated do
tasks = defined?(JRUBY_VERSION) ?
%w(isolated_test_jdbcmysql isolated_test_jdbcsqlite3 isolated_test_jdbcpostgresql) :
%w(isolated_test_mysql2 isolated_test_trilogy isolated_test_sqlite3 isolated_test_postgresql)
run_without_aborting(*tasks)
end
Rake::TestTask.new(:arel) do |t|
t.libs << "test"
t.test_files = FileList["test/cases/arel/**/*_test.rb"]
t.warning = true
t.verbose = true
end
end
namespace :db do
desc "Build MySQL and PostgreSQL test databases"
task create: ["db:mysql:build", "db:postgresql:build"]
desc "Drop MySQL and PostgreSQL test databases"
task drop: ["db:mysql:drop", "db:postgresql:drop"]
end
%w( mysql2 trilogy postgresql sqlite3 sqlite3_mem ).each do |adapter|
namespace :test do
Rake::TestTask.new(adapter => "#{adapter}:env") do |t|
adapter_short = adapter[/^[a-z0-9]+/]
t.libs << "test"
files = (FileList["test/cases/**/*_test.rb"].reject {
|x| x.include?("/adapters/") || x.include?("/encryption/performance")
} + FileList["test/cases/adapters/#{adapter_short}/**/*_test.rb"])
files = files + FileList["test/cases/adapters/abstract_mysql_adapter/**/*_test.rb"] if ["mysql2", "trilogy"].include?(adapter)
t.test_files = files
t.warning = true
t.verbose = true
t.ruby_opts = ["--dev"] if defined?(JRUBY_VERSION)
end
namespace :integration do
# Active Job Integration Tests
namespace :active_job do
Rake::TestTask.new(adapter => "#{adapter}:env") do |t|
t.libs << "test"
t.test_files = FileList["test/activejob/*_test.rb"]
t.warning = true
t.verbose = true
t.ruby_opts = ["--dev"] if defined?(JRUBY_VERSION)
end
end
end
namespace :isolated do
task adapter => "#{adapter}:env" do
adapter_short = adapter[/^[a-z0-9]+/]
puts [adapter, adapter_short].inspect
dash_i = [
"test",
"lib",
"../activesupport/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)
# Every test file loads "cases/helper" first, so doing it
# post-fork gains us nothing.
# We need to dance around minitest autorun, though.
require "minitest"
Minitest.singleton_class.class_eval do
alias_method :_original_autorun, :autorun
def autorun
# no-op
end
require "cases/helper"
alias_method :autorun, :autorun # suppress redefinition warning
alias_method :autorun, :_original_autorun
end
failing_files = []
test_options = ENV["TESTOPTS"].to_s.split(/[\s]+/)
test_files = (Dir["test/cases/**/*_test.rb"].reject {
|x| x.include?("/adapters/") || x.include?("/encryption/performance")
} + Dir["test/cases/adapters/#{adapter_short}/**/*_test.rb"]).sort
if ENV["BUILDKITE_PARALLEL_JOB_COUNT"]
n = ENV["BUILDKITE_PARALLEL_JOB"].to_i
m = ENV["BUILDKITE_PARALLEL_JOB_COUNT"].to_i
test_files = test_files.each_slice(m).filter_map { |slice| slice[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
Minitest.autorun
load file
}
unless $?.success?
failing_files << file
puts "^^^ +++"
end
puts
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
namespace :encryption do
namespace :performance do
Rake::TestTask.new(adapter => "#{adapter}:env") do |t|
t.description = "Encryption performance tests for #{adapter}"
t.libs << "test"
t.test_files = FileList["test/cases/encryption/performance/*_test.rb"]
t.warning = true
t.verbose = true
t.ruby_opts = ["--dev"] if defined?(JRUBY_VERSION)
end
end
end
end
namespace adapter do
task test: "test_#{adapter}"
task isolated_test: "isolated_test_#{adapter}"
# Set the connection environment for the adapter
task(:env) { ENV["ARCONN"] = adapter }
end
# Make sure the adapter test evaluates the env setting task
task "test_#{adapter}" => ["#{adapter}:env", "test:#{adapter}", "test:integration:active_job:#{adapter}"]
task "isolated_test_#{adapter}" => ["#{adapter}:env", "test:isolated:#{adapter}"]
end
namespace :db do
namespace :mysql do
mysql2_config = ARTest.config["connections"]["mysql2"]
mysql2_connection_arguments = lambda do |connection_name|
mysql2_connection = mysql2_config[connection_name]
["--user=#{mysql2_connection["username"]}", ("--password=#{mysql2_connection["password"]}" if mysql2_connection["password"]), ("--host=#{mysql2_connection["host"]}" if mysql2_connection["host"]), ("--socket=#{mysql2_connection["socket"]}" if mysql2_connection["socket"])].join(" ")
end
trilogy_config = ARTest.config["connections"]["trilogy"]
trilogy_connection_arguments = lambda do |connection_name|
trilogy_connection = trilogy_config[connection_name]
["--user=#{trilogy_connection["username"]}", ("--password=#{trilogy_connection["password"]}" if trilogy_connection["password"]), ("--host=#{trilogy_connection["host"]}" if trilogy_connection["host"]), ("--socket=#{trilogy_connection["socket"]}" if trilogy_connection["socket"])].join(" ")
end
mysql_configs = [mysql2_config, trilogy_config]
desc "Create the MySQL Rails User"
task :build_user do
if ENV["MYSQL_CODESPACES"]
mysql_command = "mysql -uroot -proot -e"
else
mysql_command = "mysql -uroot -e"
end
mysql_configs.each do |config|
%x( #{mysql_command} "CREATE USER IF NOT EXISTS '#{config["arunit"]["username"]}'@'%';" )
%x( #{mysql_command} "CREATE USER IF NOT EXISTS '#{config["arunit2"]["username"]}'@'%';" )
%x( #{mysql_command} "GRANT ALL PRIVILEGES ON #{config["arunit"]["database"]}.* to '#{config["arunit"]["username"]}'@'%'" )
%x( #{mysql_command} "GRANT ALL PRIVILEGES ON #{config["arunit2"]["database"]}.* to '#{config["arunit2"]["username"]}'@'%'" )
%x( #{mysql_command} "GRANT ALL PRIVILEGES ON inexistent_activerecord_unittest.* to '#{config["arunit"]["username"]}'@'%';" )
end
end
desc "Build the MySQL test databases"
task build: ["db:mysql:build_user"] do
%x( mysql #{mysql2_connection_arguments["arunit"]} -e "create DATABASE IF NOT EXISTS #{mysql2_config["arunit"]["database"]} DEFAULT CHARACTER SET utf8mb4" )
%x( mysql #{mysql2_connection_arguments["arunit2"]} -e "create DATABASE IF NOT EXISTS #{mysql2_config["arunit2"]["database"]} DEFAULT CHARACTER SET utf8mb4" )
%x( mysql #{trilogy_connection_arguments["arunit"]} -e "create DATABASE IF NOT EXISTS #{trilogy_config["arunit"]["database"]} DEFAULT CHARACTER SET utf8mb4" )
%x( mysql #{trilogy_connection_arguments["arunit2"]} -e "create DATABASE IF NOT EXISTS #{trilogy_config["arunit2"]["database"]} DEFAULT CHARACTER SET utf8mb4" )
end
desc "Drop the MySQL test databases"
task drop: ["db:mysql:build_user"] do
%x( mysql #{mysql2_connection_arguments["arunit"]} -e "drop database IF EXISTS #{mysql2_config["arunit"]["database"]}" )
%x( mysql #{mysql2_connection_arguments["arunit2"]} -e "drop database IF EXISTS #{mysql2_config["arunit2"]["database"]}" )
%x( mysql #{trilogy_connection_arguments["arunit"]} -e "drop database IF EXISTS #{trilogy_config["arunit"]["database"]}" )
%x( mysql #{trilogy_connection_arguments["arunit2"]} -e "drop database IF EXISTS #{trilogy_config["arunit2"]["database"]}" )
end
desc "Rebuild the MySQL test databases"
task rebuild: [:drop, :build]
end
namespace :postgresql do
desc "Build the PostgreSQL test databases"
task :build do
config = ARTest.config["connections"]["postgresql"]
%x( createdb -E UTF8 -T template0 #{config["arunit"]["database"]} --lc-collate en_US.UTF-8 )
%x( createdb -E UTF8 -T template0 #{config["arunit2"]["database"]} --lc-collate en_US.UTF-8 )
end
desc "Drop the PostgreSQL test databases"
task :drop do
config = ARTest.config["connections"]["postgresql"]
%x( dropdb --if-exists #{config["arunit"]["database"]} )
%x( dropdb --if-exists #{config["arunit2"]["database"]} )
end
desc "Rebuild the PostgreSQL test databases"
task rebuild: [:drop, :build]
end
end
task build_mysql_databases: "db:mysql:build"
task drop_mysql_databases: "db:mysql:drop"
task rebuild_mysql_databases: "db:mysql:rebuild"
task build_postgresql_databases: "db:postgresql:build"
task drop_postgresql_databases: "db:postgresql:drop"
task rebuild_postgresql_databases: "db:postgresql:rebuild"
task :lines do
load File.expand_path("../tools/line_statistics", __dir__)
files = FileList["lib/active_record/**/*.rb"]
CodeTools::LineStatistics.new(files).print_loc
end
|