From f5de85e49dd1bf74ae6342344069fa71771288f2 Mon Sep 17 00:00:00 2001 From: Ralph Straubs Date: Mon, 18 Sep 2017 03:37:28 -0500 Subject: Add Junit tests to 'policy-core' These tests focus on the following classes: - PolicyContainer - PolicySession - PolicySessionFeatureAPI 'maven-invoker-plugin' was used to compile and install artifacts for testing during the 'test-compile' phase. These aren't part of the Maven project hierarchy, so they aren't visible to Sonar and SonarQube, and they aren't deployed. Change-Id: I67c122debbe5280f0153e7330248dc5d13c5b2c0 Issue-ID: POLICY-236 Signed-off-by: Ralph Straubs --- .../policy/drools/core/DroolsContainerTest.java | 334 +++++++++++++++++++++ .../drools/core/TestPolicySessionFeatureAPI.java | 157 ++++++++++ ...onap.policy.drools.core.PolicySessionFeatureAPI | 1 + 3 files changed, 492 insertions(+) create mode 100644 policy-core/src/test/java/org/onap/policy/drools/core/DroolsContainerTest.java create mode 100644 policy-core/src/test/java/org/onap/policy/drools/core/TestPolicySessionFeatureAPI.java create mode 100644 policy-core/src/test/resources/META-INF/services/org.onap.policy.drools.core.PolicySessionFeatureAPI (limited to 'policy-core/src/test') diff --git a/policy-core/src/test/java/org/onap/policy/drools/core/DroolsContainerTest.java b/policy-core/src/test/java/org/onap/policy/drools/core/DroolsContainerTest.java new file mode 100644 index 00000000..e83f026c --- /dev/null +++ b/policy-core/src/test/java/org/onap/policy/drools/core/DroolsContainerTest.java @@ -0,0 +1,334 @@ +/*- + * ============LICENSE_START======================================================= + * policy-core + * ================================================================================ + * Copyright (C) 2017 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.assertFalse; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Collection; + +/** + * These tests focus on the following classes: + * PolicyContainer + * PolicySession + * PolicySessionFeatureAPI + */ +public class DroolsContainerTest +{ + /** + * This test is centered around the creation of a 'PolicyContainer' + * and 'PolicySession', and the updating of that container to a new + * version. + */ + @Test + public void createAndUpdate() throws Exception + { + // make sure feature log starts out clean + TestPolicySessionFeatureAPI.getLog(); + + // run 'globalInit', and verify expected feature hook fired + PolicyContainer.globalInit(new String[0]); + assertEquals(buildArrayList("globalInit"), + TestPolicySessionFeatureAPI.getLog()); + + // initial conditions -- there should be no containers + assertEquals(0, PolicyContainer.getPolicyContainers().size()); + + // create the container, and start it + PolicyContainer container = + new PolicyContainer("org.onap.policy.drools-pdp", + "drools-artifact1", "17.1.0-SNAPSHOT"); + container.start(); + assertTrue(container.isAlive()); + + // verify expected feature hooks fired + assertEquals(buildArrayList("activatePolicySession", + "newPolicySession", + "selectThreadModel"), + TestPolicySessionFeatureAPI.getLog()); + + // this container should be on the list + { + Collection containers = + PolicyContainer.getPolicyContainers(); + assertEquals(1, containers.size()); + assertTrue(containers.contains(container)); + } + + // verify initial container attributes + assertEquals("org.onap.policy.drools-pdp:drools-artifact1:17.1.0-SNAPSHOT", + container.getName()); + assertEquals("org.onap.policy.drools-pdp", container.getGroupId()); + assertEquals("drools-artifact1", container.getArtifactId()); + assertEquals("17.1.0-SNAPSHOT", container.getVersion()); + + try + { + // fetch the session, and verify that it exists + PolicySession session = container.getPolicySession("session1"); + assertTrue(session != null); + + // get all sessions, and verify that this one is the only one + { + Collection sessions = container.getPolicySessions(); + assertEquals(1, sessions.size()); + assertTrue(sessions.contains(session)); + } + + // verify session attributes + assertEquals(container, session.getPolicyContainer()); + assertEquals("session1", session.getName()); + assertEquals("org.onap.policy.drools-pdp:drools-artifact1:17.1.0-SNAPSHOT:session1", + session.getFullName()); + + // insert a new fact + int[] a = new int[]{0, 3, 8, 2}; + session.getKieSession().insert(a); + + // the Drools rules should add 3 + 8 + 2, and store 13 in a[0] + assertTrue(waitForChange(a) == 13); + + // update the container to a new version -- + // the rules will then multiply values rather than add them + assertEquals("[]", + container.updateToVersion("17.2.0-SNAPSHOT").toString()); + + // verify expected feature hooks fired + assertEquals(buildArrayList("selectThreadModel"), + TestPolicySessionFeatureAPI.getLog()); + + // verify new container attributes + assertEquals + ("org.onap.policy.drools-pdp:drools-artifact1:17.2.0-SNAPSHOT", + container.getName()); + assertEquals("org.onap.policy.drools-pdp", container.getGroupId()); + assertEquals("drools-artifact1", container.getArtifactId()); + assertEquals("17.2.0-SNAPSHOT", container.getVersion()); + + // verify new session attributes + assertEquals(container, session.getPolicyContainer()); + assertEquals("session1", session.getName()); + assertEquals("org.onap.policy.drools-pdp:drools-artifact1:17.2.0-SNAPSHOT:session1", + session.getFullName()); + + // the updated rules should now multiply 3 * 8 * 2, and return 48 + + a[0] = 0; + container.insert("session1", a); + assertTrue(waitForChange(a) == 48); + } + finally + { + container.shutdown(); + assertFalse(container.isAlive()); + + // verify expected feature hooks fired + assertEquals(buildArrayList("disposeKieSession"), + TestPolicySessionFeatureAPI.getLog()); + } + + // final conditions -- there should be no containers + assertEquals(0, PolicyContainer.getPolicyContainers().size()); + } + + /** + * This test create a 'PolicyContainer' and 'PolicySession', and verifies + * their behavior, but uses alternate interfaces to increase code coverage. + * In addition, feature hook invocations will trigger exceptions in this + * test, also to increase code coverage. + */ + @Test + public void versionList() throws Exception + { + // make sure feature log starts out clean + TestPolicySessionFeatureAPI.getLog(); + + // trigger exceptions in all feature hooks + TestPolicySessionFeatureAPI.setExceptionTrigger(true); + + // run 'globalInit', and verify expected feature hook fired + PolicyContainer.globalInit(new String[0]); + assertEquals(buildArrayList("globalInit-exception"), + TestPolicySessionFeatureAPI.getLog()); + + // initial conditions -- there should be no containers + assertEquals(0, PolicyContainer.getPolicyContainers().size()); + + String versionList = + "17.3.0-SNAPSHOT,17.1.0-SNAPSHOT,17.2.0-SNAPSHOT"; + + // versions should be tried in order -- the 17.1.0-SNAPSHOT should "win", + // given the fact that '17.3.0-SNAPSHOT' doesn't exist + PolicyContainer container = + new PolicyContainer("org.onap.policy.drools-pdp", + "drools-artifact1", versionList); + // the following should be equivalent to 'container.start()' + PolicyContainer.activate(); + assertTrue(container.isAlive()); + + // verify expected feature hooks fired + assertEquals(buildArrayList("activatePolicySession-exception", + "newPolicySession-exception", + "selectThreadModel-exception"), + TestPolicySessionFeatureAPI.getLog()); + + // this container should be on the list + { + Collection containers = + PolicyContainer.getPolicyContainers(); + assertEquals(1, containers.size()); + assertTrue(containers.contains(container)); + } + + // verify initial container attributes + assertEquals("org.onap.policy.drools-pdp:drools-artifact1:17.1.0-SNAPSHOT", + container.getName()); + assertEquals("org.onap.policy.drools-pdp", container.getGroupId()); + assertEquals("drools-artifact1", container.getArtifactId()); + assertEquals("17.1.0-SNAPSHOT", container.getVersion()); + + // some container adjunct tests + { + Object bogusAdjunct = new Object(); + + // initially, no adjunct + assertSame(null, container.getAdjunct(this)); + + // set and verify adjunct + container.setAdjunct(this, bogusAdjunct); + assertSame(bogusAdjunct, container.getAdjunct(this)); + + // clear and verify adjunct + container.setAdjunct(this, null); + assertSame(null, container.getAdjunct(this)); + } + + try + { + // fetch the session, and verify that it exists + PolicySession session = container.getPolicySession("session1"); + assertTrue(session != null); + + // get all sessions, and verify that this one is the only one + { + Collection sessions = container.getPolicySessions(); + assertEquals(1, sessions.size()); + assertTrue(sessions.contains(session)); + } + + // verify session attributes + assertEquals(container, session.getPolicyContainer()); + assertEquals("session1", session.getName()); + assertEquals("org.onap.policy.drools-pdp:drools-artifact1:17.1.0-SNAPSHOT:session1", + session.getFullName()); + + // some session adjunct tests + { + Object bogusAdjunct = new Object(); + + // initially, no adjunct + assertSame(null, session.getAdjunct(this)); + + // set and verify adjunct + session.setAdjunct(this, bogusAdjunct); + assertSame(bogusAdjunct, session.getAdjunct(this)); + + // clear and verify adjunct + session.setAdjunct(this, null); + assertSame(null, session.getAdjunct(this)); + } + + // insert a new fact (using 'insertAll') + int[] a = new int[]{0, 7, 3, 4}; + container.insertAll(a); + + // the Drools rules should add 7 + 3 + 4, and store 14 in a[0] + assertTrue(waitForChange(a) == 14); + + // exercise some more API methods + assertEquals(container.getClassLoader(), + container.getKieContainer().getClassLoader()); + } + finally + { + // should be equivalent to 'shutdown' without persistence + container.destroy(); + assertFalse(container.isAlive()); + + // verify expected feature hooks fired + assertEquals(buildArrayList("destroyKieSession-exception"), + TestPolicySessionFeatureAPI.getLog()); + + // clear exception trigger + TestPolicySessionFeatureAPI.setExceptionTrigger(false); + } + + // 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); + } + + /** + * @param args an array of string arguments + * @return an ArrayList constructed from the provided arguments + */ + private ArrayList buildArrayList(String... args) + { + ArrayList rval = new ArrayList<>(); + for (String arg : args) + { + rval.add(arg); + } + return(rval); + } +} diff --git a/policy-core/src/test/java/org/onap/policy/drools/core/TestPolicySessionFeatureAPI.java b/policy-core/src/test/java/org/onap/policy/drools/core/TestPolicySessionFeatureAPI.java new file mode 100644 index 00000000..f456d814 --- /dev/null +++ b/policy-core/src/test/java/org/onap/policy/drools/core/TestPolicySessionFeatureAPI.java @@ -0,0 +1,157 @@ +/*- + * ============LICENSE_START======================================================= + * policy-core + * ================================================================================ + * Copyright (C) 2017 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 java.util.ArrayList; +import org.kie.api.runtime.KieSession; + +/** + * This class supports 'DroolsContainerTest' by implementing + * 'PolicySessionFeatureAPI', and providing a means to indicate + * which hooks have been invoked. + */ +public class TestPolicySessionFeatureAPI implements PolicySessionFeatureAPI +{ + // contains the log entries since the most recent 'getLog()' call + static private ArrayList log = new ArrayList<>(); + + // if 'true', trigger an exception right after doing the log, + // to verify that exceptions are handled + static private boolean exceptionTrigger = false; + + /** + * @return the current contents of the log, and clear the log + */ + static public ArrayList getLog() + { + synchronized(log) + { + ArrayList rval = new ArrayList<>(log); + log.clear(); + return(rval); + } + } + + /** + * This method controls whether these hooks trigger an exception after + * being invoked. + * + * @param indicator if 'true', subsequent hook method calls will trigger + * an exception; if 'false', no exception is triggered + */ + static public void setExceptionTrigger(boolean indicator) + { + exceptionTrigger = indicator; + } + + /** + * This method adds an entry to the log, and possibly triggers an exception + * + * @param arg value to add to the log + */ + static private void addLog(String arg) + { + if (exceptionTrigger) + { + // the log entry will include a '-exception' appended to the end + synchronized(log) + { + log.add(arg + "-exception"); + } + System.out.println("*** " + arg + "-exception invoked ***"); + + // throw an exception -- it is up to the invoking code to catch it + throw(new IllegalStateException("Triggered from " + arg)); + } + else + { + // create a log entry, and display to standard output + synchronized(log) + { + log.add(arg); + } + System.out.println("*** " + arg + " invoked ***"); + } + } + + /***************************************/ + /* 'PolicySessionFeatureAPI' interface */ + /***************************************/ + + /** + * {@inheritDoc} + */ + public int getSequenceNumber() + { + return(1); + } + + /** + * {@inheritDoc} + */ + public void globalInit(String args[], String configDir) + { + addLog("globalInit"); + } + + /** + * {@inheritDoc} + */ + public KieSession activatePolicySession + (PolicyContainer policyContainer, String name, String kieBaseName) + { + addLog("activatePolicySession"); + return(null); + } + + /** + * {@inheritDoc} + */ + public void newPolicySession(PolicySession policySession) + { + addLog("newPolicySession"); + } + + /** + * {@inheritDoc} + */ + public PolicySession.ThreadModel selectThreadModel(PolicySession session) + { + addLog("selectThreadModel"); + return(null); + } + + /** + * {@inheritDoc} + */ + public void disposeKieSession(PolicySession policySession) + { + addLog("disposeKieSession"); + } + + /** + * {@inheritDoc} + */ + public void destroyKieSession(PolicySession policySession) + { + addLog("destroyKieSession"); + } +} diff --git a/policy-core/src/test/resources/META-INF/services/org.onap.policy.drools.core.PolicySessionFeatureAPI b/policy-core/src/test/resources/META-INF/services/org.onap.policy.drools.core.PolicySessionFeatureAPI new file mode 100644 index 00000000..d6b088c3 --- /dev/null +++ b/policy-core/src/test/resources/META-INF/services/org.onap.policy.drools.core.PolicySessionFeatureAPI @@ -0,0 +1 @@ +org.onap.policy.drools.core.TestPolicySessionFeatureAPI -- cgit 1.2.3-korg