From 1480379b0e9907c0d41e8a782468c30f0ee83196 Mon Sep 17 00:00:00 2001 From: Jim Hahn Date: Thu, 12 Jul 2018 17:47:09 -0400 Subject: Distinguish lock from refresh This is the first step of separating the lock "refresh" operation from the original "lock" operation. This step entails adding the refresh() method to both the default and the feature-distriubted locking mechanisms. Change method call, in junit test, from lock to refresh. Change branch name in git review. Change-Id: I506de7a96cb3ee786839aca04ad67cdd7378832c Issue-ID: POLICY-872 Signed-off-by: Jim Hahn --- .../lock/PolicyResourceLockFeatureAPITest.java | 11 ++ .../core/lock/PolicyResourceLockManagerTest.java | 120 +++++++++++++++++++++ .../drools/core/lock/SimpleLockManagerTest.java | 78 +++++++++++++- 3 files changed, 207 insertions(+), 2 deletions(-) (limited to 'policy-core/src/test') diff --git a/policy-core/src/test/java/org/onap/policy/drools/core/lock/PolicyResourceLockFeatureAPITest.java b/policy-core/src/test/java/org/onap/policy/drools/core/lock/PolicyResourceLockFeatureAPITest.java index 0404877b..0d7d9437 100644 --- a/policy-core/src/test/java/org/onap/policy/drools/core/lock/PolicyResourceLockFeatureAPITest.java +++ b/policy-core/src/test/java/org/onap/policy/drools/core/lock/PolicyResourceLockFeatureAPITest.java @@ -54,6 +54,17 @@ public class PolicyResourceLockFeatureAPITest { assertFalse(api.afterLock(RESOURCE_ID, OWNER, false)); } + @Test + public void testBeforeRefresh() { + assertEquals(OperResult.OPER_UNHANDLED, api.beforeRefresh(RESOURCE_ID, OWNER, 0)); + } + + @Test + public void testAfterRefresh() { + assertFalse(api.afterRefresh(RESOURCE_ID, OWNER, true)); + assertFalse(api.afterRefresh(RESOURCE_ID, OWNER, false)); + } + @Test public void testBeforeUnlock() { assertEquals(OperResult.OPER_UNHANDLED, api.beforeUnlock(RESOURCE_ID, OWNER)); diff --git a/policy-core/src/test/java/org/onap/policy/drools/core/lock/PolicyResourceLockManagerTest.java b/policy-core/src/test/java/org/onap/policy/drools/core/lock/PolicyResourceLockManagerTest.java index 92e60268..5cbed304 100644 --- a/policy-core/src/test/java/org/onap/policy/drools/core/lock/PolicyResourceLockManagerTest.java +++ b/policy-core/src/test/java/org/onap/policy/drools/core/lock/PolicyResourceLockManagerTest.java @@ -108,6 +108,7 @@ public class PolicyResourceLockManagerTest { */ private void initImplementer(PolicyResourceLockFeatureAPI impl) { when(impl.beforeLock(anyString(), anyString(), anyInt())).thenReturn(OperResult.OPER_UNHANDLED); + when(impl.beforeRefresh(anyString(), anyString(), anyInt())).thenReturn(OperResult.OPER_UNHANDLED); when(impl.beforeUnlock(anyString(), anyString())).thenReturn(OperResult.OPER_UNHANDLED); when(impl.beforeIsLocked(anyString())).thenReturn(OperResult.OPER_UNHANDLED); when(impl.beforeIsLockedBy(anyString(), anyString())).thenReturn(OperResult.OPER_UNHANDLED); @@ -224,6 +225,125 @@ public class PolicyResourceLockManagerTest { verify(impl2).afterLock(RESOURCE_A, OWNER2, false); } + @Test + public void testRefresh() throws Exception { + assertTrue(mgr.lock(RESOURCE_A, OWNER1, MAX_AGE_SEC)); + assertTrue(mgr.refresh(RESOURCE_A, OWNER1, MAX_AGE_SEC)); + + verify(impl1).beforeRefresh(RESOURCE_A, OWNER1, MAX_AGE_SEC); + verify(impl2).beforeRefresh(RESOURCE_A, OWNER1, MAX_AGE_SEC); + verify(impl1).afterRefresh(RESOURCE_A, OWNER1, true); + verify(impl2).afterRefresh(RESOURCE_A, OWNER1, true); + + assertTrue(mgr.isLocked(RESOURCE_A)); + assertTrue(mgr.isLockedBy(RESOURCE_A, OWNER1)); + assertFalse(mgr.isLocked(RESOURCE_B)); + assertFalse(mgr.isLockedBy(RESOURCE_A, OWNER2)); + + // different owner and resource + assertFalse(mgr.refresh(RESOURCE_C, OWNER3, MAX_AGE_SEC)); + + // different owner + assertFalse(mgr.refresh(RESOURCE_A, OWNER3, MAX_AGE_SEC)); + } + + @Test + public void testRefresh_ArgEx() { + IllegalArgumentException ex = + expectException(IllegalArgumentException.class, () -> mgr.refresh(null, OWNER1, MAX_AGE_SEC)); + assertEquals(NULL_RESOURCE_ID, ex.getMessage()); + + ex = expectException(IllegalArgumentException.class, () -> mgr.refresh(RESOURCE_A, null, MAX_AGE_SEC)); + assertEquals(NULL_OWNER, ex.getMessage()); + + // this should not throw an exception + mgr.refresh(RESOURCE_A, OWNER1, MAX_AGE_SEC); + } + + @Test + public void testRefresh_Acquired_BeforeIntercepted() { + assertTrue(mgr.lock(RESOURCE_A, OWNER1, MAX_AGE_SEC)); + + // have impl1 intercept + when(impl1.beforeRefresh(RESOURCE_A, OWNER1, MAX_AGE_SEC)).thenReturn(OperResult.OPER_ACCEPTED); + + assertTrue(mgr.refresh(RESOURCE_A, OWNER1, MAX_AGE_SEC)); + + verify(impl1).beforeRefresh(RESOURCE_A, OWNER1, MAX_AGE_SEC); + verify(impl2, never()).beforeRefresh(anyString(), anyString(), anyInt()); + + verify(impl1, never()).afterRefresh(anyString(), anyString(), anyBoolean()); + verify(impl2, never()).afterRefresh(anyString(), anyString(), anyBoolean()); + } + + @Test + public void testRefresh_Denied_BeforeIntercepted() { + assertTrue(mgr.lock(RESOURCE_A, OWNER1, MAX_AGE_SEC)); + + // have impl1 intercept + when(impl1.beforeRefresh(RESOURCE_A, OWNER1, MAX_AGE_SEC)).thenReturn(OperResult.OPER_DENIED); + + assertFalse(mgr.refresh(RESOURCE_A, OWNER1, MAX_AGE_SEC)); + + verify(impl1).beforeRefresh(RESOURCE_A, OWNER1, MAX_AGE_SEC); + verify(impl2, never()).beforeRefresh(anyString(), anyString(), anyInt()); + + verify(impl1, never()).afterRefresh(anyString(), anyString(), anyBoolean()); + verify(impl2, never()).afterRefresh(anyString(), anyString(), anyBoolean()); + } + + @Test + public void testRefresh_Acquired_AfterIntercepted() throws Exception { + assertTrue(mgr.lock(RESOURCE_A, OWNER1, MAX_AGE_SEC)); + + // impl1 intercepts during afterRefresh() + when(impl1.afterRefresh(RESOURCE_A, OWNER1, true)).thenReturn(true); + + assertTrue(mgr.refresh(RESOURCE_A, OWNER1, MAX_AGE_SEC)); + + // impl1 sees it, but impl2 does not + verify(impl1).afterRefresh(RESOURCE_A, OWNER1, true); + verify(impl2, never()).afterRefresh(anyString(), anyString(), anyBoolean()); + } + + @Test + public void testRefresh_Acquired() throws Exception { + assertTrue(mgr.lock(RESOURCE_A, OWNER1, MAX_AGE_SEC)); + + assertTrue(mgr.refresh(RESOURCE_A, OWNER1, MAX_AGE_SEC)); + + verify(impl1).afterRefresh(RESOURCE_A, OWNER1, true); + verify(impl2).afterRefresh(RESOURCE_A, OWNER1, true); + } + + @Test + public void testRefresh_Denied_AfterIntercepted() throws Exception { + + mgr.lock(RESOURCE_A, OWNER1, MAX_AGE_SEC); + + // impl1 intercepts during afterRefresh() + when(impl1.afterRefresh(RESOURCE_A, OWNER2, false)).thenReturn(true); + + // owner2 tries to lock + assertFalse(mgr.refresh(RESOURCE_A, OWNER2, MAX_AGE_SEC)); + + // impl1 sees it, but impl2 does not + verify(impl1).afterRefresh(RESOURCE_A, OWNER2, false); + verify(impl2, never()).afterRefresh(RESOURCE_A, OWNER2, false); + } + + @Test + public void testRefresh_Denied() { + + mgr.lock(RESOURCE_A, OWNER1, MAX_AGE_SEC); + + // owner2 tries to lock + mgr.refresh(RESOURCE_A, OWNER2, MAX_AGE_SEC); + + verify(impl1).afterRefresh(RESOURCE_A, OWNER2, false); + verify(impl2).afterRefresh(RESOURCE_A, OWNER2, false); + } + @Test public void testUnlock() throws Exception { mgr.lock(RESOURCE_A, OWNER1, MAX_AGE_SEC); diff --git a/policy-core/src/test/java/org/onap/policy/drools/core/lock/SimpleLockManagerTest.java b/policy-core/src/test/java/org/onap/policy/drools/core/lock/SimpleLockManagerTest.java index 14964e0e..df6fb10a 100644 --- a/policy-core/src/test/java/org/onap/policy/drools/core/lock/SimpleLockManagerTest.java +++ b/policy-core/src/test/java/org/onap/policy/drools/core/lock/SimpleLockManagerTest.java @@ -100,10 +100,10 @@ public class SimpleLockManagerTest { assertFalse(mgr.isLocked(RESOURCE_B)); assertFalse(mgr.isLockedBy(RESOURCE_A, OWNER2)); - // null callback - not locked yet + // different owner and resource - should succeed assertTrue(mgr.lock(RESOURCE_C, OWNER3, MAX_AGE_SEC)); - // null callback - already locked + // different owner - already locked assertFalse(mgr.lock(RESOURCE_A, OWNER3, MAX_AGE_SEC)); } @@ -151,6 +151,80 @@ public class SimpleLockManagerTest { mgr.lock(RESOURCE_A, OWNER1, MAX_AGE_SEC); } + @Test + public void testRefresh() throws Exception { + // don't own the lock yet - cannot refresh + assertFalse(mgr.refresh(RESOURCE_A, OWNER1, MAX_AGE_SEC)); + + assertTrue(mgr.lock(RESOURCE_A, OWNER1, MAX_AGE_SEC)); + + // now the lock is owned + assertTrue(mgr.refresh(RESOURCE_A, OWNER1, MAX_AGE_SEC)); + + // refresh again + assertTrue(mgr.refresh(RESOURCE_A, OWNER1, MAX_AGE_SEC + 1)); + + assertTrue(mgr.isLocked(RESOURCE_A)); + assertTrue(mgr.isLockedBy(RESOURCE_A, OWNER1)); + assertFalse(mgr.isLocked(RESOURCE_B)); + assertFalse(mgr.isLockedBy(RESOURCE_A, OWNER2)); + + // different owner + assertFalse(mgr.refresh(RESOURCE_A, OWNER3, MAX_AGE_SEC)); + + // different resource + assertFalse(mgr.refresh(RESOURCE_C, OWNER1, MAX_AGE_SEC)); + } + + @Test + public void testRefresh_ExtendLock() throws Exception { + mgr.lock(RESOURCE_A, OWNER1, MAX_AGE_SEC); + + // sleep half of the cycle + testTime.sleep(MAX_AGE_MS / 2); + assertTrue(mgr.isLockedBy(RESOURCE_A, OWNER1)); + + // extend the lock + mgr.refresh(RESOURCE_A, OWNER1, MAX_AGE_SEC); + + // verify still locked after sleeping the other half of the cycle + testTime.sleep(MAX_AGE_MS / 2 + 1); + assertTrue(mgr.isLockedBy(RESOURCE_A, OWNER1)); + + // and should release after another half cycle + testTime.sleep(MAX_AGE_MS / 2); + + // cannot refresh expired lock + assertFalse(mgr.refresh(RESOURCE_A, OWNER1, MAX_AGE_SEC)); + + assertFalse(mgr.isLockedBy(RESOURCE_A, OWNER1)); + } + + @Test + public void testRefresh_AlreadyLocked() throws Exception { + mgr.lock(RESOURCE_A, OWNER1, MAX_AGE_SEC); + + // same owner + assertTrue(mgr.refresh(RESOURCE_A, OWNER1, MAX_AGE_SEC)); + + // different owner + assertFalse(mgr.refresh(RESOURCE_A, OWNER2, MAX_AGE_SEC)); + assertFalse(mgr.lock(RESOURCE_A, OWNER2, MAX_AGE_SEC)); + } + + @Test + public void testRefresh_ArgEx() { + IllegalArgumentException ex = + expectException(IllegalArgumentException.class, () -> mgr.refresh(null, OWNER1, MAX_AGE_SEC)); + assertEquals(NULL_RESOURCE_ID, ex.getMessage()); + + ex = expectException(IllegalArgumentException.class, () -> mgr.refresh(RESOURCE_A, null, MAX_AGE_SEC)); + assertEquals(NULL_OWNER, ex.getMessage()); + + // this should not throw an exception + mgr.refresh(RESOURCE_A, OWNER1, MAX_AGE_SEC); + } + @Test public void testUnlock() throws Exception { mgr.lock(RESOURCE_A, OWNER1, MAX_AGE_SEC); -- cgit 1.2.3-korg