Added easy junit test coverage cases.
Fixed sonar issue: removed sleep from DroolsContainerTest.
Fixed sonar bug in ClassExtractors.
Change-Id: I942badf17c42346c1735bc3951450fc31c02a769
Issue-ID: POLICY-1148
Signed-off-by: Jim Hahn <jrh3@att.com>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
- <version>${jackson.version}</version>
<scope>provided</scope>
</dependency>
*/
private Extractor buildExtractor(Class<?> clazz, String value) {
if (!value.startsWith("${")) {
- logger.warn("property value for {}{} does not start with '${'", prefix, clazz.getName());
+ logger.warn("property value for {}{} does not start with {}", prefix, clazz.getName(), "'${'");
return new NullExtractor();
}
/**
* This class is a wrapper around 'KieSession', which adds the following:
- *
+ *
* <p>1) A thread running 'KieSession.fireUntilHalt()'
* 2) Access to UEB
* 3) Logging of events
/**
* Get policy container.
- *
+ *
* @return the 'PolicyContainer' object containing this session
*/
public PolicyContainer getPolicyContainer() {
/**
* Get Kie Session.
- *
+ *
* @return the associated 'KieSession' instance
*/
public KieSession getKieSession() {
/**
* Get name.
- *
+ *
* @return the local name of this session, which should either match the
* name specified in 'kmodule.xml' file associated with this session, or the
* name passed on the 'PolicyContainer.adoptKieSession' method.
/**
* Get full name.
- *
+ *
* @return the 'PolicyContainer' name, followed by ':', followed by the
* local name of the session. It should be useful in log messages.
*/
/**
* Get current session.
- *
+ *
* @return the 'PolicySession' instance associated with the current thread
* (Note that this only works if the current thread is the one running
* 'kieSession.fireUntilHalt()'.)
*/
@Override
public void afterMatchFired(AfterMatchFiredEvent event) {
- if (logger.isDebugEnabled()) {
- logger.debug("afterMatchFired: " + getFullName()
- + ": AgendaEventListener.afterMatchFired(" + event + ")");
- }
+ logger.debug("afterMatchFired: {}: AgendaEventListener.afterMatchFired({})", getFullName(), event);
PdpJmx.getInstance().ruleFired();
}
*/
@Override
public void afterRuleFlowGroupActivated(RuleFlowGroupActivatedEvent event) {
- if (logger.isDebugEnabled()) {
- logger.debug("afterRuleFlowGroupActivated: " + getFullName()
- + ": AgendaEventListener.afterRuleFlowGroupActivated("
- + event + ")");
- }
+ logger.debug("afterRuleFlowGroupActivated: {}: AgendaEventListener.afterRuleFlowGroupActivated({})",
+ getFullName(), event);
}
/**
*/
@Override
public void afterRuleFlowGroupDeactivated(RuleFlowGroupDeactivatedEvent event) {
- if (logger.isDebugEnabled()) {
- logger.debug("afterRuleFlowGroupDeactivated: " + getFullName()
- + ": AgendaEventListener.afterRuleFlowGroupDeactivated("
- + event + ")");
- }
+ logger.debug("afterRuleFlowGroupDeactivated: {}: AgendaEventListener.afterRuleFlowGroupDeactivated({})",
+ getFullName(), event);
}
/**
*/
@Override
public void agendaGroupPopped(AgendaGroupPoppedEvent event) {
- if (logger.isDebugEnabled()) {
- logger.debug("agendaGroupPopped: " + getFullName()
- + ": AgendaEventListener.agendaGroupPopped("
- + event + ")");
- }
+ logger.debug("agendaGroupPopped: {}: AgendaEventListener.agendaGroupPopped({})", getFullName(), event);
}
/**
*/
@Override
public void agendaGroupPushed(AgendaGroupPushedEvent event) {
- if (logger.isDebugEnabled()) {
- logger.debug("agendaGroupPushed: " + getFullName()
- + ": AgendaEventListener.agendaGroupPushed("
- + event + ")");
- }
+ logger.debug("agendaGroupPushed: {}: AgendaEventListener.agendaGroupPushed({})", getFullName(), event);
}
/**
*/
@Override
public void beforeMatchFired(BeforeMatchFiredEvent event) {
- if (logger.isDebugEnabled()) {
- logger.debug("beforeMatchFired: " + getFullName()
- + ": AgendaEventListener.beforeMatchFired("
- + event + ")");
- }
+ logger.debug("beforeMatchFired: {}: AgendaEventListener.beforeMatchFired({})", getFullName(), event);
}
/**
*/
@Override
public void beforeRuleFlowGroupActivated(RuleFlowGroupActivatedEvent event) {
- if (logger.isDebugEnabled()) {
- logger.debug("beforeRuleFlowGroupActivated: " + getFullName()
- + ": AgendaEventListener.beforeRuleFlowGroupActivated("
- + event + ")");
- }
+ logger.debug("beforeRuleFlowGroupActivated: {}: AgendaEventListener.beforeRuleFlowGroupActivated({})",
+ getFullName(), event);
}
/**
*/
@Override
public void beforeRuleFlowGroupDeactivated(RuleFlowGroupDeactivatedEvent event) {
- if (logger.isDebugEnabled()) {
- logger.debug("beforeRuleFlowGroupDeactivated: " + getFullName()
- + ": AgendaEventListener.beforeRuleFlowGroupDeactivated("
- + event + ")");
- }
+ logger.debug("beforeRuleFlowGroupDeactivated: {}: AgendaEventListener.beforeRuleFlowGroupDeactivated({})",
+ getFullName(), event);
}
/**
*/
@Override
public void matchCancelled(MatchCancelledEvent event) {
- if (logger.isDebugEnabled()) {
- logger.debug("matchCancelled: " + getFullName()
- + ": AgendaEventListener.matchCancelled(" + event + ")");
- }
+ logger.debug("matchCancelled: {}: AgendaEventListener.matchCancelled({})", getFullName(), event);
}
/**
*/
@Override
public void matchCreated(MatchCreatedEvent event) {
- if (logger.isDebugEnabled()) {
- logger.debug("matchCreated: " + getFullName()
- + ": AgendaEventListener.matchCreated(" + event + ")");
- }
+ logger.debug("matchCreated: {}: AgendaEventListener.matchCreated({})", getFullName(), event);
}
- /*======================================*/
+ /* ====================================== */
/* 'RuleRuntimeEventListener' interface */
- /*======================================*/
+ /* ====================================== */
/**
* {@inheritDoc}.
*/
@Override
public void objectDeleted(ObjectDeletedEvent event) {
- if (logger.isDebugEnabled()) {
- logger.debug("objectDeleted: " + getFullName()
- + ": AgendaEventListener.objectDeleted(" + event + ")");
- }
+ logger.debug("objectDeleted: {}: AgendaEventListener.objectDeleted({})", getFullName(), event);
}
/**
*/
@Override
public void objectInserted(ObjectInsertedEvent event) {
- if (logger.isDebugEnabled()) {
- logger.debug("objectInserted: " + getFullName()
- + ": AgendaEventListener.objectInserted(" + event + ")");
- }
+ logger.debug("objectInserted: {}: AgendaEventListener.objectInserted({})", getFullName(), event);
}
/**
*/
@Override
public void objectUpdated(ObjectUpdatedEvent event) {
- if (logger.isDebugEnabled()) {
- logger.debug("objectUpdated: " + getFullName()
- + ": AgendaEventListener.objectUpdated(" + event + ")");
- }
+ logger.debug("objectUpdated: {}: AgendaEventListener.objectUpdated({})", getFullName(), event);
}
-
+
/* ============================================================ */
/**
/**
* Get thread name.
- *
+ *
* @return the String to use as the thread name
*/
private String getThreadName() {
*/
public static boolean isFeatureEnabled(Properties props, String propName) {
String val = props.getProperty(propName);
- return (val != null ? Boolean.valueOf(val) : false);
+ return (val != null && Boolean.valueOf(val));
}
}
public class KieUtils {
private KieUtils() {
- throw new IllegalStateException("Utility class");
+ // Utility class
}
/**
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collection;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
import org.junit.BeforeClass;
import org.junit.Test;
import org.onap.policy.drools.util.KieUtils;
* PolicySessionFeatureAPI
*/
public class DroolsContainerTest {
+
+ private static final long TIMEOUT_SEC = 5;
+
/**
* This test is centered around the creation of a 'PolicyContainer'
* and 'PolicySession', and the updating of that container to a new
session.getFullName());
// insert a new fact
- int[] facts = new int[]{0, 3, 8, 2};
- session.getKieSession().insert(facts);
+ LinkedBlockingQueue<Integer> result = new LinkedBlockingQueue<>();
+ session.getKieSession().insert(Arrays.asList(3, 8, 2));
+ session.getKieSession().insert(result);
// the Drools rules should add 3 + 8 + 2, and store 13 in a[0]
- assertTrue(waitForChange(facts) == 13);
+ assertEquals(13, result.poll(TIMEOUT_SEC, TimeUnit.SECONDS).intValue());
// update the container to a new version --
// the rules will then multiply values rather than add them
session.getFullName());
// the updated rules should now multiply 3 * 8 * 2, and return 48
+
+ result = new LinkedBlockingQueue<>();
+ container.insert("session1", Arrays.asList(3, 8, 2));
+ container.insert("session1", result);
- facts[0] = 0;
- container.insert("session1", facts);
- assertTrue(waitForChange(facts) == 48);
+ assertEquals(48, result.poll(TIMEOUT_SEC, TimeUnit.SECONDS).intValue());
} finally {
container.shutdown();
assertFalse(container.isAlive());
}
// insert a new fact (using 'insertAll')
- int[] facts = new int[]{0, 7, 3, 4};
- container.insertAll(facts);
+ LinkedBlockingQueue<Integer> result = new LinkedBlockingQueue<>();
+ container.insertAll(Arrays.asList(7, 3, 4));
+ container.insertAll(result);
// the Drools rules should add 7 + 3 + 4, and store 14 in a[0]
- assertTrue(waitForChange(facts) == 14);
+ assertEquals(14, result.poll(TIMEOUT_SEC, TimeUnit.SECONDS).intValue());
// exercise some more API methods
assertEquals(container.getClassLoader(),
// final conditions -- there should be no containers
assertEquals(0, PolicyContainer.getPolicyContainers().size());
}
-
- /**
- * This method is tied to the expected behavior of the drools sessions.
- * Initially, the value of 'array[0]' should be 0. The Drools rules
- * will either add or multiply 'array[1]' through 'array[n-1]', depending
- * upon the version. It waits up to 30 seconds for a non-zero value
- * to appear.
- */
- private int waitForChange(int[] array) throws InterruptedException {
- int rval = -1;
-
- // the value is tested every 1/100 of a second, and it waits up to
- // 3000 iterations (= 30 seconds) for a non-zero value
- for (int i = 0 ; i < 3000 ; i += 1) {
- // wait for 10 milliseconds = 1/100 of a second
- Thread.sleep(10);
- if ((rval = array[0]) != 0) {
- // a non-zero value has been stored
- break;
- }
- }
- return (rval);
- }
}
--- /dev/null
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2018 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.drools.core;
+
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+
+public class PolicySessionFeatureApiTest {
+
+ @Test
+ public void test() {
+ PolicySessionFeatureAPI api = new PolicySessionFeatureAPI() {
+ @Override
+ public int getSequenceNumber() {
+ return 0;
+ }
+ };
+
+ // test default methods
+ api.globalInit(null, null);
+ api.newPolicySession(null);
+ api.disposeKieSession(null);
+ api.destroyKieSession(null);
+
+ assertNull(api.activatePolicySession(null, null, null));
+ assertNull(api.selectThreadModel(null));
+ }
+
+}
--- /dev/null
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2018 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.drools.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.concurrent.Semaphore;
+import org.junit.Before;
+import org.junit.Test;
+import org.kie.api.event.rule.AgendaEventListener;
+import org.kie.api.event.rule.RuleRuntimeEventListener;
+import org.kie.api.runtime.KieSession;
+import org.onap.policy.drools.core.PolicySession.ThreadModel;
+
+public class PolicySessionTest {
+
+ private static final String MY_NAME = "my-name";
+ private static final String CONTAINER = "my-container";
+ private static final String EXPECTED = null;
+
+ private PolicySession session;
+ private PolicyContainer container;
+ private KieSession kie;
+
+ /**
+ * Initialize test objects.
+ */
+ @Before
+ public void setUp() {
+ container = mock(PolicyContainer.class);
+ kie = mock(KieSession.class);
+
+ when(container.getName()).thenReturn(CONTAINER);
+
+ session = new PolicySession(MY_NAME, container, kie);
+ }
+
+ @Test
+ public void test_Simple() {
+ // verify constructor operations
+ AgendaEventListener agenda = session;
+ verify(kie).addEventListener(agenda);
+
+ RuleRuntimeEventListener rule = session;
+ verify(kie).addEventListener(rule);
+
+ // test other simple methods
+ assertEquals(container, session.getPolicyContainer());
+ assertEquals(kie, session.getKieSession());
+ assertEquals(MY_NAME, session.getName());
+ assertEquals(CONTAINER + ":" + MY_NAME, session.getFullName());
+
+ session.stopThread();
+ session.updated();
+
+ session.afterRuleFlowGroupActivated(null);
+ session.afterRuleFlowGroupDeactivated(null);
+ session.agendaGroupPopped(null);
+ session.agendaGroupPushed(null);
+ session.beforeMatchFired(null);
+ session.beforeRuleFlowGroupActivated(null);
+ session.beforeRuleFlowGroupDeactivated(null);
+ session.matchCancelled(null);
+ session.matchCreated(null);
+ session.objectDeleted(null);
+ session.objectInserted(null);
+ session.objectUpdated(null);
+ }
+
+ @Test
+ public void testStartThread() {
+ session.startThread();
+
+ // re-start
+ session.startThread();
+
+ session.stopThread();
+ }
+
+ @Test
+ public void testSetPolicySession_testGetCurrentSession() {
+ PolicySession sess2 = new PolicySession(MY_NAME + "-b", container, kie);
+
+ session.setPolicySession();
+ assertEquals(session, PolicySession.getCurrentSession());
+
+ sess2.setPolicySession();
+ assertEquals(sess2, PolicySession.getCurrentSession());
+ }
+
+ @Test
+ public void testGetAdjunct_testSetAdjunct() {
+ Object adjnm1 = "adjunct-a";
+ Object adjval1 = "value-a";
+ session.setAdjunct(adjnm1, adjval1);
+
+ Object adjnm2 = "adjunct-b";
+ Object adjval2 = "value-b";
+ session.setAdjunct(adjnm2, adjval2);
+
+ assertEquals(adjval1, session.getAdjunct(adjnm1));
+ assertEquals(adjval2, session.getAdjunct(adjnm2));
+ assertNull(session.getAdjunct("unknown-adjunct"));
+ }
+
+ @Test
+ public void testThreadModel() {
+ ThreadModel model = new PolicySession.ThreadModel() {
+ @Override
+ public void stop() {
+ // do nothing
+ }
+
+ @Override
+ public void start() {}
+ };
+
+ model.updated();
+ }
+
+ @Test
+ public void testDefaultThreadModelRun() throws Exception {
+ testDefaultThreadModelRun_Ex(() -> {
+ throw new RuntimeException(EXPECTED);
+ });
+ testDefaultThreadModelRun_Ex(() -> {
+ throw new LinkageError(EXPECTED);
+ });
+ }
+
+ /**
+ * Starts a thread and then invokes a function to generate an exception within the
+ * fireUntilHalt() method.
+ *
+ * @param genEx function to generate an exception
+ * @throws Exception if an error occurs
+ */
+ private void testDefaultThreadModelRun_Ex(Runnable genEx) throws Exception {
+ Semaphore me = new Semaphore(0);
+ Semaphore thread = new Semaphore(0);
+
+ doAnswer(args -> {
+ // let me know the thread has started
+ me.release(1);
+
+ // wait until I tell it to continue
+ thread.acquire();
+
+ // generate the exception
+ genEx.run();
+
+ // never reaches here
+ return null;
+
+ }).when(kie).fireUntilHalt();
+
+ session.startThread();
+
+ me.acquire();
+ thread.release();
+
+ session.stopThread();
+ }
+
+}
--- /dev/null
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2018 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.drools.core.jmx;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class PdpJmxTest {
+
+ private PdpJmx jmx;
+
+ @Before
+ public void setUp() {
+ jmx = new PdpJmx();
+ }
+
+ @Test
+ public void testGetInstance() {
+ jmx = PdpJmx.getInstance();
+ assertNotNull(jmx);
+ assertTrue(PdpJmx.getInstance() == jmx);
+ }
+
+ @Test
+ public void testGetUpdates_testUpdateOccured() {
+ assertEquals(0, jmx.getUpdates());
+ assertEquals(0, jmx.getRulesFired());
+
+ jmx.updateOccured();
+ assertEquals(1, jmx.getUpdates());
+ assertEquals(0, jmx.getRulesFired());
+
+ jmx.updateOccured();
+ assertEquals(2, jmx.getUpdates());
+ assertEquals(0, jmx.getRulesFired());
+ }
+
+ @Test
+ public void testGetRulesFired_testRuleFired() {
+ assertEquals(0, jmx.getUpdates());
+ assertEquals(0, jmx.getRulesFired());
+
+ jmx.ruleFired();
+ assertEquals(0, jmx.getUpdates());
+ assertEquals(1, jmx.getRulesFired());
+
+ jmx.ruleFired();
+ assertEquals(0, jmx.getUpdates());
+ assertEquals(2, jmx.getRulesFired());
+ }
+}
* ============LICENSE_END=========================================================
*/
package org.onap.policy.drools.core.test;
+
+ import java.util.concurrent.BlockingQueue;
+ import java.util.List;
rule "Initialization"
when
}
end
-rule "Add elements of an int array"
+rule "Add elements of an int list"
when
- $object : Object()
+ $lst : List()
+ $queue : BlockingQueue()
then
{
- if ($object instanceof int[])
- {
- int[] array = (int[])($object);
-
- System.out.println("Received array of length " + array.length);
- int sum = 0;
- for (int i = 1 ; i < array.length ; i += 1)
- {
- sum += array[i];
- }
- array[0] = sum;
- retract($object);
- }
+ System.out.println("Received list of length " + $lst.size());
+ int sum = 0;
+ List<Integer> intlst = $lst;
+ for(int val: intlst) {
+ sum += val;
+ }
+ $queue.add(sum);
+ retract($lst);
+ retract($queue);
}
end
* ============LICENSE_END=========================================================
*/
package org.onap.policy.drools.core.test;
+
+ import java.util.concurrent.BlockingQueue;
+ import java.util.List;
rule "Initialization"
when
}
end
-rule "Multiply elements of an int array"
- when
- $object : Object()
- then
- {
- if ($object instanceof int[])
- {
- int[] array = (int[])($object);
-
- System.out.println("Received array of length " + array.length);
- int product = 1;
- for (int i = 1 ; i < array.length ; i += 1)
- {
- product *= array[i];
- }
- array[0] = product;
- }
- }
+rule "Multiply elements of an int list"
+ when
+ $lst : List()
+ $queue : BlockingQueue()
+ then
+ {
+ System.out.println("Received list of length " + $lst.size());
+ int prod = 1;
+ List<Integer> intlst = $lst;
+ for(int val: intlst) {
+ prod *= val;
+ }
+ $queue.add(prod);
+ retract($lst);
+ retract($queue);
+ }
end