mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
ACS-9259 Improve stability of HazelcastLockStoreTxTest test (#3248)
This commit is contained in:
@@ -25,29 +25,30 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.lock.mem;
|
package org.alfresco.repo.lock.mem;
|
||||||
|
|
||||||
import java.util.Date;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
import jakarta.transaction.NotSupportedException;
|
import jakarta.transaction.NotSupportedException;
|
||||||
import jakarta.transaction.SystemException;
|
import jakarta.transaction.SystemException;
|
||||||
import jakarta.transaction.UserTransaction;
|
import jakarta.transaction.UserTransaction;
|
||||||
|
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
|
||||||
import org.alfresco.service.cmr.lock.LockType;
|
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
|
||||||
import org.alfresco.service.transaction.TransactionService;
|
|
||||||
import org.alfresco.util.ApplicationContextHelper;
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.dao.ConcurrencyFailureException;
|
import org.springframework.dao.ConcurrencyFailureException;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
import static org.junit.Assert.assertNull;
|
import org.alfresco.service.cmr.lock.LockType;
|
||||||
import static org.junit.Assert.fail;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.transaction.TransactionService;
|
||||||
|
import org.alfresco.util.ApplicationContextHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Integration tests that check transaction related functionality of {@link LockStore} implementations.
|
* Integration tests that check transaction related functionality of {@link LockStore} implementations.
|
||||||
|
*
|
||||||
* @author Matt Ward
|
* @author Matt Ward
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractLockStoreTxTest<T extends LockStore>
|
public abstract class AbstractLockStoreTxTest<T extends LockStore>
|
||||||
@@ -82,10 +83,10 @@ public abstract class AbstractLockStoreTxTest<T extends LockStore>
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>Start outer txn</li>
|
* <li>Start outer txn</li>
|
||||||
* <li>Modify lock in outer txn</li>
|
* <li>Modify lock in outer txn</li>
|
||||||
* <li>Start inner txn</li>
|
* <li>Start inner txn</li>
|
||||||
* <li>Modify lock in inner txn</li>
|
* <li>Modify lock in inner txn</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* Inner transaction should fail while outer succeeds
|
* Inner transaction should fail while outer succeeds
|
||||||
*/
|
*/
|
||||||
@@ -106,11 +107,9 @@ public abstract class AbstractLockStoreTxTest<T extends LockStore>
|
|||||||
Date now = new Date();
|
Date now = new Date();
|
||||||
Date expires = new Date(now.getTime() + 180000);
|
Date expires = new Date(now.getTime() + 180000);
|
||||||
final LockState lockState1 = LockState.createLock(nodeRef, LockType.WRITE_LOCK,
|
final LockState lockState1 = LockState.createLock(nodeRef, LockType.WRITE_LOCK,
|
||||||
"jbloggs", expires, Lifetime.EPHEMERAL, null);
|
"jbloggs", expires, Lifetime.EPHEMERAL, null);
|
||||||
|
|
||||||
|
Thread txB = new Thread("TxB") {
|
||||||
Thread txB = new Thread("TxB")
|
|
||||||
{
|
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
{
|
{
|
||||||
@@ -138,7 +137,7 @@ public abstract class AbstractLockStoreTxTest<T extends LockStore>
|
|||||||
|
|
||||||
// txB sets a value, already seen as non-existent lock by txA
|
// txB sets a value, already seen as non-existent lock by txA
|
||||||
lockStore.set(nodeRef2, LockState.createLock(nodeRef2, LockType.WRITE_LOCK,
|
lockStore.set(nodeRef2, LockState.createLock(nodeRef2, LockType.WRITE_LOCK,
|
||||||
"csmith", null, Lifetime.EPHEMERAL, null));
|
"csmith", null, Lifetime.EPHEMERAL, null));
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@@ -152,7 +151,7 @@ public abstract class AbstractLockStoreTxTest<T extends LockStore>
|
|||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
// Stop 'main' from waiting
|
// Stop 'main' from waiting
|
||||||
synchronized(main)
|
synchronized (main)
|
||||||
{
|
{
|
||||||
main.notifyAll();
|
main.notifyAll();
|
||||||
}
|
}
|
||||||
@@ -166,6 +165,9 @@ public abstract class AbstractLockStoreTxTest<T extends LockStore>
|
|||||||
// txA set lock state 1
|
// txA set lock state 1
|
||||||
lockStore.set(nodeRef, lockState1);
|
lockStore.set(nodeRef, lockState1);
|
||||||
|
|
||||||
|
// Perform a read, that we know will retrieve a null value (and null will be cached for this transaction)
|
||||||
|
assertNull("nodeRef2 LockState", lockStore.get(nodeRef2));
|
||||||
|
|
||||||
// Wait while txB reads and checks the LockState
|
// Wait while txB reads and checks the LockState
|
||||||
txB.setDaemon(true);
|
txB.setDaemon(true);
|
||||||
txB.start();
|
txB.start();
|
||||||
@@ -186,13 +188,10 @@ public abstract class AbstractLockStoreTxTest<T extends LockStore>
|
|||||||
// Check we can see the update.
|
// Check we can see the update.
|
||||||
assertEquals("bsmith", lockStore.get(nodeRef).getOwner());
|
assertEquals("bsmith", lockStore.get(nodeRef).getOwner());
|
||||||
|
|
||||||
// Perform a read, that we know will retrieve a null value
|
|
||||||
assertNull("nodeRef2 LockState", lockStore.get(nodeRef2));
|
|
||||||
|
|
||||||
// Wait while txB populates the store with a value for nodeRef2
|
// Wait while txB populates the store with a value for nodeRef2
|
||||||
passControl(this, txB);
|
passControl(this, txB);
|
||||||
|
|
||||||
// Perform the read again - update should not be visible in this transaction
|
// Perform the read again - update should not be visible in this transaction (was already cached)
|
||||||
assertNull("nodeRef2 LockState", lockStore.get(nodeRef2));
|
assertNull("nodeRef2 LockState", lockStore.get(nodeRef2));
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
@@ -203,16 +202,16 @@ public abstract class AbstractLockStoreTxTest<T extends LockStore>
|
|||||||
|
|
||||||
protected void passControl(Object from, Object to)
|
protected void passControl(Object from, Object to)
|
||||||
{
|
{
|
||||||
synchronized(to)
|
synchronized (to)
|
||||||
{
|
{
|
||||||
to.notifyAll();
|
to.notifyAll();
|
||||||
}
|
}
|
||||||
synchronized(from)
|
synchronized (from)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// TODO: wait should be called in a loop with repeated wait condition check,
|
// TODO: wait should be called in a loop with repeated wait condition check,
|
||||||
// but what's the condition we're waiting on?
|
// but what's the condition we're waiting on?
|
||||||
from.wait(10000);
|
from.wait(10000);
|
||||||
}
|
}
|
||||||
catch (InterruptedException error)
|
catch (InterruptedException error)
|
||||||
@@ -231,11 +230,9 @@ public abstract class AbstractLockStoreTxTest<T extends LockStore>
|
|||||||
Date now = new Date();
|
Date now = new Date();
|
||||||
Date expires = new Date(now.getTime() + 180000);
|
Date expires = new Date(now.getTime() + 180000);
|
||||||
final LockState lockState1 = LockState.createLock(nodeRef, LockType.WRITE_LOCK,
|
final LockState lockState1 = LockState.createLock(nodeRef, LockType.WRITE_LOCK,
|
||||||
"jbloggs", expires, Lifetime.EPHEMERAL, null);
|
"jbloggs", expires, Lifetime.EPHEMERAL, null);
|
||||||
|
|
||||||
|
Thread txB = new Thread("TxB") {
|
||||||
Thread txB = new Thread("TxB")
|
|
||||||
{
|
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
{
|
{
|
||||||
@@ -260,7 +257,7 @@ public abstract class AbstractLockStoreTxTest<T extends LockStore>
|
|||||||
// when it has been modified by another tx since this tx last inspected it.
|
// when it has been modified by another tx since this tx last inspected it.
|
||||||
AuthenticationUtil.setFullyAuthenticatedUser("jbloggs"); // Current lock owner
|
AuthenticationUtil.setFullyAuthenticatedUser("jbloggs"); // Current lock owner
|
||||||
lockStore.set(nodeRef, LockState.createLock(nodeRef, LockType.WRITE_LOCK,
|
lockStore.set(nodeRef, LockState.createLock(nodeRef, LockType.WRITE_LOCK,
|
||||||
"csmith", null, Lifetime.EPHEMERAL, null));
|
"csmith", null, Lifetime.EPHEMERAL, null));
|
||||||
fail("Exception should have been thrown but was not.");
|
fail("Exception should have been thrown but was not.");
|
||||||
}
|
}
|
||||||
catch (ConcurrencyFailureException e)
|
catch (ConcurrencyFailureException e)
|
||||||
@@ -280,7 +277,7 @@ public abstract class AbstractLockStoreTxTest<T extends LockStore>
|
|||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
// Stop 'main' from waiting
|
// Stop 'main' from waiting
|
||||||
synchronized(main)
|
synchronized (main)
|
||||||
{
|
{
|
||||||
main.notifyAll();
|
main.notifyAll();
|
||||||
}
|
}
|
||||||
@@ -325,12 +322,11 @@ public abstract class AbstractLockStoreTxTest<T extends LockStore>
|
|||||||
final Date now = new Date();
|
final Date now = new Date();
|
||||||
Date expired = new Date(now.getTime() - 180000);
|
Date expired = new Date(now.getTime() - 180000);
|
||||||
final LockState lockState1 = LockState.createLock(nodeRef, LockType.WRITE_LOCK,
|
final LockState lockState1 = LockState.createLock(nodeRef, LockType.WRITE_LOCK,
|
||||||
"jbloggs", expired, Lifetime.EPHEMERAL, null);
|
"jbloggs", expired, Lifetime.EPHEMERAL, null);
|
||||||
|
|
||||||
final LockState lockState2 = LockState.createWithOwner(lockState1, "another");
|
final LockState lockState2 = LockState.createWithOwner(lockState1, "another");
|
||||||
|
|
||||||
Thread txB = new Thread("TxB")
|
Thread txB = new Thread("TxB") {
|
||||||
{
|
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
{
|
{
|
||||||
@@ -351,7 +347,7 @@ public abstract class AbstractLockStoreTxTest<T extends LockStore>
|
|||||||
// (but not since this tx's initial read)
|
// (but not since this tx's initial read)
|
||||||
Date expiresFuture = new Date(now.getTime() + 180000);
|
Date expiresFuture = new Date(now.getTime() + 180000);
|
||||||
final LockState newUserLockState = LockState.createLock(nodeRef, LockType.WRITE_LOCK,
|
final LockState newUserLockState = LockState.createLock(nodeRef, LockType.WRITE_LOCK,
|
||||||
"new-user", expiresFuture, Lifetime.EPHEMERAL, null);
|
"new-user", expiresFuture, Lifetime.EPHEMERAL, null);
|
||||||
lockStore.set(nodeRef, newUserLockState);
|
lockStore.set(nodeRef, newUserLockState);
|
||||||
|
|
||||||
// Read
|
// Read
|
||||||
@@ -369,7 +365,7 @@ public abstract class AbstractLockStoreTxTest<T extends LockStore>
|
|||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
// Stop 'main' from waiting
|
// Stop 'main' from waiting
|
||||||
synchronized(main)
|
synchronized (main)
|
||||||
{
|
{
|
||||||
main.notifyAll();
|
main.notifyAll();
|
||||||
}
|
}
|
||||||
@@ -404,7 +400,6 @@ public abstract class AbstractLockStoreTxTest<T extends LockStore>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNotOnlyCurrentLockOwnerCanChangeInfo() throws NotSupportedException, SystemException
|
public void testNotOnlyCurrentLockOwnerCanChangeInfo() throws NotSupportedException, SystemException
|
||||||
{
|
{
|
||||||
@@ -414,7 +409,7 @@ public abstract class AbstractLockStoreTxTest<T extends LockStore>
|
|||||||
Date now = new Date();
|
Date now = new Date();
|
||||||
Date expires = new Date(now.getTime() + 180000);
|
Date expires = new Date(now.getTime() + 180000);
|
||||||
final LockState lockState1 = LockState.createLock(nodeRef, LockType.WRITE_LOCK,
|
final LockState lockState1 = LockState.createLock(nodeRef, LockType.WRITE_LOCK,
|
||||||
"jbloggs", expires, Lifetime.EPHEMERAL, null);
|
"jbloggs", expires, Lifetime.EPHEMERAL, null);
|
||||||
|
|
||||||
txA.begin();
|
txA.begin();
|
||||||
try
|
try
|
||||||
@@ -455,7 +450,7 @@ public abstract class AbstractLockStoreTxTest<T extends LockStore>
|
|||||||
Date now = new Date();
|
Date now = new Date();
|
||||||
Date expired = new Date(now.getTime() - 900);
|
Date expired = new Date(now.getTime() - 900);
|
||||||
final LockState lockState1 = LockState.createLock(nodeRef, LockType.WRITE_LOCK,
|
final LockState lockState1 = LockState.createLock(nodeRef, LockType.WRITE_LOCK,
|
||||||
"jbloggs", expired, Lifetime.EPHEMERAL, null);
|
"jbloggs", expired, Lifetime.EPHEMERAL, null);
|
||||||
|
|
||||||
txA.begin();
|
txA.begin();
|
||||||
try
|
try
|
||||||
@@ -469,7 +464,7 @@ public abstract class AbstractLockStoreTxTest<T extends LockStore>
|
|||||||
AuthenticationUtil.setFullyAuthenticatedUser("csmith");
|
AuthenticationUtil.setFullyAuthenticatedUser("csmith");
|
||||||
Date expiresFuture = new Date(now.getTime() + 180000);
|
Date expiresFuture = new Date(now.getTime() + 180000);
|
||||||
final LockState lockState2 = LockState.createLock(nodeRef, LockType.WRITE_LOCK,
|
final LockState lockState2 = LockState.createLock(nodeRef, LockType.WRITE_LOCK,
|
||||||
"csmith", expiresFuture, Lifetime.EPHEMERAL, null);
|
"csmith", expiresFuture, Lifetime.EPHEMERAL, null);
|
||||||
lockStore.set(nodeRef, lockState2);
|
lockStore.set(nodeRef, lockState2);
|
||||||
|
|
||||||
// Updated, since lock had expired.
|
// Updated, since lock had expired.
|
||||||
|
Reference in New Issue
Block a user