def test_migration_014(self):
        """Test that adding _name_id column works correctly."""
        for (key, engine) in self.engines.items():
            migration_api.version_control(engine,
                                          TestMigrations.REPOSITORY,
                                          migration.db_initial_version())
            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 13)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 14)
            volumes = sqlalchemy.Table('volumes',
                                       metadata,
                                       autoload=True)
            self.assertIsInstance(volumes.c._name_id.type,
                                  sqlalchemy.types.VARCHAR)

            migration_api.downgrade(engine, TestMigrations.REPOSITORY, 13)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            volumes = sqlalchemy.Table('volumes',
                                       metadata,
                                       autoload=True)
            self.assertNotIn('_name_id', volumes.c)
    def test_migration_022(self):
        """Test that adding disabled_reason column works correctly."""
        for (key, engine) in self.engines.items():
            migration_api.version_control(engine,
                                          TestMigrations.REPOSITORY,
                                          migration.db_initial_version())
            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 21)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 22)
            services = sqlalchemy.Table('services',
                                        metadata,
                                        autoload=True)
            self.assertIsInstance(services.c.disabled_reason.type,
                                  sqlalchemy.types.VARCHAR)

            migration_api.downgrade(engine, TestMigrations.REPOSITORY, 21)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            services = sqlalchemy.Table('services',
                                        metadata,
                                        autoload=True)
            self.assertNotIn('disabled_reason', services.c)
    def test_migration_004(self):
        """Test that volume_type_id migration works correctly."""
        for (key, engine) in self.engines.items():
            migration_api.version_control(engine,
                                          TestMigrations.REPOSITORY,
                                          migration.INIT_VERSION)
            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 3)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 4)
            volumes = sqlalchemy.Table('volumes',
                                       metadata,
                                       autoload=True)
            volume_types = sqlalchemy.Table('volume_types',
                                            metadata,
                                            autoload=True)
            extra_specs = sqlalchemy.Table('volume_type_extra_specs',
                                           metadata,
                                           autoload=True)

            self.assertTrue(isinstance(volumes.c.volume_type_id.type,
                                       sqlalchemy.types.VARCHAR))
            self.assertTrue(isinstance(volume_types.c.id.type,
                                       sqlalchemy.types.VARCHAR))
            self.assertTrue(isinstance(extra_specs.c.volume_type_id.type,
                                       sqlalchemy.types.VARCHAR))

            self.assertTrue(extra_specs.c.volume_type_id.foreign_keys)
    def test_migration_019(self):
        """Test that adding migration_status column works correctly."""
        for (key, engine) in self.engines.items():
            migration_api.version_control(engine,
                                          TestMigrations.REPOSITORY,
                                          migration.db_initial_version())
            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 18)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 19)
            volumes = sqlalchemy.Table('volumes',
                                       metadata,
                                       autoload=True)
            self.assertIsInstance(volumes.c.migration_status.type,
                                  sqlalchemy.types.VARCHAR)

            migration_api.downgrade(engine, TestMigrations.REPOSITORY, 18)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            volumes = sqlalchemy.Table('volumes',
                                       metadata,
                                       autoload=True)
            self.assertNotIn('migration_status', volumes.c)
Exemple #5
0
    def test_migration_021(self):
        """Test adding default data for quota classes works correctly."""
        for (key, engine) in self.engines.items():
            migration_api.version_control(engine, TestMigrations.REPOSITORY,
                                          migration.db_initial_version())
            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 20)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 21)

            quota_class_metadata = sqlalchemy.Table('quota_classes',
                                                    metadata,
                                                    autoload=True)

            num_defaults = quota_class_metadata.count().\
                where(quota_class_metadata.c.class_name == 'default').\
                execute().scalar()

            self.assertEqual(3, num_defaults)

            migration_api.downgrade(engine, TestMigrations.REPOSITORY, 20)

            # Defaults should not be deleted during downgrade
            num_defaults = quota_class_metadata.count().\
                where(quota_class_metadata.c.class_name == 'default').\
                execute().scalar()

            self.assertEqual(3, num_defaults)
    def test_migration_012(self):
        """Test that adding attached_host column works correctly."""
        for (key, engine) in self.engines.items():
            migration_api.version_control(engine,
                                          TestMigrations.REPOSITORY,
                                          migration.INIT_VERSION)
            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 11)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 12)
            volumes = sqlalchemy.Table('volumes',
                                       metadata,
                                       autoload=True)
            self.assertTrue(isinstance(volumes.c.attached_host.type,
                                       sqlalchemy.types.VARCHAR))

            migration_api.downgrade(engine, TestMigrations.REPOSITORY, 11)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            volumes = sqlalchemy.Table('volumes',
                                       metadata,
                                       autoload=True)
            self.assertNotIn('attached_host', volumes.c)
Exemple #7
0
    def test_migration_010(self):
        """Test adding transfers table works correctly."""
        for (key, engine) in self.engines.items():
            migration_api.version_control(engine, TestMigrations.REPOSITORY, migration.INIT_VERSION)
            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 9)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 10)
            self.assertTrue(engine.dialect.has_table(engine.connect(), "transfers"))
            transfers = sqlalchemy.Table("transfers", metadata, autoload=True)

            self.assertIsInstance(transfers.c.created_at.type, sqlalchemy.types.DATETIME)
            self.assertIsInstance(transfers.c.updated_at.type, sqlalchemy.types.DATETIME)
            self.assertIsInstance(transfers.c.deleted_at.type, sqlalchemy.types.DATETIME)
            self.assertIsInstance(transfers.c.deleted.type, sqlalchemy.types.BOOLEAN)
            self.assertIsInstance(transfers.c.id.type, sqlalchemy.types.VARCHAR)
            self.assertIsInstance(transfers.c.volume_id.type, sqlalchemy.types.VARCHAR)
            self.assertIsInstance(transfers.c.display_name.type, sqlalchemy.types.VARCHAR)
            self.assertIsInstance(transfers.c.salt.type, sqlalchemy.types.VARCHAR)
            self.assertIsInstance(transfers.c.crypt_hash.type, sqlalchemy.types.VARCHAR)
            self.assertIsInstance(transfers.c.expires_at.type, sqlalchemy.types.DATETIME)

            migration_api.downgrade(engine, TestMigrations.REPOSITORY, 9)

            self.assertFalse(engine.dialect.has_table(engine.connect(), "transfers"))
Exemple #8
0
    def _walk_versions(self, engine=None, snake_walk=False, downgrade=True):
        # Determine latest version script from the repo, then
        # upgrade from 1 through to the latest, with no data
        # in the databases. This just checks that the schema itself
        # upgrades successfully.

        # Place the database under version control
        migration_api.version_control(engine, TestMigrations.REPOSITORY, migration.INIT_VERSION)
        self.assertEqual(migration.INIT_VERSION, migration_api.db_version(engine, TestMigrations.REPOSITORY))

        migration_api.upgrade(engine, TestMigrations.REPOSITORY, migration.INIT_VERSION + 1)

        LOG.debug("latest version is %s" % TestMigrations.REPOSITORY.latest)

        for version in xrange(migration.INIT_VERSION + 2, TestMigrations.REPOSITORY.latest + 1):
            # upgrade -> downgrade -> upgrade
            self._migrate_up(engine, version)
            if snake_walk:
                self._migrate_down(engine, version - 1)
                self._migrate_up(engine, version)

        if downgrade:
            # Now walk it back down to 0 from the latest, testing
            # the downgrade paths.
            for version in reversed(xrange(migration.INIT_VERSION + 1, TestMigrations.REPOSITORY.latest)):
                # downgrade -> upgrade -> downgrade
                self._migrate_down(engine, version)
                if snake_walk:
                    self._migrate_up(engine, version + 1)
                    self._migrate_down(engine, version)
Exemple #9
0
    def test_migration_013(self):
        """Test that adding provider_geometry column works correctly."""
        for (key, engine) in self.engines.items():
            migration_api.version_control(engine,
                                          TestMigrations.REPOSITORY,
                                          migration.INIT_VERSION)
            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 12)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 13)
            volumes = sqlalchemy.Table('volumes',
                                       metadata,
                                       autoload=True)
            self.assertIsInstance(volumes.c.provider_geometry.type,
                                  sqlalchemy.types.VARCHAR)

            migration_api.downgrade(engine, TestMigrations.REPOSITORY, 12)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            volumes = sqlalchemy.Table('volumes',
                                       metadata,
                                       autoload=True)
            self.assertNotIn('provider_geometry', volumes.c)
Exemple #10
0
    def test_migration_013(self):
        """Test that adding provider_geometry column works correctly."""
        for (key, engine) in self.engines.items():
            migration_api.version_control(engine,
                                          TestMigrations.REPOSITORY,
                                          migration.INIT_VERSION)
            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 12)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 13)
            volumes = sqlalchemy.Table('volumes',
                                       metadata,
                                       autoload=True)
            self.assertTrue(isinstance(volumes.c.provider_geometry.type,
                                       sqlalchemy.types.VARCHAR))

            migration_api.downgrade(engine, TestMigrations.REPOSITORY, 12)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            volumes = sqlalchemy.Table('volumes',
                                       metadata,
                                       autoload=True)
            self.assertNotIn('provider_geometry', volumes.c)
Exemple #11
0
    def test_migration_014(self):
        """Test that adding _name_id column works correctly."""
        for (key, engine) in self.engines.items():
            migration_api.version_control(engine,
                                          TestMigrations.REPOSITORY,
                                          migration.INIT_VERSION)
            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 13)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 14)
            volumes = sqlalchemy.Table('volumes',
                                       metadata,
                                       autoload=True)
            self.assertTrue(isinstance(volumes.c._name_id.type,
                                       sqlalchemy.types.VARCHAR))

            migration_api.downgrade(engine, TestMigrations.REPOSITORY, 13)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            volumes = sqlalchemy.Table('volumes',
                                       metadata,
                                       autoload=True)
            self.assertTrue('_name_id' not in volumes.c)
    def test_migration_021(self):
        """Test adding default data for quota classes works correctly."""
        for (key, engine) in self.engines.items():
            migration_api.version_control(engine,
                                          TestMigrations.REPOSITORY,
                                          migration.db_initial_version())
            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 20)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 21)

            quota_class_metadata = sqlalchemy.Table('quota_classes',
                                                    metadata,
                                                    autoload=True)

            num_defaults = quota_class_metadata.count().\
                where(quota_class_metadata.c.class_name == 'default').\
                execute().scalar()

            self.assertEqual(3, num_defaults)

            migration_api.downgrade(engine, TestMigrations.REPOSITORY, 20)

            # Defaults should not be deleted during downgrade
            num_defaults = quota_class_metadata.count().\
                where(quota_class_metadata.c.class_name == 'default').\
                execute().scalar()

            self.assertEqual(3, num_defaults)
Exemple #13
0
    def test_migration_019(self):
        """Test that adding migration_status column works correctly."""
        for (key, engine) in self.engines.items():
            migration_api.version_control(engine,
                                          TestMigrations.REPOSITORY,
                                          migration.INIT_VERSION)
            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 18)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 19)
            volumes = sqlalchemy.Table('volumes',
                                       metadata,
                                       autoload=True)
            self.assertIsInstance(volumes.c.migration_status.type,
                                  sqlalchemy.types.VARCHAR)

            migration_api.downgrade(engine, TestMigrations.REPOSITORY, 18)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            volumes = sqlalchemy.Table('volumes',
                                       metadata,
                                       autoload=True)
            self.assertNotIn('migration_status', volumes.c)
Exemple #14
0
    def test_migration_020(self):
        """Test adding volume_admin_metadata table works correctly."""
        for (key, engine) in self.engines.items():
            migration_api.version_control(engine, TestMigrations.REPOSITORY, migration.INIT_VERSION)
            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 19)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 20)

            self.assertTrue(engine.dialect.has_table(engine.connect(), "volume_admin_metadata"))
            volume_admin_metadata = sqlalchemy.Table("volume_admin_metadata", metadata, autoload=True)

            self.assertIsInstance(volume_admin_metadata.c.created_at.type, sqlalchemy.types.DATETIME)
            self.assertIsInstance(volume_admin_metadata.c.updated_at.type, sqlalchemy.types.DATETIME)
            self.assertIsInstance(volume_admin_metadata.c.deleted_at.type, sqlalchemy.types.DATETIME)
            self.assertIsInstance(volume_admin_metadata.c.deleted.type, sqlalchemy.types.BOOLEAN)
            self.assertIsInstance(volume_admin_metadata.c.deleted.type, sqlalchemy.types.BOOLEAN)
            self.assertIsInstance(volume_admin_metadata.c.id.type, sqlalchemy.types.INTEGER)
            self.assertIsInstance(volume_admin_metadata.c.volume_id.type, sqlalchemy.types.VARCHAR)
            self.assertIsInstance(volume_admin_metadata.c.key.type, sqlalchemy.types.VARCHAR)
            self.assertIsInstance(volume_admin_metadata.c.value.type, sqlalchemy.types.VARCHAR)

            migration_api.downgrade(engine, TestMigrations.REPOSITORY, 19)

            self.assertFalse(engine.dialect.has_table(engine.connect(), "volume_admin_metadata"))
    def test_migration_022(self):
        """Test that adding disabled_reason column works correctly."""
        for (key, engine) in self.engines.items():
            migration_api.version_control(engine,
                                          TestMigrations.REPOSITORY,
                                          migration.db_initial_version())
            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 21)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 22)
            services = sqlalchemy.Table('services',
                                        metadata,
                                        autoload=True)
            self.assertIsInstance(services.c.disabled_reason.type,
                                  sqlalchemy.types.VARCHAR)

            migration_api.downgrade(engine, TestMigrations.REPOSITORY, 21)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            services = sqlalchemy.Table('services',
                                        metadata,
                                        autoload=True)
            self.assertNotIn('disabled_reason', services.c)
    def test_migration_016(self):
        """Test that dropping xen storage manager tables works correctly."""
        for (key, engine) in self.engines.items():
            migration_api.version_control(engine,
                                          TestMigrations.REPOSITORY,
                                          migration.db_initial_version())
            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 15)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 16)
            self.assertFalse(engine.dialect.has_table(engine.connect(),
                                                      'sm_flavors'))
            self.assertFalse(engine.dialect.has_table(engine.connect(),
                                                      'sm_backend_config'))
            self.assertFalse(engine.dialect.has_table(engine.connect(),
                                                      'sm_volume'))

            migration_api.downgrade(engine, TestMigrations.REPOSITORY, 15)
            self.assertTrue(engine.dialect.has_table(engine.connect(),
                                                     'sm_flavors'))
            self.assertTrue(engine.dialect.has_table(engine.connect(),
                                                     'sm_backend_config'))
            self.assertTrue(engine.dialect.has_table(engine.connect(),
                                                     'sm_volume'))
Exemple #17
0
    def test_migration_011(self):
        """Test adding transfers table works correctly."""
        for (key, engine) in self.engines.items():
            migration_api.version_control(engine, TestMigrations.REPOSITORY, migration.INIT_VERSION)
            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 10)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            volumes_v10 = sqlalchemy.Table("volumes", metadata, autoload=True)

            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 11)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            self.assertTrue(engine.dialect.has_table(engine.connect(), "volumes"))
            volumes = sqlalchemy.Table("volumes", metadata, autoload=True)

            # Make sure we didn't miss any columns in the upgrade
            for column in volumes_v10.c:
                self.assertTrue(volumes.c.__contains__(column.name))

            self.assertIsInstance(volumes.c.bootable.type, sqlalchemy.types.BOOLEAN)

            migration_api.downgrade(engine, TestMigrations.REPOSITORY, 10)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            volumes = sqlalchemy.Table("volumes", metadata, autoload=True)
            self.assertNotIn("bootable", volumes.c)

            # Make sure we put all the columns back
            for column in volumes_v10.c:
                self.assertTrue(volumes.c.__contains__(column.name))
Exemple #18
0
    def test_migration_016(self):
        """Test that dropping xen storage manager tables works correctly."""
        for (key, engine) in self.engines.items():
            migration_api.version_control(engine, TestMigrations.REPOSITORY,
                                          migration.INIT_VERSION)
            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 15)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 16)
            self.assertFalse(
                engine.dialect.has_table(engine.connect(), 'sm_flavors'))
            self.assertFalse(
                engine.dialect.has_table(engine.connect(),
                                         'sm_backend_config'))
            self.assertFalse(
                engine.dialect.has_table(engine.connect(), 'sm_volume'))

            migration_api.downgrade(engine, TestMigrations.REPOSITORY, 15)
            self.assertTrue(
                engine.dialect.has_table(engine.connect(), 'sm_flavors'))
            self.assertTrue(
                engine.dialect.has_table(engine.connect(),
                                         'sm_backend_config'))
            self.assertTrue(
                engine.dialect.has_table(engine.connect(), 'sm_volume'))
Exemple #19
0
    def test_migration_017(self):
        """Test that added encryption information works correctly."""

        # upgrade schema
        for (key, engine) in self.engines.items():
            migration_api.version_control(engine, TestMigrations.REPOSITORY,
                                          migration.INIT_VERSION)
            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 16)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 17)

            # encryption key UUID
            volumes = sqlalchemy.Table('volumes', metadata, autoload=True)
            self.assertTrue('encryption_key_id' in volumes.c)
            self.assertTrue(
                isinstance(volumes.c.encryption_key_id.type,
                           sqlalchemy.types.VARCHAR))

            snapshots = sqlalchemy.Table('snapshots', metadata, autoload=True)
            self.assertTrue('encryption_key_id' in snapshots.c)
            self.assertTrue(
                isinstance(snapshots.c.encryption_key_id.type,
                           sqlalchemy.types.VARCHAR))
            self.assertTrue('volume_type_id' in snapshots.c)
            self.assertTrue(
                isinstance(snapshots.c.volume_type_id.type,
                           sqlalchemy.types.VARCHAR))

            # encryption types table
            encryption = sqlalchemy.Table('encryption',
                                          metadata,
                                          autoload=True)
            self.assertTrue(
                isinstance(encryption.c.volume_type_id.type,
                           sqlalchemy.types.VARCHAR))
            self.assertTrue(
                isinstance(encryption.c.cipher.type, sqlalchemy.types.VARCHAR))
            self.assertTrue(
                isinstance(encryption.c.key_size.type,
                           sqlalchemy.types.INTEGER))
            self.assertTrue(
                isinstance(encryption.c.provider.type,
                           sqlalchemy.types.VARCHAR))

            # downgrade schema
            migration_api.downgrade(engine, TestMigrations.REPOSITORY, 16)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            volumes = sqlalchemy.Table('volumes', metadata, autoload=True)
            self.assertTrue('encryption_key_id' not in volumes.c)

            snapshots = sqlalchemy.Table('snapshots', metadata, autoload=True)
            self.assertTrue('encryption_key_id' not in snapshots.c)

            self.assertFalse(
                engine.dialect.has_table(engine.connect(), 'encryption'))
Exemple #20
0
    def test_migration_008(self):
        """Test that adding and removing the backups table works correctly."""
        for (key, engine) in self.engines.items():
            migration_api.version_control(engine, TestMigrations.REPOSITORY,
                                          migration.db_initial_version())
            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 7)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 8)

            self.assertTrue(
                engine.dialect.has_table(engine.connect(), "backups"))
            backups = sqlalchemy.Table('backups', metadata, autoload=True)

            self.assertIsInstance(backups.c.created_at.type,
                                  self.time_type[engine.name])
            self.assertIsInstance(backups.c.updated_at.type,
                                  self.time_type[engine.name])
            self.assertIsInstance(backups.c.deleted_at.type,
                                  self.time_type[engine.name])
            self.assertIsInstance(backups.c.deleted.type,
                                  self.bool_type[engine.name])
            self.assertIsInstance(backups.c.id.type, sqlalchemy.types.VARCHAR)
            self.assertIsInstance(backups.c.volume_id.type,
                                  sqlalchemy.types.VARCHAR)
            self.assertIsInstance(backups.c.user_id.type,
                                  sqlalchemy.types.VARCHAR)
            self.assertIsInstance(backups.c.project_id.type,
                                  sqlalchemy.types.VARCHAR)
            self.assertIsInstance(backups.c.host.type,
                                  sqlalchemy.types.VARCHAR)
            self.assertIsInstance(backups.c.availability_zone.type,
                                  sqlalchemy.types.VARCHAR)
            self.assertIsInstance(backups.c.display_name.type,
                                  sqlalchemy.types.VARCHAR)
            self.assertIsInstance(backups.c.display_description.type,
                                  sqlalchemy.types.VARCHAR)
            self.assertIsInstance(backups.c.container.type,
                                  sqlalchemy.types.VARCHAR)
            self.assertIsInstance(backups.c.status.type,
                                  sqlalchemy.types.VARCHAR)
            self.assertIsInstance(backups.c.fail_reason.type,
                                  sqlalchemy.types.VARCHAR)
            self.assertIsInstance(backups.c.service_metadata.type,
                                  sqlalchemy.types.VARCHAR)
            self.assertIsInstance(backups.c.service.type,
                                  sqlalchemy.types.VARCHAR)
            self.assertIsInstance(backups.c.size.type,
                                  sqlalchemy.types.INTEGER)
            self.assertIsInstance(backups.c.object_count.type,
                                  sqlalchemy.types.INTEGER)

            migration_api.downgrade(engine, TestMigrations.REPOSITORY, 7)

            self.assertFalse(
                engine.dialect.has_table(engine.connect(), "backups"))
Exemple #21
0
    def _metadatas(self, upgrade_to, downgrade_to=None):
        for (key, engine) in self.engines.items():
            migration_api.version_control(engine, TestMigrations.REPOSITORY, migration.INIT_VERSION)
            migration_api.upgrade(engine, TestMigrations.REPOSITORY, upgrade_to)

            if downgrade_to is not None:
                migration_api.downgrade(engine, TestMigrations.REPOSITORY, downgrade_to)

            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine
            yield metadata
Exemple #22
0
    def test_migration_015(self):
        """Test removing migrations table works correctly."""
        for (key, engine) in self.engines.items():
            migration_api.version_control(engine, TestMigrations.REPOSITORY, migration.INIT_VERSION)
            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 15)

            self.assertFalse(engine.dialect.has_table(engine.connect(), "migrations"))

            migration_api.downgrade(engine, TestMigrations.REPOSITORY, 14)

            self.assertTrue(engine.dialect.has_table(engine.connect(), "migrations"))
Exemple #23
0
    def test_migration_005(self):
        """Test that adding source_volid column works correctly."""
        for (key, engine) in self.engines.items():
            migration_api.version_control(engine, TestMigrations.REPOSITORY, migration.INIT_VERSION)
            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 4)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 5)
            volumes = sqlalchemy.Table("volumes", metadata, autoload=True)
            self.assertIsInstance(volumes.c.source_volid.type, sqlalchemy.types.VARCHAR)
    def test_migration_017(self):
        """Test that added encryption information works correctly."""

            # upgrade schema
        for (key, engine) in self.engines.items():
            migration_api.version_control(engine,
                                          TestMigrations.REPOSITORY,
                                          migration.db_initial_version())
            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 16)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 17)

            # encryption key UUID
            volumes = sqlalchemy.Table('volumes', metadata, autoload=True)
            self.assertIn('encryption_key_id', volumes.c)
            self.assertIsInstance(volumes.c.encryption_key_id.type,
                                  sqlalchemy.types.VARCHAR)

            snapshots = sqlalchemy.Table('snapshots', metadata, autoload=True)
            self.assertIn('encryption_key_id', snapshots.c)
            self.assertIsInstance(snapshots.c.encryption_key_id.type,
                                  sqlalchemy.types.VARCHAR)
            self.assertIn('volume_type_id', snapshots.c)
            self.assertIsInstance(snapshots.c.volume_type_id.type,
                                  sqlalchemy.types.VARCHAR)

            # encryption types table
            encryption = sqlalchemy.Table('encryption',
                                          metadata,
                                          autoload=True)
            self.assertIsInstance(encryption.c.volume_type_id.type,
                                  sqlalchemy.types.VARCHAR)
            self.assertIsInstance(encryption.c.cipher.type,
                                  sqlalchemy.types.VARCHAR)
            self.assertIsInstance(encryption.c.key_size.type,
                                  sqlalchemy.types.INTEGER)
            self.assertIsInstance(encryption.c.provider.type,
                                  sqlalchemy.types.VARCHAR)

            # downgrade schema
            migration_api.downgrade(engine, TestMigrations.REPOSITORY, 16)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            volumes = sqlalchemy.Table('volumes', metadata, autoload=True)
            self.assertNotIn('encryption_key_id', volumes.c)

            snapshots = sqlalchemy.Table('snapshots', metadata, autoload=True)
            self.assertNotIn('encryption_key_id', snapshots.c)

            self.assertFalse(engine.dialect.has_table(engine.connect(),
                                                      'encryption'))
Exemple #25
0
    def test_migration_005(self):
        """Test that adding source_volid column works correctly."""
        for (key, engine) in self.engines.items():
            migration_api.version_control(engine, TestMigrations.REPOSITORY,
                                          migration.INIT_VERSION)
            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 4)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 5)
            volumes = sqlalchemy.Table('volumes', metadata, autoload=True)
            self.assertIsInstance(volumes.c.source_volid.type,
                                  sqlalchemy.types.VARCHAR)
Exemple #26
0
    def test_migration_020(self):
        """Test adding volume_admin_metadata table works correctly."""
        for (key, engine) in self.engines.items():
            migration_api.version_control(engine, TestMigrations.REPOSITORY,
                                          migration.INIT_VERSION)
            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 19)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 20)

            self.assertTrue(
                engine.dialect.has_table(engine.connect(),
                                         "volume_admin_metadata"))
            volume_admin_metadata = sqlalchemy.Table('volume_admin_metadata',
                                                     metadata,
                                                     autoload=True)

            self.assertTrue(
                isinstance(volume_admin_metadata.c.created_at.type,
                           sqlalchemy.types.DATETIME))
            self.assertTrue(
                isinstance(volume_admin_metadata.c.updated_at.type,
                           sqlalchemy.types.DATETIME))
            self.assertTrue(
                isinstance(volume_admin_metadata.c.deleted_at.type,
                           sqlalchemy.types.DATETIME))
            self.assertTrue(
                isinstance(volume_admin_metadata.c.deleted.type,
                           sqlalchemy.types.BOOLEAN))
            self.assertTrue(
                isinstance(volume_admin_metadata.c.deleted.type,
                           sqlalchemy.types.BOOLEAN))
            self.assertTrue(
                isinstance(volume_admin_metadata.c.id.type,
                           sqlalchemy.types.INTEGER))
            self.assertTrue(
                isinstance(volume_admin_metadata.c.volume_id.type,
                           sqlalchemy.types.VARCHAR))
            self.assertTrue(
                isinstance(volume_admin_metadata.c.key.type,
                           sqlalchemy.types.VARCHAR))
            self.assertTrue(
                isinstance(volume_admin_metadata.c.value.type,
                           sqlalchemy.types.VARCHAR))

            migration_api.downgrade(engine, TestMigrations.REPOSITORY, 19)

            self.assertFalse(
                engine.dialect.has_table(engine.connect(),
                                         "volume_admin_metadata"))
Exemple #27
0
    def test_migration_015(self):
        """Test removing migrations table works correctly."""
        for (key, engine) in self.engines.items():
            migration_api.version_control(engine, TestMigrations.REPOSITORY,
                                          migration.INIT_VERSION)
            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 15)

            self.assertFalse(
                engine.dialect.has_table(engine.connect(), "migrations"))

            migration_api.downgrade(engine, TestMigrations.REPOSITORY, 14)

            self.assertTrue(
                engine.dialect.has_table(engine.connect(), "migrations"))
Exemple #28
0
    def _metadatas(self, upgrade_to, downgrade_to=None):
        for (key, engine) in self.engines.items():
            migration_api.version_control(engine, TestMigrations.REPOSITORY,
                                          migration.INIT_VERSION)
            migration_api.upgrade(engine, TestMigrations.REPOSITORY,
                                  upgrade_to)

            if downgrade_to is not None:
                migration_api.downgrade(engine, TestMigrations.REPOSITORY,
                                        downgrade_to)

            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine
            yield metadata
Exemple #29
0
    def test_migration_010(self):
        """Test adding transfers table works correctly."""
        for (key, engine) in self.engines.items():
            migration_api.version_control(engine, TestMigrations.REPOSITORY,
                                          migration.INIT_VERSION)
            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 9)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 10)

            self.assertTrue(
                engine.dialect.has_table(engine.connect(), "transfers"))
            transfers = sqlalchemy.Table('transfers', metadata, autoload=True)

            self.assertTrue(
                isinstance(transfers.c.created_at.type,
                           sqlalchemy.types.DATETIME))
            self.assertTrue(
                isinstance(transfers.c.updated_at.type,
                           sqlalchemy.types.DATETIME))
            self.assertTrue(
                isinstance(transfers.c.deleted_at.type,
                           sqlalchemy.types.DATETIME))
            self.assertTrue(
                isinstance(transfers.c.deleted.type, sqlalchemy.types.BOOLEAN))
            self.assertTrue(
                isinstance(transfers.c.id.type, sqlalchemy.types.VARCHAR))
            self.assertTrue(
                isinstance(transfers.c.volume_id.type,
                           sqlalchemy.types.VARCHAR))
            self.assertTrue(
                isinstance(transfers.c.display_name.type,
                           sqlalchemy.types.VARCHAR))
            self.assertTrue(
                isinstance(transfers.c.salt.type, sqlalchemy.types.VARCHAR))
            self.assertTrue(
                isinstance(transfers.c.crypt_hash.type,
                           sqlalchemy.types.VARCHAR))
            self.assertTrue(
                isinstance(transfers.c.expires_at.type,
                           sqlalchemy.types.DATETIME))

            migration_api.downgrade(engine, TestMigrations.REPOSITORY, 9)

            self.assertFalse(
                engine.dialect.has_table(engine.connect(), "transfers"))
Exemple #30
0
    def test_migration_011(self):
        """Test adding transfers table works correctly."""
        for (key, engine) in self.engines.items():
            migration_api.version_control(engine,
                                          TestMigrations.REPOSITORY,
                                          migration.INIT_VERSION)
            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 10)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            volumes_v10 = sqlalchemy.Table('volumes',
                                           metadata,
                                           autoload=True)

            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 11)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            self.assertTrue(engine.dialect.has_table(engine.connect(),
                                                     "volumes"))
            volumes = sqlalchemy.Table('volumes',
                                       metadata,
                                       autoload=True)

            # Make sure we didn't miss any columns in the upgrade
            for column in volumes_v10.c:
                self.assertTrue(volumes.c.__contains__(column.name))

            self.assertIsInstance(volumes.c.bootable.type,
                                  sqlalchemy.types.BOOLEAN)

            migration_api.downgrade(engine, TestMigrations.REPOSITORY, 10)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            volumes = sqlalchemy.Table('volumes',
                                       metadata,
                                       autoload=True)
            self.assertNotIn('bootable', volumes.c)

            # Make sure we put all the columns back
            for column in volumes_v10.c:
                self.assertTrue(volumes.c.__contains__(column.name))
Exemple #31
0
    def test_migration_018(self):
        """Test that added qos_specs table works correctly."""
        for (key, engine) in self.engines.items():
            migration_api.version_control(engine, TestMigrations.REPOSITORY,
                                          migration.INIT_VERSION)
            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 17)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 18)
            self.assertTrue(
                engine.dialect.has_table(engine.connect(),
                                         "quality_of_service_specs"))
            qos_specs = sqlalchemy.Table('quality_of_service_specs',
                                         metadata,
                                         autoload=True)
            self.assertTrue(
                isinstance(qos_specs.c.created_at.type,
                           sqlalchemy.types.DATETIME))
            self.assertTrue(
                isinstance(qos_specs.c.updated_at.type,
                           sqlalchemy.types.DATETIME))
            self.assertTrue(
                isinstance(qos_specs.c.deleted_at.type,
                           sqlalchemy.types.DATETIME))
            self.assertTrue(
                isinstance(qos_specs.c.deleted.type, sqlalchemy.types.BOOLEAN))
            self.assertTrue(
                isinstance(qos_specs.c.id.type, sqlalchemy.types.VARCHAR))
            self.assertTrue(
                isinstance(qos_specs.c.specs_id.type,
                           sqlalchemy.types.VARCHAR))
            self.assertTrue(
                isinstance(qos_specs.c.key.type, sqlalchemy.types.VARCHAR))
            self.assertTrue(
                isinstance(qos_specs.c.value.type, sqlalchemy.types.VARCHAR))

            migration_api.downgrade(engine, TestMigrations.REPOSITORY, 17)

            self.assertFalse(
                engine.dialect.has_table(engine.connect(),
                                         "quality_of_service_specs"))
Exemple #32
0
    def test_migration_009(self):
        """Test adding snapshot_metadata table works correctly."""
        for (key, engine) in self.engines.items():
            migration_api.version_control(engine, TestMigrations.REPOSITORY,
                                          migration.db_initial_version())
            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 8)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 9)

            self.assertTrue(
                engine.dialect.has_table(engine.connect(),
                                         "snapshot_metadata"))
            snapshot_metadata = sqlalchemy.Table('snapshot_metadata',
                                                 metadata,
                                                 autoload=True)

            self.assertIsInstance(snapshot_metadata.c.created_at.type,
                                  self.time_type[engine.name])
            self.assertIsInstance(snapshot_metadata.c.updated_at.type,
                                  self.time_type[engine.name])
            self.assertIsInstance(snapshot_metadata.c.deleted_at.type,
                                  self.time_type[engine.name])
            self.assertIsInstance(snapshot_metadata.c.deleted.type,
                                  self.bool_type[engine.name])
            self.assertIsInstance(snapshot_metadata.c.deleted.type,
                                  self.bool_type[engine.name])
            self.assertIsInstance(snapshot_metadata.c.id.type,
                                  sqlalchemy.types.INTEGER)
            self.assertIsInstance(snapshot_metadata.c.snapshot_id.type,
                                  sqlalchemy.types.VARCHAR)
            self.assertIsInstance(snapshot_metadata.c.key.type,
                                  sqlalchemy.types.VARCHAR)
            self.assertIsInstance(snapshot_metadata.c.value.type,
                                  sqlalchemy.types.VARCHAR)

            migration_api.downgrade(engine, TestMigrations.REPOSITORY, 8)

            self.assertFalse(
                engine.dialect.has_table(engine.connect(),
                                         "snapshot_metadata"))
    def test_migration_009(self):
        """Test adding snapshot_metadata table works correctly."""
        for (key, engine) in self.engines.items():
            migration_api.version_control(engine,
                                          TestMigrations.REPOSITORY,
                                          migration.db_initial_version())
            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 8)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 9)

            self.assertTrue(engine.dialect.has_table(engine.connect(),
                                                     "snapshot_metadata"))
            snapshot_metadata = sqlalchemy.Table('snapshot_metadata',
                                                 metadata,
                                                 autoload=True)

            self.assertIsInstance(snapshot_metadata.c.created_at.type,
                                  sqlalchemy.types.DATETIME)
            self.assertIsInstance(snapshot_metadata.c.updated_at.type,
                                  sqlalchemy.types.DATETIME)
            self.assertIsInstance(snapshot_metadata.c.deleted_at.type,
                                  sqlalchemy.types.DATETIME)
            self.assertIsInstance(snapshot_metadata.c.deleted.type,
                                  self.bool_type[engine.name])
            self.assertIsInstance(snapshot_metadata.c.deleted.type,
                                  self.bool_type[engine.name])
            self.assertIsInstance(snapshot_metadata.c.id.type,
                                  sqlalchemy.types.INTEGER)
            self.assertIsInstance(snapshot_metadata.c.snapshot_id.type,
                                  sqlalchemy.types.VARCHAR)
            self.assertIsInstance(snapshot_metadata.c.key.type,
                                  sqlalchemy.types.VARCHAR)
            self.assertIsInstance(snapshot_metadata.c.value.type,
                                  sqlalchemy.types.VARCHAR)

            migration_api.downgrade(engine, TestMigrations.REPOSITORY, 8)

            self.assertFalse(engine.dialect.has_table(engine.connect(),
                                                      "snapshot_metadata"))
Exemple #34
0
    def test_migration_012(self):
        """Test that adding attached_host column works correctly."""
        for (key, engine) in self.engines.items():
            migration_api.version_control(engine, TestMigrations.REPOSITORY,
                                          migration.INIT_VERSION)
            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 11)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 12)
            volumes = sqlalchemy.Table('volumes', metadata, autoload=True)
            self.assertTrue(
                isinstance(volumes.c.attached_host.type,
                           sqlalchemy.types.VARCHAR))

            migration_api.downgrade(engine, TestMigrations.REPOSITORY, 11)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            volumes = sqlalchemy.Table('volumes', metadata, autoload=True)
            self.assertTrue('attached_host' not in volumes.c)
Exemple #35
0
    def _walk_versions(self, engine=None, snake_walk=False, downgrade=True):
        # Determine latest version script from the repo, then
        # upgrade from 1 through to the latest, with no data
        # in the databases. This just checks that the schema itself
        # upgrades successfully.

        # Place the database under version control
        migration_api.version_control(engine,
                                      TestMigrations.REPOSITORY,
                                      migration.INIT_VERSION)
        self.assertEqual(migration.INIT_VERSION,
                         migration_api.db_version(engine,
                                                  TestMigrations.REPOSITORY))

        migration_api.upgrade(engine, TestMigrations.REPOSITORY,
                              migration.INIT_VERSION + 1)

        LOG.debug('latest version is %s' % TestMigrations.REPOSITORY.latest)

        for version in xrange(migration.INIT_VERSION + 2,
                              TestMigrations.REPOSITORY.latest + 1):
            # upgrade -> downgrade -> upgrade
            self._migrate_up(engine, version, with_data=True)
            if snake_walk:
                self._migrate_down(engine, version - 1)
                self._migrate_up(engine, version)

        if downgrade:
            # Now walk it back down to 0 from the latest, testing
            # the downgrade paths.
            for version in reversed(
                xrange(migration.INIT_VERSION + 1,
                       TestMigrations.REPOSITORY.latest)):
                # downgrade -> upgrade -> downgrade
                self._migrate_down(engine, version)
                if snake_walk:
                    self._migrate_up(engine, version + 1)
                    self._migrate_down(engine, version)
Exemple #36
0
    def test_migration_018(self):
        """Test that added qos_specs table works correctly."""
        for (key, engine) in self.engines.items():
            migration_api.version_control(engine, TestMigrations.REPOSITORY, migration.INIT_VERSION)
            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 17)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 18)
            self.assertTrue(engine.dialect.has_table(engine.connect(), "quality_of_service_specs"))
            qos_specs = sqlalchemy.Table("quality_of_service_specs", metadata, autoload=True)
            self.assertIsInstance(qos_specs.c.created_at.type, sqlalchemy.types.DATETIME)
            self.assertIsInstance(qos_specs.c.updated_at.type, sqlalchemy.types.DATETIME)
            self.assertIsInstance(qos_specs.c.deleted_at.type, sqlalchemy.types.DATETIME)
            self.assertIsInstance(qos_specs.c.deleted.type, sqlalchemy.types.BOOLEAN)
            self.assertIsInstance(qos_specs.c.id.type, sqlalchemy.types.VARCHAR)
            self.assertIsInstance(qos_specs.c.specs_id.type, sqlalchemy.types.VARCHAR)
            self.assertIsInstance(qos_specs.c.key.type, sqlalchemy.types.VARCHAR)
            self.assertIsInstance(qos_specs.c.value.type, sqlalchemy.types.VARCHAR)

            migration_api.downgrade(engine, TestMigrations.REPOSITORY, 17)

            self.assertFalse(engine.dialect.has_table(engine.connect(), "quality_of_service_specs"))
Exemple #37
0
    def test_migration_008(self):
        """Test that adding and removing the backups table works correctly"""
        for (key, engine) in self.engines.items():
            migration_api.version_control(engine, TestMigrations.REPOSITORY, migration.INIT_VERSION)
            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 7)
            metadata = sqlalchemy.schema.MetaData()
            metadata.bind = engine

            migration_api.upgrade(engine, TestMigrations.REPOSITORY, 8)

            self.assertTrue(engine.dialect.has_table(engine.connect(), "backups"))
            backups = sqlalchemy.Table("backups", metadata, autoload=True)

            self.assertIsInstance(backups.c.created_at.type, sqlalchemy.types.DATETIME)
            self.assertIsInstance(backups.c.updated_at.type, sqlalchemy.types.DATETIME)
            self.assertIsInstance(backups.c.deleted_at.type, sqlalchemy.types.DATETIME)
            self.assertIsInstance(backups.c.deleted.type, sqlalchemy.types.BOOLEAN)
            self.assertIsInstance(backups.c.id.type, sqlalchemy.types.VARCHAR)
            self.assertIsInstance(backups.c.volume_id.type, sqlalchemy.types.VARCHAR)
            self.assertIsInstance(backups.c.user_id.type, sqlalchemy.types.VARCHAR)
            self.assertIsInstance(backups.c.project_id.type, sqlalchemy.types.VARCHAR)
            self.assertIsInstance(backups.c.host.type, sqlalchemy.types.VARCHAR)
            self.assertIsInstance(backups.c.availability_zone.type, sqlalchemy.types.VARCHAR)
            self.assertIsInstance(backups.c.display_name.type, sqlalchemy.types.VARCHAR)
            self.assertIsInstance(backups.c.display_description.type, sqlalchemy.types.VARCHAR)
            self.assertIsInstance(backups.c.container.type, sqlalchemy.types.VARCHAR)
            self.assertIsInstance(backups.c.status.type, sqlalchemy.types.VARCHAR)
            self.assertIsInstance(backups.c.fail_reason.type, sqlalchemy.types.VARCHAR)
            self.assertIsInstance(backups.c.service_metadata.type, sqlalchemy.types.VARCHAR)
            self.assertIsInstance(backups.c.service.type, sqlalchemy.types.VARCHAR)
            self.assertIsInstance(backups.c.size.type, sqlalchemy.types.INTEGER)
            self.assertIsInstance(backups.c.object_count.type, sqlalchemy.types.INTEGER)

            migration_api.downgrade(engine, TestMigrations.REPOSITORY, 7)

            self.assertFalse(engine.dialect.has_table(engine.connect(), "backups"))