2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2020-2021 AT&T Intellectual Property. All rights reserved.
6 * Modifications Copyright (C) 2021, 2023-2024 Nordix Foundation.
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
22 package org.onap.policy.controlloop.common.rules.test;
24 import static org.junit.jupiter.api.Assertions.assertEquals;
25 import static org.junit.jupiter.api.Assertions.assertSame;
26 import static org.junit.jupiter.api.Assertions.assertTrue;
27 import static org.mockito.ArgumentMatchers.any;
28 import static org.mockito.ArgumentMatchers.eq;
29 import static org.mockito.Mockito.mock;
30 import static org.mockito.Mockito.spy;
31 import static org.mockito.Mockito.times;
32 import static org.mockito.Mockito.verify;
33 import static org.mockito.Mockito.when;
35 import java.util.LinkedList;
37 import java.util.Queue;
38 import java.util.concurrent.atomic.AtomicLong;
39 import java.util.function.Predicate;
40 import java.util.function.Supplier;
41 import org.junit.jupiter.api.AfterAll;
42 import org.junit.jupiter.api.BeforeAll;
43 import org.junit.jupiter.api.BeforeEach;
44 import org.junit.jupiter.api.Disabled;
45 import org.junit.jupiter.api.Test;
46 import org.onap.policy.appc.CommonHeader;
47 import org.onap.policy.appc.Request;
48 import org.onap.policy.appclcm.AppcLcmBody;
49 import org.onap.policy.appclcm.AppcLcmCommonHeader;
50 import org.onap.policy.appclcm.AppcLcmInput;
51 import org.onap.policy.appclcm.AppcLcmMessageWrapper;
52 import org.onap.policy.common.utils.coder.StandardCoder;
53 import org.onap.policy.common.utils.coder.StandardCoderInstantAsMillis;
54 import org.onap.policy.controlloop.ControlLoopNotificationType;
55 import org.onap.policy.controlloop.VirtualControlLoopNotification;
56 import org.onap.policy.drools.controller.DroolsController;
57 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
58 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
59 import org.onap.policy.sdnr.PciBody;
60 import org.onap.policy.sdnr.PciCommonHeader;
61 import org.onap.policy.sdnr.PciMessage;
62 import org.onap.policy.sdnr.PciRequest;
63 import org.springframework.test.util.ReflectionTestUtils;
66 private static final String POLICY_NAME = "my-policy-name";
69 private static Supplier<HttpClients> httpClientMaker;
70 private static Supplier<Simulators> simMaker;
71 private static Supplier<Topics> topicMaker;
73 private BaseTest base;
74 private LinkedList<VirtualControlLoopNotification> clMgtQueue;
75 private Queue<AppcLcmMessageWrapper> appcLcmQueue;
76 private Queue<Request> appcLegacyQueue;
77 private Queue<PciMessage> sdnrQueue;
78 private int permitCount;
79 private int finalCount;
81 private final HttpClients httpClients = mock(HttpClients.class);
82 private final Simulators simulators = mock(Simulators.class);
83 private final Topics topics = mock(Topics.class);
84 private final Listener<VirtualControlLoopNotification> policyClMgt = mock();
85 private final Listener<Request> appcClSink = mock();
86 private final Listener<AppcLcmMessageWrapper> appcLcmRead = mock();
87 private final Listener<PciMessage> sdnrClSink = mock();
88 private final DroolsController drools = mock(DroolsController.class);
89 private final ToscaPolicy policy = mock(ToscaPolicy.class);
90 private final ToscaConceptIdentifier policyIdent = mock(ToscaConceptIdentifier.class);
93 * Saves static values from the class.
95 @SuppressWarnings("unchecked")
97 public static void setUpBeforeClass() {
98 httpClientMaker = (Supplier<HttpClients>) ReflectionTestUtils.getField(BaseTest.class, "httpClientMaker");
99 simMaker = (Supplier<Simulators>) ReflectionTestUtils.getField(BaseTest.class, "simMaker");
100 topicMaker = (Supplier<Topics>) ReflectionTestUtils.getField(BaseTest.class, "topicMaker");
104 * Restores static values.
107 public static void tearDownAfterClass() {
108 ReflectionTestUtils.setField(BaseTest.class, "httpClientMaker", httpClientMaker);
109 ReflectionTestUtils.setField(BaseTest.class, "simMaker", simMaker);
110 ReflectionTestUtils.setField(BaseTest.class, "topicMaker", topicMaker);
117 public void setUp() {
118 when(topics.createListener(eq(BaseTest.POLICY_CL_MGT_TOPIC), eq(VirtualControlLoopNotification.class),
119 any(StandardCoder.class))).thenReturn(policyClMgt);
120 when(topics.createListener(eq(BaseTest.APPC_LCM_READ_TOPIC), eq(AppcLcmMessageWrapper.class),
121 any(StandardCoder.class))).thenReturn(appcLcmRead);
122 when(topics.createListener(eq(BaseTest.APPC_CL_TOPIC), eq(Request.class),
123 any(StandardCoderInstantAsMillis.class))).thenReturn(appcClSink);
124 when(topics.createListener(eq(BaseTest.SDNR_CL_TOPIC), eq(PciMessage.class), any(StandardCoder.class)))
125 .thenReturn(sdnrClSink);
127 Supplier<HttpClients> httpClientMaker = this::makeHttpClients;
128 Supplier<Simulators> simMaker = this::makeSim;
129 Supplier<Topics> topicMaker = this::makeTopics;
131 ReflectionTestUtils.setField(BaseTest.class, "httpClientMaker", httpClientMaker);
132 ReflectionTestUtils.setField(BaseTest.class, "simMaker", simMaker);
133 ReflectionTestUtils.setField(BaseTest.class, "topicMaker", topicMaker);
135 clMgtQueue = new LinkedList<>();
136 appcLcmQueue = new LinkedList<>();
137 appcLegacyQueue = new LinkedList<>();
138 sdnrQueue = new LinkedList<>();
140 when(policyClMgt.await(any())).thenAnswer(args -> {
141 VirtualControlLoopNotification notif = clMgtQueue.remove();
142 Predicate<VirtualControlLoopNotification> pred = args.getArgument(0);
143 assertTrue(pred.test(notif));
147 when(appcLcmRead.await(any())).thenAnswer(args -> {
148 AppcLcmMessageWrapper req = appcLcmQueue.remove();
149 Predicate<AppcLcmMessageWrapper> pred = args.getArgument(0);
150 assertTrue(pred.test(req));
154 when(appcClSink.await(any())).thenAnswer(args -> {
155 Request req = appcLegacyQueue.remove();
156 Predicate<Request> pred = args.getArgument(0);
157 assertTrue(pred.test(req));
161 when(sdnrClSink.await(any())).thenAnswer(args -> {
162 PciMessage pcireq = sdnrQueue.remove();
163 Predicate<PciMessage> pred = args.getArgument(0);
164 assertTrue(pred.test(pcireq));
173 BaseTest.initStatics();
178 void testInitStatics() {
179 assertSame(httpClients, BaseTest.httpClients);
180 assertSame(simulators, BaseTest.simulators);
184 void testFinishStatics() {
185 BaseTest.finishStatics();
186 verify(httpClients).destroy();
187 verify(simulators).destroy();
192 assertSame(topics, BaseTest.getTopics());
198 verify(topics).destroy();
202 void testTestService123Compliant() {
203 enqueueAppcLcm("restart", "restart", "restart", "restart", "rebuild", "migrate");
204 enqueueClMgt(ControlLoopNotificationType.OPERATION_SUCCESS);
205 enqueueClMgt(ControlLoopNotificationType.FINAL_SUCCESS);
207 base.testService123Compliant();
209 assertEquals(1, permitCount);
210 assertEquals(1, finalCount);
212 assertTrue(appcLcmQueue.isEmpty());
213 assertTrue(clMgtQueue.isEmpty());
216 verify(topics).inject(eq(BaseTest.DCAE_TOPIC), any());
218 // replies to each APPC request
219 verify(topics, times(6)).inject(eq(BaseTest.APPC_LCM_WRITE_TOPIC), any(), any());
223 void testTestDuplicatesEvents() {
224 // the test expects the count to be incremented by 2 between calls
225 var count = new AtomicLong(5);
227 when(base.getCreateCount()).thenAnswer(args -> count.getAndAdd(2));
229 enqueueAppcLcm("restart", "restart");
230 enqueueClMgt(ControlLoopNotificationType.FINAL_SUCCESS);
231 enqueueClMgt(ControlLoopNotificationType.FINAL_SUCCESS);
233 clMgtQueue.get(0).setAai(Map.of("generic-vnf.vnf-id", "duplicate-VNF"));
234 clMgtQueue.get(1).setAai(Map.of("generic-vnf.vnf-id", "vCPE_Infrastructure_vGMUX_demo_app"));
236 base.testDuplicatesEvents();
238 assertEquals(0, permitCount);
239 assertEquals(2, finalCount);
241 assertTrue(appcLcmQueue.isEmpty());
242 assertTrue(clMgtQueue.isEmpty());
245 verify(topics).inject(eq(BaseTest.DCAE_TOPIC), any());
246 verify(topics, times(2)).inject(eq(BaseTest.DCAE_TOPIC), any(), any());
249 verify(topics, times(2)).inject(eq(BaseTest.APPC_LCM_WRITE_TOPIC), any(), any());
253 void testTestVcpeSunnyDayCompliant() {
254 checkAppcLcmPolicy("restart", base::testVcpeSunnyDayCompliant);
258 void testTestVcpeOnsetFloodPrevention() {
259 enqueueAppcLcm("restart");
260 enqueueClMgt(ControlLoopNotificationType.OPERATION_SUCCESS);
261 enqueueClMgt(ControlLoopNotificationType.FINAL_SUCCESS);
263 base.testVcpeOnsetFloodPrevention();
265 assertEquals(1, permitCount);
266 assertEquals(1, finalCount);
268 assertTrue(appcLcmQueue.isEmpty());
269 assertTrue(clMgtQueue.isEmpty());
272 verify(topics, times(3)).inject(eq(BaseTest.DCAE_TOPIC), any());
275 verify(topics).inject(eq(BaseTest.APPC_LCM_WRITE_TOPIC), any(), any());
279 void testTestVdnsSunnyDayCompliant() {
280 checkHttpPolicy(base::testVdnsSunnyDayCompliant);
284 void testTestVdnsRainyDayCompliant() {
285 checkHttpPolicyCompliantFailure(base::testVdnsRainyDayCompliant);
289 void testTestVfwSunnyDayCompliant() {
290 checkAppcLegacyPolicy("ModifyConfig", base::testVfwSunnyDayCompliant);
294 void testTestVfwRainyDayOverallTimeout() {
295 checkAppcLegacyPolicyFinalFailure("ModifyConfig", base::testVfwRainyDayOverallTimeout);
299 void testTestVfwRainyDayCompliantTimeout() {
300 checkAppcLegacyPolicyFinalFailure("ModifyConfig", base::testVfwRainyDayCompliantTimeout);
304 void testTestVpciSunnyDayCompliant() {
305 checkSdnrPolicy("ModifyConfig", base::testVpciSunnyDayCompliant);
309 void testTestVsonhSunnyDayCompliant() {
310 checkSdnrPolicy("ModifyConfigANR", base::testVsonhSunnyDayCompliant);
313 protected void checkAppcLcmPolicy(String operation, Runnable test) {
314 enqueueAppcLcm(operation);
315 enqueueClMgt(ControlLoopNotificationType.OPERATION_SUCCESS);
316 enqueueClMgt(ControlLoopNotificationType.FINAL_SUCCESS);
320 assertEquals(1, permitCount);
321 assertEquals(1, finalCount);
323 assertTrue(appcLcmQueue.isEmpty());
324 assertTrue(clMgtQueue.isEmpty());
327 verify(topics).inject(eq(BaseTest.DCAE_TOPIC), any());
329 // reply to each APPC request
330 verify(topics).inject(eq(BaseTest.APPC_LCM_WRITE_TOPIC), any(), any());
333 protected void checkAppcLegacyPolicy(String operation, Runnable test) {
334 enqueueAppcLegacy(operation);
335 enqueueClMgt(ControlLoopNotificationType.OPERATION_SUCCESS);
336 enqueueClMgt(ControlLoopNotificationType.FINAL_SUCCESS);
340 assertEquals(1, permitCount);
341 assertEquals(1, finalCount);
343 assertTrue(appcLcmQueue.isEmpty());
344 assertTrue(clMgtQueue.isEmpty());
347 verify(topics).inject(eq(BaseTest.DCAE_TOPIC), any());
349 // reply to each APPC request
350 verify(topics).inject(eq(BaseTest.APPC_CL_TOPIC), any(), any());
353 protected void checkAppcLegacyPolicyOperationFailure(String operation, Runnable test) {
354 enqueueAppcLegacy(operation);
355 enqueueClMgt(ControlLoopNotificationType.OPERATION_FAILURE);
356 enqueueClMgt(ControlLoopNotificationType.FINAL_FAILURE);
360 assertEquals(1, permitCount);
361 assertEquals(1, finalCount);
363 assertTrue(appcLcmQueue.isEmpty());
364 assertTrue(clMgtQueue.isEmpty());
367 verify(topics).inject(eq(BaseTest.DCAE_TOPIC), any());
369 // reply to each APPC request
370 verify(topics).inject(eq(BaseTest.APPC_CL_TOPIC), any(), any());
373 protected void checkAppcLegacyPolicyFinalFailure(String operation, Runnable test) {
374 enqueueAppcLegacy(operation);
375 enqueueClMgt(ControlLoopNotificationType.FINAL_FAILURE);
379 assertEquals(1, permitCount);
380 assertEquals(1, finalCount);
382 assertTrue(appcLcmQueue.isEmpty());
383 assertTrue(clMgtQueue.isEmpty());
386 verify(topics).inject(eq(BaseTest.DCAE_TOPIC), any());
388 // There were no requests sent
391 protected void checkSdnrPolicy(String operation, Runnable test) {
392 enqueueSdnr(operation);
393 enqueueClMgt(ControlLoopNotificationType.OPERATION_SUCCESS);
394 enqueueClMgt(ControlLoopNotificationType.FINAL_SUCCESS);
398 assertEquals(1, permitCount);
399 assertEquals(1, finalCount);
401 assertTrue(sdnrQueue.isEmpty());
402 assertTrue(clMgtQueue.isEmpty());
405 verify(topics).inject(eq(BaseTest.DCAE_TOPIC), any());
407 // reply to each SDNR request
408 verify(topics).inject(eq(BaseTest.SDNR_CL_RSP_TOPIC), any(), any());
411 protected void checkHttpPolicy(Runnable test) {
412 enqueueClMgt(ControlLoopNotificationType.OPERATION_SUCCESS);
413 enqueueClMgt(ControlLoopNotificationType.FINAL_SUCCESS);
417 assertEquals(1, permitCount);
418 assertEquals(1, finalCount);
420 assertTrue(clMgtQueue.isEmpty());
423 verify(topics).inject(eq(BaseTest.DCAE_TOPIC), any());
426 protected void checkHttpPolicyCompliantFailure(Runnable test) {
427 enqueueClMgt(ControlLoopNotificationType.OPERATION_FAILURE);
428 enqueueClMgt(ControlLoopNotificationType.FINAL_FAILURE);
432 assertEquals(1, permitCount);
433 assertEquals(1, finalCount);
435 assertTrue(clMgtQueue.isEmpty());
438 verify(topics).inject(eq(BaseTest.DCAE_TOPIC), any());
441 private void enqueueClMgt(ControlLoopNotificationType type) {
442 var notif = new VirtualControlLoopNotification();
443 notif.setNotification(type);
444 notif.setPolicyName(POLICY_NAME + ".EVENT.MANAGER.FINAL");
446 clMgtQueue.add(notif);
449 private void enqueueAppcLcm(String... operationNames) {
450 for (var oper : operationNames) {
451 var req = new AppcLcmMessageWrapper();
452 req.setRpcName(oper);
454 var body = new AppcLcmBody();
457 var input = new AppcLcmInput();
458 body.setInput(input);
460 var header = new AppcLcmCommonHeader();
461 input.setCommonHeader(header);
463 header.setSubRequestId("my-subrequest-id");
465 appcLcmQueue.add(req);
469 private void enqueueAppcLegacy(String... operationNames) {
470 for (var oper : operationNames) {
471 var req = new Request();
474 var header = new CommonHeader();
475 req.setCommonHeader(header);
477 header.setSubRequestId("my-subrequest-id");
479 appcLegacyQueue.add(req);
483 private void enqueueSdnr(String... operationNames) {
484 for (String oper : operationNames) {
485 var pcimessage = new PciMessage();
486 var req = new PciRequest();
487 var body = new PciBody();
489 pcimessage.setBody(body);
490 pcimessage.getBody().getInput().setAction(oper);
491 var header = new PciCommonHeader();
492 pcimessage.getBody().getInput().setCommonHeader(header);
494 header.setSubRequestId("my-subrequest-id");
496 sdnrQueue.add(pcimessage);
500 private HttpClients makeHttpClients() {
504 private Simulators makeSim() {
508 private Topics makeTopics() {
513 * We don't want junit trying to run this, so it's marked "Ignore".
516 private class MyTest extends BaseTest {
519 protected void waitForLockAndPermit(ToscaPolicy policy, Listener<VirtualControlLoopNotification> policyClMgt) {
524 protected VirtualControlLoopNotification waitForFinal(ToscaPolicy policy,
525 Listener<VirtualControlLoopNotification> policyClMgt, ControlLoopNotificationType finalType) {
527 return policyClMgt.await(notif -> notif.getNotification() == finalType);