2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2020-2021 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.actorserviceprovider.parameters;
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;
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.junit.runner.RunWith;
50 import org.mockito.Mock;
51 import org.mockito.junit.MockitoJUnitRunner;
52 import org.onap.policy.common.parameters.BeanValidationResult;
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.parameters.ControlLoopOperationParams.ControlLoopOperationParamsBuilder;
58 import org.onap.policy.controlloop.actorserviceprovider.spi.Actor;
60 @RunWith(MockitoJUnitRunner.class)
61 public class ControlLoopOperationParamsTest {
62 private static final String NULL_MSG = "null";
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 Integer RETRY = 3;
67 private static final Integer TIMEOUT = 100;
68 private static final UUID REQ_ID = UUID.randomUUID();
74 private ActorService actorService;
77 private Consumer<OperationOutcome> completer;
80 private Executor executor;
83 private CompletableFuture<OperationOutcome> operFuture;
86 private Operator operator;
89 private Operation operation;
92 private Consumer<OperationOutcome> starter;
94 private Map<String, Object> payload;
96 private ControlLoopOperationParams params;
97 private OperationOutcome outcome;
101 * Initializes mocks and sets {@link #params} to a fully-loaded set of parameters.
104 public void setUp() {
105 when(actorService.getActor(ACTOR)).thenReturn(actor);
106 when(actor.getOperator(OPERATION)).thenReturn(operator);
107 when(operator.buildOperation(any())).thenReturn(operation);
108 when(operation.start()).thenReturn(operFuture);
110 payload = new TreeMap<>();
112 params = ControlLoopOperationParams.builder().actorService(actorService).completeCallback(completer)
113 .requestId(REQ_ID).executor(executor).actor(ACTOR).operation(OPERATION).payload(payload)
114 .retry(RETRY).timeoutSec(TIMEOUT)
115 .startCallback(starter).build();
117 outcome = params.makeOutcome();
121 public void testStart() {
122 assertThatIllegalArgumentException().isThrownBy(() -> params.toBuilder().requestId(null).build().start());
124 assertSame(operFuture, params.start());
128 public void testBuild() {
129 assertThatIllegalArgumentException().isThrownBy(() -> params.toBuilder().requestId(null).build().build());
131 assertSame(operation, params.build());
135 public void testGetRequestId() {
136 assertSame(REQ_ID, params.getRequestId());
140 public void testMakeOutcome() {
141 assertEquals(ACTOR, outcome.getActor());
142 assertEquals(OPERATION, outcome.getOperation());
143 assertNull(outcome.getStart());
144 assertNull(outcome.getEnd());
145 assertNull(outcome.getSubRequestId());
146 assertNotNull(outcome.getResult());
147 assertNull(outcome.getMessage());
151 public void testCallbackStarted() {
152 params.callbackStarted(outcome);
153 verify(starter).accept(outcome);
155 // modify starter to throw an exception
156 AtomicInteger count = new AtomicInteger();
158 count.incrementAndGet();
159 throw new IllegalStateException(EXPECTED_EXCEPTION);
160 }).when(starter).accept(outcome);
162 params.callbackStarted(outcome);
163 verify(starter, times(2)).accept(outcome);
164 assertEquals(1, count.get());
166 // repeat with no start-callback - no additional calls expected
167 params.toBuilder().startCallback(null).build().callbackStarted(outcome);
168 verify(starter, times(2)).accept(outcome);
169 assertEquals(1, count.get());
171 // should not call complete-callback
172 verify(completer, never()).accept(any());
176 public void testCallbackCompleted() {
177 params.callbackCompleted(outcome);
178 verify(completer).accept(outcome);
180 // modify completer to throw an exception
181 AtomicInteger count = new AtomicInteger();
183 count.incrementAndGet();
184 throw new IllegalStateException(EXPECTED_EXCEPTION);
185 }).when(completer).accept(outcome);
187 params.callbackCompleted(outcome);
188 verify(completer, times(2)).accept(outcome);
189 assertEquals(1, count.get());
191 // repeat with no complete-callback - no additional calls expected
192 params.toBuilder().completeCallback(null).build().callbackCompleted(outcome);
193 verify(completer, times(2)).accept(outcome);
194 assertEquals(1, count.get());
196 // should not call start-callback
197 verify(starter, never()).accept(any());
201 public void testValidateFields() {
202 testValidate("actor", NULL_MSG, bldr -> bldr.actor(null));
203 testValidate("actorService", NULL_MSG, bldr -> bldr.actorService(null));
204 testValidate("executor", NULL_MSG, bldr -> bldr.executor(null));
205 testValidate("operation", NULL_MSG, bldr -> bldr.operation(null));
206 testValidate("requestId", NULL_MSG, bldr -> bldr.requestId(null));
208 // has no target entity
209 BeanValidationResult result = params.toBuilder().build().validate();
210 assertTrue(result.isValid());
213 assertTrue(params.toBuilder().build().validate().isValid());
216 assertTrue(params.toBuilder().payload(null).retry(null).timeoutSec(null).startCallback(null)
217 .completeCallback(null).build().validate().isValid());
219 // test with minimal fields
220 assertTrue(ControlLoopOperationParams.builder().actorService(actorService).requestId(REQ_ID).actor(ACTOR)
221 .operation(OPERATION).build().validate().isValid());
224 private void testValidate(String fieldName, String expected,
225 Function<ControlLoopOperationParamsBuilder, ControlLoopOperationParamsBuilder> makeInvalid) {
227 // original params should be valid
228 BeanValidationResult result = params.validate();
229 assertTrue(fieldName, result.isValid());
231 // make invalid params
232 result = makeInvalid.apply(params.toBuilder()).build().validate();
233 assertFalse(fieldName, result.isValid());
234 assertThat(result.getResult()).contains(fieldName).contains(expected);
238 public void testBuilder_testToBuilder() {
239 assertEquals(params, params.toBuilder().build());
243 public void testGetActor() {
244 assertSame(ACTOR, params.getActor());
248 public void testGetActorService() {
249 assertSame(actorService, params.getActorService());
253 public void testGetExecutor() {
254 assertSame(executor, params.getExecutor());
256 // should use default when unspecified
257 assertSame(ForkJoinPool.commonPool(), ControlLoopOperationParams.builder().build().getExecutor());
261 public void testGetOperation() {
262 assertSame(OPERATION, params.getOperation());
266 public void testGetPayload() {
267 assertSame(payload, params.getPayload());
269 // should be null when unspecified
270 assertNull(ControlLoopOperationParams.builder().build().getPayload());
274 public void testGetRetry() {
275 assertSame(RETRY, params.getRetry());
277 // should be null when unspecified
278 assertNull(ControlLoopOperationParams.builder().build().getRetry());
282 public void testGetTimeoutSec() {
283 assertSame(TIMEOUT, params.getTimeoutSec());
285 // should be 300 when unspecified
286 assertEquals(Integer.valueOf(300), ControlLoopOperationParams.builder().build().getTimeoutSec());
288 // null should be ok too
289 assertNull(ControlLoopOperationParams.builder().timeoutSec(null).build().getTimeoutSec());
293 public void testGetStartCallback() {
294 assertSame(starter, params.getStartCallback());
298 public void testGetCompleteCallback() {
299 assertSame(completer, params.getCompleteCallback());