diff options
author | Jim Hahn <jrh3@att.com> | 2020-02-17 13:57:56 -0500 |
---|---|---|
committer | Jim Hahn <jrh3@att.com> | 2020-02-17 20:41:09 -0500 |
commit | e44f1a1c58efed9fbe2efce78864aaee3b577003 (patch) | |
tree | e0a1903c107162dc2d9a3bcae2257862a99c6b48 /models-interactions/model-actors/actor.test/src | |
parent | 85a2fee4074903012e77f78e26328b9a03a8bdfc (diff) |
More changes to actor code
Use Coder.convert() from policy-common.
Passed response to setOutcome().
Changed class names from XxxOperator to XxxOperation.
Modified SDNC junits to invoke start() instead of startOperationAsync().
Changed context obtain() to re-run if the future was canceled.
Added junit support class, BasicBidirectionalTopicOperation.
Modified HttpOperation to allow subsequent requests to be issued.
Some actors, like SO, send an initial HTTP request and then follow
it with HTTP "are you done?" requests.
Issue-ID: POLICY-2363-prop
Change-Id: I12b5c2d4f07254e0cb79fabfe1ccf844b70a0654
Signed-off-by: Jim Hahn <jrh3@att.com>
Diffstat (limited to 'models-interactions/model-actors/actor.test/src')
3 files changed, 322 insertions, 1 deletions
diff --git a/models-interactions/model-actors/actor.test/src/main/java/org/onap/policy/controlloop/actor/test/BasicBidirectionalTopicOperation.java b/models-interactions/model-actors/actor.test/src/main/java/org/onap/policy/controlloop/actor/test/BasicBidirectionalTopicOperation.java new file mode 100644 index 000000000..14c7ef576 --- /dev/null +++ b/models-interactions/model-actors/actor.test/src/main/java/org/onap/policy/controlloop/actor/test/BasicBidirectionalTopicOperation.java @@ -0,0 +1,181 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.controlloop.actor.test; + +import static org.mockito.Mockito.when; + +import java.util.Map; +import java.util.TreeMap; +import java.util.UUID; +import java.util.function.BiConsumer; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.common.utils.coder.StandardCoderObject; +import org.onap.policy.common.utils.time.PseudoExecutor; +import org.onap.policy.controlloop.VirtualControlLoopEvent; +import org.onap.policy.controlloop.actorserviceprovider.ActorService; +import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome; +import org.onap.policy.controlloop.actorserviceprovider.controlloop.ControlLoopEventContext; +import org.onap.policy.controlloop.actorserviceprovider.impl.BidirectionalTopicOperator; +import org.onap.policy.controlloop.actorserviceprovider.parameters.BidirectionalTopicParams; +import org.onap.policy.controlloop.actorserviceprovider.parameters.ControlLoopOperationParams; +import org.onap.policy.controlloop.actorserviceprovider.topic.BidirectionalTopicHandler; +import org.onap.policy.controlloop.actorserviceprovider.topic.Forwarder; + +/** + * Superclass for various BidirectionalTopicOperation tests. + */ +public class BasicBidirectionalTopicOperation { + protected static final UUID REQ_ID = UUID.randomUUID(); + protected static final String DEFAULT_ACTOR = "default-actor"; + protected static final String DEFAULT_OPERATION = "default-operation"; + protected static final String MY_SINK = "my-sink"; + protected static final String MY_SOURCE = "my-source"; + protected static final String TARGET_ENTITY = "my-target"; + protected static final Coder coder = new StandardCoder(); + protected static final int TIMEOUT = 10; + + protected final String actorName; + protected final String operationName; + + @Captor + protected ArgumentCaptor<BiConsumer<String, StandardCoderObject>> listenerCaptor; + + @Mock + protected ActorService service; + @Mock + protected BidirectionalTopicHandler topicHandler; + @Mock + protected Forwarder forwarder; + @Mock + protected BidirectionalTopicOperator operator; + + protected BidirectionalTopicParams topicParams; + protected ControlLoopOperationParams params; + protected Map<String, String> enrichment; + protected VirtualControlLoopEvent event; + protected ControlLoopEventContext context; + protected OperationOutcome outcome; + protected PseudoExecutor executor; + + /** + * Constructs the object using a default actor and operation name. + */ + public BasicBidirectionalTopicOperation() { + this.actorName = DEFAULT_ACTOR; + this.operationName = DEFAULT_OPERATION; + } + + /** + * Constructs the object. + * + * @param actor actor name + * @param operation operation name + */ + public BasicBidirectionalTopicOperation(String actor, String operation) { + this.actorName = actor; + this.operationName = operation; + } + + /** + * Initializes mocks and sets up. + */ + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + + executor = new PseudoExecutor(); + + makeContext(); + + outcome = params.makeOutcome(); + topicParams = BidirectionalTopicParams.builder().sinkTopic(MY_SINK).sourceTopic(MY_SOURCE).timeoutSec(TIMEOUT) + .build(); + + initOperator(); + } + + /** + * Reinitializes {@link #enrichment}, {@link #event}, {@link #context}, and + * {@link #params}. + * <p/> + * Note: {@link #params} is configured to use {@link #executor}. + */ + protected void makeContext() { + enrichment = new TreeMap<>(makeEnrichment()); + + event = new VirtualControlLoopEvent(); + event.setRequestId(REQ_ID); + event.setAai(enrichment); + + context = new ControlLoopEventContext(event); + + params = ControlLoopOperationParams.builder().executor(executor).context(context).actorService(service) + .actor(actorName).operation(operationName).targetEntity(TARGET_ENTITY).payload(makePayload()) + .build(); + } + + protected Map<String, String> makePayload() { + return null; + } + + /** + * Initializes an operator so that it is "alive" and has the given names. + */ + protected void initOperator() { + when(operator.isAlive()).thenReturn(true); + when(operator.getFullName()).thenReturn(actorName + "." + operationName); + when(operator.getActorName()).thenReturn(actorName); + when(operator.getName()).thenReturn(operationName); + when(operator.getTopicHandler()).thenReturn(topicHandler); + when(operator.getForwarder()).thenReturn(forwarder); + when(operator.getParams()).thenReturn(topicParams); + } + + /** + * Makes enrichment data. + * + * @return enrichment data + */ + protected Map<String, String> makeEnrichment() { + return new TreeMap<>(); + } + + /** + * Provides a response to the topic {@link #listenerCaptor}. + * + * @param listener listener to which to provide the response + * @param response response to be provided + */ + protected void provideResponse(BiConsumer<String, StandardCoderObject> listener, String response) { + try { + StandardCoderObject sco = coder.decode(response, StandardCoderObject.class); + listener.accept(response, sco); + + } catch (CoderException e) { + throw new IllegalArgumentException("response is not a Map", e); + } + } +} diff --git a/models-interactions/model-actors/actor.test/src/main/java/org/onap/policy/controlloop/actor/test/BasicHttpOperation.java b/models-interactions/model-actors/actor.test/src/main/java/org/onap/policy/controlloop/actor/test/BasicHttpOperation.java index e160479b3..492929296 100644 --- a/models-interactions/model-actors/actor.test/src/main/java/org/onap/policy/controlloop/actor/test/BasicHttpOperation.java +++ b/models-interactions/model-actors/actor.test/src/main/java/org/onap/policy/controlloop/actor/test/BasicHttpOperation.java @@ -45,7 +45,7 @@ import org.onap.policy.controlloop.actorserviceprovider.impl.HttpOperator; import org.onap.policy.controlloop.actorserviceprovider.parameters.ControlLoopOperationParams; /** - * Superclass for various operator tests. + * Superclass for various HttpOperation tests. * * @param <Q> request type */ diff --git a/models-interactions/model-actors/actor.test/src/test/java/org/onap/policy/controlloop/actor/test/BasicBidirectionalTopicOperationTest.java b/models-interactions/model-actors/actor.test/src/test/java/org/onap/policy/controlloop/actor/test/BasicBidirectionalTopicOperationTest.java new file mode 100644 index 000000000..4fd559101 --- /dev/null +++ b/models-interactions/model-actors/actor.test/src/test/java/org/onap/policy/controlloop/actor/test/BasicBidirectionalTopicOperationTest.java @@ -0,0 +1,140 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.controlloop.actor.test; + +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.verify; + +import java.util.function.BiConsumer; +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.onap.policy.common.utils.coder.StandardCoderObject; + +public class BasicBidirectionalTopicOperationTest { + private static final String ACTOR = "my-actor"; + private static final String OPERATION = "my-operation"; + + @Mock + private BiConsumer<String, StandardCoderObject> listener; + + private BasicBidirectionalTopicOperation oper; + + + /** + * Sets up. + */ + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + + oper = new BasicBidirectionalTopicOperation(ACTOR, OPERATION); + oper.setUp(); + } + + @Test + public void testBasicBidirectionalTopicOperation() { + oper = new BasicBidirectionalTopicOperation(); + assertEquals(BasicHttpOperation.DEFAULT_ACTOR, oper.actorName); + assertEquals(BasicHttpOperation.DEFAULT_OPERATION, oper.operationName); + } + + @Test + public void testBasicBidirectionalTopicOperationStringString() { + assertEquals(ACTOR, oper.actorName); + assertEquals(OPERATION, oper.operationName); + } + + @Test + public void testSetUp() { + assertNotNull(oper.topicParams); + assertNotNull(oper.context); + assertNotNull(oper.outcome); + assertNotNull(oper.executor); + assertTrue(oper.operator.isAlive()); + } + + @Test + public void testMakeContext() { + oper.makeContext(); + + assertTrue(oper.enrichment.isEmpty()); + + assertSame(BasicBidirectionalTopicOperation.REQ_ID, oper.event.getRequestId()); + assertSame(oper.enrichment, oper.event.getAai()); + + assertSame(oper.event, oper.context.getEvent()); + + assertSame(oper.context, oper.params.getContext()); + assertSame(oper.service, oper.params.getActorService()); + assertSame(oper.executor, oper.params.getExecutor()); + assertEquals(ACTOR, oper.params.getActor()); + assertEquals(OPERATION, oper.params.getOperation()); + assertEquals(BasicBidirectionalTopicOperation.TARGET_ENTITY, oper.params.getTargetEntity()); + } + + @Test + public void testMakePayload() { + assertNull(oper.makePayload()); + } + + @Test + public void testInitOperator() { + oper.initOperator(); + + assertTrue(oper.operator.isAlive()); + assertEquals(ACTOR + "." + OPERATION, oper.operator.getFullName()); + assertEquals(ACTOR, oper.operator.getActorName()); + assertEquals(OPERATION, oper.operator.getName()); + assertSame(oper.topicHandler, oper.operator.getTopicHandler()); + assertSame(oper.forwarder, oper.operator.getForwarder()); + assertSame(oper.topicParams, oper.operator.getParams()); + } + + @Test + public void testMakeEnrichment() { + assertTrue(oper.makeEnrichment().isEmpty()); + } + + @Test + public void testProvideResponse() { + String response = "{\"input\": 10}"; + + oper.provideResponse(listener, response); + + ArgumentCaptor<StandardCoderObject> scoCaptor = ArgumentCaptor.forClass(StandardCoderObject.class); + verify(listener).accept(eq(response), scoCaptor.capture()); + + assertEquals("10", scoCaptor.getValue().getString("input")); + + // try with an invalid response + assertThatIllegalArgumentException().isThrownBy(() -> oper.provideResponse(listener, "{invalid json")) + .withMessage("response is not a Map"); + } +} |