Skip to content

Commit

Permalink
Add support for running tests against different DB adapters (#120)
Browse files Browse the repository at this point in the history
  • Loading branch information
m-darbinyan authored Jan 8, 2025
1 parent ac27805 commit 5607d6b
Show file tree
Hide file tree
Showing 18 changed files with 238 additions and 25 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Install SQLite3 Development Libraries
run: sudo apt-get update && sudo apt-get install -y libsqlite3-dev
run: sudo apt-get update && sudo apt-get install -y libsqlite3-dev docker-compose
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true
- name: Run the default task
run: bundle exec rake
- name: Run Tests with All Adapters
run: bundle exec rake test:all

rubocop:
runs-on: ubuntu-latest
Expand Down
1 change: 1 addition & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ GEM
zeitwerk (2.6.12)

PLATFORMS
arm64-darwin-22
arm64-darwin-23
x86_64-darwin-20
x86_64-darwin-22
Expand Down
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,24 @@ To run tests with a specific version of Rails using Appraisal:
bundle exec appraisal rails.6.0 rake test TEST=test/rake_task_test.rb TESTOPTS="--name=/db::db:rollback_branches#test_0003_keeps/"
```

By default, `rake test` runs tests using `SQLite3`. To explicitly run tests with `SQLite3`, `PostgreSQL`, or `MySQL`, you can use the following tasks:
- Run tests with `SQLite3`:
```sh
bundle exec rake test:sqlite3
```
- Run tests with `PostgreSQL` (requires Docker):
```sh
bundle exec rake test:postgresql
```
- Run tests with `MySQL` (requires Docker):
```sh
bundle exec rake test:mysql2
```
- Run tests for all supported adapters:
```sh
bundle exec rake test:all
```

## Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/widefix/actual_db_schema. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/widefix/actual_db_schema/blob/master/CODE_OF_CONDUCT.md).
Expand Down
2 changes: 2 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
require "bundler/gem_tasks"
require "rake/testtask"

load "lib/tasks/test.rake"

Rake::TestTask.new(:test) do |t|
t.libs << "test"
t.libs << "lib"
Expand Down
23 changes: 23 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
version: '3.8'

services:
postgres:
image: postgres:14
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
POSTGRES_DB: actual_db_schema_test
ports:
- "5432:5432"
volumes:
- ./docker/postgres-init:/docker-entrypoint-initdb.d

mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: actual_db_schema_test
ports:
- "3306:3306"
volumes:
- ./docker/mysql-init:/docker-entrypoint-initdb.d
1 change: 1 addition & 0 deletions docker/mysql-init/create_secondary_db.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CREATE DATABASE actual_db_schema_test_secondary;
1 change: 1 addition & 0 deletions docker/postgres-init/create_secondary_db.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CREATE DATABASE actual_db_schema_test_secondary;
2 changes: 2 additions & 0 deletions gemfiles/rails.6.0.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ source "https://rubygems.org"
gem "activerecord", "~> 6.0.0"
gem "activesupport", "~> 6.0.0"
gem "minitest", "~> 5.0"
gem "mysql2", "~> 0.5.2"
gem "pg", "~> 1.5"
gem "rake"
gem "rubocop", "~> 1.21"
gem "sqlite3", "~> 1.4.0"
Expand Down
2 changes: 2 additions & 0 deletions gemfiles/rails.6.1.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ source "https://rubygems.org"
gem "activerecord", "~> 6.1.0"
gem "activesupport", "~> 6.1.0"
gem "minitest", "~> 5.0"
gem "mysql2", "~> 0.5.2"
gem "pg", "~> 1.5"
gem "rake"
gem "rubocop", "~> 1.21"
gem "sqlite3", "~> 1.4.0"
Expand Down
2 changes: 2 additions & 0 deletions gemfiles/rails.7.0.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ source "https://rubygems.org"
gem "activerecord", "~> 7.0.0"
gem "activesupport", "~> 7.0.0"
gem "minitest", "~> 5.0"
gem "mysql2", "~> 0.5.2"
gem "pg", "~> 1.5"
gem "rake"
gem "rubocop", "~> 1.21"
gem "sqlite3", "~> 1.4.0"
Expand Down
2 changes: 2 additions & 0 deletions gemfiles/rails.7.1.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ source "https://rubygems.org"
gem "activerecord", "~> 7.1.0"
gem "activesupport", "~> 7.1.0"
gem "minitest", "~> 5.0"
gem "mysql2", "~> 0.5.2"
gem "pg", "~> 1.5"
gem "rake"
gem "rubocop", "~> 1.21"
gem "sqlite3", "~> 1.4.0"
Expand Down
2 changes: 2 additions & 0 deletions gemfiles/rails.edge.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ source "https://rubygems.org"
gem "activerecord", ">= 7.2.0.beta"
gem "activesupport", ">= 7.2.0.beta"
gem "minitest", "~> 5.0"
gem "mysql2", "~> 0.5.2"
gem "pg", "~> 1.5"
gem "rake"
gem "rubocop", "~> 1.21"
gem "rails", ">= 7.2.0.beta"
Expand Down
11 changes: 10 additions & 1 deletion lib/actual_db_schema/patches/migration_context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ def handle_rollback_error(migration, exception)
error_message = <<~ERROR
Error encountered during rollback:
#{exception.message.gsub(/^An error has occurred, all later migrations canceled:\s*/, "").strip}
#{cleaned_exception_message(exception.message)}
ERROR

puts colorize(error_message, :red)
Expand All @@ -118,6 +118,15 @@ def handle_rollback_error(migration, exception)
branch: branch_for(migration.version.to_s)
)
end

def cleaned_exception_message(message)
patterns_to_remove = [
/^An error has occurred, all later migrations canceled:\s*/,
/^An error has occurred, this and all later migrations canceled:\s*/
]

patterns_to_remove.reduce(message.strip) { |msg, pattern| msg.gsub(pattern, "").strip }
end
end
end
end
69 changes: 69 additions & 0 deletions lib/tasks/test.rake
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# frozen_string_literal: true

namespace :test do # rubocop:disable Metrics/BlockLength
desc "Run tests with SQLite3"
task :sqlite3 do
ENV["DB_ADAPTER"] = "sqlite3"
Rake::Task["test"].invoke
Rake::Task["test"].reenable
end

desc "Run tests with PostgreSQL"
task :postgresql do
sh "docker-compose up -d postgres"
wait_for_postgres

begin
ENV["DB_ADAPTER"] = "postgresql"
Rake::Task["test"].invoke
Rake::Task["test"].reenable
ensure
sh "docker-compose down"
end
end

desc "Run tests with MySQL"
task :mysql2 do
sh "docker-compose up -d mysql"
wait_for_mysql

begin
ENV["DB_ADAPTER"] = "mysql2"
Rake::Task["test"].invoke
Rake::Task["test"].reenable
ensure
sh "docker-compose down"
end
end

desc "Run tests with all adapters (SQLite3, PostgreSQL, MySQL)"
task all: %i[sqlite3 postgresql mysql2]

def wait_for_postgres
retries = 10
begin
sh "docker-compose exec -T postgres pg_isready -U postgres"
rescue StandardError
retries -= 1

raise "PostgreSQL is not ready after several attempts." if retries < 1

sleep 2
retry
end
end

def wait_for_mysql
retries = 10
begin
sh "docker-compose exec -T mysql mysqladmin ping -h 127.0.0.1 --silent"
rescue StandardError
retries -= 1

raise "MySQL is not ready after several attempts." if retries < 1

sleep 2
retry
end
end
end
25 changes: 15 additions & 10 deletions test/controllers/actual_db_schema/migrations_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,35 +44,35 @@ def active_record_setup
assert_select "td", text: "20130906111511"
assert_select "td", text: "FirstPrimary"
assert_select "td", text: @utils.branch_for("20130906111511")
assert_select "td", text: "tmp/primary.sqlite3"
assert_select "td", text: @utils.primary_database
end
assert_select "tr" do
assert_select "td", text: "up"
assert_select "td", text: "20130906111512"
assert_select "td", text: "SecondPrimary"
assert_select "td", text: @utils.branch_for("20130906111512")
assert_select "td", text: "tmp/primary.sqlite3"
assert_select "td", text: @utils.primary_database
end
assert_select "tr" do
assert_select "td", text: "up"
assert_select "td", text: "20130906111514"
assert_select "td", text: "FirstSecondary"
assert_select "td", text: @utils.branch_for("20130906111514")
assert_select "td", text: "tmp/secondary.sqlite3"
assert_select "td", text: @utils.secondary_database
end
assert_select "tr" do
assert_select "td", text: "up"
assert_select "td", text: "20130906111515"
assert_select "td", text: "SecondSecondary"
assert_select "td", text: @utils.branch_for("20130906111515")
assert_select "td", text: "tmp/secondary.sqlite3"
assert_select "td", text: @utils.secondary_database
end
end
end
end

test "GET #show returns a successful response" do
get :show, params: { id: "20130906111511", database: "tmp/primary.sqlite3" }
get :show, params: { id: "20130906111511", database: @utils.primary_database }
assert_response :success
assert_select "h2", text: "Migration FirstPrimary Details"
assert_select "table" do
Expand All @@ -86,7 +86,7 @@ def active_record_setup
end
assert_select "tr" do
assert_select "th", text: "Database"
assert_select "td", text: "tmp/primary.sqlite3"
assert_select "td", text: @utils.primary_database
end
assert_select "tr" do
assert_select "th", text: "Branch"
Expand All @@ -96,7 +96,7 @@ def active_record_setup
end

test "GET #show returns a 404 response if migration not found" do
get :show, params: { id: "nil", database: "tmp/primary.sqlite3" }
get :show, params: { id: "nil", database: @utils.primary_database }
assert_response :not_found
end

Expand All @@ -115,15 +115,20 @@ def down
RUBY
end
@utils.prepare_phantom_migrations(TestingState.db_config)
post :rollback, params: { id: "20130906111513", database: "tmp/primary.sqlite3" }
post :rollback, params: { id: "20130906111513", database: @utils.primary_database }
assert_response :redirect
get :index
message = "An error has occurred, this and all later migrations canceled:\n\nActiveRecord::IrreversibleMigration"
message = if ENV["DB_ADAPTER"] == "mysql2"
"An error has occurred, all later migrations canceled:\n\nActiveRecord::IrreversibleMigration"
else
"An error has occurred, this and all later migrations canceled:\n\n" \
"ActiveRecord::IrreversibleMigration"
end
assert_select ".flash", text: message
end

test "POST #rollback changes migration status to down and hide migration with down status" do
post :rollback, params: { id: "20130906111511", database: "tmp/primary.sqlite3" }
post :rollback, params: { id: "20130906111511", database: @utils.primary_database }
assert_response :redirect
get :index
assert_select "table" do
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,28 +51,28 @@ def active_record_setup
assert_select "td", text: "20130906111511"
assert_select "td", text: "FirstPrimary"
assert_select "td", text: @utils.branch_for("20130906111511")
assert_select "td", text: "tmp/primary.sqlite3"
assert_select "td", text: @utils.primary_database
end
assert_select "tr" do
assert_select "td", text: "up"
assert_select "td", text: "20130906111512"
assert_select "td", text: "SecondPrimary"
assert_select "td", text: @utils.branch_for("20130906111512")
assert_select "td", text: "tmp/primary.sqlite3"
assert_select "td", text: @utils.primary_database
end
assert_select "tr" do
assert_select "td", text: "up"
assert_select "td", text: "20130906111514"
assert_select "td", text: "FirstSecondary"
assert_select "td", text: @utils.branch_for("20130906111514")
assert_select "td", text: "tmp/secondary.sqlite3"
assert_select "td", text: @utils.secondary_database
end
assert_select "tr" do
assert_select "td", text: "up"
assert_select "td", text: "20130906111515"
assert_select "td", text: "SecondSecondary"
assert_select "td", text: @utils.branch_for("20130906111515")
assert_select "td", text: "tmp/secondary.sqlite3"
assert_select "td", text: @utils.secondary_database
end
end
end
Expand All @@ -86,7 +86,7 @@ def active_record_setup
end

test "GET #show returns a successful response" do
get :show, params: { id: "20130906111511", database: "tmp/primary.sqlite3" }
get :show, params: { id: "20130906111511", database: @utils.primary_database }
assert_response :success
assert_select "h2", text: "Phantom Migration FirstPrimary Details"
assert_select "table" do
Expand All @@ -100,7 +100,7 @@ def active_record_setup
end
assert_select "tr" do
assert_select "th", text: "Database"
assert_select "td", text: "tmp/primary.sqlite3"
assert_select "td", text: @utils.primary_database
end
assert_select "tr" do
assert_select "th", text: "Branch"
Expand All @@ -110,12 +110,12 @@ def active_record_setup
end

test "GET #show returns a 404 response if migration not found" do
get :show, params: { id: "nil", database: "tmp/primary.sqlite3" }
get :show, params: { id: "nil", database: @utils.primary_database }
assert_response :not_found
end

test "POST #rollback changes migration status to down and hide migration with down status" do
post :rollback, params: { id: "20130906111511", database: "tmp/primary.sqlite3" }
post :rollback, params: { id: "20130906111511", database: @utils.primary_database }
assert_response :redirect
get :index
assert_select "table" do
Expand Down Expand Up @@ -151,10 +151,15 @@ def down
RUBY
end
@utils.prepare_phantom_migrations(TestingState.db_config)
post :rollback, params: { id: "20130906111513", database: "tmp/primary.sqlite3" }
post :rollback, params: { id: "20130906111513", database: @utils.primary_database }
assert_response :redirect
get :index
message = "An error has occurred, this and all later migrations canceled:\n\nActiveRecord::IrreversibleMigration"
message = if ENV["DB_ADAPTER"] == "mysql2"
"An error has occurred, all later migrations canceled:\n\nActiveRecord::IrreversibleMigration"
else
"An error has occurred, this and all later migrations canceled:\n\n" \
"ActiveRecord::IrreversibleMigration"
end
assert_select ".flash", text: message
end

Expand Down
Loading

0 comments on commit 5607d6b

Please sign in to comment.