1 /* 2 * Copyright (C) 2009 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.common.util.concurrent; 18 19 import junit.framework.TestCase; 20 21 import java.util.concurrent.Callable; 22 import java.util.concurrent.CountDownLatch; 23 import java.util.concurrent.ExecutionException; 24 import java.util.concurrent.ExecutorService; 25 import java.util.concurrent.Executors; 26 import java.util.concurrent.TimeUnit; 27 28 /** 29 * Test case for {@link ListenableFutureTask}. 30 * 31 * @author Sven Mawson 32 */ 33 public class ListenableFutureTaskTest extends TestCase { 34 35 private ExecutorService exec; 36 37 protected final CountDownLatch runLatch = new CountDownLatch(1); 38 protected final CountDownLatch taskLatch = new CountDownLatch(1); 39 protected final CountDownLatch listenerLatch = new CountDownLatch(1); 40 41 protected volatile boolean throwException = false; 42 43 protected final ListenableFutureTask<Integer> task = 44 ListenableFutureTask.create(new Callable<Integer>() { 45 @Override 46 public Integer call() throws Exception { 47 runLatch.countDown(); 48 taskLatch.await(); 49 if (throwException) { 50 throw new IllegalStateException("Fail"); 51 } 52 return 25; 53 } 54 }); 55 56 @Override 57 protected void setUp() throws Exception { 58 super.setUp(); 59 60 exec = Executors.newCachedThreadPool(); 61 62 task.addListener(new Runnable() { 63 @Override 64 public void run() { 65 listenerLatch.countDown(); 66 } 67 }, MoreExecutors.sameThreadExecutor()); 68 } 69 70 @Override 71 protected void tearDown() throws Exception { 72 if (exec != null) { 73 exec.shutdown(); 74 } 75 76 super.tearDown(); 77 } 78 79 public void testListenerDoesNotRunUntilTaskCompletes() throws Exception { 80 81 // Test default state of not started. 82 assertEquals(1, listenerLatch.getCount()); 83 assertFalse(task.isDone()); 84 assertFalse(task.isCancelled()); 85 86 // Start the task to put it in the RUNNING state. Have to use a separate 87 // thread because the task will block on the task latch after unblocking 88 // the run latch. 89 exec.execute(task); 90 runLatch.await(); 91 assertEquals(1, listenerLatch.getCount()); 92 assertFalse(task.isDone()); 93 assertFalse(task.isCancelled()); 94 95 // Finish the task by unblocking the task latch. Then wait for the 96 // listener to be called by blocking on the listener latch. 97 taskLatch.countDown(); 98 assertEquals(25, task.get().intValue()); 99 assertTrue(listenerLatch.await(5, TimeUnit.SECONDS)); 100 assertTrue(task.isDone()); 101 assertFalse(task.isCancelled()); 102 } 103 104 public void testListenerCalledOnException() throws Exception { 105 throwException = true; 106 107 // Start up the task and unblock the latch to finish the task. 108 exec.execute(task); 109 runLatch.await(); 110 taskLatch.countDown(); 111 112 try { 113 task.get(5, TimeUnit.SECONDS); 114 fail("Should have propagated the failure."); 115 } catch (ExecutionException e) { 116 assertEquals(IllegalStateException.class, e.getCause().getClass()); 117 } 118 119 assertTrue(listenerLatch.await(5, TimeUnit.SECONDS)); 120 assertTrue(task.isDone()); 121 assertFalse(task.isCancelled()); 122 } 123 124 public void testListenerCalledOnCancelFromNotRunning() throws Exception { 125 task.cancel(false); 126 assertTrue(task.isDone()); 127 assertTrue(task.isCancelled()); 128 assertEquals(1, runLatch.getCount()); 129 130 // Wait for the listeners to be called, don't rely on the same-thread exec. 131 listenerLatch.await(5, TimeUnit.SECONDS); 132 assertTrue(task.isDone()); 133 assertTrue(task.isCancelled()); 134 135 // Make sure we didn't run anything. 136 assertEquals(1, runLatch.getCount()); 137 } 138 139 public void testListenerCalledOnCancelFromRunning() throws Exception { 140 exec.execute(task); 141 runLatch.await(); 142 143 // Task has started up, cancel it while it's running. 144 task.cancel(true); 145 assertTrue(task.isDone()); 146 assertTrue(task.isCancelled()); 147 assertEquals(1, taskLatch.getCount()); 148 149 // Wait for the listeners to be called. 150 listenerLatch.await(5, TimeUnit.SECONDS); 151 assertTrue(task.isDone()); 152 assertTrue(task.isCancelled()); 153 assertEquals(1, taskLatch.getCount()); 154 } 155 } 156