Skip to content

Commit f776f62

Browse files
Add support for multiple DBs in Rails >= 6.1 (grosser#930)
* Add support for multiple DBs in Rails >= 6.1 * changelog entry * rubocop * Return nil to represent 'all' databases * No core extensions * ActiveRecord check in for_each_database * don't return too early now
1 parent 8129c4c commit f776f62

File tree

3 files changed

+108
-33
lines changed

3 files changed

+108
-33
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
### Breaking Changes
66

77
### Added
8+
- Support for running tasks against individual databases in a multi-database setup with Rails >= 6.1 ([#930](https://github.com/grosser/parallel_tests/pull/930))
89

910
## 4.4.0 - 2023-12-24
1011

Readme.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,28 @@ test:
3333
### Create additional database(s)
3434
rake parallel:create
3535
36+
### (Multi-DB) Create individual database
37+
rake parallel:create:<database>
38+
rake parallel:create:secondary
39+
3640
### Copy development schema (repeat after migrations)
3741
rake parallel:prepare
3842
3943
### Run migrations in additional database(s) (repeat after migrations)
4044
rake parallel:migrate
4145
46+
### (Multi-DB) Run migrations in individual database
47+
rake parallel:migrate:<database>
48+
4249
### Setup environment from scratch (create db and loads schema, useful for CI)
4350
rake parallel:setup
4451
4552
### Drop all test databases
4653
rake parallel:drop
4754
55+
### (Multi-DB) Drop individual test database
56+
rake parallel:drop:<database>
57+
4858
### Run!
4959
rake parallel:test # Minitest
5060
rake parallel:spec # RSpec

lib/parallel_tests/tasks.rb

Lines changed: 97 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ def suppress_output(command, ignore_regex)
4848
activate_pipefail = "set -o pipefail"
4949
remove_ignored_lines = %{(grep -v #{Shellwords.escape(ignore_regex)} || true)}
5050

51+
# remove nil values (ex: #purge_before_load returns nil)
52+
command.compact!
53+
5154
if system('/bin/bash', '-c', "#{activate_pipefail} 2>/dev/null")
5255
shell_command = "#{activate_pipefail} && (#{Shellwords.shelljoin(command)}) | #{remove_ignored_lines}"
5356
['/bin/bash', '-c', shell_command]
@@ -125,6 +128,23 @@ def build_run_command(type, args)
125128
command
126129
end
127130

131+
def configured_databases
132+
return [] unless defined?(ActiveRecord) && rails_61_or_greater?
133+
134+
@@configured_databases ||= ActiveRecord::Tasks::DatabaseTasks.setup_initial_database_yaml
135+
end
136+
137+
def for_each_database(&block)
138+
# Use nil to represent all databases
139+
block&.call(nil)
140+
141+
return unless defined?(ActiveRecord)
142+
143+
ActiveRecord::Tasks::DatabaseTasks.for_each(configured_databases) do |name|
144+
block&.call(name)
145+
end
146+
end
147+
128148
private
129149

130150
def rails_7_or_greater?
@@ -145,25 +165,45 @@ def rails_61_or_greater?
145165
ParallelTests::Tasks.run_in_parallel(ParallelTests::Tasks.suppress_schema_load_output(command), args)
146166
end
147167

148-
desc "Create test databases via db:create --> parallel:create[num_cpus]"
149-
task :create, :count do |_, args|
150-
ParallelTests::Tasks.run_in_parallel(
151-
[$0, "db:create", "RAILS_ENV=#{ParallelTests::Tasks.rails_env}"],
152-
args
153-
)
168+
ParallelTests::Tasks.for_each_database do |name|
169+
task_name = 'create'
170+
task_name += ":#{name}" if name
171+
description = if name
172+
"Create test #{name} database via db:#{task_name} --> parallel:#{task_name}[num_cpus]"
173+
else
174+
"Create test databases via db:#{task_name} --> parallel:#{task_name}[num_cpus]"
175+
end
176+
177+
desc description
178+
task task_name.to_sym, :count do |_, args|
179+
ParallelTests::Tasks.run_in_parallel(
180+
[$0, "db:#{task_name}", "RAILS_ENV=#{ParallelTests::Tasks.rails_env}"],
181+
args
182+
)
183+
end
154184
end
155185

156-
desc "Drop test databases via db:drop --> parallel:drop[num_cpus]"
157-
task :drop, :count do |_, args|
158-
ParallelTests::Tasks.run_in_parallel(
159-
[
160-
$0,
161-
"db:drop",
162-
"RAILS_ENV=#{ParallelTests::Tasks.rails_env}",
163-
"DISABLE_DATABASE_ENVIRONMENT_CHECK=1"
164-
],
165-
args
166-
)
186+
ParallelTests::Tasks.for_each_database do |name|
187+
task_name = 'drop'
188+
task_name += ":#{name}" if name
189+
description = if name
190+
"Drop test #{name} database via db:#{task_name} --> parallel:#{task_name}[num_cpus]"
191+
else
192+
"Drop test databases via db:#{task_name} --> parallel:#{task_name}[num_cpus]"
193+
end
194+
195+
desc description
196+
task task_name.to_sym, :count do |_, args|
197+
ParallelTests::Tasks.run_in_parallel(
198+
[
199+
$0,
200+
"db:#{task_name}",
201+
"RAILS_ENV=#{ParallelTests::Tasks.rails_env}",
202+
"DISABLE_DATABASE_ENVIRONMENT_CHECK=1"
203+
],
204+
args
205+
)
206+
end
167207
end
168208

169209
desc "Update test databases by dumping and loading --> parallel:prepare[num_cpus]"
@@ -190,12 +230,22 @@ def rails_61_or_greater?
190230
end
191231

192232
# when dumping/resetting takes too long
193-
desc "Update test databases via db:migrate --> parallel:migrate[num_cpus]"
194-
task :migrate, :count do |_, args|
195-
ParallelTests::Tasks.run_in_parallel(
196-
[$0, "db:migrate", "RAILS_ENV=#{ParallelTests::Tasks.rails_env}"],
197-
args
198-
)
233+
ParallelTests::Tasks.for_each_database do |name|
234+
task_name = 'migrate'
235+
task_name += ":#{name}" if name
236+
description = if name
237+
"Update test #{name} database via db:#{task_name} --> parallel:#{task_name}[num_cpus]"
238+
else
239+
"Update test databases via db:#{task_name} --> parallel:#{task_name}[num_cpus]"
240+
end
241+
242+
desc description
243+
task task_name.to_sym, :count do |_, args|
244+
ParallelTests::Tasks.run_in_parallel(
245+
[$0, "db:#{task_name}", "RAILS_ENV=#{ParallelTests::Tasks.rails_env}"],
246+
args
247+
)
248+
end
199249
end
200250

201251
desc "Rollback test databases via db:rollback --> parallel:rollback[num_cpus]"
@@ -207,16 +257,30 @@ def rails_61_or_greater?
207257
end
208258

209259
# just load the schema (good for integration server <-> no development db)
210-
desc "Load dumped schema for test databases via db:schema:load --> parallel:load_schema[num_cpus]"
211-
task :load_schema, :count do |_, args|
212-
command = [
213-
$0,
214-
ParallelTests::Tasks.purge_before_load,
215-
"db:schema:load",
216-
"RAILS_ENV=#{ParallelTests::Tasks.rails_env}",
217-
"DISABLE_DATABASE_ENVIRONMENT_CHECK=1"
218-
]
219-
ParallelTests::Tasks.run_in_parallel(ParallelTests::Tasks.suppress_schema_load_output(command), args)
260+
ParallelTests::Tasks.for_each_database do |name|
261+
rails_task = 'db:schema:load'
262+
rails_task += ":#{name}" if name
263+
264+
task_name = 'load_schema'
265+
task_name += ":#{name}" if name
266+
267+
description = if name
268+
"Load dumped schema for test #{name} database via #{rails_task} --> parallel:#{task_name}[num_cpus]"
269+
else
270+
"Load dumped schema for test databases via #{rails_task} --> parallel:#{task_name}[num_cpus]"
271+
end
272+
273+
desc description
274+
task task_name.to_sym, :count do |_, args|
275+
command = [
276+
$0,
277+
ParallelTests::Tasks.purge_before_load,
278+
rails_task,
279+
"RAILS_ENV=#{ParallelTests::Tasks.rails_env}",
280+
"DISABLE_DATABASE_ENVIRONMENT_CHECK=1"
281+
]
282+
ParallelTests::Tasks.run_in_parallel(ParallelTests::Tasks.suppress_schema_load_output(command), args)
283+
end
220284
end
221285

222286
# load the structure from the structure.sql file

0 commit comments

Comments
 (0)