Validate request content of various actors 31/101931/3
authorJim Hahn <jrh3@att.com>
Tue, 18 Feb 2020 20:28:39 +0000 (15:28 -0500)
committerJim Hahn <jrh3@att.com>
Tue, 18 Feb 2020 21:39:14 +0000 (16:39 -0500)
Created common junit superclass, BasicOperation, containing
verifyRequest() method, among others.

Issue-ID: POLICY-2363
Signed-off-by: Jim Hahn <jrh3@att.com>
Change-Id: I7ff4428e94bfd301ff4194e1766ef61906714dcf

17 files changed:
models-interactions/model-actors/actor.aai/src/test/java/org/onap/policy/controlloop/actor/aai/AaiCustomQueryOperationTest.java
models-interactions/model-actors/actor.aai/src/test/resources/cq.json [new file with mode: 0644]
models-interactions/model-actors/actor.appc/src/test/java/org/onap/policy/controlloop/actor/appc/BasicAppcOperation.java
models-interactions/model-actors/actor.appc/src/test/java/org/onap/policy/controlloop/actor/appc/ModifyConfigOperationTest.java
models-interactions/model-actors/actor.appc/src/test/resources/modifyConfig.json [new file with mode: 0644]
models-interactions/model-actors/actor.sdnc/src/test/java/org/onap/policy/controlloop/actor/sdnc/BandwidthOnDemandOperationTest.java
models-interactions/model-actors/actor.sdnc/src/test/java/org/onap/policy/controlloop/actor/sdnc/BasicSdncOperation.java
models-interactions/model-actors/actor.sdnc/src/test/java/org/onap/policy/controlloop/actor/sdnc/RerouteOperationTest.java
models-interactions/model-actors/actor.test/pom.xml
models-interactions/model-actors/actor.test/src/main/java/org/onap/policy/controlloop/actor/test/BasicBidirectionalTopicOperation.java
models-interactions/model-actors/actor.test/src/main/java/org/onap/policy/controlloop/actor/test/BasicHttpOperation.java
models-interactions/model-actors/actor.test/src/main/java/org/onap/policy/controlloop/actor/test/BasicOperation.java [new file with mode: 0644]
models-interactions/model-actors/actor.test/src/test/java/org/onap/policy/controlloop/actor/test/BasicBidirectionalTopicOperationTest.java
models-interactions/model-actors/actor.test/src/test/java/org/onap/policy/controlloop/actor/test/BasicHttpOperationTest.java
models-interactions/model-actors/actor.test/src/test/java/org/onap/policy/controlloop/actor/test/BasicOperationTest.java [new file with mode: 0644]
models-interactions/model-actors/actor.test/src/test/resources/actual.json [new file with mode: 0644]
models-interactions/model-actors/actor.test/src/test/resources/expected.json [new file with mode: 0644]

index a935087..05b07fb 100644 (file)
@@ -25,16 +25,21 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
+import java.util.TreeMap;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeoutException;
+import javax.ws.rs.client.Entity;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
 import org.mockito.Mock;
 import org.onap.policy.aai.AaiConstants;
 import org.onap.policy.aai.AaiCqResponse;
@@ -55,6 +60,9 @@ public class AaiCustomQueryOperationTest extends BasicAaiOperation<Map<String, S
 
     private static final String MY_LINK = "my-link";
 
+    @Captor
+    private ArgumentCaptor<Entity<Map<String, String>>> entityCaptor;
+
     @Mock
     private Actor tenantActor;
 
@@ -133,6 +141,25 @@ public class AaiCustomQueryOperationTest extends BasicAaiOperation<Map<String, S
         verifyHeaders(oper.makeHeaders());
     }
 
+    @Test
+    public void testMakeRequest() throws Exception {
+        // preload
+        preloadTenantData();
+
+        when(rawResponse.readEntity(String.class)).thenReturn(makeCqReply());
+        when(client.put(any(), any(), any(), any())).thenAnswer(provideResponse(rawResponse));
+
+        oper.start();
+        executor.runAll(100);
+
+        verify(client).put(any(), any(), entityCaptor.capture(), any());
+
+        // sort the request fields so they match the order in cq.json
+        Map<String, String> request = new TreeMap<>(entityCaptor.getValue().getEntity());
+
+        verifyRequest("cq.json", request);
+    }
+
     @Test
     public void testMakeRequestNoResourceLink() throws Exception {
         // pre-load EMPTY tenant data
diff --git a/models-interactions/model-actors/actor.aai/src/test/resources/cq.json b/models-interactions/model-actors/actor.aai/src/test/resources/cq.json
new file mode 100644 (file)
index 0000000..0b8fcb9
--- /dev/null
@@ -0,0 +1,4 @@
+{
+  "query": "query/closed-loop",
+  "start": "my-link"
+}
index cbdcad6..3d4a046 100644 (file)
@@ -36,10 +36,7 @@ import java.util.function.BiFunction;
 import org.onap.policy.appc.Response;
 import org.onap.policy.appc.ResponseCode;
 import org.onap.policy.appc.ResponseStatus;
-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.resources.ResourceUtils;
 import org.onap.policy.controlloop.actor.test.BasicBidirectionalTopicOperation;
 import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome;
 import org.onap.policy.controlloop.actorserviceprovider.Util;
@@ -53,6 +50,7 @@ import org.powermock.reflect.Whitebox;
  * Superclass for various operator tests.
  */
 public abstract class BasicAppcOperation extends BasicBidirectionalTopicOperation {
+    protected static final String[] IGNORE_FIELDS = {"RequestID", "subRequestID", "seconds", "nanos"};
     protected static final String MY_DESCRIPTION = "my-description";
     protected static final String MY_VNF = "my-vnf";
     protected static final String KEY1 = "my-key-A";
@@ -117,26 +115,6 @@ public abstract class BasicAppcOperation extends BasicBidirectionalTopicOperatio
         assertEquals(MY_DESCRIPTION, outcome.getMessage());
     }
 
-    /**
-     * Pretty-prints a request and verifies that the result matches the expected JSON.
-     *
-     * @param <T> request type
-     * @param expectedJsonFile name of the file containing the expected JSON
-     * @param request request to verify
-     * @throws CoderException if the request cannot be pretty-printed
-     */
-    protected <T> void verifyRequest(String expectedJsonFile, T request) throws CoderException {
-        String json = new StandardCoder().encode(request, true);
-        String expected = ResourceUtils.getResourceAsString(expectedJsonFile);
-
-        // strip request id, because it changes each time
-        final String stripper = "svc-request-id[^,]*";
-        json = json.replaceFirst(stripper, "").trim();
-        expected = expected.replaceFirst(stripper, "").trim();
-
-        assertEquals(expected, json);
-    }
-
     /**
      * Verifies that an exception is thrown if a field is missing from the enrichment
      * data.
index f7c88f6..34bbec3 100644 (file)
@@ -39,6 +39,7 @@ import org.junit.Test;
 import org.onap.aai.domain.yang.GenericVnf;
 import org.onap.policy.aai.AaiCqResponse;
 import org.onap.policy.appc.Request;
+import org.onap.policy.common.utils.coder.CoderException;
 import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome;
 import org.onap.policy.controlloop.actorserviceprovider.controlloop.ControlLoopEventContext;
 
@@ -85,7 +86,7 @@ public class ModifyConfigOperationTest extends BasicAppcOperation {
     }
 
     @Test
-    public void testMakeRequest() {
+    public void testMakeRequest() throws CoderException {
         AaiCqResponse cq = new AaiCqResponse("{}");
 
         // missing vnf-id
@@ -101,5 +102,7 @@ public class ModifyConfigOperationTest extends BasicAppcOperation {
         Request request = oper.makeRequest(2);
         assertNotNull(request);
         assertEquals(MY_VNF, request.getPayload().get(ModifyConfigOperation.VNF_ID_KEY));
+
+        verifyRequest("modifyConfig.json", request, IGNORE_FIELDS);
     }
 }
diff --git a/models-interactions/model-actors/actor.appc/src/test/resources/modifyConfig.json b/models-interactions/model-actors/actor.appc/src/test/resources/modifyConfig.json
new file mode 100644 (file)
index 0000000..eae6223
--- /dev/null
@@ -0,0 +1,23 @@
+{
+  "CommonHeader": {
+    "TimeStamp": {
+      "seconds": 1582057368,
+      "nanos": 981593700
+    },
+    "APIver": "1.01",
+    "RequestID": "9a06c485-ebf1-4780-a183-6a1d862eebeb",
+    "SubRequestID": "2d011587-a311-45e6-a75d-67fcd3dfae1a",
+    "RequestTrack": [],
+    "Flags": []
+  },
+  "Action": "ModifyConfig",
+  "Payload": {
+    "my-key-B": {
+      "output": "world"
+    },
+    "my-key-A": {
+      "input": "hello"
+    },
+    "generic-vnf.vnf-id": "my-vnf"
+  }
+}
index 42042da..e849062 100644 (file)
@@ -59,13 +59,13 @@ public class BandwidthOnDemandOperationTest extends BasicSdncOperation {
         assertEquals(BandwidthOnDemandOperation.URI, request.getUrl());
         assertNotNull(request.getHealRequest().getRequestHeaderInfo().getSvcRequestId());
 
-        verifyRequest("bod.json", request);
+        verifyRequest("bod.json", request, IGNORE_FIELDS);
 
         verifyMissing(BandwidthOnDemandOperation.SERVICE_ID_KEY, "service", BandwidthOnDemandOperation::new);
 
         // perform the operation
         makeContext();
-        verifyRequest("bod.json", verifyOperation(oper));
+        verifyRequest("bod.json", verifyOperation(oper), IGNORE_FIELDS);
     }
 
     @Override
index db8751d..c1278f1 100644 (file)
@@ -33,9 +33,7 @@ import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeoutException;
 import java.util.function.BiFunction;
-import org.onap.policy.common.utils.coder.CoderException;
 import org.onap.policy.common.utils.coder.StandardCoder;
-import org.onap.policy.common.utils.resources.ResourceUtils;
 import org.onap.policy.controlloop.actor.test.BasicHttpOperation;
 import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome;
 import org.onap.policy.controlloop.actorserviceprovider.impl.HttpOperator;
@@ -50,6 +48,10 @@ import org.powermock.reflect.Whitebox;
  * Superclass for various operator tests.
  */
 public abstract class BasicSdncOperation extends BasicHttpOperation<SdncRequest> {
+    /**
+     * Fields to be ignored when comparing requests with JSON.
+     */
+    protected static final String[] IGNORE_FIELDS = {"svc-request-id"};
 
     protected SdncResponse response;
 
@@ -109,26 +111,6 @@ public abstract class BasicSdncOperation extends BasicHttpOperation<SdncRequest>
         return requestCaptor.getValue().getEntity();
     }
 
-    /**
-     * Pretty-prints a request and verifies that the result matches the expected JSON.
-     *
-     * @param <T> request type
-     * @param expectedJsonFile name of the file containing the expected JSON
-     * @param request request to verify
-     * @throws CoderException if the request cannot be pretty-printed
-     */
-    protected <T> void verifyRequest(String expectedJsonFile, T request) throws CoderException {
-        String json = new StandardCoder().encode(request, true);
-        String expected = ResourceUtils.getResourceAsString(expectedJsonFile);
-
-        // strip request id, because it changes each time
-        final String stripper = "svc-request-id[^,]*";
-        json = json.replaceFirst(stripper, "").trim();
-        expected = expected.replaceFirst(stripper, "").trim();
-
-        assertEquals(expected, json);
-    }
-
     /**
      * Verifies that an exception is thrown if a field is missing from the enrichment
      * data.
@@ -137,7 +119,7 @@ public abstract class BasicSdncOperation extends BasicHttpOperation<SdncRequest>
      * @param expectedText text expected in the exception message
      */
     protected void verifyMissing(String fieldName, String expectedText,
-                    BiFunction<ControlLoopOperationParams,HttpOperator,SdncOperation> maker) {
+                    BiFunction<ControlLoopOperationParams, HttpOperator, SdncOperation> maker) {
 
         makeContext();
         enrichment.remove(fieldName);
index a98c381..f0836b9 100644 (file)
@@ -59,14 +59,14 @@ public class RerouteOperationTest extends BasicSdncOperation {
         assertEquals(RerouteOperation.URI, request.getUrl());
         assertNotNull(request.getHealRequest().getRequestHeaderInfo().getSvcRequestId());
 
-        verifyRequest("reroute.json", request);
+        verifyRequest("reroute.json", request, IGNORE_FIELDS);
 
         verifyMissing(RerouteOperation.SERVICE_ID_KEY, "service", RerouteOperation::new);
         verifyMissing(RerouteOperation.NETWORK_ID_KEY, "network", RerouteOperation::new);
 
         // perform the operation
         makeContext();
-        verifyRequest("reroute.json", verifyOperation(oper));
+        verifyRequest("reroute.json", verifyOperation(oper), IGNORE_FIELDS);
     }
 
     @Override
index 3a10fa3..9bddbd9 100644 (file)
@@ -53,7 +53,7 @@
         <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
-            <scope>test</scope>
+            <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>org.onap.policy.common</groupId>
index 14c7ef5..e10e941 100644 (file)
@@ -22,50 +22,30 @@ 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";
+public class BasicBidirectionalTopicOperation extends BasicOperation {
     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
@@ -74,19 +54,12 @@ public class BasicBidirectionalTopicOperation {
     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;
+        super();
     }
 
     /**
@@ -96,8 +69,7 @@ public class BasicBidirectionalTopicOperation {
      * @param operation operation name
      */
     public BasicBidirectionalTopicOperation(String actor, String operation) {
-        this.actorName = actor;
-        this.operationName = operation;
+        super(actor, operation);
     }
 
     /**
@@ -117,30 +89,6 @@ public class BasicBidirectionalTopicOperation {
         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.
      */
@@ -154,15 +102,6 @@ public class BasicBidirectionalTopicOperation {
         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}.
      *
index 4929292..05fa226 100644 (file)
@@ -23,8 +23,6 @@ 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.concurrent.CompletableFuture;
 import javax.ws.rs.client.Entity;
 import javax.ws.rs.client.InvocationCallback;
@@ -32,34 +30,20 @@ import javax.ws.rs.core.Response;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Captor;
 import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
 import org.mockito.stubbing.Answer;
 import org.onap.policy.common.endpoints.http.client.HttpClient;
 import org.onap.policy.common.endpoints.http.client.HttpClientFactory;
-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.HttpOperator;
-import org.onap.policy.controlloop.actorserviceprovider.parameters.ControlLoopOperationParams;
 
 /**
  * Superclass for various HttpOperation tests.
  *
  * @param <Q> request type
  */
-public class BasicHttpOperation<Q> {
-    protected static final UUID REQ_ID = UUID.randomUUID();
-    protected static final String DEFAULT_ACTOR = "default-actor";
-    protected static final String DEFAULT_OPERATION = "default-operation";
+public class BasicHttpOperation<Q> extends BasicOperation {
     protected static final String MY_CLIENT = "my-client";
     protected static final String BASE_URI = "/base-uri";
     protected static final String PATH = "/my-path";
-    protected static final String TARGET_ENTITY = "my-target";
-
-    protected final String actorName;
-    protected final String operationName;
 
     @Captor
     protected ArgumentCaptor<InvocationCallback<Response>> callbackCaptor;
@@ -70,9 +54,6 @@ public class BasicHttpOperation<Q> {
     @Captor
     protected ArgumentCaptor<Map<String, Object>> headerCaptor;
 
-    @Mock
-    protected ActorService service;
-
     @Mock
     protected HttpClient client;
 
@@ -85,20 +66,12 @@ public class BasicHttpOperation<Q> {
     @Mock
     protected HttpOperator operator;
 
-    protected CompletableFuture<Response> future;
-    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 BasicHttpOperation() {
-        this.actorName = DEFAULT_ACTOR;
-        this.operationName = DEFAULT_OPERATION;
+        super();
     }
 
     /**
@@ -108,51 +81,24 @@ public class BasicHttpOperation<Q> {
      * @param operation operation name
      */
     public BasicHttpOperation(String actor, String operation) {
-        this.actorName = actor;
-        this.operationName = operation;
+        super(actor, operation);
     }
 
     /**
      * Initializes mocks and sets up.
      */
     public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
+        super.setUp();
 
         when(factory.get(MY_CLIENT)).thenReturn(client);
 
         when(rawResponse.getStatus()).thenReturn(200);
 
-        future = new CompletableFuture<>();
         when(client.getBaseUrl()).thenReturn(BASE_URI);
 
-        executor = new PseudoExecutor();
-
-        makeContext();
-
-        outcome = params.makeOutcome();
-
         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).build();
-    }
-
     /**
      * Initializes an operator so that it is "alive" and has the given names.
      */
@@ -165,15 +111,6 @@ public class BasicHttpOperation<Q> {
         when(operator.getPath()).thenReturn(PATH);
     }
 
-    /**
-     * Makes enrichment data.
-     *
-     * @return enrichment data
-     */
-    protected Map<String, String> makeEnrichment() {
-        return new TreeMap<>();
-    }
-
     /**
      * Provides a response to an asynchronous HttpClient call.
      *
diff --git a/models-interactions/model-actors/actor.test/src/main/java/org/onap/policy/controlloop/actor/test/BasicOperation.java b/models-interactions/model-actors/actor.test/src/main/java/org/onap/policy/controlloop/actor/test/BasicOperation.java
new file mode 100644 (file)
index 0000000..dbdd553
--- /dev/null
@@ -0,0 +1,165 @@
+/*-
+ * ============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.junit.Assert.assertEquals;
+
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.UUID;
+import java.util.concurrent.CompletableFuture;
+import javax.ws.rs.core.Response;
+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.resources.ResourceUtils;
+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.parameters.ControlLoopOperationParams;
+
+/**
+ * Superclass for various Operation tests.
+ */
+public class BasicOperation {
+    protected static final Coder coder = new StandardCoder();
+    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 TARGET_ENTITY = "my-target";
+
+    protected final String actorName;
+    protected final String operationName;
+
+    @Mock
+    protected ActorService service;
+
+    protected CompletableFuture<Response> future;
+    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 BasicOperation() {
+        this.actorName = DEFAULT_ACTOR;
+        this.operationName = DEFAULT_OPERATION;
+    }
+
+    /**
+     * Constructs the object.
+     *
+     * @param actor actor name
+     * @param operation operation name
+     */
+    public BasicOperation(String actor, String operation) {
+        this.actorName = actor;
+        this.operationName = operation;
+    }
+
+    /**
+     * Initializes mocks and sets up.
+     */
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        future = new CompletableFuture<>();
+
+        executor = new PseudoExecutor();
+
+        makeContext();
+
+        outcome = params.makeOutcome();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * Makes enrichment data.
+     *
+     * @return enrichment data
+     */
+    protected Map<String, String> makeEnrichment() {
+        return new TreeMap<>();
+    }
+
+
+    /**
+     * Makes payload data.
+     *
+     * @return payload data
+     */
+    protected Map<String, String> makePayload() {
+        return null;
+    }
+
+    /**
+     * Pretty-prints a request and verifies that the result matches the expected JSON.
+     *
+     * @param <R> request type
+     * @param expectedJsonFile name of the file containing the expected JSON
+     * @param request request to verify
+     * @param ignore names of fields to be ignored, because they change with each request
+     * @throws CoderException if the request cannot be pretty-printed
+     */
+    protected <R> void verifyRequest(String expectedJsonFile, R request, String... ignore) throws CoderException {
+        String json = coder.encode(request, true);
+        String expected = ResourceUtils.getResourceAsString(expectedJsonFile);
+
+        // strip various items, because they change for each request
+        for (String stripper : ignore) {
+            stripper += "[^,]*";
+            json = json.replaceAll(stripper, "");
+            expected = expected.replaceAll(stripper, "");
+        }
+
+        json = json.trim();
+        expected = expected.trim();
+
+        assertEquals(expected, json);
+    }
+}
index 4fd5591..9ec118e 100644 (file)
@@ -23,7 +23,6 @@ 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;
@@ -80,30 +79,6 @@ public class BasicBidirectionalTopicOperationTest {
         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();
@@ -117,11 +92,6 @@ public class BasicBidirectionalTopicOperationTest {
         assertSame(oper.topicParams, oper.operator.getParams());
     }
 
-    @Test
-    public void testMakeEnrichment() {
-        assertTrue(oper.makeEnrichment().isEmpty());
-    }
-
     @Test
     public void testProvideResponse() {
         String response = "{\"input\": 10}";
index 096b8b8..c463d6d 100644 (file)
@@ -71,25 +71,6 @@ public class BasicHttpOperationTest {
         assertTrue(oper.operator.isAlive());
     }
 
-    @Test
-    public void testMakeContext() {
-        oper.makeContext();
-
-        assertTrue(oper.enrichment.isEmpty());
-
-        assertSame(BasicHttpOperation.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(BasicHttpOperation.TARGET_ENTITY, oper.params.getTargetEntity());
-    }
-
     @Test
     public void testInitOperator() throws Exception {
         oper.initOperator();
@@ -102,11 +83,6 @@ public class BasicHttpOperationTest {
         assertEquals(BasicHttpOperation.PATH, oper.operator.getPath());
     }
 
-    @Test
-    public void testMakeEnrichment() {
-        assertTrue(oper.makeEnrichment().isEmpty());
-    }
-
     @Test
     public void testProvideResponse() throws Exception {
         InvocationCallback<Response> cb = new InvocationCallback<>() {
diff --git a/models-interactions/model-actors/actor.test/src/test/java/org/onap/policy/controlloop/actor/test/BasicOperationTest.java b/models-interactions/model-actors/actor.test/src/test/java/org/onap/policy/controlloop/actor/test/BasicOperationTest.java
new file mode 100644 (file)
index 0000000..ee0e5ce
--- /dev/null
@@ -0,0 +1,100 @@
+/*-
+ * ============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.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 java.util.Map;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.common.utils.resources.ResourceUtils;
+import org.onap.policy.controlloop.actorserviceprovider.Util;
+
+public class BasicOperationTest {
+    private static final String ACTOR = "my-actor";
+    private static final String OPERATION = "my-operation";
+
+    private BasicOperation oper;
+
+
+    @Before
+    public void setUp() throws Exception {
+        oper = new BasicHttpOperation<>(ACTOR, OPERATION);
+        oper.setUp();
+    }
+
+    @Test
+    public void testBasicHttpOperation() {
+        oper = new BasicHttpOperation<>();
+        assertEquals(BasicHttpOperation.DEFAULT_ACTOR, oper.actorName);
+        assertEquals(BasicHttpOperation.DEFAULT_OPERATION, oper.operationName);
+    }
+
+    @Test
+    public void testBasicHttpOperationStringString() {
+        assertEquals(ACTOR, oper.actorName);
+        assertEquals(OPERATION, oper.operationName);
+    }
+
+    @Test
+    public void testSetUp() throws Exception {
+        assertNotNull(oper.future);
+        assertNotNull(oper.context);
+        assertNotNull(oper.outcome);
+        assertNotNull(oper.executor);
+    }
+
+    @Test
+    public void testMakeContext() {
+        oper.makeContext();
+
+        assertTrue(oper.enrichment.isEmpty());
+
+        assertSame(BasicHttpOperation.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(BasicHttpOperation.TARGET_ENTITY, oper.params.getTargetEntity());
+    }
+
+    @Test
+    public void testMakeEnrichment_testMakePayload() {
+        assertTrue(oper.makeEnrichment().isEmpty());
+        assertNull(oper.makePayload());
+    }
+
+    @Test
+    public void testVerifyRequest() throws CoderException {
+        Map<String, Object> map = Util.translateToMap("", ResourceUtils.getResourceAsString("actual.json"));
+        oper.verifyRequest("expected.json", map, "svc-request-id", "vnf-id");
+    }
+}
diff --git a/models-interactions/model-actors/actor.test/src/test/resources/actual.json b/models-interactions/model-actors/actor.test/src/test/resources/actual.json
new file mode 100644 (file)
index 0000000..c551cd0
--- /dev/null
@@ -0,0 +1,19 @@
+
+
+{
+  "input": {
+    "sdnc-request-header": {
+      "svc-request-id": "actual-value",
+      "svc-action": "update"
+    },
+    "request-information": {
+      "request-action": "SdwanBandwidthChange"
+    },
+    "service-information": {
+      "service-instance-id": "my-service"
+    },
+    "vnf-information": {
+      "vnf-id": "actual-value"
+    }
+  }
+}
diff --git a/models-interactions/model-actors/actor.test/src/test/resources/expected.json b/models-interactions/model-actors/actor.test/src/test/resources/expected.json
new file mode 100644 (file)
index 0000000..85fbc99
--- /dev/null
@@ -0,0 +1,19 @@
+{
+  "input": {
+    "sdnc-request-header": {
+      "svc-request-id": "expected-value",
+      "svc-action": "update"
+    },
+    "request-information": {
+      "request-action": "SdwanBandwidthChange"
+    },
+    "service-information": {
+      "service-instance-id": "my-service"
+    },
+    "vnf-information": {
+      "vnf-id": "expected-value"
+    }
+  }
+}
+
+