2 * ============LICENSE_START=======================================================
3 * feature-test-transaction
4 * ================================================================================
5 * Copyright (C) 2017-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.drools.testtransaction;
23 import static org.junit.Assert.assertEquals;
24 import static org.junit.Assert.assertFalse;
25 import static org.junit.Assert.assertNotNull;
26 import static org.junit.Assert.assertTrue;
27 import static org.mockito.ArgumentMatchers.any;
28 import static org.mockito.ArgumentMatchers.anyBoolean;
29 import static org.mockito.ArgumentMatchers.anyString;
30 import static org.mockito.Mockito.mock;
31 import static org.mockito.Mockito.never;
32 import static org.mockito.Mockito.times;
33 import static org.mockito.Mockito.verify;
34 import static org.mockito.Mockito.when;
36 import java.util.Arrays;
37 import java.util.Collections;
38 import java.util.EventObject;
39 import java.util.List;
41 import java.util.TreeMap;
42 import java.util.concurrent.atomic.AtomicInteger;
43 import org.junit.Before;
44 import org.junit.Test;
45 import org.onap.policy.drools.controller.DroolsController;
46 import org.onap.policy.drools.core.PolicyContainer;
47 import org.onap.policy.drools.system.PolicyController;
49 public class TestTransactionAdditionalTest {
51 private static final int MAX_SLEEP_COUNT = 3;
52 private static final String EXPECTED = "expected exception";
53 private static final String CONTROLLER1 = "controller-a";
54 private static final String CONTROLLER2 = "controller-b";
55 private static final String CONTROLLER3 = "controller-c";
56 private static final String SESSION1 = "session-a";
57 private static final String SESSION2 = "session-b";
58 private static final List<String> sessions = Arrays.asList(SESSION1, SESSION2);
59 private static final List<Object> facts = Arrays.asList(0L);
61 private Thread theThread;
62 private PolicyController controller;
63 private PolicyController controller2;
64 private PolicyController controller3;
65 private Runnable theAction;
66 private long waitJoinMs;
67 private long doSleepMs;
68 private DroolsController drools;
69 private PolicyContainer container;
70 private Map<String, TtControllerTask> name2task;
71 private TtControllerTask task;
72 private TtControllerTask task2;
73 private TtControllerTask task3;
74 private TestTransTImplTester impl;
77 * Initialize objects for each test.
81 theThread = mock(Thread.class);
82 controller = mock(PolicyController.class);
83 controller2 = mock(PolicyController.class);
84 controller3 = mock(PolicyController.class);
88 drools = mock(DroolsController.class);
89 container = mock(PolicyContainer.class);
90 task2 = mock(TtControllerTask.class);
91 task3 = mock(TtControllerTask.class);
92 name2task = new TreeMap<>();
94 when(drools.getSessionNames()).thenReturn(sessions);
95 when(drools.isBrained()).thenReturn(true);
96 when(drools.factQuery(anyString(), anyString(), anyString(), anyBoolean())).thenReturn(facts);
97 when(drools.getContainer()).thenReturn(container);
99 when(controller.getName()).thenReturn(CONTROLLER1);
100 when(controller.getDrools()).thenReturn(drools);
101 when(controller.isAlive()).thenReturn(true);
103 when(controller2.getName()).thenReturn(CONTROLLER2);
104 when(controller2.getDrools()).thenReturn(drools);
105 when(controller2.isAlive()).thenReturn(true);
107 when(controller3.getName()).thenReturn(CONTROLLER3);
108 when(controller3.getDrools()).thenReturn(drools);
109 when(controller3.isAlive()).thenReturn(true);
111 task = new TestTransControllerTaskTester(controller);
113 name2task.put(CONTROLLER1, task);
114 name2task.put(CONTROLLER2, task2);
115 name2task.put(CONTROLLER3, task3);
117 impl = new TestTransTImplTester();
121 public void testTestTransactionImpl() {
122 assertNotNull(TestTransactionConstants.getManager());
126 public void testTestTransactionImplRegister_testTestTransactionImplUnregister() {
127 task = mock(TtControllerTask.class);
128 when(task.isAlive()).thenReturn(true);
129 name2task.put(CONTROLLER1, task);
131 impl.register(controller);
132 impl.register(controller2);
135 impl.register(controller);
137 // re-register when task is not running
139 // give controller3 same name as controller1 -> task3 replaces task
140 when(controller3.getName()).thenReturn(CONTROLLER1);
141 name2task.put(CONTROLLER1, task3);
142 when(task.isAlive()).thenReturn(false);
143 impl.register(controller3);
145 impl.unregister(controller);
146 verify(task, never()).stop();
147 verify(task2, never()).stop();
148 verify(task3).stop();
150 impl.unregister(controller2);
151 verify(task2).stop();
153 // unregister again - stop() should not be called again
154 impl.unregister(controller3);
155 verify(task3).stop();
157 // unregister original controller - no stop() should be called again
158 impl.unregister(controller);
159 verify(task, never()).stop();
160 verify(task2).stop();
161 verify(task3).stop();
165 public void testTestTransactionControllerTaskFactory() throws Exception {
166 task = new TtControllerTask(controller) {
168 protected Thread makeThread(Runnable action) {
173 protected void joinThread(long waitTimeMs) throws InterruptedException {
179 assertEquals(Thread.currentThread(), task.getCurrentThread());
183 public void testTestTransactionControllerTask() {
184 assertEquals(task, theAction);
185 assertTrue(task.isAlive());
186 assertEquals(controller, task.getController());
187 assertEquals(theThread, task.getThread());
189 verify(theThread).start();
193 public void testTestTransactionControllerTaskGetController() {
194 assertEquals(controller, task.getController());
198 public void testTestTransactionControllerTaskGetThread() {
199 assertEquals(theThread, task.getThread());
203 public void testTestTransactionControllerTaskStop() throws Exception {
205 assertFalse(task.isAlive());
206 verify(theThread).interrupt();
207 assertTrue(waitJoinMs > 0);
209 // throw interrupt during join()
211 task = new TestTransControllerTaskTester(controller) {
213 protected void joinThread(long waitTimeMs) throws InterruptedException {
214 waitJoinMs = waitTimeMs;
215 throw new InterruptedException(EXPECTED);
219 assertFalse(task.isAlive());
220 verify(theThread, times(2)).interrupt();
221 assertTrue(waitJoinMs > 0);
225 public void testTestTransactionControllerTaskRun() {
227 assertFalse(task.isAlive());
228 verify(theThread, never()).interrupt();
229 verify(controller, times(MAX_SLEEP_COUNT + 1)).isAlive();
230 assertTrue(doSleepMs > 0);
234 when(drools.isBrained()).thenReturn(false);
236 assertFalse(task.isAlive());
237 verify(controller, never()).isAlive();
238 assertEquals(-1, doSleepMs);
240 // controller not running
242 when(controller.isAlive()).thenReturn(false);
244 assertFalse(task.isAlive());
245 assertEquals(-1, doSleepMs);
247 // controller is locked
249 when(controller.isLocked()).thenReturn(true);
251 assertFalse(task.isAlive());
252 assertEquals(-1, doSleepMs);
254 // un-brain during sleep
256 task = new TestTransControllerTaskTester(controller) {
258 protected void doSleep(long sleepMs) throws InterruptedException {
259 when(drools.isBrained()).thenReturn(false);
260 super.doSleep(sleepMs);
264 assertFalse(task.isAlive());
265 // only hit top of the loop twice
266 verify(controller, times(2)).isAlive();
267 assertTrue(doSleepMs > 0);
271 task = new TestTransControllerTaskTester(controller) {
273 protected void doSleep(long sleepMs) throws InterruptedException {
275 super.doSleep(sleepMs);
279 assertFalse(task.isAlive());
280 // only hit top of the loop twice
281 verify(controller, times(2)).isAlive();
282 assertTrue(doSleepMs > 0);
284 // isInterrupted() returns true the first time, interrupt next time
286 AtomicInteger count = new AtomicInteger(1);
287 when(theThread.isInterrupted()).thenAnswer(args -> {
288 if (count.decrementAndGet() >= 0) {
291 throw new InterruptedException(EXPECTED);
295 assertFalse(task.isAlive());
296 verify(controller, times(2)).isAlive();
297 // doSleep() should not be called
298 assertEquals(-1, doSleepMs);
300 // interrupt during sleep
302 task = new TestTransControllerTaskTester(controller) {
304 protected void doSleep(long sleepMs) throws InterruptedException {
305 super.doSleep(sleepMs);
306 throw new InterruptedException(EXPECTED);
310 assertFalse(task.isAlive());
311 verify(theThread).interrupt();
312 // only hit top of the loop once
313 verify(controller).isAlive();
314 assertTrue(doSleepMs > 0);
316 // stop() during factQuery()
318 when(drools.factQuery(anyString(), anyString(), anyString(), anyBoolean())).thenAnswer(args -> {
323 assertFalse(task.isAlive());
324 // only hit top of the loop once
325 verify(controller).isAlive();
327 // exception during isBrained() check
329 when(drools.isBrained()).thenThrow(new IllegalArgumentException(EXPECTED));
331 assertFalse(task.isAlive());
333 // other exception during isBrained() check
335 when(drools.isBrained()).thenThrow(new RuntimeException(EXPECTED));
337 assertFalse(task.isAlive());
341 public void testTestTransactionControllerTaskInjectTxIntoSessions() {
343 verify(container, times(MAX_SLEEP_COUNT * sessions.size())).insert(anyString(), any(EventObject.class));
347 when(drools.factQuery(anyString(), anyString(), anyString(), anyBoolean())).thenReturn(null);
349 verify(container, never()).insert(anyString(), any());
353 when(drools.factQuery(anyString(), anyString(), anyString(), anyBoolean())).thenReturn(Collections.emptyList());
355 verify(container, never()).insert(anyString(), any());
359 public void testTestTransactionControllerTaskToString() {
360 assertTrue(task.toString().startsWith("TTControllerTask ["));
364 * TestTransaction with overridden methods.
366 private class TestTransTImplTester extends TtImpl {
369 protected TtControllerTask makeControllerTask(PolicyController controller) {
370 return name2task.get(controller.getName());
375 * Controller task with overridden methods.
377 private class TestTransControllerTaskTester extends TtControllerTask {
378 private int sleepCount = MAX_SLEEP_COUNT;
380 public TestTransControllerTaskTester(PolicyController controller) {
385 protected Thread makeThread(Runnable action) {
391 protected void joinThread(long waitTimeMs) throws InterruptedException {
392 waitJoinMs = waitTimeMs;
396 protected void doSleep(long sleepMs) throws InterruptedException {
399 if (--sleepCount <= 0) {
400 when(controller.isAlive()).thenReturn(false);
405 protected Thread getCurrentThread() {