Add SO actor
[policy/models.git] / models-interactions / model-actors / actor.so / src / test / java / org / onap / policy / controlloop / actor / so / SoOperationTest.java
diff --git a/models-interactions/model-actors/actor.so/src/test/java/org/onap/policy/controlloop/actor/so/SoOperationTest.java b/models-interactions/model-actors/actor.so/src/test/java/org/onap/policy/controlloop/actor/so/SoOperationTest.java
new file mode 100644 (file)
index 0000000..e704138
--- /dev/null
@@ -0,0 +1,353 @@
+/*-
+ * ============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.so;
+
+import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.aai.domain.yang.CloudRegion;
+import org.onap.aai.domain.yang.GenericVnf;
+import org.onap.aai.domain.yang.ServiceInstance;
+import org.onap.aai.domain.yang.Tenant;
+import org.onap.policy.aai.AaiCqResponse;
+import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.controlloop.ControlLoopOperation;
+import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome;
+import org.onap.policy.controlloop.policy.PolicyResult;
+import org.onap.policy.so.SoModelInfo;
+import org.onap.policy.so.SoRequest;
+import org.onap.policy.so.SoRequestInfo;
+import org.onap.policy.so.SoRequestParameters;
+import org.onap.policy.so.SoRequestReferences;
+import org.onap.policy.so.SoRequestStatus;
+import org.onap.policy.so.SoResponse;
+
+public class SoOperationTest extends BasicSoOperation {
+
+    private SoOperation oper;
+
+    /**
+     * Sets up.
+     */
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+
+        initOperator();
+
+        oper = new SoOperation(params, soOperator) {};
+    }
+
+    @Test
+    public void testConstructor_testGetWaitMsGet() {
+        assertEquals(DEFAULT_ACTOR, oper.getActorName());
+        assertEquals(DEFAULT_OPERATION, oper.getName());
+        assertSame(soOperator, oper.getOperator());
+        assertEquals(1000 * WAIT_SEC_GETS, oper.getWaitMsGet());
+    }
+
+    @Test
+    public void testStartPreprocessorAsync() {
+        AtomicBoolean guardStarted = new AtomicBoolean();
+
+        oper = new SoOperation(params, soOperator) {
+            @Override
+            protected CompletableFuture<OperationOutcome> startGuardAsync() {
+                guardStarted.set(true);
+                return super.startGuardAsync();
+            }
+        };
+
+        assertNull(oper.startPreprocessorAsync());
+        assertTrue(guardStarted.get());
+    }
+
+    @Test
+    public void testPostProcess() throws Exception {
+        // completed
+        CompletableFuture<OperationOutcome> future2 = oper.postProcessResponse(outcome, PATH, rawResponse, response);
+        assertTrue(future2.isDone());
+        assertSame(outcome, future2.get());
+        assertEquals(PolicyResult.SUCCESS, outcome.getResult());
+
+        // failed
+        response.getRequest().getRequestStatus().setRequestState(SoOperation.FAILED);
+        future2 = oper.postProcessResponse(outcome, PATH, rawResponse, response);
+        assertTrue(future2.isDone());
+        assertSame(outcome, future2.get());
+        assertEquals(PolicyResult.FAILURE, outcome.getResult());
+
+        // no request id in the response
+        response.getRequestReferences().setRequestId(null);
+        response.getRequest().getRequestStatus().setRequestState("unknown");
+        assertThatIllegalArgumentException()
+                        .isThrownBy(() -> oper.postProcessResponse(outcome, PATH, rawResponse, response))
+                        .withMessage("missing request ID in response");
+        response.getRequestReferences().setRequestId(REQ_ID.toString());
+
+        // status = 500
+        when(rawResponse.getStatus()).thenReturn(500);
+
+        // null request reference
+        SoRequestReferences ref = response.getRequestReferences();
+        response.setRequestReferences(null);
+        assertThatIllegalArgumentException()
+                        .isThrownBy(() -> oper.postProcessResponse(outcome, PATH, rawResponse, response))
+                        .withMessage("missing request ID in response");
+        response.setRequestReferences(ref);
+    }
+
+    /**
+     * Tests postProcess() when the "get" is repeated a couple of times.
+     */
+    @Test
+    public void testPostProcessRepeated_testResetGetCount() throws Exception {
+        /*
+         * Two failures and then a success - should result in two "get" calls.
+         *
+         * Note: getStatus() is invoked twice during each call, so have to double up the
+         * return values.
+         */
+        when(rawResponse.getStatus()).thenReturn(500, 500, 500, 500, 200, 200);
+
+        when(client.get(any(), any(), any())).thenAnswer(provideResponse(rawResponse));
+
+        // use a real executor
+        params = params.toBuilder().executor(ForkJoinPool.commonPool()).build();
+
+        oper = new SoOperation(params, soOperator) {
+            @Override
+            public long getWaitMsGet() {
+                return 1;
+            }
+        };
+
+        CompletableFuture<OperationOutcome> future2 = oper.postProcessResponse(outcome, PATH, rawResponse, response);
+
+        assertSame(outcome, future2.get(5, TimeUnit.SECONDS));
+        assertEquals(PolicyResult.SUCCESS, outcome.getResult());
+        assertEquals(2, oper.getGetCount());
+
+        /*
+         * repeat - this time, the "get" operations will be exhausted, so it should fail
+         */
+        when(rawResponse.getStatus()).thenReturn(500);
+
+        future2 = oper.postProcessResponse(outcome, PATH, rawResponse, response);
+
+        assertSame(outcome, future2.get(5, TimeUnit.SECONDS));
+        assertEquals(PolicyResult.FAILURE_TIMEOUT, outcome.getResult());
+        assertEquals(MAX_GETS + 1, oper.getGetCount());
+
+        oper.resetGetCount();
+        assertEquals(0, oper.getGetCount());
+    }
+
+    @Test
+    public void testGetRequestState() {
+        SoResponse resp = new SoResponse();
+        assertNull(oper.getRequestState(resp));
+
+        SoRequest req = new SoRequest();
+        resp.setRequest(req);
+        assertNull(oper.getRequestState(resp));
+
+        SoRequestStatus status = new SoRequestStatus();
+        req.setRequestStatus(status);
+        assertNull(oper.getRequestState(resp));
+
+        status.setRequestState("my-state");
+        assertEquals("my-state", oper.getRequestState(resp));
+    }
+
+    @Test
+    public void testIsSuccess() {
+        // always true
+
+        assertTrue(oper.isSuccess(rawResponse, response));
+
+        when(rawResponse.getStatus()).thenReturn(500);
+        assertTrue(oper.isSuccess(rawResponse, response));
+    }
+
+    @Test
+    public void testSetOutcome() {
+        // success case
+        when(rawResponse.getStatus()).thenReturn(200);
+        assertSame(outcome, oper.setOutcome(outcome, PolicyResult.SUCCESS, rawResponse, response));
+
+        assertEquals(PolicyResult.SUCCESS, outcome.getResult());
+        assertEquals("200 " + ControlLoopOperation.SUCCESS_MSG, outcome.getMessage());
+
+        // failure case
+        when(rawResponse.getStatus()).thenReturn(500);
+        assertSame(outcome, oper.setOutcome(outcome, PolicyResult.FAILURE, rawResponse, response));
+
+        assertEquals(PolicyResult.FAILURE, outcome.getResult());
+        assertEquals("500 " + ControlLoopOperation.FAILED_MSG, outcome.getMessage());
+    }
+
+    @Test
+    public void testPrepareSoModelInfo() throws CoderException {
+        verifyMissingModelInfo(target::getModelCustomizationId, target::setModelCustomizationId);
+        verifyMissingModelInfo(target::getModelInvariantId, target::setModelInvariantId);
+        verifyMissingModelInfo(target::getModelName, target::setModelName);
+        verifyMissingModelInfo(target::getModelVersion, target::setModelVersion);
+        verifyMissingModelInfo(target::getModelVersionId, target::setModelVersionId);
+
+        // valid data
+        SoModelInfo info = oper.prepareSoModelInfo();
+        verifyRequest("model.json", info);
+
+        // try with null target
+        params = params.toBuilder().target(null).build();
+        oper = new SoOperation(params, soOperator) {};
+
+        assertThatIllegalArgumentException().isThrownBy(() -> oper.prepareSoModelInfo()).withMessage("missing Target");
+    }
+
+    private void verifyMissingModelInfo(Supplier<String> getter, Consumer<String> setter) {
+        String original = getter.get();
+
+        setter.accept(null);
+        assertThatIllegalArgumentException().isThrownBy(() -> oper.prepareSoModelInfo())
+                        .withMessage("missing VF Module model");
+
+        setter.accept(original);
+    }
+
+    @Test
+    public void testConstructRequestInfo() throws CoderException {
+        SoRequestInfo info = oper.constructRequestInfo();
+        verifyRequest("reqinfo.json", info);
+    }
+
+    @Test
+    public void testBuildRequestParameters() throws CoderException {
+        // valid data
+        SoRequestParameters reqParams = oper.buildRequestParameters();
+        verifyRequest("reqparams.json", reqParams);
+
+        // invalid json
+        params.getPayload().put(SoOperation.REQ_PARAM_NM, "{invalid json");
+        assertThatIllegalArgumentException().isThrownBy(() -> oper.buildRequestParameters())
+                        .withMessage("invalid payload value: " + SoOperation.REQ_PARAM_NM);
+
+        // missing data
+        params.getPayload().remove(SoOperation.REQ_PARAM_NM);
+        assertNull(oper.buildRequestParameters());
+
+        // null payload
+        params = params.toBuilder().payload(null).build();
+        oper = new SoOperation(params, soOperator) {};
+        assertNull(oper.buildRequestParameters());
+    }
+
+    @Test
+    public void testBuildConfigurationParameters() {
+        // valid data
+        List<Map<String, String>> result = oper.buildConfigurationParameters();
+        assertEquals(List.of(Collections.emptyMap()), result);
+
+        // invalid json
+        params.getPayload().put(SoOperation.CONFIG_PARAM_NM, "{invalid json");
+        assertThatIllegalArgumentException().isThrownBy(() -> oper.buildConfigurationParameters())
+                        .withMessage("invalid payload value: " + SoOperation.CONFIG_PARAM_NM);
+
+        // missing data
+        params.getPayload().remove(SoOperation.CONFIG_PARAM_NM);
+        assertNull(oper.buildConfigurationParameters());
+
+        // null payload
+        params = params.toBuilder().payload(null).build();
+        oper = new SoOperation(params, soOperator) {};
+        assertNull(oper.buildConfigurationParameters());
+    }
+
+    @Test
+    public void testGetVnfItem() {
+        // missing data
+        AaiCqResponse cq = mock(AaiCqResponse.class);
+        assertThatIllegalArgumentException().isThrownBy(() -> oper.getVnfItem(cq, oper.prepareSoModelInfo()))
+                        .withMessage("missing generic VNF");
+
+        // valid data
+        GenericVnf vnf = new GenericVnf();
+        when(cq.getGenericVnfByVfModuleModelInvariantId(MODEL_INVAR_ID)).thenReturn(vnf);
+        assertSame(vnf, oper.getVnfItem(cq, oper.prepareSoModelInfo()));
+    }
+
+    @Test
+    public void testGetServiceInstance() {
+        // missing data
+        AaiCqResponse cq = mock(AaiCqResponse.class);
+        assertThatIllegalArgumentException().isThrownBy(() -> oper.getServiceInstance(cq))
+                        .withMessage("missing VNF Service Item");
+
+        // valid data
+        ServiceInstance instance = new ServiceInstance();
+        when(cq.getServiceInstance()).thenReturn(instance);
+        assertSame(instance, oper.getServiceInstance(cq));
+    }
+
+    @Test
+    public void testGetDefaultTenant() {
+        // missing data
+        AaiCqResponse cq = mock(AaiCqResponse.class);
+        assertThatIllegalArgumentException().isThrownBy(() -> oper.getDefaultTenant(cq))
+                        .withMessage("missing Tenant Item");
+
+        // valid data
+        Tenant tenant = new Tenant();
+        when(cq.getDefaultTenant()).thenReturn(tenant);
+        assertSame(tenant, oper.getDefaultTenant(cq));
+    }
+
+    @Test
+    public void testGetDefaultCloudRegion() {
+        // missing data
+        AaiCqResponse cq = mock(AaiCqResponse.class);
+        assertThatIllegalArgumentException().isThrownBy(() -> oper.getDefaultCloudRegion(cq))
+                        .withMessage("missing Cloud Region");
+
+        // valid data
+        CloudRegion region = new CloudRegion();
+        when(cq.getDefaultCloudRegion()).thenReturn(region);
+        assertSame(region, oper.getDefaultCloudRegion(cq));
+    }
+}