aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--policy-core/pom.xml4
-rw-r--r--policy-core/src/main/java/org/onap/policy/drools/core/PolicyContainer.java149
-rw-r--r--policy-core/src/test/java/org/onap/policy/drools/core/DroolsContainerTest.java106
-rw-r--r--policy-core/src/test/java/org/onap/policy/drools/core/PolicyContainerTest.java230
-rw-r--r--policy-core/src/test/java/org/onap/policy/drools/core/PolicySessionFeatureApiMock.java6
-rw-r--r--policy-core/src/test/java/org/onap/policy/drools/core/jmx/PdpJmxListenerTest.java66
-rw-r--r--policy-core/src/test/java/org/onap/policy/drools/core/lock/AlwaysFailLockTest.java6
-rw-r--r--policy-core/src/test/java/org/onap/policy/drools/core/lock/AlwaysSuccessLockTest.java25
-rw-r--r--policy-management/src/main/java/org/onap/policy/drools/system/internal/LockManager.java3
-rw-r--r--policy-management/src/test/java/org/onap/policy/drools/controller/internal/NullDroolsControllerTest.java89
-rw-r--r--policy-management/src/test/java/org/onap/policy/drools/system/PolicyEngineManagerTest.java166
-rw-r--r--policy-utils/pom.xml4
-rw-r--r--policy-utils/src/main/java/org/onap/policy/drools/metrics/Metric.java4
-rw-r--r--policy-utils/src/main/java/org/onap/policy/drools/policies/DomainMaker.java27
-rw-r--r--policy-utils/src/test/java/org/onap/policy/drools/metrics/MetricTest.java32
-rw-r--r--policy-utils/src/test/java/org/onap/policy/drools/policies/DomainMakerTest.java72
-rw-r--r--policy-utils/src/test/java/org/onap/policy/drools/utils/LookupTest.java57
-rw-r--r--policy-utils/src/test/java/org/onap/policy/drools/utils/PropertyUtilTest.java125
18 files changed, 858 insertions, 313 deletions
diff --git a/policy-core/pom.xml b/policy-core/pom.xml
index 57fd613c..9eb0af1a 100644
--- a/policy-core/pom.xml
+++ b/policy-core/pom.xml
@@ -133,6 +133,10 @@
<groupId>org.glassfish.hk2.external</groupId>
<artifactId>jakarta.inject</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-test</artifactId>
+ </dependency>
</dependencies>
</project>
diff --git a/policy-core/src/main/java/org/onap/policy/drools/core/PolicyContainer.java b/policy-core/src/main/java/org/onap/policy/drools/core/PolicyContainer.java
index ec5ceb21..533ac223 100644
--- a/policy-core/src/main/java/org/onap/policy/drools/core/PolicyContainer.java
+++ b/policy-core/src/main/java/org/onap/policy/drools/core/PolicyContainer.java
@@ -28,6 +28,8 @@ import java.util.HashSet;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import lombok.Getter;
+import lombok.NonNull;
+import org.apache.commons.lang3.StringUtils;
import org.kie.api.KieServices;
import org.kie.api.builder.KieScanner;
import org.kie.api.builder.Message;
@@ -49,13 +51,13 @@ public class PolicyContainer implements Startable {
// get an instance of logger
private static final Logger logger = LoggerFactory.getLogger(PolicyContainer.class);
// 'KieServices' singleton
- private static KieServices kieServices = KieServices.Factory.get();
+ private static final KieServices kieServices = KieServices.Factory.get();
// set of all 'PolicyContainer' instances
private static final HashSet<PolicyContainer> containers = new HashSet<>();
// maps feature objects to per-PolicyContainer data
- private ConcurrentHashMap<Object, Object> adjuncts = new ConcurrentHashMap<>();
+ private final ConcurrentHashMap<Object, Object> adjuncts = new ConcurrentHashMap<>();
// 'KieContainer' associated with this 'PolicyContainer'
@Getter
@@ -90,9 +92,9 @@ public class PolicyContainer implements Startable {
*
* <p>An exception occurs if the creation of the 'KieContainer' fails.
*
- * @param groupId the 'groupId' associated with the artifact
+ * @param groupId the 'groupId' associated with the artifact
* @param artifactId the artifact name
- * @param version a comma-separated list of possible versions
+ * @param version a comma-separated list of possible versions
*/
public PolicyContainer(String groupId, String artifactId, String version) {
this(kieServices.newReleaseId(groupId, artifactId, version));
@@ -112,7 +114,7 @@ public class PolicyContainer implements Startable {
if (newReleaseId.getVersion().contains(",")) {
// this is actually a comma-separated list of release ids
newReleaseId =
- loadArtifact(newReleaseId.getGroupId(), newReleaseId.getArtifactId(), newReleaseId.getVersion());
+ loadArtifact(newReleaseId.getGroupId(), newReleaseId.getArtifactId(), newReleaseId.getVersion());
} else {
kieContainer = kieServices.newKieContainer(newReleaseId);
}
@@ -138,9 +140,9 @@ public class PolicyContainer implements Startable {
* Load an artifact into a new KieContainer. This method handles the case where the 'version' is
* actually a comma-separated list of versions.
*
- * @param groupId the 'groupId' associated with the artifact
+ * @param groupId the 'groupId' associated with the artifact
* @param artifactId the artifact name
- * @param version a comma-separated list of possible versions
+ * @param version a comma-separated list of possible versions
*/
private ReleaseId loadArtifact(String groupId, String artifactId, String version) {
String[] versions = version.split(",");
@@ -180,15 +182,11 @@ public class PolicyContainer implements Startable {
}
/**
- * Get name.
+ * Get name in the form of (groupId + ":" + artifactId + ":" + version)
+ * Note that the name changes after a successful call to 'updateToVersion', although
+ * typically only the 'version' part changes.
*
- * @return the name of the container, which is the String equivalent of the 'ReleaseId'. It has
- * the form:
- *
- * (groupId + ":" + artifactId + ":" + version)
- *
- * Note that the name changes after a successful call to 'updateToVersion', although
- * typically only the 'version' part changes.
+ * @return the name of the container, which is the String equivalent of the 'ReleaseId'.
*/
public String getName() {
return kieContainer.getReleaseId().toString();
@@ -204,7 +202,7 @@ public class PolicyContainer implements Startable {
}
/**
- * Get group Id.
+ * Get group id.
*
* @return the Maven GroupId of the top-level artifact wrapped by the container.
*/
@@ -235,7 +233,7 @@ public class PolicyContainer implements Startable {
* Fetch the named 'PolicySession'.
*
* @param name the name of the KieSession (which is also the name of the associated
- * PolicySession)
+ * PolicySession)
* @return a PolicySession if found, 'null' if not
*/
public PolicySession getPolicySession(String name) {
@@ -245,7 +243,7 @@ public class PolicyContainer implements Startable {
/**
* Internal method to create a PolicySession, possibly restoring it from persistent storage.
*
- * @param name of the KieSession and PolicySession
+ * @param name of the KieSession and PolicySession
* @param kieBaseName name of the associated 'KieBase' instance
* @return a new or existing PolicySession, or 'null' if not found
*/
@@ -255,7 +253,7 @@ public class PolicyContainer implements Startable {
PolicySession session = sessions.computeIfAbsent(name, key -> makeSession(name, kieBaseName));
logger.info("activatePolicySession:session - {} is returned.",
- session == null ? "null" : session.getFullName());
+ session == null ? "null" : session.getFullName());
return session;
}
}
@@ -307,30 +305,32 @@ public class PolicyContainer implements Startable {
* provides a way for 'KieSession' instances that are created programmatically to fit into this
* framework.
*
- * @param name the name for the new 'PolicySession'
+ * @param name the name for the new 'PolicySession'
* @param kieSession a 'KieSession' instance, that will be included in this infrastructure
* @return the new 'PolicySession'
* @throws IllegalArgumentException if 'kieSession' does not reside within this container
- * @throws IllegalStateException if a 'PolicySession' already exists with this name
+ * @throws IllegalStateException if a 'PolicySession' already exists with this name
*/
public PolicySession adoptKieSession(String name, KieSession kieSession) {
- if (name == null) {
+ if (StringUtils.isBlank(name)) {
logger.warn("adoptKieSession:input name is null");
throw new IllegalArgumentException("KieSession input name is null " + getName());
- } else if (kieSession == null) {
+ }
+
+ if (kieSession == null) {
logger.warn("adoptKieSession:input kieSession is null");
throw new IllegalArgumentException("KieSession '" + name + "' is null " + getName());
- } else {
- logger.info("adoptKieSession:name: {} kieSession: {}", name, kieSession);
}
+
+ logger.info("adoptKieSession:name: {} kieSession: {}", name, kieSession);
// fetch KieBase, and verify it belongs to this KieContainer
var match = false;
var kieBase = kieSession.getKieBase();
logger.info("adoptKieSession:kieBase: {}", kieBase);
for (String kieBaseName : kieContainer.getKieBaseNames()) {
logger.info("adoptKieSession:kieBaseName: {}", kieBaseName);
- if (kieBase == kieContainer.getKieBase(kieBaseName)) {
+ if (kieBase.equals(kieContainer.getKieBase(kieBaseName))) {
match = true;
break;
}
@@ -338,9 +338,9 @@ public class PolicyContainer implements Startable {
logger.info("adoptKieSession:match {}", match);
// if we don't have a match yet, the last chance is to look at the
// default KieBase, if it exists
- if (!match && kieBase != kieContainer.getKieBase()) {
+ if (!match && !kieBase.equals(kieContainer.getKieBase())) {
throw new IllegalArgumentException(
- "KieSession '" + name + "' does not reside within container " + getName());
+ "KieSession '" + name + "' does not reside within container " + getName());
}
synchronized (sessions) {
@@ -370,15 +370,13 @@ public class PolicyContainer implements Startable {
* This call 'KieContainer.updateToVersion()', and returns the associated response as a String.
* If successful, the name of this 'PolicyContainer' changes to match the new version.
*
- * @param newVersion this is the version to update to (the 'groupId' and 'artifactId' remain the
- * same)
- * @return the list of messages associated with the update (not sure if this can be 'null', or
- * how to determine success/failure)
+ * @param newVersion this is the version to update to ('groupId' and 'artifactId' remain the same)
+ * @return the list of messages associated with the update
*/
public String updateToVersion(String newVersion) {
var releaseId = kieContainer.getReleaseId();
- var results = this.updateToVersion(
- kieServices.newReleaseId(releaseId.getGroupId(), releaseId.getArtifactId(), newVersion));
+ var results = this.updateToVersion(kieServices.newReleaseId(releaseId.getGroupId(),
+ releaseId.getArtifactId(), newVersion));
List<Message> messages = results == null ? null : results.getMessages();
return messages == null ? null : messages.toString();
@@ -455,46 +453,46 @@ public class PolicyContainer implements Startable {
*
* @param releaseId the release id used to create the container
*/
- public synchronized void startScanner(ReleaseId releaseId) {
+ public synchronized void startScanner(@NonNull ReleaseId releaseId) {
String version = releaseId.getVersion();
- if (scannerStarted || scanner != null || version == null) {
+ if (!isValidVersion(version)) {
+ logger.warn("version is invalid - check if empty or if it's not LATEST, RELEASE or SNAPSHOT");
return;
}
- if (!("LATEST".equals(version) || "RELEASE".equals(version) || version.endsWith("-SNAPSHOT"))) {
+ if (isScannerStarted()) {
+ logger.warn("scanner already started");
return;
}
// create the scanner, and poll at 60 second intervals
- try {
- scannerStarted = true;
- // start this in a separate thread -- it can block for a long time
- new Thread("Scanner Starter " + getName()) {
- @Override
- public void run() {
+ scannerStarted = true;
+
+ // start this in a separate thread -- it can block for a long time
+ new Thread("Scanner Starter " + getName()) {
+ @Override
+ public void run() {
+ try {
scanner = kieServices.newKieScanner(kieContainer);
scanner.start(60000L);
+ } catch (Exception e) {
+ // sometimes the scanner initialization fails for some reason
+ logger.error("startScanner error", e);
}
- }.start();
- } catch (Exception e) {
- // sometimes the scanner initialization fails for some reason
- logger.error("startScanner error", e);
- }
+ }
+ }.start();
}
/**
* Insert a fact into a specific named session.
*
- * @param name this is the session name
+ * @param name this is the session name
* @param object this is the fact to be inserted into the session
* @return 'true' if the named session was found, 'false' if not
*/
public boolean insert(String name, Object object) {
- // TODO: Should the definition of 'name' be expanded to include an
- // alternate entry point as well? For example, 'name.entryPoint' (or
- // something other than '.' if that is a problem).
synchronized (sessions) {
PolicySession session = sessions.get(name);
if (session != null) {
@@ -568,7 +566,7 @@ public class PolicyContainer implements Startable {
Collection<PolicySession> localSessions;
synchronized (sessions) {
- // local set containing all of the sessions
+ // local set containing all the sessions
localSessions = new HashSet<>(sessions.values());
// clear the 'name->session' map in 'PolicyContainer'
@@ -631,7 +629,7 @@ public class PolicyContainer implements Startable {
Collection<PolicySession> localSessions;
synchronized (sessions) {
- // local set containing all of the sessions
+ // local set containing all the sessions
localSessions = new HashSet<>(sessions.values());
// clear the 'name->session' map in 'PolicyContainer'
@@ -667,7 +665,7 @@ public class PolicyContainer implements Startable {
* This method is called when the host goes from the 'standby->active' state.
*/
public static void activate() {
- // start all of the 'PolicyContainer' instances
+ // start all the 'PolicyContainer' instances
for (PolicyContainer container : containers) {
try {
container.start();
@@ -681,7 +679,7 @@ public class PolicyContainer implements Startable {
* This method is called when the host goes from the 'active->standby' state.
*/
public static void deactivate() {
- // deactivate all of the 'PolicyContainer' instances
+ // deactivate all the 'PolicyContainer' instances
for (PolicyContainer container : containers) {
try {
container.stop();
@@ -694,7 +692,7 @@ public class PolicyContainer implements Startable {
/**
* This method does the following:
*
- * <p>1) Initializes logging 2) Starts the DroolsPDP Integrity Monitor 3) Initilaizes persistence
+ * <p>1) Initializes logging 2) Starts the DroolsPDP Integrity Monitor 3) Initializes persistence
*
* <p>It no longer reads in properties files, o creates 'PolicyContainer' instances.
*
@@ -718,7 +716,7 @@ public class PolicyContainer implements Startable {
* Fetch the adjunct object associated with a given feature.
*
* @param object this is typically the singleton feature object that is used as a key, but it
- * might also be useful to use nested objects within the feature as keys.
+ * might also be useful to use nested objects within the feature as keys.
* @return a feature-specific object associated with the key, or 'null' if it is not found.
*/
public Object getAdjunct(Object object) {
@@ -729,9 +727,9 @@ public class PolicyContainer implements Startable {
* Store the adjunct object associated with a given feature.
*
* @param object this is typically the singleton feature object that is used as a key, but it
- * might also be useful to use nested objects within the feature as keys.
- * @param value a feature-specific object associated with the key, or 'null' if the
- * feature-specific object should be removed
+ * might also be useful to use nested objects within the feature as keys.
+ * @param value a feature-specific object associated with the key, or 'null' if the
+ * feature-specific object should be removed
*/
public void setAdjunct(Object object, Object value) {
if (value == null) {
@@ -768,4 +766,33 @@ public class PolicyContainer implements Startable {
KieUtils.addKiePackages(kieContainer.getKieBase(name), kiePackages);
}
}
+
+ /**
+ * Checks if boolean scannerStarted is true and if scanner itself is not null.
+ *
+ * @return true if the above is all true, false otherwise.
+ */
+ public boolean isScannerStarted() {
+ return scannerStarted || scanner != null;
+ }
+
+ /**
+ * Validation of a release version for starting a scanner.
+ * Can be valid if LATEST, RELEASE or SNAPSHOT version.
+ *
+ * @param version release version
+ * @return true if valid based on values above, false otherwise.
+ */
+ protected boolean isValidVersion(String version) {
+ if (StringUtils.isBlank(version)) {
+ logger.warn("version is empty");
+ return false;
+ }
+
+ if (version.toUpperCase().contains("LATEST") || version.toUpperCase().contains("RELEASE")) {
+ return true;
+ } else {
+ return version.toUpperCase().endsWith("-SNAPSHOT");
+ }
+ }
}
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
index abed9727..d6804b60 100644
--- 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
@@ -79,44 +79,7 @@ public class DroolsContainerTest {
*/
@Test
void createAndUpdate() throws Exception {
- // make sure feature log starts out clean
- PolicySessionFeatureApiMock.getLog();
-
- // run 'globalInit', and verify expected feature hook fired
- PolicyContainer.globalInit(new String[0]);
- assertEquals(List.of("globalInit"),
- PolicySessionFeatureApiMock.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(Arrays.asList("activatePolicySession",
- "newPolicySession",
- "selectThreadModel"),
- PolicySessionFeatureApiMock.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());
+ PolicyContainer container = validateCreatedContainer();
try {
// fetch the session, and verify that it exists
@@ -225,20 +188,17 @@ public class DroolsContainerTest {
// run 'globalInit', and verify expected feature hook fired
PolicyContainer.globalInit(new String[0]);
- assertEquals(List.of("globalInit-exception"),
- PolicySessionFeatureApiMock.getLog());
+ assertEquals(List.of("globalInit-exception"), PolicySessionFeatureApiMock.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";
+ 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);
+ new PolicyContainer("org.onap.policy.drools-pdp", "drools-artifact1", versionList);
// the following should be equivalent to 'container.start()'
PolicyContainer.activate();
assertTrue(container.isAlive());
@@ -251,15 +211,12 @@ public class DroolsContainerTest {
// this container should be on the list
{
- Collection<PolicyContainer> containers =
- PolicyContainer.getPolicyContainers();
- assertEquals(1, containers.size());
- assertTrue(containers.contains(container));
+ Collection<PolicyContainer> containers = PolicyContainer.getPolicyContainers();
+ assertTrue(containers.contains(container) && (containers.size() == 1));
}
// verify initial container attributes
- assertEquals("org.onap.policy.drools-pdp:drools-artifact1:17.1.0-SNAPSHOT",
- container.getName());
+ 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());
@@ -288,8 +245,7 @@ public class DroolsContainerTest {
// 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));
+ assertTrue(sessions.contains(session) && (1 == sessions.size()));
}
// verify session attributes
@@ -341,4 +297,50 @@ public class DroolsContainerTest {
// final conditions -- there should be no containers
assertEquals(0, PolicyContainer.getPolicyContainers().size());
}
+
+ /**
+ * Creates a policy container.
+ * @return a container used on create and update test
+ */
+ private static PolicyContainer validateCreatedContainer() {
+ // make sure feature log starts out clean
+ PolicySessionFeatureApiMock.getLog();
+
+ // run 'globalInit', and verify expected feature hook fired
+ PolicyContainer.globalInit(new String[0]);
+ assertEquals(List.of("globalInit"),
+ PolicySessionFeatureApiMock.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(Arrays.asList("activatePolicySession",
+ "newPolicySession",
+ "selectThreadModel"),
+ PolicySessionFeatureApiMock.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());
+ return container;
+ }
}
diff --git a/policy-core/src/test/java/org/onap/policy/drools/core/PolicyContainerTest.java b/policy-core/src/test/java/org/onap/policy/drools/core/PolicyContainerTest.java
new file mode 100644
index 00000000..72c8d2d3
--- /dev/null
+++ b/policy-core/src/test/java/org/onap/policy/drools/core/PolicyContainerTest.java
@@ -0,0 +1,230 @@
+/*-
+ * ============LICENSE_START================================================
+ * policy-core
+ * =========================================================================
+ * Copyright (C) 2024 Nordix Foundation.
+ * =========================================================================
+ * 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.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.doCallRealMethod;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.HashMap;
+import java.util.List;
+import org.junit.jupiter.api.Test;
+import org.kie.api.KieBase;
+import org.kie.api.KieServices;
+import org.kie.api.builder.KieScanner;
+import org.kie.api.builder.ReleaseId;
+import org.kie.api.event.rule.AgendaEventListener;
+import org.kie.api.event.rule.RuleRuntimeEventListener;
+import org.kie.api.runtime.KieContainer;
+import org.kie.api.runtime.KieSession;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+import org.springframework.test.util.ReflectionTestUtils;
+
+class PolicyContainerTest {
+
+ private static final String VERSION = "1.0.0";
+
+ @Test
+ void adoptKieSession_Exceptions() {
+ var mockKieSession = mock(KieSession.class);
+ var policyContainer = mock(PolicyContainer.class);
+
+ when(policyContainer.getName()).thenReturn("kieReleaseName");
+ when(policyContainer.adoptKieSession(any(), eq(mockKieSession))).thenCallRealMethod();
+ when(policyContainer.adoptKieSession("name", null)).thenCallRealMethod();
+
+ assertThatThrownBy(() -> policyContainer.adoptKieSession("", mockKieSession))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("KieSession input name is null kieReleaseName");
+
+ assertThatThrownBy(() -> policyContainer.adoptKieSession(null, mockKieSession))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("KieSession input name is null kieReleaseName");
+
+ assertThatThrownBy(() -> policyContainer.adoptKieSession("name", null))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("KieSession 'name' is null kieReleaseName");
+ }
+
+ @Test
+ void testAdoptKieSession() {
+ var mockKieSession = mock(KieSession.class);
+ doNothing().when(mockKieSession).addEventListener(any(AgendaEventListener.class));
+ doNothing().when(mockKieSession).addEventListener(any(RuleRuntimeEventListener.class));
+
+ var policyContainer = mock(PolicyContainer.class);
+ when(policyContainer.adoptKieSession("name", mockKieSession)).thenCallRealMethod();
+ when(policyContainer.getName()).thenReturn("kieReleaseName");
+
+ var mockKieBase = mock(KieBase.class);
+ when(mockKieSession.getKieBase()).thenReturn(mockKieBase);
+
+ var mockKieContainer = mock(KieContainer.class);
+ when(policyContainer.getKieContainer()).thenReturn(mockKieContainer);
+ when(mockKieContainer.getKieBase("baseName")).thenReturn(mockKieBase);
+ when(mockKieContainer.getKieBaseNames()).thenReturn(List.of("baseName"));
+ when(mockKieContainer.getKieBase()).thenReturn(mockKieBase);
+
+ HashMap<String, PolicySession> sessions = new HashMap<>();
+ ReflectionTestUtils.setField(policyContainer, "sessions", sessions);
+ ReflectionTestUtils.setField(policyContainer, "kieContainer", mockKieContainer);
+
+ assertNotNull(policyContainer.adoptKieSession("name", mockKieSession));
+ assertThatThrownBy(() -> policyContainer.adoptKieSession("name", mockKieSession))
+ .isInstanceOf(IllegalStateException.class)
+ .hasMessageContaining("PolicySession 'name' already exists");
+ }
+
+ @Test
+ void testAdoptKieSession_KieBaseDoesntMatch() {
+ var mockKieSession = mock(KieSession.class);
+
+ var policyContainer = mock(PolicyContainer.class);
+ when(policyContainer.adoptKieSession("name", mockKieSession)).thenCallRealMethod();
+ when(policyContainer.getName()).thenReturn("kieReleaseName");
+
+ var mockKieBase = mock(KieBase.class);
+ when(mockKieSession.getKieBase()).thenReturn(mockKieBase);
+ var mockKieBase2 = mock(KieBase.class);
+
+ var mockKieContainer = mock(KieContainer.class);
+ when(policyContainer.getKieContainer()).thenReturn(mockKieContainer);
+ when(mockKieContainer.getKieBase("baseName")).thenReturn(mockKieBase2);
+ when(mockKieContainer.getKieBaseNames()).thenReturn(List.of("baseName"));
+ when(mockKieContainer.getKieBase()).thenReturn(mockKieBase2);
+
+ ReflectionTestUtils.setField(policyContainer, "kieContainer", mockKieContainer);
+
+ assertThatThrownBy(() -> policyContainer.adoptKieSession("name", mockKieSession))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("KieSession 'name' does not reside within container kieReleaseName");
+ }
+
+ @Test
+ void startScanner_Exceptions() {
+ var policyContainer = mock(PolicyContainer.class);
+ doCallRealMethod().when(policyContainer).startScanner(any(ReleaseId.class));
+ doCallRealMethod().when(policyContainer).startScanner(isNull());
+ when(policyContainer.isScannerStarted()).thenCallRealMethod();
+
+ assertThatThrownBy(() -> policyContainer.startScanner(null))
+ .hasMessageContaining("releaseId is marked non-null but is null");
+ assertFalse(policyContainer.isScannerStarted());
+
+ // shouldn't throw exception, but won't start scanner as version is null
+ var mockVersionNull = mock(ReleaseId.class);
+ when(mockVersionNull.getVersion()).thenReturn(null);
+ when(policyContainer.isValidVersion(isNull())).thenCallRealMethod();
+ assertDoesNotThrow(() -> policyContainer.startScanner(mockVersionNull));
+ assertFalse(policyContainer.isScannerStarted());
+
+ var mockVersionSnapshot = mock(ReleaseId.class);
+ when(mockVersionSnapshot.getVersion()).thenReturn(VERSION);
+ when(policyContainer.isValidVersion(VERSION)).thenCallRealMethod();
+ assertDoesNotThrow(() -> policyContainer.startScanner(mockVersionSnapshot));
+ assertFalse(policyContainer.isScannerStarted());
+ }
+
+ @Test
+ void startScanner_SnapshotVersion() {
+ var policyContainer = mock(PolicyContainer.class);
+ when(policyContainer.isScannerStarted()).thenCallRealMethod();
+ when(policyContainer.isValidVersion(VERSION + "-SNAPSHOT")).thenCallRealMethod();
+
+ var mockVersionSnapshot = mock(ReleaseId.class);
+ when(mockVersionSnapshot.getVersion()).thenReturn(VERSION + "-SNAPSHOT");
+
+ doCallRealMethod().when(policyContainer).startScanner(mockVersionSnapshot);
+
+ assertDoesNotThrow(() -> policyContainer.startScanner(mockVersionSnapshot));
+ assertTrue(policyContainer.isScannerStarted());
+ }
+
+ @Test
+ void startScanner_LatestVersion() {
+ var policyContainer = mock(PolicyContainer.class);
+ when(policyContainer.isScannerStarted()).thenCallRealMethod();
+ when(policyContainer.isValidVersion(anyString())).thenCallRealMethod();
+
+ var mockLatestVersion = mock(ReleaseId.class);
+ when(mockLatestVersion.getVersion()).thenReturn(VERSION + "LATEST");
+
+ doCallRealMethod().when(policyContainer).startScanner(mockLatestVersion);
+
+ assertDoesNotThrow(() -> policyContainer.startScanner(mockLatestVersion));
+ assertTrue(policyContainer.isScannerStarted());
+ }
+
+ @Test
+ void startScanner_ReleaseVersion() {
+ var mockKieServices = mock(KieServices.class);
+ when(mockKieServices.newKieScanner(any(KieContainer.class))).thenReturn(mock(KieScanner.class));
+
+ try (MockedStatic<KieServices.Factory> factory = Mockito.mockStatic(KieServices.Factory.class)) {
+ factory.when(KieServices.Factory::get).thenReturn(mockKieServices);
+ assertEquals(mockKieServices, KieServices.Factory.get());
+
+ var policyContainer = mock(PolicyContainer.class);
+ when(policyContainer.isScannerStarted()).thenCallRealMethod();
+ when(policyContainer.isValidVersion(VERSION + "RELEASE")).thenCallRealMethod();
+
+ var mockLatestVersion = mock(ReleaseId.class);
+ when(mockLatestVersion.getVersion()).thenReturn(VERSION + "RELEASE");
+
+ doCallRealMethod().when(policyContainer).startScanner(mockLatestVersion);
+
+ assertDoesNotThrow(() -> policyContainer.startScanner(mockLatestVersion));
+ assertTrue(policyContainer.isScannerStarted());
+
+ // try again, but should come out at checking if scanner is already started.
+ assertDoesNotThrow(() -> policyContainer.startScanner(mockLatestVersion));
+ }
+ }
+
+ @Test
+ void insert() {
+ var policyContainer = mock(PolicyContainer.class);
+ var object = new Object();
+ when(policyContainer.insert("name", object)).thenCallRealMethod();
+
+ HashMap<String, PolicySession> sessions = new HashMap<>();
+ ReflectionTestUtils.setField(policyContainer, "sessions", sessions);
+
+ assertFalse(policyContainer.insert("name", object));
+ }
+
+ @Test
+ void deactivate() {
+ assertDoesNotThrow(PolicyContainer::deactivate);
+ }
+} \ No newline at end of file
diff --git a/policy-core/src/test/java/org/onap/policy/drools/core/PolicySessionFeatureApiMock.java b/policy-core/src/test/java/org/onap/policy/drools/core/PolicySessionFeatureApiMock.java
index d8257067..f0e5b516 100644
--- a/policy-core/src/test/java/org/onap/policy/drools/core/PolicySessionFeatureApiMock.java
+++ b/policy-core/src/test/java/org/onap/policy/drools/core/PolicySessionFeatureApiMock.java
@@ -86,6 +86,7 @@ public class PolicySessionFeatureApiMock implements PolicySessionFeatureApi {
/**
* {@inheritDoc}.
*/
+ @Override
public void globalInit(String[] args, String configDir) {
addLog("globalInit");
}
@@ -93,6 +94,7 @@ public class PolicySessionFeatureApiMock implements PolicySessionFeatureApi {
/**
* {@inheritDoc}.
*/
+ @Override
public KieSession activatePolicySession(PolicyContainer policyContainer, String name, String kieBaseName) {
addLog("activatePolicySession");
return null;
@@ -101,6 +103,7 @@ public class PolicySessionFeatureApiMock implements PolicySessionFeatureApi {
/**
* {@inheritDoc}.
*/
+ @Override
public void newPolicySession(PolicySession policySession) {
addLog("newPolicySession");
}
@@ -108,6 +111,7 @@ public class PolicySessionFeatureApiMock implements PolicySessionFeatureApi {
/**
* {@inheritDoc}.
*/
+ @Override
public PolicySession.ThreadModel selectThreadModel(PolicySession session) {
addLog("selectThreadModel");
return null;
@@ -116,6 +120,7 @@ public class PolicySessionFeatureApiMock implements PolicySessionFeatureApi {
/**
* {@inheritDoc}.
*/
+ @Override
public void disposeKieSession(PolicySession policySession) {
addLog("disposeKieSession");
}
@@ -123,6 +128,7 @@ public class PolicySessionFeatureApiMock implements PolicySessionFeatureApi {
/**
* {@inheritDoc}.
*/
+ @Override
public void destroyKieSession(PolicySession policySession) {
addLog("destroyKieSession");
}
diff --git a/policy-core/src/test/java/org/onap/policy/drools/core/jmx/PdpJmxListenerTest.java b/policy-core/src/test/java/org/onap/policy/drools/core/jmx/PdpJmxListenerTest.java
new file mode 100644
index 00000000..d81dc3e9
--- /dev/null
+++ b/policy-core/src/test/java/org/onap/policy/drools/core/jmx/PdpJmxListenerTest.java
@@ -0,0 +1,66 @@
+/*-
+ * ============LICENSE_START===============================================
+ * ONAP
+ * ========================================================================
+ * Copyright (C) 2024 Nordix Foundation.
+ * ========================================================================
+ * 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.jupiter.api.Assertions.assertEquals;
+
+import java.lang.management.ManagementFactory;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanRegistrationException;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.NotCompliantMBeanException;
+import javax.management.ObjectName;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+
+class PdpJmxListenerTest {
+
+ @Test
+ void test() {
+ Assertions.assertDoesNotThrow(PdpJmxListener::start);
+ Assertions.assertDoesNotThrow(PdpJmxListener::stop);
+ }
+
+ @Test
+ void testExceptions()
+ throws MalformedObjectNameException, NotCompliantMBeanException, InstanceAlreadyExistsException,
+ MBeanRegistrationException, InstanceNotFoundException {
+
+ var mockMBean = Mockito.mock(MBeanServer.class);
+ Mockito.doThrow(MBeanRegistrationException.class).when(mockMBean)
+ .registerMBean(PdpJmx.getInstance(), new ObjectName("PolicyEngine:type=PdpJmx"));
+ Mockito.doThrow(MBeanRegistrationException.class).when(mockMBean)
+ .unregisterMBean(new ObjectName("PolicyEngine:type=PdpJmx"));
+
+ // trying to reach exception catch clause, but can't validate if exception was thrown
+ try (MockedStatic<ManagementFactory> factory = Mockito.mockStatic(ManagementFactory.class)) {
+ factory.when(ManagementFactory::getPlatformMBeanServer).thenReturn(mockMBean);
+ assertEquals(mockMBean, ManagementFactory.getPlatformMBeanServer());
+
+ Assertions.assertDoesNotThrow(PdpJmxListener::start);
+ Assertions.assertDoesNotThrow(PdpJmxListener::stop);
+ }
+ }
+} \ No newline at end of file
diff --git a/policy-core/src/test/java/org/onap/policy/drools/core/lock/AlwaysFailLockTest.java b/policy-core/src/test/java/org/onap/policy/drools/core/lock/AlwaysFailLockTest.java
index 51273d7d..02c3fead 100644
--- a/policy-core/src/test/java/org/onap/policy/drools/core/lock/AlwaysFailLockTest.java
+++ b/policy-core/src/test/java/org/onap/policy/drools/core/lock/AlwaysFailLockTest.java
@@ -22,6 +22,7 @@
package org.onap.policy.drools.core.lock;
import static org.assertj.core.api.Assertions.assertThatCode;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock;
@@ -52,4 +53,9 @@ class AlwaysFailLockTest extends AlwaysLockBaseTest<AlwaysFailLock> {
assertFalse(lock.free());
assertTrue(lock.isUnavailable());
}
+
+ @Test
+ void testExtend() {
+ assertDoesNotThrow(() -> lock.extend(10, callback));
+ }
}
diff --git a/policy-core/src/test/java/org/onap/policy/drools/core/lock/AlwaysSuccessLockTest.java b/policy-core/src/test/java/org/onap/policy/drools/core/lock/AlwaysSuccessLockTest.java
index 80f81f92..0104d0a8 100644
--- a/policy-core/src/test/java/org/onap/policy/drools/core/lock/AlwaysSuccessLockTest.java
+++ b/policy-core/src/test/java/org/onap/policy/drools/core/lock/AlwaysSuccessLockTest.java
@@ -25,6 +25,7 @@ import static org.assertj.core.api.Assertions.assertThatCode;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock;
@@ -67,4 +68,28 @@ class AlwaysSuccessLockTest extends AlwaysLockBaseTest<AlwaysSuccessLock> {
assertEquals(HOLD_SEC2, lock.getHoldSec());
assertSame(callback2, lock.getCallback());
}
+
+ @Test
+ void testNullArgs() {
+ assertThrows(NullPointerException.class,
+ () -> new AlwaysSuccessLock(null, RESOURCE, OWNER_KEY, HOLD_SEC, callback));
+
+ assertThrows(NullPointerException.class,
+ () -> new AlwaysSuccessLock(LockState.WAITING, null, OWNER_KEY, HOLD_SEC, callback));
+
+ assertThrows(NullPointerException.class,
+ () -> new AlwaysSuccessLock(LockState.WAITING, RESOURCE, null, HOLD_SEC, callback));
+
+ assertThrows(NullPointerException.class,
+ () -> new AlwaysSuccessLock(LockState.WAITING, RESOURCE, OWNER_KEY, HOLD_SEC, null));
+
+ assertThrows(NullPointerException.class,
+ () -> new AlwaysSuccessLock(null, OWNER_KEY, HOLD_SEC, callback));
+
+ assertThrows(NullPointerException.class,
+ () -> new AlwaysSuccessLock(RESOURCE, null, HOLD_SEC, callback));
+
+ assertThrows(NullPointerException.class,
+ () -> new AlwaysSuccessLock(RESOURCE, OWNER_KEY, HOLD_SEC, null));
+ }
}
diff --git a/policy-management/src/main/java/org/onap/policy/drools/system/internal/LockManager.java b/policy-management/src/main/java/org/onap/policy/drools/system/internal/LockManager.java
index 1683b0f5..fa264426 100644
--- a/policy-management/src/main/java/org/onap/policy/drools/system/internal/LockManager.java
+++ b/policy-management/src/main/java/org/onap/policy/drools/system/internal/LockManager.java
@@ -3,6 +3,7 @@
* ONAP
* ================================================================================
* Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2024 Nordix Foundation.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -122,7 +123,7 @@ public abstract class LockManager<T extends FeatureLockImpl> implements PolicyRe
/**
* After performing checks, this invokes
* {@link #makeLock(LockState, String, String, int, LockCallback)} to create a lock
- * object, inserts it into the map, and then invokes {@link #finishLock(MgrLock)}.
+ * object, inserts it into the map, and then invokes {@link #finishLock(FeatureLockImpl)}.
*/
@Override
public Lock createLock(String resourceId, String ownerKey, int holdSec, LockCallback callback,
diff --git a/policy-management/src/test/java/org/onap/policy/drools/controller/internal/NullDroolsControllerTest.java b/policy-management/src/test/java/org/onap/policy/drools/controller/internal/NullDroolsControllerTest.java
index f61412d9..ccefcc6f 100644
--- a/policy-management/src/test/java/org/onap/policy/drools/controller/internal/NullDroolsControllerTest.java
+++ b/policy-management/src/test/java/org/onap/policy/drools/controller/internal/NullDroolsControllerTest.java
@@ -22,6 +22,7 @@
package org.onap.policy.drools.controller.internal;
import static org.assertj.core.api.Assertions.assertThatCode;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -36,32 +37,35 @@ import org.onap.policy.drools.controller.DroolsControllerConstants;
class NullDroolsControllerTest {
+ private final NullDroolsController controller = new NullDroolsController();
+ private static final String NULL_EXCEPTION = "marked non-null but is null";
+
@Test
void testStart() {
- DroolsController controller = new NullDroolsController();
- controller.start();
- assertFalse(controller.isAlive());
- controller.stop();
- assertFalse(controller.isAlive());
- controller.shutdown();
- assertFalse(controller.isAlive());
- controller.halt();
- assertFalse(controller.isAlive());
+ DroolsController controller1 = new NullDroolsController();
+ controller1.start();
+ assertFalse(controller1.isAlive());
+ controller1.stop();
+ assertFalse(controller1.isAlive());
+ controller1.shutdown();
+ assertFalse(controller1.isAlive());
+ controller1.halt();
+ assertFalse(controller1.isAlive());
}
@Test
void testSerialize() {
assertThatCode(() -> new GsonTestUtils().compareGson(new NullDroolsController(),
- NullDroolsControllerTest.class)).doesNotThrowAnyException();
+ NullDroolsControllerTest.class)).doesNotThrowAnyException();
}
@Test
void testLock() {
- DroolsController controller = new NullDroolsController();
- controller.lock();
- assertFalse(controller.isLocked());
- controller.unlock();
- assertFalse(controller.isLocked());
+ DroolsController controller1 = new NullDroolsController();
+ controller1.lock();
+ assertFalse(controller1.isLocked());
+ controller1.unlock();
+ assertFalse(controller1.isLocked());
}
@Test
@@ -81,78 +85,75 @@ class NullDroolsControllerTest {
@Test
void getSessionNames() {
- assertTrue(new NullDroolsController().getSessionNames().isEmpty());
+ assertTrue(controller.getSessionNames().isEmpty());
}
@Test
void getCanonicalSessionNames() {
- assertTrue(new NullDroolsController().getCanonicalSessionNames().isEmpty());
+ assertTrue(controller.getCanonicalSessionNames().isEmpty());
}
@Test
void offer() {
- assertFalse(new NullDroolsController().offer(null, null));
+ assertFalse(controller.offer(null, null));
+ assertFalse(controller.offer(null));
}
@Test
void deliver() {
- var controller = new NullDroolsController();
assertThrows(IllegalStateException.class, () -> controller.deliver(null, null));
}
@Test
void getRecentSourceEvents() {
- assertEquals(0, new NullDroolsController().getRecentSourceEvents().length);
+ assertEquals(0, controller.getRecentSourceEvents().length);
}
@Test
void getRecentSinkEvents() {
- assertEquals(0, new NullDroolsController().getRecentSinkEvents().length);
+ assertEquals(0, controller.getRecentSinkEvents().length);
}
@Test
void getContainer() {
- assertNull(new NullDroolsController().getContainer());
+ assertNull(controller.getContainer());
}
@Test
void getDomains() {
- assertTrue(new NullDroolsController().getBaseDomainNames().isEmpty());
+ assertTrue(controller.getBaseDomainNames().isEmpty());
}
@Test
void ownsCoder() {
- var controller = new NullDroolsController();
assertThrows(IllegalStateException.class, () -> controller.ownsCoder(null, 0));
}
@Test
void fetchModelClass() {
- var controller = new NullDroolsController();
var className = this.getClass().getName();
assertThrows(IllegalArgumentException.class, () -> controller.fetchModelClass(className));
}
@Test
void isBrained() {
- assertFalse(new NullDroolsController().isBrained());
+ assertFalse(controller.isBrained());
}
@Test
void stringify() {
- assertNotNull(new NullDroolsController().toString());
+ assertNotNull(controller.toString());
}
@Test
void updateToVersion() {
- var controller = new NullDroolsController();
assertThrows(IllegalArgumentException.class, () ->
controller.updateToVersion(null, null, null, null, null));
}
@Test
void factClassNames() {
- assertTrue(new NullDroolsController().factClassNames(null).isEmpty());
+ assertTrue(controller.factClassNames(null).isEmpty());
}
@Test
@@ -162,18 +163,40 @@ class NullDroolsControllerTest {
@Test
void facts() {
- assertTrue(new NullDroolsController().facts(null, null, true).isEmpty());
+ assertTrue(controller.facts(null, null, true).isEmpty());
+ assertTrue(controller.facts("sessionName", Object.class).isEmpty());
+
+ assertThatThrownBy(() -> controller.facts(null, Object.class)).hasMessageContaining(NULL_EXCEPTION);
+ assertThatThrownBy(() -> controller.facts("sessionName", null)).hasMessageContaining(NULL_EXCEPTION);
}
@Test
void factQuery() {
- assertTrue(new NullDroolsController().factQuery(null, null, null, false).isEmpty());
+ assertTrue(controller.factQuery(null, null, null, false).isEmpty());
}
@Test
void exists() {
Object o1 = new Object();
- assertFalse(new NullDroolsController().exists("blah", o1));
- assertFalse(new NullDroolsController().exists(o1));
+ assertFalse(controller.exists("blah", o1));
+ assertFalse(controller.exists(o1));
+
+ assertThatThrownBy(() -> controller.exists("blah", null)).hasMessageContaining(NULL_EXCEPTION);
+ assertThatThrownBy(() -> controller.exists(null, o1)).hasMessageContaining(NULL_EXCEPTION);
+ assertThatThrownBy(() -> controller.exists(null)).hasMessageContaining(NULL_EXCEPTION);
+ }
+
+ @Test
+ void testDelete() {
+ assertThatThrownBy(() -> controller.delete("sessionName", null)).hasMessageContaining(NULL_EXCEPTION);
+ assertThatThrownBy(() -> controller.delete(null, Object.class)).hasMessageContaining(NULL_EXCEPTION);
+ assertThatThrownBy(() -> controller.delete(null)).hasMessageContaining(NULL_EXCEPTION);
+ Object o1 = null;
+ assertThatThrownBy(() -> controller.delete(o1)).hasMessageContaining(NULL_EXCEPTION);
+
+ assertFalse(controller.delete("sessionName", new Object()));
+ assertFalse(controller.delete("sessionName", Object.class));
+ assertFalse(controller.delete(new Object()));
+ assertFalse(controller.delete(Object.class));
}
}
diff --git a/policy-management/src/test/java/org/onap/policy/drools/system/PolicyEngineManagerTest.java b/policy-management/src/test/java/org/onap/policy/drools/system/PolicyEngineManagerTest.java
index 0b88b3f1..138ad9f8 100644
--- a/policy-management/src/test/java/org/onap/policy/drools/system/PolicyEngineManagerTest.java
+++ b/policy-management/src/test/java/org/onap/policy/drools/system/PolicyEngineManagerTest.java
@@ -102,7 +102,7 @@ class PolicyEngineManagerTest {
private static final Object MY_EVENT = new Object();
private static final GsonTestUtils gson = new GsonMgmtTestBuilder().addTopicSourceMock().addTopicSinkMock()
- .addHttpServletServerMock().build();
+ .addHttpServletServerMock().build();
private Properties properties;
private PolicyEngineFeatureApi prov1;
@@ -579,30 +579,34 @@ class PolicyEngineManagerTest {
verify(prov1).afterConfigure(mgr);
verify(prov2).afterConfigure(mgr);
+ // other tests
+ checkBeforeAfter(
+ (prov, flag) -> when(prov.beforeConfigure(mgr, properties)).thenReturn(flag),
+ (prov, flag) -> when(prov.afterConfigure(mgr)).thenReturn(flag),
+ () -> mgr.configure(properties),
+ prov -> verify(prov).beforeConfigure(mgr, properties),
+ () -> assertSame(properties, mgr.getProperties()),
+ prov -> verify(prov).afterConfigure(mgr));
+ }
+
+ @Test
+ void testConfigureProperties_InvalidProperties() throws Exception {
// middle stuff throws exception - still calls afterXxx
- setUp();
when(endpoint.addTopicSources(properties)).thenThrow(new IllegalArgumentException(EXPECTED));
when(endpoint.addTopicSinks(properties)).thenThrow(new IllegalArgumentException(EXPECTED));
when(serverFactory.build(properties)).thenThrow(new IllegalArgumentException(EXPECTED));
when(clientFactory.build(properties)).thenThrow(new IllegalArgumentException(EXPECTED));
mgr.configure(properties);
verify(prov2).afterConfigure(mgr);
+ }
+ @Test
+ void testConfigureProperties_NullProperties() {
// null properties - nothing should be invoked
- setUp();
Properties nullProps = null;
assertThatIllegalArgumentException().isThrownBy(() -> mgr.configure(nullProps));
verify(prov1, never()).beforeConfigure(mgr, properties);
verify(prov1, never()).afterConfigure(mgr);
-
- // other tests
- checkBeforeAfter(
- (prov, flag) -> when(prov.beforeConfigure(mgr, properties)).thenReturn(flag),
- (prov, flag) -> when(prov.afterConfigure(mgr)).thenReturn(flag),
- () -> mgr.configure(properties),
- prov -> verify(prov).beforeConfigure(mgr, properties),
- () -> assertSame(properties, mgr.getProperties()),
- prov -> verify(prov).afterConfigure(mgr));
}
@Test
@@ -631,17 +635,8 @@ class PolicyEngineManagerTest {
}
@Test
- void testCreatePolicyController() throws Exception {
- assertEquals(controller, mgr.createPolicyController(MY_NAME, properties));
-
- verify(contProv1).beforeCreate(MY_NAME, properties);
- verify(contProv2).beforeCreate(MY_NAME, properties);
- verify(controller, never()).lock();
- verify(contProv1).afterCreate(controller);
- verify(contProv2).afterCreate(controller);
-
+ void testCreatePolicy_FirstProviderThrowsException() {
// first provider throws exceptions - same result
- setUp();
when(contProv1.beforeCreate(MY_NAME, properties)).thenThrow(new RuntimeException(EXPECTED));
when(contProv1.afterCreate(controller)).thenThrow(new RuntimeException(EXPECTED));
assertEquals(controller, mgr.createPolicyController(MY_NAME, properties));
@@ -651,17 +646,11 @@ class PolicyEngineManagerTest {
verify(controller, never()).lock();
verify(contProv1).afterCreate(controller);
verify(contProv2).afterCreate(controller);
+ }
- // locked - same result, but engine locked
- setUp();
- mgr.lock();
- assertEquals(controller, mgr.createPolicyController(MY_NAME, properties));
- verify(contProv1).beforeCreate(MY_NAME, properties);
- verify(controller, times(2)).lock();
- verify(contProv2).afterCreate(controller);
-
+ @Test
+ void testCreatePolicyController_InvalidProperties() throws Exception {
// empty name in properties - same result
- setUp();
properties.setProperty(DroolsPropertyConstants.PROPERTY_CONTROLLER_NAME, "");
assertEquals(controller, mgr.createPolicyController(MY_NAME, properties));
verify(contProv1).beforeCreate(MY_NAME, properties);
@@ -677,6 +666,25 @@ class PolicyEngineManagerTest {
properties.setProperty(DroolsPropertyConstants.PROPERTY_CONTROLLER_NAME, "mistmatched-name");
assertThatIllegalStateException().isThrownBy(() -> mgr.createPolicyController(MY_NAME, properties));
verify(contProv1, never()).beforeCreate(MY_NAME, properties);
+ }
+
+ @Test
+ void testCreatePolicyController() throws Exception {
+ assertEquals(controller, mgr.createPolicyController(MY_NAME, properties));
+
+ verify(contProv1).beforeCreate(MY_NAME, properties);
+ verify(contProv2).beforeCreate(MY_NAME, properties);
+ verify(controller, never()).lock();
+ verify(contProv1).afterCreate(controller);
+ verify(contProv2).afterCreate(controller);
+
+ // locked - same result, but engine locked
+ setUp();
+ mgr.lock();
+ assertEquals(controller, mgr.createPolicyController(MY_NAME, properties));
+ verify(contProv1).beforeCreate(MY_NAME, properties);
+ verify(controller, times(2)).lock();
+ verify(contProv2).afterCreate(controller);
// first provider generates controller - stops after first provider
setUp();
@@ -902,7 +910,7 @@ class PolicyEngineManagerTest {
* Tests the start() method, after setting some option.
*
* @param expectedResult what start() is expected to return
- * @param setOption function that sets an option
+ * @param setOption function that sets an option
* @throws Throwable if an error occurs during setup
*/
private void testStart(boolean expectedResult, RunnableWithEx setOption) throws Throwable {
@@ -1004,7 +1012,7 @@ class PolicyEngineManagerTest {
* Tests the stop() method, after setting some option.
*
* @param expectedResult what stop() is expected to return
- * @param setOption function that sets an option
+ * @param setOption function that sets an option
* @throws Throwable if an error occurs during setup
*/
private void testStop(boolean expectedResult, RunnableWithEx setOption) throws Throwable {
@@ -1211,7 +1219,7 @@ class PolicyEngineManagerTest {
* Tests the lock() method, after setting some option.
*
* @param expectedResult what lock() is expected to return
- * @param setOption function that sets an option
+ * @param setOption function that sets an option
* @throws Throwable if an error occurs during setup
*/
private void testLock(boolean expectedResult, RunnableWithEx setOption) throws Throwable {
@@ -1287,7 +1295,7 @@ class PolicyEngineManagerTest {
* Tests the unlock() method, after setting some option.
*
* @param expectedResult what unlock() is expected to return
- * @param setOption function that sets an option
+ * @param setOption function that sets an option
* @throws Throwable if an error occurs during setup
*/
private void testUnlock(boolean expectedResult, RunnableWithEx setOption) throws Throwable {
@@ -1411,8 +1419,8 @@ class PolicyEngineManagerTest {
assertEquals(1, mgr.getStats().getSubgroupStats().get(CONTROLLOOP).getPolicyExecutedFailCount());
Summary.Child.Value summary =
- PolicyEngineManagerImpl.transLatencySecsSummary
- .labels(CONTROLLER1, CONTROLLOOP, POLICY, PdpResponseStatus.FAIL.name()).get();
+ PolicyEngineManagerImpl.transLatencySecsSummary
+ .labels(CONTROLLER1, CONTROLLOOP, POLICY, PdpResponseStatus.FAIL.name()).get();
assertEquals(0, summary.count, 0.0);
assertEquals(0, summary.sum, 0.0);
@@ -1423,8 +1431,8 @@ class PolicyEngineManagerTest {
mgr.transaction(CONTROLLER1, CONTROLLOOP, metric);
summary =
- PolicyEngineManagerImpl.transLatencySecsSummary
- .labels(CONTROLLER1, CONTROLLOOP, POLICY, PdpResponseStatus.FAIL.name()).get();
+ PolicyEngineManagerImpl.transLatencySecsSummary
+ .labels(CONTROLLER1, CONTROLLOOP, POLICY, PdpResponseStatus.FAIL.name()).get();
assertEquals(1, summary.count, 0.0);
assertEquals(5, summary.sum, 0.0);
@@ -1553,7 +1561,7 @@ class PolicyEngineManagerTest {
mgr.start();
when(sink1.send(any())).thenThrow(new ArithmeticException(EXPECTED));
assertThatThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT))
- .isInstanceOf(ArithmeticException.class);
+ .isInstanceOf(ArithmeticException.class);
/*
* For remaining tests, have the controller handle delivery.
@@ -1610,7 +1618,7 @@ class PolicyEngineManagerTest {
// unknown topic
assertThatIllegalStateException()
- .isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, "unknown-topic", MESSAGE));
+ .isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, "unknown-topic", MESSAGE));
// locked
mgr.lock();
@@ -1737,7 +1745,7 @@ class PolicyEngineManagerTest {
// not configured yet, thus no lock manager
assertThatIllegalStateException()
- .isThrownBy(() -> mgr.createLock(MY_RESOURCE, MY_OWNER, 10, callback, false));
+ .isThrownBy(() -> mgr.createLock(MY_RESOURCE, MY_OWNER, 10, callback, false));
// now configure it and try again
mgr.configure(properties);
@@ -1745,14 +1753,14 @@ class PolicyEngineManagerTest {
// test illegal args
assertThatThrownBy(() -> mgr.createLock(null, MY_OWNER, 10, callback, false))
- .hasMessageContaining("resourceId");
+ .hasMessageContaining("resourceId");
assertThatThrownBy(() -> mgr.createLock(MY_RESOURCE, null, 10, callback, false))
- .hasMessageContaining("ownerKey");
+ .hasMessageContaining("ownerKey");
assertThatIllegalArgumentException()
- .isThrownBy(() -> mgr.createLock(MY_RESOURCE, MY_OWNER, -1, callback, false))
- .withMessageContaining("holdSec");
+ .isThrownBy(() -> mgr.createLock(MY_RESOURCE, MY_OWNER, -1, callback, false))
+ .withMessageContaining("holdSec");
assertThatThrownBy(() -> mgr.createLock(MY_RESOURCE, MY_OWNER, 10, null, false))
- .hasMessageContaining("callback");
+ .hasMessageContaining("callback");
}
@Test
@@ -1850,19 +1858,19 @@ class PolicyEngineManagerTest {
* Performs an operation that has a beforeXxx method and an afterXxx method. Tries
* combinations where beforeXxx and afterXxx return {@code true} and {@code false}.
*
- * @param setBefore function to set the return value of a provider's beforeXxx method
- * @param setAfter function to set the return value of a provider's afterXxx method
- * @param action invokes the operation
+ * @param setBefore function to set the return value of a provider's beforeXxx method
+ * @param setAfter function to set the return value of a provider's afterXxx method
+ * @param action invokes the operation
* @param verifyBefore verifies that a provider's beforeXxx method was invoked
* @param verifyMiddle verifies that the action occurring between the beforeXxx loop
- * and the afterXxx loop was invoked
- * @param verifyAfter verifies that a provider's afterXxx method was invoked
+ * and the afterXxx loop was invoked
+ * @param verifyAfter verifies that a provider's afterXxx method was invoked
* @throws Exception if an error occurs while calling {@link #setUp()}
*/
private void checkBeforeAfter(BiConsumer<PolicyEngineFeatureApi, Boolean> setBefore,
- BiConsumer<PolicyEngineFeatureApi, Boolean> setAfter, Runnable action,
- Consumer<PolicyEngineFeatureApi> verifyBefore, Runnable verifyMiddle,
- Consumer<PolicyEngineFeatureApi> verifyAfter) throws Exception {
+ BiConsumer<PolicyEngineFeatureApi, Boolean> setAfter, Runnable action,
+ Consumer<PolicyEngineFeatureApi> verifyBefore, Runnable verifyMiddle,
+ Consumer<PolicyEngineFeatureApi> verifyAfter) throws Exception {
checkBeforeAfter_FalseFalse(setBefore, setAfter, action, verifyBefore, verifyMiddle, verifyAfter);
checkBeforeAfter_FalseTrue(setBefore, setAfter, action, verifyBefore, verifyMiddle, verifyAfter);
@@ -1875,19 +1883,19 @@ class PolicyEngineManagerTest {
* Performs an operation that has a beforeXxx method and an afterXxx method. Tries the
* case where both the beforeXxx and afterXxx methods return {@code false}.
*
- * @param setBefore function to set the return value of a provider's beforeXxx method
- * @param setAfter function to set the return value of a provider's afterXxx method
- * @param action invokes the operation
+ * @param setBefore function to set the return value of a provider's beforeXxx method
+ * @param setAfter function to set the return value of a provider's afterXxx method
+ * @param action invokes the operation
* @param verifyBefore verifies that a provider's beforeXxx method was invoked
* @param verifyMiddle verifies that the action occurring between the beforeXxx loop
- * and the afterXxx loop was invoked
- * @param verifyAfter verifies that a provider's afterXxx method was invoked
+ * and the afterXxx loop was invoked
+ * @param verifyAfter verifies that a provider's afterXxx method was invoked
* @throws Exception if an error occurs while calling {@link #setUp()}
*/
private void checkBeforeAfter_FalseFalse(BiConsumer<PolicyEngineFeatureApi, Boolean> setBefore,
- BiConsumer<PolicyEngineFeatureApi, Boolean> setAfter, Runnable action,
- Consumer<PolicyEngineFeatureApi> verifyBefore, Runnable verifyMiddle,
- Consumer<PolicyEngineFeatureApi> verifyAfter) throws Exception {
+ BiConsumer<PolicyEngineFeatureApi, Boolean> setAfter, Runnable action,
+ Consumer<PolicyEngineFeatureApi> verifyBefore, Runnable verifyMiddle,
+ Consumer<PolicyEngineFeatureApi> verifyAfter) throws Exception {
setUp();
@@ -1916,19 +1924,19 @@ class PolicyEngineManagerTest {
* case where the first provider's afterXxx returns {@code true}, while the others
* return {@code false}.
*
- * @param setBefore function to set the return value of a provider's beforeXxx method
- * @param setAfter function to set the return value of a provider's afterXxx method
- * @param action invokes the operation
+ * @param setBefore function to set the return value of a provider's beforeXxx method
+ * @param setAfter function to set the return value of a provider's afterXxx method
+ * @param action invokes the operation
* @param verifyBefore verifies that a provider's beforeXxx method was invoked
* @param verifyMiddle verifies that the action occurring between the beforeXxx loop
- * and the afterXxx loop was invoked
- * @param verifyAfter verifies that a provider's afterXxx method was invoked
+ * and the afterXxx loop was invoked
+ * @param verifyAfter verifies that a provider's afterXxx method was invoked
* @throws Exception if an error occurs while calling {@link #setUp()}
*/
private void checkBeforeAfter_FalseTrue(BiConsumer<PolicyEngineFeatureApi, Boolean> setBefore,
- BiConsumer<PolicyEngineFeatureApi, Boolean> setAfter, Runnable action,
- Consumer<PolicyEngineFeatureApi> verifyBefore, Runnable verifyMiddle,
- Consumer<PolicyEngineFeatureApi> verifyAfter) throws Exception {
+ BiConsumer<PolicyEngineFeatureApi, Boolean> setAfter, Runnable action,
+ Consumer<PolicyEngineFeatureApi> verifyBefore, Runnable verifyMiddle,
+ Consumer<PolicyEngineFeatureApi> verifyAfter) throws Exception {
setUp();
@@ -1957,19 +1965,19 @@ class PolicyEngineManagerTest {
* case where the first provider's beforeXxx returns {@code true}, while the others
* return {@code false}.
*
- * @param setBefore function to set the return value of a provider's beforeXxx method
- * @param setAfter function to set the return value of a provider's afterXxx method
- * @param action invokes the operation
+ * @param setBefore function to set the return value of a provider's beforeXxx method
+ * @param setAfter function to set the return value of a provider's afterXxx method
+ * @param action invokes the operation
* @param verifyBefore verifies that a provider's beforeXxx method was invoked
* @param verifyMiddle verifies that the action occurring between the beforeXxx loop
- * and the afterXxx loop was invoked
- * @param verifyAfter verifies that a provider's afterXxx method was invoked
+ * and the afterXxx loop was invoked
+ * @param verifyAfter verifies that a provider's afterXxx method was invoked
* @throws Exception if an error occurs while calling {@link #setUp()}
*/
private void checkBeforeAfter_TrueFalse(BiConsumer<PolicyEngineFeatureApi, Boolean> setBefore,
- BiConsumer<PolicyEngineFeatureApi, Boolean> setAfter, Runnable action,
- Consumer<PolicyEngineFeatureApi> verifyBefore, Runnable verifyMiddle,
- Consumer<PolicyEngineFeatureApi> verifyAfter) throws Exception {
+ BiConsumer<PolicyEngineFeatureApi, Boolean> setAfter, Runnable action,
+ Consumer<PolicyEngineFeatureApi> verifyBefore, Runnable verifyMiddle,
+ Consumer<PolicyEngineFeatureApi> verifyAfter) throws Exception {
setUp();
diff --git a/policy-utils/pom.xml b/policy-utils/pom.xml
index 319711a1..09c4e142 100644
--- a/policy-utils/pom.xml
+++ b/policy-utils/pom.xml
@@ -70,5 +70,9 @@
<groupId>net.jimblackler.jsonschemafriend</groupId>
<artifactId>core</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-test</artifactId>
+ </dependency>
</dependencies>
</project>
diff --git a/policy-utils/src/main/java/org/onap/policy/drools/metrics/Metric.java b/policy-utils/src/main/java/org/onap/policy/drools/metrics/Metric.java
index 01ff58f5..c2755211 100644
--- a/policy-utils/src/main/java/org/onap/policy/drools/metrics/Metric.java
+++ b/policy-utils/src/main/java/org/onap/policy/drools/metrics/Metric.java
@@ -3,6 +3,7 @@
* ONAP
* ================================================================================
* Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2024 Nordix Foundation.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -134,8 +135,7 @@ public class Metric {
}
if (endTime != null && startTime != null) {
- this.elapsedTime =
- Duration.between(startTime, endTime).toMillis();
+ this.elapsedTime = Duration.between(startTime, endTime).toMillis();
return;
}
diff --git a/policy-utils/src/main/java/org/onap/policy/drools/policies/DomainMaker.java b/policy-utils/src/main/java/org/onap/policy/drools/policies/DomainMaker.java
index 84c81cf0..27dfee49 100644
--- a/policy-utils/src/main/java/org/onap/policy/drools/policies/DomainMaker.java
+++ b/policy-utils/src/main/java/org/onap/policy/drools/policies/DomainMaker.java
@@ -31,7 +31,6 @@ import org.onap.policy.common.utils.coder.StandardCoder;
import org.onap.policy.common.utils.resources.ResourceUtils;
import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
-import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -70,7 +69,7 @@ public class DomainMaker {
return false;
}
- return validators.get(policyType).isConformant(json);
+ return getValidator(policyType).isConformant(json);
}
/**
@@ -94,7 +93,7 @@ public class DomainMaker {
}
try {
- return validators.get(policyType).encode(domainPolicy) != null;
+ return getValidator(policyType).encode(domainPolicy) != null;
} catch (CoderException e) {
logger.info("policy {}:{} is not conformant", policyType, domainPolicy.getClass().getName(), e);
return false;
@@ -116,7 +115,7 @@ public class DomainMaker {
}
try {
- validators.get(policy.getTypeIdentifier()).conformance(rawPolicy);
+ getValidator(policy.getTypeIdentifier()).conformance(rawPolicy);
} catch (CoderException e) {
logger.error("policy {}:{}:{} is not conformant",
policy.getTypeIdentifier(), policy.getName(), policy.getVersion(), e);
@@ -137,7 +136,7 @@ public class DomainMaker {
}
try {
- validators.get(policyType).encode(domainPolicy);
+ getValidator(policyType).encode(domainPolicy);
} catch (CoderException e) {
logger.error("policy {}:{} is not conformant", policyType, domainPolicy.getClass().getName(), e);
return false;
@@ -190,29 +189,21 @@ public class DomainMaker {
public <T> T convertTo(@NonNull ToscaConceptIdentifier policyType, @NonNull String json, @NonNull Class<T> clazz)
throws CoderException {
if (isRegistered(policyType)) {
- return validators.get(policyType).decode(json, clazz);
+ return getValidator(policyType).decode(json, clazz);
} else {
return nonValCoder.decode(json, clazz);
}
}
- /**
- * Converts a Tosca Policy Type specification to a domain-specific json specification.
- */
- public String convertToSchema(@NonNull ToscaPolicyType policyType) {
- //
- // TODO: // NOSONAR
- // 1. Convert Tosca Policy Type definition schema to suitable json schema.
- // 2. Call registerValidator to register
- throw new UnsupportedOperationException("schema generation from policy type is not supported");
- }
-
public boolean isRegistered(@NonNull ToscaConceptIdentifier policyType) {
return validators.containsKey(policyType) || registerValidator(policyType);
}
+ private StandardValCoder getValidator(ToscaConceptIdentifier policyType) {
+ return validators.get(policyType);
+ }
- private String serialize(@NonNull ToscaPolicy policy) {
+ private String serialize(ToscaPolicy policy) {
String rawPolicy = null;
try {
rawPolicy = nonValCoder.encode(policy);
diff --git a/policy-utils/src/test/java/org/onap/policy/drools/metrics/MetricTest.java b/policy-utils/src/test/java/org/onap/policy/drools/metrics/MetricTest.java
index 924d1c95..f1999cce 100644
--- a/policy-utils/src/test/java/org/onap/policy/drools/metrics/MetricTest.java
+++ b/policy-utils/src/test/java/org/onap/policy/drools/metrics/MetricTest.java
@@ -48,12 +48,12 @@ class MetricTest {
void testPojo() {
PojoClass metric = PojoClassFactory.getPojoClass(Metric.class);
Validator val = ValidatorBuilder
- .create()
- .with(new SetterMustExistRule())
- .with(new GetterMustExistRule())
- .with(new SetterTester())
- .with(new GetterTester())
- .build();
+ .create()
+ .with(new SetterMustExistRule())
+ .with(new GetterMustExistRule())
+ .with(new SetterTester())
+ .with(new GetterTester())
+ .build();
val.validate(metric);
}
@@ -190,4 +190,24 @@ class MetricTest {
Instant now = Instant.now();
assertEquals(new SimpleDateFormat(Metric.DATE_FORMAT).format(Date.from(now)), Metric.toTimestamp(now));
}
+
+ @Test
+ void testElapsedTime_EndTimeStartTimeNullValues() {
+ // test seems unnecessary, but when setElapsedTime receives null,
+ // the method tries to calculate elapsed time between start and end time,
+ // which only having the values was covered.
+ Metric metric = new Metric();
+
+ metric.setElapsedTime(null);
+ assertNull(metric.getElapsedTime());
+
+ metric.setEndTime(Instant.now());
+ metric.setElapsedTime(null);
+ assertNull(metric.getElapsedTime());
+
+ metric = new Metric();
+ metric.setStartTime(Instant.now());
+ metric.setElapsedTime(null);
+ assertNull(metric.getElapsedTime());
+ }
} \ No newline at end of file
diff --git a/policy-utils/src/test/java/org/onap/policy/drools/policies/DomainMakerTest.java b/policy-utils/src/test/java/org/onap/policy/drools/policies/DomainMakerTest.java
index f8ffa503..8fbf237f 100644
--- a/policy-utils/src/test/java/org/onap/policy/drools/policies/DomainMakerTest.java
+++ b/policy-utils/src/test/java/org/onap/policy/drools/policies/DomainMakerTest.java
@@ -26,6 +26,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
import java.io.IOException;
import java.nio.file.Files;
@@ -40,7 +42,7 @@ import org.onap.policy.drools.models.domains.a.Nested;
import org.onap.policy.drools.models.domains.a.Properties;
import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
-import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyType;
+import org.springframework.test.util.ReflectionTestUtils;
class DomainMakerTest {
@@ -62,6 +64,13 @@ class DomainMakerTest {
policyTypeId.setVersion("2.0.0");
assertFalse(domainMaker.isConformant(policyTypeId, rawJsonPolicyType));
+
+ // for code coverage
+ assertThatThrownBy(() -> domainMaker.isConformant(null, "{\"json\":\"valid\"}"))
+ .hasMessageContaining("policyType is marked non-null but is null");
+
+ assertThatThrownBy(() -> domainMaker.isConformant(policyTypeId, null))
+ .hasMessageContaining("json is marked non-null but is null");
}
@Test
@@ -93,6 +102,12 @@ class DomainMakerTest {
// not registered schema for policy type
policyTypeId.setVersion("2.0.0");
assertFalse(domainMaker.isDomainConformant(policyTypeId, domainAPolicy));
+
+ assertThatThrownBy(() -> domainMaker.isDomainConformant(null, domainAPolicy))
+ .hasMessageContaining("policyType is marked non-null but is null");
+
+ assertThatThrownBy(() -> domainMaker.isDomainConformant(policyTypeId, null))
+ .hasMessageContaining("domainPolicy is marked non-null but is null");
}
@@ -117,6 +132,12 @@ class DomainMakerTest {
policy2.setTypeVersion("4.2.5");
assertFalse(domainMaker.conformance(policy2));
assertFalse(domainMaker.conformance(policy2.getTypeIdentifier(), domainAPolicy));
+
+ assertThatThrownBy(() -> domainMaker.conformance(null, domainAPolicy))
+ .hasMessageContaining("policyType is marked non-null but is null");
+
+ assertThatThrownBy(() -> domainMaker.conformance(null))
+ .hasMessageContaining("policy is marked non-null but is null");
}
@Test
@@ -136,6 +157,15 @@ class DomainMakerTest {
assertFalse(domainMaker.isConformant(policy));
assertFalse(domainMaker.registerValidator(policy.getTypeIdentifier(), "$schema"));
+
+ assertThatThrownBy(() -> domainMaker.registerValidator(null))
+ .hasMessageContaining("policyType is marked non-null but is null");
+
+ assertThatThrownBy(() -> domainMaker.registerValidator(null, "$schema"))
+ .hasMessageContaining("policyType is marked non-null but is null");
+
+ assertThatThrownBy(() -> domainMaker.registerValidator(policy.getTypeIdentifier(), null))
+ .hasMessageContaining("schema is marked non-null but is null");
}
@Test
@@ -146,14 +176,21 @@ class DomainMakerTest {
assertNotNull(domainMaker.convertTo(getToscaPolicy("src/test/resources/policyA-no-policy-type.json"),
DomainAPolicy.class));
- }
- @Test
- void testConvertToSchema() {
- ToscaPolicyType type = new ToscaPolicyType();
- assertThatThrownBy(() -> domainMaker
- .convertToSchema(type))
- .isInstanceOf(UnsupportedOperationException.class);
+ assertThatThrownBy(() -> domainMaker.convertTo(null, DomainAPolicy.class))
+ .hasMessageContaining("toscaPolicy is marked non-null but is null");
+
+ assertThatThrownBy(() -> domainMaker.convertTo(mock(ToscaPolicy.class), null))
+ .hasMessageContaining("clazz is marked non-null but is null");
+
+ assertThatThrownBy(() -> domainMaker.convertTo(null, "json", DomainAPolicy.class))
+ .hasMessageContaining("policyType is marked non-null but is null");
+
+ assertThatThrownBy(() -> domainMaker.convertTo(mock(ToscaConceptIdentifier.class), null, DomainAPolicy.class))
+ .hasMessageContaining("json is marked non-null but is null");
+
+ assertThatThrownBy(() -> domainMaker.convertTo(mock(ToscaConceptIdentifier.class), "json", null))
+ .hasMessageContaining("clazz is marked non-null but is null");
}
@Test
@@ -166,6 +203,25 @@ class DomainMakerTest {
new ToscaConceptIdentifier("policy.type.external", "7.7.9");
assertFalse(domainMaker.isRegistered(policyTypeId2));
+ assertThatThrownBy(() -> domainMaker.isRegistered(null))
+ .hasMessageContaining("policyType is marked non-null but is null");
+ }
+
+ @Test
+ void testIsConformant_SerializeReturnsNull() throws CoderException {
+ var mockDomainMaker = mock(DomainMaker.class);
+ var mockToscaPolicy = mock(ToscaPolicy.class);
+ when(mockDomainMaker.isConformant(mockToscaPolicy)).thenCallRealMethod();
+
+ var mockCoder = mock(StandardCoder.class);
+ when(mockCoder.encode(mockToscaPolicy)).thenThrow(new CoderException("error"));
+ ReflectionTestUtils.setField(mockDomainMaker, "nonValCoder", mockCoder);
+
+ assertFalse(mockDomainMaker.isConformant(mockToscaPolicy));
+
+ when(mockDomainMaker.conformance(mockToscaPolicy)).thenCallRealMethod();
+ when(mockDomainMaker.isRegistered(mockToscaPolicy.getTypeIdentifier())).thenReturn(true);
+ assertFalse(mockDomainMaker.conformance(mockToscaPolicy));
}
private String getJsonFromFile(String filePath) throws IOException {
diff --git a/policy-utils/src/test/java/org/onap/policy/drools/utils/LookupTest.java b/policy-utils/src/test/java/org/onap/policy/drools/utils/LookupTest.java
new file mode 100644
index 00000000..dd043b47
--- /dev/null
+++ b/policy-utils/src/test/java/org/onap/policy/drools/utils/LookupTest.java
@@ -0,0 +1,57 @@
+/*-
+ * ============LICENSE_START================================================
+ * Copyright (C) 2024 Nordix Foundation.
+ * =========================================================================
+ * 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.utils;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Test;
+import org.onap.policy.common.utils.security.CryptoCoder;
+
+class LookupTest {
+
+ @Test
+ void testCryptoLookup() {
+ var cryptoCoder = new CryptoCoderValueLookup(new CryptoCoder() {
+ @Override
+ public String encrypt(String s) {
+ return String.valueOf(s.hashCode());
+ }
+
+ @Override
+ public String decrypt(String s) {
+ return s;
+ }
+ });
+
+ assertTrue(cryptoCoder.lookup("hello").startsWith("enc"));
+ assertNull(cryptoCoder.lookup(null));
+ assertNull(cryptoCoder.lookup(""));
+ }
+
+ @Test
+ void testEnvDefaultLookup() {
+ var envLookup = new EnvironmentVariableWithDefaultLookup();
+
+ assertNull(envLookup.lookup(null));
+ assertNull(envLookup.lookup(""));
+ assertEquals("", envLookup.lookup(":"));
+ }
+} \ No newline at end of file
diff --git a/policy-utils/src/test/java/org/onap/policy/drools/utils/PropertyUtilTest.java b/policy-utils/src/test/java/org/onap/policy/drools/utils/PropertyUtilTest.java
index f2676e5d..bec22237 100644
--- a/policy-utils/src/test/java/org/onap/policy/drools/utils/PropertyUtilTest.java
+++ b/policy-utils/src/test/java/org/onap/policy/drools/utils/PropertyUtilTest.java
@@ -22,6 +22,8 @@
package org.onap.policy.drools.utils;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.File;
@@ -93,7 +95,8 @@ public class PropertyUtilTest {
// create a directory for temporary files
directory = new File(UUID.randomUUID().toString());
- directory.mkdir();
+ var isDirCreated = directory.mkdir();
+ logger.info("directory created: {}", isDirCreated);
}
/**
@@ -141,8 +144,7 @@ public class PropertyUtilTest {
public void propertiesChanged(Properties properties, Set<String> changedKeys) {
// When a notification is received, store the values in the
// 'returns' array, and signal using the same array.
- logger.info("Listener invoked: properties=" + properties
- + ", changedKeys=" + changedKeys);
+ logger.info("Listener invoked: properties={}, changedKeys={}", properties, changedKeys);
returns[0] = properties;
returns[1] = changedKeys;
synchronized (returns) {
@@ -181,6 +183,73 @@ public class PropertyUtilTest {
}
+ /**
+ * This tests the 'PropertyUtil.Listener' interface.
+ */
+ @Test
+ void testListenerInterface() throws Exception {
+ logger.info("testListenerInterface: test receipt of dynamic updates");
+
+ // create initial property file
+ Properties prop1 = new Properties();
+ prop1.setProperty("p1", "p1 value");
+ prop1.setProperty("p2", "p2 value");
+ prop1.setProperty("p3", "p3 value");
+ logger.info("Create initial properties file: {}", prop1);
+ File file1 = createFile("createAndReadPropertyFile-2", prop1);
+
+ // create a listener for the notification interface
+ Object[] returns = new Object[2];
+ PropertyUtil.Listener listener = createListenerThread(returns);
+
+ // read it in, and do a comparison
+ Properties prop2 = PropertyUtil.getProperties(file1, listener);
+ logger.info("Read in properties: {}", prop2);
+ assertEquals(prop1, prop2);
+ assertEquals("p1 value", prop2.getProperty("p1"));
+ assertEquals("p2 value", prop2.getProperty("p2"));
+ assertEquals("p3 value", prop2.getProperty("p3"));
+
+ // make some changes, and update the file (p3 is left unchanged)
+ prop2.remove("p1"); // remove one property
+ prop2.setProperty("p2", "new p2 value"); // change one property
+ prop2.setProperty("p4", "p4 value"); // add a new property
+ logger.info("Modified properties: {}", prop2);
+
+ // now, update the file, and wait for notification
+ synchronized (returns) {
+ createFile("createAndReadPropertyFile-2", prop2);
+
+ // wait up to 60 seconds, although we should receive notification
+ // in 10 seconds or less (if things are working)
+ returns.wait(60000L);
+ }
+
+ // verify we have the updates
+ assertEquals(prop2, returns[0]);
+
+ // verify that we have the expected set of keys
+ assertEquals(new TreeSet<>(Arrays.asList("p1", "p2", "p4")), returns[1]);
+
+ String filePath = file1.getAbsolutePath();
+ PropertyUtil.stopListening(filePath, listener);
+ }
+
+ @Test
+ void testGetProperties_ListenerNull() throws IOException {
+ String filepath = "src/test/resources/interpolation.properties";
+ File propertiesFile = new File(filepath);
+ assertNotNull(propertiesFile);
+ PropertyUtil.Listener listener = null;
+ var result = PropertyUtil.getProperties(propertiesFile, listener);
+ assertNotNull(result);
+ assertInstanceOf(Properties.class, result);
+
+ var anotherResult = PropertyUtil.getProperties(filepath, listener);
+ assertNotNull(anotherResult);
+ assertInstanceOf(Properties.class, anotherResult);
+ }
+
private void testGetDefaultCryptoSystemProps() throws IOException {
// system properties + default crypto coder
PropertyUtil.setDefaultCryptoCoder(new CryptoUtils(INTERPOLATION_CRYPTO_KEY));
@@ -251,54 +320,4 @@ public class PropertyUtilTest {
assertEquals(System.getProperty("user.home"), props.getProperty(INTERPOLATION_SYS));
assertEquals(INTERPOLATION_ENVD_DEFAULT_VALUE, props.getProperty(INTERPOLATION_ENVD_DEFAULT));
}
-
- /**
- * This tests the 'PropertyUtil.Listener' interface.
- */
- @Test
- void testListenerInterface() throws Exception {
- logger.info("testListenerInterface: test receipt of dynamic updates");
-
- // create initial property file
- Properties prop1 = new Properties();
- prop1.setProperty("p1", "p1 value");
- prop1.setProperty("p2", "p2 value");
- prop1.setProperty("p3", "p3 value");
- logger.info("Create initial properties file: " + prop1);
- File file1 = createFile("createAndReadPropertyFile-2", prop1);
-
- // create a listener for the notification interface
- Object[] returns = new Object[2];
- PropertyUtil.Listener listener = createListenerThread(returns);
-
- // read it in, and do a comparison
- Properties prop2 = PropertyUtil.getProperties(file1, listener);
- logger.info("Read in properties: " + prop2);
- assertEquals(prop1, prop2);
- assertEquals("p1 value", prop2.getProperty("p1"));
- assertEquals("p2 value", prop2.getProperty("p2"));
- assertEquals("p3 value", prop2.getProperty("p3"));
-
- // make some changes, and update the file (p3 is left unchanged)
- prop2.remove("p1"); // remove one property
- prop2.setProperty("p2", "new p2 value"); // change one property
- prop2.setProperty("p4", "p4 value"); // add a new property
- logger.info("Modified properties: " + prop2);
-
- // now, update the file, and wait for notification
- synchronized (returns) {
- createFile("createAndReadPropertyFile-2", prop2);
-
- // wait up to 60 seconds, although we should receive notification
- // in 10 seconds or less (if things are working)
- returns.wait(60000L);
- }
-
- // verify we have the updates
- assertEquals(prop2, returns[0]);
-
- // verify that we have the expected set of keys
- assertEquals(new TreeSet<String>(Arrays.asList(new String[]{"p1", "p2", "p4"})),
- returns[1]);
- }
}