def test_order_migrations_error_on_unclear_start_migration(self):
        first = migration.Migration('1', None)
        second = migration.Migration('3', '2')
        migrations = [first, second]

        manager = migration_manager.MigrationManager(self.TEST_MIGRATIONS_DIR)
        with self.assertRaisesRegex(error.SpannerError, 'no valid previous'):
            manager._order_migrations(migrations)
    def test_order_migrations_error_on_unclear_start_migration(self):
        first = migration.Migration("1", None, "1")
        second = migration.Migration("3", "2", "3")
        migrations = [first, second]

        manager = migration_manager.MigrationManager(self.TEST_MIGRATIONS_DIR)
        with self.assertRaisesRegex(error.SpannerError, "no valid previous"):
            manager._order_migrations(migrations)
    def test_order_migrations_error_on_circular_dependency(self):
        first = migration.Migration("1", "3", "1")
        second = migration.Migration("2", "1", "2")
        third = migration.Migration("3", "2", "3")
        migrations = [third, first, second]

        manager = migration_manager.MigrationManager(self.TEST_MIGRATIONS_DIR)
        with self.assertRaisesRegex(error.SpannerError, "No valid migration"):
            manager._order_migrations(migrations)
    def test_order_migrations_error_on_circular_dependency(self):
        first = migration.Migration('1', '3')
        second = migration.Migration('2', '1')
        third = migration.Migration('3', '2')
        migrations = [third, first, second]

        manager = migration_manager.MigrationManager(self.TEST_MIGRATIONS_DIR)
        with self.assertRaisesRegex(error.SpannerError, 'No valid migration'):
            manager._order_migrations(migrations)
    def test_order_migrations_error_on_unclear_successor(self):
        first = migration.Migration('1', None)
        second = migration.Migration('2', '1')
        third = migration.Migration('3', '1')
        migrations = [third, first, second]

        manager = migration_manager.MigrationManager(self.TEST_MIGRATIONS_DIR)
        with self.assertRaisesRegex(error.SpannerError, 'unclear successor'):
            manager._order_migrations(migrations)
    def test_order_migrations_with_no_none(self):
        first = migration.Migration('2', '1')
        second = migration.Migration('3', '2')
        third = migration.Migration('4', '3')
        migrations = [third, first, second]
        expected_order = [first, second, third]

        manager = migration_manager.MigrationManager(self.TEST_MIGRATIONS_DIR)
        self.assertEqual(manager._order_migrations(migrations), expected_order)
    def test_order_migrations_error_on_unclear_successor(self):
        first = migration.Migration("1", None, "1")
        second = migration.Migration("2", "1", "2")
        third = migration.Migration("3", "1", "3")
        migrations = [third, first, second]

        manager = migration_manager.MigrationManager(self.TEST_MIGRATIONS_DIR)
        with self.assertRaisesRegex(error.SpannerError, "unclear successor"):
            manager._order_migrations(migrations)
    def test_order_migrations_with_no_none(self):
        first = migration.Migration("2", "1", "2")
        second = migration.Migration("3", "2", "3")
        third = migration.Migration("4", "3", "4")
        migrations = [third, first, second]
        expected_order = [first, second, third]

        manager = migration_manager.MigrationManager(self.TEST_MIGRATIONS_DIR)
        self.assertEqual(manager._order_migrations(migrations), expected_order)
    def test_migrate(self):
        connection = mock.Mock()
        executor = migration_executor.MigrationExecutor(connection)

        first = migration.Migration('1', None)
        second = migration.Migration('2', '1')
        third = migration.Migration('3', '2')
        with mock.patch.object(executor, 'migrations') as migrations:
            migrations.return_value = [first, second, third]
            migrated = {'1': True, '2': False, '3': False}
            with mock.patch.object(executor, '_migration_status_map',
                                   migrated):
                executor.migrate()
                self.assertEqual(migrated, {'1': True, '2': True, '3': True})
    def test_rollback(self):
        connection = mock.Mock()
        executor = migration_executor.MigrationExecutor(
            connection, self.TEST_MIGRATIONS_DIR
        )

        first = migration.Migration("1", None, "1")
        second = migration.Migration("2", "1", "2")
        third = migration.Migration("3", "2", "3")
        with mock.patch.object(executor, "migrations") as migrations:
            migrations.return_value = [first, second, third]
            migrated = {"1": True, "2": False, "3": False}
            with mock.patch.object(executor, "_migration_status_map", migrated):
                executor.rollback("1")
                self.assertEqual(migrated, {"1": False, "2": False, "3": False})
    def test_filter_migrations_error_on_bad_last_migration(self):
        connection = mock.Mock()
        executor = migration_executor.MigrationExecutor(connection)

        first = migration.Migration('1', None)
        second = migration.Migration('2', '1')
        third = migration.Migration('3', '2')
        migrations = [first, second, third]

        migrated = {'1': True, '2': False, '3': False}
        with mock.patch.object(executor, '_migration_status_map', migrated):
            with self.assertRaises(error.SpannerError):
                executor._filter_migrations(migrations, False, '1')

            with self.assertRaises(error.SpannerError):
                executor._filter_migrations(migrations, False, '4')
示例#12
0
    def _migration_from_file(self, filename: str) -> migration.Migration:
        """Loads a single migration from the given filename in the base dir."""
        module_name = re.sub(r"\W", "_", filename)
        path = os.path.join(self.basedir, filename)

        if self._pkg_name is not None:
            # Prepend package name to module name to import full module name
            module_name = "{}.{}".format(self._pkg_name, module_name)

        spec = importlib.util.spec_from_file_location(module_name, path)
        module = importlib.util.module_from_spec(spec)
        spec.loader.exec_module(module)
        module_doc = module.__doc__.split("\n")
        if not module_doc:
            description = "<unknown>"
        else:
            description = module_doc[0]
        try:
            result = migration.Migration(
                module.migration_id,
                module.prev_migration_id,
                description,
                getattr(module, "upgrade", None),
                getattr(module, "downgrade", None),
            )
        except AttributeError:
            raise error.SpannerError("{} has no migration id".format(path))
        return result
    def test_filter_migrations_error_on_bad_last_migration(self):
        connection = mock.Mock()
        executor = migration_executor.MigrationExecutor(
            connection, self.TEST_MIGRATIONS_DIR
        )

        first = migration.Migration("1", None, "1")
        second = migration.Migration("2", "1", "2")
        third = migration.Migration("3", "2", "3")
        migrations = [first, second, third]

        migrated = {"1": True, "2": False, "3": False}
        with mock.patch.object(executor, "_migration_status_map", migrated):
            with self.assertRaises(error.SpannerError):
                executor._filter_migrations(migrations, False, "1")

            with self.assertRaises(error.SpannerError):
                executor._filter_migrations(migrations, False, "4")
    def test_show_migrations(self):
        connection = mock.Mock()
        executor = migration_executor.MigrationExecutor(
            connection, self.TEST_MIGRATIONS_DIR
        )

        first = migration.Migration("abcdef", None, "1")
        second = migration.Migration("012345", "abcdef", "2")
        third = migration.Migration("6abcde", "012345", "3")
        with mock.patch.object(executor, "migrations") as migrations:
            migrations.return_value = [first, second, third]
            migrated = {"abcdef": True, "012345": False, "6abcde": False}
            with mock.patch.object(executor, "_migration_status_map", migrated):
                with mock.patch("sys.stdout", new_callable=StringIO) as mock_stdout:
                    executor.show_migrations()
                    self.assertEqual(
                        "[ ] 6abcde, 3\n[ ] 012345, 2\n[X] abcdef, 1\n",
                        mock_stdout.getvalue(),
                    )
示例#15
0
    def test_validate_migrations(self):
        connection = mock.Mock()
        executor = migration_executor.MigrationExecutor(
            connection, self.TEST_MIGRATIONS_DIR)

        first = migration.Migration('1', None)
        second = migration.Migration('2', '1')
        third = migration.Migration('3', '2')
        with mock.patch.object(executor, 'migrations') as migrations:
            migrations.return_value = [first, second, third]

            migrated = {'1': True, '2': False, '3': False}
            with mock.patch.object(executor, '_migration_status_map',
                                   migrated):
                executor._validate_migrations()

            migrated = {'1': False, '2': False, '3': False}
            with mock.patch.object(executor, '_migration_status_map',
                                   migrated):
                executor._validate_migrations()
    def test_filter_migrations(self):
        connection = mock.Mock()
        executor = migration_executor.MigrationExecutor(connection)

        first = migration.Migration('1', None)
        second = migration.Migration('2', '1')
        third = migration.Migration('3', '2')
        migrations = [first, second, third]

        migrated = {'1': True, '2': False, '3': False}
        with mock.patch.object(executor, '_migration_status_map', migrated):
            filtered = executor._filter_migrations(migrations, False, None)
            self.assertEqual(filtered, [second, third])

            filtered = executor._filter_migrations(migrations, False, '2')
            self.assertEqual(filtered, [second])

            filtered = executor._filter_migrations(reversed(migrations), True,
                                                   '1')
            self.assertEqual(filtered, [first])
    def test_filter_migrations(self):
        connection = mock.Mock()
        executor = migration_executor.MigrationExecutor(
            connection, self.TEST_MIGRATIONS_DIR
        )

        first = migration.Migration("1", None, "1")
        second = migration.Migration("2", "1", "2")
        third = migration.Migration("3", "2", "3")
        migrations = [first, second, third]

        migrated = {"1": True, "2": False, "3": False}
        with mock.patch.object(executor, "_migration_status_map", migrated):
            filtered = executor._filter_migrations(migrations, False, None)
            self.assertEqual(filtered, [second, third])

            filtered = executor._filter_migrations(migrations, False, "2")
            self.assertEqual(filtered, [second])

            filtered = executor._filter_migrations(reversed(migrations), True, "1")
            self.assertEqual(filtered, [first])
    def test_validate_migrations_error_on_unmigrated_after_migrated(self):
        connection = mock.Mock()
        executor = migration_executor.MigrationExecutor(
            connection, self.TEST_MIGRATIONS_DIR
        )

        first = migration.Migration("1", None, "1")
        second = migration.Migration("2", "1", "2")
        third = migration.Migration("3", "2", "3")
        with mock.patch.object(executor, "migrations") as migrations:
            migrations.return_value = [first, second, third]

            migrated = {"1": False, "2": True, "3": False}
            with mock.patch.object(executor, "_migration_status_map", migrated):
                with self.assertRaises(error.SpannerError):
                    executor._validate_migrations()

            migrated = {"1": False, "2": False, "3": True}
            with mock.patch.object(executor, "_migration_status_map", migrated):
                with self.assertRaises(error.SpannerError):
                    executor._validate_migrations()
    def test_validate_migrations_error_on_unmigrated_after_migrated(self):
        connection = mock.Mock()
        executor = migration_executor.MigrationExecutor(connection)

        first = migration.Migration('1', None)
        second = migration.Migration('2', '1')
        third = migration.Migration('3', '2')
        with mock.patch.object(executor, 'migrations') as migrations:
            migrations.return_value = [first, second, third]

            migrated = {'1': False, '2': True, '3': False}
            with mock.patch.object(executor, '_migration_status_map',
                                   migrated):
                with self.assertRaises(error.SpannerError):
                    executor._validate_migrations()

            migrated = {'1': False, '2': False, '3': True}
            with mock.patch.object(executor, '_migration_status_map',
                                   migrated):
                with self.assertRaises(error.SpannerError):
                    executor._validate_migrations()
示例#20
0
 def _migration_from_file(self, filename: str) -> migration.Migration:
     """Loads a single migration from the given filename in the base dir."""
     module_name = re.sub(r'\W', '_', filename)
     path = os.path.join(self.basedir, filename)
     spec = importlib.util.spec_from_file_location(module_name, path)
     module = importlib.util.module_from_spec(spec)
     spec.loader.exec_module(module)
     try:
         result = migration.Migration(module.migration_id,
                                      module.prev_migration_id,
                                      getattr(module, 'upgrade', None),
                                      getattr(module, 'downgrade', None))
     except AttributeError:
         raise error.SpannerError('{} has no migration id'.format(path))
     return result
    def test_validate_migrations_error_on_unmigrated_first(self):
        connection = mock.Mock()
        executor = migration_executor.MigrationExecutor(connection)

        first = migration.Migration('2', '1')
        with mock.patch.object(executor, 'migrations') as migrations:
            migrations.return_value = [first]

            migrated = {'1': False}
            with mock.patch.object(executor, '_migration_status_map',
                                   migrated):
                with self.assertRaises(error.SpannerError):
                    executor._validate_migrations()

            migrated = {}
            with mock.patch.object(executor, '_migration_status_map',
                                   migrated):
                with self.assertRaises(error.SpannerError):
                    executor._validate_migrations()