2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.onap.policy.controlloop.actor.so;
23 import static org.assertj.core.api.Assertions.assertThatCode;
24 import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
25 import static org.junit.Assert.assertEquals;
26 import static org.junit.Assert.assertFalse;
27 import static org.junit.Assert.assertNotNull;
28 import static org.junit.Assert.assertNull;
29 import static org.junit.Assert.assertSame;
30 import static org.junit.Assert.assertTrue;
31 import static org.mockito.Mockito.mock;
32 import static org.mockito.Mockito.when;
34 import java.time.LocalDateTime;
35 import java.time.Month;
36 import java.util.Collections;
37 import java.util.List;
38 import java.util.concurrent.CompletableFuture;
39 import java.util.function.Consumer;
40 import java.util.function.Supplier;
41 import org.junit.Before;
42 import org.junit.Test;
43 import org.onap.aai.domain.yang.CloudRegion;
44 import org.onap.aai.domain.yang.GenericVnf;
45 import org.onap.aai.domain.yang.ServiceInstance;
46 import org.onap.aai.domain.yang.Tenant;
47 import org.onap.policy.aai.AaiCqResponse;
48 import org.onap.policy.common.utils.coder.Coder;
49 import org.onap.policy.common.utils.coder.CoderException;
50 import org.onap.policy.controlloop.ControlLoopOperation;
51 import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome;
52 import org.onap.policy.controlloop.policy.PolicyResult;
53 import org.onap.policy.so.SoModelInfo;
54 import org.onap.policy.so.SoRequest;
55 import org.onap.policy.so.SoRequestInfo;
56 import org.onap.policy.so.SoRequestStatus;
57 import org.onap.policy.so.SoResponse;
59 public class SoOperationTest extends BasicSoOperation {
61 private static final String VF_COUNT_KEY = SoConstants.VF_COUNT_PREFIX
62 + "[my-model-customization-id][my-model-invariant-id][my-model-version-id]";
63 private SoOperation oper;
69 public void setUp() throws Exception {
74 oper = new SoOperation(params, config) {};
78 public void testConstructor() {
79 assertEquals(DEFAULT_ACTOR, oper.getActorName());
80 assertEquals(DEFAULT_OPERATION, oper.getName());
81 assertSame(config, oper.getConfig());
82 assertTrue(oper.isUsePolling());
84 // check when Target is null
85 params = params.toBuilder().target(null).build();
86 assertThatIllegalArgumentException().isThrownBy(() -> new SoOperation(params, config) {})
87 .withMessageContaining("Target information");
91 public void testValidateTarget() {
92 // check when various fields are null
93 verifyNotNull("modelCustomizationId", target::getModelCustomizationId, target::setModelCustomizationId);
94 verifyNotNull("modelInvariantId", target::getModelInvariantId, target::setModelInvariantId);
95 verifyNotNull("modelVersionId", target::getModelVersionId, target::setModelVersionId);
97 // verify it's still valid
98 assertThatCode(() -> new VfModuleCreate(params, config)).doesNotThrowAnyException();
101 private void verifyNotNull(String expectedText, Supplier<String> getter, Consumer<String> setter) {
102 String originalValue = getter.get();
106 assertThatIllegalArgumentException().isThrownBy(() -> new VfModuleCreate(params, config))
107 .withMessageContaining(expectedText);
109 setter.accept(originalValue);
113 public void testStartPreprocessorAsync() {
114 assertNotNull(oper.startPreprocessorAsync());
118 public void testObtainVfCount_testGetVfCount_testSetVfCount() throws Exception {
119 // insert CQ data so it's there for the check
120 context.setProperty(AaiCqResponse.CONTEXT_KEY, makeCqResponse());
122 // shouldn't actually need to do anything
123 assertNull(oper.obtainVfCount());
125 // verify that the count was stored
126 Integer vfcount = context.getProperty(VF_COUNT_KEY);
127 assertEquals(VF_COUNT, vfcount);
128 assertEquals(VF_COUNT.intValue(), oper.getVfCount());
130 // change the count and then verify that it isn't overwritten by another call
131 oper.setVfCount(VF_COUNT + 1);
133 assertNull(oper.obtainVfCount());
134 vfcount = context.getProperty(VF_COUNT_KEY);
135 assertEquals(VF_COUNT + 1, vfcount.intValue());
136 assertEquals(VF_COUNT + 1, oper.getVfCount());
140 * Tests obtainVfCount() when it actually has to query.
143 public void testObtainVfCountQuery() throws Exception {
144 CompletableFuture<OperationOutcome> future2 = oper.obtainVfCount();
145 assertNotNull(future2);
146 assertTrue(executor.runAll(100));
149 assertFalse(future2.isDone());
151 provideCqResponse(makeCqResponse());
153 assertTrue(executor.runAll(100));
154 assertTrue(future2.isDone());
155 assertEquals(PolicyResult.SUCCESS, future2.get().getResult());
157 // verify that the count was stored
158 Integer vfcount = context.getProperty(VF_COUNT_KEY);
159 assertEquals(VF_COUNT, vfcount);
161 // repeat - shouldn't need to do anything now
162 assertNull(oper.obtainVfCount());
166 public void testGetRequestState() {
167 SoResponse resp = new SoResponse();
168 assertNull(oper.getRequestState(resp));
170 SoRequest req = new SoRequest();
171 resp.setRequest(req);
172 assertNull(oper.getRequestState(resp));
174 SoRequestStatus status = new SoRequestStatus();
175 req.setRequestStatus(status);
176 assertNull(oper.getRequestState(resp));
178 status.setRequestState("my-state");
179 assertEquals("my-state", oper.getRequestState(resp));
183 public void testIsSuccess() {
186 assertTrue(oper.isSuccess(rawResponse, response));
188 when(rawResponse.getStatus()).thenReturn(500);
189 assertTrue(oper.isSuccess(rawResponse, response));
193 public void testSetOutcome() {
195 when(rawResponse.getStatus()).thenReturn(200);
196 assertSame(outcome, oper.setOutcome(outcome, PolicyResult.SUCCESS, rawResponse, response));
198 assertEquals(PolicyResult.SUCCESS, outcome.getResult());
199 assertEquals("200 " + ControlLoopOperation.SUCCESS_MSG, outcome.getMessage());
200 assertSame(response, outcome.getResponse());
203 when(rawResponse.getStatus()).thenReturn(500);
204 assertSame(outcome, oper.setOutcome(outcome, PolicyResult.FAILURE, rawResponse, response));
206 assertEquals(PolicyResult.FAILURE, outcome.getResult());
207 assertEquals("500 " + ControlLoopOperation.FAILED_MSG, outcome.getMessage());
208 assertSame(response, outcome.getResponse());
212 public void testPrepareSoModelInfo() throws CoderException {
213 verifyMissingModelInfo(target::getModelCustomizationId, target::setModelCustomizationId);
214 verifyMissingModelInfo(target::getModelInvariantId, target::setModelInvariantId);
215 verifyMissingModelInfo(target::getModelName, target::setModelName);
216 verifyMissingModelInfo(target::getModelVersion, target::setModelVersion);
217 verifyMissingModelInfo(target::getModelVersionId, target::setModelVersionId);
220 SoModelInfo info = oper.prepareSoModelInfo();
221 verifyRequest("model.json", info);
223 // try with null target
224 params = params.toBuilder().target(null).build();
225 assertThatIllegalArgumentException().isThrownBy(() -> new SoOperation(params, config) {})
226 .withMessageContaining("missing Target");
229 private void verifyMissingModelInfo(Supplier<String> getter, Consumer<String> setter) {
230 String original = getter.get();
233 assertThatIllegalArgumentException().isThrownBy(() -> oper.prepareSoModelInfo())
234 .withMessage("missing VF Module model");
236 setter.accept(original);
240 public void testConstructRequestInfo() throws CoderException {
241 SoRequestInfo info = oper.constructRequestInfo();
242 verifyRequest("reqinfo.json", info);
246 public void testBuildRequestParameters() throws CoderException {
248 verifyRequest("reqparams.json", oper.buildRequestParameters().get());
251 params.getPayload().put(SoOperation.REQ_PARAM_NM, "{invalid json");
252 assertThatIllegalArgumentException().isThrownBy(() -> oper.buildRequestParameters())
253 .withMessage("invalid payload value: " + SoOperation.REQ_PARAM_NM);
256 params.getPayload().remove(SoOperation.REQ_PARAM_NM);
257 assertTrue(oper.buildRequestParameters().isEmpty());
260 params = params.toBuilder().payload(null).build();
261 oper = new SoOperation(params, config) {};
262 assertTrue(oper.buildRequestParameters().isEmpty());
266 public void testBuildConfigurationParameters() {
268 assertEquals(List.of(Collections.emptyMap()), oper.buildConfigurationParameters().get());
271 params.getPayload().put(SoOperation.CONFIG_PARAM_NM, "{invalid json");
272 assertThatIllegalArgumentException().isThrownBy(() -> oper.buildConfigurationParameters())
273 .withMessage("invalid payload value: " + SoOperation.CONFIG_PARAM_NM);
276 params.getPayload().remove(SoOperation.CONFIG_PARAM_NM);
277 assertTrue(oper.buildConfigurationParameters().isEmpty());
280 params = params.toBuilder().payload(null).build();
281 oper = new SoOperation(params, config) {};
282 assertTrue(oper.buildConfigurationParameters().isEmpty());
286 public void testGetVnfItem() {
288 AaiCqResponse cq = mock(AaiCqResponse.class);
289 assertThatIllegalArgumentException().isThrownBy(() -> oper.getVnfItem(cq, oper.prepareSoModelInfo()))
290 .withMessage("missing generic VNF");
293 GenericVnf vnf = new GenericVnf();
294 when(cq.getGenericVnfByVfModuleModelInvariantId(MODEL_INVAR_ID)).thenReturn(vnf);
295 assertSame(vnf, oper.getVnfItem(cq, oper.prepareSoModelInfo()));
299 public void testGetServiceInstance() {
301 AaiCqResponse cq = mock(AaiCqResponse.class);
302 assertThatIllegalArgumentException().isThrownBy(() -> oper.getServiceInstance(cq))
303 .withMessage("missing VNF Service Item");
306 ServiceInstance instance = new ServiceInstance();
307 when(cq.getServiceInstance()).thenReturn(instance);
308 assertSame(instance, oper.getServiceInstance(cq));
312 public void testGetDefaultTenant() {
314 AaiCqResponse cq = mock(AaiCqResponse.class);
315 assertThatIllegalArgumentException().isThrownBy(() -> oper.getDefaultTenant(cq))
316 .withMessage("missing Tenant Item");
319 Tenant tenant = new Tenant();
320 when(cq.getDefaultTenant()).thenReturn(tenant);
321 assertSame(tenant, oper.getDefaultTenant(cq));
325 public void testGetDefaultCloudRegion() {
327 AaiCqResponse cq = mock(AaiCqResponse.class);
328 assertThatIllegalArgumentException().isThrownBy(() -> oper.getDefaultCloudRegion(cq))
329 .withMessage("missing Cloud Region");
332 CloudRegion region = new CloudRegion();
333 when(cq.getDefaultCloudRegion()).thenReturn(region);
334 assertSame(region, oper.getDefaultCloudRegion(cq));
338 public void testGetCoder() throws CoderException {
339 Coder opcoder = oper.getCoder();
341 // ensure we can decode an SO timestamp
342 String json = "{'request':{'finishTime':'Fri, 15 May 2020 12:14:21 GMT'}}";
343 SoResponse resp = opcoder.decode(json.replace('\'', '"'), SoResponse.class);
345 LocalDateTime tfinish = resp.getRequest().getFinishTime();
346 assertNotNull(tfinish);
347 assertEquals(2020, tfinish.getYear());
348 assertEquals(Month.MAY, tfinish.getMonth());