{
TesteeSet<T> testeeSet = getTesteeSet(node1, 1, 3);
T testee = testeeSet.impl;
HAPartition partition = testee.getPartition();
LocalLockHandler handler = testee.getLocalHandler();
final RpcTarget target = testeeSet.target;
ClusterNode inferiorNode = testee.getCurrentView().get(2);
assertFalse(node1.equals(inferiorNode));
ClusterNode superiorNode = testee.getCurrentView().get(0);
assertFalse(node1.equals(superiorNode));
resetToStrict(partition);
makeThreadSafe(partition, true);
resetToStrict(handler);
makeThreadSafe(handler, true);
// When caller 1 invokes, block before giving response
CountDownLatch answerAwaitLatch = new CountDownLatch(1);
CountDownLatch answerStartLatch = new CountDownLatch(1);
ArrayList<RemoteLockResponse> rspList = new ArrayList<RemoteLockResponse>();
rspList.add(new RemoteLockResponse(superiorNode, RemoteLockResponse.Flag.OK));
rspList.add(new RemoteLockResponse(inferiorNode, RemoteLockResponse.Flag.REJECT, inferiorNode));
BlockingAnswer<ArrayList<RemoteLockResponse>> caller1Answer =
new BlockingAnswer<ArrayList<RemoteLockResponse>>(rspList, answerAwaitLatch, answerStartLatch, null);
expect(partition.callMethodOnCluster(eq("test"),
eq("remoteLock"),
eqLockParams(node1, 200000),
aryEq(AbstractClusterLockSupport.REMOTE_LOCK_TYPES),
eq(true))).andAnswer(caller1Answer);
expect(partition.callMethodOnCluster(eq("test"),
eq("releaseRemoteLock"),
aryEq(new Object[]{"test", node1}),
aryEq(AbstractClusterLockSupport.RELEASE_REMOTE_LOCK_TYPES),
eq(true))).andReturn(new ArrayList<Object>());
rspList = new ArrayList<RemoteLockResponse>();
rspList.add(new RemoteLockResponse(superiorNode, RemoteLockResponse.Flag.OK));
rspList.add(new RemoteLockResponse(inferiorNode, RemoteLockResponse.Flag.OK));
expect(partition.callMethodOnCluster(eq("test"),
eq("remoteLock"),
eqLockParams(node1, 200000),
aryEq(AbstractClusterLockSupport.REMOTE_LOCK_TYPES),
eq(true))).andReturn(rspList);
handler.lockFromCluster(eq("test"), eq(node1), anyLong());
replay(partition);
replay(handler);
CountDownLatch finishedLatch = new CountDownLatch(1);
LocalLockCaller winner = new LocalLockCaller(testee, null, null, finishedLatch);
Thread t1 = new Thread(winner);
t1.setDaemon(true);
try
{
t1.start();
assertTrue(answerStartLatch.await(1, TimeUnit.SECONDS));
// t1 should now be blocking in caller1Answer
RemoteLockResponse rsp = target.remoteLock("test", inferiorNode, 1);
assertEquals(RemoteLockResponse.Flag.REJECT, rsp.flag);
assertEquals(node1, rsp.holder);
// release t1
answerAwaitLatch.countDown();