def _walk_versions(self, initial_version=0): # 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. # Assert we are not under version control... self.assertRaises(exception.DatabaseMigrationError, migration_api.db_version) # Place the database under version control migration_api.version_control(version=initial_version) cur_version = migration_api.db_version() self.assertEqual(initial_version, cur_version) for version in xrange(initial_version + 1, TestMigrations.REPOSITORY.latest + 1): migration_api.db_sync(version) cur_version = migration_api.db_version() self.assertEqual(cur_version, version) # Now walk it back down to 0 from the latest, testing # the downgrade paths. for version in reversed(xrange(0, TestMigrations.REPOSITORY.latest)): migration_api.downgrade(version) cur_version = migration_api.db_version() self.assertEqual(cur_version, version)
def test_db_sync(self): initial_version = 0 migration_api.db_sync(initial_version) cur_version = migration_api.db_version() self.assertEqual(cur_version, initial_version) migration_api.db_sync(TestMigrations.REPOSITORY.latest) cur_version = migration_api.db_version() self.assertEqual(cur_version, TestMigrations.REPOSITORY.latest) migration_api.db_sync(initial_version) cur_version = migration_api.db_version() self.assertEqual(cur_version, initial_version)
def _no_data_loss_2_to_3_to_2(self, engine): migration_api.version_control(version=0) migration_api.upgrade(2) cur_version = migration_api.db_version() self.assertEquals(2, cur_version) # We are now on version 2. Check that the images table does # not contain the type column... images_table = Table('images', MetaData(), autoload=True, autoload_with=engine) image_properties_table = Table('image_properties', MetaData(), autoload=True, autoload_with=engine) self.assertTrue( 'type' in images_table.c, "'type' column found in images table columns! " "images table columns: %s" % images_table.c.keys()) conn = engine.connect() sel = select([func.count("*")], from_obj=[images_table]) orig_num_images = conn.execute(sel).scalar() sel = select([func.count("*")], from_obj=[image_properties_table]) orig_num_image_properties = conn.execute(sel).scalar() now = datetime.datetime.now() inserter = images_table.insert() conn.execute(inserter, [{ 'deleted': False, 'created_at': now, 'updated_at': now, 'type': 'kernel', 'status': 'active', 'is_public': True }, { 'deleted': False, 'created_at': now, 'updated_at': now, 'type': 'ramdisk', 'status': 'active', 'is_public': True }]) sel = select([func.count("*")], from_obj=[images_table]) num_images = conn.execute(sel).scalar() self.assertEqual(orig_num_images + 2, num_images) conn.close() # Now let's upgrade to 3. This should move the type column # to the image_properties table as type properties. migration_api.upgrade(3) cur_version = migration_api.db_version() self.assertEquals(3, cur_version) images_table = Table('images', MetaData(), autoload=True, autoload_with=engine) self.assertTrue( 'type' not in images_table.c, "'type' column not found in images table columns! " "images table columns reported by metadata: %s\n" % images_table.c.keys()) image_properties_table = Table('image_properties', MetaData(), autoload=True, autoload_with=engine) conn = engine.connect() sel = select([func.count("*")], from_obj=[image_properties_table]) num_image_properties = conn.execute(sel).scalar() self.assertEqual(orig_num_image_properties + 2, num_image_properties) conn.close() # Downgrade to 2 and check that the type properties were moved # to the main image table migration_api.downgrade(2) images_table = Table('images', MetaData(), autoload=True, autoload_with=engine) self.assertTrue( 'type' in images_table.c, "'type' column found in images table columns! " "images table columns: %s" % images_table.c.keys()) image_properties_table = Table('image_properties', MetaData(), autoload=True, autoload_with=engine) conn = engine.connect() sel = select([func.count("*")], from_obj=[image_properties_table]) last_num_image_properties = conn.execute(sel).scalar() self.assertEqual(num_image_properties - 2, last_num_image_properties)
def version(self): """Print database's current migration level""" print(migration.db_version())
def _no_data_loss_2_to_3_to_2(self, engine): migration_api.version_control(version=0) migration_api.upgrade(2) cur_version = migration_api.db_version() self.assertEquals(2, cur_version) # We are now on version 2. Check that the images table does # not contain the type column... images_table = Table('images', MetaData(), autoload=True, autoload_with=engine) image_properties_table = Table('image_properties', MetaData(), autoload=True, autoload_with=engine) self.assertTrue('type' in images_table.c, "'type' column found in images table columns! " "images table columns: %s" % images_table.c.keys()) conn = engine.connect() sel = select([func.count("*")], from_obj=[images_table]) orig_num_images = conn.execute(sel).scalar() sel = select([func.count("*")], from_obj=[image_properties_table]) orig_num_image_properties = conn.execute(sel).scalar() now = datetime.datetime.now() inserter = images_table.insert() conn.execute(inserter, [ {'deleted': False, 'created_at': now, 'updated_at': now, 'type': 'kernel', 'status': 'active', 'is_public': True}, {'deleted': False, 'created_at': now, 'updated_at': now, 'type': 'ramdisk', 'status': 'active', 'is_public': True}]) sel = select([func.count("*")], from_obj=[images_table]) num_images = conn.execute(sel).scalar() self.assertEqual(orig_num_images + 2, num_images) conn.close() # Now let's upgrade to 3. This should move the type column # to the image_properties table as type properties. migration_api.upgrade(3) cur_version = migration_api.db_version() self.assertEquals(3, cur_version) images_table = Table('images', MetaData(), autoload=True, autoload_with=engine) self.assertTrue('type' not in images_table.c, "'type' column not found in images table columns! " "images table columns reported by metadata: %s\n" % images_table.c.keys()) image_properties_table = Table('image_properties', MetaData(), autoload=True, autoload_with=engine) conn = engine.connect() sel = select([func.count("*")], from_obj=[image_properties_table]) num_image_properties = conn.execute(sel).scalar() self.assertEqual(orig_num_image_properties + 2, num_image_properties) conn.close() # Downgrade to 2 and check that the type properties were moved # to the main image table migration_api.downgrade(2) images_table = Table('images', MetaData(), autoload=True, autoload_with=engine) self.assertTrue('type' in images_table.c, "'type' column found in images table columns! " "images table columns: %s" % images_table.c.keys()) image_properties_table = Table('image_properties', MetaData(), autoload=True, autoload_with=engine) conn = engine.connect() sel = select([func.count("*")], from_obj=[image_properties_table]) last_num_image_properties = conn.execute(sel).scalar() self.assertEqual(num_image_properties - 2, last_num_image_properties)
def _no_data_loss_15_to_16_to_15(self, engine): migration_api.version_control(version=0) migration_api.upgrade(15) cur_version = migration_api.db_version() self.assertEquals(15, cur_version) # We are now on version 15. image_members_table = Table('image_members', MetaData(), autoload=True, autoload_with=engine) self.assertTrue('status' not in image_members_table.c, "'status' not column found in image_members table " "columns! image_members table columns: %s" % image_members_table.c.keys()) conn = engine.connect() sel = select([func.count("*")], from_obj=[image_members_table]) orig_num_image_members = conn.execute(sel).scalar() now = datetime.datetime.now() inserter = image_members_table.insert() conn.execute(inserter, [ {'deleted': False, 'created_at': now, 'member': 'fake-member', 'updated_at': now, 'can_share': False, 'image_id': 'fake-image-id1'}]) sel = select([func.count("*")], from_obj=[image_members_table]) num_image_members = conn.execute(sel).scalar() self.assertEqual(orig_num_image_members + 1, num_image_members) conn.close() #Upgrade to version 16 migration_api.upgrade(16) cur_version = migration_api.db_version() self.assertEquals(16, cur_version) image_members_table = Table('image_members', MetaData(), autoload=True, autoload_with=engine) self.assertTrue('status' in image_members_table.c, "'status' column found in image_members table " "columns! image_members table columns: %s" % image_members_table.c.keys()) conn = engine.connect() sel = select([func.count("*")], from_obj=[image_members_table]) num_image_members = conn.execute(sel).scalar() self.assertEqual(orig_num_image_members + 1, num_image_members) now = datetime.datetime.now() inserter = image_members_table.insert() conn.execute(inserter, [ {'deleted': False, 'created_at': now, 'member': 'fake-member', 'updated_at': now, 'can_share': False, 'status': 'pending', 'image_id': 'fake-image-id2'}]) sel = select([func.count("*")], from_obj=[image_members_table]) num_image_members = conn.execute(sel).scalar() self.assertEqual(orig_num_image_members + 2, num_image_members) conn.close() #Downgrade to version 15 migration_api.downgrade(15) cur_version = migration_api.db_version() self.assertEquals(15, cur_version) image_members_table = Table('image_members', MetaData(), autoload=True, autoload_with=engine) self.assertTrue('status' not in image_members_table.c, "'status' column not found in image_members table " "columns! image_members table columns: %s" % image_members_table.c.keys()) conn = engine.connect() sel = select([func.count("*")], from_obj=[image_members_table]) num_image_members = conn.execute(sel).scalar() self.assertEqual(orig_num_image_members + 2, num_image_members) conn.close()