aboutsummaryrefslogtreecommitdiffstats
path: root/main/src/test/java/org
diff options
context:
space:
mode:
authorjrh3 <jrh3@att.com>2019-06-11 10:56:25 -0400
committerjrh3 <jrh3@att.com>2019-06-11 17:23:35 -0400
commita240d7a4020d0346040fe4d86682a6ab8fcd757a (patch)
tree31b2fa3a76c38f00a0ab5a45fca5a4d17508e45f /main/src/test/java/org
parentfde702471743115e7492951873dd48ba3dbc66bb (diff)
Add PDP heart beat expiration timer
Added heart beat interval to the PDP-UPDATE message sent in response to a heart beat message received from a PDP. Added timers to detect missing heart beats and remove the PDP from the DB - PdpTracker. Modified current heart beat listener to update PdpTracker when a heart beat is received. Allow 3 missed heart beats instead of 2. Change-Id: I81621fefbe494e0c4d6f0b9767b00b2a9dd398d8 Issue-ID: POLICY-1795 Signed-off-by: jrh3 <jrh3@att.com>
Diffstat (limited to 'main/src/test/java/org')
-rw-r--r--main/src/test/java/org/onap/policy/pap/main/comm/PdpTrackerTest.java212
-rw-r--r--main/src/test/java/org/onap/policy/pap/main/parameters/TestPdpParameters.java13
2 files changed, 223 insertions, 2 deletions
diff --git a/main/src/test/java/org/onap/policy/pap/main/comm/PdpTrackerTest.java b/main/src/test/java/org/onap/policy/pap/main/comm/PdpTrackerTest.java
new file mode 100644
index 00000000..19684a71
--- /dev/null
+++ b/main/src/test/java/org/onap/policy/pap/main/comm/PdpTrackerTest.java
@@ -0,0 +1,212 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP PAP
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.pap.main.comm;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.function.Consumer;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.onap.policy.common.utils.coder.StandardCoder;
+import org.onap.policy.common.utils.resources.ResourceUtils;
+import org.onap.policy.models.base.PfModelException;
+import org.onap.policy.models.pdp.concepts.PdpGroup;
+import org.onap.policy.models.pdp.concepts.PdpGroups;
+import org.onap.policy.models.provider.PolicyModelsProvider;
+import org.onap.policy.pap.main.PolicyModelsProviderFactoryWrapper;
+import org.onap.policy.pap.main.PolicyPapRuntimeException;
+import org.onap.policy.pap.main.comm.TimerManager.Timer;
+
+public class PdpTrackerTest {
+ private static final String PDP1 = "pdp1";
+ private static final String PDP2 = "pdp2";
+
+ private PdpTracker tracker;
+ private PdpTracker.PdpTrackerBuilder builder;
+
+ private Object modifyLock;
+
+ @Captor
+ private ArgumentCaptor<Consumer<String>> handlerCaptor;
+
+ @Mock
+ private PdpModifyRequestMap requestMap;
+
+ @Mock
+ private TimerManager timers;
+
+ @Mock
+ private PolicyModelsProviderFactoryWrapper daoFactory;
+
+ @Mock
+ private PolicyModelsProvider dao;
+
+ @Mock
+ private Timer timer1;
+
+ @Mock
+ private Timer timer2;
+
+ /**
+ * Sets up.
+ *
+ * @throws Exception if an error occurs
+ */
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ modifyLock = new Object();
+
+ builder = PdpTracker.builder().daoFactory(daoFactory).modifyLock(modifyLock).requestMap(requestMap)
+ .timers(timers);
+
+ when(daoFactory.create()).thenReturn(dao);
+
+ when(dao.getPdpGroups(null)).thenReturn(Collections.emptyList());
+
+ when(timers.register(eq(PDP1), any())).thenReturn(timer1);
+ when(timers.register(eq(PDP2), any())).thenReturn(timer2);
+
+ tracker = builder.build();
+ }
+
+ @Test
+ public void testPdpTracker() throws Exception {
+ // verify that PDPs were loaded
+ verify(dao).getPdpGroups(null);
+ }
+
+ @Test
+ public void testBuilderToString() throws Exception {
+ assertNotNull(builder.toString());
+ }
+
+ @Test
+ public void testPdpTracker_MissingRequestMap() throws Exception {
+ assertThatThrownBy(() -> builder.requestMap(null).build()).isInstanceOf(NullPointerException.class);
+ }
+
+ @Test
+ public void testPdpTracker_MissingModifyLock() throws Exception {
+ assertThatThrownBy(() -> builder.modifyLock(null).build()).isInstanceOf(NullPointerException.class);
+ }
+
+ @Test
+ public void testPdpTracker_MissingTimers() throws Exception {
+ assertThatThrownBy(() -> builder.timers(null).build()).isInstanceOf(NullPointerException.class);
+ }
+
+ @Test
+ public void testPdpTracker_MissingDaoFactory() throws Exception {
+ assertThatThrownBy(() -> builder.daoFactory(null).build()).isInstanceOf(NullPointerException.class);
+ }
+
+ @Test
+ public void testLoadPdps_testLoadPdpsFromGroup() throws Exception {
+ // arrange for DAO to return a couple of groups
+ String groupsJson = ResourceUtils.getResourceAsString("comm/PdpTracker.json");
+ List<PdpGroup> groups = new StandardCoder().decode(groupsJson, PdpGroups.class).getGroups();
+ when(dao.getPdpGroups(null)).thenReturn(groups);
+
+ tracker = builder.build();
+
+ // verify that all PDPs were registered
+ verify(timers).register(eq("pdp-A"), any());
+ verify(timers).register(eq("pdp-B"), any());
+ verify(timers).register(eq("pdp-C"), any());
+ verify(timers).register(eq("pdp-D"), any());
+ }
+
+ @Test
+ public void testLoadPdps_DaoException() throws Exception {
+ // arrange for DAO to throw an exception
+ PfModelException ex = mock(PfModelException.class);
+ when(daoFactory.create()).thenThrow(ex);
+
+ assertThatThrownBy(() -> builder.build()).isInstanceOf(PolicyPapRuntimeException.class).hasCause(ex);
+ }
+
+ @Test
+ public void testAdd() {
+ tracker.add(PDP1);
+ verify(timers).register(eq(PDP1), any());
+ verify(timer1, never()).cancel();
+
+ tracker.add(PDP2);
+ verify(timers).register(eq(PDP2), any());
+ verify(timer1, never()).cancel();
+ verify(timer2, never()).cancel();
+
+ // re-add PDP1 - old timer should be canceled and a new timer added
+ Timer timer3 = mock(Timer.class);
+ when(timers.register(eq(PDP1), any())).thenReturn(timer3);
+ tracker.add(PDP1);
+ verify(timer1).cancel();
+ verify(timer2, never()).cancel();
+ verify(timer3, never()).cancel();
+ }
+
+ @Test
+ public void testHandleTimeout() throws Exception {
+ tracker.add(PDP1);
+ tracker.add(PDP2);
+
+ verify(timers).register(eq(PDP1), handlerCaptor.capture());
+
+ handlerCaptor.getValue().accept(PDP1);
+
+ verify(requestMap).removeFromGroups(PDP1);
+
+ // now we'll re-add PDP1 - the original timer should not be canceled
+ Timer timer3 = mock(Timer.class);
+ when(timers.register(eq(PDP1), any())).thenReturn(timer3);
+ tracker.add(PDP1);
+ verify(timer1, never()).cancel();
+ }
+
+ @Test
+ public void testHandleTimeout_MapException() throws Exception {
+ tracker.add(PDP1);
+
+ verify(timers).register(eq(PDP1), handlerCaptor.capture());
+
+ // arrange for request map to throw an exception
+ PfModelException ex = mock(PfModelException.class);
+ when(requestMap.removeFromGroups(PDP1)).thenThrow(ex);
+
+ // exception should be caught, but not re-thrown
+ handlerCaptor.getValue().accept(PDP1);
+ }
+}
diff --git a/main/src/test/java/org/onap/policy/pap/main/parameters/TestPdpParameters.java b/main/src/test/java/org/onap/policy/pap/main/parameters/TestPdpParameters.java
index eb9a6e8b..1474bbfb 100644
--- a/main/src/test/java/org/onap/policy/pap/main/parameters/TestPdpParameters.java
+++ b/main/src/test/java/org/onap/policy/pap/main/parameters/TestPdpParameters.java
@@ -46,6 +46,8 @@ public class TestPdpParameters {
PdpStateChangeParameters state = params.getStateChangeParameters();
assertNotNull(state);
assertEquals(5, state.getMaxWaitMs());
+
+ assertEquals(6L, params.getHeartBeatMs());
}
@Test
@@ -58,6 +60,13 @@ public class TestPdpParameters {
assertNull(result.getResult());
assertTrue(result.isValid());
+ // invalid heart beat
+ json2 = json.replaceFirst(": 6", ": 0");
+ result = coder.decode(json2, PapParameterGroup.class).getPdpParameters().validate();
+ assertFalse(result.isValid());
+ assertTrue(result.getResult().contains(
+ "field 'heartBeatMs' type 'long' value '0' INVALID, must be >= 1".replace('\'', '"')));
+
// no update params
json2 = testData.nullifyField(json, "updateParameters");
result = coder.decode(json2, PapParameterGroup.class).getPdpParameters().validate();
@@ -66,7 +75,7 @@ public class TestPdpParameters {
assertTrue(result.getResult().contains("is null"));
// invalid update params
- json2 = json.replaceFirst("2", "-2");
+ json2 = json.replaceFirst(": 2", ": -2");
result = coder.decode(json2, PapParameterGroup.class).getPdpParameters().validate();
assertFalse(result.isValid());
assertTrue(result.getResult().contains("parameter group 'PdpUpdateParameters'".replace('\'', '"')));
@@ -79,7 +88,7 @@ public class TestPdpParameters {
assertFalse(result.isValid());
// invalid state-change params
- json2 = json.replaceFirst("5", "-5");
+ json2 = json.replaceFirst(": 5", ": -5");
result = coder.decode(json2, PapParameterGroup.class).getPdpParameters().validate();
assertFalse(result.isValid());
assertTrue(result.getResult().contains("parameter group 'PdpStateChangeParameters'".replace('\'', '"')));