98ca6736d91cab0b4d35b4744c6939cb4799d39f
[policy/models.git] / models-interactions / model-actors / actorServiceProvider / src / test / java / org / onap / policy / controlloop / actorserviceprovider / parameters / ControlLoopOperationParamsTest.java
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.actorserviceprovider.parameters;
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.Mockito.doAnswer;
33 import static org.mockito.Mockito.never;
34 import static org.mockito.Mockito.times;
35 import static org.mockito.Mockito.verify;
36 import static org.mockito.Mockito.when;
37
38 import java.util.Map;
39 import java.util.TreeMap;
40 import java.util.UUID;
41 import java.util.concurrent.CompletableFuture;
42 import java.util.concurrent.Executor;
43 import java.util.concurrent.ForkJoinPool;
44 import java.util.concurrent.atomic.AtomicInteger;
45 import java.util.function.Consumer;
46 import java.util.function.Function;
47 import org.junit.Before;
48 import org.junit.Test;
49 import org.mockito.Mock;
50 import org.mockito.MockitoAnnotations;
51 import org.onap.policy.common.parameters.BeanValidationResult;
52 import org.onap.policy.controlloop.VirtualControlLoopEvent;
53 import org.onap.policy.controlloop.actorserviceprovider.ActorService;
54 import org.onap.policy.controlloop.actorserviceprovider.Operation;
55 import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome;
56 import org.onap.policy.controlloop.actorserviceprovider.Operator;
57 import org.onap.policy.controlloop.actorserviceprovider.controlloop.ControlLoopEventContext;
58 import org.onap.policy.controlloop.actorserviceprovider.parameters.ControlLoopOperationParams.ControlLoopOperationParamsBuilder;
59 import org.onap.policy.controlloop.actorserviceprovider.spi.Actor;
60 import org.onap.policy.controlloop.policy.Target;
61
62 public class ControlLoopOperationParamsTest {
63     private static final String EXPECTED_EXCEPTION = "expected exception";
64     private static final String ACTOR = "my-actor";
65     private static final String OPERATION = "my-operation";
66     private static final Target TARGET = new Target();
67     private static final String TARGET_ENTITY = "my-target";
68     private static final Integer RETRY = 3;
69     private static final Integer TIMEOUT = 100;
70     private static final UUID REQ_ID = UUID.randomUUID();
71
72     @Mock
73     private Actor actor;
74
75     @Mock
76     private ActorService actorService;
77
78     @Mock
79     private Consumer<OperationOutcome> completer;
80
81     @Mock
82     private ControlLoopEventContext context;
83
84     @Mock
85     private VirtualControlLoopEvent event;
86
87     @Mock
88     private Executor executor;
89
90     @Mock
91     private CompletableFuture<OperationOutcome> operFuture;
92
93     @Mock
94     private Operator operator;
95
96     @Mock
97     private Operation operation;
98
99     @Mock
100     private Consumer<OperationOutcome> starter;
101
102     private Map<String, Object> payload;
103
104     private ControlLoopOperationParams params;
105     private OperationOutcome outcome;
106
107
108     /**
109      * Initializes mocks and sets {@link #params} to a fully-loaded set of parameters.
110      */
111     @Before
112     public void setUp() {
113         MockitoAnnotations.initMocks(this);
114
115         when(actorService.getActor(ACTOR)).thenReturn(actor);
116         when(actor.getOperator(OPERATION)).thenReturn(operator);
117         when(operator.buildOperation(any())).thenReturn(operation);
118         when(operation.start()).thenReturn(operFuture);
119
120         when(event.getRequestId()).thenReturn(REQ_ID);
121
122         when(context.getEvent()).thenReturn(event);
123
124         payload = new TreeMap<>();
125
126         params = ControlLoopOperationParams.builder().actorService(actorService).completeCallback(completer)
127                         .context(context).executor(executor).actor(ACTOR).operation(OPERATION).payload(payload)
128                         .retry(RETRY).target(TARGET).targetEntity(TARGET_ENTITY).timeoutSec(TIMEOUT)
129                         .startCallback(starter).preprocessed(true).build();
130
131         outcome = params.makeOutcome();
132     }
133
134     @Test
135     public void testStart() {
136         assertSame(operFuture, params.start());
137
138         assertThatIllegalArgumentException().isThrownBy(() -> params.toBuilder().context(null).build().start());
139     }
140
141     @Test
142     public void testBuild() {
143         assertSame(operation, params.build());
144
145         assertThatIllegalArgumentException().isThrownBy(() -> params.toBuilder().context(null).build().build());
146     }
147
148     @Test
149     public void testGetRequestId() {
150         assertSame(REQ_ID, params.getRequestId());
151
152         // try with null context
153         assertNull(params.toBuilder().context(null).build().getRequestId());
154
155         // try with null event
156         when(context.getEvent()).thenReturn(null);
157         assertNull(params.getRequestId());
158     }
159
160     @Test
161     public void testMakeOutcome() {
162         assertEquals(ACTOR, outcome.getActor());
163         assertEquals(OPERATION, outcome.getOperation());
164         checkRemainingFields("with actor");
165     }
166
167     protected void checkRemainingFields(String testName) {
168         assertEquals(testName, TARGET_ENTITY, outcome.getTarget());
169         assertNull(testName, outcome.getStart());
170         assertNull(testName, outcome.getEnd());
171         assertNull(testName, outcome.getSubRequestId());
172         assertNotNull(testName, outcome.getResult());
173         assertNull(testName, outcome.getMessage());
174     }
175
176     @Test
177     public void testCallbackStarted() {
178         params.callbackStarted(outcome);
179         verify(starter).accept(outcome);
180
181         // modify starter to throw an exception
182         AtomicInteger count = new AtomicInteger();
183         doAnswer(args -> {
184             count.incrementAndGet();
185             throw new IllegalStateException(EXPECTED_EXCEPTION);
186         }).when(starter).accept(outcome);
187
188         params.callbackStarted(outcome);
189         verify(starter, times(2)).accept(outcome);
190         assertEquals(1, count.get());
191
192         // repeat with no start-callback - no additional calls expected
193         params.toBuilder().startCallback(null).build().callbackStarted(outcome);
194         verify(starter, times(2)).accept(outcome);
195         assertEquals(1, count.get());
196
197         // should not call complete-callback
198         verify(completer, never()).accept(any());
199     }
200
201     @Test
202     public void testCallbackCompleted() {
203         params.callbackCompleted(outcome);
204         verify(completer).accept(outcome);
205
206         // modify completer to throw an exception
207         AtomicInteger count = new AtomicInteger();
208         doAnswer(args -> {
209             count.incrementAndGet();
210             throw new IllegalStateException(EXPECTED_EXCEPTION);
211         }).when(completer).accept(outcome);
212
213         params.callbackCompleted(outcome);
214         verify(completer, times(2)).accept(outcome);
215         assertEquals(1, count.get());
216
217         // repeat with no complete-callback - no additional calls expected
218         params.toBuilder().completeCallback(null).build().callbackCompleted(outcome);
219         verify(completer, times(2)).accept(outcome);
220         assertEquals(1, count.get());
221
222         // should not call start-callback
223         verify(starter, never()).accept(any());
224     }
225
226     @Test
227     public void testValidateFields() {
228         testValidate("actor", "null", bldr -> bldr.actor(null));
229         testValidate("actorService", "null", bldr -> bldr.actorService(null));
230         testValidate("context", "null", bldr -> bldr.context(null));
231         testValidate("executor", "null", bldr -> bldr.executor(null));
232         testValidate("operation", "null", bldr -> bldr.operation(null));
233         testValidate("target", "null", bldr -> bldr.targetEntity(null));
234
235         // check edge cases
236         assertTrue(params.toBuilder().build().validate().isValid());
237
238         // these can be null
239         assertTrue(params.toBuilder().payload(null).retry(null).target(null).timeoutSec(null).startCallback(null)
240                         .completeCallback(null).build().validate().isValid());
241
242         // test with minimal fields
243         assertTrue(ControlLoopOperationParams.builder().actorService(actorService).context(context).actor(ACTOR)
244                         .operation(OPERATION).targetEntity(TARGET_ENTITY).build().validate().isValid());
245     }
246
247     private void testValidate(String fieldName, String expected,
248                     Function<ControlLoopOperationParamsBuilder, ControlLoopOperationParamsBuilder> makeInvalid) {
249
250         // original params should be valid
251         BeanValidationResult result = params.validate();
252         assertTrue(fieldName, result.isValid());
253
254         // make invalid params
255         result = makeInvalid.apply(params.toBuilder()).build().validate();
256         assertFalse(fieldName, result.isValid());
257         assertThat(result.getResult()).contains(fieldName).contains(expected);
258     }
259
260     @Test
261     public void testBuilder_testToBuilder() {
262         assertEquals(params, params.toBuilder().build());
263     }
264
265     @Test
266     public void testGetActor() {
267         assertSame(ACTOR, params.getActor());
268     }
269
270     @Test
271     public void testGetActorService() {
272         assertSame(actorService, params.getActorService());
273     }
274
275     @Test
276     public void testGetContext() {
277         assertSame(context, params.getContext());
278     }
279
280     @Test
281     public void testGetExecutor() {
282         assertSame(executor, params.getExecutor());
283
284         // should use default when unspecified
285         assertSame(ForkJoinPool.commonPool(), ControlLoopOperationParams.builder().build().getExecutor());
286     }
287
288     @Test
289     public void testGetOperation() {
290         assertSame(OPERATION, params.getOperation());
291     }
292
293     @Test
294     public void testGetPayload() {
295         assertSame(payload, params.getPayload());
296
297         // should be null when unspecified
298         assertNull(ControlLoopOperationParams.builder().build().getPayload());
299     }
300
301     @Test
302     public void test() {
303         assertTrue(params.isPreprocessed());
304
305         // should be false when unspecified
306         assertFalse(ControlLoopOperationParams.builder().build().isPreprocessed());
307     }
308
309     @Test
310     public void testGetRetry() {
311         assertSame(RETRY, params.getRetry());
312
313         // should be null when unspecified
314         assertNull(ControlLoopOperationParams.builder().build().getRetry());
315     }
316
317     @Test
318     public void testTarget() {
319         assertSame(TARGET, params.getTarget());
320
321         // should be null when unspecified
322         assertNull(ControlLoopOperationParams.builder().build().getTarget());
323     }
324
325     @Test
326     public void testGetTimeoutSec() {
327         assertSame(TIMEOUT, params.getTimeoutSec());
328
329         // should be 300 when unspecified
330         assertEquals(Integer.valueOf(300), ControlLoopOperationParams.builder().build().getTimeoutSec());
331
332         // null should be ok too
333         assertNull(ControlLoopOperationParams.builder().timeoutSec(null).build().getTimeoutSec());
334     }
335
336     @Test
337     public void testGetStartCallback() {
338         assertSame(starter, params.getStartCallback());
339     }
340
341     @Test
342     public void testGetCompleteCallback() {
343         assertSame(completer, params.getCompleteCallback());
344     }
345
346     @Test
347     public void testGetTargetEntity() {
348         assertEquals(TARGET_ENTITY, params.getTargetEntity());
349     }
350 }