def test_rollback_to_rev_id(self): wd = WorkDirectory(self.work_dir) migr_ctx = create_migration_ctx(wd.get_migration_ctx_config()) self.assertIsNone(migr_ctx.head) one = gen_rev_id() two = gen_rev_id() three = gen_rev_id() revisions = [ Revision(one, "adding table foo", datetime.now(), upgrade_sql="create table test.foo (a string);", downgrade_sql="drop table test.foo;"), Revision(two, "adding table bar", datetime.now(), upgrade_sql="create table test.bar (a string);", downgrade_sql="drop table test.bar;"), Revision(three, "add column b foo", datetime.now(), upgrade_sql="alter table test.foo add column b string;", downgrade_sql="alter table test.foo drop column b;") ] for rev in revisions: wd.add_revision(rev) runner = CliRunner() res = runner.invoke(upgrade) self.assertTrue(res.exit_code == 0) self.assertIsNotNone(migr_ctx.head) self.assertTrue(len(migr_ctx.revisions) == 3) res = runner.invoke(rollback, ['-r', two]) self.assertTrue(res.exit_code == 0) self.assertTrue(len(migr_ctx.revisions) == 1)
def test_rollback_step_cmd(self): wd = WorkDirectory(self.work_dir) migr_ctx = create_migration_ctx(wd.get_migration_ctx_config()) self.assertIsNone(migr_ctx.head) runner = CliRunner() wd.add_revision( Revision(gen_rev_id(), "adding table foo", datetime.now(), upgrade_sql="create table test.foo (a string);", downgrade_sql="drop table test.foo")) res = runner.invoke(upgrade) self.assertTrue(res.exit_code == 0) wd.add_revision( Revision(gen_rev_id(), "adding table bar", datetime.now(), upgrade_sql="create table test.bar (a string);", downgrade_sql="drop table test.bar")) res = runner.invoke(upgrade) self.assertTrue(res.exit_code == 0) self.assertIsNotNone(migr_ctx.head) self.assertTrue(len(migr_ctx.revisions) == 2) res = runner.invoke(rollback, ['-n', 2]) self.assertIsNone(migr_ctx.head)
def test_ctx_add_revisions(self): wd = WorkDirectory(path=self.work_dir) ctx = create_migration_ctx(wd.get_migration_ctx_config()) ctx.create_revisions_tbl() self.assertTrue(len(ctx.revisions) == 0) revisions = [ Revision(gen_rev_id(), "adding table foo", datetime.now(), upgrade_sql="create table test.foo (a string);", downgrade_sql="drop table test.foo;"), Revision(gen_rev_id(), "adding table bar", datetime.now(), upgrade_sql="create table test.bar (a string);", downgrade_sql="drop table test.bar;") ] ctx.add_revisions(revisions) self.assertTrue(len(ctx.revisions) == 2)
def test_upgrade_raise(self): wd = WorkDirectory(self.work_dir) migr_ctx = create_migration_ctx(wd.get_migration_ctx_config()) self.assertIsNone(migr_ctx.head) wd.add_revision( Revision(gen_rev_id(), "adding table foo", datetime.now())) self.assertTrue(len(wd.revisions) == 1) runner = CliRunner() res = runner.invoke(upgrade) self.assertTrue(res.exit_code == 1)
def revisions(self) -> List[Revision]: config = self.config revisions = get_revisions(config.db_name, tbl_name=config.tbl_name, hostname=config.hostname, port=config.port, username=config.username, password=config.password) return [ Revision(id_, description, ts) for id_, description, ts in revisions ]
def head(self) -> Revision: config = self.config head = get_head(config.db_name, tbl_name=config.tbl_name, hostname=config.hostname, port=config.port, username=config.username, password=config.password) if head is not None: id_, description, ts = head return Revision(id_, description, ts) return head
def test_ctx_remove_revisions(self): wd = WorkDirectory(path=self.work_dir) ctx = create_migration_ctx(wd.get_migration_ctx_config()) ctx.create_revisions_tbl() self.assertTrue(len(ctx.revisions) == 0) id_1 = gen_rev_id() id_2 = gen_rev_id() d_1 = datetime.now() d_2 = datetime.now() conn = pymonetdb.connect(self.db_name) sql = """insert into sys.mroll_revisions values ('{}', '{}', '{}'), ('{}', '{}', '{}');""".format( id_1, "revision 1", d_1, id_2, "revision 2", d_2) conn.execute(sql) conn.commit() self.assertTrue(len(ctx.revisions) == 2) revisions = [ Revision(id_1, "revision 1", d_1), Revision(id_2, "revision 2", d_2) ] ctx.remove_revisions(revisions) self.assertTrue(len(ctx.revisions) == 0)
def test_upgrade_num_command(self): # Test upgrade cmd with a step wd = WorkDirectory(self.work_dir) revisions = [ Revision(gen_rev_id(), "adding table foo", datetime.now(), upgrade_sql="create table test.foo (a string);", downgrade_sql="drop table test.foo;"), Revision(gen_rev_id(), "adding table bar", datetime.now(), upgrade_sql="create table test.bar (a string);", downgrade_sql="drop table test.bar;") ] for rev in revisions: wd.add_revision(rev) self.assertTrue(len(wd.revisions) == 2) runner = CliRunner() res = runner.invoke(upgrade, ['-n', 1]) self.assertTrue(res.exit_code == 0) migr_ctx = create_migration_ctx(wd.get_migration_ctx_config()) self.assertIsNotNone(migr_ctx.head) self.assertTrue(len(migr_ctx.revisions) == 1)
def test_show_applied_revisions(self): wd = WorkDirectory(self.work_dir) wd.add_revision( Revision(gen_rev_id(), "adding table bar", datetime.now(), upgrade_sql="create table test.bar (a string);", downgrade_sql="drop table test.bar")) self.assertTrue(len(wd.revisions) == 1) runner = CliRunner() res = runner.invoke(upgrade) self.assertTrue(res.exit_code == 0) res = runner.invoke(show, ['applied']) self.assertTrue(res.exit_code == 0) self.assertNotEqual(res.stdout, '')
def revision(message): """ Creates new revision from a template. """ ensure_setup() config = Config.from_file(MROLL_CONFIG_FILE) wd = WorkDirectory(config.work_dir) ts = datetime.now().isoformat() id_ = gen_rev_id() description = message or '' wd.add_revision(Revision(id_, description, ts)) kebab = description.strip().replace(' ', '_') fn = os.path.join(wd.path, 'versions', '{}_{}.sql'.format(id_, kebab)) assert os.path.exists(fn) print('ok')
def test_serialize(self): content = """ -- identifiers used by mroll -- id=099c9a23ab3b -- description=add column -- ts=2020-05-04T23:14:37.498799 -- migration:upgrade alter table foo add column b string; -- migration:downgrade alter table foo drop column b; """ rev = Revision('099c9a23ab3b', 'add column', '2020-05-04T23:14:37.498799', upgrade_sql='alter table foo add column b string;', downgrade_sql='alter table foo drop column b;') pass
def test_rollback_raises(self): wd = WorkDirectory(self.work_dir) migr_ctx = create_migration_ctx(wd.get_migration_ctx_config()) self.assertIsNone(migr_ctx.head) runner = CliRunner() # add revison with no downgrade_sql wd.add_revision( Revision( gen_rev_id(), "adding table foo", datetime.now(), upgrade_sql="create table test.foo (a string);", )) res = runner.invoke(upgrade) self.assertTrue(res.exit_code == 0) self.assertIsNotNone(migr_ctx.head) self.assertTrue(len(migr_ctx.revisions) == 1) res = runner.invoke(rollback) self.assertNotEqual(res.exit_code, 0)
def test_show_pending_revisions(self): wd = WorkDirectory(self.work_dir) wd.add_revision( Revision(gen_rev_id(), "adding table bar", datetime.now(), upgrade_sql="create table test.bar (a string);", downgrade_sql="drop table test.bar;")) self.assertTrue(len(wd.revisions) == 1) runner = CliRunner() res = runner.invoke(upgrade) self.assertTrue(res.exit_code == 0) migr_ctx = create_migration_ctx(wd.get_migration_ctx_config()) self.assertIsNotNone(migr_ctx.head) self.assertTrue(len(migr_ctx.revisions) == 1) self.add_rev_cmd('add column a to bar') self.add_rev_cmd('add column a to baz') self.assertTrue(len(wd.revisions) == 3) res = runner.invoke(show, ['pending']) self.assertTrue(res.exit_code == 0)
def test_rollback_default_cmd(self): # test rollback no cli options wd = WorkDirectory(self.work_dir) migr_ctx = create_migration_ctx(wd.get_migration_ctx_config()) self.assertIsNone(migr_ctx.head) rev = Revision(gen_rev_id(), "adding table foo", datetime.now(), upgrade_sql="create table test.foo (a string);", downgrade_sql="drop table test.foo;") wd.add_revision(rev) self.assertTrue(len(wd.revisions) == 1) runner = CliRunner() res = runner.invoke(upgrade) self.assertTrue(res.exit_code == 0) self.assertIsNotNone(migr_ctx.head) self.assertTrue(len(migr_ctx.revisions) == 1) res = runner.invoke(rollback) self.assertTrue(res.exit_code == 0) self.assertIsNone(migr_ctx.head) self.assertTrue(len(migr_ctx.revisions) == 0)
def test_rev_from_file(self): content = """ -- identifiers used by mroll -- id=099c9a23ab3b -- description=add column -- ts=2020-05-04T23:14:37.498799 -- migration:upgrade alter table foo add column b string; -- migration:downgrade alter table foo drop column b; """ fn = '/tmp/foo.sql' with open(fn, 'wt') as f: f.write(content) res = Revision.from_file(fn) self.assertEqual(res.id, '099c9a23ab3b') self.assertEqual(res.description, 'add column') self.assertEqual(res.ts, '2020-05-04T23:14:37.498799') self.assertIsNotNone(res.upgrade_sql) self.assertIsNotNone(res.downgrade_sql) self.assertTrue(len(res.upgrade_stmts) > 0) self.assertTrue(len(res.downgrade_stmts) > 0)