aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/Rakefile
blob: f259ae7e12bc3a1937b476597d6d84a0efea908a (plain) (blame)
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
# frozen_string_literal: true

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, sqlite, and postgresql tests by default"
task default: :test

task :package

desc "Run mysql2, sqlite, and postgresql tests"
task :test do
  tasks = defined?(JRUBY_VERSION) ?
    %w(test_jdbcmysql test_jdbcsqlite3 test_jdbcpostgresql) :
    %w(test_mysql2 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_sqlite3 isolated_test_postgresql)
    run_without_aborting(*tasks)
  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 postgresql sqlite3 sqlite3_mem db2 oracle jdbcmysql jdbcpostgresql jdbcsqlite3 jdbcderby jdbch2 jdbchsqldb ).each do |adapter|
  namespace :test do
    Rake::TestTask.new(adapter => "#{adapter}:env") { |t|
      adapter_short = adapter == "db2" ? adapter : adapter[/^[a-z0-9]+/]
      t.libs << "test"
      t.test_files = (Dir.glob("test/cases/**/*_test.rb").reject {
        |x| x.include?("/adapters/")
      } + Dir.glob("test/cases/adapters/#{adapter_short}/**/*_test.rb"))

      t.warning = true
      t.verbose = true
      t.ruby_opts = ["--dev"] if defined?(JRUBY_VERSION)
    }

    namespace :isolated do
      task adapter => "#{adapter}:env" do
        adapter_short = adapter == "db2" ? adapter : 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.instance_eval do
          alias _original_autorun autorun
          def autorun
            # no-op
          end
          require "cases/helper"
          alias 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/")
        } + 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).map { |slice| slice[n] }.compact
        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
  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}"]
  task "isolated_test_#{adapter}" => ["#{adapter}:env", "test:isolated:#{adapter}"]
end

namespace :db do
  namespace :mysql do
    connection_arguments = lambda do |connection_name|
      config = ARTest.config["connections"]["mysql2"][connection_name]
      ["--user=#{config["username"]}", "--password=#{config["password"]}", ("--host=#{config["host"]}" if config["host"])].join(" ")
    end

    desc "Build the MySQL test databases"
    task :build do
      config = ARTest.config["connections"]["mysql2"]
      %x( mysql #{connection_arguments["arunit"]} -e "create DATABASE #{config["arunit"]["database"]} DEFAULT CHARACTER SET utf8mb4" )
      %x( mysql #{connection_arguments["arunit2"]} -e "create DATABASE #{config["arunit2"]["database"]} DEFAULT CHARACTER SET utf8mb4" )
    end

    desc "Drop the MySQL test databases"
    task :drop do
      config = ARTest.config["connections"]["mysql2"]
      %x( mysqladmin #{connection_arguments["arunit"]} -f drop #{config["arunit"]["database"]} )
      %x( mysqladmin #{connection_arguments["arunit2"]} -f drop #{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"]} )
      %x( createdb -E UTF8 -T template0 #{config["arunit2"]["database"]} )
    end

    desc "Drop the PostgreSQL test databases"
    task :drop do
      config = ARTest.config["connections"]["postgresql"]
      %x( dropdb #{config["arunit"]["database"]} )
      %x( dropdb #{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