Java 17 / Spring 6 / Spring Boot 3 Upgrade
[policy/pap.git] / main / src / test / java / org / onap / policy / pap / main / notification / DeploymentStatusTest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP
4  * ================================================================================
5  * Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
6  * Modifications Copyright (C) 2022 Bell Canada. All rights reserved.
7  * Modifications Copyright (C) 2023 Nordix Foundation.
8  * ================================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.policy.pap.main.notification;
24
25 import static org.assertj.core.api.Assertions.assertThat;
26 import static org.mockito.ArgumentMatchers.anyString;
27 import static org.mockito.Mockito.verify;
28 import static org.mockito.Mockito.when;
29
30 import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
31 import java.util.HashMap;
32 import java.util.List;
33 import java.util.Map;
34 import java.util.Set;
35 import lombok.NonNull;
36 import org.apache.commons.lang3.builder.CompareToBuilder;
37 import org.junit.jupiter.api.AfterAll;
38 import org.junit.jupiter.api.AfterEach;
39 import org.junit.jupiter.api.BeforeAll;
40 import org.junit.jupiter.api.BeforeEach;
41 import org.junit.jupiter.api.Test;
42 import org.mockito.ArgumentCaptor;
43 import org.mockito.Captor;
44 import org.mockito.Mock;
45 import org.mockito.MockitoAnnotations;
46 import org.onap.policy.common.utils.services.Registry;
47 import org.onap.policy.models.pap.concepts.PolicyNotification;
48 import org.onap.policy.models.pap.concepts.PolicyStatus;
49 import org.onap.policy.models.pdp.concepts.PdpPolicyStatus;
50 import org.onap.policy.models.pdp.concepts.PdpPolicyStatus.PdpPolicyStatusBuilder;
51 import org.onap.policy.models.pdp.concepts.PdpPolicyStatus.State;
52 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
53 import org.onap.policy.pap.main.PapConstants;
54 import org.onap.policy.pap.main.notification.StatusAction.Action;
55 import org.onap.policy.pap.main.service.PolicyStatusService;
56
57 public class DeploymentStatusTest {
58
59     private static final String VERSION = "1.2.3";
60     private static final @NonNull String GROUP_A = "groupA";
61     private static final String PDP_A = "pdpA";
62     private static final String PDP_B = "pdpB";
63     private static final String PDP_C = "pdpC";
64     private static final String PDP_D = "pdpD";
65     private static final String PDP_TYPE = "MyPdpType";
66     private static final ToscaConceptIdentifier POLICY_A = new ToscaConceptIdentifier("MyPolicyA", VERSION);
67     private static final ToscaConceptIdentifier POLICY_B = new ToscaConceptIdentifier("MyPolicyB", VERSION);
68     private static final ToscaConceptIdentifier POLICY_C = new ToscaConceptIdentifier("MyPolicyC", VERSION);
69     private static final ToscaConceptIdentifier POLICY_D = new ToscaConceptIdentifier("MyPolicyD", VERSION);
70     private static final ToscaConceptIdentifier POLICY_TYPE = new ToscaConceptIdentifier("MyPolicyType", VERSION);
71
72     private PdpPolicyStatusBuilder builder;
73
74     @Captor
75     private ArgumentCaptor<List<PdpPolicyStatus>> created;
76     @Captor
77     private ArgumentCaptor<List<PdpPolicyStatus>> updated;
78     @Captor
79     private ArgumentCaptor<List<PdpPolicyStatus>> deleted;
80
81     @Mock
82     private PolicyStatusService policyStatusService;
83
84     private DeploymentStatus tracker;
85
86     AutoCloseable autoCloseable;
87
88     /**
89      * Set up the meter registry for tests.
90      */
91     @BeforeAll
92     public static void setUpBeforeClass() {
93         Registry.registerOrReplace(PapConstants.REG_METER_REGISTRY, new SimpleMeterRegistry());
94     }
95
96     /**
97      * Tear down the meter registry after tests.
98      */
99     @AfterAll
100     public static void tearDownAfterClass() {
101         Registry.unregister(PapConstants.REG_METER_REGISTRY);
102     }
103
104     /**
105      * Sets up.
106      */
107     @BeforeEach
108     public void setUp() {
109         autoCloseable = MockitoAnnotations.openMocks(this);
110         tracker = new DeploymentStatus(policyStatusService);
111
112         // @formatter:off
113         builder = PdpPolicyStatus.builder()
114                         .pdpGroup(GROUP_A)
115                         .pdpId(PDP_A)
116                         .pdpType(PDP_TYPE)
117                         .policy(POLICY_A)
118                         .policyType(POLICY_TYPE)
119                         .deploy(true)
120                         .state(State.SUCCESS);
121         // @formatter:on
122
123     }
124
125     @AfterEach
126     void tearDown() throws Exception {
127         autoCloseable.close();
128     }
129
130     @Test
131     void testAddNotifications() {
132         PdpPolicyStatus create = builder.pdpId("created").state(State.FAILURE).build();
133         PdpPolicyStatus update = builder.pdpId("updated").state(State.SUCCESS).build();
134         PdpPolicyStatus delete = builder.pdpId("deleted").state(State.SUCCESS).build();
135         PdpPolicyStatus unchange = builder.pdpId("unchanged").state(State.FAILURE).build();
136
137         // @formatter:off
138         tracker.getRecordMap().putAll(makeMap(
139                         Action.CREATED, create,
140                         Action.UPDATED, update,
141                         Action.DELETED, delete,
142                         Action.UNCHANGED, unchange
143                         ));
144         // @formatter:on
145
146         PolicyNotification notif = new PolicyNotification();
147
148         tracker.addNotifications(notif);
149         assertThat(notif.getAdded()).hasSize(1);
150         assertThat(notif.getDeleted()).isEmpty();
151
152         PolicyStatus status = notif.getAdded().get(0);
153         assertThat(status.getFailureCount()).isEqualTo(2);
154         assertThat(status.getIncompleteCount()).isZero();
155         assertThat(status.getSuccessCount()).isEqualTo(1);
156         assertThat(status.getPolicy()).isEqualTo(POLICY_A);
157         assertThat(status.getPolicyType()).isEqualTo(POLICY_TYPE);
158
159         /*
160          * repeat - should be no notifications
161          */
162         notif = new PolicyNotification();
163         tracker.addNotifications(notif);
164         assertThat(notif.getAdded()).isEmpty();
165         assertThat(notif.getDeleted()).isEmpty();
166     }
167
168     @Test
169     void testLoadByGroup() {
170         PdpPolicyStatus status1 = builder.build();
171         PdpPolicyStatus status2 = builder.policy(POLICY_B).build();
172         PdpPolicyStatus status3 = builder.policy(POLICY_A).pdpId(PDP_B).build();
173
174         when(policyStatusService.getGroupPolicyStatus(GROUP_A)).thenReturn(List.of(status1, status2, status3));
175
176         tracker.loadByGroup(GROUP_A);
177
178         // @formatter:off
179         assertThat(tracker.getRecordMap()).isEqualTo(makeMap(
180             Action.UNCHANGED, status1,
181             Action.UNCHANGED, status2,
182             Action.UNCHANGED, status3
183             ));
184         // @formatter:on
185
186         // try again - should not reload
187         tracker.loadByGroup(GROUP_A);
188         verify(policyStatusService).getGroupPolicyStatus(anyString());
189     }
190
191     @Test
192     void testFlushPdpNotification() {
193         PdpPolicyStatus create = builder.pdpId("created").state(State.FAILURE).build();
194         tracker.getRecordMap().putAll(makeMap(Action.CREATED, create));
195
196         PolicyNotification notif = new PolicyNotification();
197
198         tracker.flush(notif);
199
200         assertThat(notif.getAdded()).hasSize(1);
201         assertThat(notif.getDeleted()).isEmpty();
202     }
203
204     @Test
205     void testFlush() {
206         PdpPolicyStatus create1 = builder.pdpId("createA").build();
207         PdpPolicyStatus create2 = builder.pdpId("createB").build();
208         PdpPolicyStatus update1 = builder.pdpId("updateA").build();
209         PdpPolicyStatus update2 = builder.pdpId("updateB").build();
210         PdpPolicyStatus delete1 = builder.pdpId("deleteA").build();
211         PdpPolicyStatus delete2 = builder.pdpId("deleteB").build();
212         PdpPolicyStatus unchange1 = builder.pdpId("unchangeA").build();
213         PdpPolicyStatus unchange2 = builder.pdpId("unchangeB").build();
214
215         // @formatter:off
216         tracker.getRecordMap().putAll(makeMap(
217                         Action.CREATED, create1,
218                         Action.CREATED, create2,
219                         Action.UPDATED, update1,
220                         Action.UPDATED, update2,
221                         Action.DELETED, delete1,
222                         Action.DELETED, delete2,
223                         Action.UNCHANGED, unchange1,
224                         Action.UNCHANGED, unchange2
225                         ));
226         // @formatter:on
227
228         tracker.flush();
229
230         verify(policyStatusService).cudPolicyStatus(created.capture(), updated.capture(), deleted.capture());
231
232         assertThat(sort(created.getValue())).isEqualTo(List.of(create1, create2));
233         assertThat(sort(updated.getValue())).isEqualTo(List.of(update1, update2));
234         assertThat(sort(deleted.getValue())).isEqualTo(List.of(delete1, delete2));
235
236         // @formatter:off
237         assertThat(tracker.getRecordMap()).isEqualTo(makeMap(
238                         Action.UNCHANGED, create1,
239                         Action.UNCHANGED, create2,
240                         Action.UNCHANGED, update1,
241                         Action.UNCHANGED, update2,
242                         Action.UNCHANGED, unchange1,
243                         Action.UNCHANGED, unchange2
244                         ));
245         // @formatter:on
246     }
247
248     @Test
249     void testDeleteUndeployments() {
250         builder.deploy(true);
251         PdpPolicyStatus delete = builder.policy(POLICY_A).build();
252         PdpPolicyStatus deployedComplete = builder.policy(POLICY_B).build();
253
254         builder.deploy(false);
255         PdpPolicyStatus undepComplete1 = builder.policy(POLICY_C).build();
256         PdpPolicyStatus undepIncomplete1 = builder.policy(POLICY_D).build();
257
258         builder.pdpId(PDP_B);
259         PdpPolicyStatus undepComplete2 = builder.policy(POLICY_C).build();
260         PdpPolicyStatus undepIncomplete2 = builder.policy(POLICY_D).state(State.WAITING).build();
261
262         // @formatter:off
263         Map<StatusKey, StatusAction> map = makeMap(
264                         Action.DELETED, delete,
265                         Action.UNCHANGED, deployedComplete,
266                         Action.UNCHANGED, undepComplete1,
267                         Action.UNCHANGED, undepComplete2,
268                         Action.UNCHANGED, undepIncomplete1,
269                         Action.UNCHANGED, undepIncomplete2
270                         );
271         // @formatter:on
272
273         tracker.getRecordMap().putAll(map);
274
275         tracker.deleteUndeployments();
276
277         // the completed undeployments should now be marked DELETED
278
279         // @formatter:off
280         assertThat(tracker.getRecordMap()).isEqualTo(makeMap(
281                         Action.DELETED, delete,
282                         Action.UNCHANGED, deployedComplete,
283                         Action.DELETED, undepComplete1,
284                         Action.DELETED, undepComplete2,
285                         Action.UNCHANGED, undepIncomplete1,
286                         Action.UNCHANGED, undepIncomplete2
287                         ));
288         // @formatter:on
289     }
290
291     @Test
292     void testDeleteDeploymentString() {
293         PdpPolicyStatus statusaa = builder.pdpId(PDP_A).policy(POLICY_A).build();
294         PdpPolicyStatus statusab = builder.pdpId(PDP_A).policy(POLICY_B).build();
295         PdpPolicyStatus statusba = builder.pdpId(PDP_B).policy(POLICY_A).build();
296         PdpPolicyStatus statuscb = builder.pdpId(PDP_C).policy(POLICY_B).build();
297
298         // @formatter:off
299         tracker.getRecordMap().putAll(makeMap(
300                         Action.UNCHANGED, statusaa,
301                         Action.UNCHANGED, statusab,
302                         Action.UNCHANGED, statusba,
303                         Action.UNCHANGED, statuscb
304                         ));
305         // @formatter:on
306
307         tracker.deleteDeployment(PDP_A);
308
309         // @formatter:off
310         assertThat(tracker.getRecordMap()).isEqualTo(makeMap(
311                         Action.DELETED, statusaa,
312                         Action.DELETED, statusab,
313                         Action.UNCHANGED, statusba,
314                         Action.UNCHANGED, statuscb
315                         ));
316         // @formatter:on
317     }
318
319     @Test
320     void testDeleteDeploymentToscaConceptIdentifierBoolean() {
321         PdpPolicyStatus deploy1A = builder.policy(POLICY_A).build();
322         PdpPolicyStatus deploy2A = builder.policy(POLICY_A).pdpId(PDP_B).build();
323         PdpPolicyStatus deployB = builder.policy(POLICY_B).pdpId(PDP_A).build();
324
325         builder.deploy(false);
326         PdpPolicyStatus undeployA = builder.policy(POLICY_A).build();
327         PdpPolicyStatus undeployB = builder.policy(POLICY_B).build();
328
329         // @formatter:off
330         tracker.getRecordMap().putAll(makeMap(
331                         Action.UNCHANGED, deploy1A,
332                         Action.UNCHANGED, deploy2A,
333                         Action.UNCHANGED, deployB,
334                         Action.UNCHANGED, undeployA,
335                         Action.UNCHANGED, undeployB
336                         ));
337         // @formatter:on
338
339         tracker.deleteDeployment(POLICY_A, true);
340
341         // @formatter:off
342         assertThat(tracker.getRecordMap()).isEqualTo(makeMap(
343                         Action.DELETED, deploy1A,
344                         Action.DELETED, deploy2A,
345                         Action.UNCHANGED, deployB,
346                         Action.UNCHANGED, undeployA,
347                         Action.UNCHANGED, undeployB
348                         ));
349         // @formatter:on
350
351         tracker.deleteDeployment(POLICY_B, false);
352
353         // @formatter:off
354         assertThat(tracker.getRecordMap()).isEqualTo(makeMap(
355                         Action.DELETED, deploy1A,
356                         Action.DELETED, deploy2A,
357                         Action.UNCHANGED, deployB,
358                         Action.UNCHANGED, undeployA,
359                         Action.DELETED, undeployB
360                         ));
361         // @formatter:on
362     }
363
364     @Test
365     void testDeleteDeploymentBiPredicateOfStatusKeyStatusAction() {
366         PdpPolicyStatus create1 = builder.pdpId(PDP_A).build();
367         PdpPolicyStatus delete = builder.pdpId(PDP_B).build();
368         PdpPolicyStatus update = builder.pdpId(PDP_C).build();
369         PdpPolicyStatus unchange = builder.pdpId(PDP_D).build();
370
371         PdpPolicyStatus create2 = builder.pdpId(PDP_B).build();
372
373         // @formatter:off
374         tracker.getRecordMap().putAll(makeMap(
375                         Action.CREATED, create1,
376                         Action.CREATED, create2,
377                         Action.DELETED, delete,
378                         Action.UPDATED, update,
379                         Action.UNCHANGED, unchange
380                         ));
381         // @formatter:on
382
383         tracker.deleteDeployment(POLICY_A, true);
384
385         // @formatter:off
386         assertThat(tracker.getRecordMap()).isEqualTo(makeMap(
387                         Action.DELETED, delete,
388                         Action.DELETED, update,
389                         Action.DELETED, unchange
390                         ));
391         // @formatter:on
392     }
393
394     @Test
395     void testDeploy() {
396         tracker.deploy(PDP_A, POLICY_A, POLICY_TYPE, GROUP_A, PDP_TYPE, true);
397
398         assertThat(tracker.getRecordMap()).hasSize(1);
399
400         StatusAction status2 = tracker.getRecordMap().values().iterator().next();
401
402         assertThat(status2.getAction()).isEqualTo(Action.CREATED);
403         assertThat(status2.getStatus().getState()).isEqualTo(State.WAITING);
404         assertThat(status2.getStatus().isDeploy()).isTrue();
405
406         /*
407          * repeat - should be the same status
408          */
409         tracker.deploy(PDP_A, POLICY_A, POLICY_TYPE, GROUP_A, PDP_TYPE, true);
410
411         assertThat(tracker.getRecordMap()).hasSize(1);
412         assertThat(tracker.getRecordMap().values().iterator().next()).isSameAs(status2);
413         assertThat(status2.getAction()).isEqualTo(Action.CREATED);
414         assertThat(status2.getStatus().getState()).isEqualTo(State.WAITING);
415         assertThat(status2.getStatus().isDeploy()).isTrue();
416
417         /*
418          * repeat, with different values - should be unchanged
419          */
420         status2.setAction(Action.UNCHANGED);
421         status2.getStatus().setDeploy(true);
422         status2.getStatus().setState(State.SUCCESS);
423
424         tracker.deploy(PDP_A, POLICY_A, POLICY_TYPE, GROUP_A, PDP_TYPE, true);
425
426         assertThat(tracker.getRecordMap()).hasSize(1);
427         assertThat(tracker.getRecordMap().values().iterator().next()).isSameAs(status2);
428         assertThat(status2.getAction()).isEqualTo(Action.UNCHANGED);
429         assertThat(status2.getStatus().getState()).isEqualTo(State.SUCCESS);
430         assertThat(status2.getStatus().isDeploy()).isTrue();
431
432         /*
433          * incorrect "deploy" value - should update it
434          */
435         status2.setAction(Action.UNCHANGED);
436         status2.getStatus().setDeploy(true);
437
438         tracker.deploy(PDP_A, POLICY_A, POLICY_TYPE, GROUP_A, PDP_TYPE, false);
439
440         assertThat(status2.getAction()).isEqualTo(Action.UPDATED);
441         assertThat(status2.getStatus().getState()).isEqualTo(State.WAITING);
442         assertThat(status2.getStatus().isDeploy()).isFalse();
443
444         /*
445          * marked for deletion - should reinstate it
446          */
447         status2.setAction(Action.DELETED);
448         status2.getStatus().setState(State.FAILURE);
449         status2.getStatus().setDeploy(false);
450
451         tracker.deploy(PDP_A, POLICY_A, POLICY_TYPE, GROUP_A, PDP_TYPE, false);
452
453         assertThat(status2.getAction()).isEqualTo(Action.UPDATED);
454         assertThat(status2.getStatus().getState()).isEqualTo(State.FAILURE);
455         assertThat(status2.getStatus().isDeploy()).isFalse();
456     }
457
458     @Test
459     void testCompleteDeploy() {
460         tracker.deploy(PDP_A, POLICY_A, POLICY_TYPE, GROUP_A, PDP_TYPE, true);
461         assertThat(tracker.getRecordMap()).hasSize(1);
462
463         // deployed, but not expected to be deployed - record should be left as is
464         checkCompleteDeploy(true, Set.of(), Set.of(), Action.UNCHANGED, State.WAITING);
465         checkCompleteDeploy(true, Set.of(), Set.of(POLICY_A), Action.UNCHANGED, State.WAITING);
466
467         // expected, but not actually deployed - failure
468         checkCompleteDeploy(true, Set.of(POLICY_A), Set.of(), Action.UPDATED, State.FAILURE);
469
470         // expected and actually deployed - success
471         checkCompleteDeploy(true, Set.of(POLICY_A), Set.of(POLICY_A), Action.UPDATED, State.SUCCESS);
472         checkCompleteDeploy(true, Set.of(POLICY_A, POLICY_B), Set.of(POLICY_A), Action.UPDATED, State.SUCCESS);
473
474         // not expected and not actually deployed - success
475         checkCompleteDeploy(false, Set.of(), Set.of(), Action.UPDATED, State.SUCCESS);
476
477         // not expected, but actually deployed - failure
478         checkCompleteDeploy(false, Set.of(), Set.of(POLICY_A), Action.UPDATED, State.FAILURE);
479
480         // undeployed, but expected to be deployed - record should be left as is
481         checkCompleteDeploy(false, Set.of(POLICY_A), Set.of(), Action.UNCHANGED, State.WAITING);
482         checkCompleteDeploy(false, Set.of(POLICY_A), Set.of(POLICY_A), Action.UNCHANGED, State.WAITING);
483         checkCompleteDeploy(false, Set.of(POLICY_A, POLICY_B), Set.of(POLICY_A), Action.UNCHANGED, State.WAITING);
484
485         /*
486          * Try a case where the state is already correct.
487          */
488         StatusAction status = tracker.getRecordMap().values().iterator().next();
489         status.getStatus().setDeploy(false);
490         status.setAction(Action.UNCHANGED);
491         status.getStatus().setState(State.SUCCESS);
492
493         tracker.completeDeploy(PDP_A, Set.of(), Set.of());
494
495         assertThat(status.getAction()).isEqualTo(Action.UNCHANGED);
496         assertThat(status.getStatus().getState()).isEqualTo(State.SUCCESS);
497
498         /*
499          * Try a case where the PDP does not match the record.
500          */
501         status.getStatus().setDeploy(false);
502         status.setAction(Action.UNCHANGED);
503         status.getStatus().setState(State.WAITING);
504
505         tracker.completeDeploy(PDP_B, Set.of(), Set.of());
506
507         assertThat(status.getAction()).isEqualTo(Action.UNCHANGED);
508         assertThat(status.getStatus().getState()).isEqualTo(State.WAITING);
509     }
510
511     private void checkCompleteDeploy(boolean deploy, Set<ToscaConceptIdentifier> expected,
512                                      Set<ToscaConceptIdentifier> actual, Action action, State state) {
513
514         StatusAction status = tracker.getRecordMap().values().iterator().next();
515         status.getStatus().setDeploy(deploy);
516         status.setAction(Action.UNCHANGED);
517         status.getStatus().setState(State.WAITING);
518
519         tracker.completeDeploy(PDP_A, expected, actual);
520
521         assertThat(status.getAction()).isEqualTo(action);
522         assertThat(status.getStatus().getState()).isEqualTo(state);
523     }
524
525     private List<PdpPolicyStatus> sort(List<PdpPolicyStatus> list) {
526
527         list.sort((rec1, rec2) -> {
528
529             // @formatter:off
530             return new CompareToBuilder()
531                             .append(rec1.getPdpId(), rec2.getPdpId())
532                             .append(rec1.getPolicy(), rec2.getPolicy())
533                             .toComparison();
534             // @formatter:on
535         });
536
537         return list;
538     }
539
540     /**
541      * Makes a map.
542      *
543      * @param data pairs of (Action, PdpPolicyStatus)
544      * @return a new map containing the given data
545      */
546     private Map<StatusKey, StatusAction> makeMap(Object... data) {
547         Map<StatusKey, StatusAction> map = new HashMap<>();
548
549         assert (data.length % 2 == 0);
550
551         for (int idata = 0; idata < data.length; idata += 2) {
552             Action action = (Action) data[idata];
553             PdpPolicyStatus status = (PdpPolicyStatus) data[idata + 1];
554             map.put(new StatusKey(status), new StatusAction(action, status));
555         }
556
557         return map;
558     }
559 }