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.actorserviceprovider.pipeline;
23 import static org.assertj.core.api.Assertions.assertThatThrownBy;
24 import static org.junit.Assert.assertEquals;
25 import static org.junit.Assert.assertFalse;
26 import static org.junit.Assert.assertNotSame;
27 import static org.junit.Assert.assertNull;
28 import static org.junit.Assert.assertSame;
29 import static org.junit.Assert.assertTrue;
30 import static org.mockito.ArgumentMatchers.anyBoolean;
31 import static org.mockito.Mockito.never;
32 import static org.mockito.Mockito.verify;
34 import java.util.concurrent.CompletableFuture;
35 import java.util.concurrent.Future;
36 import java.util.concurrent.atomic.AtomicReference;
37 import java.util.function.BiConsumer;
38 import java.util.function.Function;
39 import org.junit.Before;
40 import org.junit.Test;
41 import org.mockito.Mock;
42 import org.mockito.MockitoAnnotations;
44 public class PipelineControllerFutureTest {
45 private static final IllegalStateException EXPECTED_EXCEPTION = new IllegalStateException("expected exception");
46 private static final String TEXT = "some text";
49 private Runnable runnable1;
52 private Runnable runnable2;
55 private Future<String> future1;
58 private Future<String> future2;
61 private CompletableFuture<String> compFuture;
64 private PipelineControllerFuture<String> controller;
68 * Initializes fields, including {@link #controller}. Adds all runners and futures to
73 MockitoAnnotations.initMocks(this);
75 controller = new PipelineControllerFuture<>();
77 controller.add(runnable1);
78 controller.add(future1);
79 controller.add(runnable2);
80 controller.add(future2);
84 public void testCancel_testAddFutureOfFBoolean_testAddRunnable__testIsRunning() {
85 assertTrue(controller.isRunning());
87 assertTrue(controller.cancel(false));
89 assertTrue(controller.isCancelled());
90 assertFalse(controller.isRunning());
92 verify(runnable1).run();
93 verify(runnable2).run();
94 verify(future1).cancel(anyBoolean());
95 verify(future2).cancel(anyBoolean());
97 // re-invoke; nothing should change
98 assertTrue(controller.cancel(true));
100 assertTrue(controller.isCancelled());
101 assertFalse(controller.isRunning());
103 verify(runnable1).run();
104 verify(runnable2).run();
105 verify(future1).cancel(anyBoolean());
106 verify(future2).cancel(anyBoolean());
110 public void testDelayedComplete() throws Exception {
111 controller.add(runnable1);
113 BiConsumer<String, Throwable> stopper = controller.delayedComplete();
115 // shouldn't have run yet
116 assertTrue(controller.isRunning());
117 verify(runnable1, never()).run();
119 stopper.accept(TEXT, null);
121 assertTrue(controller.isDone());
122 assertEquals(TEXT, controller.get());
124 assertFalse(controller.isRunning());
125 verify(runnable1).run();
127 // re-invoke; nothing should change
128 stopper.accept(TEXT, EXPECTED_EXCEPTION);
129 assertFalse(controller.isCompletedExceptionally());
131 assertFalse(controller.isRunning());
132 verify(runnable1).run();
136 * Tests delayedComplete() when an exception is generated.
139 public void testDelayedCompleteWithException() throws Exception {
140 controller.add(runnable1);
142 BiConsumer<String, Throwable> stopper = controller.delayedComplete();
144 // shouldn't have run yet
145 assertTrue(controller.isRunning());
146 verify(runnable1, never()).run();
148 stopper.accept(TEXT, EXPECTED_EXCEPTION);
150 assertTrue(controller.isDone());
151 assertThatThrownBy(() -> controller.get()).hasCause(EXPECTED_EXCEPTION);
153 assertFalse(controller.isRunning());
154 verify(runnable1).run();
156 // re-invoke; nothing should change
157 stopper.accept(TEXT, null);
158 assertTrue(controller.isCompletedExceptionally());
160 assertFalse(controller.isRunning());
161 verify(runnable1).run();
165 public void testDelayedRemoveFutureOfF() throws Exception {
166 BiConsumer<String, Throwable> remover = controller.delayedRemove(future1);
168 remover.accept(TEXT, EXPECTED_EXCEPTION);
170 // should not have completed the controller
171 assertFalse(controller.isDone());
173 verify(future1, never()).cancel(anyBoolean());
175 controller.delayedComplete().accept(TEXT, EXPECTED_EXCEPTION);
177 verify(future1, never()).cancel(anyBoolean());
178 verify(future2).cancel(anyBoolean());
182 public void testDelayedRemoveRunnable() throws Exception {
183 BiConsumer<String, Throwable> remover = controller.delayedRemove(runnable1);
185 remover.accept(TEXT, EXPECTED_EXCEPTION);
187 // should not have completed the controller
188 assertFalse(controller.isDone());
190 verify(runnable1, never()).run();
192 controller.delayedComplete().accept(TEXT, EXPECTED_EXCEPTION);
194 verify(runnable1, never()).run();
195 verify(runnable2).run();
199 public void testRemoveFutureOfF_testRemoveRunnable() {
200 controller.remove(runnable2);
201 controller.remove(future1);
203 controller.cancel(true);
205 verify(runnable1).run();
206 verify(runnable2, never()).run();
207 verify(future1, never()).cancel(anyBoolean());
208 verify(future2).cancel(anyBoolean());
212 public void testAddFunction() {
213 AtomicReference<String> value = new AtomicReference<>();
215 Function<String, CompletableFuture<String>> func = controller.add(input -> {
220 assertSame(compFuture, func.apply(TEXT));
221 assertEquals(TEXT, value.get());
223 verify(compFuture, never()).cancel(anyBoolean());
225 // should not have completed the controller
226 assertFalse(controller.isDone());
228 // cancel - should propagate
229 controller.cancel(false);
231 verify(compFuture).cancel(anyBoolean());
235 * Tests add(Function) when the controller is not running.
238 public void testAddFunctionNotRunning() {
239 AtomicReference<String> value = new AtomicReference<>();
241 Function<String, CompletableFuture<String>> func = controller.add(input -> {
246 controller.cancel(false);
248 CompletableFuture<String> fut = func.apply(TEXT);
249 assertNotSame(compFuture, fut);
250 assertFalse(fut.isDone());
252 assertNull(value.get());