/*
* Copyright Terracotta, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.ehcache.clustered.lock.server;
import org.ehcache.clustered.common.internal.lock.LockMessaging;
import org.ehcache.clustered.common.internal.lock.LockMessaging.LockTransition;
import org.hamcrest.beans.HasPropertyWithValue;
import org.junit.Test;
import org.mockito.Matchers;
import org.terracotta.entity.ClientCommunicator;
import org.terracotta.entity.ClientDescriptor;
import org.terracotta.entity.EntityResponse;
import org.terracotta.entity.MessageCodecException;
import static org.ehcache.clustered.common.internal.lock.LockMessaging.HoldType.READ;
import static org.ehcache.clustered.common.internal.lock.LockMessaging.HoldType.WRITE;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
public class VoltronReadWriteLockActiveEntityTest {
@Test
public void testWriteLock() {
ClientCommunicator communicator = mock(ClientCommunicator.class);
VoltronReadWriteLockActiveEntity entity = new VoltronReadWriteLockActiveEntity(communicator);
ClientDescriptor client = mock(ClientDescriptor.class);
LockTransition transition = entity.invoke(client, LockMessaging.lock(WRITE));
assertThat(transition.isAcquired(), is(true));
}
@Test
public void testReadLock() {
ClientCommunicator communicator = mock(ClientCommunicator.class);
VoltronReadWriteLockActiveEntity entity = new VoltronReadWriteLockActiveEntity(communicator);
ClientDescriptor client = mock(ClientDescriptor.class);
LockTransition transition = entity.invoke(client, LockMessaging.lock(READ));
assertThat(transition.isAcquired(), is(true));
}
@Test
public void testWriteUnlock() {
ClientCommunicator communicator = mock(ClientCommunicator.class);
VoltronReadWriteLockActiveEntity entity = new VoltronReadWriteLockActiveEntity(communicator);
ClientDescriptor client = mock(ClientDescriptor.class);
entity.invoke(client, LockMessaging.lock(WRITE));
LockTransition transition = entity.invoke(client, LockMessaging.unlock(WRITE));
assertThat(transition.isReleased(), is(true));
}
@Test
public void testReadUnlock() {
ClientCommunicator communicator = mock(ClientCommunicator.class);
VoltronReadWriteLockActiveEntity entity = new VoltronReadWriteLockActiveEntity(communicator);
ClientDescriptor client = mock(ClientDescriptor.class);
entity.invoke(client, LockMessaging.lock(READ));
LockTransition transition = entity.invoke(client, LockMessaging.unlock(READ));
assertThat(transition.isReleased(), is(true));
}
@Test
public void testTryWriteLockWhenWriteLocked() {
ClientCommunicator communicator = mock(ClientCommunicator.class);
VoltronReadWriteLockActiveEntity entity = new VoltronReadWriteLockActiveEntity(communicator);
entity.invoke(mock(ClientDescriptor.class), LockMessaging.lock(WRITE));
LockTransition transition = entity.invoke(mock(ClientDescriptor.class), LockMessaging.tryLock(WRITE));
assertThat(transition.isAcquired(), is(false));
}
@Test
public void testTryReadLockWhenWriteLocked() {
ClientCommunicator communicator = mock(ClientCommunicator.class);
VoltronReadWriteLockActiveEntity entity = new VoltronReadWriteLockActiveEntity(communicator);
entity.invoke(mock(ClientDescriptor.class), LockMessaging.lock(WRITE));
LockTransition transition = entity.invoke(mock(ClientDescriptor.class), LockMessaging.tryLock(READ));
assertThat(transition.isAcquired(), is(false));
}
@Test
public void testTryWriteLockWhenReadLocked() {
ClientCommunicator communicator = mock(ClientCommunicator.class);
VoltronReadWriteLockActiveEntity entity = new VoltronReadWriteLockActiveEntity(communicator);
entity.invoke(mock(ClientDescriptor.class), LockMessaging.lock(READ));
LockTransition transition = entity.invoke(mock(ClientDescriptor.class), LockMessaging.tryLock(WRITE));
assertThat(transition.isAcquired(), is(false));
}
@Test
public void testTryReadLockWhenReadLocked() {
ClientCommunicator communicator = mock(ClientCommunicator.class);
VoltronReadWriteLockActiveEntity entity = new VoltronReadWriteLockActiveEntity(communicator);
entity.invoke(mock(ClientDescriptor.class), LockMessaging.lock(READ));
LockTransition transition = entity.invoke(mock(ClientDescriptor.class), LockMessaging.tryLock(READ));
assertThat(transition.isAcquired(), is(true));
}
@Test
public void testWriteUnlockNotifiesListeners() throws MessageCodecException {
ClientCommunicator communicator = mock(ClientCommunicator.class);
VoltronReadWriteLockActiveEntity entity = new VoltronReadWriteLockActiveEntity(communicator);
ClientDescriptor locker = mock(ClientDescriptor.class);
ClientDescriptor waiter = mock(ClientDescriptor.class);
entity.invoke(locker, LockMessaging.lock(WRITE));
entity.invoke(waiter, LockMessaging.lock(WRITE));
entity.invoke(locker, LockMessaging.unlock(WRITE));
verify(communicator).sendNoResponse(eq(waiter), Matchers.<EntityResponse>argThat(
HasPropertyWithValue.<EntityResponse>hasProperty("released", is(true))));
}
@Test
public void testReadUnlockNotifiesListeners() throws MessageCodecException {
ClientCommunicator communicator = mock(ClientCommunicator.class);
VoltronReadWriteLockActiveEntity entity = new VoltronReadWriteLockActiveEntity(communicator);
ClientDescriptor locker = mock(ClientDescriptor.class);
ClientDescriptor waiter = mock(ClientDescriptor.class);
entity.invoke(locker, LockMessaging.lock(READ));
entity.invoke(waiter, LockMessaging.lock(WRITE));
entity.invoke(locker, LockMessaging.unlock(READ));
verify(communicator).sendNoResponse(eq(waiter), Matchers.<EntityResponse>argThat(
HasPropertyWithValue.<EntityResponse>hasProperty("released", is(true))));
}
}