a14cc17088ab246e014213090ee47f60b13d0484
[policy/drools-applications.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP
4  * ================================================================================
5  * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.controlloop.eventmanager;
22
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;
38
39 import java.time.Instant;
40 import java.util.Map;
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.VirtualControlLoopEvent;
58 import org.onap.policy.controlloop.actor.guard.GuardActorServiceProvider;
59 import org.onap.policy.controlloop.actor.guard.GuardOperation;
60 import org.onap.policy.controlloop.actorserviceprovider.ActorService;
61 import org.onap.policy.controlloop.actorserviceprovider.Operation;
62 import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome;
63 import org.onap.policy.controlloop.actorserviceprovider.Operator;
64 import org.onap.policy.controlloop.actorserviceprovider.controlloop.ControlLoopEventContext;
65 import org.onap.policy.controlloop.actorserviceprovider.parameters.ControlLoopOperationParams;
66 import org.onap.policy.controlloop.actorserviceprovider.spi.Actor;
67 import org.onap.policy.controlloop.ophistory.OperationHistoryDataManager;
68 import org.onap.policy.controlloop.policy.Policy;
69 import org.onap.policy.controlloop.policy.PolicyResult;
70 import org.onap.policy.controlloop.policy.Target;
71 import org.onap.policy.controlloop.policy.TargetType;
72
73 public class ControlLoopOperationManager2Test {
74     private static final UUID REQ_ID = UUID.randomUUID();
75     private static final String MISMATCH = "mismatch";
76     private static final String POLICY_ID = "my-policy";
77     private static final String POLICY_ACTOR = "my-actor";
78     private static final String POLICY_OPERATION = "my-operation";
79     private static final String OTHER_ACTOR = "another-actor";
80     private static final String MY_TARGET = "my-target";
81     private static final String MY_VNF_ID = "my-vnf-id";
82     private static final String PAYLOAD_KEY = "payload-key";
83     private static final String PAYLOAD_VALUE = "payload-value";
84     private static final long REMAINING_MS = 5000;
85     private static final int MAX_RUN = 100;
86     private static final Integer POLICY_RETRY = 3;
87     private static final Integer POLICY_TIMEOUT = 20;
88     private static final IllegalArgumentException EXPECTED_EXCEPTION =
89                     new IllegalArgumentException("expected exception");
90
91     @Captor
92     private ArgumentCaptor<Consumer<OperationOutcome>> lockCallback;
93
94     @Mock
95     private OperationHistoryDataManager dataMgr;
96     @Mock
97     private ManagerContext mgrctx;
98     @Mock
99     private Operator policyOperator;
100     @Mock
101     private Operation policyOperation;
102     @Mock
103     private Actor policyActor;
104     @Mock
105     private ActorService actors;
106     @Mock
107     private AaiCqResponse cqdata;
108     @Mock
109     private GenericVnf vnf;
110
111     private CompletableFuture<OperationOutcome> lockFuture;
112     private CompletableFuture<OperationOutcome> policyFuture;
113     private Target target;
114     private Map<String, String> payload;
115     private Policy policy;
116     private VirtualControlLoopEvent event;
117     private ControlLoopEventContext context;
118     private PseudoExecutor executor;
119     private ControlLoopOperationManager2 mgr;
120
121     /**
122      * Sets up.
123      */
124     @Before
125     public void setUp() {
126         MockitoAnnotations.initMocks(this);
127
128         lockFuture = new CompletableFuture<>();
129         policyFuture = new CompletableFuture<>();
130
131         when(mgrctx.getActorService()).thenReturn(actors);
132         when(mgrctx.getDataManager()).thenReturn(dataMgr);
133         when(mgrctx.requestLock(any(), any())).thenReturn(lockFuture);
134
135         // configure policy operation
136         when(actors.getActor(POLICY_ACTOR)).thenReturn(policyActor);
137         when(policyActor.getOperator(POLICY_OPERATION)).thenReturn(policyOperator);
138         when(policyOperator.buildOperation(any())).thenReturn(policyOperation);
139         when(policyOperation.start()).thenReturn(policyFuture);
140
141         when(vnf.getVnfId()).thenReturn(MY_VNF_ID);
142         when(cqdata.getDefaultGenericVnf()).thenReturn(vnf);
143
144         target = new Target();
145         target.setType(TargetType.VM);
146
147         payload = Map.of(PAYLOAD_KEY, PAYLOAD_VALUE);
148
149         policy = new Policy();
150         policy.setId(POLICY_ID);
151         policy.setActor(POLICY_ACTOR);
152         policy.setRecipe(POLICY_OPERATION);
153         policy.setTarget(target);
154         policy.setPayload(payload);
155         policy.setRetry(POLICY_RETRY);
156         policy.setTimeout(POLICY_TIMEOUT);
157
158         event = new VirtualControlLoopEvent();
159         event.setRequestId(REQ_ID);
160         event.setTarget(ControlLoopOperationManager2.VSERVER_VSERVER_NAME);
161         event.setAai(new TreeMap<>(Map.of(ControlLoopOperationManager2.VSERVER_VSERVER_NAME, MY_TARGET)));
162
163         context = new ControlLoopEventContext(event);
164         context.setProperty(AaiCqResponse.CONTEXT_KEY, cqdata);
165
166         executor = new PseudoExecutor();
167
168         mgr = new ControlLoopOperationManager2(mgrctx, context, policy, executor);
169     }
170
171     @Test
172     public void testStart() {
173         mgr.start(REMAINING_MS);
174
175         // should have determined the target entity by now
176         assertEquals(MY_TARGET, mgr.getTargetEntity());
177
178         verify(mgrctx).requestLock(eq(MY_TARGET), any());
179
180         lockFuture.complete(new OperationOutcome());
181         genGuardOutcome();
182         policyFuture.complete(genOpOutcome());
183         runToCompletion();
184
185         assertEquals(ControlLoopOperationManager2.State.GUARD_STARTED, mgr.getState());
186
187         assertTrue(mgr.nextStep());
188         assertEquals(ControlLoopOperationManager2.State.GUARD_PERMITTED, mgr.getState());
189
190         assertTrue(mgr.nextStep());
191         assertEquals(ControlLoopOperationManager2.State.OPERATION_SUCCESS, mgr.getState());
192
193         assertFalse(mgr.nextStep());
194
195         OperationOutcome outcome = mgr.getOutcomes().peek();
196         assertEquals(PolicyResult.SUCCESS, outcome.getResult());
197         assertTrue(outcome.isFinalOutcome());
198
199         verify(mgrctx, times(3)).updated(mgr);
200     }
201
202     /**
203      * Tests start() when detmTarget() (i.e., the first task) throws an exception.
204      */
205     @Test
206     public void testStartDetmTargetException() {
207         policy.setTarget(null);
208         mgr.start(REMAINING_MS);
209
210         runToCompletion();
211
212         assertFalse(mgr.nextStep());
213         assertEquals(ControlLoopOperationManager2.State.OPERATION_FAILURE, mgr.getState());
214
215         // should have called update() for operation-start, but not for any nextStep()
216         verify(mgrctx).updated(mgr);
217     }
218
219     /**
220      * Tests start() when a subsequent task throws an exception.
221      */
222     @Test
223     public void testStartException() {
224         when(policyOperation.start()).thenThrow(EXPECTED_EXCEPTION);
225
226         mgr.start(REMAINING_MS);
227
228         lockFuture.complete(new OperationOutcome());
229         runToCompletion();
230
231         assertFalse(mgr.nextStep());
232         assertEquals(ControlLoopOperationManager2.State.OPERATION_FAILURE, mgr.getState());
233
234         // should have called update() for operation-start, but not for any nextStep()
235         verify(mgrctx).updated(mgr);
236     }
237
238     /**
239      * Tests start() when the control loop times out.
240      */
241     @Test
242     public void testStartClTimeout_testHandleTimeout() throws InterruptedException {
243         // catch the callback when it times out
244         CountDownLatch updatedLatch = new CountDownLatch(1);
245         doAnswer(args -> {
246             updatedLatch.countDown();
247             return null;
248         }).when(mgrctx).updated(any());
249
250         long tstart = System.currentTimeMillis();
251
252         // give it a short timeout
253         mgr.start(100);
254
255         assertTrue(updatedLatch.await(5, TimeUnit.SECONDS));
256         assertTrue(System.currentTimeMillis() - tstart >= 100);
257
258         // don't generate any responses
259         runToCompletion();
260
261         // wait for the future to be canceled, via a background thread
262         CountDownLatch futureLatch = new CountDownLatch(1);
263         mgr.getFuture().whenComplete((unused, thrown) -> futureLatch.countDown());
264         assertTrue(futureLatch.await(5, TimeUnit.SECONDS));
265
266         // lock should have been canceled
267         assertTrue(mgr.getFuture().isCancelled());
268
269         assertFalse(mgr.nextStep());
270         assertEquals(ControlLoopOperationManager2.State.CONTROL_LOOP_TIMEOUT, mgr.getState());
271
272         // should have called update() for operation-start, but not for any nextStep()
273         verify(mgrctx).updated(mgr);
274
275         // should not have tried to store anything in the DB
276         verify(dataMgr, never()).store(any(), any(), any());
277     }
278
279     @Test
280     public void testStartOperation() {
281         mgr.start(REMAINING_MS);
282
283         lockFuture.complete(new OperationOutcome());
284         genGuardOutcome();
285         runToCompletion();
286
287         verify(policyOperation).start();
288
289         ArgumentCaptor<ControlLoopOperationParams> captor = ArgumentCaptor.forClass(ControlLoopOperationParams.class);
290         verify(policyOperator).buildOperation(captor.capture());
291
292         ControlLoopOperationParams params = captor.getValue();
293
294         assertNotNull(params);
295         assertEquals(POLICY_ACTOR, params.getActor());
296         assertSame(actors, params.getActorService());
297         assertNotNull(params.getCompleteCallback());
298         assertSame(context, params.getContext());
299         assertSame(executor, params.getExecutor());
300         assertEquals(POLICY_OPERATION, params.getOperation());
301         assertEquals(payload, params.getPayload());
302         assertSame(REQ_ID, params.getRequestId());
303         assertSame(POLICY_RETRY, params.getRetry());
304         assertNotNull(params.getStartCallback());
305         assertSame(target, params.getTarget());
306         assertEquals(MY_TARGET, params.getTargetEntity());
307         assertSame(POLICY_TIMEOUT, params.getTimeoutSec());
308     }
309
310     @Test
311     public void testStartOperationNullPayload() {
312         policy.setPayload(null);
313         mgr.start(REMAINING_MS);
314
315         lockFuture.complete(new OperationOutcome());
316         genGuardOutcome();
317         runToCompletion();
318
319         verify(policyOperation).start();
320
321         ArgumentCaptor<ControlLoopOperationParams> captor = ArgumentCaptor.forClass(ControlLoopOperationParams.class);
322         verify(policyOperator).buildOperation(captor.capture());
323
324         ControlLoopOperationParams params = captor.getValue();
325
326         assertNotNull(params);
327         assertEquals(POLICY_ACTOR, params.getActor());
328         assertSame(actors, params.getActorService());
329         assertNotNull(params.getCompleteCallback());
330         assertSame(context, params.getContext());
331         assertSame(executor, params.getExecutor());
332         assertEquals(POLICY_OPERATION, params.getOperation());
333         assertTrue(params.getPayload().isEmpty());
334         assertSame(REQ_ID, params.getRequestId());
335         assertSame(POLICY_RETRY, params.getRetry());
336         assertNotNull(params.getStartCallback());
337         assertSame(target, params.getTarget());
338         assertEquals(MY_TARGET, params.getTargetEntity());
339         assertSame(POLICY_TIMEOUT, params.getTimeoutSec());
340     }
341
342     @Test
343     public void testGetOperationMessage() {
344         // no history yet
345         assertNull(mgr.getOperationMessage());
346
347         runCyle();
348         assertThat(mgr.getOperationMessage()).contains("actor=my-actor").contains("operation=my-operation");
349     }
350
351     @Test
352     public void testGetOperationResult() {
353         // no history yet
354         assertNotNull(mgr.getOperationResult());
355
356         runCyle();
357         assertEquals(PolicyResult.SUCCESS, mgr.getOperationResult());
358     }
359
360     /**
361      * Tests getOperationResult() when it ends in a failure.
362      */
363     @Test
364     public void testGetOperationResultFailure() {
365         mgr.start(REMAINING_MS);
366
367         genLockFailure();
368         runToCompletion();
369
370         assertEquals(PolicyResult.FAILURE_GUARD, mgr.getOperationResult());
371     }
372
373     /**
374      * Tests handleException() when the exception is a "cancel".
375      */
376     @Test
377     public void testHandleExceptionCanceled() {
378         lockFuture.cancel(false);
379
380         mgr.start(REMAINING_MS);
381
382         runToCompletion();
383
384         assertTrue(mgr.nextStep());
385         assertEquals(ControlLoopOperationManager2.State.ACTIVE, mgr.getState());
386     }
387
388     @Test
389     public void testCancel() {
390         mgr.start(REMAINING_MS);
391
392         mgr.cancel();
393         assertTrue(mgr.getFuture().isCancelled());
394     }
395
396     /**
397      * Tests cancel() when the operation hasn't been started.
398      */
399     @Test
400     public void testCancelNotStarted() {
401         assertNull(mgr.getFuture());
402
403         mgr.cancel();
404         assertNull(mgr.getFuture());
405     }
406
407     @Test
408     public void testLockUnavailable() {
409         mgr.start(REMAINING_MS);
410
411         runToCompletion();
412
413         // lock failure outcome
414         final OperationOutcome outcome = genLockFailure();
415
416         runToCompletion();
417
418         assertFalse(mgr.nextStep());
419         assertEquals(ControlLoopOperationManager2.State.LOCK_DENIED, mgr.getState());
420
421         assertEquals(outcome, mgr.getOutcomes().peek());
422
423         // should have called update() for operation-start, but not for any nextStep()
424         verify(mgrctx).updated(mgr);
425     }
426
427     /**
428      * Tests onStart() and onComplete() with other actors.
429      */
430     @Test
431     public void testOnStart_testOnComplete() {
432         mgr.start(REMAINING_MS);
433
434         lockFuture.complete(new OperationOutcome());
435         genGuardOutcome();
436
437         // generate failure outcome for ANOTHER actor - should be ignored
438         OperationOutcome outcome = mgr.getParams().makeOutcome();
439         outcome.setActor(OTHER_ACTOR);
440         outcome.setResult(PolicyResult.FAILURE);
441         outcome.setStart(Instant.now());
442         mgr.getParams().callbackStarted(new OperationOutcome(outcome));
443
444         outcome.setEnd(Instant.now());
445         mgr.getParams().callbackCompleted(outcome);
446
447         policyFuture.complete(genOpOutcome());
448         runToCompletion();
449
450         // should not include the other actor's outcome
451         assertEquals(ControlLoopOperationManager2.State.GUARD_STARTED, mgr.getState());
452
453         assertTrue(mgr.nextStep());
454         assertEquals(ControlLoopOperationManager2.State.GUARD_PERMITTED, mgr.getState());
455
456         assertTrue(mgr.nextStep());
457         assertEquals(ControlLoopOperationManager2.State.OPERATION_SUCCESS, mgr.getState());
458
459         assertFalse(mgr.nextStep());
460
461         assertEquals(PolicyResult.SUCCESS, mgr.getOutcomes().peek().getResult());
462
463         verify(mgrctx, times(3)).updated(mgr);
464     }
465
466     @Test
467     public void testNextStep() {
468         mgr.start(REMAINING_MS);
469
470         // only do the lock and the guard
471         lockFuture.complete(new OperationOutcome());
472         genGuardOutcome();
473         runToCompletion();
474
475         assertEquals(ControlLoopOperationManager2.State.GUARD_STARTED, mgr.getState());
476
477         assertTrue(mgr.nextStep());
478         assertEquals(ControlLoopOperationManager2.State.GUARD_PERMITTED, mgr.getState());
479
480         assertTrue(mgr.nextStep());
481         assertTrue(mgr.nextStep());
482
483         verify(mgrctx, times(2)).updated(mgr);
484     }
485
486     /**
487      * Tests processOutcome() when the lock is denied.
488      */
489     @Test
490     public void testProcessOutcomeLockDenied() {
491         mgr.start(REMAINING_MS);
492
493         // unavailable from the start => "denied"
494         genLockFailure();
495
496         runToCompletion();
497
498         assertEquals(ControlLoopOperationManager2.State.LOCK_DENIED, mgr.getState());
499
500         assertFalse(mgr.nextStep());
501         verify(mgrctx).updated(mgr);
502
503         verifyDb(1, PolicyResult.FAILURE_GUARD, "Operation denied by Lock");
504     }
505
506     /**
507      * Tests processOutcome() when the lock is lost.
508      */
509     @Test
510     public void testProcessOutcomeLockLost() {
511         mgr.start(REMAINING_MS);
512
513         // indicate lock success initially
514         lockFuture.complete(new OperationOutcome());
515
516         // do the guard
517         genGuardOutcome();
518
519         // now generate a lock failure => "lost"
520         genLockFailure();
521
522         runToCompletion();
523
524         assertEquals(ControlLoopOperationManager2.State.GUARD_STARTED, mgr.getState());
525
526         assertTrue(mgr.nextStep());
527         assertEquals(ControlLoopOperationManager2.State.GUARD_PERMITTED, mgr.getState());
528
529         assertTrue(mgr.nextStep());
530         assertEquals(ControlLoopOperationManager2.State.LOCK_LOST, mgr.getState());
531
532         assertFalse(mgr.nextStep());
533         verify(mgrctx, times(3)).updated(mgr);
534
535         verifyDb(1, PolicyResult.FAILURE, "Operation aborted by Lock");
536     }
537
538     /**
539      * Tests processOutcome() when the guard is permitted.
540      */
541     @Test
542     public void testProcessOutcomeGuardPermit() {
543         mgr.start(REMAINING_MS);
544
545         lockFuture.complete(new OperationOutcome());
546         genGuardOutcome();
547
548         runToCompletion();
549
550         assertEquals(ControlLoopOperationManager2.State.GUARD_STARTED, mgr.getState());
551
552         assertTrue(mgr.nextStep());
553         assertEquals(ControlLoopOperationManager2.State.GUARD_PERMITTED, mgr.getState());
554
555         assertTrue(mgr.nextStep());
556         verify(mgrctx, times(2)).updated(mgr);
557
558         verify(dataMgr, never()).store(any(), any(), any());
559     }
560
561     /**
562      * Tests processOutcome() when the guard is permitted.
563      */
564     @Test
565     public void testProcessOutcomeGuardDenied() {
566         mgr.start(REMAINING_MS);
567
568         lockFuture.complete(new OperationOutcome());
569         genGuardOutcome(false);
570
571         runToCompletion();
572
573         assertEquals(ControlLoopOperationManager2.State.GUARD_STARTED, mgr.getState());
574
575         assertTrue(mgr.nextStep());
576         assertEquals(ControlLoopOperationManager2.State.GUARD_DENIED, mgr.getState());
577
578         assertFalse(mgr.nextStep());
579         verify(mgrctx, times(2)).updated(mgr);
580
581         verifyDb(1, PolicyResult.FAILURE_GUARD, "Operation denied by Guard");
582     }
583
584     /**
585      * Tests processOutcome() when the operation is a success.
586      */
587     @Test
588     public void testProcessOutcomeOperSuccess() {
589         mgr.start(REMAINING_MS);
590
591         lockFuture.complete(new OperationOutcome());
592         genGuardOutcome();
593         genOpOutcome();
594
595         runToCompletion();
596
597         assertEquals(ControlLoopOperationManager2.State.GUARD_STARTED, mgr.getState());
598
599         assertTrue(mgr.nextStep());
600         assertEquals(ControlLoopOperationManager2.State.GUARD_PERMITTED, mgr.getState());
601
602         assertTrue(mgr.nextStep());
603         assertEquals(ControlLoopOperationManager2.State.OPERATION_SUCCESS, mgr.getState());
604
605         assertFalse(mgr.nextStep());
606         verify(mgrctx, times(3)).updated(mgr);
607
608         verifyDb(1, PolicyResult.SUCCESS, null);
609     }
610
611     /**
612      * Tests processOutcome() when the operation is a failure.
613      */
614     @Test
615     public void testProcessOutcomeOperFailure() {
616         mgr.start(REMAINING_MS);
617
618         lockFuture.complete(new OperationOutcome());
619         genGuardOutcome();
620         genOpOutcome(false);
621
622         runToCompletion();
623
624         assertEquals(ControlLoopOperationManager2.State.GUARD_STARTED, mgr.getState());
625
626         assertTrue(mgr.nextStep());
627         assertEquals(ControlLoopOperationManager2.State.GUARD_PERMITTED, mgr.getState());
628
629         assertTrue(mgr.nextStep());
630         assertEquals(ControlLoopOperationManager2.State.OPERATION_FAILURE, mgr.getState());
631         verifyDb(1, PolicyResult.FAILURE, null);
632
633         assertThat(mgr.toString()).contains("attempts=1");
634
635         // next failure
636         genOpOutcome(false);
637         runToCompletion();
638
639         assertTrue(mgr.nextStep());
640         assertEquals(ControlLoopOperationManager2.State.OPERATION_FAILURE, mgr.getState());
641         verifyDb(2, PolicyResult.FAILURE, null);
642
643         assertThat(mgr.toString()).contains("attempts=2");
644
645         // and finally a success
646         genOpOutcome();
647
648         assertTrue(mgr.nextStep());
649         assertEquals(ControlLoopOperationManager2.State.OPERATION_SUCCESS, mgr.getState());
650         verifyDb(3, PolicyResult.SUCCESS, null);
651
652         assertThat(mgr.toString()).contains("attempts=3");
653
654         assertFalse(mgr.nextStep());
655         verify(mgrctx, times(5)).updated(mgr);
656     }
657
658     @Test
659     public void testGetOperationHistory() {
660         // no history yet
661         assertNull(mgr.getOperationHistory());
662
663         runCyle();
664         assertThat(mgr.getOperationHistory()).contains("actor=my-actor").contains("operation=my-operation")
665                         .contains("outcome=Success");
666     }
667
668     @Test
669     public void testGetHistory() {
670         // no history yet
671         assertEquals(0, mgr.getHistory().size());
672
673         runCyle();
674         assertEquals(1, mgr.getHistory().size());
675     }
676
677     @Test
678     public void testDetmTargetVm() {
679         target.setType(TargetType.VM);
680         assertNull(mgr.detmTarget());
681         assertEquals(MY_TARGET, mgr.getTargetEntity());
682
683         target.setType(TargetType.VNF);
684         assertNull(mgr.detmTarget());
685         assertEquals(MY_TARGET, mgr.getTargetEntity());
686
687         target.setType(TargetType.VFMODULE);
688         assertNull(mgr.detmTarget());
689         assertEquals(MY_TARGET, mgr.getTargetEntity());
690
691         // unsupported type
692         target.setType(TargetType.VFC);
693         assertThatIllegalArgumentException().isThrownBy(() -> mgr.detmTarget())
694                         .withMessage("The target type is not supported");
695
696         // null type
697         target.setType(null);
698         assertThatIllegalArgumentException().isThrownBy(() -> mgr.detmTarget()).withMessage("The target type is null");
699
700         // null target
701         policy.setTarget(null);
702         assertThatIllegalArgumentException().isThrownBy(() -> mgr.detmTarget()).withMessage("The target is null");
703     }
704
705     @Test
706     public void testDetmPnfTarget() {
707         setTargetPnf();
708         assertNull(mgr.detmTarget());
709         assertEquals(MY_TARGET, mgr.getTargetEntity());
710
711         // missing enrichment data
712         event.getAai().clear();
713         assertThatIllegalArgumentException().isThrownBy(() -> mgr.detmTarget())
714                         .withMessage("AAI section is missing " + ControlLoopOperationManager2.PNF_NAME);
715
716         // wrong target
717         event.setTarget(MISMATCH);
718         assertThatIllegalArgumentException().isThrownBy(() -> mgr.detmTarget())
719                         .withMessage("Target does not match target type");
720     }
721
722     @Test
723     public void testDetmVfModuleTarget() {
724         // vserver
725         event.setTarget(ControlLoopOperationManager2.VSERVER_VSERVER_NAME);
726         event.getAai().clear();
727         event.getAai().putAll(Map.of(ControlLoopOperationManager2.VSERVER_VSERVER_NAME, MY_TARGET));
728         assertNull(mgr.detmTarget());
729         assertEquals(MY_TARGET, mgr.getTargetEntity());
730
731         // vnf-id
732         event.setTarget(ControlLoopOperationManager2.GENERIC_VNF_VNF_ID);
733         event.getAai().clear();
734         event.getAai().putAll(Map.of(ControlLoopOperationManager2.GENERIC_VNF_VNF_ID, MY_TARGET));
735         assertNull(mgr.detmTarget());
736         assertEquals(MY_TARGET, mgr.getTargetEntity());
737
738         // wrong type
739         event.setTarget(MISMATCH);
740         assertThatIllegalArgumentException().isThrownBy(() -> mgr.detmTarget())
741                         .withMessage("Target does not match target type");
742
743         // missing enrichment data
744         event.setTarget(ControlLoopOperationManager2.VSERVER_VSERVER_NAME);
745         event.getAai().clear();
746         assertThatIllegalArgumentException().isThrownBy(() -> mgr.detmTarget())
747                         .withMessage("Enrichment data is missing " + ControlLoopOperationManager2.VSERVER_VSERVER_NAME);
748
749         // null target
750         event.setTarget(null);
751         assertThatIllegalArgumentException().isThrownBy(() -> mgr.detmTarget()).withMessage("Target is null");
752     }
753
754     @Test
755     public void testDetmVnfName() {
756         setTargetVnfName();
757         assertNull(mgr.detmTarget());
758         assertEquals(MY_TARGET, mgr.getTargetEntity());
759
760         // force it to be gotten from the CQ data
761         event.getAai().clear();
762         assertNull(mgr.detmTarget());
763         assertEquals(MY_VNF_ID, mgr.getTargetEntity());
764     }
765
766     @Test
767     public void testExtractVnfFromCq() {
768         // force it to be gotten from the CQ data
769         setTargetVnfName();
770         event.getAai().clear();
771
772         // missing vnf id in CQ data
773         when(vnf.getVnfId()).thenReturn(null);
774         assertThatIllegalArgumentException().isThrownBy(() -> mgr.detmTarget()).withMessage("No vnf-id found");
775
776         // missing default vnf in CQ data
777         when(cqdata.getDefaultGenericVnf()).thenReturn(null);
778         assertThatIllegalArgumentException().isThrownBy(() -> mgr.detmTarget()).withMessage("No vnf-id found");
779     }
780
781     @Test
782     public void testGetState_testGetActor_testGetOperation() {
783         assertEquals(ControlLoopOperationManager2.State.ACTIVE, mgr.getState());
784         assertEquals(POLICY_ACTOR, mgr.getActor());
785         assertEquals(POLICY_OPERATION, mgr.getOperation());
786     }
787
788     @Test
789     public void testToString() {
790         assertThat(mgr.toString()).contains("state").contains("requestId").contains("policyId").contains("attempts");
791     }
792
793     /**
794      * Runs a cycle, from start to completion.
795      */
796     private void runCyle() {
797         mgr.start(REMAINING_MS);
798
799         lockFuture.complete(new OperationOutcome());
800         genGuardOutcome();
801         genOpOutcome();
802
803         runToCompletion();
804
805         assertTrue(mgr.nextStep());
806         assertTrue(mgr.nextStep());
807         assertFalse(mgr.nextStep());
808     }
809
810     /**
811      * Runs everything until the executor queue is empty.
812      */
813     private void runToCompletion() {
814         assertTrue(executor.runAll(MAX_RUN));
815     }
816
817     /**
818      * Generates a failure outcome for the lock, and invokes the callbacks.
819      *
820      * @return the generated outcome
821      */
822     private OperationOutcome genLockFailure() {
823         OperationOutcome outcome = new OperationOutcome();
824         outcome.setActor(ControlLoopOperationManager2.LOCK_ACTOR);
825         outcome.setOperation(ControlLoopOperationManager2.LOCK_OPERATION);
826         outcome.setResult(PolicyResult.FAILURE);
827         outcome.setStart(Instant.now());
828         outcome.setEnd(Instant.now());
829         outcome.setFinalOutcome(true);
830
831         verify(mgrctx).requestLock(eq(MY_TARGET), lockCallback.capture());
832         lockCallback.getValue().accept(outcome);
833
834         lockFuture.complete(outcome);
835
836         return outcome;
837     }
838
839     /**
840      * Generates an outcome for the guard, and invokes the callbacks.
841      *
842      * @return the generated outcome
843      */
844     private OperationOutcome genGuardOutcome() {
845         return genGuardOutcome(true);
846     }
847
848     /**
849      * Generates an outcome for the guard, and invokes the callbacks.
850      *
851      * @param permit {@code true} if the guard should be permitted, {@code false} if
852      *        denied
853      * @return the generated outcome
854      */
855     private OperationOutcome genGuardOutcome(boolean permit) {
856         OperationOutcome outcome = mgr.getParams().makeOutcome();
857         outcome.setActor(GuardActorServiceProvider.NAME);
858         outcome.setOperation(GuardOperation.NAME);
859         outcome.setStart(Instant.now());
860         mgr.getParams().callbackStarted(new OperationOutcome(outcome));
861
862         if (!permit) {
863             outcome.setResult(PolicyResult.FAILURE);
864         }
865
866         outcome.setEnd(Instant.now());
867         mgr.getParams().callbackCompleted(outcome);
868
869         return outcome;
870     }
871
872     /**
873      * Generates an outcome for the operation, itself, and invokes the callbacks.
874      *
875      * @return the generated outcome
876      */
877     private OperationOutcome genOpOutcome() {
878         return genOpOutcome(true);
879     }
880
881     /**
882      * Generates an outcome for the operation, itself, and invokes the callbacks.
883      *
884      * @param success {@code true} if the outcome should be a success, {@code false} if a
885      *        failure
886      * @return the generated outcome
887      */
888     private OperationOutcome genOpOutcome(boolean success) {
889         OperationOutcome outcome = mgr.getParams().makeOutcome();
890         outcome.setStart(Instant.now());
891         mgr.getParams().callbackStarted(new OperationOutcome(outcome));
892
893         if (success) {
894             outcome.setFinalOutcome(true);
895         } else {
896             outcome.setResult(PolicyResult.FAILURE);
897         }
898
899         outcome.setEnd(Instant.now());
900         mgr.getParams().callbackCompleted(outcome);
901
902         return outcome;
903     }
904
905     /**
906      * Configures the data for a PNF target.
907      */
908     private void setTargetPnf() {
909         event.setTarget(ControlLoopOperationManager2.PNF_NAME);
910         event.getAai().clear();
911         event.getAai().putAll(Map.of(ControlLoopOperationManager2.PNF_NAME, MY_TARGET));
912
913         target.setType(TargetType.PNF);
914     }
915
916     /**
917      * Configures the data for a VNF-NAME target.
918      */
919     private void setTargetVnfName() {
920         event.setTarget(ControlLoopOperationManager2.GENERIC_VNF_VNF_NAME);
921         event.getAai().clear();
922         event.getAai().putAll(Map.of(ControlLoopOperationManager2.GENERIC_VNF_VNF_ID, MY_TARGET));
923
924         target.setType(TargetType.VNF);
925     }
926
927     private void verifyDb(int nrecords, PolicyResult expectedResult, String expectedMsg) {
928         ArgumentCaptor<ControlLoopOperation> captor = ArgumentCaptor.forClass(ControlLoopOperation.class);
929         verify(dataMgr, times(nrecords)).store(any(), any(), captor.capture());
930
931         ControlLoopOperation oper = captor.getValue();
932
933         assertEquals(expectedResult.toString(), oper.getOutcome());
934         assertEquals(expectedMsg, oper.getMessage());
935     }
936 }