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