2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017-2021 AT&T Intellectual Property. All rights reserved.
6 * Modifications Copyright (C) 2024 Nordix Foundation.
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
22 package org.onap.policy.drools.core;
24 import static org.junit.jupiter.api.Assertions.assertEquals;
25 import static org.junit.jupiter.api.Assertions.assertFalse;
26 import static org.junit.jupiter.api.Assertions.assertNotNull;
27 import static org.junit.jupiter.api.Assertions.assertSame;
28 import static org.junit.jupiter.api.Assertions.assertTrue;
29 import static org.mockito.ArgumentMatchers.any;
30 import static org.mockito.Mockito.mock;
31 import static org.mockito.Mockito.when;
33 import java.nio.file.Paths;
34 import java.util.Arrays;
35 import java.util.Collection;
36 import java.util.List;
37 import java.util.Objects;
38 import java.util.concurrent.LinkedBlockingQueue;
39 import java.util.concurrent.TimeUnit;
40 import org.drools.core.WorkingMemory;
41 import org.junit.jupiter.api.BeforeAll;
42 import org.junit.jupiter.api.Test;
43 import org.onap.policy.drools.util.KieUtils;
46 * These tests focus on the following classes.
49 * PolicySessionFeatureAPI
51 public class DroolsContainerTest {
53 private static final long TIMEOUT_SEC = 5;
56 * This test is centered around the creation of a 'PolicyContainer'
57 * and 'PolicySession', and the updating of that container to a new
61 public static void setUp() throws Exception {
62 KieUtils.installArtifact(
63 Paths.get("src/test/resources/drools-artifact-1.1/src/main/resources/META-INF/kmodule.xml").toFile(),
64 Paths.get("src/test/resources/drools-artifact-1.1/pom.xml").toFile(),
65 "src/main/resources/rules/org/onap/policy/drools/core/test/",
66 Paths.get("src/test/resources/drools-artifact-1.1/src/main/resources/rules.drl").toFile());
68 KieUtils.installArtifact(
69 Paths.get("src/test/resources/drools-artifact-1.2/src/main/resources/META-INF/kmodule.xml").toFile(),
70 Paths.get("src/test/resources/drools-artifact-1.2/pom.xml").toFile(),
71 "src/main/resources/rules/org/onap/policy/drools/core/test/",
72 Paths.get("src/test/resources/drools-artifact-1.2/src/main/resources/rules.drl").toFile());
76 * This test is centered around the creation of a 'PolicyContainer'
77 * and 'PolicySession', and the updating of that container to a new
81 void createAndUpdate() throws Exception {
82 // make sure feature log starts out clean
83 PolicySessionFeatureApiMock.getLog();
85 // run 'globalInit', and verify expected feature hook fired
86 PolicyContainer.globalInit(new String[0]);
87 assertEquals(List.of("globalInit"),
88 PolicySessionFeatureApiMock.getLog());
90 // initial conditions -- there should be no containers
91 assertEquals(0, PolicyContainer.getPolicyContainers().size());
93 // create the container, and start it
94 PolicyContainer container =
95 new PolicyContainer("org.onap.policy.drools-pdp",
96 "drools-artifact1", "17.1.0-SNAPSHOT");
98 assertTrue(container.isAlive());
100 // verify expected feature hooks fired
101 assertEquals(Arrays.asList("activatePolicySession",
103 "selectThreadModel"),
104 PolicySessionFeatureApiMock.getLog());
106 // this container should be on the list
108 Collection<PolicyContainer> containers =
109 PolicyContainer.getPolicyContainers();
110 assertEquals(1, containers.size());
111 assertTrue(containers.contains(container));
114 // verify initial container attributes
115 assertEquals("org.onap.policy.drools-pdp:drools-artifact1:17.1.0-SNAPSHOT",
116 container.getName());
117 assertEquals("org.onap.policy.drools-pdp", container.getGroupId());
118 assertEquals("drools-artifact1", container.getArtifactId());
119 assertEquals("17.1.0-SNAPSHOT", container.getVersion());
122 // fetch the session, and verify that it exists
123 PolicySession session = container.getPolicySession("session1");
124 assertNotNull(session);
126 // get all sessions, and verify that this one is the only one
128 Collection<PolicySession> sessions = container.getPolicySessions();
129 assertEquals(1, sessions.size());
130 assertTrue(sessions.contains(session));
133 // verify session attributes
134 assertEquals(container, session.getContainer());
135 assertEquals("session1", session.getName());
136 assertEquals("org.onap.policy.drools-pdp:drools-artifact1:17.1.0-SNAPSHOT:session1",
137 session.getFullName());
140 LinkedBlockingQueue<Integer> result = new LinkedBlockingQueue<>();
141 session.getKieSession().insert(Arrays.asList(3, 8, 2));
142 session.getKieSession().insert(result);
144 // the Drools rules should add 3 + 8 + 2, and store 13 in a[0]
145 assertEquals(13, Objects.requireNonNull(result.poll(TIMEOUT_SEC, TimeUnit.SECONDS)).intValue());
147 // update the container to a new version --
148 // the rules will then multiply values rather than add them
150 container.updateToVersion("17.2.0-SNAPSHOT"));
152 // verify expected feature hooks fired
153 assertEquals(List.of("selectThreadModel"),
154 PolicySessionFeatureApiMock.getLog());
156 // verify new container attributes
157 assertEquals("org.onap.policy.drools-pdp:drools-artifact1:17.2.0-SNAPSHOT",
158 container.getName());
159 assertEquals("org.onap.policy.drools-pdp", container.getGroupId());
160 assertEquals("drools-artifact1", container.getArtifactId());
161 assertEquals("17.2.0-SNAPSHOT", container.getVersion());
163 // verify new session attributes
164 assertEquals(container, session.getContainer());
165 assertEquals("session1", session.getName());
166 assertEquals("org.onap.policy.drools-pdp:drools-artifact1:17.2.0-SNAPSHOT:session1",
167 session.getFullName());
169 // the updated rules should now multiply 3 * 8 * 2, and return 48
171 result = new LinkedBlockingQueue<>();
172 container.insert("session1", Arrays.asList(3, 8, 2));
173 container.insert("session1", result);
175 assertEquals(48, Objects.requireNonNull(result.poll(TIMEOUT_SEC, TimeUnit.SECONDS)).intValue());
178 * verify that default KiePackages have been added by testing that
179 * 'DroolsRunnable' is functioning. Also verifies that DroolsExecutor works by
180 * using it to inject the runnable, though we have to mock the WorkingMemory
181 * object since I don't know how to obtain it from the kieSession
184 WorkingMemory wm = mock(WorkingMemory.class);
185 when(wm.insert(any())).thenAnswer(ans -> {
186 Object object = ans.getArgument(0);
187 return container.getPolicySession("session1").getKieSession().insert(object);
190 DroolsExecutor executor = new DroolsExecutor(wm);
192 final LinkedBlockingQueue<String> lbq = new LinkedBlockingQueue<>();
193 executor.execute(() -> lbq.add("DroolsRunnable String"));
194 assertEquals("DroolsRunnable String", lbq.poll(TIMEOUT_SEC, TimeUnit.SECONDS));
196 executor.execute(() -> lbq.add("another DroolsRunnable String"));
197 assertEquals("another DroolsRunnable String", lbq.poll(TIMEOUT_SEC, TimeUnit.SECONDS));
200 container.shutdown();
201 assertFalse(container.isAlive());
203 // verify expected feature hooks fired
204 assertEquals(List.of("disposeKieSession"),
205 PolicySessionFeatureApiMock.getLog());
208 // final conditions -- there should be no containers
209 assertEquals(0, PolicyContainer.getPolicyContainers().size());
213 * This test create a 'PolicyContainer' and 'PolicySession', and verifies
214 * their behavior, but uses alternate interfaces to increase code coverage.
215 * In addition, feature hook invocations will trigger exceptions in this
216 * test, also to increase code coverage.
219 void versionList() throws Exception {
220 // make sure feature log starts out clean
221 PolicySessionFeatureApiMock.getLog();
223 // trigger exceptions in all feature hooks
224 PolicySessionFeatureApiMock.setExceptionTrigger(true);
226 // run 'globalInit', and verify expected feature hook fired
227 PolicyContainer.globalInit(new String[0]);
228 assertEquals(List.of("globalInit-exception"),
229 PolicySessionFeatureApiMock.getLog());
231 // initial conditions -- there should be no containers
232 assertEquals(0, PolicyContainer.getPolicyContainers().size());
235 "17.3.0-SNAPSHOT,17.1.0-SNAPSHOT,17.2.0-SNAPSHOT";
237 // versions should be tried in order -- the 17.1.0-SNAPSHOT should "win",
238 // given the fact that '17.3.0-SNAPSHOT' doesn't exist
239 PolicyContainer container =
240 new PolicyContainer("org.onap.policy.drools-pdp",
241 "drools-artifact1", versionList);
242 // the following should be equivalent to 'container.start()'
243 PolicyContainer.activate();
244 assertTrue(container.isAlive());
246 // verify expected feature hooks fired
247 assertEquals(Arrays.asList("activatePolicySession-exception",
248 "newPolicySession-exception",
249 "selectThreadModel-exception"),
250 PolicySessionFeatureApiMock.getLog());
252 // this container should be on the list
254 Collection<PolicyContainer> containers =
255 PolicyContainer.getPolicyContainers();
256 assertEquals(1, containers.size());
257 assertTrue(containers.contains(container));
260 // verify initial container attributes
261 assertEquals("org.onap.policy.drools-pdp:drools-artifact1:17.1.0-SNAPSHOT",
262 container.getName());
263 assertEquals("org.onap.policy.drools-pdp", container.getGroupId());
264 assertEquals("drools-artifact1", container.getArtifactId());
265 assertEquals("17.1.0-SNAPSHOT", container.getVersion());
267 // some container adjunct tests
269 Object bogusAdjunct = new Object();
271 // initially, no adjunct
272 assertSame(null, container.getAdjunct(this));
274 // set and verify adjunct
275 container.setAdjunct(this, bogusAdjunct);
276 assertSame(bogusAdjunct, container.getAdjunct(this));
278 // clear and verify adjunct
279 container.setAdjunct(this, null);
280 assertSame(null, container.getAdjunct(this));
284 // fetch the session, and verify that it exists
285 PolicySession session = container.getPolicySession("session1");
286 assertNotNull(session);
288 // get all sessions, and verify that this one is the only one
290 Collection<PolicySession> sessions = container.getPolicySessions();
291 assertEquals(1, sessions.size());
292 assertTrue(sessions.contains(session));
295 // verify session attributes
296 assertEquals(container, session.getContainer());
297 assertEquals("session1", session.getName());
298 assertEquals("org.onap.policy.drools-pdp:drools-artifact1:17.1.0-SNAPSHOT:session1",
299 session.getFullName());
301 // some session adjunct tests
303 Object bogusAdjunct = new Object();
305 // initially, no adjunct
306 assertSame(null, session.getAdjunct(this));
308 // set and verify adjunct
309 session.setAdjunct(this, bogusAdjunct);
310 assertSame(bogusAdjunct, session.getAdjunct(this));
312 // clear and verify adjunct
313 session.setAdjunct(this, null);
314 assertSame(null, session.getAdjunct(this));
317 // insert a new fact (using 'insertAll')
318 LinkedBlockingQueue<Integer> result = new LinkedBlockingQueue<>();
319 container.insertAll(Arrays.asList(7, 3, 4));
320 container.insertAll(result);
322 // the Drools rules should add 7 + 3 + 4, and store 14 in a[0]
323 assertEquals(14, Objects.requireNonNull(result.poll(TIMEOUT_SEC, TimeUnit.SECONDS)).intValue());
325 // exercise some more API methods
326 assertEquals(container.getClassLoader(),
327 container.getKieContainer().getClassLoader());
329 // should be equivalent to 'shutdown' without persistence
331 assertFalse(container.isAlive());
333 // verify expected feature hooks fired
334 assertEquals(List.of("destroyKieSession-exception"),
335 PolicySessionFeatureApiMock.getLog());
337 // clear exception trigger
338 PolicySessionFeatureApiMock.setExceptionTrigger(false);
341 // final conditions -- there should be no containers
342 assertEquals(0, PolicyContainer.getPolicyContainers().size());