2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.onap.policy.controlloop.eventmanager;
23 import static org.assertj.core.api.Assertions.assertThat;
24 import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
25 import static org.junit.Assert.assertEquals;
26 import static org.junit.Assert.assertFalse;
27 import static org.junit.Assert.assertNotNull;
28 import static org.junit.Assert.assertNull;
29 import static org.junit.Assert.assertSame;
30 import static org.junit.Assert.assertTrue;
31 import static org.mockito.ArgumentMatchers.any;
32 import static org.mockito.ArgumentMatchers.eq;
33 import static org.mockito.Mockito.doAnswer;
34 import static org.mockito.Mockito.never;
35 import static org.mockito.Mockito.times;
36 import static org.mockito.Mockito.verify;
37 import static org.mockito.Mockito.when;
39 import java.time.Instant;
41 import java.util.TreeMap;
42 import java.util.UUID;
43 import java.util.concurrent.CompletableFuture;
44 import java.util.concurrent.CountDownLatch;
45 import java.util.concurrent.TimeUnit;
46 import java.util.function.Consumer;
47 import org.junit.Before;
48 import org.junit.Test;
49 import org.mockito.ArgumentCaptor;
50 import org.mockito.Captor;
51 import org.mockito.Mock;
52 import org.mockito.MockitoAnnotations;
53 import org.onap.aai.domain.yang.GenericVnf;
54 import org.onap.policy.aai.AaiCqResponse;
55 import org.onap.policy.common.utils.time.PseudoExecutor;
56 import org.onap.policy.controlloop.ControlLoopOperation;
57 import org.onap.policy.controlloop.ControlLoopResponse;
58 import org.onap.policy.controlloop.VirtualControlLoopEvent;
59 import org.onap.policy.controlloop.actor.guard.DecisionOperation;
60 import org.onap.policy.controlloop.actor.guard.GuardActor;
61 import org.onap.policy.controlloop.actorserviceprovider.ActorService;
62 import org.onap.policy.controlloop.actorserviceprovider.Operation;
63 import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome;
64 import org.onap.policy.controlloop.actorserviceprovider.OperationResult;
65 import org.onap.policy.controlloop.actorserviceprovider.Operator;
66 import org.onap.policy.controlloop.actorserviceprovider.TargetType;
67 import org.onap.policy.controlloop.actorserviceprovider.controlloop.ControlLoopEventContext;
68 import org.onap.policy.controlloop.actorserviceprovider.parameters.ControlLoopOperationParams;
69 import org.onap.policy.controlloop.actorserviceprovider.spi.Actor;
70 import org.onap.policy.controlloop.ophistory.OperationHistoryDataManager;
71 import org.onap.policy.drools.domain.models.operational.ActorOperation;
72 import org.onap.policy.drools.domain.models.operational.OperationalTarget;
73 import org.onap.policy.sdnr.PciBody;
74 import org.onap.policy.sdnr.PciMessage;
75 import org.onap.policy.sdnr.PciResponse;
77 public class ControlLoopOperationManager2Test {
78 private static final UUID REQ_ID = UUID.randomUUID();
79 private static final String MISMATCH = "mismatch";
80 private static final String POLICY_ID = "my-policy";
81 private static final String POLICY_ACTOR = "my-actor";
82 private static final String POLICY_OPERATION = "my-operation";
83 private static final String OTHER_ACTOR = "another-actor";
84 private static final String MY_TARGET = "my-target";
85 private static final String MY_VNF_ID = "my-vnf-id";
86 private static final String PAYLOAD_KEY = "payload-key";
87 private static final String PAYLOAD_VALUE = "payload-value";
88 private static final long REMAINING_MS = 5000;
89 private static final int MAX_RUN = 100;
90 private static final Integer POLICY_RETRY = 3;
91 private static final Integer POLICY_TIMEOUT = 20;
92 private static final IllegalArgumentException EXPECTED_EXCEPTION =
93 new IllegalArgumentException("expected exception");
96 private ArgumentCaptor<Consumer<OperationOutcome>> lockCallback;
99 private OperationHistoryDataManager dataMgr;
101 private ManagerContext mgrctx;
103 private Operator policyOperator;
105 private Operation policyOperation;
107 private Actor policyActor;
109 private ActorService actors;
111 private AaiCqResponse cqdata;
113 private GenericVnf vnf;
115 private CompletableFuture<OperationOutcome> lockFuture;
116 private CompletableFuture<OperationOutcome> policyFuture;
117 private ActorOperation operation;
118 private OperationalTarget target;
119 private Map<String, String> entityIds;
120 private Map<String, String> payload;
121 private org.onap.policy.drools.domain.models.operational.Operation policy;
122 private VirtualControlLoopEvent event;
123 private ControlLoopEventContext context;
124 private PseudoExecutor executor;
125 private ControlLoopOperationManager2 mgr;
131 public void setUp() {
132 MockitoAnnotations.initMocks(this);
134 lockFuture = new CompletableFuture<>();
135 policyFuture = new CompletableFuture<>();
137 when(mgrctx.getActorService()).thenReturn(actors);
138 when(mgrctx.getDataManager()).thenReturn(dataMgr);
139 when(mgrctx.requestLock(any(), any())).thenReturn(lockFuture);
141 // configure policy operation
142 when(actors.getActor(POLICY_ACTOR)).thenReturn(policyActor);
143 when(policyActor.getOperator(POLICY_OPERATION)).thenReturn(policyOperator);
144 when(policyOperator.buildOperation(any())).thenReturn(policyOperation);
145 when(policyOperation.start()).thenReturn(policyFuture);
147 when(vnf.getVnfId()).thenReturn(MY_VNF_ID);
148 when(cqdata.getDefaultGenericVnf()).thenReturn(vnf);
150 entityIds = Map.of("entity-name-A", "entity-value-A");
152 target = OperationalTarget.builder()
153 .targetType(TargetType.VM.toString())
154 .entityIds(entityIds)
157 payload = Map.of(PAYLOAD_KEY, PAYLOAD_VALUE);
159 operation = ActorOperation.builder()
161 .operation(POLICY_OPERATION)
166 policy = org.onap.policy.drools.domain.models.operational.Operation.builder()
168 .actorOperation(operation)
169 .retries(POLICY_RETRY)
170 .timeout(POLICY_TIMEOUT)
173 event = new VirtualControlLoopEvent();
174 event.setRequestId(REQ_ID);
175 event.setTarget(ControlLoopOperationManager2.VSERVER_VSERVER_NAME);
176 event.setAai(new TreeMap<>(Map.of(ControlLoopOperationManager2.VSERVER_VSERVER_NAME, MY_TARGET)));
178 context = new ControlLoopEventContext(event);
179 context.setProperty(AaiCqResponse.CONTEXT_KEY, cqdata);
181 executor = new PseudoExecutor();
183 mgr = new ControlLoopOperationManager2(mgrctx, context, policy, executor);
187 public void testStart() {
188 mgr.start(REMAINING_MS);
190 // should have determined the target entity by now
191 assertEquals(MY_TARGET, mgr.getTargetEntity());
193 verify(mgrctx).requestLock(eq(MY_TARGET), any());
195 lockFuture.complete(new OperationOutcome());
197 policyFuture.complete(genOpOutcome());
200 assertEquals(ControlLoopOperationManager2.State.GUARD_STARTED, mgr.getState());
202 assertTrue(mgr.nextStep());
203 assertEquals(ControlLoopOperationManager2.State.GUARD_PERMITTED, mgr.getState());
205 assertTrue(mgr.nextStep());
206 assertEquals(ControlLoopOperationManager2.State.OPERATION_STARTED, mgr.getState());
208 assertTrue(mgr.nextStep());
209 assertEquals(ControlLoopOperationManager2.State.OPERATION_SUCCESS, mgr.getState());
211 assertFalse(mgr.nextStep());
213 OperationOutcome outcome = mgr.getOutcomes().peek();
214 assertEquals(OperationResult.SUCCESS, outcome.getResult());
215 assertTrue(outcome.isFinalOutcome());
217 verify(mgrctx, times(4)).updated(mgr);
221 * Tests start() when detmTarget() (i.e., the first task) throws an exception.
224 public void testStartDetmTargetException() {
225 operation.setTarget(OperationalTarget.builder().build());
226 mgr = new ControlLoopOperationManager2(mgrctx, context, policy, executor);
227 mgr.start(REMAINING_MS);
231 assertFalse(mgr.nextStep());
232 assertEquals(ControlLoopOperationManager2.State.OPERATION_FAILURE, mgr.getState());
234 // should have called update() for operation-start, but not for any nextStep()
235 verify(mgrctx).updated(mgr);
239 * Tests start() when a subsequent task throws an exception.
242 public void testStartException() {
243 when(policyOperation.start()).thenThrow(EXPECTED_EXCEPTION);
245 mgr.start(REMAINING_MS);
247 lockFuture.complete(new OperationOutcome());
250 assertFalse(mgr.nextStep());
251 assertEquals(ControlLoopOperationManager2.State.OPERATION_FAILURE, mgr.getState());
253 // should have called update() for operation-start, but not for any nextStep()
254 verify(mgrctx).updated(mgr);
258 * Tests start() when the control loop times out before the operation starts.
261 public void testStartClTimeout_testHandleTimeout() throws InterruptedException {
262 // catch the callback when it times out
263 CountDownLatch updatedLatch = new CountDownLatch(1);
265 updatedLatch.countDown();
267 }).when(mgrctx).updated(any());
269 long tstart = System.currentTimeMillis();
271 // give it a short timeout
274 assertTrue(updatedLatch.await(5, TimeUnit.SECONDS));
275 assertTrue(System.currentTimeMillis() - tstart >= 100);
277 // don't generate any responses
280 // wait for the future to be canceled, via a background thread
281 CountDownLatch futureLatch = new CountDownLatch(1);
282 mgr.getFuture().whenComplete((unused, thrown) -> futureLatch.countDown());
283 assertTrue(futureLatch.await(5, TimeUnit.SECONDS));
285 // lock should have been canceled
286 assertTrue(mgr.getFuture().isCancelled());
288 assertFalse(mgr.nextStep());
289 assertEquals(ControlLoopOperationManager2.State.CONTROL_LOOP_TIMEOUT, mgr.getState());
291 // should have called update() for operation-start, but not for any nextStep()
292 verify(mgrctx).updated(mgr);
294 // should have added a record to the DB
295 verify(dataMgr).store(any(), any(), any(), any());
299 public void testStartOperation() {
300 mgr.start(REMAINING_MS);
302 lockFuture.complete(new OperationOutcome());
306 verify(policyOperation).start();
308 ArgumentCaptor<ControlLoopOperationParams> captor = ArgumentCaptor.forClass(ControlLoopOperationParams.class);
309 verify(policyOperator).buildOperation(captor.capture());
311 ControlLoopOperationParams params = captor.getValue();
313 assertNotNull(params);
314 assertEquals(POLICY_ACTOR, params.getActor());
315 assertSame(actors, params.getActorService());
316 assertNotNull(params.getCompleteCallback());
317 assertSame(context, params.getContext());
318 assertSame(executor, params.getExecutor());
319 assertEquals(POLICY_OPERATION, params.getOperation());
320 assertEquals(payload, params.getPayload());
321 assertSame(REQ_ID, params.getRequestId());
322 assertSame(POLICY_RETRY, params.getRetry());
323 assertNotNull(params.getStartCallback());
324 assertEquals(target.getTargetType().toString(), params.getTargetType().toString());
325 assertSame(entityIds, params.getTargetEntityIds());
326 assertEquals(MY_TARGET, params.getTargetEntity());
327 assertSame(POLICY_TIMEOUT, params.getTimeoutSec());
331 public void testStartOperationNullPayload() {
332 operation.setPayload(null);
333 mgr.start(REMAINING_MS);
335 lockFuture.complete(new OperationOutcome());
339 verify(policyOperation).start();
341 ArgumentCaptor<ControlLoopOperationParams> captor = ArgumentCaptor.forClass(ControlLoopOperationParams.class);
342 verify(policyOperator).buildOperation(captor.capture());
344 ControlLoopOperationParams params = captor.getValue();
346 assertNotNull(params);
347 assertEquals(POLICY_ACTOR, params.getActor());
348 assertSame(actors, params.getActorService());
349 assertNotNull(params.getCompleteCallback());
350 assertSame(context, params.getContext());
351 assertSame(executor, params.getExecutor());
352 assertEquals(POLICY_OPERATION, params.getOperation());
353 assertTrue(params.getPayload().isEmpty());
354 assertSame(REQ_ID, params.getRequestId());
355 assertSame(POLICY_RETRY, params.getRetry());
356 assertNotNull(params.getStartCallback());
357 assertEquals(target.getTargetType().toString(), params.getTargetType().toString());
358 assertSame(entityIds, params.getTargetEntityIds());
359 assertEquals(MY_TARGET, params.getTargetEntity());
360 assertSame(POLICY_TIMEOUT, params.getTimeoutSec());
364 public void testMakeControlLoopResponse() {
365 final OperationOutcome outcome = new OperationOutcome();
366 PciMessage msg = new PciMessage();
367 outcome.setResponse(msg);
369 PciBody body = new PciBody();
372 PciResponse output = new PciResponse();
373 body.setOutput(output);
375 output.setPayload("my-payload");
378 // not an SDNR action - should return null
379 assertNull(mgr.makeControlLoopResponse(outcome));
382 * now work with SDNR actor
384 operation.setActor("SDNR");
385 mgr = new ControlLoopOperationManager2(mgrctx, context, policy, executor);
387 // should return null for a null input
388 assertNull(mgr.makeControlLoopResponse(null));
390 // should generate a response, with a payload
391 checkResp(outcome, "my-payload");
394 * these should generate a response, with null payload
396 output.setPayload(null);
397 checkResp(outcome, null);
399 body.setOutput(null);
400 checkResp(outcome, null);
403 checkResp(outcome, null);
405 outcome.setResponse(null);
406 checkResp(outcome, null);
410 public void testGetOperationMessage() {
412 assertNull(mgr.getOperationMessage());
415 assertThat(mgr.getOperationMessage()).contains("actor=my-actor").contains("operation=my-operation");
419 public void testGetOperationResult() {
421 assertNotNull(mgr.getOperationResult());
424 assertEquals(OperationResult.SUCCESS, mgr.getOperationResult());
428 * Tests getOperationResult() when it ends in a failure.
431 public void testGetOperationResultFailure() {
432 mgr.start(REMAINING_MS);
437 assertEquals(OperationResult.FAILURE_GUARD, mgr.getOperationResult());
441 * Tests handleException() when the exception is a "cancel".
444 public void testHandleExceptionCanceled() {
445 lockFuture.cancel(false);
447 mgr.start(REMAINING_MS);
451 assertTrue(mgr.nextStep());
452 assertEquals(ControlLoopOperationManager2.State.ACTIVE, mgr.getState());
456 public void testCancel() {
457 mgr.start(REMAINING_MS);
460 assertTrue(mgr.getFuture().isCancelled());
464 * Tests cancel() when the operation hasn't been started.
467 public void testCancelNotStarted() {
468 assertNull(mgr.getFuture());
471 assertNull(mgr.getFuture());
475 public void testLockUnavailable() {
476 mgr.start(REMAINING_MS);
480 // lock failure outcome
481 final OperationOutcome outcome = genLockFailure();
485 assertFalse(mgr.nextStep());
486 assertEquals(ControlLoopOperationManager2.State.LOCK_DENIED, mgr.getState());
488 assertEquals(outcome, mgr.getOutcomes().peek());
490 // should have called update() for operation-start, but not for any nextStep()
491 verify(mgrctx).updated(mgr);
495 * Tests onStart() and onComplete() with other actors.
498 public void testOnStart_testOnComplete() {
499 mgr.start(REMAINING_MS);
501 lockFuture.complete(new OperationOutcome());
504 // generate failure outcome for ANOTHER actor - should be ignored
505 OperationOutcome outcome = mgr.getParams().makeOutcome();
506 outcome.setActor(OTHER_ACTOR);
507 outcome.setResult(OperationResult.FAILURE);
508 outcome.setStart(Instant.now());
509 mgr.getParams().callbackStarted(new OperationOutcome(outcome));
511 outcome.setEnd(Instant.now());
512 mgr.getParams().callbackCompleted(outcome);
514 policyFuture.complete(genOpOutcome());
517 // should not include the other actor's outcome
518 assertEquals(ControlLoopOperationManager2.State.GUARD_STARTED, mgr.getState());
520 assertTrue(mgr.nextStep());
521 assertEquals(ControlLoopOperationManager2.State.GUARD_PERMITTED, mgr.getState());
523 assertTrue(mgr.nextStep());
524 assertEquals(ControlLoopOperationManager2.State.OPERATION_STARTED, mgr.getState());
526 assertTrue(mgr.nextStep());
527 assertEquals(ControlLoopOperationManager2.State.OPERATION_SUCCESS, mgr.getState());
529 assertFalse(mgr.nextStep());
531 assertEquals(OperationResult.SUCCESS, mgr.getOutcomes().peek().getResult());
533 verify(mgrctx, times(4)).updated(mgr);
537 public void testNextStep() {
538 mgr.start(REMAINING_MS);
540 // only do the lock and the guard
541 lockFuture.complete(new OperationOutcome());
545 assertEquals(ControlLoopOperationManager2.State.GUARD_STARTED, mgr.getState());
547 assertTrue(mgr.nextStep());
548 assertEquals(ControlLoopOperationManager2.State.GUARD_PERMITTED, mgr.getState());
550 assertTrue(mgr.nextStep());
551 assertTrue(mgr.nextStep());
553 verify(mgrctx, times(2)).updated(mgr);
557 * Tests processOutcome() when the lock is denied.
560 public void testProcessOutcomeLockDenied() {
561 mgr.start(REMAINING_MS);
563 // unavailable from the start => "denied"
568 assertEquals(ControlLoopOperationManager2.State.LOCK_DENIED, mgr.getState());
570 assertFalse(mgr.nextStep());
571 verify(mgrctx).updated(mgr);
573 verifyDb(1, OperationResult.FAILURE_GUARD, "Operation denied by Lock");
577 * Tests processOutcome() when the lock is lost.
580 public void testProcessOutcomeLockLost() {
581 mgr.start(REMAINING_MS);
583 // indicate lock success initially
584 lockFuture.complete(new OperationOutcome());
589 // now generate a lock failure => "lost"
594 assertEquals(ControlLoopOperationManager2.State.GUARD_STARTED, mgr.getState());
596 assertTrue(mgr.nextStep());
597 assertEquals(ControlLoopOperationManager2.State.GUARD_PERMITTED, mgr.getState());
599 assertTrue(mgr.nextStep());
600 assertEquals(ControlLoopOperationManager2.State.LOCK_LOST, mgr.getState());
602 assertFalse(mgr.nextStep());
603 verify(mgrctx, times(3)).updated(mgr);
605 verifyDb(1, OperationResult.FAILURE, "Operation aborted by Lock");
609 * Tests processOutcome() when the guard is permitted.
612 public void testProcessOutcomeGuardPermit() {
613 mgr.start(REMAINING_MS);
615 lockFuture.complete(new OperationOutcome());
620 assertEquals(ControlLoopOperationManager2.State.GUARD_STARTED, mgr.getState());
622 assertTrue(mgr.nextStep());
623 assertEquals(ControlLoopOperationManager2.State.GUARD_PERMITTED, mgr.getState());
625 assertTrue(mgr.nextStep());
626 verify(mgrctx, times(2)).updated(mgr);
628 verify(dataMgr, never()).store(any(), any(), any(), any());
632 * Tests processOutcome() when the guard is permitted.
635 public void testProcessOutcomeGuardDenied() {
636 mgr.start(REMAINING_MS);
638 lockFuture.complete(new OperationOutcome());
639 genGuardOutcome(false);
643 assertEquals(ControlLoopOperationManager2.State.GUARD_STARTED, mgr.getState());
645 assertTrue(mgr.nextStep());
646 assertEquals(ControlLoopOperationManager2.State.GUARD_DENIED, mgr.getState());
648 assertFalse(mgr.nextStep());
649 verify(mgrctx, times(2)).updated(mgr);
651 verifyDb(1, OperationResult.FAILURE_GUARD, "Operation denied by Guard");
655 * Tests processOutcome() when the operation is a success.
658 public void testProcessOutcomeOperSuccess() {
659 mgr.start(REMAINING_MS);
661 lockFuture.complete(new OperationOutcome());
667 assertEquals(ControlLoopOperationManager2.State.GUARD_STARTED, mgr.getState());
669 assertTrue(mgr.nextStep());
670 assertEquals(ControlLoopOperationManager2.State.GUARD_PERMITTED, mgr.getState());
672 assertTrue(mgr.nextStep());
673 assertEquals(ControlLoopOperationManager2.State.OPERATION_STARTED, mgr.getState());
675 assertTrue(mgr.nextStep());
676 assertEquals(ControlLoopOperationManager2.State.OPERATION_SUCCESS, mgr.getState());
678 assertFalse(mgr.nextStep());
679 verify(mgrctx, times(4)).updated(mgr);
681 verifyDb(2, OperationResult.SUCCESS, null);
685 * Tests processOutcome() when the operation is a failure.
688 public void testProcessOutcomeOperFailure() {
689 mgr.start(REMAINING_MS);
691 lockFuture.complete(new OperationOutcome());
697 assertEquals(ControlLoopOperationManager2.State.GUARD_STARTED, mgr.getState());
699 assertTrue(mgr.nextStep());
700 assertEquals(ControlLoopOperationManager2.State.GUARD_PERMITTED, mgr.getState());
702 assertTrue(mgr.nextStep());
703 assertEquals(ControlLoopOperationManager2.State.OPERATION_STARTED, mgr.getState());
705 assertTrue(mgr.nextStep());
706 assertEquals(ControlLoopOperationManager2.State.OPERATION_FAILURE, mgr.getState());
707 verifyDb(2, OperationResult.FAILURE, null);
709 assertThat(mgr.toString()).contains("attempts=1");
715 assertTrue(mgr.nextStep());
716 assertEquals(ControlLoopOperationManager2.State.OPERATION_STARTED, mgr.getState());
718 assertTrue(mgr.nextStep());
719 assertEquals(ControlLoopOperationManager2.State.OPERATION_FAILURE, mgr.getState());
720 verifyDb(4, OperationResult.FAILURE, null);
722 assertThat(mgr.toString()).contains("attempts=2");
724 // and finally a success
727 assertTrue(mgr.nextStep());
728 assertEquals(ControlLoopOperationManager2.State.OPERATION_STARTED, mgr.getState());
730 assertTrue(mgr.nextStep());
731 assertEquals(ControlLoopOperationManager2.State.OPERATION_SUCCESS, mgr.getState());
732 verifyDb(6, OperationResult.SUCCESS, null);
734 assertThat(mgr.toString()).contains("attempts=3");
736 assertFalse(mgr.nextStep());
737 verify(mgrctx, times(8)).updated(mgr);
741 public void testGetOperationHistory() {
743 assertNull(mgr.getOperationHistory());
746 assertThat(mgr.getOperationHistory()).contains("actor=my-actor").contains("operation=my-operation")
747 .contains("outcome=Success");
751 public void testGetHistory() {
753 assertEquals(0, mgr.getHistory().size());
756 assertEquals(1, mgr.getHistory().size());
760 public void testDetmTargetVm() {
761 target.setTargetType(TargetType.VM.toString());
762 assertNull(mgr.detmTarget());
763 assertEquals(MY_TARGET, mgr.getTargetEntity());
765 target.setTargetType(TargetType.VNF.toString());
766 assertNull(mgr.detmTarget());
767 assertEquals(MY_TARGET, mgr.getTargetEntity());
769 target.setTargetType(TargetType.VFMODULE.toString());
770 assertNull(mgr.detmTarget());
771 assertEquals(MY_TARGET, mgr.getTargetEntity());
774 target.setTargetType(TargetType.VFC.toString());
775 assertThatIllegalArgumentException().isThrownBy(() -> mgr.detmTarget())
776 .withMessage("The target type is not supported");
779 target.setTargetType(null);
780 assertThatIllegalArgumentException().isThrownBy(() -> mgr.detmTarget()).withMessage("The target type is null");
783 operation.setTarget(null);
784 mgr = new ControlLoopOperationManager2(mgrctx, context, policy, executor);
785 assertThatIllegalArgumentException().isThrownBy(() -> mgr.detmTarget()).withMessage("The target is null");
789 public void testDetmPnfTarget() {
791 assertNull(mgr.detmTarget());
792 assertEquals(MY_TARGET, mgr.getTargetEntity());
794 // missing enrichment data
795 event.getAai().clear();
796 assertThatIllegalArgumentException().isThrownBy(() -> mgr.detmTarget())
797 .withMessage("AAI section is missing " + ControlLoopOperationManager2.PNF_NAME);
800 event.setTarget(MISMATCH);
801 assertThatIllegalArgumentException().isThrownBy(() -> mgr.detmTarget())
802 .withMessage("Target does not match target type");
806 public void testDetmVfModuleTarget() {
808 event.setTarget(ControlLoopOperationManager2.VSERVER_VSERVER_NAME);
809 event.getAai().clear();
810 event.getAai().putAll(Map.of(ControlLoopOperationManager2.VSERVER_VSERVER_NAME, MY_TARGET));
811 assertNull(mgr.detmTarget());
812 assertEquals(MY_TARGET, mgr.getTargetEntity());
815 event.setTarget(ControlLoopOperationManager2.GENERIC_VNF_VNF_ID);
816 event.getAai().clear();
817 event.getAai().putAll(Map.of(ControlLoopOperationManager2.GENERIC_VNF_VNF_ID, MY_TARGET));
818 assertNull(mgr.detmTarget());
819 assertEquals(MY_TARGET, mgr.getTargetEntity());
822 event.setTarget(MISMATCH);
823 assertThatIllegalArgumentException().isThrownBy(() -> mgr.detmTarget())
824 .withMessage("Target does not match target type");
826 // missing enrichment data
827 event.setTarget(ControlLoopOperationManager2.VSERVER_VSERVER_NAME);
828 event.getAai().clear();
829 assertThatIllegalArgumentException().isThrownBy(() -> mgr.detmTarget())
830 .withMessage("Enrichment data is missing " + ControlLoopOperationManager2.VSERVER_VSERVER_NAME);
833 event.setTarget(null);
834 assertThatIllegalArgumentException().isThrownBy(() -> mgr.detmTarget()).withMessage("Target is null");
838 public void testDetmVnfName() {
840 assertNull(mgr.detmTarget());
841 assertEquals(MY_TARGET, mgr.getTargetEntity());
843 // force it to be gotten from the CQ data
844 event.getAai().clear();
845 assertNull(mgr.detmTarget());
846 assertEquals(MY_VNF_ID, mgr.getTargetEntity());
850 public void testExtractVnfFromCq() {
851 // force it to be gotten from the CQ data
853 event.getAai().clear();
855 // missing vnf id in CQ data
856 when(vnf.getVnfId()).thenReturn(null);
857 assertThatIllegalArgumentException().isThrownBy(() -> mgr.detmTarget()).withMessage("No vnf-id found");
859 // missing default vnf in CQ data
860 when(cqdata.getDefaultGenericVnf()).thenReturn(null);
861 assertThatIllegalArgumentException().isThrownBy(() -> mgr.detmTarget()).withMessage("No vnf-id found");
865 public void testGetState_testGetActor_testGetOperation() {
866 assertEquals(ControlLoopOperationManager2.State.ACTIVE, mgr.getState());
867 assertEquals(POLICY_ACTOR, mgr.getActor());
868 assertEquals(POLICY_OPERATION, mgr.getOperation());
872 public void testToString() {
873 assertThat(mgr.toString()).contains("state").contains("requestId").contains("policyId").contains("attempts");
877 * Runs a cycle, from start to completion.
879 private void runCyle() {
880 mgr.start(REMAINING_MS);
882 lockFuture.complete(new OperationOutcome());
889 assertTrue(mgr.nextStep());
892 assertTrue(mgr.nextStep());
895 assertTrue(mgr.nextStep());
898 assertFalse(mgr.nextStep());
902 * Runs everything until the executor queue is empty.
904 private void runToCompletion() {
905 assertTrue(executor.runAll(MAX_RUN));
909 * Generates a failure outcome for the lock, and invokes the callbacks.
911 * @return the generated outcome
913 private OperationOutcome genLockFailure() {
914 OperationOutcome outcome = new OperationOutcome();
915 outcome.setActor(ControlLoopOperationManager2.LOCK_ACTOR);
916 outcome.setOperation(ControlLoopOperationManager2.LOCK_OPERATION);
917 outcome.setResult(OperationResult.FAILURE);
918 outcome.setStart(Instant.now());
919 outcome.setEnd(Instant.now());
920 outcome.setFinalOutcome(true);
922 verify(mgrctx).requestLock(eq(MY_TARGET), lockCallback.capture());
923 lockCallback.getValue().accept(outcome);
925 lockFuture.complete(outcome);
931 * Generates an outcome for the guard, and invokes the callbacks.
933 * @return the generated outcome
935 private OperationOutcome genGuardOutcome() {
936 return genGuardOutcome(true);
940 * Generates an outcome for the guard, and invokes the callbacks.
942 * @param permit {@code true} if the guard should be permitted, {@code false} if
944 * @return the generated outcome
946 private OperationOutcome genGuardOutcome(boolean permit) {
947 OperationOutcome outcome = mgr.getParams().makeOutcome();
948 outcome.setActor(GuardActor.NAME);
949 outcome.setOperation(DecisionOperation.NAME);
950 outcome.setStart(Instant.now());
951 mgr.getParams().callbackStarted(new OperationOutcome(outcome));
954 outcome.setResult(OperationResult.FAILURE);
957 outcome.setEnd(Instant.now());
958 mgr.getParams().callbackCompleted(outcome);
964 * Generates an outcome for the operation, itself, and invokes the callbacks.
966 * @return the generated outcome
968 private OperationOutcome genOpOutcome() {
969 return genOpOutcome(true);
973 * Generates an outcome for the operation, itself, and invokes the callbacks.
975 * @param success {@code true} if the outcome should be a success, {@code false} if a
977 * @return the generated outcome
979 private OperationOutcome genOpOutcome(boolean success) {
980 OperationOutcome outcome = mgr.getParams().makeOutcome();
981 outcome.setStart(Instant.now());
982 mgr.getParams().callbackStarted(new OperationOutcome(outcome));
985 outcome.setFinalOutcome(true);
987 outcome.setResult(OperationResult.FAILURE);
990 outcome.setEnd(Instant.now());
991 mgr.getParams().callbackCompleted(outcome);
997 * Configures the data for a PNF target.
999 private void setTargetPnf() {
1000 event.setTarget(ControlLoopOperationManager2.PNF_NAME);
1001 event.getAai().clear();
1002 event.getAai().putAll(Map.of(ControlLoopOperationManager2.PNF_NAME, MY_TARGET));
1004 target.setTargetType(TargetType.PNF.toString());
1008 * Configures the data for a VNF-NAME target.
1010 private void setTargetVnfName() {
1011 event.setTarget(ControlLoopOperationManager2.GENERIC_VNF_VNF_NAME);
1012 event.getAai().clear();
1013 event.getAai().putAll(Map.of(ControlLoopOperationManager2.GENERIC_VNF_VNF_ID, MY_TARGET));
1015 target.setTargetType(TargetType.VNF.toString());
1018 private void checkResp(OperationOutcome outcome, String expectedPayload) {
1019 ControlLoopResponse resp = mgr.makeControlLoopResponse(outcome);
1020 assertNotNull(resp);
1021 assertEquals(REQ_ID, resp.getRequestId());
1022 assertEquals(expectedPayload, resp.getPayload());
1025 private void verifyDb(int nrecords, OperationResult expectedResult, String expectedMsg) {
1026 ArgumentCaptor<String> entityCaptor = ArgumentCaptor.forClass(String.class);
1027 ArgumentCaptor<ControlLoopOperation> opCaptor = ArgumentCaptor.forClass(ControlLoopOperation.class);
1028 verify(dataMgr, times(nrecords)).store(any(), any(), entityCaptor.capture(), opCaptor.capture());
1030 assertEquals(MY_TARGET, entityCaptor.getValue());
1032 ControlLoopOperation oper = opCaptor.getValue();
1034 assertEquals(expectedResult.toString(), oper.getOutcome());
1035 assertEquals(expectedMsg, oper.getMessage());