rspec-multicore-rails 0.2.0.pre1 → 0.2.0.pre2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d79cf584351309d480685d78f5a6d75a6883f1dbc7567f0711723eb631222dd3
4
- data.tar.gz: 43a198971e8fef686be3f859658f10c3038bc897053fc0252782dc2d71c46736
3
+ metadata.gz: cab0db5c29ef823bd0106eae9fe429e50ff913d399735be5eaa3b1ed0ae766f0
4
+ data.tar.gz: a889a51713b6715cdd19f0793025b0c1a74997f20666458760d8a0e33e275d45
5
5
  SHA512:
6
- metadata.gz: ece0c46dc96d6fc0d716512a7db10b96bad1216dd8f8b1cc47aadb6e5ab0a48756efd244ce1491dca91d55e91cf3d54ce4866f917c9c7b9e0c4716f186c2ff8f
7
- data.tar.gz: b01482a80460f2e5b5e3532fc210ee6c5c3c5d0e16311403934a33d1067747484f09239b92efb920da9c8585c849051e7b4eb6ce5d149613e3c314c52782cb86
6
+ metadata.gz: 693239e0fa3955ffad52dea7a694a4ef12d2a63b5ceba3863f5550eed736719cc2c2fe99b4b00564e9c78ef4656e1694feb73ca6207eff7b0a4d9e48bcdfb9dc
7
+ data.tar.gz: 6452f0e220cf4f0911112ecc248910f001a067611cb4ba7aa30ce5983c05891e621be1e406e0eafc6efcbe078e517c05eee523644034cf686dce3e7783610e4f
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.0.pre2
4
+
5
+ - Uses Rails' standard database tasks to manage worker test databases and
6
+ removes the prerelease custom task namespace.
7
+ - Supports multiple writable test configurations while leaving replicas and
8
+ `database_tasks: false` configurations unmanaged.
9
+ - Improves release validation and retry safety.
10
+
3
11
  ## 0.2.0.pre1
4
12
 
5
13
  - Uses the core worker count as the single concurrency source.
data/README.md CHANGED
@@ -2,14 +2,24 @@
2
2
 
3
3
  `rspec-multicore-rails` loads `rspec-multicore` and automatically isolates ActiveRecord connections for Rails test workers.
4
4
 
5
- Worker 1 uses the base test database. Later workers use `_2`, `_3`, and so on; SQLite suffixes are placed before the extension. The adapter refuses non-test environments and clears inherited connections before connecting.
5
+ Worker 1 uses the base test database. Later workers use `_2`, `_3`, and so on;
6
+ SQLite suffixes are placed before the extension. The adapter refuses to connect
7
+ workers outside test and clears inherited connections before connecting.
8
+
9
+ Use Rails' standard database tasks to manage the base and worker databases:
6
10
 
7
11
  ```bash
8
- bundle exec rake db:test:multicore:prepare
9
- bundle exec rake db:test:multicore:drop
10
- bundle exec rake db:test:multicore:recreate
12
+ bin/rails db:prepare
13
+ bin/rails db:test:prepare
14
+ bin/rails db:reset
11
15
  ```
12
16
 
17
+ Create, schema-load, prepare, purge, and drop operations extend to the extra
18
+ worker databases whenever the Rails task includes test. Multiple writable test
19
+ configurations are supported; replicas and configurations with
20
+ `database_tasks: false` are not managed. No worker entries are needed in
21
+ `database.yml`, and running RSpec never mutates the database lifecycle.
22
+
13
23
  The adapter does not manage Redis, Sidekiq, caches, loggers, SimpleCov, or profilers. Configure those with `RSpec::Multicore.on_worker_fork` and `on_worker_shutdown`.
14
24
 
15
25
  Requires Ruby 3.2+, Rails/ActiveRecord 7.1–8.x, and exactly the matching `rspec-multicore` version.
@@ -6,71 +6,102 @@ require "active_record/tasks/database_tasks"
6
6
  module RSpec
7
7
  module Multicore
8
8
  module Rails
9
- # Names, prepares, and connects worker-owned ActiveRecord databases.
9
+ # Manages and connects worker-owned ActiveRecord test databases.
10
10
  class DatabaseManager
11
+ TEST_ENV = "test"
12
+
11
13
  def initialize
12
- ensure_test_environment!
13
- @base_config = ActiveRecord::Base.connection_db_config
14
+ @primary_config = ActiveRecord::Base.connection_db_config
15
+ @configs = test_configs
16
+ @configs << @primary_config unless @configs.include?(@primary_config)
17
+ @base_databases = {}.compare_by_identity
18
+ @configs.each { @base_databases[_1] = _1.database }
14
19
  end
15
20
 
16
21
  def connect_worker(slot)
22
+ ensure_test_environment!
17
23
  ActiveRecord::Base.connection_handler.clear_all_connections!
18
- ActiveRecord::Base.establish_connection(config_for(slot))
24
+ @configs.each { _1._database = database_for(slot, _1) }
25
+ ActiveRecord::Base.establish_connection(@primary_config)
26
+ end
27
+
28
+ def create_workers(name: nil) = each_worker_config(name:) { database_tasks.create(_1) }
29
+
30
+ def purge_workers(name: nil)
31
+ each_worker_config(name:) do |config|
32
+ database_tasks.purge(config)
33
+ rescue ActiveRecord::NoDatabaseError
34
+ database_tasks.create(config)
35
+ end
19
36
  end
20
37
 
21
- def prepare_all
22
- worker_slots.each do |slot|
23
- purge(slot)
24
- ActiveRecord::Tasks::DatabaseTasks.load_schema(hash_config_for(slot))
38
+ def load_schema_workers(name: nil)
39
+ each_worker_config(name:) do |config|
40
+ database_tasks.load_schema(config, schema_format(config))
25
41
  end
26
42
  end
27
43
 
28
- def drop_workers = worker_slots.drop(1).each { drop(_1) }
44
+ def prepare_workers(name: nil)
45
+ purge_workers(name:)
46
+ load_schema_workers(name:)
47
+ end
48
+
49
+ def drop_workers(name: nil) = each_worker_config(name:) { database_tasks.drop(_1) }
29
50
 
30
51
  def workers = RSpec::Multicore.workers
31
- def database_for(slot) = slot == 1 ? base_database : suffixed_database(slot)
52
+
53
+ def database_for(slot, config = @primary_config)
54
+ return base_database(config) if slot == 1
55
+
56
+ database = base_database(config)
57
+ return "#{database}_#{slot}" unless config.adapter == "sqlite3"
58
+
59
+ extension = File.extname(database)
60
+ "#{database.delete_suffix(extension)}_#{slot}#{extension}"
61
+ end
32
62
 
33
63
  private
34
64
 
35
- def worker_slots = (1..workers)
36
- def base_database = @base_config.database
65
+ def test_configs
66
+ configurations = ActiveRecord::Base.configurations
67
+ Array(configurations.configs_for(env_name: TEST_ENV, include_hidden: true))
68
+ end
37
69
 
38
- def suffixed_database(slot)
39
- if sqlite?
40
- extension = File.extname(base_database)
41
- return "#{base_database.delete_suffix(extension)}_#{slot}#{extension}"
70
+ def task_configs(name: nil)
71
+ @configs.select do |config|
72
+ config.env_name == TEST_ENV && config.database_tasks? && (!name || config.name == name)
42
73
  end
43
-
44
- "#{base_database}_#{slot}"
45
74
  end
46
75
 
47
- def sqlite? = @base_config.adapter == "sqlite3"
76
+ def each_worker_config(name:)
77
+ return enum_for(__method__, name:) unless block_given?
48
78
 
49
- def config_for(slot) = @base_config.configuration_hash.merge(database: database_for(slot))
79
+ task_configs(name:).each do |config|
80
+ 2.upto(workers) { yield derived_config(config, _1) }
81
+ end
82
+ end
50
83
 
51
- def hash_config_for(slot)
84
+ def derived_config(config, slot)
52
85
  ActiveRecord::DatabaseConfigurations::HashConfig.new(
53
- @base_config.env_name,
54
- @base_config.name,
55
- config_for(slot)
86
+ config.env_name,
87
+ config.name,
88
+ config.configuration_hash.merge(database: database_for(slot, config))
56
89
  )
57
90
  end
58
91
 
59
- def purge(slot)
60
- drop(slot)
61
- ActiveRecord::Tasks::DatabaseTasks.create(config_for(slot))
62
- end
92
+ def base_database(config) = @base_databases.fetch(config)
93
+ def database_tasks = ActiveRecord::Tasks::DatabaseTasks
94
+
95
+ def schema_format(config)
96
+ return config.schema_format if config.respond_to?(:schema_format)
63
97
 
64
- def drop(slot)
65
- ActiveRecord::Tasks::DatabaseTasks.drop(config_for(slot))
66
- rescue ActiveRecord::NoDatabaseError
67
- nil
98
+ config.configuration_hash.fetch(:schema_format, ActiveRecord.schema_format)
68
99
  end
69
100
 
70
101
  def ensure_test_environment!
71
102
  return if ::Rails.env.test?
72
103
 
73
- raise RSpec::Multicore::Error, "Parallel databases can only be managed in the Rails test environment"
104
+ raise RSpec::Multicore::Error, "Parallel databases can only be connected in the Rails test environment"
74
105
  end
75
106
  end
76
107
  end
@@ -3,7 +3,7 @@
3
3
  module RSpec
4
4
  module Multicore
5
5
  module Rails
6
- VERSION = "0.2.0.pre1"
6
+ VERSION = "0.2.0.pre2"
7
7
  end
8
8
  end
9
9
  end
@@ -2,27 +2,46 @@
2
2
 
3
3
  require "rspec/multicore/rails"
4
4
 
5
- namespace :db do
6
- namespace :test do
7
- namespace :multicore do
8
- desc "Prepare all parallel test databases (create and load schema)"
9
- task prepare: :environment do
10
- manager = RSpec::Multicore::Rails::DatabaseManager.new
11
- puts "Preparing parallel test databases..."
12
- manager.prepare_all
13
- puts "Parallel test databases ready (#{manager.workers} workers)"
14
- end
5
+ manager = -> { RSpec::Multicore::Rails::DatabaseManager.new }
6
+ test_in_scope = lambda do
7
+ Rails.env.test? || (Rails.env.development? && !ENV["DATABASE_URL"] && !ENV["SKIP_TEST_DATABASE"])
8
+ end
9
+ allowed = lambda do |scope|
10
+ scope == :all || (scope == :test ? Rails.env.test? : test_in_scope.call)
11
+ end
12
+
13
+ enhance = lambda do |task_name, operation, name: nil, scope: :current|
14
+ next unless Rake::Task.task_defined?(task_name)
15
+
16
+ Rake::Task[task_name].enhance do
17
+ next unless allowed.call(scope)
18
+
19
+ manager.call.public_send(operation, name:)
20
+ end
21
+ end
15
22
 
16
- desc "Drop all parallel test databases (except base test database)"
17
- task drop: :environment do
18
- manager = RSpec::Multicore::Rails::DatabaseManager.new
19
- puts "Dropping parallel test databases..."
20
- manager.drop_workers
21
- puts "Parallel test databases dropped"
22
- end
23
+ enhance.call("db:create", :create_workers)
24
+ enhance.call("db:create:all", :create_workers, scope: :all)
25
+ enhance.call("db:prepare", :prepare_workers)
26
+ enhance.call("db:schema:load", :load_schema_workers)
27
+ enhance.call("db:test:purge", :purge_workers, scope: :all)
28
+ enhance.call("db:test:load_schema", :load_schema_workers, scope: :all)
29
+ enhance.call("db:purge", :purge_workers)
30
+ enhance.call("db:purge:all", :purge_workers, scope: :all)
31
+ enhance.call("db:drop", :drop_workers)
32
+ enhance.call("db:drop:all", :drop_workers, scope: :all)
23
33
 
24
- desc "Recreate all parallel test databases"
25
- task recreate: :prepare
26
- end
34
+ Rake::Task.tasks.map(&:name).each do |task_name|
35
+ case task_name
36
+ when /\Adb:test:purge:(.+)\z/
37
+ enhance.call(task_name, :purge_workers, name: Regexp.last_match(1), scope: :all)
38
+ when /\Adb:test:load_schema:(.+)\z/
39
+ enhance.call(task_name, :load_schema_workers, name: Regexp.last_match(1), scope: :all)
40
+ when /\Adb:create:(?!all\z)(.+)\z/
41
+ enhance.call(task_name, :create_workers, name: Regexp.last_match(1), scope: :test)
42
+ when /\Adb:schema:load:(.+)\z/
43
+ enhance.call(task_name, :load_schema_workers, name: Regexp.last_match(1), scope: :test)
44
+ when /\Adb:drop:(?!all\z|_unsafe\z)(.+)\z/
45
+ enhance.call(task_name, :drop_workers, name: Regexp.last_match(1), scope: :test)
27
46
  end
28
47
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-multicore-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0.pre1
4
+ version: 0.2.0.pre2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sveta Markovic
@@ -55,14 +55,14 @@ dependencies:
55
55
  requirements:
56
56
  - - '='
57
57
  - !ruby/object:Gem::Version
58
- version: 0.2.0.pre1
58
+ version: 0.2.0.pre2
59
59
  type: :runtime
60
60
  prerelease: false
61
61
  version_requirements: !ruby/object:Gem::Requirement
62
62
  requirements:
63
63
  - - '='
64
64
  - !ruby/object:Gem::Version
65
- version: 0.2.0.pre1
65
+ version: 0.2.0.pre2
66
66
  - !ruby/object:Gem::Dependency
67
67
  name: rake
68
68
  requirement: !ruby/object:Gem::Requirement
@@ -120,7 +120,7 @@ dependencies:
120
120
  - !ruby/object:Gem::Version
121
121
  version: '2.0'
122
122
  description: Rails adapter for rspec-multicore that assigns each worker an isolated
123
- ActiveRecord test database and provides focused prepare, drop, and recreate tasks.
123
+ ActiveRecord test database through the standard Rails database-task lifecycle.
124
124
  email:
125
125
  - svetam.sd@pm.me
126
126
  executables: []