2 * ============LICENSE_START=======================================================
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
22 package org.onap.policy.pap.main.notification;
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;
29 import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
30 import java.util.Collections;
31 import java.util.HashMap;
32 import java.util.List;
35 import lombok.NonNull;
36 import org.apache.commons.lang3.builder.CompareToBuilder;
37 import org.junit.AfterClass;
38 import org.junit.Before;
39 import org.junit.BeforeClass;
40 import org.junit.Test;
41 import org.junit.runner.RunWith;
42 import org.mockito.ArgumentCaptor;
43 import org.mockito.Captor;
44 import org.mockito.Mock;
45 import org.mockito.junit.MockitoJUnitRunner;
46 import org.onap.policy.common.utils.services.Registry;
47 import org.onap.policy.models.base.PfModelException;
48 import org.onap.policy.models.pap.concepts.PolicyNotification;
49 import org.onap.policy.models.pap.concepts.PolicyStatus;
50 import org.onap.policy.models.pdp.concepts.PdpPolicyStatus;
51 import org.onap.policy.models.pdp.concepts.PdpPolicyStatus.PdpPolicyStatusBuilder;
52 import org.onap.policy.models.pdp.concepts.PdpPolicyStatus.State;
53 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
54 import org.onap.policy.pap.main.PapConstants;
55 import org.onap.policy.pap.main.notification.StatusAction.Action;
56 import org.onap.policy.pap.main.service.PolicyStatusService;
58 @RunWith(MockitoJUnitRunner.class)
59 public class DeploymentStatusTest {
61 private static final String VERSION = "1.2.3";
62 private static final @NonNull String GROUP_A = "groupA";
63 private static final String PDP_A = "pdpA";
64 private static final String PDP_B = "pdpB";
65 private static final String PDP_C = "pdpC";
66 private static final String PDP_D = "pdpD";
67 private static final String PDP_TYPE = "MyPdpType";
68 private static final ToscaConceptIdentifier POLICY_A = new ToscaConceptIdentifier("MyPolicyA", VERSION);
69 private static final ToscaConceptIdentifier POLICY_B = new ToscaConceptIdentifier("MyPolicyB", VERSION);
70 private static final ToscaConceptIdentifier POLICY_C = new ToscaConceptIdentifier("MyPolicyC", VERSION);
71 private static final ToscaConceptIdentifier POLICY_D = new ToscaConceptIdentifier("MyPolicyD", VERSION);
72 private static final ToscaConceptIdentifier POLICY_TYPE = new ToscaConceptIdentifier("MyPolicyType", VERSION);
74 private PdpPolicyStatusBuilder builder;
77 private ArgumentCaptor<List<PdpPolicyStatus>> created;
79 private ArgumentCaptor<List<PdpPolicyStatus>> updated;
81 private ArgumentCaptor<List<PdpPolicyStatus>> deleted;
84 private PolicyStatusService policyStatusService;
86 private DeploymentStatus tracker;
89 * Set up the meter registry for tests.
92 public static void setUpBeforeClass() {
93 Registry.registerOrReplace(PapConstants.REG_METER_REGISTRY, new SimpleMeterRegistry());
97 * Tear down the meter registry after tests.
100 public static void tearDownAfterClass() {
101 Registry.unregister(PapConstants.REG_METER_REGISTRY);
108 public void setUp() {
109 tracker = new DeploymentStatus(policyStatusService);
112 builder = PdpPolicyStatus.builder()
117 .policyType(POLICY_TYPE)
119 .state(State.SUCCESS);
125 public void testAddNotifications() {
126 PdpPolicyStatus create = builder.pdpId("created").state(State.FAILURE).build();
127 PdpPolicyStatus update = builder.pdpId("updated").state(State.SUCCESS).build();
128 PdpPolicyStatus delete = builder.pdpId("deleted").state(State.SUCCESS).build();
129 PdpPolicyStatus unchange = builder.pdpId("unchanged").state(State.FAILURE).build();
132 tracker.getRecordMap().putAll(makeMap(
133 Action.CREATED, create,
134 Action.UPDATED, update,
135 Action.DELETED, delete,
136 Action.UNCHANGED, unchange
140 PolicyNotification notif = new PolicyNotification();
142 tracker.addNotifications(notif);
143 assertThat(notif.getAdded()).hasSize(1);
144 assertThat(notif.getDeleted()).isEmpty();
146 PolicyStatus status = notif.getAdded().get(0);
147 assertThat(status.getFailureCount()).isEqualTo(2);
148 assertThat(status.getIncompleteCount()).isZero();
149 assertThat(status.getSuccessCount()).isEqualTo(1);
150 assertThat(status.getPolicy()).isEqualTo(POLICY_A);
151 assertThat(status.getPolicyType()).isEqualTo(POLICY_TYPE);
154 * repeat - should be no notifications
156 notif = new PolicyNotification();
157 tracker.addNotifications(notif);
158 assertThat(notif.getAdded()).isEmpty();
159 assertThat(notif.getDeleted()).isEmpty();
163 public void testLoadByGroup() throws PfModelException {
164 PdpPolicyStatus status1 = builder.build();
165 PdpPolicyStatus status2 = builder.policy(POLICY_B).build();
166 PdpPolicyStatus status3 = builder.policy(POLICY_A).pdpId(PDP_B).build();
168 when(policyStatusService.getGroupPolicyStatus(GROUP_A)).thenReturn(List.of(status1, status2, status3));
170 tracker.loadByGroup(GROUP_A);
173 assertThat(tracker.getRecordMap()).isEqualTo(makeMap(
174 Action.UNCHANGED, status1,
175 Action.UNCHANGED, status2,
176 Action.UNCHANGED, status3
180 // try again - should not reload
181 tracker.loadByGroup(GROUP_A);
182 verify(policyStatusService).getGroupPolicyStatus(anyString());
186 public void testFlushPdpNotification() {
187 PdpPolicyStatus create = builder.pdpId("created").state(State.FAILURE).build();
188 tracker.getRecordMap().putAll(makeMap(Action.CREATED, create));
190 PolicyNotification notif = new PolicyNotification();
192 tracker.flush(notif);
194 assertThat(notif.getAdded()).hasSize(1);
195 assertThat(notif.getDeleted()).isEmpty();
199 public void testFlush() throws PfModelException {
200 PdpPolicyStatus create1 = builder.pdpId("createA").build();
201 PdpPolicyStatus create2 = builder.pdpId("createB").build();
202 PdpPolicyStatus update1 = builder.pdpId("updateA").build();
203 PdpPolicyStatus update2 = builder.pdpId("updateB").build();
204 PdpPolicyStatus delete1 = builder.pdpId("deleteA").build();
205 PdpPolicyStatus delete2 = builder.pdpId("deleteB").build();
206 PdpPolicyStatus unchange1 = builder.pdpId("unchangeA").build();
207 PdpPolicyStatus unchange2 = builder.pdpId("unchangeB").build();
210 tracker.getRecordMap().putAll(makeMap(
211 Action.CREATED, create1,
212 Action.CREATED, create2,
213 Action.UPDATED, update1,
214 Action.UPDATED, update2,
215 Action.DELETED, delete1,
216 Action.DELETED, delete2,
217 Action.UNCHANGED, unchange1,
218 Action.UNCHANGED, unchange2
224 verify(policyStatusService).cudPolicyStatus(created.capture(), updated.capture(), deleted.capture());
226 assertThat(sort(created.getValue())).isEqualTo(List.of(create1, create2));
227 assertThat(sort(updated.getValue())).isEqualTo(List.of(update1, update2));
228 assertThat(sort(deleted.getValue())).isEqualTo(List.of(delete1, delete2));
231 assertThat(tracker.getRecordMap()).isEqualTo(makeMap(
232 Action.UNCHANGED, create1,
233 Action.UNCHANGED, create2,
234 Action.UNCHANGED, update1,
235 Action.UNCHANGED, update2,
236 Action.UNCHANGED, unchange1,
237 Action.UNCHANGED, unchange2
243 public void testDeleteUndeployments() {
244 builder.deploy(true);
245 PdpPolicyStatus delete = builder.policy(POLICY_A).build();
246 PdpPolicyStatus deployedComplete = builder.policy(POLICY_B).build();
248 builder.deploy(false);
249 PdpPolicyStatus undepComplete1 = builder.policy(POLICY_C).build();
250 PdpPolicyStatus undepIncomplete1 = builder.policy(POLICY_D).build();
252 builder.pdpId(PDP_B);
253 PdpPolicyStatus undepComplete2 = builder.policy(POLICY_C).build();
254 PdpPolicyStatus undepIncomplete2 = builder.policy(POLICY_D).state(State.WAITING).build();
257 Map<StatusKey, StatusAction> map = makeMap(
258 Action.DELETED, delete,
259 Action.UNCHANGED, deployedComplete,
260 Action.UNCHANGED, undepComplete1,
261 Action.UNCHANGED, undepComplete2,
262 Action.UNCHANGED, undepIncomplete1,
263 Action.UNCHANGED, undepIncomplete2
267 tracker.getRecordMap().putAll(map);
269 tracker.deleteUndeployments();
271 // the completed undeployments should now be marked DELETED
274 assertThat(tracker.getRecordMap()).isEqualTo(makeMap(
275 Action.DELETED, delete,
276 Action.UNCHANGED, deployedComplete,
277 Action.DELETED, undepComplete1,
278 Action.DELETED, undepComplete2,
279 Action.UNCHANGED, undepIncomplete1,
280 Action.UNCHANGED, undepIncomplete2
286 public void testDeleteDeploymentString() {
287 PdpPolicyStatus statusaa = builder.pdpId(PDP_A).policy(POLICY_A).build();
288 PdpPolicyStatus statusab = builder.pdpId(PDP_A).policy(POLICY_B).build();
289 PdpPolicyStatus statusba = builder.pdpId(PDP_B).policy(POLICY_A).build();
290 PdpPolicyStatus statuscb = builder.pdpId(PDP_C).policy(POLICY_B).build();
293 tracker.getRecordMap().putAll(makeMap(
294 Action.UNCHANGED, statusaa,
295 Action.UNCHANGED, statusab,
296 Action.UNCHANGED, statusba,
297 Action.UNCHANGED, statuscb
301 tracker.deleteDeployment(PDP_A);
304 assertThat(tracker.getRecordMap()).isEqualTo(makeMap(
305 Action.DELETED, statusaa,
306 Action.DELETED, statusab,
307 Action.UNCHANGED, statusba,
308 Action.UNCHANGED, statuscb
314 public void testDeleteDeploymentToscaConceptIdentifierBoolean() {
315 PdpPolicyStatus deploy1A = builder.policy(POLICY_A).build();
316 PdpPolicyStatus deploy2A = builder.policy(POLICY_A).pdpId(PDP_B).build();
317 PdpPolicyStatus deployB = builder.policy(POLICY_B).pdpId(PDP_A).build();
319 builder.deploy(false);
320 PdpPolicyStatus undeployA = builder.policy(POLICY_A).build();
321 PdpPolicyStatus undeployB = builder.policy(POLICY_B).build();
324 tracker.getRecordMap().putAll(makeMap(
325 Action.UNCHANGED, deploy1A,
326 Action.UNCHANGED, deploy2A,
327 Action.UNCHANGED, deployB,
328 Action.UNCHANGED, undeployA,
329 Action.UNCHANGED, undeployB
333 tracker.deleteDeployment(POLICY_A, true);
336 assertThat(tracker.getRecordMap()).isEqualTo(makeMap(
337 Action.DELETED, deploy1A,
338 Action.DELETED, deploy2A,
339 Action.UNCHANGED, deployB,
340 Action.UNCHANGED, undeployA,
341 Action.UNCHANGED, undeployB
345 tracker.deleteDeployment(POLICY_B, false);
348 assertThat(tracker.getRecordMap()).isEqualTo(makeMap(
349 Action.DELETED, deploy1A,
350 Action.DELETED, deploy2A,
351 Action.UNCHANGED, deployB,
352 Action.UNCHANGED, undeployA,
353 Action.DELETED, undeployB
359 public void testDeleteDeploymentBiPredicateOfStatusKeyStatusAction() {
360 PdpPolicyStatus create1 = builder.pdpId(PDP_A).build();
361 PdpPolicyStatus delete = builder.pdpId(PDP_B).build();
362 PdpPolicyStatus update = builder.pdpId(PDP_C).build();
363 PdpPolicyStatus unchange = builder.pdpId(PDP_D).build();
365 PdpPolicyStatus create2 = builder.pdpId(PDP_B).build();
368 tracker.getRecordMap().putAll(makeMap(
369 Action.CREATED, create1,
370 Action.CREATED, create2,
371 Action.DELETED, delete,
372 Action.UPDATED, update,
373 Action.UNCHANGED, unchange
377 tracker.deleteDeployment(POLICY_A, true);
380 assertThat(tracker.getRecordMap()).isEqualTo(makeMap(
381 Action.DELETED, delete,
382 Action.DELETED, update,
383 Action.DELETED, unchange
389 public void testDeploy() {
390 tracker.deploy(PDP_A, POLICY_A, POLICY_TYPE, GROUP_A, PDP_TYPE, true);
392 assertThat(tracker.getRecordMap()).hasSize(1);
394 StatusAction status2 = tracker.getRecordMap().values().iterator().next();
396 assertThat(status2.getAction()).isEqualTo(Action.CREATED);
397 assertThat(status2.getStatus().getState()).isEqualTo(State.WAITING);
398 assertThat(status2.getStatus().isDeploy()).isTrue();
401 * repeat - should be the same status
403 tracker.deploy(PDP_A, POLICY_A, POLICY_TYPE, GROUP_A, PDP_TYPE, true);
405 assertThat(tracker.getRecordMap()).hasSize(1);
406 assertThat(tracker.getRecordMap().values().iterator().next()).isSameAs(status2);
407 assertThat(status2.getAction()).isEqualTo(Action.CREATED);
408 assertThat(status2.getStatus().getState()).isEqualTo(State.WAITING);
409 assertThat(status2.getStatus().isDeploy()).isTrue();
412 * repeat, with different values - should be unchanged
414 status2.setAction(Action.UNCHANGED);
415 status2.getStatus().setDeploy(true);
416 status2.getStatus().setState(State.SUCCESS);
418 tracker.deploy(PDP_A, POLICY_A, POLICY_TYPE, GROUP_A, PDP_TYPE, true);
420 assertThat(tracker.getRecordMap()).hasSize(1);
421 assertThat(tracker.getRecordMap().values().iterator().next()).isSameAs(status2);
422 assertThat(status2.getAction()).isEqualTo(Action.UNCHANGED);
423 assertThat(status2.getStatus().getState()).isEqualTo(State.SUCCESS);
424 assertThat(status2.getStatus().isDeploy()).isTrue();
427 * incorrect "deploy" value - should update it
429 status2.setAction(Action.UNCHANGED);
430 status2.getStatus().setDeploy(true);
432 tracker.deploy(PDP_A, POLICY_A, POLICY_TYPE, GROUP_A, PDP_TYPE, false);
434 assertThat(status2.getAction()).isEqualTo(Action.UPDATED);
435 assertThat(status2.getStatus().getState()).isEqualTo(State.WAITING);
436 assertThat(status2.getStatus().isDeploy()).isFalse();
439 * marked for deletion - should reinstate it
441 status2.setAction(Action.DELETED);
442 status2.getStatus().setState(State.FAILURE);
443 status2.getStatus().setDeploy(false);
445 tracker.deploy(PDP_A, POLICY_A, POLICY_TYPE, GROUP_A, PDP_TYPE, false);
447 assertThat(status2.getAction()).isEqualTo(Action.UPDATED);
448 assertThat(status2.getStatus().getState()).isEqualTo(State.FAILURE);
449 assertThat(status2.getStatus().isDeploy()).isFalse();
453 public void testCompleteDeploy() {
454 tracker.deploy(PDP_A, POLICY_A, POLICY_TYPE, GROUP_A, PDP_TYPE, true);
455 assertThat(tracker.getRecordMap()).hasSize(1);
457 // deployed, but not expected to be deployed - record should be left as is
458 checkCompleteDeploy(true, Set.of(), Set.of(), Action.UNCHANGED, State.WAITING);
459 checkCompleteDeploy(true, Set.of(), Set.of(POLICY_A), Action.UNCHANGED, State.WAITING);
461 // expected, but not actually deployed - failure
462 checkCompleteDeploy(true, Set.of(POLICY_A), Set.of(), Action.UPDATED, State.FAILURE);
464 // expected and actually deployed - success
465 checkCompleteDeploy(true, Set.of(POLICY_A), Set.of(POLICY_A), Action.UPDATED, State.SUCCESS);
466 checkCompleteDeploy(true, Set.of(POLICY_A, POLICY_B), Set.of(POLICY_A), Action.UPDATED, State.SUCCESS);
468 // not expected and not actually deployed - success
469 checkCompleteDeploy(false, Set.of(), Set.of(), Action.UPDATED, State.SUCCESS);
471 // not expected, but actually deployed - failure
472 checkCompleteDeploy(false, Set.of(), Set.of(POLICY_A), Action.UPDATED, State.FAILURE);
474 // undeployed, but expected to be deployed - record should be left as is
475 checkCompleteDeploy(false, Set.of(POLICY_A), Set.of(), Action.UNCHANGED, State.WAITING);
476 checkCompleteDeploy(false, Set.of(POLICY_A), Set.of(POLICY_A), Action.UNCHANGED, State.WAITING);
477 checkCompleteDeploy(false, Set.of(POLICY_A, POLICY_B), Set.of(POLICY_A), Action.UNCHANGED, State.WAITING);
480 * Try a case where the state is already correct.
482 StatusAction status = tracker.getRecordMap().values().iterator().next();
483 status.getStatus().setDeploy(false);
484 status.setAction(Action.UNCHANGED);
485 status.getStatus().setState(State.SUCCESS);
487 tracker.completeDeploy(PDP_A, Set.of(), Set.of());
489 assertThat(status.getAction()).isEqualTo(Action.UNCHANGED);
490 assertThat(status.getStatus().getState()).isEqualTo(State.SUCCESS);
493 * Try a case where the PDP does not match the record.
495 status.getStatus().setDeploy(false);
496 status.setAction(Action.UNCHANGED);
497 status.getStatus().setState(State.WAITING);
499 tracker.completeDeploy(PDP_B, Set.of(), Set.of());
501 assertThat(status.getAction()).isEqualTo(Action.UNCHANGED);
502 assertThat(status.getStatus().getState()).isEqualTo(State.WAITING);
505 private void checkCompleteDeploy(boolean deploy, Set<ToscaConceptIdentifier> expected,
506 Set<ToscaConceptIdentifier> actual, Action action, State state) {
508 StatusAction status = tracker.getRecordMap().values().iterator().next();
509 status.getStatus().setDeploy(deploy);
510 status.setAction(Action.UNCHANGED);
511 status.getStatus().setState(State.WAITING);
513 tracker.completeDeploy(PDP_A, expected, actual);
515 assertThat(status.getAction()).isEqualTo(action);
516 assertThat(status.getStatus().getState()).isEqualTo(state);
519 private List<PdpPolicyStatus> sort(List<PdpPolicyStatus> list) {
521 Collections.sort(list, (rec1, rec2) -> {
524 return new CompareToBuilder()
525 .append(rec1.getPdpId(), rec2.getPdpId())
526 .append(rec1.getPolicy(), rec2.getPolicy())
537 * @param data pairs of (Action, PdpPolicyStatus)
538 * @return a new map containing the given data
540 private Map<StatusKey, StatusAction> makeMap(Object... data) {
541 Map<StatusKey, StatusAction> map = new HashMap<>();
543 assert (data.length % 2 == 0);
545 for (int idata = 0; idata < data.length; idata += 2) {
546 Action action = (Action) data[idata];
547 PdpPolicyStatus status = (PdpPolicyStatus) data[idata + 1];
548 map.put(new StatusKey(status), new StatusAction(action, status));