diff options
Diffstat (limited to 'feature-pooling-dmaap/src/test')
5 files changed, 456 insertions, 362 deletions
diff --git a/feature-pooling-dmaap/src/test/java/org/onap/policy/drools/pooling/DmaapManagerTest.java b/feature-pooling-dmaap/src/test/java/org/onap/policy/drools/pooling/DmaapManagerTest.java index e554a34a..a6404f40 100644 --- a/feature-pooling-dmaap/src/test/java/org/onap/policy/drools/pooling/DmaapManagerTest.java +++ b/feature-pooling-dmaap/src/test/java/org/onap/policy/drools/pooling/DmaapManagerTest.java @@ -32,45 +32,30 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.Arrays; -import java.util.LinkedList; +import java.util.Collections; +import java.util.List; import java.util.concurrent.CountDownLatch; -import org.junit.AfterClass; import org.junit.Before; -import org.junit.BeforeClass; import org.junit.Test; import org.onap.policy.common.endpoints.event.comm.FilterableTopicSource; import org.onap.policy.common.endpoints.event.comm.TopicListener; import org.onap.policy.common.endpoints.event.comm.TopicSink; import org.onap.policy.common.endpoints.event.comm.TopicSource; -import org.onap.policy.drools.pooling.DmaapManager.Factory; public class DmaapManagerTest { - private static String MY_TOPIC = "my.topic"; - private static String MSG = "a message"; - private static String FILTER = "a filter"; - - /** - * Original factory, to be restored when all tests complete. - */ - private static Factory saveFactory; - - private Factory factory; + private static final String EXPECTED = "expected"; + private static final String MY_TOPIC = "my.topic"; + private static final String MSG = "a message"; + private static final String FILTER = "a filter"; + private TopicListener listener; private FilterableTopicSource source; + private boolean gotSources; private TopicSink sink; + private boolean gotSinks; private DmaapManager mgr; - @BeforeClass - public static void setUpBeforeClass() throws Exception { - saveFactory = DmaapManager.getFactory(); - } - - @AfterClass - public static void tearDownAfterClass() throws Exception { - DmaapManager.setFactory(saveFactory); - } - /** * Setup. * @@ -79,33 +64,24 @@ public class DmaapManagerTest { @Before public void setUp() throws Exception { listener = mock(TopicListener.class); - factory = mock(Factory.class); source = mock(FilterableTopicSource.class); + gotSources = false; sink = mock(TopicSink.class); - - DmaapManager.setFactory(factory); + gotSinks = false; when(source.getTopic()).thenReturn(MY_TOPIC); when(sink.getTopic()).thenReturn(MY_TOPIC); when(sink.send(any())).thenReturn(true); - // three sources, with the desired one in the middle - when(factory.getTopicSources()) - .thenReturn(Arrays.asList(mock(TopicSource.class), source, mock(TopicSource.class))); - - // three sinks, with the desired one in the middle - when(factory.getTopicSinks()) - .thenReturn(Arrays.asList(mock(TopicSink.class), sink, mock(TopicSink.class))); - - mgr = new DmaapManager(MY_TOPIC); + mgr = new DmaapManagerImpl(MY_TOPIC); } @Test public void testDmaapManager() { // verify that the init methods were called - verify(factory).getTopicSinks(); - verify(factory).getTopicSinks(); + assertTrue(gotSources); + assertTrue(gotSinks); } @Test(expected = PoolingFeatureException.class) @@ -113,23 +89,26 @@ public class DmaapManagerTest { // force error by having no topics match when(source.getTopic()).thenReturn(""); - new DmaapManager(MY_TOPIC); + new DmaapManagerImpl(MY_TOPIC); } @Test(expected = PoolingFeatureException.class) public void testDmaapManager_IllegalArgEx() throws PoolingFeatureException { // force error - when(factory.getTopicSources()).thenThrow(new IllegalArgumentException("expected")); - - new DmaapManager(MY_TOPIC); + new DmaapManagerImpl(MY_TOPIC) { + @Override + protected List<TopicSource> getTopicSources() { + throw new IllegalArgumentException(EXPECTED); + } + }; } @Test(expected = PoolingFeatureException.class) public void testDmaapManager_CannotFilter() throws PoolingFeatureException { // force an error when setFilter() is called - doThrow(new UnsupportedOperationException("expected")).when(source).setFilter(any()); + doThrow(new UnsupportedOperationException(EXPECTED)).when(source).setFilter(any()); - new DmaapManager(MY_TOPIC); + new DmaapManagerImpl(MY_TOPIC); } @Test @@ -149,25 +128,34 @@ public class DmaapManagerTest { TopicSource source2 = mock(TopicSource.class); when(source2.getTopic()).thenReturn(MY_TOPIC); - when(factory.getTopicSources()).thenReturn(Arrays.asList(source2)); - - new DmaapManager(MY_TOPIC); + new DmaapManagerImpl(MY_TOPIC) { + @Override + protected List<TopicSource> getTopicSources() { + return Arrays.asList(source2); + } + }; } @Test(expected = PoolingFeatureException.class) public void testFindTopicSource_NotFound() throws PoolingFeatureException { // one item in list, and its topic doesn't match - when(factory.getTopicSources()).thenReturn(Arrays.asList(mock(TopicSource.class))); - - new DmaapManager(MY_TOPIC); + new DmaapManagerImpl(MY_TOPIC) { + @Override + protected List<TopicSource> getTopicSources() { + return Arrays.asList(mock(TopicSource.class)); + } + }; } @Test(expected = PoolingFeatureException.class) public void testFindTopicSource_EmptyList() throws PoolingFeatureException { // empty list - when(factory.getTopicSources()).thenReturn(new LinkedList<>()); - - new DmaapManager(MY_TOPIC); + new DmaapManagerImpl(MY_TOPIC) { + @Override + protected List<TopicSource> getTopicSources() { + return Collections.emptyList(); + } + }; } @Test @@ -178,17 +166,23 @@ public class DmaapManagerTest { @Test(expected = PoolingFeatureException.class) public void testFindTopicSink_NotFound() throws PoolingFeatureException { // one item in list, and its topic doesn't match - when(factory.getTopicSinks()).thenReturn(Arrays.asList(mock(TopicSink.class))); - - new DmaapManager(MY_TOPIC); + new DmaapManagerImpl(MY_TOPIC) { + @Override + protected List<TopicSink> getTopicSinks() { + return Arrays.asList(mock(TopicSink.class)); + } + }; } @Test(expected = PoolingFeatureException.class) public void testFindTopicSink_EmptyList() throws PoolingFeatureException { // empty list - when(factory.getTopicSinks()).thenReturn(new LinkedList<>()); - - new DmaapManager(MY_TOPIC); + new DmaapManagerImpl(MY_TOPIC) { + @Override + protected List<TopicSink> getTopicSinks() { + return Collections.emptyList(); + } + }; } @Test @@ -297,7 +291,7 @@ public class DmaapManagerTest { @Test(expected = PoolingFeatureException.class) public void testSetFilter_Exception() throws PoolingFeatureException { // force an error when setFilter() is called - doThrow(new UnsupportedOperationException("expected")).when(source).setFilter(any()); + doThrow(new UnsupportedOperationException(EXPECTED)).when(source).setFilter(any()); mgr.setFilter(FILTER); } @@ -339,7 +333,7 @@ public class DmaapManagerTest { mgr.startPublisher(); // arrange for send() to throw an exception - doThrow(new IllegalStateException("expected")).when(sink).send(MSG); + doThrow(new IllegalStateException(EXPECTED)).when(sink).send(MSG); mgr.publish(MSG); } @@ -353,6 +347,32 @@ public class DmaapManagerTest { // OK } } + + /** + * Manager with overrides. + */ + private class DmaapManagerImpl extends DmaapManager { + + public DmaapManagerImpl(String topic) throws PoolingFeatureException { + super(topic); + } + + @Override + protected List<TopicSource> getTopicSources() { + gotSources = true; + + // three sources, with the desired one in the middle + return Arrays.asList(mock(TopicSource.class), source, mock(TopicSource.class)); + } + + @Override + protected List<TopicSink> getTopicSinks() { + gotSinks = true; + + // three sinks, with the desired one in the middle + return Arrays.asList(mock(TopicSink.class), sink, mock(TopicSink.class)); + } + } @FunctionalInterface public static interface VFunction { diff --git a/feature-pooling-dmaap/src/test/java/org/onap/policy/drools/pooling/EndToEndFeatureTest.java b/feature-pooling-dmaap/src/test/java/org/onap/policy/drools/pooling/EndToEndFeatureTest.java index 616d95fe..362c3b01 100644 --- a/feature-pooling-dmaap/src/test/java/org/onap/policy/drools/pooling/EndToEndFeatureTest.java +++ b/feature-pooling-dmaap/src/test/java/org/onap/policy/drools/pooling/EndToEndFeatureTest.java @@ -7,9 +7,9 @@ * 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. @@ -30,7 +30,6 @@ import static org.onap.policy.drools.pooling.PoolingProperties.PREFIX; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; - import java.io.IOException; import java.util.Arrays; import java.util.Deque; @@ -43,7 +42,6 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; - import org.junit.After; import org.junit.AfterClass; import org.junit.Before; @@ -69,7 +67,7 @@ import org.slf4j.LoggerFactory; * feature object. Uses real feature objects, as well as real DMaaP sources and sinks. However, the * following are not: <dl> <dt>PolicyEngine, PolicyController, DroolsController</dt> <dd>mocked</dd> * </dl> - * + * * <p>The following fields must be set before executing this: <ul> <li>UEB_SERVERS</li> * <li>INTERNAL_TOPIC</li> <li>EXTERNAL_TOPIC</li> </ul> */ @@ -115,10 +113,26 @@ public class EndToEndFeatureTest { private static final long STD_OFFLINE_PUB_WAIT_MS = 2; private static final long EVENT_WAIT_SEC = 15; - // these are saved and restored on exit from this test class - private static PoolingFeature.Factory saveFeatureFactory; - private static PoolingManagerImpl.Factory saveManagerFactory; - private static DmaapManager.Factory saveDmaapFactory; + /** + * Used to decode events into a Map. + */ + private static final TypeReference<TreeMap<String, String>> typeRef = + new TypeReference<TreeMap<String, String>>() {}; + + /** + * Used to decode events from the external topic. + */ + private static final ThreadLocal<ObjectMapper> mapper = new ThreadLocal<ObjectMapper>() { + @Override + protected ObjectMapper initialValue() { + return new ObjectMapper(); + } + }; + + /** + * Used to identify the current host. + */ + private static final ThreadLocal<Host> currentHost = new ThreadLocal<Host>(); /** * Sink for external DMaaP topic. @@ -137,14 +151,10 @@ public class EndToEndFeatureTest { /** * Setup before class. - * + * */ @BeforeClass public static void setUpBeforeClass() { - saveFeatureFactory = PoolingFeature.getFactory(); - saveManagerFactory = PoolingManagerImpl.getFactory(); - saveDmaapFactory = DmaapManager.getFactory(); - externalSink = TopicEndpoint.manager.addTopicSinks(makeSinkProperties(EXTERNAL_TOPIC)).get(0); externalSink.start(); @@ -154,14 +164,10 @@ public class EndToEndFeatureTest { /** * Tear down after class. - * + * */ @AfterClass public static void tearDownAfterClass() { - PoolingFeature.setFactory(saveFeatureFactory); - PoolingManagerImpl.setFactory(saveManagerFactory); - DmaapManager.setFactory(saveDmaapFactory); - externalSink.stop(); internalSink.stop(); } @@ -268,13 +274,26 @@ public class EndToEndFeatureTest { } /** + * Decodes an event. + * + * @param event event + * @return the decoded event, or {@code null} if it cannot be decoded + */ + private static Object decodeEvent(String event) { + try { + return mapper.get().readValue(event, typeRef); + + } catch (IOException e) { + logger.warn("cannot decode external event", e); + return null; + } + } + + /** * Context used for a single test case. */ private static class Context { - private final FeatureFactory featureFactory; - private final ManagerFactory managerFactory; - /** * Hosts that have been added to this context. */ @@ -297,16 +316,11 @@ public class EndToEndFeatureTest { /** * Constructor. - * + * * @param nEvents number of events to be processed */ public Context(int events) { - featureFactory = new FeatureFactory(this); - managerFactory = new ManagerFactory(this); eventCounter = new CountDownLatch(events); - - PoolingFeature.setFactory(featureFactory); - PoolingManagerImpl.setFactory(managerFactory); } /** @@ -319,7 +333,7 @@ public class EndToEndFeatureTest { /** * Creates and adds a new host to the context. - * + * * @return the new Host */ public Host addHost() { @@ -356,7 +370,7 @@ public class EndToEndFeatureTest { /** * Offers an event to the external topic. - * + * * @param event event */ public void offerExternal(String event) { @@ -364,18 +378,8 @@ public class EndToEndFeatureTest { } /** - * Decodes an event. - * - * @param event event - * @return the decoded event, or {@code null} if it cannot be decoded - */ - public Object decodeEvent(String event) { - return managerFactory.decodeEvent(null, null, event); - } - - /** * Associates a controller with its drools controller. - * + * * @param controller controller * @param droolsController drools controller */ @@ -385,7 +389,7 @@ public class EndToEndFeatureTest { /** * Get controller. - * + * * @param droolsController drools controller * @return the controller associated with a drools controller, or {@code null} if it has no * associated controller @@ -396,7 +400,7 @@ public class EndToEndFeatureTest { /** * Get decode errors. - * + * * @return the number of decode errors so far */ public int getDecodeErrors() { @@ -412,7 +416,7 @@ public class EndToEndFeatureTest { /** * Get remaining events. - * + * * @return the number of events that haven't been processed */ public long getRemainingEvents() { @@ -428,7 +432,7 @@ public class EndToEndFeatureTest { /** * Waits, for a period of time, for all events to be processed. - * + * * @param time time * @param units units * @return {@code true} if all events have been processed, {@code false} otherwise @@ -440,7 +444,7 @@ public class EndToEndFeatureTest { /** * Waits, for a period of time, for all hosts to enter the Active state. - * + * * @param timeMs maximum time to wait, in milliseconds * @throws InterruptedException throws interrupted exception */ @@ -459,7 +463,7 @@ public class EndToEndFeatureTest { */ private static class Host { - private final PoolingFeature feature = new PoolingFeature(); + private final PoolingFeature feature; /** * {@code True} if this host has processed a message, {@code false} otherwise. @@ -476,7 +480,7 @@ public class EndToEndFeatureTest { /** * Constructor. - * + * * @param context context */ public Host(Context context) { @@ -496,11 +500,13 @@ public class EndToEndFeatureTest { doAnswer(new MyExternalTopicListener(context, this)).when(controller).onTopicEvent(any(), any(), any()); context.addController(controller, drools); + + feature = new PoolingFeatureImpl(context, this); } /** * Waits, for a period of time, for the host to enter the Active state. - * + * * @param timeMs time to wait, in milliseconds * @return {@code true} if the host entered the Active state within the given amount of * time, {@code false} otherwise @@ -515,18 +521,6 @@ public class EndToEndFeatureTest { * topic and its own internal "DMaaP" topic. */ public void start() { - DmaapManager.setFactory(new DmaapManager.Factory() { - @Override - public List<TopicSource> getTopicSources() { - return Arrays.asList(internalSource, externalSource); - } - - @Override - public List<TopicSink> getTopicSinks() { - return Arrays.asList(internalSink, externalSink); - } - }); - feature.beforeStart(engine); feature.afterCreate(controller); @@ -549,7 +543,7 @@ public class EndToEndFeatureTest { /** * Offers an event to the feature, before the policy controller handles it. - * + * * @param protocol protocol * @param topic2 topic * @param event event @@ -561,7 +555,7 @@ public class EndToEndFeatureTest { /** * Offers an event to the feature, after the policy controller handles it. - * + * * @param protocol protocol * @param topic topic * @param event event @@ -575,7 +569,7 @@ public class EndToEndFeatureTest { /** * Offers an event to the feature, before the drools controller handles it. - * + * * @param fact fact * @return {@code true} if the event was handled, {@code false} otherwise */ @@ -585,7 +579,7 @@ public class EndToEndFeatureTest { /** * Offers an event to the feature, after the drools controller handles it. - * + * * @param fact fact * @param successInsert {@code true} if it was successfully inserted by the drools * controller, {@code false} otherwise @@ -604,7 +598,7 @@ public class EndToEndFeatureTest { /** * Message seen. - * + * * @return {@code true} if a message was seen for this host, {@code false} otherwise */ public boolean messageSeen() { @@ -638,7 +632,7 @@ public class EndToEndFeatureTest { } boolean result; - Object fact = context.decodeEvent(event); + Object fact = decodeEvent(event); if (fact == null) { result = false; @@ -662,19 +656,21 @@ public class EndToEndFeatureTest { } /** - * Simulator for the feature-level factory. + * Feature with overrides. */ - private static class FeatureFactory extends PoolingFeature.Factory { + private static class PoolingFeatureImpl extends PoolingFeature { private final Context context; + private final Host host; /** * Constructor. - * + * * @param context context */ - public FeatureFactory(Context context) { + public PoolingFeatureImpl(Context context, Host host) { this.context = context; + this.host = host; /* * Note: do NOT extract anything from "context" at this point, because it hasn't been @@ -716,7 +712,7 @@ public class EndToEndFeatureTest { /** * Embeds a specializer within a property name, after the prefix. - * + * * @param propnm property name into which it should be embedded * @param spec specializer to be embedded * @return the property name, with the specializer embedded within it @@ -725,55 +721,80 @@ public class EndToEndFeatureTest { String suffix = propnm.substring(PREFIX.length()); return PREFIX + spec + "." + suffix; } + + @Override + protected PoolingManagerImpl makeManager(String hostName, PolicyController controller, PoolingProperties props, + CountDownLatch activeLatch) { + + /* + * Set this before creating the test, because the test's superclass + * constructor uses it before the test object has a chance to store it. + */ + currentHost.set(host); + + return new PoolingManagerTest(hostName, controller, props, activeLatch); + } } /** - * Simulator for the pooling manager factory. + * Pooling Manager with overrides. */ - private static class ManagerFactory extends PoolingManagerImpl.Factory { + private static class PoolingManagerTest extends PoolingManagerImpl { /** - * Used to decode events from the external topic. + * Constructor. + * + * @param hostName the host + * @param controller the controller + * @param props the properties + * @param activeLatch the latch */ - private final ThreadLocal<ObjectMapper> mapper = new ThreadLocal<ObjectMapper>() { - @Override - protected ObjectMapper initialValue() { - return new ObjectMapper(); - } - }; + public PoolingManagerTest(String hostName, PolicyController controller, + PoolingProperties props, CountDownLatch activeLatch) { - /** - * Used to decode events into a Map. - */ - private final TypeReference<TreeMap<String, String>> typeRef = new TypeReference<TreeMap<String, String>>() {}; + super(hostName, controller, props, activeLatch); + } + + @Override + protected DmaapManager makeDmaapManager(String topic) throws PoolingFeatureException { + return new DmaapManagerImpl(topic); + } + + @Override + protected boolean canDecodeEvent(DroolsController drools, String topic) { + return true; + } + + @Override + protected Object decodeEventWrapper(DroolsController drools, String topic, String event) { + return decodeEvent(event); + } + } + + /** + * DMaaP Manager with overrides. + */ + private static class DmaapManagerImpl extends DmaapManager { /** * Constructor. - * - * @param context context + * + * @param topic the topic + * @throws PoolingFeatureException if an error occurs */ - public ManagerFactory(Context context) { - - /* - * Note: do NOT extract anything from "context" at this point, because it hasn't been - * fully initialized yet - */ + public DmaapManagerImpl(String topic) throws PoolingFeatureException { + super(topic); } @Override - public boolean canDecodeEvent(DroolsController drools, String topic) { - return true; + protected List<TopicSource> getTopicSources() { + Host host = currentHost.get(); + return Arrays.asList(host.internalSource, host.externalSource); } @Override - public Object decodeEvent(DroolsController drools, String topic, String event) { - try { - return mapper.get().readValue(event, typeRef); - - } catch (IOException e) { - logger.warn("cannot decode external event", e); - return null; - } + protected List<TopicSink> getTopicSinks() { + return Arrays.asList(internalSink, externalSink); } } diff --git a/feature-pooling-dmaap/src/test/java/org/onap/policy/drools/pooling/FeatureTest.java b/feature-pooling-dmaap/src/test/java/org/onap/policy/drools/pooling/FeatureTest.java index 709f1b06..01253fbf 100644 --- a/feature-pooling-dmaap/src/test/java/org/onap/policy/drools/pooling/FeatureTest.java +++ b/feature-pooling-dmaap/src/test/java/org/onap/policy/drools/pooling/FeatureTest.java @@ -48,9 +48,7 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import org.junit.After; -import org.junit.AfterClass; import org.junit.Before; -import org.junit.BeforeClass; import org.junit.Test; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; @@ -79,6 +77,8 @@ import org.slf4j.LoggerFactory; * <dt>PolicyEngine, PolicyController, DroolsController</dt> * <dd>mocked</dd> * </dl> + * + * <p>Invoke {@link #runSlow()}, before the test, to slow things down. */ public class FeatureTest { @@ -109,38 +109,31 @@ public class FeatureTest { private static long stdInterPollMs = 2; private static long stdEventWaitSec = 10; - // these are saved and restored on exit from this test class - private static PoolingFeature.Factory saveFeatureFactory; - private static PoolingManagerImpl.Factory saveManagerFactory; - private static DmaapManager.Factory saveDmaapFactory; + /** + * Used to decode events into a Map. + */ + private static final TypeReference<TreeMap<String, String>> typeRef = + new TypeReference<TreeMap<String, String>>() {}; /** - * Context for the current test case. + * Used to decode events from the external topic. */ - private Context ctx; + private static final ThreadLocal<ObjectMapper> mapper = new ThreadLocal<ObjectMapper>() { + @Override + protected ObjectMapper initialValue() { + return new ObjectMapper(); + } + }; /** - * Setup before class. - * + * Used to identify the current context. */ - @BeforeClass - public static void setUpBeforeClass() { - saveFeatureFactory = PoolingFeature.getFactory(); - saveManagerFactory = PoolingManagerImpl.getFactory(); - saveDmaapFactory = DmaapManager.getFactory(); - - // note: invoke runSlow() to slow things down - } + private static final ThreadLocal<Context> currentContext = new ThreadLocal<Context>(); /** - * Tear down after class. + * Context for the current test case. */ - @AfterClass - public static void tearDownAfterClass() { - PoolingFeature.setFactory(saveFeatureFactory); - PoolingManagerImpl.setFactory(saveManagerFactory); - DmaapManager.setFactory(saveDmaapFactory); - } + private Context ctx; /** * Setup. @@ -215,14 +208,26 @@ public class FeatureTest { } /** + * Decodes an event. + * + * @param event event + * @return the decoded event, or {@code null} if it cannot be decoded + */ + private static Object decodeEvent(String event) { + try { + return mapper.get().readValue(event, typeRef); + + } catch (IOException e) { + logger.warn("cannot decode external event", e); + return null; + } + } + + /** * Context used for a single test case. */ private static class Context { - private final FeatureFactory featureFactory; - private final ManagerFactory managerFactory; - private final DmaapFactory dmaapFactory; - /** * Hosts that have been added to this context. */ @@ -265,14 +270,7 @@ public class FeatureTest { * @param nEvents number of events to be processed */ public Context(int events) { - featureFactory = new FeatureFactory(this); - managerFactory = new ManagerFactory(this); - dmaapFactory = new DmaapFactory(this); eventCounter = new CountDownLatch(events); - - PoolingFeature.setFactory(featureFactory); - PoolingManagerImpl.setFactory(managerFactory); - DmaapManager.setFactory(dmaapFactory); } /** @@ -375,16 +373,6 @@ public class FeatureTest { } /** - * Decodes an event. - * - * @param event event - * @return the decoded event, or {@code null} if it cannot be decoded - */ - public Object decodeEvent(String event) { - return managerFactory.decodeEvent(null, null, event); - } - - /** * Associates a controller with its drools controller. * * @param controller controller @@ -476,7 +464,7 @@ public class FeatureTest { private final Context context; - private final PoolingFeature feature = new PoolingFeature(); + private final PoolingFeature feature; /** * {@code True} if this host has processed a message, {@code false} otherwise. @@ -521,6 +509,8 @@ public class FeatureTest { // arrange to read from the external topic externalSource = new TopicSourceImpl(context, false); + + feature = new PoolingFeatureImpl(context); } /** @@ -665,7 +655,7 @@ public class FeatureTest { } boolean result; - Object fact = context.decodeEvent(event); + Object fact = decodeEvent(event); if (fact == null) { result = false; @@ -977,9 +967,9 @@ public class FeatureTest { } /** - * Simulator for the feature-level factory. + * Feature with overrides. */ - private static class FeatureFactory extends PoolingFeature.Factory { + private static class PoolingFeatureImpl extends PoolingFeature { private final Context context; @@ -988,7 +978,7 @@ public class FeatureTest { * * @param context context */ - public FeatureFactory(Context context) { + public PoolingFeatureImpl(Context context) { this.context = context; /* @@ -1037,87 +1027,76 @@ public class FeatureTest { String suffix = propnm.substring(PREFIX.length()); return PREFIX + spec + "." + suffix; } + + @Override + protected PoolingManagerImpl makeManager(String host, PolicyController controller, PoolingProperties props, + CountDownLatch activeLatch) { + + currentContext.set(context); + + return new PoolingManagerTest(host, controller, props, activeLatch); + } } /** - * Simulator for the pooling manager factory. + * Pooling Manager with overrides. */ - private static class ManagerFactory extends PoolingManagerImpl.Factory { - - /** - * Used to decode events from the external topic. - */ - private final ThreadLocal<ObjectMapper> mapper = new ThreadLocal<ObjectMapper>() { - @Override - protected ObjectMapper initialValue() { - return new ObjectMapper(); - } - }; - - /** - * Used to decode events into a Map. - */ - private final TypeReference<TreeMap<String, String>> typeRef = new TypeReference<TreeMap<String, String>>() {}; + private static class PoolingManagerTest extends PoolingManagerImpl { /** * Constructor. * - * @param context context + * @param host the host + * @param controller the controller + * @param props the properties + * @param activeLatch the latch */ - public ManagerFactory(Context context) { + public PoolingManagerTest(String host, PolicyController controller, PoolingProperties props, + CountDownLatch activeLatch) { - /* - * Note: do NOT extract anything from "context" at this point, because it - * hasn't been fully initialized yet - */ + super(host, controller, props, activeLatch); } @Override - public boolean canDecodeEvent(DroolsController drools, String topic) { - return true; + protected DmaapManager makeDmaapManager(String topic) throws PoolingFeatureException { + return new DmaapManagerImpl(topic); } @Override - public Object decodeEvent(DroolsController drools, String topic, String event) { - try { - return mapper.get().readValue(event, typeRef); + protected boolean canDecodeEvent(DroolsController drools, String topic) { + return true; + } - } catch (IOException e) { - logger.warn("cannot decode external event", e); - return null; - } + @Override + protected Object decodeEventWrapper(DroolsController drools, String topic, String event) { + return decodeEvent(event); } } /** - * Simulator for the dmaap manager factory. + * DMaaP Manager with overrides. */ - private static class DmaapFactory extends DmaapManager.Factory { - - private final Context context; + private static class DmaapManagerImpl extends DmaapManager { /** * Constructor. * - * @param context context + * @param context this manager's context + * @param topic the topic + * @throws PoolingFeatureException if an error occurs */ - public DmaapFactory(Context context) { - this.context = context; - - /* - * Note: do NOT extract anything from "context" at this point, because it - * hasn't been fully initialized yet - */ + public DmaapManagerImpl(String topic) throws PoolingFeatureException { + super(topic); } @Override - public List<TopicSource> getTopicSources() { - return Arrays.asList(new TopicSourceImpl(context, true)); + protected List<TopicSource> getTopicSources() { + return Arrays.asList(new TopicSourceImpl(currentContext.get(), true)); } @Override - public List<TopicSink> getTopicSinks() { - return Arrays.asList(new TopicSinkImpl(context)); + protected List<TopicSink> getTopicSinks() { + return Arrays.asList(new TopicSinkImpl(currentContext.get())); } } diff --git a/feature-pooling-dmaap/src/test/java/org/onap/policy/drools/pooling/PoolingFeatureTest.java b/feature-pooling-dmaap/src/test/java/org/onap/policy/drools/pooling/PoolingFeatureTest.java index a943575c..ed9d1c9a 100644 --- a/feature-pooling-dmaap/src/test/java/org/onap/policy/drools/pooling/PoolingFeatureTest.java +++ b/feature-pooling-dmaap/src/test/java/org/onap/policy/drools/pooling/PoolingFeatureTest.java @@ -32,16 +32,17 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Properties; -import org.junit.AfterClass; +import java.util.concurrent.CountDownLatch; import org.junit.Before; -import org.junit.BeforeClass; import org.junit.Test; import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; +import org.onap.policy.common.endpoints.event.comm.TopicSink; +import org.onap.policy.common.endpoints.event.comm.TopicSource; import org.onap.policy.drools.controller.DroolsController; -import org.onap.policy.drools.pooling.PoolingFeature.Factory; import org.onap.policy.drools.system.PolicyController; import org.onap.policy.drools.system.PolicyEngine; import org.onap.policy.drools.utils.Pair; @@ -63,11 +64,6 @@ public class PoolingFeatureTest { private static final Object OBJECT1 = new Object(); private static final Object OBJECT2 = new Object(); - /** - * Saved from PoolingFeature and restored on exit from this test class. - */ - private static Factory saveFactory; - private Properties props; private PolicyEngine engine; private PolicyController controller1; @@ -81,21 +77,9 @@ public class PoolingFeatureTest { private List<Pair<PoolingManagerImpl, PoolingProperties>> managers; private PoolingManagerImpl mgr1; private PoolingManagerImpl mgr2; - private Factory factory; private PoolingFeature pool; - - @BeforeClass - public static void setUpBeforeClass() { - saveFactory = PoolingFeature.getFactory(); - } - - @AfterClass - public static void tearDownAfterClass() { - PoolingFeature.setFactory(saveFactory); - } - /** * Setup. * @@ -105,7 +89,6 @@ public class PoolingFeatureTest { public void setUp() throws Exception { props = initProperties(); engine = mock(PolicyEngine.class); - factory = mock(Factory.class); controller1 = mock(PolicyController.class); controller2 = mock(PolicyController.class); controllerDisabled = mock(PolicyController.class); @@ -116,30 +99,13 @@ public class PoolingFeatureTest { droolsDisabled = mock(DroolsController.class); managers = new LinkedList<>(); - PoolingFeature.setFactory(factory); - when(controller1.getName()).thenReturn(CONTROLLER1); when(controller2.getName()).thenReturn(CONTROLLER2); when(controllerDisabled.getName()).thenReturn(CONTROLLER_DISABLED); when(controllerException.getName()).thenReturn(CONTROLLER_EX); when(controllerUnknown.getName()).thenReturn(CONTROLLER_UNKNOWN); - when(factory.getProperties(PoolingProperties.FEATURE_NAME)).thenReturn(props); - when(factory.getController(drools1)).thenReturn(controller1); - when(factory.getController(drools2)).thenReturn(controller2); - when(factory.getController(droolsDisabled)).thenReturn(controllerDisabled); - - when(factory.makeManager(any(), any(), any(), any())).thenAnswer(args -> { - PoolingProperties props = args.getArgument(2); - - PoolingManagerImpl mgr = mock(PoolingManagerImpl.class); - - managers.add(new Pair<>(mgr, props)); - - return mgr; - }); - - pool = new PoolingFeature(); + pool = new PoolingFeatureImpl(); pool.beforeStart(engine); @@ -161,7 +127,7 @@ public class PoolingFeatureTest { assertNotNull(host); // create another and ensure it generates another host name - pool = new PoolingFeature(); + pool = new PoolingFeatureImpl(); String host2 = pool.getHost(); assertNotNull(host2); @@ -175,7 +141,7 @@ public class PoolingFeatureTest { @Test public void testBeforeStartEngine() { - pool = new PoolingFeature(); + pool = new PoolingFeatureImpl(); assertFalse(pool.beforeStart(engine)); } @@ -183,7 +149,7 @@ public class PoolingFeatureTest { @Test public void testAfterCreate() { managers.clear(); - pool = new PoolingFeature(); + pool = new PoolingFeatureImpl(); pool.beforeStart(engine); assertFalse(pool.afterCreate(controller1)); @@ -201,7 +167,7 @@ public class PoolingFeatureTest { @Test public void testAfterCreate_NotEnabled() { managers.clear(); - pool = new PoolingFeature(); + pool = new PoolingFeatureImpl(); pool.beforeStart(engine); assertFalse(pool.afterCreate(controllerDisabled)); @@ -211,7 +177,7 @@ public class PoolingFeatureTest { @Test(expected = PoolingFeatureRtException.class) public void testAfterCreate_PropertyEx() { managers.clear(); - pool = new PoolingFeature(); + pool = new PoolingFeatureImpl(); pool.beforeStart(engine); pool.afterCreate(controllerException); @@ -219,7 +185,7 @@ public class PoolingFeatureTest { @Test(expected = PoolingFeatureRtException.class) public void testAfterCreate_NoProps() { - pool = new PoolingFeature(); + pool = new PoolingFeatureImpl(); // did not perform globalInit, which is an error @@ -229,7 +195,7 @@ public class PoolingFeatureTest { @Test public void testAfterCreate_NoFeatProps() { managers.clear(); - pool = new PoolingFeature(); + pool = new PoolingFeatureImpl(); pool.beforeStart(engine); assertFalse(pool.afterCreate(controllerUnknown)); @@ -398,9 +364,13 @@ public class PoolingFeatureTest { @Test public void testBeforeInsert_ArgEx() { - // generate exception - doThrow(new IllegalArgumentException()).when(factory).getController(any()); + pool = new PoolingFeatureImpl() { + @Override + protected PolicyController getController(DroolsController droolsController) { + throw new IllegalArgumentException(); + } + }; pool.beforeOffer(controller1, CommInfrastructure.UEB, TOPIC1, EVENT1); assertFalse(pool.beforeInsert(drools1, OBJECT1)); @@ -409,9 +379,13 @@ public class PoolingFeatureTest { @Test public void testBeforeInsert_StateEx() { - // generate exception - doThrow(new IllegalStateException()).when(factory).getController(any()); + pool = new PoolingFeatureImpl() { + @Override + protected PolicyController getController(DroolsController droolsController) { + throw new IllegalStateException(); + } + }; pool.beforeOffer(controller1, CommInfrastructure.UEB, TOPIC1, EVENT1); assertFalse(pool.beforeInsert(drools1, OBJECT1)); @@ -422,7 +396,12 @@ public class PoolingFeatureTest { public void testBeforeInsert_NullController() { // return null controller - when(factory.getController(any())).thenReturn(null); + pool = new PoolingFeatureImpl() { + @Override + protected PolicyController getController(DroolsController droolsController) { + return null; + } + }; pool.beforeOffer(controller1, CommInfrastructure.UEB, TOPIC1, EVENT1); assertFalse(pool.beforeInsert(drools1, OBJECT1)); @@ -514,4 +493,53 @@ public class PoolingFeatureTest { String.valueOf(40 + offset)); props.setProperty("pooling.controller" + suffix + ".inter.heartbeat.milliseconds", String.valueOf(50 + offset)); } + + /** + * Feature with overrides. + */ + private class PoolingFeatureImpl extends PoolingFeature { + + @Override + protected Properties getProperties(String featName) { + if (PoolingProperties.FEATURE_NAME.equals(featName)) { + return props; + } else { + throw new IllegalArgumentException("unknown feature name"); + } + } + + @Override + protected PoolingManagerImpl makeManager(String host, PolicyController controller, PoolingProperties props, + CountDownLatch activeLatch) { + + PoolingManagerImpl mgr = mock(PoolingManagerImpl.class); + + managers.add(new Pair<>(mgr, props)); + + return mgr; + } + + @Override + protected PolicyController getController(DroolsController droolsController) { + if (droolsController == drools1) { + return controller1; + } else if (droolsController == drools2) { + return controller2; + } else if (droolsController == droolsDisabled) { + return controllerDisabled; + } else { + throw new IllegalArgumentException("unknown drools controller"); + } + } + + @Override + protected List<TopicSource> initTopicSources(Properties props) { + return Collections.emptyList(); + } + + @Override + protected List<TopicSink> initTopicSinks(Properties props) { + return Collections.emptyList(); + } + } } diff --git a/feature-pooling-dmaap/src/test/java/org/onap/policy/drools/pooling/PoolingManagerImplTest.java b/feature-pooling-dmaap/src/test/java/org/onap/policy/drools/pooling/PoolingManagerImplTest.java index e6b6e4cd..7fce99d1 100644 --- a/feature-pooling-dmaap/src/test/java/org/onap/policy/drools/pooling/PoolingManagerImplTest.java +++ b/feature-pooling-dmaap/src/test/java/org/onap/policy/drools/pooling/PoolingManagerImplTest.java @@ -42,15 +42,12 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; -import org.junit.AfterClass; import org.junit.Before; -import org.junit.BeforeClass; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; import org.onap.policy.common.endpoints.event.comm.TopicListener; import org.onap.policy.drools.controller.DroolsController; -import org.onap.policy.drools.pooling.PoolingManagerImpl.Factory; import org.onap.policy.drools.pooling.extractor.ClassExtractors; import org.onap.policy.drools.pooling.message.BucketAssignments; import org.onap.policy.drools.pooling.message.Forward; @@ -94,11 +91,6 @@ public class PoolingManagerImplTest { private static final int START_PUB = 1; /** - * Saved from PoolingManagerImpl and restored on exit from this test class. - */ - private static Factory saveFactory; - - /** * Futures that have been allocated due to calls to scheduleXxx(). */ private Queue<ScheduledFuture<?>> futures; @@ -108,24 +100,15 @@ public class PoolingManagerImplTest { private ListeningController controller; private ClassExtractors extractors; private DmaapManager dmaap; + private boolean gotDmaap; private ScheduledThreadPoolExecutor sched; + private int schedCount; private DroolsController drools; private Serializer ser; - private Factory factory; private CountDownLatch active; private PoolingManagerImpl mgr; - @BeforeClass - public static void setUpBeforeClass() { - saveFactory = PoolingManagerImpl.getFactory(); - } - - @AfterClass - public static void tearDownAfterClass() { - PoolingManagerImpl.setFactory(saveFactory); - } - /** * Setup. * @@ -149,19 +132,14 @@ public class PoolingManagerImplTest { ser = new Serializer(); active = new CountDownLatch(1); - factory = mock(Factory.class); extractors = mock(ClassExtractors.class); dmaap = mock(DmaapManager.class); + gotDmaap = false; controller = mock(ListeningController.class); sched = mock(ScheduledThreadPoolExecutor.class); + schedCount = 0; drools = mock(DroolsController.class); - when(factory.makeClassExtractors(any())).thenReturn(extractors); - when(factory.makeDmaapManager(any())).thenReturn(dmaap); - when(factory.makeScheduler()).thenReturn(sched); - when(factory.canDecodeEvent(drools, TOPIC2)).thenReturn(true); - when(factory.decodeEvent(drools, TOPIC2, THE_EVENT)).thenReturn(DECODED_EVENT); - when(extractors.extract(DECODED_EVENT)).thenReturn(REQUEST_ID); when(controller.getName()).thenReturn(MY_CONTROLLER); @@ -183,14 +161,12 @@ public class PoolingManagerImplTest { return fut; }); - PoolingManagerImpl.setFactory(factory); - - mgr = new PoolingManagerImpl(MY_HOST, controller, poolProps, active); + mgr = new PoolingManagerTest(MY_HOST, controller, poolProps, active); } @Test public void testPoolingManagerImpl() throws Exception { - verify(factory).makeDmaapManager(any()); + assertTrue(gotDmaap); State st = mgr.getCurrent(); assertTrue(st instanceof IdleState); @@ -208,7 +184,7 @@ public class PoolingManagerImplTest { PolicyController ctlr = mock(PolicyController.class); PoolingFeatureRtException ex = expectException(PoolingFeatureRtException.class, - () -> new PoolingManagerImpl(MY_HOST, ctlr, poolProps, active)); + () -> new PoolingManagerTest(MY_HOST, ctlr, poolProps, active)); assertNotNull(ex.getCause()); assertTrue(ex.getCause() instanceof ClassCastException); } @@ -217,10 +193,15 @@ public class PoolingManagerImplTest { public void testPoolingManagerImpl_PoolEx() throws PoolingFeatureException { // throw an exception when we try to create the dmaap manager PoolingFeatureException ex = new PoolingFeatureException(); - when(factory.makeDmaapManager(any())).thenThrow(ex); - + PoolingFeatureRtException ex2 = expectException(PoolingFeatureRtException.class, - () -> new PoolingManagerImpl(MY_HOST, controller, poolProps, active)); + () -> new PoolingManagerTest(MY_HOST, controller, poolProps, active) { + @Override + protected DmaapManager makeDmaapManager(String topic) throws PoolingFeatureException { + throw ex; + } + }); + assertEquals(ex, ex2.getCause()); } @@ -237,7 +218,7 @@ public class PoolingManagerImplTest { public void testGetHost() { assertEquals(MY_HOST, mgr.getHost()); - mgr = new PoolingManagerImpl(HOST2, controller, poolProps, active); + mgr = new PoolingManagerTest(HOST2, controller, poolProps, active); assertEquals(HOST2, mgr.getHost()); } @@ -258,7 +239,7 @@ public class PoolingManagerImplTest { verify(dmaap).startPublisher(); - verify(factory).makeScheduler(); + assertEquals(1, schedCount); verify(sched).setMaximumPoolSize(1); verify(sched).setContinueExistingPeriodicTasksAfterShutdownPolicy(false); @@ -268,7 +249,7 @@ public class PoolingManagerImplTest { verify(dmaap).startPublisher(); - verify(factory).makeScheduler(); + assertEquals(1, schedCount); verify(sched).setMaximumPoolSize(1); verify(sched).setContinueExistingPeriodicTasksAfterShutdownPolicy(false); } @@ -798,6 +779,14 @@ public class PoolingManagerImplTest { @Test public void testDecodeEvent_CannotDecode() throws Exception { + + mgr = new PoolingManagerTest(MY_HOST, controller, poolProps, active) { + @Override + protected boolean canDecodeEvent(DroolsController drools2, String topic2) { + return false; + } + }; + startMgr(); when(controller.isLocked()).thenReturn(true); @@ -805,13 +794,20 @@ public class PoolingManagerImplTest { // create assignments, though they are irrelevant mgr.startDistributing(makeAssignments(false)); - when(factory.canDecodeEvent(drools, TOPIC2)).thenReturn(false); - assertFalse(mgr.beforeOffer(CommInfrastructure.UEB, TOPIC2, THE_EVENT)); } @Test public void testDecodeEvent_UnsuppEx() throws Exception { + + // generate exception + mgr = new PoolingManagerTest(MY_HOST, controller, poolProps, active) { + @Override + protected Object decodeEventWrapper(DroolsController drools2, String topic2, String event) { + throw new UnsupportedOperationException(); + } + }; + startMgr(); when(controller.isLocked()).thenReturn(true); @@ -819,14 +815,19 @@ public class PoolingManagerImplTest { // create assignments, though they are irrelevant mgr.startDistributing(makeAssignments(false)); - // generate exception - doThrow(new UnsupportedOperationException()).when(factory).decodeEvent(drools, TOPIC2, THE_EVENT); - assertFalse(mgr.beforeOffer(CommInfrastructure.UEB, TOPIC2, THE_EVENT)); } @Test public void testDecodeEvent_ArgEx() throws Exception { + // generate exception + mgr = new PoolingManagerTest(MY_HOST, controller, poolProps, active) { + @Override + protected Object decodeEventWrapper(DroolsController drools2, String topic2, String event) { + throw new IllegalArgumentException(); + } + }; + startMgr(); when(controller.isLocked()).thenReturn(true); @@ -834,14 +835,19 @@ public class PoolingManagerImplTest { // create assignments, though they are irrelevant mgr.startDistributing(makeAssignments(false)); - // generate exception - doThrow(new IllegalArgumentException()).when(factory).decodeEvent(drools, TOPIC2, THE_EVENT); - assertFalse(mgr.beforeOffer(CommInfrastructure.UEB, TOPIC2, THE_EVENT)); } @Test public void testDecodeEvent_StateEx() throws Exception { + // generate exception + mgr = new PoolingManagerTest(MY_HOST, controller, poolProps, active) { + @Override + protected Object decodeEventWrapper(DroolsController drools2, String topic2, String event) { + throw new IllegalStateException(); + } + }; + startMgr(); when(controller.isLocked()).thenReturn(true); @@ -849,9 +855,6 @@ public class PoolingManagerImplTest { // create assignments, though they are irrelevant mgr.startDistributing(makeAssignments(false)); - // generate exception - doThrow(new IllegalStateException()).when(factory).decodeEvent(drools, TOPIC2, THE_EVENT); - assertFalse(mgr.beforeOffer(CommInfrastructure.UEB, TOPIC2, THE_EVENT)); } @@ -1264,4 +1267,47 @@ public class PoolingManagerImplTest { public void apply() throws T; } + + /** + * Manager with overrides. + */ + private class PoolingManagerTest extends PoolingManagerImpl { + + public PoolingManagerTest(String host, PolicyController controller, PoolingProperties props, + CountDownLatch activeLatch) { + + super(host, controller, props, activeLatch); + } + + @Override + protected ClassExtractors makeClassExtractors(Properties props) { + return extractors; + } + + @Override + protected DmaapManager makeDmaapManager(String topic) throws PoolingFeatureException { + gotDmaap = true; + return dmaap; + } + + @Override + protected ScheduledThreadPoolExecutor makeScheduler() { + ++schedCount; + return sched; + } + + @Override + protected boolean canDecodeEvent(DroolsController drools2, String topic2) { + return (drools2 == drools && TOPIC2.equals(topic2)); + } + + @Override + protected Object decodeEventWrapper(DroolsController drools2, String topic2, String event) { + if (drools2 == drools && TOPIC2.equals(topic2) && event == THE_EVENT) { + return DECODED_EVENT; + } else { + return null; + } + } + } } |