2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.onap.policy.drools.pooling;
23 import static org.junit.Assert.assertEquals;
24 import static org.junit.Assert.assertFalse;
25 import static org.junit.Assert.assertTrue;
26 import static org.mockito.ArgumentMatchers.any;
27 import static org.mockito.Mockito.doThrow;
28 import static org.mockito.Mockito.mock;
29 import static org.mockito.Mockito.never;
30 import static org.mockito.Mockito.times;
31 import static org.mockito.Mockito.verify;
32 import static org.mockito.Mockito.when;
33 import java.util.LinkedList;
34 import java.util.List;
35 import java.util.Properties;
36 import org.junit.AfterClass;
37 import org.junit.Before;
38 import org.junit.BeforeClass;
39 import org.junit.Test;
40 import org.onap.policy.drools.controller.DroolsController;
41 import org.onap.policy.drools.event.comm.Topic.CommInfrastructure;
42 import org.onap.policy.drools.pooling.PoolingFeature.Factory;
43 import org.onap.policy.drools.system.PolicyController;
44 import org.onap.policy.drools.system.PolicyEngine;
45 import org.onap.policy.drools.utils.Pair;
47 public class PoolingFeatureTest {
49 private static final String CONTROLLER1 = "controllerA";
50 private static final String CONTROLLER2 = "controllerB";
51 private static final String CONTROLLER_DISABLED = "controllerDisabled";
52 private static final String CONTROLLER_EX = "controllerException";
53 private static final String CONTROLLER_UNKNOWN = "controllerUnknown";
55 private static final String TOPIC1 = "topic.one";
56 private static final String TOPIC2 = "topic.two";
58 private static final String EVENT1 = "event.one";
59 private static final String EVENT2 = "event.two";
61 private static final Object OBJECT1 = new Object();
62 private static final Object OBJECT2 = new Object();
65 * Saved from PoolingFeature and restored on exit from this test class.
67 private static Factory saveFactory;
69 private Properties props;
70 private PolicyEngine engine;
71 private PolicyController controller1;
72 private PolicyController controller2;
73 private PolicyController controllerDisabled;
74 private PolicyController controllerException;
75 private PolicyController controllerUnknown;
76 private DroolsController drools1;
77 private DroolsController drools2;
78 private DroolsController droolsDisabled;
79 private List<Pair<PoolingManagerImpl, PoolingProperties>> managers;
80 private PoolingManagerImpl mgr1;
81 private PoolingManagerImpl mgr2;
82 private Factory factory;
84 private PoolingFeature pool;
88 public static void setUpBeforeClass() {
89 saveFactory = PoolingFeature.getFactory();
93 public static void tearDownAfterClass() {
94 PoolingFeature.setFactory(saveFactory);
98 public void setUp() throws Exception {
99 props = initProperties();
100 engine = mock(PolicyEngine.class);
101 factory = mock(Factory.class);
102 controller1 = mock(PolicyController.class);
103 controller2 = mock(PolicyController.class);
104 controllerDisabled = mock(PolicyController.class);
105 controllerException = mock(PolicyController.class);
106 controllerUnknown = mock(PolicyController.class);
107 drools1 = mock(DroolsController.class);
108 drools2 = mock(DroolsController.class);
109 droolsDisabled = mock(DroolsController.class);
110 managers = new LinkedList<>();
112 PoolingFeature.setFactory(factory);
114 when(controller1.getName()).thenReturn(CONTROLLER1);
115 when(controller2.getName()).thenReturn(CONTROLLER2);
116 when(controllerDisabled.getName()).thenReturn(CONTROLLER_DISABLED);
117 when(controllerException.getName()).thenReturn(CONTROLLER_EX);
118 when(controllerUnknown.getName()).thenReturn(CONTROLLER_UNKNOWN);
120 when(factory.getProperties(PoolingProperties.FEATURE_NAME)).thenReturn(props);
121 when(factory.getController(drools1)).thenReturn(controller1);
122 when(factory.getController(drools2)).thenReturn(controller2);
123 when(factory.getController(droolsDisabled)).thenReturn(controllerDisabled);
125 when(factory.makeManager(any(), any())).thenAnswer(args -> {
126 PoolingProperties props = args.getArgument(1);
128 PoolingManagerImpl mgr = mock(PoolingManagerImpl.class);
130 managers.add(new Pair<>(mgr, props));
135 pool = new PoolingFeature();
137 pool.beforeStart(engine);
139 pool.afterCreate(controller1);
140 pool.afterCreate(controller2);
142 mgr1 = managers.get(0).first();
143 mgr2 = managers.get(1).first();
148 assertEquals(2, managers.size());
152 public void testGetSequenceNumber() {
153 assertEquals(0, pool.getSequenceNumber());
157 public void testBeforeStartEngine() {
158 pool = new PoolingFeature();
160 assertFalse(pool.beforeStart(engine));
164 public void testAfterCreate() {
166 pool = new PoolingFeature();
167 pool.beforeStart(engine);
169 assertFalse(pool.afterCreate(controller1));
170 assertEquals(1, managers.size());
173 assertFalse(pool.afterCreate(controller1));
174 assertEquals(1, managers.size());
177 assertFalse(pool.afterCreate(controller2));
178 assertEquals(2, managers.size());
182 public void testAfterCreate_NotEnabled() {
184 pool = new PoolingFeature();
185 pool.beforeStart(engine);
187 assertFalse(pool.afterCreate(controllerDisabled));
188 assertTrue(managers.isEmpty());
191 @Test(expected = PoolingFeatureRtException.class)
192 public void testAfterCreate_PropertyEx() {
194 pool = new PoolingFeature();
195 pool.beforeStart(engine);
197 pool.afterCreate(controllerException);
200 @Test(expected = PoolingFeatureRtException.class)
201 public void testAfterCreate_NoProps() {
202 pool = new PoolingFeature();
204 // did not perform globalInit, which is an error
206 pool.afterCreate(controller1);
210 public void testAfterCreate_NoFeatProps() {
212 pool = new PoolingFeature();
213 pool.beforeStart(engine);
215 assertFalse(pool.afterCreate(controllerUnknown));
216 assertTrue(managers.isEmpty());
220 public void testBeforeStart() throws Exception {
221 assertFalse(pool.beforeStart(controller1));
222 verify(mgr1).beforeStart();
224 // ensure it's still in the map by re-invoking
225 assertFalse(pool.beforeStart(controller1));
226 verify(mgr1, times(2)).beforeStart();
228 assertFalse(pool.beforeStart(controllerDisabled));
232 public void testAfterStart() {
233 assertFalse(pool.afterStart(controller1));
234 verify(mgr1).afterStart();
236 // ensure it's still in the map by re-invoking
237 assertFalse(pool.afterStart(controller1));
238 verify(mgr1, times(2)).afterStart();
240 assertFalse(pool.afterStart(controllerDisabled));
244 public void testBeforeStop() {
245 assertFalse(pool.beforeStop(controller1));
246 verify(mgr1).beforeStop();
248 // ensure it's still in the map by re-invoking
249 assertFalse(pool.beforeStop(controller1));
250 verify(mgr1, times(2)).beforeStop();
252 assertFalse(pool.beforeStop(controllerDisabled));
256 public void testAfterStop() {
257 assertFalse(pool.afterStop(controller1));
258 verify(mgr1).afterStop();
260 // ensure it has been removed from the map by re-invoking
261 assertFalse(pool.afterStop(controller1));
263 // count should be unchanged
264 verify(mgr1).afterStop();
266 assertFalse(pool.afterStop(controllerDisabled));
270 public void testBeforeLock() {
271 assertFalse(pool.beforeLock(controller1));
272 verify(mgr1).beforeLock();
274 // ensure it's still in the map by re-invoking
275 assertFalse(pool.beforeLock(controller1));
276 verify(mgr1, times(2)).beforeLock();
278 assertFalse(pool.beforeLock(controllerDisabled));
282 public void testAfterUnlock() {
283 assertFalse(pool.afterUnlock(controller1));
284 verify(mgr1).afterUnlock();
286 // ensure it's still in the map by re-invoking
287 assertFalse(pool.afterUnlock(controller1));
288 verify(mgr1, times(2)).afterUnlock();
290 assertFalse(pool.afterUnlock(controllerDisabled));
294 public void testBeforeOffer() {
295 assertFalse(pool.beforeOffer(controller1, CommInfrastructure.UEB, TOPIC1, EVENT1));
296 verify(mgr1).beforeOffer(CommInfrastructure.UEB, TOPIC1, EVENT1);
298 // ensure that the args were captured
299 pool.beforeInsert(drools1, OBJECT1);
300 verify(mgr1).beforeInsert(CommInfrastructure.UEB, TOPIC1, EVENT1, OBJECT1);
303 // ensure it's still in the map by re-invoking
304 assertFalse(pool.beforeOffer(controller1, CommInfrastructure.UEB, TOPIC2, EVENT2));
305 verify(mgr1).beforeOffer(CommInfrastructure.UEB, TOPIC2, EVENT2);
307 // ensure that the new args were captured
308 pool.beforeInsert(drools1, OBJECT2);
309 verify(mgr1).beforeInsert(CommInfrastructure.UEB, TOPIC2, EVENT2, OBJECT2);
312 assertFalse(pool.beforeOffer(controllerDisabled, CommInfrastructure.UEB, TOPIC1, EVENT1));
316 public void testBeforeOffer_NotFound() {
317 assertFalse(pool.beforeOffer(controllerDisabled, CommInfrastructure.UEB, TOPIC1, EVENT1));
321 public void testBeforeOffer_MgrTrue() {
323 // manager will return true
324 when(mgr1.beforeOffer(any(), any(), any())).thenReturn(true);
326 assertTrue(pool.beforeOffer(controller1, CommInfrastructure.UEB, TOPIC1, EVENT1));
327 verify(mgr1).beforeOffer(CommInfrastructure.UEB, TOPIC1, EVENT1);
329 // ensure it's still in the map by re-invoking
330 assertTrue(pool.beforeOffer(controller1, CommInfrastructure.UEB, TOPIC2, EVENT2));
331 verify(mgr1).beforeOffer(CommInfrastructure.UEB, TOPIC2, EVENT2);
333 assertFalse(pool.beforeOffer(controllerDisabled, CommInfrastructure.UEB, TOPIC1, EVENT1));
337 public void testBeforeInsert() {
338 pool.beforeOffer(controller1, CommInfrastructure.UEB, TOPIC1, EVENT1);
339 assertFalse(pool.beforeInsert(drools1, OBJECT1));
340 verify(mgr1).beforeInsert(CommInfrastructure.UEB, TOPIC1, EVENT1, OBJECT1);
342 // ensure it's still in the map by re-invoking
343 pool.beforeOffer(controller1, CommInfrastructure.UEB, TOPIC2, EVENT2);
344 assertFalse(pool.beforeInsert(drools1, OBJECT2));
345 verify(mgr1).beforeInsert(CommInfrastructure.UEB, TOPIC2, EVENT2, OBJECT2);
347 pool.beforeOffer(controllerDisabled, CommInfrastructure.UEB, TOPIC2, EVENT2);
348 assertFalse(pool.beforeInsert(droolsDisabled, OBJECT1));
352 public void testBeforeInsert_NoArgs() {
354 // call beforeInsert without beforeOffer
355 assertFalse(pool.beforeInsert(drools1, OBJECT1));
356 verify(mgr1, never()).beforeInsert(any(), any(), any(), any());
358 assertFalse(pool.beforeInsert(droolsDisabled, OBJECT1));
359 verify(mgr1, never()).beforeInsert(any(), any(), any(), any());
363 public void testBeforeInsert_ArgEx() {
365 // generate exception
366 doThrow(new IllegalArgumentException()).when(factory).getController(any());
368 pool.beforeOffer(controller1, CommInfrastructure.UEB, TOPIC1, EVENT1);
369 assertFalse(pool.beforeInsert(drools1, OBJECT1));
370 verify(mgr1, never()).beforeInsert(any(), any(), any(), any());
374 public void testBeforeInsert_StateEx() {
376 // generate exception
377 doThrow(new IllegalStateException()).when(factory).getController(any());
379 pool.beforeOffer(controller1, CommInfrastructure.UEB, TOPIC1, EVENT1);
380 assertFalse(pool.beforeInsert(drools1, OBJECT1));
381 verify(mgr1, never()).beforeInsert(any(), any(), any(), any());
385 public void testBeforeInsert_NullController() {
387 // return null controller
388 when(factory.getController(any())).thenReturn(null);
390 pool.beforeOffer(controller1, CommInfrastructure.UEB, TOPIC1, EVENT1);
391 assertFalse(pool.beforeInsert(drools1, OBJECT1));
392 verify(mgr1, never()).beforeInsert(any(), any(), any(), any());
396 public void testBeforeInsert_NotFound() {
398 pool.beforeOffer(controllerDisabled, CommInfrastructure.UEB, TOPIC2, EVENT2);
399 assertFalse(pool.beforeInsert(droolsDisabled, OBJECT1));
403 public void testAfterOffer() {
404 // this will create OfferArgs
405 pool.beforeOffer(controller1, CommInfrastructure.UEB, TOPIC1, EVENT1);
407 // this should clear them
408 assertFalse(pool.afterOffer(controller1, CommInfrastructure.UEB, TOPIC2, EVENT2, true));
410 assertFalse(pool.beforeInsert(drools1, OBJECT1));
411 verify(mgr1, never()).beforeInsert(any(), any(), any(), any());
414 assertFalse(pool.beforeInsert(droolsDisabled, OBJECT1));
418 public void testDoManager() throws Exception {
419 assertFalse(pool.beforeStart(controller1));
420 verify(mgr1).beforeStart();
422 // ensure it's still in the map by re-invoking
423 assertFalse(pool.beforeStart(controller1));
424 verify(mgr1, times(2)).beforeStart();
427 // different controller
428 assertFalse(pool.beforeStart(controller2));
429 verify(mgr2).beforeStart();
431 // ensure it's still in the map by re-invoking
432 assertFalse(pool.beforeStart(controller2));
433 verify(mgr2, times(2)).beforeStart();
436 assertFalse(pool.beforeStart(controllerDisabled));
440 public void testDoManager_NotFound() {
441 assertFalse(pool.beforeStart(controllerDisabled));
444 @Test(expected = PoolingFeatureRtException.class)
445 public void testDoManager_Ex() throws Exception {
447 // generate exception
448 doThrow(new PoolingFeatureException()).when(mgr1).beforeStart();
450 pool.beforeStart(controller1);
454 public void testDoDeleteManager() {
455 assertFalse(pool.afterStop(controller1));
456 verify(mgr1).afterStop();
458 // ensure it has been removed from the map by re-invoking
459 assertFalse(pool.afterStop(controller1));
461 // count should be unchanged
462 verify(mgr1).afterStop();
465 // different controller
466 assertFalse(pool.afterStop(controller2));
467 verify(mgr2).afterStop();
469 // ensure it has been removed from the map by re-invoking
470 assertFalse(pool.afterStop(controller2));
472 // count should be unchanged
473 verify(mgr2).afterStop();
476 assertFalse(pool.afterStop(controllerDisabled));
480 public void testDoDeleteManager_NotFound() {
481 assertFalse(pool.afterStop(controllerDisabled));
484 @Test(expected = PoolingFeatureRtException.class)
485 public void testDoDeleteManager_Ex() {
487 // generate exception
488 doThrow(new PoolingFeatureRtException()).when(mgr1).afterStop();
490 pool.afterStop(controller1);
493 private Properties initProperties() {
494 Properties props = new Properties();
496 initProperties(props, "A", 0);
497 initProperties(props, "B", 1);
498 initProperties(props, "Exception", 2);
500 props.setProperty("pooling.controllerDisabled.enabled", "false");
502 props.setProperty("pooling.controllerException.offline.queue.limit", "INVALID NUMBER");
507 private void initProperties(Properties props, String suffix, int offset) {
508 props.setProperty("pooling.controller" + suffix + ".topic", "topic." + suffix);
509 props.setProperty("pooling.controller" + suffix + ".enabled", "true");
510 props.setProperty("pooling.controller" + suffix + ".offline.queue.limit", String.valueOf(5 + offset));
511 props.setProperty("pooling.controller" + suffix + ".offline.queue.age.milliseconds",
512 String.valueOf(100 + offset));
513 props.setProperty("pooling.controller" + suffix + ".start.heartbeat.milliseconds", String.valueOf(10 + offset));
514 props.setProperty("pooling.controller" + suffix + ".reactivate.milliseconds", String.valueOf(20 + offset));
515 props.setProperty("pooling.controller" + suffix + ".identification.milliseconds", String.valueOf(30 + offset));
516 props.setProperty("pooling.controller" + suffix + ".active.heartbeat.milliseconds",
517 String.valueOf(40 + offset));
518 props.setProperty("pooling.controller" + suffix + ".inter.heartbeat.milliseconds", String.valueOf(50 + offset));