/* * 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.client.internal.lock; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.terracotta.connection.Connection; import org.terracotta.connection.entity.EntityRef; 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.IsNull.notNullValue; import static org.hamcrest.core.IsNull.nullValue; import static org.junit.Assert.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import org.terracotta.exception.EntityAlreadyExistsException; public class VoltronReadWriteLockTest { @Mock private VoltronReadWriteLockClient client; @Mock private EntityRef<VoltronReadWriteLockClient, Void, Void> entityRef; @Mock private Connection connection; @Before public void setUp() { MockitoAnnotations.initMocks(this); } @Test public void testCreateLockEntityWhenNotExisting() throws Exception { when(entityRef.fetchEntity(null)).thenReturn(client); when(connection.<VoltronReadWriteLockClient, Void, Void>getEntityRef(VoltronReadWriteLockClient.class, 1, "VoltronReadWriteLock-TestLock")).thenReturn(entityRef); VoltronReadWriteLock lock = new VoltronReadWriteLock(connection, "TestLock"); lock.readLock(); verify(entityRef).create(any(Void.class)); } @Test public void testFetchExistingLockEntityWhenExists() throws Exception { doThrow(EntityAlreadyExistsException.class).when(entityRef).create(any(Void.class)); when(entityRef.fetchEntity(null)).thenReturn(client); when(connection.<VoltronReadWriteLockClient, Void, Void>getEntityRef(VoltronReadWriteLockClient.class, 1, "VoltronReadWriteLock-TestLock")).thenReturn(entityRef); VoltronReadWriteLock lock = new VoltronReadWriteLock(connection, "TestLock"); lock.readLock(); } @Test public void testWriteLockLocksWrite() throws Exception { when(entityRef.fetchEntity(null)).thenReturn(client); when(connection.<VoltronReadWriteLockClient, Void, Void>getEntityRef(VoltronReadWriteLockClient.class, 1, "VoltronReadWriteLock-TestLock")).thenReturn(entityRef); VoltronReadWriteLock lock = new VoltronReadWriteLock(connection, "TestLock"); lock.writeLock(); verify(client).lock(WRITE); } @Test public void testReadLockLocksRead() throws Exception { when(entityRef.fetchEntity(null)).thenReturn(client); when(connection.<VoltronReadWriteLockClient, Void, Void>getEntityRef(VoltronReadWriteLockClient.class, 1, "VoltronReadWriteLock-TestLock")).thenReturn(entityRef); VoltronReadWriteLock lock = new VoltronReadWriteLock(connection, "TestLock"); lock.readLock(); verify(client).lock(READ); } @Test public void testWriteUnlockUnlocksWrite() throws Exception { when(entityRef.fetchEntity(null)).thenReturn(client); when(connection.<VoltronReadWriteLockClient, Void, Void>getEntityRef(VoltronReadWriteLockClient.class, 1, "VoltronReadWriteLock-TestLock")).thenReturn(entityRef); VoltronReadWriteLock lock = new VoltronReadWriteLock(connection, "TestLock"); lock.writeLock().unlock(); verify(client).unlock(WRITE); } @Test public void testReadUnlockUnlocksRead() throws Exception { when(entityRef.fetchEntity(null)).thenReturn(client); when(connection.<VoltronReadWriteLockClient, Void, Void>getEntityRef(VoltronReadWriteLockClient.class, 1, "VoltronReadWriteLock-TestLock")).thenReturn(entityRef); VoltronReadWriteLock lock = new VoltronReadWriteLock(connection, "TestLock"); lock.readLock().unlock(); verify(client).unlock(READ); } @Test public void testWriteUnlockClosesEntity() throws Exception { when(entityRef.fetchEntity(null)).thenReturn(client); when(connection.<VoltronReadWriteLockClient, Void, Void>getEntityRef(VoltronReadWriteLockClient.class, 1, "VoltronReadWriteLock-TestLock")).thenReturn(entityRef); VoltronReadWriteLock lock = new VoltronReadWriteLock(connection, "TestLock"); lock.writeLock().unlock(); verify(client).close(); } @Test public void testReadUnlockClosesEntity() throws Exception { when(entityRef.fetchEntity(null)).thenReturn(client); when(connection.<VoltronReadWriteLockClient, Void, Void>getEntityRef(VoltronReadWriteLockClient.class, 1, "VoltronReadWriteLock-TestLock")).thenReturn(entityRef); VoltronReadWriteLock lock = new VoltronReadWriteLock(connection, "TestLock"); lock.readLock().unlock(); verify(client).close(); } @Test public void testWriteUnlockDestroysEntity() throws Exception { when(entityRef.fetchEntity(null)).thenReturn(client); when(connection.<VoltronReadWriteLockClient, Void, Void>getEntityRef(VoltronReadWriteLockClient.class, 1, "VoltronReadWriteLock-TestLock")).thenReturn(entityRef); VoltronReadWriteLock lock = new VoltronReadWriteLock(connection, "TestLock"); lock.writeLock().unlock(); verify(entityRef).destroy(); } @Test public void testReadUnlockDestroysEntity() throws Exception { when(entityRef.fetchEntity(null)).thenReturn(client); when(connection.<VoltronReadWriteLockClient, Void, Void>getEntityRef(VoltronReadWriteLockClient.class, 1, "VoltronReadWriteLock-TestLock")).thenReturn(entityRef); VoltronReadWriteLock lock = new VoltronReadWriteLock(connection, "TestLock"); lock.readLock().unlock(); verify(entityRef).destroy(); } @Test public void testTryWriteLockTryLocksWrite() throws Exception { when(client.tryLock(WRITE)).thenReturn(true); when(entityRef.fetchEntity(null)).thenReturn(client); when(connection.<VoltronReadWriteLockClient, Void, Void>getEntityRef(VoltronReadWriteLockClient.class, 1, "VoltronReadWriteLock-TestLock")).thenReturn(entityRef); VoltronReadWriteLock lock = new VoltronReadWriteLock(connection, "TestLock"); assertThat(lock.tryWriteLock(), notNullValue()); verify(client).tryLock(WRITE); } @Test public void testTryReadLockTryLocksRead() throws Exception { when(client.tryLock(READ)).thenReturn(true); when(entityRef.fetchEntity(null)).thenReturn(client); when(connection.<VoltronReadWriteLockClient, Void, Void>getEntityRef(VoltronReadWriteLockClient.class, 1, "VoltronReadWriteLock-TestLock")).thenReturn(entityRef); VoltronReadWriteLock lock = new VoltronReadWriteLock(connection, "TestLock"); assertThat(lock.tryReadLock(), notNullValue()); verify(client).tryLock(READ); } @Test public void testTryWriteUnlockUnlocksWrite() throws Exception { when(client.tryLock(WRITE)).thenReturn(true); when(entityRef.fetchEntity(null)).thenReturn(client); when(connection.<VoltronReadWriteLockClient, Void, Void>getEntityRef(VoltronReadWriteLockClient.class, 1, "VoltronReadWriteLock-TestLock")).thenReturn(entityRef); VoltronReadWriteLock lock = new VoltronReadWriteLock(connection, "TestLock"); lock.tryWriteLock().unlock(); verify(client).unlock(WRITE); } @Test public void testTryReadUnlockUnlocksRead() throws Exception { when(client.tryLock(READ)).thenReturn(true); when(entityRef.fetchEntity(null)).thenReturn(client); when(connection.<VoltronReadWriteLockClient, Void, Void>getEntityRef(VoltronReadWriteLockClient.class, 1, "VoltronReadWriteLock-TestLock")).thenReturn(entityRef); VoltronReadWriteLock lock = new VoltronReadWriteLock(connection, "TestLock"); lock.tryReadLock().unlock(); verify(client).unlock(READ); } @Test public void testTryWriteUnlockClosesEntity() throws Exception { when(client.tryLock(WRITE)).thenReturn(true); when(entityRef.fetchEntity(null)).thenReturn(client); when(connection.<VoltronReadWriteLockClient, Void, Void>getEntityRef(VoltronReadWriteLockClient.class, 1, "VoltronReadWriteLock-TestLock")).thenReturn(entityRef); VoltronReadWriteLock lock = new VoltronReadWriteLock(connection, "TestLock"); lock.tryWriteLock().unlock(); verify(client).close(); } @Test public void testTryReadUnlockClosesEntity() throws Exception { when(client.tryLock(READ)).thenReturn(true); when(entityRef.fetchEntity(null)).thenReturn(client); when(connection.<VoltronReadWriteLockClient, Void, Void>getEntityRef(VoltronReadWriteLockClient.class, 1, "VoltronReadWriteLock-TestLock")).thenReturn(entityRef); VoltronReadWriteLock lock = new VoltronReadWriteLock(connection, "TestLock"); lock.tryReadLock().unlock(); verify(client).close(); } @Test public void testTryWriteUnlockDestroysEntity() throws Exception { when(client.tryLock(WRITE)).thenReturn(true); when(entityRef.fetchEntity(null)).thenReturn(client); when(connection.<VoltronReadWriteLockClient, Void, Void>getEntityRef(VoltronReadWriteLockClient.class, 1, "VoltronReadWriteLock-TestLock")).thenReturn(entityRef); VoltronReadWriteLock lock = new VoltronReadWriteLock(connection, "TestLock"); lock.tryWriteLock().unlock(); verify(entityRef).destroy(); } @Test public void testTryReadUnlockDestroysEntity() throws Exception { when(client.tryLock(READ)).thenReturn(true); when(entityRef.fetchEntity(null)).thenReturn(client); when(connection.<VoltronReadWriteLockClient, Void, Void>getEntityRef(VoltronReadWriteLockClient.class, 1, "VoltronReadWriteLock-TestLock")).thenReturn(entityRef); VoltronReadWriteLock lock = new VoltronReadWriteLock(connection, "TestLock"); lock.tryReadLock().unlock(); verify(entityRef).destroy(); } @Test public void testTryWriteLockFailingClosesEntity() throws Exception { when(client.tryLock(WRITE)).thenReturn(false); when(entityRef.fetchEntity(null)).thenReturn(client); when(connection.<VoltronReadWriteLockClient, Void, Void>getEntityRef(VoltronReadWriteLockClient.class, 1, "VoltronReadWriteLock-TestLock")).thenReturn(entityRef); VoltronReadWriteLock lock = new VoltronReadWriteLock(connection, "TestLock"); assertThat(lock.tryWriteLock(), nullValue()); verify(client).close(); } @Test public void testTryReadLockFailingClosesEntity() throws Exception { when(client.tryLock(READ)).thenReturn(false); when(entityRef.fetchEntity(null)).thenReturn(client); when(connection.<VoltronReadWriteLockClient, Void, Void>getEntityRef(VoltronReadWriteLockClient.class, 1, "VoltronReadWriteLock-TestLock")).thenReturn(entityRef); VoltronReadWriteLock lock = new VoltronReadWriteLock(connection, "TestLock"); assertThat(lock.tryReadLock(), nullValue()); verify(client).close(); } @Test public void testTryWriteLockFailingDestroysEntity() throws Exception { when(client.tryLock(WRITE)).thenReturn(false); when(entityRef.fetchEntity(null)).thenReturn(client); when(connection.<VoltronReadWriteLockClient, Void, Void>getEntityRef(VoltronReadWriteLockClient.class, 1, "VoltronReadWriteLock-TestLock")).thenReturn(entityRef); VoltronReadWriteLock lock = new VoltronReadWriteLock(connection, "TestLock"); assertThat(lock.tryWriteLock(), nullValue()); verify(entityRef).destroy(); } @Test public void testTryReadLockFailingDestroysEntity() throws Exception { when(client.tryLock(READ)).thenReturn(false); when(entityRef.fetchEntity(null)).thenReturn(client); when(connection.<VoltronReadWriteLockClient, Void, Void>getEntityRef(VoltronReadWriteLockClient.class, 1, "VoltronReadWriteLock-TestLock")).thenReturn(entityRef); VoltronReadWriteLock lock = new VoltronReadWriteLock(connection, "TestLock"); assertThat(lock.tryReadLock(), nullValue()); verify(entityRef).destroy(); } }