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