4a1cef0d920db3b8f7c0299598b53687304364c1
[policy/drools-applications.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP
4  * ================================================================================
5  * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
6  * Modifications Copyright (C) 2021 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
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
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=========================================================
20  */
21
22 package org.onap.policy.controlloop.common.rules.test;
23
24 import static org.junit.Assert.assertEquals;
25 import static org.junit.Assert.assertSame;
26 import static org.junit.Assert.assertTrue;
27 import static org.mockito.ArgumentMatchers.any;
28 import static org.mockito.ArgumentMatchers.eq;
29 import static org.mockito.Mockito.spy;
30 import static org.mockito.Mockito.times;
31 import static org.mockito.Mockito.verify;
32 import static org.mockito.Mockito.when;
33
34 import java.util.LinkedList;
35 import java.util.Map;
36 import java.util.Queue;
37 import java.util.concurrent.atomic.AtomicLong;
38 import java.util.function.Predicate;
39 import java.util.function.Supplier;
40 import org.junit.AfterClass;
41 import org.junit.Before;
42 import org.junit.BeforeClass;
43 import org.junit.Ignore;
44 import org.junit.Test;
45 import org.mockito.Mock;
46 import org.mockito.MockitoAnnotations;
47 import org.onap.policy.appc.CommonHeader;
48 import org.onap.policy.appc.Request;
49 import org.onap.policy.appclcm.AppcLcmBody;
50 import org.onap.policy.appclcm.AppcLcmCommonHeader;
51 import org.onap.policy.appclcm.AppcLcmDmaapWrapper;
52 import org.onap.policy.appclcm.AppcLcmInput;
53 import org.onap.policy.common.utils.coder.StandardCoder;
54 import org.onap.policy.common.utils.coder.StandardCoderInstantAsMillis;
55 import org.onap.policy.controlloop.ControlLoopNotificationType;
56 import org.onap.policy.controlloop.VirtualControlLoopNotification;
57 import org.onap.policy.drools.controller.DroolsController;
58 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
59 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
60 import org.onap.policy.sdnr.PciBody;
61 import org.onap.policy.sdnr.PciCommonHeader;
62 import org.onap.policy.sdnr.PciMessage;
63 import org.onap.policy.sdnr.PciRequest;
64 import org.powermock.reflect.Whitebox;
65
66 public class BaseTestTest {
67     private static final String POLICY_NAME = "my-policy-name";
68
69     // saved values
70     private static Supplier<HttpClients> httpClientMaker;
71     private static Supplier<Simulators> simMaker;
72     private static Supplier<Topics> topicMaker;
73
74     private BaseTest base;
75     private LinkedList<VirtualControlLoopNotification> clMgtQueue;
76     private Queue<AppcLcmDmaapWrapper> appcLcmQueue;
77     private Queue<Request> appcLegacyQueue;
78     private Queue<PciMessage> sdnrQueue;
79     private int permitCount;
80     private int finalCount;
81
82     @Mock
83     private HttpClients httpClients;
84     @Mock
85     private Simulators simulators;
86     @Mock
87     private Topics topics;
88     @Mock
89     private Listener<VirtualControlLoopNotification> policyClMgt;
90     @Mock
91     private Listener<Request> appcClSink;
92     @Mock
93     private Listener<AppcLcmDmaapWrapper> appcLcmRead;
94     @Mock
95     private Listener<PciMessage> sdnrClSink;
96     @Mock
97     private DroolsController drools;
98     @Mock
99     private ToscaPolicy policy;
100     @Mock
101     private ToscaConceptIdentifier policyIdent;
102
103
104     /**
105      * Saves static values from the class.
106      */
107     @BeforeClass
108     public static void setUpBeforeClass() {
109         httpClientMaker = Whitebox.getInternalState(BaseTest.class, "httpClientMaker");
110         simMaker = Whitebox.getInternalState(BaseTest.class, "simMaker");
111         topicMaker = Whitebox.getInternalState(BaseTest.class, "topicMaker");
112     }
113
114     /**
115      * Restores static values.
116      */
117     @AfterClass
118     public static void tearDownAfterClass() {
119         Whitebox.setInternalState(BaseTest.class, "httpClientMaker", httpClientMaker);
120         Whitebox.setInternalState(BaseTest.class, "simMaker", simMaker);
121         Whitebox.setInternalState(BaseTest.class, "topicMaker", topicMaker);
122     }
123
124     /**
125      * Sets up.
126      */
127     @Before
128     public void setUp() {
129         MockitoAnnotations.initMocks(this);
130
131         when(policy.getIdentifier()).thenReturn(policyIdent);
132         when(policyIdent.getName()).thenReturn(POLICY_NAME);
133
134         when(topics.createListener(eq(BaseTest.POLICY_CL_MGT_TOPIC), eq(VirtualControlLoopNotification.class),
135                         any(StandardCoder.class))).thenReturn(policyClMgt);
136         when(topics.createListener(eq(BaseTest.APPC_LCM_READ_TOPIC), eq(AppcLcmDmaapWrapper.class),
137                         any(StandardCoder.class))).thenReturn(appcLcmRead);
138         when(topics.createListener(eq(BaseTest.APPC_CL_TOPIC), eq(Request.class),
139                         any(StandardCoderInstantAsMillis.class))).thenReturn(appcClSink);
140         when(topics.createListener(eq(BaseTest.SDNR_CL_TOPIC), eq(PciMessage.class), any(StandardCoder.class)))
141                         .thenReturn(sdnrClSink);
142
143         Supplier<HttpClients> httpClientMaker = this::makeHttpClients;
144         Supplier<Simulators> simMaker = this::makeSim;
145         Supplier<Topics> topicMaker = this::makeTopics;
146
147         Whitebox.setInternalState(BaseTest.class, "httpClientMaker", httpClientMaker);
148         Whitebox.setInternalState(BaseTest.class, "simMaker", simMaker);
149         Whitebox.setInternalState(BaseTest.class, "topicMaker", topicMaker);
150
151         clMgtQueue = new LinkedList<>();
152         appcLcmQueue = new LinkedList<>();
153         appcLegacyQueue = new LinkedList<>();
154         sdnrQueue = new LinkedList<>();
155
156         when(policyClMgt.await(any())).thenAnswer(args -> {
157             VirtualControlLoopNotification notif = clMgtQueue.remove();
158             Predicate<VirtualControlLoopNotification> pred = args.getArgument(0);
159             assertTrue(pred.test(notif));
160             return notif;
161         });
162
163         when(appcLcmRead.await(any())).thenAnswer(args -> {
164             AppcLcmDmaapWrapper req = appcLcmQueue.remove();
165             Predicate<AppcLcmDmaapWrapper> pred = args.getArgument(0);
166             assertTrue(pred.test(req));
167             return req;
168         });
169
170         when(appcClSink.await(any())).thenAnswer(args -> {
171             Request req = appcLegacyQueue.remove();
172             Predicate<Request> pred = args.getArgument(0);
173             assertTrue(pred.test(req));
174             return req;
175         });
176
177         when(sdnrClSink.await(any())).thenAnswer(args -> {
178             PciMessage pcireq = sdnrQueue.remove();
179             Predicate<PciMessage> pred = args.getArgument(0);
180             assertTrue(pred.test(pcireq));
181             return pcireq;
182         });
183
184         permitCount = 0;
185         finalCount = 0;
186
187         base = new MyTest();
188
189         BaseTest.initStatics();
190         base.init();
191     }
192
193     @Test
194     public void testInitStatics() {
195         assertSame(httpClients, BaseTest.httpClients);
196         assertSame(simulators, BaseTest.simulators);
197     }
198
199     @Test
200     public void testFinishStatics() {
201         BaseTest.finishStatics();
202         verify(httpClients).destroy();
203         verify(simulators).destroy();
204     }
205
206     @Test
207     public void testInit() {
208         assertSame(topics, BaseTest.getTopics());
209     }
210
211     @Test
212     public void testFinish() {
213         base.finish();
214         verify(topics).destroy();
215     }
216
217     @Test
218     public void testTestService123Compliant() {
219         enqueueAppcLcm("restart", "restart", "restart", "restart", "rebuild", "migrate");
220         enqueueClMgt(ControlLoopNotificationType.OPERATION_SUCCESS);
221         enqueueClMgt(ControlLoopNotificationType.FINAL_SUCCESS);
222
223         base.testService123Compliant();
224
225         assertEquals(1, permitCount);
226         assertEquals(1, finalCount);
227
228         assertTrue(appcLcmQueue.isEmpty());
229         assertTrue(clMgtQueue.isEmpty());
230
231         // initial event
232         verify(topics).inject(eq(BaseTest.DCAE_TOPIC), any());
233
234         // replies to each APPC request
235         verify(topics, times(6)).inject(eq(BaseTest.APPC_LCM_WRITE_TOPIC), any(), any());
236     }
237
238     @Test
239     public void testTestDuplicatesEvents() {
240         // the test expects the count to be incremented by 2 between calls
241         AtomicLong count = new AtomicLong(5);
242         base = spy(base);
243         when(base.getCreateCount()).thenAnswer(args -> count.getAndAdd(2));
244
245         enqueueAppcLcm("restart", "restart");
246         enqueueClMgt(ControlLoopNotificationType.FINAL_SUCCESS);
247         enqueueClMgt(ControlLoopNotificationType.FINAL_SUCCESS);
248
249         clMgtQueue.get(0).setAai(Map.of("generic-vnf.vnf-id", "duplicate-VNF"));
250         clMgtQueue.get(1).setAai(Map.of("generic-vnf.vnf-id", "vCPE_Infrastructure_vGMUX_demo_app"));
251
252         base.testDuplicatesEvents();
253
254         assertEquals(0, permitCount);
255         assertEquals(2, finalCount);
256
257         assertTrue(appcLcmQueue.isEmpty());
258         assertTrue(clMgtQueue.isEmpty());
259
260         // initial events
261         verify(topics).inject(eq(BaseTest.DCAE_TOPIC), any());
262         verify(topics, times(2)).inject(eq(BaseTest.DCAE_TOPIC), any(), any());
263
264         // two restarts
265         verify(topics, times(2)).inject(eq(BaseTest.APPC_LCM_WRITE_TOPIC), any(), any());
266     }
267
268     @Test
269     public void testTestVcpeSunnyDayCompliant() {
270         checkAppcLcmPolicy("restart", base::testVcpeSunnyDayCompliant);
271     }
272
273     @Test
274     public void testTestVcpeOnsetFloodPrevention() {
275         enqueueAppcLcm("restart");
276         enqueueClMgt(ControlLoopNotificationType.OPERATION_SUCCESS);
277         enqueueClMgt(ControlLoopNotificationType.FINAL_SUCCESS);
278
279         base.testVcpeOnsetFloodPrevention();
280
281         assertEquals(1, permitCount);
282         assertEquals(1, finalCount);
283
284         assertTrue(appcLcmQueue.isEmpty());
285         assertTrue(clMgtQueue.isEmpty());
286
287         // initial events
288         verify(topics, times(3)).inject(eq(BaseTest.DCAE_TOPIC), any());
289
290         // one restart
291         verify(topics).inject(eq(BaseTest.APPC_LCM_WRITE_TOPIC), any(), any());
292     }
293
294     @Test
295     public void testTestVdnsSunnyDayCompliant() {
296         checkHttpPolicy(base::testVdnsSunnyDayCompliant);
297     }
298
299     @Test
300     public void testTestVdnsRainyDayCompliant() {
301         checkHttpPolicyCompliantFailure(base::testVdnsRainyDayCompliant);
302     }
303
304     @Test
305     public void testTestVfwSunnyDayCompliant() {
306         checkAppcLegacyPolicy("ModifyConfig", base::testVfwSunnyDayCompliant);
307     }
308
309     @Test
310     public void testTestVfwRainyDayOverallTimeout() {
311         checkAppcLegacyPolicyFinalFailure("ModifyConfig", base::testVfwRainyDayOverallTimeout);
312     }
313
314     @Test
315     public void testTestVfwRainyDayCompliantTimeout() {
316         checkAppcLegacyPolicyFinalFailure("ModifyConfig", base::testVfwRainyDayCompliantTimeout);
317     }
318
319     @Test
320     public void testTestVpciSunnyDayCompliant() {
321         checkSdnrPolicy("ModifyConfig", base::testVpciSunnyDayCompliant);
322     }
323
324     @Test
325     public void testTestVsonhSunnyDayCompliant() {
326         checkSdnrPolicy("ModifyConfigANR", base::testVsonhSunnyDayCompliant);
327     }
328
329     protected void checkAppcLcmPolicy(String operation, Runnable test) {
330         enqueueAppcLcm(operation);
331         enqueueClMgt(ControlLoopNotificationType.OPERATION_SUCCESS);
332         enqueueClMgt(ControlLoopNotificationType.FINAL_SUCCESS);
333
334         test.run();
335
336         assertEquals(1, permitCount);
337         assertEquals(1, finalCount);
338
339         assertTrue(appcLcmQueue.isEmpty());
340         assertTrue(clMgtQueue.isEmpty());
341
342         // initial event
343         verify(topics).inject(eq(BaseTest.DCAE_TOPIC), any());
344
345         // reply to each APPC request
346         verify(topics).inject(eq(BaseTest.APPC_LCM_WRITE_TOPIC), any(), any());
347     }
348
349     protected void checkAppcLegacyPolicy(String operation, Runnable test) {
350         enqueueAppcLegacy(operation);
351         enqueueClMgt(ControlLoopNotificationType.OPERATION_SUCCESS);
352         enqueueClMgt(ControlLoopNotificationType.FINAL_SUCCESS);
353
354         test.run();
355
356         assertEquals(1, permitCount);
357         assertEquals(1, finalCount);
358
359         assertTrue(appcLcmQueue.isEmpty());
360         assertTrue(clMgtQueue.isEmpty());
361
362         // initial event
363         verify(topics).inject(eq(BaseTest.DCAE_TOPIC), any());
364
365         // reply to each APPC request
366         verify(topics).inject(eq(BaseTest.APPC_CL_TOPIC), any(), any());
367     }
368
369     protected void checkAppcLegacyPolicyOperationFailure(String operation, Runnable test) {
370         enqueueAppcLegacy(operation);
371         enqueueClMgt(ControlLoopNotificationType.OPERATION_FAILURE);
372         enqueueClMgt(ControlLoopNotificationType.FINAL_FAILURE);
373
374         test.run();
375
376         assertEquals(1, permitCount);
377         assertEquals(1, finalCount);
378
379         assertTrue(appcLcmQueue.isEmpty());
380         assertTrue(clMgtQueue.isEmpty());
381
382         // initial event
383         verify(topics).inject(eq(BaseTest.DCAE_TOPIC), any());
384
385         // reply to each APPC request
386         verify(topics).inject(eq(BaseTest.APPC_CL_TOPIC), any(), any());
387     }
388
389     protected void checkAppcLegacyPolicyFinalFailure(String operation, Runnable test) {
390         enqueueAppcLegacy(operation);
391         enqueueClMgt(ControlLoopNotificationType.FINAL_FAILURE);
392
393         test.run();
394
395         assertEquals(1, permitCount);
396         assertEquals(1, finalCount);
397
398         assertTrue(appcLcmQueue.isEmpty());
399         assertTrue(clMgtQueue.isEmpty());
400
401         // initial event
402         verify(topics).inject(eq(BaseTest.DCAE_TOPIC), any());
403
404         // There were no requests sent
405     }
406
407     protected void checkSdnrPolicy(String operation, Runnable test) {
408         enqueueSdnr(operation);
409         enqueueClMgt(ControlLoopNotificationType.OPERATION_SUCCESS);
410         enqueueClMgt(ControlLoopNotificationType.FINAL_SUCCESS);
411
412         test.run();
413
414         assertEquals(1, permitCount);
415         assertEquals(1, finalCount);
416
417         assertTrue(sdnrQueue.isEmpty());
418         assertTrue(clMgtQueue.isEmpty());
419
420         // initial event
421         verify(topics).inject(eq(BaseTest.DCAE_TOPIC), any());
422
423         // reply to each SDNR request
424         verify(topics).inject(eq(BaseTest.SDNR_CL_RSP_TOPIC), any(), any());
425     }
426
427     protected void checkHttpPolicy(Runnable test) {
428         enqueueClMgt(ControlLoopNotificationType.OPERATION_SUCCESS);
429         enqueueClMgt(ControlLoopNotificationType.FINAL_SUCCESS);
430
431         test.run();
432
433         assertEquals(1, permitCount);
434         assertEquals(1, finalCount);
435
436         assertTrue(clMgtQueue.isEmpty());
437
438         // initial event
439         verify(topics).inject(eq(BaseTest.DCAE_TOPIC), any());
440     }
441
442     protected void checkHttpPolicyCompliantFailure(Runnable test) {
443         enqueueClMgt(ControlLoopNotificationType.OPERATION_FAILURE);
444         enqueueClMgt(ControlLoopNotificationType.FINAL_FAILURE);
445
446         test.run();
447
448         assertEquals(1, permitCount);
449         assertEquals(1, finalCount);
450
451         assertTrue(clMgtQueue.isEmpty());
452
453         // initial event
454         verify(topics).inject(eq(BaseTest.DCAE_TOPIC), any());
455     }
456
457     private void enqueueClMgt(ControlLoopNotificationType type) {
458         VirtualControlLoopNotification notif = new VirtualControlLoopNotification();
459         notif.setNotification(type);
460         notif.setPolicyName(POLICY_NAME + ".EVENT.MANAGER.FINAL");
461
462         clMgtQueue.add(notif);
463     }
464
465     private void enqueueAppcLcm(String... operationNames) {
466         for (String oper : operationNames) {
467             AppcLcmDmaapWrapper req = new AppcLcmDmaapWrapper();
468             req.setRpcName(oper);
469
470             AppcLcmBody body = new AppcLcmBody();
471             req.setBody(body);
472
473             AppcLcmInput input = new AppcLcmInput();
474             body.setInput(input);
475
476             AppcLcmCommonHeader header = new AppcLcmCommonHeader();
477             input.setCommonHeader(header);
478
479             header.setSubRequestId("my-subrequest-id");
480
481             appcLcmQueue.add(req);
482         }
483     }
484
485     private void enqueueAppcLegacy(String... operationNames) {
486         for (String oper : operationNames) {
487             Request req = new Request();
488             req.setAction(oper);
489
490             CommonHeader header = new CommonHeader();
491             req.setCommonHeader(header);
492
493             header.setSubRequestId("my-subrequest-id");
494
495             appcLegacyQueue.add(req);
496         }
497     }
498
499     private void enqueueSdnr(String... operationNames) {
500         for (String oper : operationNames) {
501             PciMessage pcimessage = new PciMessage();
502             PciRequest req = new PciRequest();
503             PciBody body = new PciBody();
504             body.setInput(req);
505             pcimessage.setBody(body);
506             pcimessage.getBody().getInput().setAction(oper);
507             PciCommonHeader header = new PciCommonHeader();
508             pcimessage.getBody().getInput().setCommonHeader(header);
509
510             header.setSubRequestId("my-subrequest-id");
511
512             sdnrQueue.add(pcimessage);
513         }
514     }
515
516     private HttpClients makeHttpClients() {
517         return httpClients;
518     }
519
520     private Simulators makeSim() {
521         return simulators;
522     }
523
524     private Topics makeTopics() {
525         return topics;
526     }
527
528     /*
529      * We don't want junit trying to run this, so it's marked "Ignore".
530      */
531     @Ignore
532     private class MyTest extends BaseTest {
533
534         @Override
535         protected void waitForLockAndPermit(ToscaPolicy policy, Listener<VirtualControlLoopNotification> policyClMgt) {
536             permitCount++;
537         }
538
539         @Override
540         protected VirtualControlLoopNotification waitForFinal(ToscaPolicy policy,
541                         Listener<VirtualControlLoopNotification> policyClMgt, ControlLoopNotificationType finalType) {
542             finalCount++;
543             return policyClMgt.await(notif -> notif.getNotification() == finalType);
544         }
545     }
546 }