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>
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 0000000..24a6d37
--- /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 0000000..2231968
--- /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 0000000..9dac208
--- /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 0000000..6b39d7c
--- /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 0000000..2231968
--- /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 0000000..e69b659
--- /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 076a4bf..53e6f4a 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 0000000..e83f026
--- /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 0000000..f456d81
--- /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 0000000..d6b088c
--- /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