2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2018-2021 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.assertThatCode;
24 import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
25 import static org.assertj.core.api.Assertions.assertThatThrownBy;
26 import static org.junit.Assert.assertEquals;
27 import static org.junit.Assert.assertFalse;
28 import static org.junit.Assert.assertNotNull;
29 import static org.junit.Assert.assertTrue;
30 import static org.mockito.ArgumentMatchers.any;
31 import static org.mockito.Mockito.mock;
32 import static org.mockito.Mockito.never;
33 import static org.mockito.Mockito.times;
34 import static org.mockito.Mockito.verify;
35 import static org.mockito.Mockito.when;
37 import java.util.Arrays;
38 import java.util.List;
39 import java.util.Properties;
40 import java.util.function.BiConsumer;
41 import java.util.function.Consumer;
42 import org.junit.Before;
43 import org.junit.Test;
44 import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure;
45 import org.onap.policy.common.endpoints.event.comm.TopicEndpoint;
46 import org.onap.policy.common.endpoints.event.comm.TopicSink;
47 import org.onap.policy.common.endpoints.event.comm.TopicSource;
48 import org.onap.policy.common.utils.gson.GsonTestUtils;
49 import org.onap.policy.drools.controller.DroolsController;
50 import org.onap.policy.drools.controller.DroolsControllerFactory;
51 import org.onap.policy.drools.features.PolicyControllerFeatureApi;
52 import org.onap.policy.drools.persistence.SystemPersistence;
53 import org.onap.policy.drools.protocol.configuration.DroolsConfiguration;
54 import org.onap.policy.drools.system.GsonMgmtTestBuilder;
56 public class AggregatedPolicyControllerTest {
58 private static final String AGG_NAME = "agg-name";
59 private static final String SINK_TOPIC1 = "sink-a";
60 private static final String SINK_TOPIC2 = "sink-b";
61 private static final String SOURCE_TOPIC1 = "source-a";
62 private static final String SOURCE_TOPIC2 = "source-b";
64 private static final String EXPECTED = "expected exception";
66 private static final String MY_EVENT = "my-event";
68 private static final String ARTIFACT1 = "artifact-a";
69 private static final String GROUP1 = "group-a";
70 private static final String VERSION1 = "version-a";
72 private static final String ARTIFACT2 = "artifact-b";
73 private static final String GROUP2 = "group-b";
74 private static final String VERSION2 = "version-b";
76 private Properties properties;
77 private TopicEndpoint endpointMgr;
78 private List<TopicSource> sources;
79 private TopicSource source1;
80 private TopicSource source2;
81 private List<TopicSink> sinks;
82 private TopicSink sink1;
83 private TopicSink sink2;
84 private SystemPersistence persist;
85 private DroolsControllerFactory droolsFactory;
86 private DroolsController drools;
87 private DroolsConfiguration config;
88 private List<PolicyControllerFeatureApi> providers;
89 private PolicyControllerFeatureApi prov1;
90 private PolicyControllerFeatureApi prov2;
91 private AggregatedPolicyController apc;
94 * Initializes the object to be tested.
98 properties = new Properties();
100 source1 = mock(TopicSource.class);
101 source2 = mock(TopicSource.class);
102 when(source1.getTopic()).thenReturn(SOURCE_TOPIC1);
103 when(source2.getTopic()).thenReturn(SOURCE_TOPIC2);
105 sink1 = mock(TopicSink.class);
106 sink2 = mock(TopicSink.class);
107 when(sink1.getTopic()).thenReturn(SINK_TOPIC1);
108 when(sink2.getTopic()).thenReturn(SINK_TOPIC2);
110 sources = Arrays.asList(source1, source2);
111 sinks = Arrays.asList(sink1, sink2);
113 endpointMgr = mock(TopicEndpoint.class);
114 when(endpointMgr.addTopicSources(any(Properties.class))).thenReturn(sources);
115 when(endpointMgr.addTopicSinks(any(Properties.class))).thenReturn(sinks);
117 persist = mock(SystemPersistence.class);
119 drools = mock(DroolsController.class);
120 when(drools.start()).thenReturn(true);
121 when(drools.stop()).thenReturn(true);
122 when(drools.offer(any(), any())).thenReturn(true);
123 when(drools.deliver(any(), any())).thenReturn(true);
124 when(drools.lock()).thenReturn(true);
125 when(drools.unlock()).thenReturn(true);
126 when(drools.getArtifactId()).thenReturn(ARTIFACT1);
127 when(drools.getGroupId()).thenReturn(GROUP1);
128 when(drools.getVersion()).thenReturn(VERSION1);
130 config = mock(DroolsConfiguration.class);
131 when(config.getArtifactId()).thenReturn(ARTIFACT2);
132 when(config.getGroupId()).thenReturn(GROUP2);
133 when(config.getVersion()).thenReturn(VERSION2);
135 droolsFactory = mock(DroolsControllerFactory.class);
136 when(droolsFactory.build(any(), any(), any())).thenReturn(drools);
138 prov1 = mock(PolicyControllerFeatureApi.class);
139 prov2 = mock(PolicyControllerFeatureApi.class);
141 providers = Arrays.asList(prov1, prov2);
143 apc = new AggregatedPolicyControllerImpl(AGG_NAME, properties);
147 public void testFactory() {
148 apc = new AggregatedPolicyController(AGG_NAME, properties);
149 assertNotNull(apc.getDroolsFactory());
150 assertNotNull(apc.getEndpointManager());
151 assertNotNull(apc.getProviders());
152 assertNotNull(apc.getPersistenceManager());
156 public void testAggregatedPolicyController_() {
157 verify(persist).storeController(AGG_NAME, properties);
160 @Test(expected = IllegalArgumentException.class)
161 public void testInitDrools_Ex() {
162 new AggregatedPolicyControllerImpl(AGG_NAME, properties) {
164 protected DroolsControllerFactory getDroolsFactory() {
165 throw new RuntimeException(EXPECTED);
170 @Test(expected = IllegalArgumentException.class)
171 public void testInitDrools_Error() {
172 new AggregatedPolicyControllerImpl(AGG_NAME, properties) {
174 protected DroolsControllerFactory getDroolsFactory() {
175 throw new LinkageError(EXPECTED);
181 public void testUpdateDrools_ConfigVariations() {
183 // config should return same values as current controller
184 when(config.getArtifactId()).thenReturn(ARTIFACT1.toUpperCase());
185 when(config.getGroupId()).thenReturn(GROUP1.toUpperCase());
186 when(config.getVersion()).thenReturn(VERSION1.toUpperCase());
188 assertTrue(apc.updateDrools(config));
190 // number of times store should have been called
193 // invoked once during construction, but shouldn't be invoked during update
194 verify(persist, times(++count)).storeController(any(), any());
197 // different artifact
198 when(config.getArtifactId()).thenReturn(ARTIFACT2);
200 assertTrue(apc.updateDrools(config));
202 // should be invoked during update
203 verify(persist, times(++count)).storeController(any(), any());
207 when(config.getArtifactId()).thenReturn(ARTIFACT1);
208 when(config.getGroupId()).thenReturn(GROUP2);
210 assertTrue(apc.updateDrools(config));
212 // should be invoked during update
213 verify(persist, times(++count)).storeController(any(), any());
217 when(config.getGroupId()).thenReturn(GROUP1);
218 when(config.getVersion()).thenReturn(VERSION2);
220 assertTrue(apc.updateDrools(config));
222 // should be invoked during update
223 verify(persist, times(++count)).storeController(any(), any());
229 when(drools.lock()).thenThrow(new IllegalArgumentException(EXPECTED));
230 when(drools.unlock()).thenThrow(new IllegalArgumentException(EXPECTED));
232 assertFalse(apc.updateDrools(config));
236 public void testUpdateDrools_LockVariations() {
238 apc.updateDrools(config);
239 verify(drools, never()).lock();
240 verify(drools).unlock();
245 apc.updateDrools(config);
246 verify(drools, times(2)).lock();
247 verify(drools, never()).unlock();
251 public void testUpdateDrools_AliveVariations() {
253 apc.updateDrools(config);
254 verify(drools, never()).start();
255 verify(drools).stop();
260 apc.updateDrools(config);
261 verify(drools, times(2)).start();
262 verify(drools, never()).stop();
266 public void testSerialize() {
267 GsonTestUtils gson = new GsonMgmtTestBuilder().addDroolsControllerMock().addTopicSinkMock().addTopicSourceMock()
269 assertThatCode(() -> gson.compareGson(apc, AggregatedPolicyControllerTest.class)).doesNotThrowAnyException();
273 public void testGetName() {
274 assertEquals(AGG_NAME, apc.getName());
278 public void testStart() {
279 // arrange for first provider to throw exceptions
280 when(prov1.beforeStart(any())).thenThrow(new RuntimeException(EXPECTED));
281 when(prov1.afterStart(any())).thenThrow(new RuntimeException(EXPECTED));
283 // arrange for first sink to throw exception
284 when(sink1.start()).thenThrow(new RuntimeException(EXPECTED));
287 assertTrue(apc.start());
289 assertTrue(apc.isAlive());
291 verify(prov1).beforeStart(apc);
292 verify(prov2).beforeStart(apc);
294 verify(source1).register(apc);
295 verify(source2).register(apc);
297 verify(sink1).start();
298 verify(sink2).start();
300 verify(prov1).afterStart(apc);
301 verify(prov2).afterStart(apc);
304 (prov, flag) -> when(prov.beforeStart(apc)).thenReturn(flag),
305 (prov, flag) -> when(prov.afterStart(apc)).thenReturn(flag),
307 prov -> verify(prov).beforeStart(apc),
308 () -> verify(source1).register(apc),
309 prov -> verify(prov).afterStart(apc));
313 public void testStart_AlreadyStarted() {
317 assertTrue(apc.start());
319 assertTrue(apc.isAlive());
321 // these should now have been called twice
322 verify(prov1, times(2)).beforeStart(apc);
323 verify(prov2, times(2)).beforeStart(apc);
325 // these should still only have been called once
326 verify(source1).register(apc);
327 verify(sink1).start();
328 verify(prov1).afterStart(apc);
332 public void testStart_Locked() {
336 assertThatIllegalStateException().isThrownBy(() -> apc.start());
338 assertFalse(apc.isAlive());
340 // should call beforeStart(), but stop after that
341 verify(prov1).beforeStart(apc);
342 verify(prov2).beforeStart(apc);
344 verify(source1, never()).register(apc);
345 verify(sink1, never()).start();
346 verify(prov1, never()).afterStart(apc);
350 public void testStop() {
351 // arrange for first provider to throw exceptions
352 when(prov1.beforeStop(any())).thenThrow(new RuntimeException(EXPECTED));
353 when(prov1.afterStop(any())).thenThrow(new RuntimeException(EXPECTED));
359 assertTrue(apc.stop());
361 assertFalse(apc.isAlive());
363 verify(prov1).beforeStop(apc);
364 verify(prov2).beforeStop(apc);
366 verify(source1).unregister(apc);
367 verify(source2).unregister(apc);
369 verify(prov1).afterStop(apc);
370 verify(prov2).afterStop(apc);
372 // ensure no shutdown operations were called
373 verify(prov1, never()).beforeShutdown(apc);
374 verify(droolsFactory, never()).shutdown(drools);
375 verify(prov2, never()).afterShutdown(apc);
378 (prov, flag) -> when(prov.beforeStop(apc)).thenReturn(flag),
379 (prov, flag) -> when(prov.afterStop(apc)).thenReturn(flag),
384 prov -> verify(prov).beforeStop(apc),
385 () -> verify(source1).unregister(apc),
386 prov -> verify(prov).afterStop(apc));
390 public void testStop_AlreadyStopped() {
395 assertTrue(apc.stop());
398 verify(prov1, times(2)).beforeStop(apc);
399 verify(prov2, times(2)).beforeStop(apc);
401 // should NOT be called again
402 verify(source1).unregister(apc);
403 verify(prov1).afterStop(apc);
407 public void testShutdown() {
408 // arrange for first provider to throw exceptions
409 when(prov1.beforeShutdown(any())).thenThrow(new RuntimeException(EXPECTED));
410 when(prov1.afterShutdown(any())).thenThrow(new RuntimeException(EXPECTED));
418 verify(prov1).beforeShutdown(apc);
419 verify(prov2).beforeShutdown(apc);
421 assertFalse(apc.isAlive());
423 verify(prov1).afterStop(apc);
424 verify(prov2).afterStop(apc);
426 verify(droolsFactory).shutdown(drools);
428 verify(prov1).afterShutdown(apc);
429 verify(prov2).afterShutdown(apc);
431 // ensure no halt operation was called
432 verify(prov1, never()).beforeHalt(apc);
435 (prov, flag) -> when(prov.beforeShutdown(apc)).thenReturn(flag),
436 (prov, flag) -> when(prov.afterShutdown(apc)).thenReturn(flag),
441 prov -> verify(prov).beforeShutdown(apc),
442 () -> verify(source1).unregister(apc),
443 prov -> verify(prov).afterShutdown(apc));
447 public void testHalt() {
448 // arrange for first provider to throw exceptions
449 when(prov1.beforeHalt(any())).thenThrow(new RuntimeException(EXPECTED));
450 when(prov1.afterHalt(any())).thenThrow(new RuntimeException(EXPECTED));
458 verify(prov1).beforeHalt(apc);
459 verify(prov2).beforeHalt(apc);
461 assertFalse(apc.isAlive());
463 verify(prov1).beforeStop(apc);
464 verify(prov2).beforeStop(apc);
466 verify(droolsFactory).destroy(drools);
467 verify(persist).deleteController(AGG_NAME);
469 verify(prov1).afterHalt(apc);
470 verify(prov2).afterHalt(apc);
472 // ensure no shutdown operation was called
473 verify(prov1, never()).beforeShutdown(apc);
476 (prov, flag) -> when(prov.beforeHalt(apc)).thenReturn(flag),
477 (prov, flag) -> when(prov.afterHalt(apc)).thenReturn(flag),
482 prov -> verify(prov).beforeHalt(apc),
483 () -> verify(source1).unregister(apc),
484 prov -> verify(prov).afterHalt(apc));
488 public void testOnTopicEvent() {
489 // arrange for first provider to throw exceptions
490 when(prov1.beforeOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT))
491 .thenThrow(new RuntimeException(EXPECTED));
492 when(prov1.afterOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT, true))
493 .thenThrow(new RuntimeException(EXPECTED));
499 apc.onTopicEvent(CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT);
501 verify(prov1).beforeOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT);
502 verify(prov2).beforeOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT);
504 verify(drools).offer(SOURCE_TOPIC1, MY_EVENT);
506 verify(prov1).afterOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT, true);
507 verify(prov2).afterOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT, true);
510 (prov, flag) -> when(prov.beforeOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT))
512 (prov, flag) -> when(
513 prov.afterOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT, true))
517 apc.onTopicEvent(CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT);
519 prov -> verify(prov).beforeOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT),
520 () -> verify(drools).offer(SOURCE_TOPIC1, MY_EVENT),
521 prov -> verify(prov).afterOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT, true));
525 public void testOnTopicEvent_Locked() {
532 apc.onTopicEvent(CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT);
534 verify(prov1, never()).beforeOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT);
535 verify(prov2, never()).beforeOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT);
537 // never gets this far
538 verify(drools, never()).offer(SOURCE_TOPIC1, MY_EVENT);
539 verify(prov1, never()).afterOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT, true);
543 public void testOnTopicEvent_NotStarted() {
546 apc.onTopicEvent(CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT);
548 verify(prov1, never()).beforeOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT);
549 verify(prov2, never()).beforeOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT);
551 // never gets this far
552 verify(drools, never()).offer(SOURCE_TOPIC1, MY_EVENT);
553 verify(prov1, never()).afterOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT, true);
557 public void testDeliver_testInitSinks() {
558 // arrange for first provider to throw exceptions
559 when(prov1.beforeDeliver(apc, CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT))
560 .thenThrow(new RuntimeException(EXPECTED));
561 when(prov1.afterDeliver(apc, CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT, true))
562 .thenThrow(new RuntimeException(EXPECTED));
568 assertTrue(apc.deliver(CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT));
570 verify(prov1).beforeDeliver(apc, CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT);
571 verify(prov2).beforeDeliver(apc, CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT);
573 verify(drools).deliver(sink1, MY_EVENT);
574 verify(drools, never()).deliver(sink2, MY_EVENT);
576 verify(prov1).afterDeliver(apc, CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT, true);
577 verify(prov2).afterDeliver(apc, CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT, true);
579 // offer to the other topic
580 assertTrue(apc.deliver(CommInfrastructure.NOOP, SINK_TOPIC2, MY_EVENT));
582 // now both topics should show one message delivered
583 verify(drools).deliver(sink1, MY_EVENT);
584 verify(drools).deliver(sink2, MY_EVENT);
587 (prov, flag) -> when(prov.beforeDeliver(apc, CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT))
589 (prov, flag) -> when(
590 prov.afterDeliver(apc, CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT, true))
594 apc.deliver(CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT);
596 prov -> verify(prov).beforeDeliver(apc, CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT),
597 () -> verify(drools).deliver(sink1, MY_EVENT),
598 prov -> verify(prov).afterDeliver(apc, CommInfrastructure.NOOP, SINK_TOPIC1, MY_EVENT, true));
601 @Test(expected = IllegalArgumentException.class)
602 public void testDeliver_NullTopic() {
603 validateDeliverFailure(null, MY_EVENT);
606 @Test(expected = IllegalArgumentException.class)
607 public void testDeliver_EmptyTopic() {
608 validateDeliverFailure("", MY_EVENT);
611 @Test(expected = IllegalArgumentException.class)
612 public void testDeliver_NullEvent() {
613 validateDeliverFailure(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("));
788 private void validateDeliverFailure(String topic, String event) {
790 apc.deliver(CommInfrastructure.NOOP, topic, event);
794 * Performs an operation that has a beforeXxx method and an afterXxx method. Tries
795 * combinations where beforeXxx and afterXxx return {@code true} and {@code false}.
797 * @param setBefore function to set the return value of a provider's beforeXxx method
798 * @param setAfter function to set the return value of a provider's afterXxx method
799 * @param action invokes the operation
800 * @param verifyBefore verifies that a provider's beforeXxx method was invoked
801 * @param verifyMiddle verifies that the action occurring between the beforeXxx loop
802 * and the afterXxx loop was invoked
803 * @param verifyAfter verifies that a provider's afterXxx method was invoked
805 private void checkBeforeAfter(BiConsumer<PolicyControllerFeatureApi, Boolean> setBefore,
806 BiConsumer<PolicyControllerFeatureApi, Boolean> setAfter, Runnable action,
807 Consumer<PolicyControllerFeatureApi> verifyBefore, Runnable verifyMiddle,
808 Consumer<PolicyControllerFeatureApi> verifyAfter) {
810 checkBeforeAfter_FalseFalse(setBefore, setAfter, action, verifyBefore, verifyMiddle, verifyAfter);
811 checkBeforeAfter_FalseTrue(setBefore, setAfter, action, verifyBefore, verifyMiddle, verifyAfter);
812 checkBeforeAfter_TrueFalse(setBefore, setAfter, action, verifyBefore, verifyMiddle, verifyAfter);
814 // don't need to test true-true, as it's behavior is a subset of true-false
818 * Performs an operation that has a beforeXxx method and an afterXxx method. Tries the
819 * case where both the beforeXxx and afterXxx methods return {@code false}.
821 * @param setBefore function to set the return value of a provider's beforeXxx method
822 * @param setAfter function to set the return value of a provider's afterXxx method
823 * @param action invokes the operation
824 * @param verifyBefore verifies that a provider's beforeXxx method was invoked
825 * @param verifyMiddle verifies that the action occurring between the beforeXxx loop
826 * and the afterXxx loop was invoked
827 * @param verifyAfter verifies that a provider's afterXxx method was invoked
829 private void checkBeforeAfter_FalseFalse(BiConsumer<PolicyControllerFeatureApi, Boolean> setBefore,
830 BiConsumer<PolicyControllerFeatureApi, Boolean> setAfter, Runnable action,
831 Consumer<PolicyControllerFeatureApi> verifyBefore, Runnable verifyMiddle,
832 Consumer<PolicyControllerFeatureApi> verifyAfter) {
836 // configure for the test
837 setBefore.accept(prov1, false);
838 setBefore.accept(prov2, false);
840 setAfter.accept(prov1, false);
841 setAfter.accept(prov2, false);
846 // verify that various methods were invoked
847 verifyBefore.accept(prov1);
848 verifyBefore.accept(prov2);
852 verifyAfter.accept(prov1);
853 verifyAfter.accept(prov2);
857 * Performs an operation that has a beforeXxx method and an afterXxx method. Tries the
858 * case where the first provider's afterXxx returns {@code true}, while the others
859 * return {@code false}.
861 * @param setBefore function to set the return value of a provider's beforeXxx method
862 * @param setAfter function to set the return value of a provider's afterXxx method
863 * @param action invokes the operation
864 * @param verifyBefore verifies that a provider's beforeXxx method was invoked
865 * @param verifyMiddle verifies that the action occurring between the beforeXxx loop
866 * and the afterXxx loop was invoked
867 * @param verifyAfter verifies that a provider's afterXxx method was invoked
869 private void checkBeforeAfter_FalseTrue(BiConsumer<PolicyControllerFeatureApi, Boolean> setBefore,
870 BiConsumer<PolicyControllerFeatureApi, Boolean> setAfter, Runnable action,
871 Consumer<PolicyControllerFeatureApi> verifyBefore, Runnable verifyMiddle,
872 Consumer<PolicyControllerFeatureApi> verifyAfter) {
876 // configure for the test
877 setBefore.accept(prov1, false);
878 setBefore.accept(prov2, false);
880 setAfter.accept(prov1, true);
881 setAfter.accept(prov2, false);
886 // verify that various methods were invoked
887 verifyBefore.accept(prov1);
888 verifyBefore.accept(prov2);
892 verifyAfter.accept(prov1);
893 assertThatThrownBy(() -> verifyAfter.accept(prov2)).isInstanceOf(AssertionError.class);
897 * Performs an operation that has a beforeXxx method and an afterXxx method. Tries the
898 * case where the first provider's beforeXxx returns {@code true}, while the others
899 * return {@code false}.
901 * @param setBefore function to set the return value of a provider's beforeXxx method
902 * @param setAfter function to set the return value of a provider's afterXxx method
903 * @param action invokes the operation
904 * @param verifyBefore verifies that a provider's beforeXxx method was invoked
905 * @param verifyMiddle verifies that the action occurring between the beforeXxx loop
906 * and the afterXxx loop was invoked
907 * @param verifyAfter verifies that a provider's afterXxx method was invoked
909 private void checkBeforeAfter_TrueFalse(BiConsumer<PolicyControllerFeatureApi, Boolean> setBefore,
910 BiConsumer<PolicyControllerFeatureApi, Boolean> setAfter, Runnable action,
911 Consumer<PolicyControllerFeatureApi> verifyBefore, Runnable verifyMiddle,
912 Consumer<PolicyControllerFeatureApi> verifyAfter) {
916 // configure for the test
917 setBefore.accept(prov1, true);
918 setBefore.accept(prov2, false);
920 setAfter.accept(prov1, false);
921 setAfter.accept(prov2, false);
926 // verify that various methods were invoked
927 verifyBefore.accept(prov1);
929 // remaining methods should not have been invoked
930 assertThatThrownBy(() -> verifyBefore.accept(prov2)).isInstanceOf(AssertionError.class);
932 assertThatThrownBy(verifyMiddle::run).isInstanceOf(AssertionError.class);
934 assertThatThrownBy(() -> verifyAfter.accept(prov1)).isInstanceOf(AssertionError.class);
935 assertThatThrownBy(() -> verifyAfter.accept(prov2)).isInstanceOf(AssertionError.class);
939 * Controller with overrides.
941 private class AggregatedPolicyControllerImpl extends AggregatedPolicyController {
943 public AggregatedPolicyControllerImpl(String name, Properties properties) {
944 super(name, properties);
948 protected SystemPersistence getPersistenceManager() {
953 protected TopicEndpoint getEndpointManager() {
958 protected DroolsControllerFactory getDroolsFactory() {
959 return droolsFactory;
963 protected List<PolicyControllerFeatureApi> getProviders() {