@Override public RerunnableObjectInfo value(RerunnableObjectInfo rerunnableObjectInfo1, ChangePair changePair) { // TODO make this a bit more OO, e.g. avoid the instanceof all over the place Change source = changePair.getSourceChange(); Change deployed = changePair.getDeployedChange(); if (source == null && deployed == null) { // this branch and exception throwing here is to avoid null deference warnings in findbugs for the next else branch throw new IllegalStateException("This code branch should never happen; either of source or deployed should exist"); } if (source == null && deployed != null) { // In this case - the change exists in the target DB but was removed from the source rerunnableObjectInfo1.addDroppedObject(deployed); } else if (source != null && deployed == null) { rerunnableObjectInfo1.addChangedObject(source); } else if (ObjectUtils.equals(source.getContentHash(), deployed.getContentHash()) || source.getAcceptableHashes().contains(deployed.getContentHash())) { // In this case - the change exists in both the source and target db. // We need to check if anything has changed, using the hash LOG.trace("Nothing to do here; source [{}] and target [{}] match in hash", source, deployed); } else { rerunnableObjectInfo1.addChangedObject(source); } return rerunnableObjectInfo1; } });
@Test public void testBaseline() { Change dep1 = new ChangeIncremental(tableChangeType, "schema", "tabB", "ch1", 0, "chng1", CONTENT); Change dep2 = new ChangeIncremental(tableChangeType, "schema", "tabB", "ch2", 0, "chng1", CONTENT); Change dep3 = new ChangeIncremental(tableChangeType, "schema", "tabB", "ch3", 0, "chng1", CONTENT); Change srcB = new ChangeIncremental(tableChangeType, "schema", "tabB", "bas1", 0, "chng1", CONTENT) .withBaselines(Lists.mutable.with("ch1", "ch2", "ch3")); Change src4 = new ChangeIncremental(tableChangeType, "schema", "tabB", "ch4", 1, "chng1", CONTENT); ListIterable<ChangeCommand> changeset = cmdCalc.calculateCommands(tableChangeType, Lists.mutable.of( new ChangePair(srcB, null) , new ChangePair(src4, null) , new ChangePair(null, dep1) , new ChangePair(null, dep2) , new ChangePair(null, dep3) ), unusedChangesArg, false); assertEquals(2, changeset.size()); Verify.assertAnySatisfy(changeset, assertValue(DeployChangeCommand.class, src4)); Predicate<ChangeCommand> baselineCommandPredicate = assertValue(BaselineChangeCommand.class, srcB); Verify.assertAnySatisfy(changeset, baselineCommandPredicate); BaselineChangeCommand baselineCommand = (BaselineChangeCommand) changeset.detect(baselineCommandPredicate); assertEquals(Sets.mutable.with(dep1, dep2, dep3), baselineCommand.getReplacedChanges().toSet()); }
@Test public void testIncrementalTableChange() { Change tabB0Dep = new ChangeIncremental(tableChangeType, "schema", "tabB", "b0", 0, "chng1", CONTENT); Change tabB0Src = new ChangeIncremental(tableChangeType, "schema", "tabB", "b0", 0, "chng1", CONTENT); Change tabB1FkSrc = new ChangeIncremental(foreignKeyChangeType, "schema", "tabB", "b1", 1, "chng1.5fk", CONTENT); Change tabB3Dep = new ChangeIncremental(tableChangeType, "schema", "tabB", "b3", 3, "chng3ToBeRolledback1", CONTENT); Change tabB3Src = new ChangeIncremental(tableChangeType, "schema", "tabB", tabB3Dep.getChangeName(), 3, "chng3ToBeRolledback1", CONTENT, "rollback", true); Change tabB4Src = new ChangeIncremental(tableChangeType, "schema", "tabB", "b4", 4, "chng4Insertion", CONTENT); Change tabB5Src = new ChangeIncremental(tableChangeType, "schema", "tabB", "b5", 5, "chng5AlreadyRolledBack", CONTENT, "rollback", true); Change tabB6Dep = new ChangeIncremental(tableChangeType, "schema", "tabB", "b6", 6, "chng6ToBeRolledback2", CONTENT); Change tabB6Src = new ChangeIncremental(tableChangeType, "schema", "tabB", tabB6Dep.getChangeName(), 6, "chng6ToBeRolledback2", CONTENT, "rollback", true); ListIterable<ChangeCommand> changeset = cmdCalc.calculateCommands(tableChangeType, Lists.mutable.of( new ChangePair(tabB0Src, tabB0Dep) , new ChangePair(tabB1FkSrc, null) , new ChangePair(tabB3Src, tabB3Dep) , new ChangePair(tabB4Src, null) , new ChangePair(tabB5Src, null) , new ChangePair(tabB6Src, tabB6Dep) ), unusedChangesArg, false); assertEquals(4, changeset.size()); Verify.assertAnySatisfy(changeset, assertValue(UndeployChangeCommand.class, tabB3Src)); Verify.assertAnySatisfy(changeset, assertValue(DeployChangeCommand.class, tabB4Src)); Verify.assertAnySatisfy(changeset, assertValue(UndeployChangeCommand.class, tabB6Src)); Verify.assertAnySatisfy(changeset, assertValue(DeployChangeCommand.class, tabB1FkSrc)); }
@Test public void testBaselineException() { // In this use case, srcB is the baseline change w/ ch1 ch2 ch3 marked. However, we only see ch1 and ch2 deployed, so we throw an exception Change dep1 = new ChangeIncremental(tableChangeType, "schema", "tabB", "ch1", 0, "chng1", CONTENT); Change dep2 = new ChangeIncremental(tableChangeType, "schema", "tabB", "ch2", 0, "chng1", CONTENT); // hiding dep3 as to show the exception use case //Change dep3 = new ChangeIncremental(tableChangeType, "schema", "tabB", "ch3", 0, "chng1", CONTENT); Change srcB = new ChangeIncremental(tableChangeType, "schema", "tabB", "bas1", 0, "chng1", CONTENT) .withBaselines(Lists.mutable.with("ch1", "ch2", "ch3")); Change src4 = new ChangeIncremental(tableChangeType, "schema", "tabB", "ch4", 1, "chng1", CONTENT); ListIterable<ChangeCommand> changeset = cmdCalc.calculateCommands(tableChangeType, Lists.mutable.of( new ChangePair(srcB, null) , new ChangePair(src4, null) , new ChangePair(null, dep1) , new ChangePair(null, dep2) ), unusedChangesArg, false); assertEquals(2, changeset.size()); Verify.assertAnySatisfy(changeset, assertValue(DeployChangeCommand.class, src4)); Predicate<ChangeCommand> baselineWarningPredicate = assertValue(IncompleteBaselineWarning.class, srcB); Verify.assertAnySatisfy(changeset, baselineWarningPredicate); IncompleteBaselineWarning baselineWarning = (IncompleteBaselineWarning) changeset.detect(baselineWarningPredicate); assertEquals(Sets.mutable.with("ch3"), baselineWarning.getNonDeployedChanges()); }
@Override public RerunnableObjectInfo value(RerunnableObjectInfo rerunnableObjectInfo1, ChangePair changePair) { // TODO make this a bit more OO, e.g. avoid the instanceof all over the place Change source = changePair.getSourceChange(); Change deployed = changePair.getDeployedChange(); if (source == null && deployed == null) { // this branch and exception throwing here is to avoid null deference warnings in findbugs for the next else branch throw new IllegalStateException("This code branch should never happen; either of source or deployed should exist"); } if (source == null && deployed != null) { // In this case - the change exists in the target DB but was removed from the source rerunnableObjectInfo1.addDroppedObject(deployed); } else if (source != null && deployed == null) { rerunnableObjectInfo1.addChangedObject(source); } else if (ObjectUtils.equals(source.getContentHash(), deployed.getContentHash()) || source.getAcceptableHashes().contains(deployed.getContentHash())) { // In this case - the change exists in both the source and target db. // We need to check if anything has changed, using the hash LOG.trace("Nothing to do here; source [{}] and target [{}] match in hash", source, deployed); } else { rerunnableObjectInfo1.addChangedObject(source); } return rerunnableObjectInfo1; } });
@Test public void testBaselineNewAddition() { // dep1, dep2, dep3 are not deployed - hence, we should deploy the baseline we find in the source Change srcB = new ChangeIncremental(tableChangeType, "schema", "tabB", "bas1", 0, "chng1", CONTENT) .withBaselines(Lists.mutable.with("ch1", "ch2", "ch3")); Change src4 = new ChangeIncremental(tableChangeType, "schema", "tabB", "ch4", 1, "chng1", CONTENT); ListIterable<ChangeCommand> changeset = cmdCalc.calculateCommands(tableChangeType, Lists.mutable.of( new ChangePair(srcB, null) , new ChangePair(src4, null) ), unusedChangesArg, false); assertEquals(2, changeset.size()); Verify.assertAnySatisfy(changeset, assertValue(DeployChangeCommand.class, srcB)); Verify.assertAnySatisfy(changeset, assertValue(DeployChangeCommand.class, src4)); }
@Test public void testImproperlyDroppedSourceChange() { Change tabE0Dep = new ChangeIncremental(tableChangeType, "schema", "tabE", "0", 0, "chng0", CONTENT); ListIterable<ChangeCommand> changeset = cmdCalc.calculateCommands(tableChangeType, Lists.mutable.<ChangePair>of( new ChangePair(null, tabE0Dep) ), unusedChangesArg, false); assertEquals(1, changeset.size()); Verify.assertAnySatisfy(changeset, assertValue(ImproperlyRemovedWarning.class, tabE0Dep)); }
@Test public void testNewTableAdd() { Change tabA1Src = new ChangeIncremental(tableChangeType, "schema", "tabA", "new", 0, "chng1", CONTENT); ListIterable<ChangeCommand> changeCommands = cmdCalc.calculateCommands(tableChangeType, Lists.mutable.<ChangePair>of( new ChangePair(tabA1Src, null) ), unusedChangesArg, false); assertEquals(1, changeCommands.size()); Verify.assertAnySatisfy(changeCommands, assertValue(DeployChangeCommand.class, tabA1Src)); }
private void testTableDrops(boolean forceDrop) { Change tabC1Dep = new ChangeIncremental(tableChangeType, "schema", "tabC", "chng1", 0, "tabCExistingToBeDropped", CONTENT); Change tabC1Src = new ChangeIncremental(tableChangeType, "schema", "tabC", tabC1Dep.getChangeName(), 0, "tabCExistingToBeDropped", CONTENT); Change tabC2Src = new ChangeIncremental(tableChangeType, "schema", "tabC", "chng2", 1, "tabCExistingToBeDropped", CONTENT); Change tabC3Src = new ChangeIncremental(tableChangeType, "schema", "tabC", "chng3", 2, "tabCExistingToBeDropped", CONTENT).withDrop(true).withKeepIncrementalOrder(true); Change tabD1Src = new ChangeIncremental(tableChangeType, "schema", "tabD", "cdrop1", 0, "tabDNewTableIsDropped", CONTENT); ChangeIncremental tabD2Src = new ChangeIncremental(tableChangeType, "schema", "tabD", "cdrop2", 1, "tabDNewTableIsDropped", CONTENT).withDrop(true).withKeepIncrementalOrder(true); tabD2Src.setForceDropForEnvCleaning(forceDrop); ListIterable<ChangeCommand> changeset = cmdCalc.calculateCommands(tableChangeType, Lists.mutable.<ChangePair>of( new ChangePair(tabC1Src, tabC1Dep) , new ChangePair(tabC2Src, null) , new ChangePair(tabC3Src, null) , new ChangePair(tabD1Src, null) , new ChangePair(tabD2Src, null) ), unusedChangesArg, false); assertEquals(4, changeset.size()); Verify.assertAnySatisfy(changeset, assertValue(DeployChangeCommand.class, tabC2Src)); Verify.assertAnySatisfy(changeset, assertValue(DropObjectChangeCommand.class, tabC3Src)); if (forceDrop) { // if forceDrop, then ensure that the drops are actually executed Verify.assertAnySatisfy(changeset, assertValue(DeployChangeCommand.class, tabD1Src)); Verify.assertAnySatisfy(changeset, assertValue(DropObjectChangeCommand.class, tabD2Src)); } else { // as tabD was never previously deployed, we should not try to deploy it again Verify.assertAnySatisfy(changeset, assertValue(AlreadyDroppedTableWarning.class, tabD1Src)); Verify.assertAnySatisfy(changeset, assertValue(AlreadyDroppedTableWarning.class, tabD2Src)); } }
@Test public void testSimpleViews() { Change view1Dep = new ChangeRerunnable(viewChangeType(), "schema", "viewA", "hash", CONTENT); Change view1Src = new ChangeRerunnable(viewChangeType(), "schema", "viewA", "hashdiff", CONTENT); Change view2Dep = new ChangeRerunnable(viewChangeType(), "schema", "viewB", "samehash", CONTENT); Change view2Src = new ChangeRerunnable(viewChangeType(), "schema", "viewB", "samehash", CONTENT); Change view3Dep = new ChangeRerunnable(viewChangeType(), "schema", "viewC", "deletion", CONTENT); Change view4Src = new ChangeRerunnable(viewChangeType(), "schema", "viewD", "addition", CONTENT); MutableList<Change> allSourceChanges = Lists.mutable.with( view1Src, view2Src, view4Src ); ListIterable<ChangeCommand> changeset = cmdCalc.calculateCommands(viewChangeType(), Lists.mutable.of( new ChangePair(view1Src, view1Dep) , new ChangePair(view2Src, view2Dep) , new ChangePair(null, view3Dep) , new ChangePair(view4Src, null) ), allSourceChanges, false); assertEquals(3, changeset.size()); Verify.assertAnySatisfy(changeset, assertValue(DeployChangeCommand.class, view1Src)); Verify.assertAnySatisfy(changeset, assertValue(DeployChangeCommand.class, view4Src)); Verify.assertAnySatisfy(changeset, assertValue(DropObjectChangeCommand.class, view3Dep)); }
new ChangePair(tabE0Src, tabE0Dep) , new ChangePair(tabE1Src, tabE1Dep) , new ChangePair(tabE2Src, tabE2Dep) , new ChangePair(tabE3Src, null) , new ChangePair(tabE4Src, null) , new ChangePair(tabE5Src, tabE5Dep) , new ChangePair(tabE6Src, tabE6Dep) ), unusedChangesArg, false);
/** * Same input data as the testImproperDroppedSourceChange test, but this time, we run with rollback. Hence, we allow it to go through * without an exception, btu we log a warning message */ @Test public void testDroppedSourceChangeWithRollback() { ChangeIncremental tabE0Dep = new ChangeIncremental(tableChangeType, "schema", "tabE", "0", 0, "chng0", CONTENT); tabE0Dep.setRollbackActivated(true); ListIterable<ChangeCommand> changeset = cmdCalc.calculateCommands(tableChangeType, Lists.mutable.<ChangePair>of( new ChangePair(null, tabE0Dep) ), unusedChangesArg, false); assertEquals(1, changeset.size()); Verify.assertAnySatisfy(changeset, assertValue(UnrolledbackChangeWarning.class, tabE0Dep)); }