diff options
author | Ralph Straubs <rs8887@att.com> | 2017-09-18 03:37:28 -0500 |
---|---|---|
committer | Ralph Straubs <rs8887@att.com> | 2017-09-18 07:16:10 -0500 |
commit | f5de85e49dd1bf74ae6342344069fa71771288f2 (patch) | |
tree | 857d2956b14e7b2744ace1ff8e7a80586789a23f | |
parent | fbed3c9c7b816b9fa4dd96dc218a0603b1d1c544 (diff) |
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 <rs8887@att.com>
10 files changed, 685 insertions, 1 deletions
diff --git a/policy-core/drools-artifact-1.1/pom.xml b/policy-core/drools-artifact-1.1/pom.xml new file mode 100644 index 00000000..24a6d37d --- /dev/null +++ b/policy-core/drools-artifact-1.1/pom.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + ONAP Policy Engine - Drools PDP + ================================================================================ + 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========================================================= + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <artifactId>drools-artifact1</artifactId> + <version>17.1.0-SNAPSHOT</version> + <description>supports Junit tests in policy-core</description> + + <parent> + <groupId>org.onap.policy.drools-pdp</groupId> + <artifactId>drools-pdp</artifactId> + <version>1.1.0-SNAPSHOT</version> + </parent> +</project> diff --git a/policy-core/drools-artifact-1.1/src/main/resources/META-INF/kmodule.xml b/policy-core/drools-artifact-1.1/src/main/resources/META-INF/kmodule.xml new file mode 100644 index 00000000..22319689 --- /dev/null +++ b/policy-core/drools-artifact-1.1/src/main/resources/META-INF/kmodule.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule"> + <kbase name="rules"> + <ksession name="session1"/> + </kbase> +</kmodule> diff --git a/policy-core/drools-artifact-1.1/src/main/resources/rules.drl b/policy-core/drools-artifact-1.1/src/main/resources/rules.drl new file mode 100644 index 00000000..9dac208b --- /dev/null +++ b/policy-core/drools-artifact-1.1/src/main/resources/rules.drl @@ -0,0 +1,30 @@ +package org.onap.policy.drools.core.test; + +rule "Initialization" + when + then + { + System.out.println("Initialization rule running"); + } +end + +rule "Add 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 sum = 0; + for (int i = 1 ; i < array.length ; i += 1) + { + sum += array[i]; + } + array[0] = sum; + retract($object); + } + } +end diff --git a/policy-core/drools-artifact-1.2/pom.xml b/policy-core/drools-artifact-1.2/pom.xml new file mode 100644 index 00000000..6b39d7c4 --- /dev/null +++ b/policy-core/drools-artifact-1.2/pom.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + ONAP Policy Engine - Drools PDP + ================================================================================ + 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========================================================= + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <artifactId>drools-artifact1</artifactId> + <version>17.2.0-SNAPSHOT</version> + <description>supports Junit tests in policy-core</description> + + <parent> + <groupId>org.onap.policy.drools-pdp</groupId> + <artifactId>drools-pdp</artifactId> + <version>1.1.0-SNAPSHOT</version> + </parent> +</project> diff --git a/policy-core/drools-artifact-1.2/src/main/resources/META-INF/kmodule.xml b/policy-core/drools-artifact-1.2/src/main/resources/META-INF/kmodule.xml new file mode 100644 index 00000000..22319689 --- /dev/null +++ b/policy-core/drools-artifact-1.2/src/main/resources/META-INF/kmodule.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule"> + <kbase name="rules"> + <ksession name="session1"/> + </kbase> +</kmodule> diff --git a/policy-core/drools-artifact-1.2/src/main/resources/rules.drl b/policy-core/drools-artifact-1.2/src/main/resources/rules.drl new file mode 100644 index 00000000..e69b6597 --- /dev/null +++ b/policy-core/drools-artifact-1.2/src/main/resources/rules.drl @@ -0,0 +1,29 @@ +package org.onap.policy.drools.core.test; + +rule "Initialization" + when + then + { + System.out.println("Initialization rule running"); + } +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; + } + } +end diff --git a/policy-core/pom.xml b/policy-core/pom.xml index 076a4bf2..53e6f4aa 100644 --- a/policy-core/pom.xml +++ b/policy-core/pom.xml @@ -30,6 +30,57 @@ <version>1.1.0-SNAPSHOT</version> </parent> + <build> + <plugins> + + <!-- + 'maven-invoker-plugin' is used to build and install two versions of a + Drools artifact, both of which are used in Junit tests. These Maven + projects are invisible to Sonar and SonarQube, so there are no + complaints about multiple projects with the same artifact, and they + don't show up in the list of files or code line counts. + --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-invoker-plugin</artifactId> + <version>3.0.1</version> + <executions> + + <execution> + <id>drools-artifact-1.1</id> + <goals> + <goal>run</goal> + </goals> + <phase>test-compile</phase> + <configuration> + <pom>drools-artifact-1.1/pom.xml</pom> + <goals> + <goal>install</goal> + </goals> + <streamLogs>true</streamLogs> + </configuration> + </execution> + + <execution> + <id>drools-artifact-1.2</id> + <goals> + <goal>run</goal> + </goals> + <phase>test-compile</phase> + <configuration> + <pom>drools-artifact-1.2/pom.xml</pom> + <goals> + <goal>install</goal> + </goals> + <streamLogs>true</streamLogs> + </configuration> + </execution> + + </executions> + </plugin> + </plugins> + </build> + <dependencies> <dependency> <groupId>org.kie</groupId> @@ -61,5 +112,5 @@ <artifactId>junit</artifactId> <scope>test</scope> </dependency> - </dependencies> + </dependencies> </project> 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<PolicyContainer> 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<PolicySession> 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<PolicyContainer> 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<PolicySession> 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<String> buildArrayList(String... args) + { + ArrayList<String> 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<String> 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<String> getLog() + { + synchronized(log) + { + ArrayList<String> 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 |