X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=models-interactions%2Fmodel-actors%2Factor.appclcm%2Fsrc%2Ftest%2Fjava%2Forg%2Fonap%2Fpolicy%2Fcontrolloop%2Factor%2Fappclcm%2FAppcLcmOperationTest.java;h=5765e3c98f63edb87dff60b766bae27a7d965448;hb=e3938e43b8a1f02f74368ecb75c38530285feac0;hp=d2af4e7e22b93f99103ded8aecce5340543a85e9;hpb=efafe30feec4864cd325bcb36bff6a7cd9dd4e5e;p=policy%2Fmodels.git diff --git a/models-interactions/model-actors/actor.appclcm/src/test/java/org/onap/policy/controlloop/actor/appclcm/AppcLcmOperationTest.java b/models-interactions/model-actors/actor.appclcm/src/test/java/org/onap/policy/controlloop/actor/appclcm/AppcLcmOperationTest.java index d2af4e7e2..5765e3c98 100644 --- a/models-interactions/model-actors/actor.appclcm/src/test/java/org/onap/policy/controlloop/actor/appclcm/AppcLcmOperationTest.java +++ b/models-interactions/model-actors/actor.appclcm/src/test/java/org/onap/policy/controlloop/actor/appclcm/AppcLcmOperationTest.java @@ -1,8 +1,9 @@ /*- * ============LICENSE_START======================================================= - * AppcLcmOperation + * ONAP * ================================================================================ - * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2020-2021 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2023 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,173 +21,343 @@ package org.onap.policy.controlloop.actor.appclcm; +import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.atLeast; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import java.util.Arrays; +import java.util.HashMap; import java.util.List; -import java.util.UUID; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import org.junit.After; +import org.junit.AfterClass; import org.junit.Before; -import org.junit.Ignore; +import org.junit.BeforeClass; import org.junit.Test; -import org.mockito.Mockito; +import org.junit.runner.RunWith; +import org.mockito.junit.MockitoJUnitRunner; import org.onap.policy.appclcm.AppcLcmBody; import org.onap.policy.appclcm.AppcLcmCommonHeader; import org.onap.policy.appclcm.AppcLcmDmaapWrapper; -import org.onap.policy.appclcm.AppcLcmInput; import org.onap.policy.appclcm.AppcLcmOutput; import org.onap.policy.appclcm.AppcLcmResponseStatus; -import org.onap.policy.controlloop.VirtualControlLoopEvent; -import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome; -import org.onap.policy.controlloop.actorserviceprovider.controlloop.ControlLoopEventContext; +import org.onap.policy.common.endpoints.event.comm.TopicSink; +import org.onap.policy.common.endpoints.event.comm.TopicSource; +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.controlloop.ControlLoopOperation; +import org.onap.policy.controlloop.actor.test.BasicBidirectionalTopicOperation; +import org.onap.policy.controlloop.actorserviceprovider.OperationProperties; +import org.onap.policy.controlloop.actorserviceprovider.OperationResult; import org.onap.policy.controlloop.actorserviceprovider.impl.BidirectionalTopicOperation.Status; +import org.onap.policy.controlloop.actorserviceprovider.parameters.BidirectionalTopicConfig; +import org.onap.policy.controlloop.actorserviceprovider.parameters.BidirectionalTopicParams; import org.onap.policy.controlloop.actorserviceprovider.parameters.ControlLoopOperationParams; -import org.onap.policy.controlloop.policy.PolicyResult; -import org.powermock.reflect.Whitebox; - -public class AppcLcmOperationTest { - private AppcLcmInput mockInput; - private AppcLcmOutput mockOutput; - private AppcLcmBody mockBody; - private AppcLcmDmaapWrapper mockInputWrapper; - private AppcLcmDmaapWrapper mockOutputWrapper; - private OperationOutcome mockOperationOutcome; - private AppcLcmOperation operation; - private AppcLcmResponseStatus mockResponseStatus; - private AppcLcmCommonHeader mockCommonHeader; - private ControlLoopOperationParams mockParams; - private ControlLoopEventContext mockContext; - private VirtualControlLoopEvent mockEvent; +import org.onap.policy.simulators.AppcLcmTopicServer; +import org.onap.policy.simulators.TopicServer; + +@RunWith(MockitoJUnitRunner.class) +public class AppcLcmOperationTest extends BasicBidirectionalTopicOperation { + + private static final String EXPECTED_EXCEPTION = "expected exception"; + private static final String PAYLOAD_KEY1 = "key-A"; + private static final String PAYLOAD_VALUE1 = "value-A"; + private static final String MY_MESSAGE = "my-message"; + protected static final String MY_VNF = "my-vnf"; + protected static final String RESOURCE_ID = "my-resource"; + private static final int SUCCESS_CODE = 400; + + private AppcLcmDmaapWrapper response; + private AppcLcmOperation oper; + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + initBeforeClass(MY_SINK, MY_SOURCE); + } + + @AfterClass + public static void tearDownAfterClass() { + destroyAfterClass(); + } /** - * Setup mocks for testing. + * Sets up. */ @Before - public void setup() { - mockInput = Mockito.mock(AppcLcmInput.class); - mockOutput = Mockito.mock(AppcLcmOutput.class); - mockBody = Mockito.mock(AppcLcmBody.class); - mockContext = Mockito.mock(ControlLoopEventContext.class); - mockEvent = Mockito.mock(VirtualControlLoopEvent.class); - mockInputWrapper = Mockito.mock(AppcLcmDmaapWrapper.class); - mockOutputWrapper = Mockito.mock(AppcLcmDmaapWrapper.class); - mockOperationOutcome = Mockito.mock(OperationOutcome.class); - mockResponseStatus = Mockito.mock(AppcLcmResponseStatus.class); - mockCommonHeader = Mockito.mock(AppcLcmCommonHeader.class); - mockParams = Mockito.mock(ControlLoopOperationParams.class); - operation = Mockito.mock(AppcLcmOperation.class); + public void setUp() { + super.setUpBasic(); + + response = makeResponse(); + + oper = new AppcLcmOperation(params, config); + oper.setProperty(OperationProperties.AAI_TARGET_ENTITY, TARGET_ENTITY); } + @After + public void tearDown() { + super.tearDownBasic(); + } + + @Override + protected TopicServer makeServer(TopicSink sink, TopicSource source) { + return new AppcLcmTopicServer(sink, source); + } + + /** + * Tests "success" case with simulator. + */ @Test - public void testStartPreprocessorAsync() { - Mockito.doCallRealMethod().when(operation).startPreprocessorAsync(); - assertNull(operation.startPreprocessorAsync()); + public void testSuccess() throws Exception { + BidirectionalTopicParams opParams = + BidirectionalTopicParams.builder().sinkTopic(MY_SINK).sourceTopic(MY_SOURCE).build(); + config = new BidirectionalTopicConfig(blockingExecutor, opParams, topicMgr, AppcLcmOperation.SELECTOR_KEYS); + + params = params.toBuilder().retry(0).timeoutSec(5).executor(blockingExecutor).build(); + + oper = new AppcLcmOperation(params, config); + oper.setProperty(OperationProperties.AAI_TARGET_ENTITY, TARGET_ENTITY); + + outcome = oper.start().get(); + assertEquals(OperationResult.SUCCESS, outcome.getResult()); + assertTrue(outcome.getResponse() instanceof AppcLcmDmaapWrapper); + } + + @Test + public void testConstructor() { + assertEquals(DEFAULT_ACTOR, oper.getActorName()); + assertEquals(DEFAULT_OPERATION, oper.getName()); + } + + @Test + public void testGetPropertyNames() { + assertThat(oper.getPropertyNames()).isEqualTo(List.of(OperationProperties.AAI_TARGET_ENTITY)); } - @Ignore @Test public void testMakeRequest() { - UUID randomId = UUID.randomUUID(); - Mockito.doCallRealMethod().when(operation).makeRequest(1, "sampleTargetVnf"); - Mockito.when(mockParams.getRequestId()).thenReturn(randomId); - Mockito.when(mockParams.getPayload()).thenReturn(null); - Mockito.when(mockParams.getContext()).thenReturn(mockContext); - Mockito.when(mockParams.getOperation()).thenReturn("Config-Modify"); - Mockito.when(mockContext.getEvent()).thenReturn(mockEvent); - Mockito.when(mockEvent.getRequestId()).thenReturn(randomId); - Whitebox.setInternalState(operation, "params", mockParams); - assertNotNull(operation.makeRequest(1, "sampleTargetVnf")); - Mockito.verify(mockParams, atLeast(1)).getRequestId(); - Mockito.verify(mockParams, atLeast(1)).getPayload(); - Mockito.verify(mockParams, atLeast(1)).getContext(); - Mockito.verify(mockContext, atLeast(1)).getEvent(); - Mockito.verify(mockEvent, atLeast(1)).getRequestId(); + oper.generateSubRequestId(2); + String subreq = oper.getSubRequestId(); + assertNotNull(subreq); + + AppcLcmDmaapWrapper request = oper.makeRequest(2); + assertEquals("DefaultOperation", request.getBody().getInput().getAction()); + + AppcLcmCommonHeader header = request.getBody().getInput().getCommonHeader(); + assertNotNull(header); + assertEquals(params.getRequestId(), header.getRequestId()); + + assertEquals(subreq, header.getSubRequestId()); + + assertEquals("{vnf-id=my-target}", request.getBody().getInput().getActionIdentifiers().toString()); + + request = oper.makeRequest(2); + assertEquals(subreq, request.getBody().getInput().getCommonHeader().getSubRequestId()); } + /** + * Tests makeRequest() when a property is missing. + */ @Test - public void testGetExpectedKeyValues() { - Mockito.doCallRealMethod().when(operation).getExpectedKeyValues(1, mockInputWrapper); - Mockito.when(mockInputWrapper.getBody()).thenReturn(mockBody); - Mockito.when(mockBody.getInput()).thenReturn(mockInput); - Mockito.when(mockInput.getCommonHeader()).thenReturn(mockCommonHeader); - Mockito.when(mockCommonHeader.getSubRequestId()).thenReturn("sampleSubRequestId"); + public void testMakeRequestMissingProperty() throws Exception { + oper = new AppcLcmOperation(params, config); + oper.generateSubRequestId(1); + + assertThatIllegalStateException().isThrownBy(() -> oper.makeRequest(1)) + .withMessageContaining("missing target entity"); + } + + @Test + public void testConvertPayload() { + // only builds a payload for ConfigModify + params = params.toBuilder().operation(AppcLcmConstants.OPERATION_CONFIG_MODIFY).build(); + oper = new AppcLcmOperation(params, config); + oper.setProperty(OperationProperties.AAI_TARGET_ENTITY, TARGET_ENTITY); + + oper.generateSubRequestId(2); + AppcLcmDmaapWrapper req = oper.makeRequest(2); + assertEquals("{\"key-A\":\"value-A\"}", req.getBody().getInput().getPayload()); - List retList = operation.getExpectedKeyValues(1, mockInputWrapper); - assertNotNull(retList); - assertEquals(1, retList.size()); + // coder exception + oper = new AppcLcmOperation(params, config) { + @Override + protected Coder getCoder() { + return new StandardCoder() { + @Override + public String encode(Object object) throws CoderException { + throw new CoderException(EXPECTED_EXCEPTION); + } + }; + } + }; - Mockito.verify(mockInputWrapper, atLeast(1)).getBody(); - Mockito.verify(mockBody, atLeast(1)).getInput(); - Mockito.verify(mockInput, atLeast(1)).getCommonHeader(); - Mockito.verify(mockCommonHeader, atLeast(1)).getSubRequestId(); + oper.setProperty(OperationProperties.AAI_TARGET_ENTITY, TARGET_ENTITY); + oper.generateSubRequestId(2); + + assertThatIllegalArgumentException().isThrownBy(() -> oper.makeRequest(2)) + .withMessageContaining("Cannot convert payload"); + } + + @Test + public void testGetExpectedKeyValues() { + oper.generateSubRequestId(2); + AppcLcmDmaapWrapper request = oper.makeRequest(2); + assertEquals(Arrays.asList(request.getBody().getInput().getCommonHeader().getSubRequestId()), + oper.getExpectedKeyValues(50, request)); } @Test public void testDetmStatus() { - Mockito.doCallRealMethod().when(operation).detmStatus("testResponse", mockOutputWrapper); - Mockito.when(mockOutputWrapper.getBody()).thenReturn(mockBody); - Mockito.when(mockBody.getOutput()).thenReturn(mockOutput); - Mockito.when(mockOutput.getStatus()).thenReturn(mockResponseStatus); - Mockito.when(mockResponseStatus.getCode()).thenReturn(100); - Status retStatus = operation.detmStatus("testResponse", mockOutputWrapper); - assertEquals(Status.STILL_WAITING, retStatus); + assertEquals(Status.SUCCESS, oper.detmStatus(null, response)); - Mockito.when(mockResponseStatus.getCode()).thenReturn(400); - retStatus = operation.detmStatus("testResponse", mockOutputWrapper); - assertEquals(Status.SUCCESS, retStatus); + // failure + response.getBody().getOutput().getStatus().setCode(405); + assertEquals(Status.FAILURE, oper.detmStatus(null, response)); - Mockito.when(mockResponseStatus.getCode()).thenReturn(450); - retStatus = operation.detmStatus("testResponse", mockOutputWrapper); - assertEquals(Status.FAILURE, retStatus); + // error + response.getBody().getOutput().getStatus().setCode(200); + assertThatIllegalArgumentException().isThrownBy(() -> oper.detmStatus(null, response)); - Mockito.when(mockOutput.getStatus()).thenReturn(null); - assertThatIllegalArgumentException().isThrownBy(() -> operation.detmStatus("testResponse", mockOutputWrapper)); + // reject + response.getBody().getOutput().getStatus().setCode(305); + assertThatIllegalArgumentException().isThrownBy(() -> oper.detmStatus(null, response)); - Mockito.when(mockResponseStatus.getCode()).thenReturn(200); - assertThatIllegalArgumentException().isThrownBy(() -> operation.detmStatus("testResponse", mockOutputWrapper)); + // accepted + response.getBody().getOutput().getStatus().setCode(100); + assertEquals(Status.STILL_WAITING, oper.detmStatus(null, response)); - Mockito.verify(mockOutputWrapper, atLeast(1)).getBody(); - Mockito.verify(mockBody, atLeast(1)).getOutput(); - Mockito.verify(mockOutput, atLeast(1)).getStatus(); - Mockito.verify(mockResponseStatus, atLeast(1)).getCode(); + // other + response.getBody().getOutput().getStatus().setCode(-1); + assertThatIllegalArgumentException().isThrownBy(() -> oper.detmStatus(null, response)); + + // null status + response.getBody().getOutput().setStatus(null); + assertThatIllegalArgumentException().isThrownBy(() -> oper.detmStatus(null, response)); } @Test public void testSetOutcome() { - Mockito.doCallRealMethod().when(operation).setOutcome(mockOperationOutcome, PolicyResult.SUCCESS, - mockOutputWrapper); - Mockito.doCallRealMethod().when(operation).setOutcome(mockOperationOutcome, PolicyResult.FAILURE, - mockOutputWrapper); - - Mockito.doCallRealMethod().when(mockOperationOutcome).setResult(any(PolicyResult.class)); - Mockito.doCallRealMethod().when(mockOperationOutcome).setMessage(any(String.class)); - Mockito.doCallRealMethod().when(mockOperationOutcome).getResult(); - Mockito.doCallRealMethod().when(mockOperationOutcome).getMessage(); - - Mockito.when(mockOutputWrapper.getBody()).thenReturn(mockBody); - Mockito.when(mockBody.getOutput()).thenReturn(mockOutput); - Mockito.when(mockOutput.getStatus()).thenReturn(mockResponseStatus); - Mockito.when(mockResponseStatus.getMessage()).thenReturn(null); - - OperationOutcome result = operation.setOutcome(mockOperationOutcome, PolicyResult.SUCCESS, mockOutputWrapper); - assertNull(result); - Mockito.verify(operation).setOutcome(mockOperationOutcome, PolicyResult.SUCCESS, mockOutputWrapper); - - Mockito.when(mockOutput.getStatus()).thenReturn(mockResponseStatus); - Mockito.when(mockResponseStatus.getMessage()).thenReturn("sampleMessage"); - result = operation.setOutcome(mockOperationOutcome, PolicyResult.FAILURE, mockOutputWrapper); - assertEquals(PolicyResult.FAILURE, result.getResult()); - assertNotNull(result.getMessage()); - - Mockito.verify(mockOutputWrapper, atLeast(1)).getBody(); - Mockito.verify(mockBody, atLeast(1)).getOutput(); - Mockito.verify(mockOutput, atLeast(1)).getStatus(); - Mockito.verify(mockResponseStatus, atLeast(1)).getMessage(); - Mockito.verify(operation, atLeast(1)).setOutcome(mockOperationOutcome, PolicyResult.SUCCESS, mockOutputWrapper); - Mockito.verify(operation, atLeast(1)).setOutcome(mockOperationOutcome, PolicyResult.FAILURE, mockOutputWrapper); + oper.setOutcome(outcome, OperationResult.SUCCESS, response); + assertEquals(OperationResult.SUCCESS, outcome.getResult()); + assertEquals(MY_MESSAGE, outcome.getMessage()); + assertSame(response, outcome.getResponse()); + + // failure + oper.setOutcome(outcome, OperationResult.FAILURE, response); + assertEquals(OperationResult.FAILURE, outcome.getResult()); + assertEquals(MY_MESSAGE, outcome.getMessage()); + assertSame(response, outcome.getResponse()); + + // null message + response.getBody().getOutput().getStatus().setMessage(null); + oper.setOutcome(outcome, OperationResult.SUCCESS, response); + assertEquals(ControlLoopOperation.SUCCESS_MSG, outcome.getMessage()); + assertSame(response, outcome.getResponse()); + + // null status + response.getBody().getOutput().setStatus(null); + oper.setOutcome(outcome, OperationResult.SUCCESS, response); + assertEquals(ControlLoopOperation.SUCCESS_MSG, outcome.getMessage()); + assertSame(response, outcome.getResponse()); } + @Test + public void testGetStatus() { + assertNotNull(oper.getStatus(response)); + + // null status + response.getBody().getOutput().setStatus(null); + assertNull(oper.getStatus(response)); + + // null outcome + response.getBody().setOutput(null); + assertNull(oper.getStatus(response)); + + // null body + response.setBody(null); + assertNull(oper.getStatus(response)); + + // null response + assertNull(oper.getStatus(null)); + } + + @Test + public void testOperationSupportsPayload() { + // these should support a payload + Set supported = Set.of(AppcLcmConstants.OPERATION_CONFIG_MODIFY); + + for (String name : supported) { + params = params.toBuilder().operation(name).build(); + oper = new AppcLcmOperation(params, config); + assertTrue(name, oper.operationSupportsPayload()); + } + + // these should NOT support a payload + Set unsupported = AppcLcmConstants.OPERATION_NAMES.stream().filter(name -> !supported.contains(name)) + .collect(Collectors.toSet()); + + for (String name : unsupported) { + params = params.toBuilder().operation(name).build(); + oper = new AppcLcmOperation(params, config); + assertFalse(name, oper.operationSupportsPayload()); + } + + // pick an operation that would ordinarily support payloads + String sup = supported.iterator().next(); + + // verify that it still supports payload + params = params.toBuilder().operation(sup).build(); + oper = new AppcLcmOperation(params, config); + assertTrue(oper.operationSupportsPayload()); + + // try with empty payload + params = params.toBuilder().payload(Map.of()).build(); + oper = new AppcLcmOperation(params, config); + assertFalse(oper.operationSupportsPayload()); + + // try with null payload + params = params.toBuilder().payload(null).build(); + oper = new AppcLcmOperation(params, config); + assertFalse(oper.operationSupportsPayload()); + } + + @Override + protected void makeContext() { + super.makeContext(); + + Map targetEntities = new HashMap<>(); + targetEntities.put(ControlLoopOperationParams.PARAMS_ENTITY_RESOURCEID, RESOURCE_ID); + + params = params.toBuilder().targetEntityIds(targetEntities).build(); + } + + @Override + protected Map makePayload() { + return Map.of(PAYLOAD_KEY1, PAYLOAD_VALUE1); + } + + private AppcLcmDmaapWrapper makeResponse() { + AppcLcmDmaapWrapper response = new AppcLcmDmaapWrapper(); + + AppcLcmBody body = new AppcLcmBody(); + response.setBody(body); + + AppcLcmOutput output = new AppcLcmOutput(); + body.setOutput(output); + + AppcLcmResponseStatus status = new AppcLcmResponseStatus(); + output.setStatus(status); + status.setMessage(MY_MESSAGE); + status.setCode(SUCCESS_CODE); + + return response; + } }