Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -174,11 +174,10 @@ public int doRollbacks(JdbcMigrationContext context, int[] rollbackLevel, boolea
throws SQLException, MigrationException
{
PatchInfoStore patchTable = createPatchStore(context);

int executedPatchCount = 0;
lockPatchStore(context);

// Now apply the patches
int executedPatchCount = 0;
try
{

Expand Down Expand Up @@ -206,7 +205,7 @@ public int doRollbacks(JdbcMigrationContext context, int[] rollbackLevel, boolea
{
// If there was any kind of error, we don't want to eat it, but we do
// want to unlock the patch store. So do that, then re-throw.
patchTable.unlockPatchStore();
unlockPatchStore(patchTable);
throw me;
}

Expand All @@ -220,7 +219,7 @@ public int doRollbacks(JdbcMigrationContext context, int[] rollbackLevel, boolea
{
try
{
patchTable.unlockPatchStore();
unlockPatchStore(patchTable);
}
catch (MigrationException e)
{
Expand Down Expand Up @@ -473,11 +472,10 @@ public LinkedHashMap getContexts()
protected int doMigrations(JdbcMigrationContext context) throws SQLException, MigrationException
{
PatchInfoStore patchTable = createPatchStore(context);

int executedPatchCount = 0;
lockPatchStore(context);

// Now apply the patches
int executedPatchCount = 0;
try
{

Expand Down Expand Up @@ -506,7 +504,7 @@ protected int doMigrations(JdbcMigrationContext context) throws SQLException, Mi
{
// If there was any kind of error, we don't want to eat it, but we do
// want to unlock the patch store. So do that, then re-throw.
patchTable.unlockPatchStore();
unlockPatchStore(patchTable);
throw me;
}

Expand All @@ -520,7 +518,7 @@ protected int doMigrations(JdbcMigrationContext context) throws SQLException, Mi
{
try
{
patchTable.unlockPatchStore();
unlockPatchStore(patchTable);
}
catch (MigrationException e)
{
Expand All @@ -538,6 +536,11 @@ protected int doMigrations(JdbcMigrationContext context) throws SQLException, Mi
*/
private void lockPatchStore(JdbcMigrationContext context) throws MigrationException
{
// Do not issue a lock and write to the database in ReadOnly mode
if (isReadOnly()) {
return;
}

// Patch locks ensure that only one system sharing a patch store will patch
// it at the same time.
boolean lockObtained = false;
Expand All @@ -561,6 +564,21 @@ private void lockPatchStore(JdbcMigrationContext context) throws MigrationExcept
}
}

/**
* Unlock the patch store.
*
* @param patchInfoStore PatchInfoStore to unlock
*/
private void unlockPatchStore(PatchInfoStore patchInfoStore) throws MigrationException
{
// Do not issue an unlock and write to the database in ReadOnly mode
if (isReadOnly()) {
return;
}

patchInfoStore.unlockPatchStore();
}

/**
* create a patch table object for use in migrations
*
Expand Down Expand Up @@ -590,7 +608,7 @@ private void waitForFreeLock(JdbcMigrationContext context) throws MigrationExcep
if ((getLockPollRetries() != -1) && (i >= getLockPollRetries()))
{
log.info("Reached maximum lock poll retries (" + getLockPollRetries() + "), overriding patch lock");
piStore.unlockPatchStore();
unlockPatchStore(piStore);
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import static org.easymock.EasyMock.anyInt;
import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.classextension.EasyMock.createControl;
import static org.easymock.classextension.EasyMock.createStrictControl;

Expand Down Expand Up @@ -66,6 +67,8 @@ public class JdbcMigrationLauncherTest extends MigrationListenerTestBase {
private static final int[] ROLLBACK_LEVELS = new int[]{ROLLBACK_LEVEL};
private static final int ROLLBACK_EXPECTED = 5;
private static final boolean FORCE_ROLLBACK = false;
private static final String MIGRATION = "migration";
private static final String ROLLBACK = "rollback";

/**
* constructor that takes a name
Expand Down Expand Up @@ -124,6 +127,7 @@ protected void setUp() throws Exception {
Connection connectionMock = rollbackMocksControl.createMock(Connection.class);

//Dependency Interactions
expect(rollbackMigrationProcessMock.isReadOnly()).andReturn(false).anyTimes();
expect(patchInfoStoreMock.isPatchStoreLocked()).andReturn(false);
expect(patchInfoStoreMock.getPatchLevel()).andReturn(3);
patchInfoStoreMock.lockPatchStore();
Expand Down Expand Up @@ -487,4 +491,45 @@ public void testDoRollbacksActionWithoutForceRollbackParameter() throws Migratio
rollbackMocksControl.verify();
}

private void runReadOnlyTest(String mode) throws MigrationException{
IMocksControl mockControl = createControl();
TestJdbcMigrationLauncher testLauncher = new TestJdbcMigrationLauncher();

PatchInfoStore patchStore = mockControl.createMock(PatchInfoStore.class);
expect(patchStore.getPatchLevel()).andReturn(ROLLBACK_LEVEL).anyTimes();
MigrationProcess migrationProcess = mockControl.createMock(MigrationProcess.class);
expect(migrationProcess.doMigrations(patchStore, context)).andReturn(0).anyTimes();
expect(migrationProcess.doRollbacks(patchStore, ROLLBACK_LEVELS, context, false)).andReturn(0).anyTimes();
expect(migrationProcess.doPostPatchMigrations(context)).andReturn(0).anyTimes();
migrationProcess.addListener(testLauncher);
expectLastCall().anyTimes();
migrationProcess.addMigrationTaskSource((MigrationTaskSource) EasyMock.anyObject());
expectLastCall().anyTimes();
migrationProcess.setReadOnly(true);
expectLastCall();
expect(migrationProcess.isReadOnly()).andReturn(true).anyTimes();
mockControl.replay();

testLauncher.setMigrationProcess(migrationProcess);
testLauncher.addContext(context);
testLauncher.setPatchStore(patchStore);
testLauncher.getMigrationProcess().setReadOnly(true);

if (mode.equals(MIGRATION)) {
testLauncher.doMigrations();
} else if (mode.equals(ROLLBACK)) {
testLauncher.doRollbacks(ROLLBACK_LEVELS);
} else {
throw new MigrationException("Unsupported mode: " + mode);
}
mockControl.verify();
}

public void testDoMigrationsDoesNotUpdatePatchStoreInReadOnlyMode() throws MigrationException {
runReadOnlyTest(MIGRATION);
}

public void testDoRollbacksDoesNotUpdatePatchStoreInReadOnlyMode() throws MigrationException {
runReadOnlyTest(ROLLBACK);
}
}