mirror of
https://gh.wpcy.net/https://github.com/discourse/discourse.git
synced 2026-05-15 15:29:48 +08:00
Some checks are pending
Licenses / run (push) Waiting to run
Linting / run (push) Waiting to run
Publish Assets / publish-assets (push) Waiting to run
Tests / core backend (push) Waiting to run
Tests / plugins backend (push) Waiting to run
Tests / core frontend (Chrome) (push) Waiting to run
Tests / plugins frontend (push) Waiting to run
Tests / themes frontend (push) Waiting to run
Tests / core system (push) Waiting to run
Tests / plugins system (push) Waiting to run
Tests / themes system (push) Waiting to run
Tests / core frontend (Firefox ESR) (push) Waiting to run
Tests / core frontend (Firefox Evergreen) (push) Waiting to run
Tests / chat system (push) Waiting to run
Tests / merge (push) Blocked by required conditions
Our SafeMigrate system is designed to prevent tables/columns being dropped in pre-deploy migrations. Its regex-based detection was triggering incorrectly on `ALTER COLUMN DROP DEFAULT`.
185 lines
5.2 KiB
Ruby
185 lines
5.2 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
RSpec.describe Migration::SafeMigrate do
|
|
before { Migration::SafeMigrate::SafeMigration.disable_safe! }
|
|
|
|
after do
|
|
Migration::SafeMigrate.disable!
|
|
Migration::SafeMigrate::SafeMigration.enable_safe!
|
|
end
|
|
|
|
def migrate_up(path)
|
|
migrations = ActiveRecord::MigrationContext.new(path).migrations
|
|
ActiveRecord::Migrator.new(
|
|
:up,
|
|
migrations,
|
|
ActiveRecord::Base.connection_pool.schema_migration,
|
|
ActiveRecord::Base.connection_pool.internal_metadata,
|
|
migrations.first.version,
|
|
).run
|
|
end
|
|
|
|
it "bans all table removal" do
|
|
Migration::SafeMigrate.enable!
|
|
|
|
path = File.expand_path "#{Rails.root}/spec/fixtures/db/migrate/drop_table"
|
|
|
|
output = capture_stdout { expect do migrate_up(path) end.to raise_error(StandardError) }
|
|
|
|
expect(output).to include("rails g post_migration")
|
|
|
|
expect { User.first }.not_to raise_error
|
|
expect(User.first).not_to eq(nil)
|
|
end
|
|
|
|
it "bans all table renames" do
|
|
Migration::SafeMigrate.enable!
|
|
|
|
path = File.expand_path "#{Rails.root}/spec/fixtures/db/migrate/rename_table"
|
|
|
|
output = capture_stdout { expect do migrate_up(path) end.to raise_error(StandardError) }
|
|
|
|
expect { User.first }.not_to raise_error
|
|
expect(User.first).not_to eq(nil)
|
|
|
|
expect(output).to include("rails g post_migration")
|
|
end
|
|
|
|
it "bans all column removal" do
|
|
Migration::SafeMigrate.enable!
|
|
|
|
path = File.expand_path "#{Rails.root}/spec/fixtures/db/migrate/remove_column"
|
|
|
|
output = capture_stdout { expect do migrate_up(path) end.to raise_error(StandardError) }
|
|
|
|
expect(output).to include("rails g post_migration")
|
|
|
|
expect(User.first).not_to eq(nil)
|
|
expect { User.first.username }.not_to raise_error
|
|
end
|
|
|
|
it "bans all column renames" do
|
|
Migration::SafeMigrate.enable!
|
|
|
|
path = File.expand_path "#{Rails.root}/spec/fixtures/db/migrate/rename_column"
|
|
|
|
output = capture_stdout { expect do migrate_up(path) end.to raise_error(StandardError) }
|
|
|
|
expect(output).to include("rails g post_migration")
|
|
|
|
expect(User.first).not_to eq(nil)
|
|
expect { User.first.username }.not_to raise_error
|
|
end
|
|
|
|
it "allows running a migration that creates an index concurrently if it checks if the index exists first" do
|
|
Migration::SafeMigrate.enable!
|
|
|
|
path =
|
|
File.expand_path "#{Rails.root}/spec/fixtures/db/migrate/create_index_concurrently_safe_activerecord"
|
|
|
|
error = nil
|
|
|
|
capture_stdout do
|
|
begin
|
|
migrate_up(path)
|
|
rescue StandardError => e
|
|
error = e
|
|
end
|
|
end
|
|
|
|
expect(error.cause.cause.message).to include(
|
|
"CREATE INDEX CONCURRENTLY cannot run inside a transaction block",
|
|
)
|
|
end
|
|
|
|
it "allows running a migration that creates an index concurrently if it drops the index first" do
|
|
Migration::SafeMigrate.enable!
|
|
|
|
path = File.expand_path "#{Rails.root}/spec/fixtures/db/migrate/create_index_concurrently_safe"
|
|
error = nil
|
|
|
|
capture_stdout do
|
|
begin
|
|
migrate_up(path)
|
|
rescue StandardError => e
|
|
error = e
|
|
end
|
|
end
|
|
|
|
expect(error.cause.cause.message).to include(
|
|
"CREATE INDEX CONCURRENTLY cannot run inside a transaction block",
|
|
)
|
|
end
|
|
|
|
it "bans running a migration that creates an index concurrently without first dropping the index if it exists" do
|
|
Migration::SafeMigrate.enable!
|
|
|
|
path =
|
|
File.expand_path("#{Rails.root}/spec/fixtures/db/migrate/create_index_concurrently_unsafe")
|
|
|
|
error = nil
|
|
|
|
capture_stdout do
|
|
migrate_up(path)
|
|
rescue StandardError => e
|
|
error = e
|
|
end
|
|
|
|
expect(error.message).to include(
|
|
"An attempt was made to create an index concurrently in a migration without first dropping the index.",
|
|
)
|
|
end
|
|
|
|
it "allows dropping NOT NULL" do
|
|
Migration::SafeMigrate.enable!
|
|
|
|
path = File.expand_path "#{Rails.root}/spec/fixtures/db/migrate/drop_not_null"
|
|
|
|
output = capture_stdout { migrate_up(path) }
|
|
|
|
expect(output).to include("change_column_null(:users, :username, true, nil)")
|
|
end
|
|
|
|
it "allows dropping default" do
|
|
Migration::SafeMigrate.enable!
|
|
|
|
path = File.expand_path "#{Rails.root}/spec/fixtures/db/migrate/drop_default"
|
|
|
|
output = capture_stdout { migrate_up(path) }
|
|
|
|
expect(output).to include("change_column_default(:posts, :like_count, nil)")
|
|
end
|
|
|
|
it "supports being disabled" do
|
|
Migration::SafeMigrate.enable!
|
|
Migration::SafeMigrate.disable!
|
|
|
|
path = File.expand_path "#{Rails.root}/spec/fixtures/db/migrate/drop_table"
|
|
|
|
output = capture_stdout { migrate_up(path) }
|
|
|
|
expect(output).to include("drop_table(:email_logs)")
|
|
end
|
|
|
|
describe "for a post deployment migration" do
|
|
it "should not ban unsafe migrations using up" do
|
|
Migration::SafeMigrate::SafeMigration.enable_safe!
|
|
|
|
path = File.expand_path "#{Rails.root}/spec/fixtures/db/post_migrate/drop_table"
|
|
|
|
output = capture_stdout { migrate_up(path) }
|
|
|
|
expect(output).to include("drop_table(:email_logs)")
|
|
end
|
|
|
|
it "should not ban unsafe migrations using change" do
|
|
Migration::SafeMigrate::SafeMigration.enable_safe!
|
|
|
|
path = File.expand_path "#{Rails.root}/spec/fixtures/db/post_migrate/change"
|
|
|
|
output = capture_stdout { migrate_up(path) }
|
|
|
|
expect(output).to include("drop_table(:email_logs)")
|
|
end
|
|
end
|
|
end
|