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