package io.cattle.platform.lock.impl; import static org.junit.Assert.*; import static org.mockito.Mockito.*; import io.cattle.platform.lock.Lock; import io.cattle.platform.lock.LockCallback; import io.cattle.platform.lock.LockCallbackNoReturn; import io.cattle.platform.lock.LockCallbackWithException; import io.cattle.platform.lock.definition.LockDefinition; import io.cattle.platform.lock.definition.MultiLockDefinition; import io.cattle.platform.lock.exception.FailedToAcquireLockException; import io.cattle.platform.lock.provider.LockProvider; import java.io.FileNotFoundException; import java.util.concurrent.atomic.AtomicInteger; import org.junit.Before; import org.junit.Test; public class LockManagerImplTest { LockProvider lockProvider; LockManagerImpl lockManager; LockDefinition goodLockDef = new TestLockDefinition("good"); LockDefinition good2LockDef = new TestLockDefinition("good2"); LockDefinition badLockDef = new TestLockDefinition("bad"); Lock goodLock = LockTestUtils.goodLock(goodLockDef); Lock good2Lock = LockTestUtils.goodLock(good2LockDef); Lock badLock = LockTestUtils.badLock(badLockDef); @Before public void setUp() { lockProvider = mock(LockProvider.class); when(lockProvider.getLock(goodLockDef)).thenReturn(goodLock); when(lockProvider.getLock(good2LockDef)).thenReturn(good2Lock); when(lockProvider.getLock(badLockDef)).thenReturn(badLock); lockManager = new LockManagerImpl(); lockManager.setLockProvider(lockProvider); } @Test public void test_bad_multilock() { MultiLockDefinition def = new TestMultiLockDefinition(goodLockDef, badLockDef, good2LockDef); try { lockManager.lock(def, new LockCallbackNoReturn() { @Override public void doWithLockNoResult() { fail(); } }); } catch (FailedToAcquireLockException e) { assertTrue(e.isLock(badLockDef)); } verify(goodLock, times(1)).lock(); verify(badLock, times(1)).lock(); verify(good2Lock, times(0)).lock(); verify(goodLock, times(1)).unlock(); verify(badLock, times(1)).unlock(); verify(good2Lock, times(1)).unlock(); verify(lockProvider, times(1)).getLock(goodLockDef); verify(lockProvider, times(1)).getLock(badLockDef); verify(lockProvider, times(1)).getLock(good2LockDef); verify(lockProvider, times(1)).releaseLock(goodLock); verify(lockProvider, times(1)).releaseLock(badLock); verify(lockProvider, times(1)).releaseLock(good2Lock); } @Test public void test_good_multilock() { MultiLockDefinition def = new TestMultiLockDefinition(goodLockDef, goodLockDef, good2LockDef); final AtomicInteger i = new AtomicInteger(); lockManager.lock(def, new LockCallbackNoReturn() { @Override public void doWithLockNoResult() { i.incrementAndGet(); } }); assertEquals(1, i.intValue()); verify(goodLock, times(2)).lock(); verify(good2Lock, times(1)).lock(); verify(goodLock, times(2)).unlock(); verify(good2Lock, times(1)).unlock(); verify(lockProvider, times(2)).getLock(goodLockDef); verify(lockProvider, times(1)).getLock(good2LockDef); verify(lockProvider, times(2)).releaseLock(goodLock); verify(lockProvider, times(1)).releaseLock(good2Lock); } @Test public void test_exceptions() { try { lockManager.lock(goodLockDef, new LockCallbackNoReturn() { @Override public void doWithLockNoResult() { throw new RuntimeException("42"); } }); } catch (RuntimeException e) { assertEquals("42", e.getMessage()); } verify(goodLock, times(1)).lock(); verify(goodLock, times(1)).unlock(); verify(lockProvider, times(1)).getLock(goodLockDef); verify(lockProvider, times(1)).releaseLock(goodLock); } @Test public void test_checked_exceptions() { try { lockManager.lock(goodLockDef, new LockCallbackWithException<Object, FileNotFoundException>() { @Override public Object doWithLock() throws FileNotFoundException { throw new FileNotFoundException("42"); } }, FileNotFoundException.class); } catch (FileNotFoundException e) { assertEquals("42", e.getMessage()); } verify(goodLock, times(1)).lock(); verify(goodLock, times(1)).unlock(); verify(lockProvider, times(1)).getLock(goodLockDef); verify(lockProvider, times(1)).releaseLock(goodLock); } @Test public void test_return() { assertEquals(new Long(42), lockManager.lock(goodLockDef, new LockCallback<Long>() { @Override public Long doWithLock() { return 42L; } })); verify(goodLock, times(1)).lock(); verify(goodLock, times(1)).unlock(); verify(lockProvider, times(1)).getLock(goodLockDef); verify(lockProvider, times(1)).releaseLock(goodLock); } }