def test_get_applied_versions(fake_db): settings = configuration.Settings() fake_db.return_value = [["1.0"], ["1.1"]] result = db.get_applied_versions(settings) assert result == [Version.from_string("1.0"), Version.from_string("1.1")]
def test_is_schema_initialized(fake_db, db_responses, initialized): settings = configuration.Settings() fake_db.side_effect = db_responses result = db.is_schema_initialized(settings) assert result is initialized
def test_init_schema(mocker): patch = mocker.patch("septentrion.migration.run_script") settings = configuration.Settings( host="", port="", username="", dbname="", migrations_root="example_migrations", target_version=versions.Version.from_string("1.1"), ) migration.init_schema( settings=settings, init_version=core.get_best_schema_version(settings=settings)) calls = [ call( settings=settings, path=pathlib.Path("example_migrations/schemas/schema_0.1.sql"), ), call( settings=settings, path=pathlib.Path("example_migrations/fixtures/fixtures_0.1.sql"), ), ] assert calls == patch.call_args_list
def test_build_migration_plan_unknown_version(known_versions): settings = configuration.Settings( target_version=Version.from_string("1.5")) from_version = Version.from_string("0") with pytest.raises(ValueError): list(core.build_migration_plan(settings, from_version=from_version))
def test_get_applied_migrations(fake_db): settings = configuration.Settings() fake_db.return_value = [["first.sql"], ["second.sql"]] result = db.get_applied_migrations(settings, Version.from_string("1.1")) assert result == ["first.sql", "second.sql"] fake_db.assert_called_once()
def test_get_current_schema_version(fake_db, applied_versions, current_version): settings = configuration.Settings() fake_db.return_value = applied_versions result = db.get_current_schema_version(settings) assert result == current_version
def initialize(**kwargs): settings = configuration.Settings(**kwargs) if settings.CREATE_TABLE: # All other commands will need the table to be created logger.info("Ensuring migration table exists") db.create_table(settings=settings) # idempotent return settings
def test_get_best_schema_version_ko(mocker, known_versions): mocker.patch( "septentrion.core.files.get_special_files", return_value=["schema_1.0.sql", "schema_1.3.sql"], ) settings = configuration.Settings( target_version=Version.from_string("1.2")) with pytest.raises(exceptions.SeptentrionException): core.get_best_schema_version(settings=settings)
def test_get_best_schema_version_ok(mocker, known_versions): mocker.patch( "septentrion.core.files.get_special_files", return_value=["schema_1.1.sql", "schema_1.2.sql"], ) settings = configuration.Settings( target_version=Version.from_string("1.2")) version = core.get_best_schema_version(settings=settings) assert version == Version.from_string("1.2")
def test_get_closest_version_ok(known_versions): settings = configuration.Settings() version = core.get_closest_version( settings=settings, target_version=Version.from_string("1.1"), sql_tpl="schema_{}.sql", existing_files=["schema_1.0.sql", "schema_1.1.sql"], ) assert version == Version.from_string("1.1")
def test_get_closest_version_unknown_target_version(known_versions): settings = configuration.Settings( target_version=Version.from_string("1.5")) # target_version is not a known version with pytest.raises(ValueError): core.get_closest_version( settings=settings, target_version=Version.from_string("1.5"), sql_tpl="schema_{}.sql", existing_files=[], )
def test_get_closest_version_schema_doesnt_exist(known_versions): settings = configuration.Settings() version = core.get_closest_version( settings=settings, target_version=Version.from_string("1.1"), sql_tpl="schema_{}.sql", existing_files=["schema_1.0.sql", "schema_1.2.sql"], ) # schema_1.1.sql doesn't exist assert version is None
def test_get_applied_versions(mocker, known_versions): mocker.patch( "septentrion.core.db.get_applied_versions", return_value=[ Version.from_string("1.0"), Version.from_string("1.1"), ], ) settings = configuration.Settings() versions_ = core.get_applied_versions(settings=settings) assert versions_ == [Version.from_string("1.1")]
def test_get_closest_version_earlier_schema(known_versions): settings = configuration.Settings() version = core.get_closest_version( settings=settings, target_version=Version.from_string("1.3"), sql_tpl="schema_{}.sql", existing_files=["schema_1.0.sql", "schema_1.1.sql"], force_version=Version.from_string("1.2"), ) assert version is None
def test_get_closest_version_schema_force_ko(known_versions): """ Will fail because "1.4" is unknown """ settings = configuration.Settings() with pytest.raises(ValueError): core.get_closest_version( settings=settings, target_version=Version.from_string("1.1"), sql_tpl="schema_{}.sql", existing_files=["schema_1.0.sql", "schema_1.1.sql"], force_version=Version.from_string("1.4"), )
def test_get_known_versions(mocker): mocker.patch( "septentrion.files.iter_dirs", return_value=[ pathlib.Path("16.11"), pathlib.Path("16.12"), pathlib.Path("16.9"), ], ) settings = configuration.Settings() values = files.get_known_versions(settings=settings) assert values == [ versions.Version.from_string("16.9"), versions.Version.from_string("16.11"), versions.Version.from_string("16.12"), ]
def test_build_migration_plan_with_schema(mocker, known_versions): mocker.patch("septentrion.core.db.get_applied_migrations", return_value=[]) settings = configuration.Settings(target_version="1.2") from_version = Version.from_string("1.1") plan = list( core.build_migration_plan(settings=settings, from_version=from_version)) expected = [ { "plan": [], "version": Version.from_string("1.1") }, { "plan": [], "version": Version.from_string("1.2") }, ] assert list(plan) == expected
def test_get_migrations_files_mapping(mocker): mocker.patch( "septentrion.files.iter_files", return_value=[ pathlib.Path("tests/test_data/sql/17.1/manual/file.sql"), pathlib.Path("tests/test_data/sql/17.1/manual/file.dml.sql"), pathlib.Path("tests/test_data/sql/17.1/manual/file.ddl.sql"), ], ) settings = configuration.Settings(migrations_root="tests/test_data/sql", ignore_symlinks=True) values = files.get_migrations_files_mapping( settings=settings, version=versions.Version.from_string("17.1")) assert values == { "file.dml.sql": pathlib.Path("tests/test_data/sql/17.1/manual/file.dml.sql"), "file.ddl.sql": pathlib.Path("tests/test_data/sql/17.1/manual/file.ddl.sql"), }
def test_current_database_state(cli_runner, db): result = cli_runner.invoke( __main__.main, [ # database connection settings "--host", db["host"], "--port", db["port"], "--username", db["user"], "--dbname", db["dbname"], # migrate settings "--target-version", "1.1", "--migrations-root", "example_migrations", "migrate", ], catch_exceptions=False, ) settings = configuration.Settings(host=db["host"], port=db["port"], username=db["user"], dbname=db["dbname"]) assert result.exit_code == 0 assert db_module.is_schema_initialized(settings=settings) assert (db_module.get_current_schema_version( settings=settings).original_string == "1.1") assert "Loading schema" in result.output assert "Applied 0.1" in result.output assert "Version 1.0" in result.output assert "Applying 1.0-0-version-dml.sql ..." in result.output assert "Applied 1.0-0-version-dml.sql" in result.output assert "Version 1.1" in result.output assert "Applying 1.1-index-ddl.sql ..." in result.output assert "Applied 1.1-index-ddl.sql" in result.output
def test_settings_init(): s = configuration.Settings(foo="blah") assert s.FOO == "blah"
def test_get_known_versions_error(mocker): mocker.patch("septentrion.files.iter_dirs", side_effect=OSError) settings = configuration.Settings() with pytest.raises(exceptions.SeptentrionException): files.get_known_versions(settings=settings)
def test_settings_clean_schema_version(): schema = configuration.Settings(schema_version="1.2.3").SCHEMA_VERSION assert schema == versions.Version(version_tuple=(1, 2, 3), original_string="1.2.3")
def test_settings_clean_target_version(): target = configuration.Settings(target_version="1.2.3").TARGET_VERSION assert target == versions.Version(version_tuple=(1, 2, 3), original_string="1.2.3")
def test_build_migration_plan_db(mocker, known_versions): # What a mock hell >< # So first, we mock db.get_applied_migrations to tell the following story: # - on 1.1, only migration "a" was previously applied. # - on 1.2, no migration was previously applied. mocker.patch( "septentrion.db.get_applied_migrations", side_effect=lambda settings, version: { Version.from_string("1.1"): ["a"], Version.from_string("1.2"): [], }[version], ) # Then, regarding the migration files that exist on the disk: # - There are 2 files for 1.1 (so one already applied and one new) # - 1 file for 1.2 # - 1 file for 1.3 mocker.patch( "septentrion.files.get_migrations_files_mapping", side_effect=lambda settings, version: { Version.from_string("1.1"): { "a": pathlib.Path("a"), "b": pathlib.Path("b"), }, Version.from_string("1.2"): { "c": pathlib.Path("c"), }, Version.from_string("1.3"): { "d": pathlib.Path("d") }, }[version], ) # The contents of each migration is ignored mocker.patch("septentrion.files.file_lines_generator", return_value="") # Migration "c" is a manual migration mocker.patch( "septentrion.files.is_manual_migration", side_effect=(lambda migration_path, migration_contents: str( migration_path) == "c"), ) # We'll apply migrations up until 1.2 included settings = configuration.Settings( target_version=Version.from_string("1.2"), ) # And we'll start at version 1.1 included from_version = Version.from_string("1.1") plan = core.build_migration_plan(settings=settings, from_version=from_version) expected = [ { "version": Version.from_string("1.1"), "plan": [ # On 1.1, migration a is already applied. It's not manual ("a", True, pathlib.Path("a"), False), # migration b, though needs to be applied. It's not manual ("b", False, pathlib.Path("b"), False), ], }, { "version": Version.from_string("1.2"), "plan": [ # migration c also needs to be applied. It's manual (the last True) ("c", False, pathlib.Path("c"), True), ], }, ] assert list(plan) == expected