Add regression test for copying migrations at timestamp boundary

We'd like to add validation to migration timestamps (attempted in 2854e37),
but this is problematic for copied migrations, e.g. engine migrations:
migrations are copied by adding one to every migration timestamp number,
which may produce an invalid timestamp.

This commit adds a regression test for this case, ensuring that if / when
we revisit migration timestamp validation, we handle the case for copied
migrations.
This commit is contained in:
Adrianna Chang 2023-12-01 12:09:21 -05:00
parent 2854e378c8
commit 5a09d32ee6
No known key found for this signature in database
GPG Key ID: 6816AFC60CB96DE5
1 changed files with 71 additions and 0 deletions

View File

@ -1801,4 +1801,75 @@ class CopyMigrationsTest < ActiveRecord::TestCase
def test_unknown_migration_version_should_raise_an_argument_error
assert_raise(ArgumentError) { ActiveRecord::Migration[1.0] }
end
class MigrationValidationTest < ActiveRecord::TestCase
def setup
@verbose_was, ActiveRecord::Migration.verbose = ActiveRecord::Migration.verbose, false
@schema_migration = ActiveRecord::Base.connection.schema_migration
@internal_metadata = ActiveRecord::Base.connection.internal_metadata
ActiveRecord::Base.connection.schema_cache.clear!
@migrations_path = MIGRATIONS_ROOT + "/temp"
@migrator = ActiveRecord::MigrationContext.new(@migrations_path, @schema_migration, @internal_metadata)
end
def teardown
@schema_migration.create_table
@schema_migration.delete_all_versions
ActiveRecord::Migration.verbose = @verbose_was
end
def test_copied_migrations_at_timestamp_boundary_are_valid
migrations_path_source = MIGRATIONS_ROOT + "/temp_source"
migrations_path_dest = MIGRATIONS_ROOT + "/temp_dest"
migrations = ["20180101010101_test_migration.rb", "20180101010102_test_migration_two.rb", "20180101010103_test_migration_three.rb"]
with_temp_migration_files(migrations_path_source, migrations) do
travel_to(Time.utc(2023, 12, 1, 10, 10, 59)) do
ActiveRecord::Migration.copy(migrations_path_dest, temp: migrations_path_source)
assert File.exist?(migrations_path_dest + "/20231201101059_test_migration.temp.rb")
assert File.exist?(migrations_path_dest + "/20231201101060_test_migration_two.temp.rb")
assert File.exist?(migrations_path_dest + "/20231201101061_test_migration_three.temp.rb")
migrator = ActiveRecord::MigrationContext.new(migrations_path_dest, @schema_migration, @internal_metadata)
migrator.up(20231201101059)
migrator.up(20231201101060)
migrator.up(20231201101061)
assert_equal 20231201101061, migrator.current_version
assert_not migrator.needs_migration?
end
end
ensure
File.delete(*Dir[migrations_path_dest + "/*.rb"])
Dir.rmdir(migrations_path_dest) if Dir.exist?(migrations_path_dest)
end
private
def with_temp_migration_files(migrations_dir, filenames)
Dir.mkdir(migrations_dir) unless Dir.exist?(migrations_dir)
paths = []
filenames.each do |filename|
path = File.join(migrations_dir, filename)
paths << path
migration_class = filename.match(ActiveRecord::Migration::MigrationFilenameRegexp)[2].camelize
File.open(path, "w+") do |file|
file << <<~MIGRATION
class #{migration_class} < ActiveRecord::Migration::Current
def change; end
end
MIGRATION
end
end
yield
ensure
paths.each { |path| File.delete(path) if File.exist?(path) }
Dir.rmdir(migrations_dir) if Dir.exist?(migrations_dir)
end
end
end