rspec-multicore-rails 0.2.0.pre1
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 +7 -0
- data/CHANGELOG.md +8 -0
- data/LICENSE.txt +21 -0
- data/README.md +15 -0
- data/lib/rspec/multicore/rails/database_manager.rb +78 -0
- data/lib/rspec/multicore/rails/version.rb +9 -0
- data/lib/rspec/multicore/rails.rb +27 -0
- data/lib/tasks/multicore.rake +28 -0
- metadata +162 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: d79cf584351309d480685d78f5a6d75a6883f1dbc7567f0711723eb631222dd3
|
|
4
|
+
data.tar.gz: 43a198971e8fef686be3f859658f10c3038bc897053fc0252782dc2d71c46736
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: ece0c46dc96d6fc0d716512a7db10b96bad1216dd8f8b1cc47aadb6e5ab0a48756efd244ce1491dca91d55e91cf3d54ce4866f917c9c7b9e0c4716f186c2ff8f
|
|
7
|
+
data.tar.gz: b01482a80460f2e5b5e3532fc210ee6c5c3c5d0e16311403934a33d1067747484f09239b92efb920da9c8585c849051e7b4eb6ce5d149613e3c314c52782cb86
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.2.0.pre1
|
|
4
|
+
|
|
5
|
+
- Uses the core worker count as the single concurrency source.
|
|
6
|
+
- Automatically handles only ActiveRecord database isolation.
|
|
7
|
+
- Adds focused prepare, drop, and recreate tasks and real SQLite isolation coverage.
|
|
8
|
+
- Supports Ruby 3.2+ and Rails/ActiveRecord/Railties 7.1–8.x.
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025-2026 Sveta Markovic
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# rspec-multicore-rails
|
|
2
|
+
|
|
3
|
+
`rspec-multicore-rails` loads `rspec-multicore` and automatically isolates ActiveRecord connections for Rails test workers.
|
|
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.
|
|
6
|
+
|
|
7
|
+
```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
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
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
|
+
|
|
15
|
+
Requires Ruby 3.2+, Rails/ActiveRecord 7.1–8.x, and exactly the matching `rspec-multicore` version.
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_record"
|
|
4
|
+
require "active_record/tasks/database_tasks"
|
|
5
|
+
|
|
6
|
+
module RSpec
|
|
7
|
+
module Multicore
|
|
8
|
+
module Rails
|
|
9
|
+
# Names, prepares, and connects worker-owned ActiveRecord databases.
|
|
10
|
+
class DatabaseManager
|
|
11
|
+
def initialize
|
|
12
|
+
ensure_test_environment!
|
|
13
|
+
@base_config = ActiveRecord::Base.connection_db_config
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def connect_worker(slot)
|
|
17
|
+
ActiveRecord::Base.connection_handler.clear_all_connections!
|
|
18
|
+
ActiveRecord::Base.establish_connection(config_for(slot))
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def prepare_all
|
|
22
|
+
worker_slots.each do |slot|
|
|
23
|
+
purge(slot)
|
|
24
|
+
ActiveRecord::Tasks::DatabaseTasks.load_schema(hash_config_for(slot))
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def drop_workers = worker_slots.drop(1).each { drop(_1) }
|
|
29
|
+
|
|
30
|
+
def workers = RSpec::Multicore.workers
|
|
31
|
+
def database_for(slot) = slot == 1 ? base_database : suffixed_database(slot)
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def worker_slots = (1..workers)
|
|
36
|
+
def base_database = @base_config.database
|
|
37
|
+
|
|
38
|
+
def suffixed_database(slot)
|
|
39
|
+
if sqlite?
|
|
40
|
+
extension = File.extname(base_database)
|
|
41
|
+
return "#{base_database.delete_suffix(extension)}_#{slot}#{extension}"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
"#{base_database}_#{slot}"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def sqlite? = @base_config.adapter == "sqlite3"
|
|
48
|
+
|
|
49
|
+
def config_for(slot) = @base_config.configuration_hash.merge(database: database_for(slot))
|
|
50
|
+
|
|
51
|
+
def hash_config_for(slot)
|
|
52
|
+
ActiveRecord::DatabaseConfigurations::HashConfig.new(
|
|
53
|
+
@base_config.env_name,
|
|
54
|
+
@base_config.name,
|
|
55
|
+
config_for(slot)
|
|
56
|
+
)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def purge(slot)
|
|
60
|
+
drop(slot)
|
|
61
|
+
ActiveRecord::Tasks::DatabaseTasks.create(config_for(slot))
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def drop(slot)
|
|
65
|
+
ActiveRecord::Tasks::DatabaseTasks.drop(config_for(slot))
|
|
66
|
+
rescue ActiveRecord::NoDatabaseError
|
|
67
|
+
nil
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def ensure_test_environment!
|
|
71
|
+
return if ::Rails.env.test?
|
|
72
|
+
|
|
73
|
+
raise RSpec::Multicore::Error, "Parallel databases can only be managed in the Rails test environment"
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rspec/multicore"
|
|
4
|
+
require "rails"
|
|
5
|
+
require_relative "rails/version"
|
|
6
|
+
require_relative "rails/database_manager"
|
|
7
|
+
|
|
8
|
+
module RSpec
|
|
9
|
+
module Multicore
|
|
10
|
+
module Rails
|
|
11
|
+
# Registers automatic ActiveRecord reconnection and database tasks.
|
|
12
|
+
class Railtie < ::Rails::Railtie
|
|
13
|
+
railtie_name :rspec_multicore_rails
|
|
14
|
+
|
|
15
|
+
initializer "rspec_multicore_rails.active_record" do
|
|
16
|
+
RSpec::Multicore.on_worker_fork do |slot|
|
|
17
|
+
DatabaseManager.new.connect_worker(slot)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
rake_tasks do
|
|
22
|
+
load File.expand_path("../../tasks/multicore.rake", __dir__)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rspec/multicore/rails"
|
|
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
|
|
15
|
+
|
|
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
|
+
|
|
24
|
+
desc "Recreate all parallel test databases"
|
|
25
|
+
task recreate: :prepare
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: rspec-multicore-rails
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.2.0.pre1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Sveta Markovic
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: activerecord
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '7.1'
|
|
19
|
+
- - "<"
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '9'
|
|
22
|
+
type: :runtime
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
requirements:
|
|
26
|
+
- - ">="
|
|
27
|
+
- !ruby/object:Gem::Version
|
|
28
|
+
version: '7.1'
|
|
29
|
+
- - "<"
|
|
30
|
+
- !ruby/object:Gem::Version
|
|
31
|
+
version: '9'
|
|
32
|
+
- !ruby/object:Gem::Dependency
|
|
33
|
+
name: railties
|
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
|
35
|
+
requirements:
|
|
36
|
+
- - ">="
|
|
37
|
+
- !ruby/object:Gem::Version
|
|
38
|
+
version: '7.1'
|
|
39
|
+
- - "<"
|
|
40
|
+
- !ruby/object:Gem::Version
|
|
41
|
+
version: '9'
|
|
42
|
+
type: :runtime
|
|
43
|
+
prerelease: false
|
|
44
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
45
|
+
requirements:
|
|
46
|
+
- - ">="
|
|
47
|
+
- !ruby/object:Gem::Version
|
|
48
|
+
version: '7.1'
|
|
49
|
+
- - "<"
|
|
50
|
+
- !ruby/object:Gem::Version
|
|
51
|
+
version: '9'
|
|
52
|
+
- !ruby/object:Gem::Dependency
|
|
53
|
+
name: rspec-multicore
|
|
54
|
+
requirement: !ruby/object:Gem::Requirement
|
|
55
|
+
requirements:
|
|
56
|
+
- - '='
|
|
57
|
+
- !ruby/object:Gem::Version
|
|
58
|
+
version: 0.2.0.pre1
|
|
59
|
+
type: :runtime
|
|
60
|
+
prerelease: false
|
|
61
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
62
|
+
requirements:
|
|
63
|
+
- - '='
|
|
64
|
+
- !ruby/object:Gem::Version
|
|
65
|
+
version: 0.2.0.pre1
|
|
66
|
+
- !ruby/object:Gem::Dependency
|
|
67
|
+
name: rake
|
|
68
|
+
requirement: !ruby/object:Gem::Requirement
|
|
69
|
+
requirements:
|
|
70
|
+
- - "~>"
|
|
71
|
+
- !ruby/object:Gem::Version
|
|
72
|
+
version: '13.0'
|
|
73
|
+
type: :development
|
|
74
|
+
prerelease: false
|
|
75
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
76
|
+
requirements:
|
|
77
|
+
- - "~>"
|
|
78
|
+
- !ruby/object:Gem::Version
|
|
79
|
+
version: '13.0'
|
|
80
|
+
- !ruby/object:Gem::Dependency
|
|
81
|
+
name: rspec
|
|
82
|
+
requirement: !ruby/object:Gem::Requirement
|
|
83
|
+
requirements:
|
|
84
|
+
- - "~>"
|
|
85
|
+
- !ruby/object:Gem::Version
|
|
86
|
+
version: '3.13'
|
|
87
|
+
type: :development
|
|
88
|
+
prerelease: false
|
|
89
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
90
|
+
requirements:
|
|
91
|
+
- - "~>"
|
|
92
|
+
- !ruby/object:Gem::Version
|
|
93
|
+
version: '3.13'
|
|
94
|
+
- !ruby/object:Gem::Dependency
|
|
95
|
+
name: rubocop
|
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
|
97
|
+
requirements:
|
|
98
|
+
- - "~>"
|
|
99
|
+
- !ruby/object:Gem::Version
|
|
100
|
+
version: '1.21'
|
|
101
|
+
type: :development
|
|
102
|
+
prerelease: false
|
|
103
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
104
|
+
requirements:
|
|
105
|
+
- - "~>"
|
|
106
|
+
- !ruby/object:Gem::Version
|
|
107
|
+
version: '1.21'
|
|
108
|
+
- !ruby/object:Gem::Dependency
|
|
109
|
+
name: sqlite3
|
|
110
|
+
requirement: !ruby/object:Gem::Requirement
|
|
111
|
+
requirements:
|
|
112
|
+
- - ">="
|
|
113
|
+
- !ruby/object:Gem::Version
|
|
114
|
+
version: '2.0'
|
|
115
|
+
type: :development
|
|
116
|
+
prerelease: false
|
|
117
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
118
|
+
requirements:
|
|
119
|
+
- - ">="
|
|
120
|
+
- !ruby/object:Gem::Version
|
|
121
|
+
version: '2.0'
|
|
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.
|
|
124
|
+
email:
|
|
125
|
+
- svetam.sd@pm.me
|
|
126
|
+
executables: []
|
|
127
|
+
extensions: []
|
|
128
|
+
extra_rdoc_files: []
|
|
129
|
+
files:
|
|
130
|
+
- CHANGELOG.md
|
|
131
|
+
- LICENSE.txt
|
|
132
|
+
- README.md
|
|
133
|
+
- lib/rspec/multicore/rails.rb
|
|
134
|
+
- lib/rspec/multicore/rails/database_manager.rb
|
|
135
|
+
- lib/rspec/multicore/rails/version.rb
|
|
136
|
+
- lib/tasks/multicore.rake
|
|
137
|
+
homepage: https://github.com/svetam/rspec-multicore
|
|
138
|
+
licenses:
|
|
139
|
+
- MIT
|
|
140
|
+
metadata:
|
|
141
|
+
homepage_uri: https://github.com/svetam/rspec-multicore
|
|
142
|
+
source_code_uri: https://github.com/svetam/rspec-multicore/tree/master/rspec-multicore-rails
|
|
143
|
+
changelog_uri: https://github.com/svetam/rspec-multicore/blob/master/rspec-multicore-rails/CHANGELOG.md
|
|
144
|
+
rubygems_mfa_required: 'true'
|
|
145
|
+
rdoc_options: []
|
|
146
|
+
require_paths:
|
|
147
|
+
- lib
|
|
148
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
149
|
+
requirements:
|
|
150
|
+
- - ">="
|
|
151
|
+
- !ruby/object:Gem::Version
|
|
152
|
+
version: 3.2.0
|
|
153
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
154
|
+
requirements:
|
|
155
|
+
- - ">="
|
|
156
|
+
- !ruby/object:Gem::Version
|
|
157
|
+
version: '0'
|
|
158
|
+
requirements: []
|
|
159
|
+
rubygems_version: 3.6.9
|
|
160
|
+
specification_version: 4
|
|
161
|
+
summary: ActiveRecord isolation for rspec-multicore Rails workers
|
|
162
|
+
test_files: []
|