2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2018-2019 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.system.internal;
23 import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
24 import static org.assertj.core.api.Assertions.assertThatThrownBy;
25 import static org.junit.Assert.assertEquals;
26 import static org.junit.Assert.assertFalse;
27 import static org.junit.Assert.assertNotNull;
28 import static org.junit.Assert.assertTrue;
29 import static org.mockito.Matchers.any;
30 import static org.mockito.Mockito.mock;
31 import static org.mockito.Mockito.never;
32 import static org.mockito.Mockito.times;
33 import static org.mockito.Mockito.verify;
34 import static org.mockito.Mockito.when;
36 import java.util.Arrays;
37 import java.util.List;
38 import java.util.Properties;
39 import java.util.function.BiConsumer;
40 import java.util.function.Consumer;
41 import org.junit.Before;
42 import org.junit.Test;
43 import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure;
44 import org.onap.policy.common.endpoints.event.comm.TopicEndpoint;
45 import org.onap.policy.common.endpoints.event.comm.TopicSink;
46 import org.onap.policy.common.endpoints.event.comm.TopicSource;
47 import org.onap.policy.drools.controller.DroolsController;
48 import org.onap.policy.drools.controller.DroolsControllerFactory;
49 import org.onap.policy.drools.features.PolicyControllerFeatureApi;
50 import org.onap.policy.drools.persistence.SystemPersistence;
51 import org.onap.policy.drools.protocol.configuration.DroolsConfiguration;
52 import org.onap.policy.drools.system.GsonMgmtTestBuilder;
54 public class AggregatedPolicyControllerTest {
56 private static final String AGG_NAME = "agg-name";
57 private static final String SINK_TOPIC1 = "sink-a";
58 private static final String SINK_TOPIC2 = "sink-b";
59 private static final String SOURCE_TOPIC1 = "source-a";
60 private static final String SOURCE_TOPIC2 = "source-b";
62 private static final String EXPECTED = "expected exception";
64 private static final String MY_EVENT = "my-event";
66 private static final String ARTIFACT1 = "artifact-a";
67 private static final String GROUP1 = "group-a";
68 private static final String VERSION1 = "version-a";
70 private static final String ARTIFACT2 = "artifact-b";
71 private static final String GROUP2 = "group-b";
72 private static final String VERSION2 = "version-b";
74 private Properties properties;
75 private TopicEndpoint endpointMgr;
76 private List<TopicSource> sources;
77 private TopicSource source1;
78 private TopicSource source2;
79 private List<TopicSink> sinks;
80 private TopicSink sink1;
81 private TopicSink sink2;
82 private SystemPersistence persist;
83 private DroolsControllerFactory droolsFactory;
84 private DroolsController drools;
85 private DroolsConfiguration config;
86 private List<PolicyControllerFeatureApi> providers;
87 private PolicyControllerFeatureApi prov1;
88 private PolicyControllerFeatureApi prov2;
89 private AggregatedPolicyController apc;
92 * Initializes the object to be tested.
96 properties = new Properties();
98 source1 = mock(TopicSource.class);
99 source2 = mock(TopicSource.class);
100 when(source1.getTopic()).thenReturn(SOURCE_TOPIC1);
101 when(source2.getTopic()).thenReturn(SOURCE_TOPIC2);
103 sink1 = mock(TopicSink.class);
104 sink2 = mock(TopicSink.class);
105 when(sink1.getTopic()).thenReturn(SINK_TOPIC1);
106 when(sink2.getTopic()).thenReturn(SINK_TOPIC2);
108 sources = Arrays.asList(source1, source2);
109 sinks = Arrays.asList(sink1, sink2);
111 endpointMgr = mock(TopicEndpoint.class);
112 when(endpointMgr.addTopicSources(any())).thenReturn(sources);
113 when(endpointMgr.addTopicSinks(any())).thenReturn(sinks);
115 persist = mock(SystemPersistence.class);
117 drools = mock(DroolsController.class);
118 when(drools.start()).thenReturn(true);
119 when(drools.stop()).thenReturn(true);
120 when(drools.offer(any(), any())).thenReturn(true);
121 when(drools.deliver(any(), any())).thenReturn(true);
122 when(drools.lock()).thenReturn(true);
123 when(drools.unlock()).thenReturn(true);
124 when(drools.getArtifactId()).thenReturn(ARTIFACT1);
125 when(drools.getGroupId()).thenReturn(GROUP1);
126 when(drools.getVersion()).thenReturn(VERSION1);
128 config = mock(DroolsConfiguration.class);
129 when(config.getArtifactId()).thenReturn(ARTIFACT2);
130 when(config.getGroupId()).thenReturn(GROUP2);
131 when(config.getVersion()).thenReturn(VERSION2);
133 droolsFactory = mock(DroolsControllerFactory.class);
134 when(droolsFactory.build(any(), any(), any())).thenReturn(drools);
136 prov1 = mock(PolicyControllerFeatureApi.class);
137 prov2 = mock(PolicyControllerFeatureApi.class);
139 providers = Arrays.asList(prov1, prov2);
141 apc = new AggregatedPolicyControllerImpl(AGG_NAME, properties);
145 public void testFactory() {
146 apc = new AggregatedPolicyController(AGG_NAME, properties);
147 assertNotNull(apc.getDroolsFactory());
148 assertNotNull(apc.getEndpointManager());
149 assertNotNull(apc.getProviders());
150 assertNotNull(apc.getPersistenceManager());
154 public void testAggregatedPolicyController_() {
155 verify(persist).storeController(AGG_NAME, properties);
158 @Test(expected = IllegalArgumentException.class)
159 public void testInitDrools_Ex() {
160 new AggregatedPolicyControllerImpl(AGG_NAME, properties) {
162 protected DroolsControllerFactory getDroolsFactory() {
163 throw new RuntimeException(EXPECTED);
168 @Test(expected = IllegalArgumentException.class)
169 public void testInitDrools_Error() {
170 new AggregatedPolicyControllerImpl(AGG_NAME, properties) {
172 protected DroolsControllerFactory getDroolsFactory() {
173 throw new LinkageError(EXPECTED);
179 public void testUpdateDrools_ConfigVariations() {
181 // config should return same values as current controller
182 when(config.getArtifactId()).thenReturn(ARTIFACT1.toUpperCase());
183 when(config.getGroupId()).thenReturn(GROUP1.toUpperCase());
184 when(config.getVersion()).thenReturn(VERSION1.toUpperCase());
186 assertTrue(apc.updateDrools(config));
188 // number of times store should have been called
191 // invoked once during construction, but shouldn't be invoked during update
192 verify(persist, times(++count)).storeController(any(), any());
195 // different artifact
196 when(config.getArtifactId()).thenReturn(ARTIFACT2);
198 assertTrue(apc.updateDrools(config));
200 // should be invoked during update
201 verify(persist, times(++count)).storeController(any(), any());
205 when(config.getArtifactId()).thenReturn(ARTIFACT1);
206 when(config.getGroupId()).thenReturn(GROUP2);
208 assertTrue(apc.updateDrools(config));
210 // should be invoked during update
211 verify(persist, times(++count)).storeController(any(), any());
215 when(config.getGroupId()).thenReturn(GROUP1);
216 when(config.getVersion()).thenReturn(VERSION2);
218 assertTrue(apc.updateDrools(config));
220 // should be invoked during update
221 verify(persist, times(++count)).storeController(any(), any());
227 when(drools.lock()).thenThrow(new IllegalArgumentException(EXPECTED));
228 when(drools.unlock()).thenThrow(new IllegalArgumentException(EXPECTED));
230 assertFalse(apc.updateDrools(config));
234 public void testUpdateDrools_LockVariations() {
236 apc.updateDrools(config);
237 verify(drools, never()).lock();
238 verify(drools).unlock();
243 apc.updateDrools(config);
244 verify(drools, times(2)).lock();
245 verify(drools, never()).unlock();
249 public void testUpdateDrools_AliveVariations() {
251 apc.updateDrools(config);
252 verify(drools, never()).start();
253 verify(drools).stop();
258 apc.updateDrools(config);
259 verify(drools, times(2)).start();
260 verify(drools, never()).stop();
264 public void testSerialize() {
265 new GsonMgmtTestBuilder().addDroolsControllerMock().addTopicSinkMock().addTopicSourceMock().build()
266 .compareGson(apc, AggregatedPolicyControllerTest.class);
270 public void testGetName() {
271 assertEquals(AGG_NAME, apc.getName());
275 public void testStart() {
276 // arrange for first provider to throw exceptions
277 when(prov1.beforeStart(any())).thenThrow(new RuntimeException(EXPECTED));
278 when(prov1.afterStart(any())).thenThrow(new RuntimeException(EXPECTED));
280 // arrange for first sink to throw exception
281 when(sink1.start()).thenThrow(new RuntimeException(EXPECTED));
284 assertTrue(apc.start());
286 assertTrue(apc.isAlive());
288 verify(prov1).beforeStart(apc);
289 verify(prov2).beforeStart(apc);
291 verify(source1).register(apc);
292 verify(source2).register(apc);
294 verify(sink1).start();
295 verify(sink2).start();
297 verify(prov1).afterStart(apc);
298 verify(prov2).afterStart(apc);
301 (prov, flag) -> when(prov.beforeStart(apc)).thenReturn(flag),
302 (prov, flag) -> when(prov.afterStart(apc)).thenReturn(flag),
304 prov -> verify(prov).beforeStart(apc),
305 () -> verify(source1).register(apc),
306 prov -> verify(prov).afterStart(apc));
310 public void testStart_AlreadyStarted() {
314 assertTrue(apc.start());
316 assertTrue(apc.isAlive());
318 // these should now have been called twice
319 verify(prov1, times(2)).beforeStart(apc);
320 verify(prov2, times(2)).beforeStart(apc);
322 // these should still only have been called once
323 verify(source1).register(apc);
324 verify(sink1).start();
325 verify(prov1).afterStart(apc);
329 public void testStart_Locked() {
333 assertThatIllegalStateException().isThrownBy(() -> apc.start());
335 assertFalse(apc.isAlive());
337 // should call beforeStart(), but stop after that
338 verify(prov1).beforeStart(apc);
339 verify(prov2).beforeStart(apc);
341 verify(source1, never()).register(apc);
342 verify(sink1, never()).start();
343 verify(prov1, never()).afterStart(apc);
347 public void testStop() {
348 // arrange for first provider to throw exceptions
349 when(prov1.beforeStop(any())).thenThrow(new RuntimeException(EXPECTED));
350 when(prov1.afterStop(any())).thenThrow(new RuntimeException(EXPECTED));
356 assertTrue(apc.stop());
358 assertFalse(apc.isAlive());
360 verify(prov1).beforeStop(apc);
361 verify(prov2).beforeStop(apc);
363 verify(source1).unregister(apc);
364 verify(source2).unregister(apc);
366 verify(prov1).afterStop(apc);
367 verify(prov2).afterStop(apc);
369 // ensure no shutdown operations were called
370 verify(prov1, never()).beforeShutdown(apc);
371 verify(droolsFactory, never()).shutdown(drools);
372 verify(prov2, never()).afterShutdown(apc);
375 (prov, flag) -> when(prov.beforeStop(apc)).thenReturn(flag),
376 (prov, flag) -> when(prov.afterStop(apc)).thenReturn(flag),
381 prov -> verify(prov).beforeStop(apc),
382 () -> verify(source1).unregister(apc),
383 prov -> verify(prov).afterStop(apc));
387 public void testStop_AlreadyStopped() {
392 assertTrue(apc.stop());
395 verify(prov1, times(2)).beforeStop(apc);
396 verify(prov2, times(2)).beforeStop(apc);
398 // should NOT be called again
399 verify(source1).unregister(apc);
400 verify(prov1).afterStop(apc);
404 public void testShutdown() {
405 // arrange for first provider to throw exceptions
406 when(prov1.beforeShutdown(any())).thenThrow(new RuntimeException(EXPECTED));
407 when(prov1.afterShutdown(any())).thenThrow(new RuntimeException(EXPECTED));
415 verify(prov1).beforeShutdown(apc);
416 verify(prov2).beforeShutdown(apc);
418 assertFalse(apc.isAlive());
420 verify(prov1).afterStop(apc);
421 verify(prov2).afterStop(apc);
423 verify(droolsFactory).shutdown(drools);
425 verify(prov1).afterShutdown(apc);
426 verify(prov2).afterShutdown(apc);
428 // ensure no halt operation was called
429 verify(prov1, never()).beforeHalt(apc);
432 (prov, flag) -> when(prov.beforeShutdown(apc)).thenReturn(flag),
433 (prov, flag) -> when(prov.afterShutdown(apc)).thenReturn(flag),
438 prov -> verify(prov).beforeShutdown(apc),
439 () -> verify(source1).unregister(apc),
440 prov -> verify(prov).afterShutdown(apc));
444 public void testHalt() {
445 // arrange for first provider to throw exceptions
446 when(prov1.beforeHalt(any())).thenThrow(new RuntimeException(EXPECTED));
447 when(prov1.afterHalt(any())).thenThrow(new RuntimeException(EXPECTED));
455 verify(prov1).beforeHalt(apc);
456 verify(prov2).beforeHalt(apc);
458 assertFalse(apc.isAlive());
460 verify(prov1).beforeStop(apc);
461 verify(prov2).beforeStop(apc);
463 verify(droolsFactory).destroy(drools);
464 verify(persist).deleteController(AGG_NAME);
466 verify(prov1).afterHalt(apc);
467 verify(prov2).afterHalt(apc);
469 // ensure no shutdown operation was called
470 verify(prov1, never()).beforeShutdown(apc);
473 (prov, flag) -> when(prov.beforeHalt(apc)).thenReturn(flag),
474 (prov, flag) -> when(prov.afterHalt(apc)).thenReturn(flag),
479 prov -> verify(prov).beforeHalt(apc),
480 () -> verify(source1).unregister(apc),
481 prov -> verify(prov).afterHalt(apc));
485 public void testOnTopicEvent() {
486 // arrange for first provider to throw exceptions
487 when(prov1.beforeOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT))
488 .thenThrow(new RuntimeException(EXPECTED));
489 when(prov1.afterOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT, true))
490 .thenThrow(new RuntimeException(EXPECTED));
496 apc.onTopicEvent(CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT);
498 verify(prov1).beforeOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT);
499 verify(prov2).beforeOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT);
501 verify(drools).offer(SOURCE_TOPIC1, MY_EVENT);
503 verify(prov1).afterOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT, true);
504 verify(prov2).afterOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT, true);
507 (prov, flag) -> when(prov.beforeOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT))
509 (prov, flag) -> when(
510 prov.afterOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT, true))
514 apc.onTopicEvent(CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT);
516 prov -> verify(prov).beforeOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT),
517 () -> verify(drools).offer(SOURCE_TOPIC1, MY_EVENT),
518 prov -> verify(prov).afterOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT, true));
522 public void testOnTopicEvent_Locked() {
529 apc.onTopicEvent(CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT);
531 verify(prov1, never()).beforeOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT);
532 verify(prov2, never()).beforeOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT);
534 // never gets this far
535 verify(drools, never()).offer(SOURCE_TOPIC1, MY_EVENT);
536 verify(prov1, never()).afterOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT, true);
540 public void testOnTopicEvent_NotStarted() {
543 apc.onTopicEvent(CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT);
545 verify(prov1, never()).beforeOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT);
546 verify(prov2, never()).beforeOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT);
548 // never gets this far
549 verify(drools, never()).offer(SOURCE_TOPIC1, MY_EVENT);
550 verify(prov1, never()).afterOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT, true);
554 public void testDeliver_testInitSinks() {
555 // arrange for first provider to throw exceptions
556 when(prov1.beforeDeliver(apc, CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT))
557 .thenThrow(new RuntimeException(EXPECTED));
558 when(prov1.afterDeliver(apc, CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT, true))
559 .thenThrow(new RuntimeException(EXPECTED));
565 assertTrue(apc.deliver(CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT));
567 verify(prov1).beforeDeliver(apc, CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT);
568 verify(prov2).beforeDeliver(apc, CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT);
570 verify(drools).deliver(sink1, MY_EVENT);
571 verify(drools, never()).deliver(sink2, MY_EVENT);
573 verify(prov1).afterDeliver(apc, CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT, true);
574 verify(prov2).afterDeliver(apc, CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT, true);
576 // offer to the other topic
577 assertTrue(apc.deliver(CommInfrastructure.NOOP, SINK_TOPIC2, MY_EVENT));
579 // now both topics should show one message delivered
580 verify(drools).deliver(sink1, MY_EVENT);
581 verify(drools).deliver(sink2, MY_EVENT);
584 (prov, flag) -> when(prov.beforeDeliver(apc, CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT))
586 (prov, flag) -> when(
587 prov.afterDeliver(apc, CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT, true))
591 apc.deliver(CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT);
593 prov -> verify(prov).beforeDeliver(apc, CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT),
594 () -> verify(drools).deliver(sink1, MY_EVENT),
595 prov -> verify(prov).afterDeliver(apc, CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT, true));
598 @Test(expected = IllegalArgumentException.class)
599 public void testDeliver_NullTopic() {
601 apc.deliver(CommInfrastructure.NOOP, null, MY_EVENT);
604 @Test(expected = IllegalArgumentException.class)
605 public void testDeliver_EmptyTopic() {
607 apc.deliver(CommInfrastructure.NOOP, "", MY_EVENT);
610 @Test(expected = IllegalArgumentException.class)
611 public void testDeliver_NullEvent() {
613 apc.deliver(CommInfrastructure.NOOP, SINK_TOPIC1, null);
616 @Test(expected = IllegalStateException.class)
617 public void testDeliver_NotStarted() {
619 apc.deliver(CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT);
622 @Test(expected = IllegalStateException.class)
623 public void testDeliver_Locked() {
626 apc.deliver(CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT);
629 @Test(expected = IllegalArgumentException.class)
630 public void testDeliver_UnknownTopic() {
632 apc.deliver(CommInfrastructure.NOOP, "unknown-topic", MY_EVENT);
636 public void testIsAlive() {
637 assertFalse(apc.isAlive());
640 assertTrue(apc.isAlive());
643 assertFalse(apc.isAlive());
647 public void testLock() {
648 // arrange for first provider to throw exceptions
649 when(prov1.beforeLock(any())).thenThrow(new RuntimeException(EXPECTED));
650 when(prov1.afterLock(any())).thenThrow(new RuntimeException(EXPECTED));
656 assertTrue(apc.lock());
658 verify(prov1).beforeLock(apc);
659 verify(prov2).beforeLock(apc);
661 assertTrue(apc.isLocked());
663 verify(drools).lock();
665 verify(prov1).afterLock(apc);
666 verify(prov2).afterLock(apc);
669 (prov, flag) -> when(prov.beforeLock(apc)).thenReturn(flag),
670 (prov, flag) -> when(prov.afterLock(apc)).thenReturn(flag),
675 prov -> verify(prov).beforeLock(apc),
676 () -> verify(drools).lock(),
677 prov -> verify(prov).afterLock(apc));
681 public void testLock_AlreadyLocked() {
686 assertTrue(apc.lock());
688 // these should be invoked a second time
689 verify(prov1, times(2)).beforeLock(apc);
690 verify(prov2, times(2)).beforeLock(apc);
692 assertTrue(apc.isLocked());
694 // these shouldn't be invoked a second time
695 verify(drools).lock();
696 verify(prov1).afterLock(apc);
700 public void testUnlock() {
701 // arrange for first provider to throw exceptions
702 when(prov1.beforeUnlock(any())).thenThrow(new RuntimeException(EXPECTED));
703 when(prov1.afterUnlock(any())).thenThrow(new RuntimeException(EXPECTED));
710 assertTrue(apc.unlock());
712 verify(prov1).beforeUnlock(apc);
713 verify(prov2).beforeUnlock(apc);
715 assertFalse(apc.isLocked());
717 verify(drools).unlock();
719 verify(prov1).afterUnlock(apc);
720 verify(prov2).afterUnlock(apc);
723 (prov, flag) -> when(prov.beforeUnlock(apc)).thenReturn(flag),
724 (prov, flag) -> when(prov.afterUnlock(apc)).thenReturn(flag),
730 prov -> verify(prov).beforeUnlock(apc),
731 () -> verify(drools).unlock(),
732 prov -> verify(prov).afterUnlock(apc));
736 public void testUnlock_NotLocked() {
740 assertTrue(apc.unlock());
742 verify(prov1).beforeUnlock(apc);
743 verify(prov2).beforeUnlock(apc);
745 assertFalse(apc.isLocked());
747 // these shouldn't be invoked
748 verify(drools, never()).unlock();
749 verify(prov1, never()).afterLock(apc);
753 public void testIsLocked() {
754 assertFalse(apc.isLocked());
757 assertTrue(apc.isLocked());
760 assertFalse(apc.isLocked());
764 public void testGetTopicSources() {
765 assertEquals(sources, apc.getTopicSources());
769 public void testGetTopicSinks() {
770 assertEquals(sinks, apc.getTopicSinks());
774 public void testGetDrools() {
775 assertEquals(drools, apc.getDrools());
779 public void testGetProperties() {
780 assertEquals(properties, apc.getProperties());
784 public void testToString() {
785 assertTrue(apc.toString().startsWith("AggregatedPolicyController ["));
789 * Performs an operation that has a beforeXxx method and an afterXxx method. Tries
790 * combinations where beforeXxx and afterXxx return {@code true} and {@code false}.
792 * @param setBefore function to set the return value of a provider's beforeXxx method
793 * @param setAfter function to set the return value of a provider's afterXxx method
794 * @param action invokes the operation
795 * @param verifyBefore verifies that a provider's beforeXxx method was invoked
796 * @param verifyMiddle verifies that the action occurring between the beforeXxx loop
797 * and the afterXxx loop was invoked
798 * @param verifyAfter verifies that a provider's afterXxx method was invoked
800 private void checkBeforeAfter(BiConsumer<PolicyControllerFeatureApi, Boolean> setBefore,
801 BiConsumer<PolicyControllerFeatureApi, Boolean> setAfter, Runnable action,
802 Consumer<PolicyControllerFeatureApi> verifyBefore, Runnable verifyMiddle,
803 Consumer<PolicyControllerFeatureApi> verifyAfter) {
805 checkBeforeAfter_FalseFalse(setBefore, setAfter, action, verifyBefore, verifyMiddle, verifyAfter);
806 checkBeforeAfter_FalseTrue(setBefore, setAfter, action, verifyBefore, verifyMiddle, verifyAfter);
807 checkBeforeAfter_TrueFalse(setBefore, setAfter, action, verifyBefore, verifyMiddle, verifyAfter);
809 // don't need to test true-true, as it's behavior is a subset of true-false
813 * Performs an operation that has a beforeXxx method and an afterXxx method. Tries the
814 * case where both the beforeXxx and afterXxx methods return {@code false}.
816 * @param setBefore function to set the return value of a provider's beforeXxx method
817 * @param setAfter function to set the return value of a provider's afterXxx method
818 * @param action invokes the operation
819 * @param verifyBefore verifies that a provider's beforeXxx method was invoked
820 * @param verifyMiddle verifies that the action occurring between the beforeXxx loop
821 * and the afterXxx loop was invoked
822 * @param verifyAfter verifies that a provider's afterXxx method was invoked
824 private void checkBeforeAfter_FalseFalse(BiConsumer<PolicyControllerFeatureApi, Boolean> setBefore,
825 BiConsumer<PolicyControllerFeatureApi, Boolean> setAfter, Runnable action,
826 Consumer<PolicyControllerFeatureApi> verifyBefore, Runnable verifyMiddle,
827 Consumer<PolicyControllerFeatureApi> verifyAfter) {
831 // configure for the test
832 setBefore.accept(prov1, false);
833 setBefore.accept(prov2, false);
835 setAfter.accept(prov1, false);
836 setAfter.accept(prov2, false);
841 // verify that various methods were invoked
842 verifyBefore.accept(prov1);
843 verifyBefore.accept(prov2);
847 verifyAfter.accept(prov1);
848 verifyAfter.accept(prov2);
852 * Performs an operation that has a beforeXxx method and an afterXxx method. Tries the
853 * case where the first provider's afterXxx returns {@code true}, while the others
854 * return {@code false}.
856 * @param setBefore function to set the return value of a provider's beforeXxx method
857 * @param setAfter function to set the return value of a provider's afterXxx method
858 * @param action invokes the operation
859 * @param verifyBefore verifies that a provider's beforeXxx method was invoked
860 * @param verifyMiddle verifies that the action occurring between the beforeXxx loop
861 * and the afterXxx loop was invoked
862 * @param verifyAfter verifies that a provider's afterXxx method was invoked
864 private void checkBeforeAfter_FalseTrue(BiConsumer<PolicyControllerFeatureApi, Boolean> setBefore,
865 BiConsumer<PolicyControllerFeatureApi, Boolean> setAfter, Runnable action,
866 Consumer<PolicyControllerFeatureApi> verifyBefore, Runnable verifyMiddle,
867 Consumer<PolicyControllerFeatureApi> verifyAfter) {
871 // configure for the test
872 setBefore.accept(prov1, false);
873 setBefore.accept(prov2, false);
875 setAfter.accept(prov1, true);
876 setAfter.accept(prov2, false);
881 // verify that various methods were invoked
882 verifyBefore.accept(prov1);
883 verifyBefore.accept(prov2);
887 verifyAfter.accept(prov1);
888 assertThatThrownBy(() -> verifyAfter.accept(prov2)).isInstanceOf(AssertionError.class);
892 * Performs an operation that has a beforeXxx method and an afterXxx method. Tries the
893 * case where the first provider's beforeXxx returns {@code true}, while the others
894 * return {@code false}.
896 * @param setBefore function to set the return value of a provider's beforeXxx method
897 * @param setAfter function to set the return value of a provider's afterXxx method
898 * @param action invokes the operation
899 * @param verifyBefore verifies that a provider's beforeXxx method was invoked
900 * @param verifyMiddle verifies that the action occurring between the beforeXxx loop
901 * and the afterXxx loop was invoked
902 * @param verifyAfter verifies that a provider's afterXxx method was invoked
904 private void checkBeforeAfter_TrueFalse(BiConsumer<PolicyControllerFeatureApi, Boolean> setBefore,
905 BiConsumer<PolicyControllerFeatureApi, Boolean> setAfter, Runnable action,
906 Consumer<PolicyControllerFeatureApi> verifyBefore, Runnable verifyMiddle,
907 Consumer<PolicyControllerFeatureApi> verifyAfter) {
911 // configure for the test
912 setBefore.accept(prov1, true);
913 setBefore.accept(prov2, false);
915 setAfter.accept(prov1, false);
916 setAfter.accept(prov2, false);
921 // verify that various methods were invoked
922 verifyBefore.accept(prov1);
924 // remaining methods should not have been invoked
925 assertThatThrownBy(() -> verifyBefore.accept(prov2)).isInstanceOf(AssertionError.class);
927 assertThatThrownBy(() -> verifyMiddle.run()).isInstanceOf(AssertionError.class);
929 assertThatThrownBy(() -> verifyAfter.accept(prov1)).isInstanceOf(AssertionError.class);
930 assertThatThrownBy(() -> verifyAfter.accept(prov2)).isInstanceOf(AssertionError.class);
934 * Controller with overrides.
936 private class AggregatedPolicyControllerImpl extends AggregatedPolicyController {
938 public AggregatedPolicyControllerImpl(String name, Properties properties) {
939 super(name, properties);
943 protected SystemPersistence getPersistenceManager() {
948 protected TopicEndpoint getEndpointManager() {
953 protected DroolsControllerFactory getDroolsFactory() {
954 return droolsFactory;
958 protected List<PolicyControllerFeatureApi> getProviders() {