11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/* 21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2008 The Guava Authors 31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License"); 51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * you may not use this file except in compliance with the License. 61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * You may obtain a copy of the License at 71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0 91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software 111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS, 121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * See the License for the specific language governing permissions and 141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * limitations under the License. 151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.util.concurrent; 181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.collect.Iterables.getOnlyElement; 201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.util.concurrent.MoreExecutors.listeningDecorator; 211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.util.concurrent.MoreExecutors.sameThreadExecutor; 221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static java.util.concurrent.TimeUnit.SECONDS; 231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static org.junit.contrib.truth.Truth.ASSERT; 241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Throwables; 261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.ImmutableList; 271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport junit.framework.TestCase; 291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Collections; 311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.List; 321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.Callable; 331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.CyclicBarrier; 341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.ExecutorService; 351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.Future; 361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.RejectedExecutionException; 371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.TimeUnit; 381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.atomic.AtomicReference; 391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/** 411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Tests for MoreExecutors. 421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Kyle Littlefield (klittle) 441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic class MoreExecutorsTest extends TestCase { 461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testSameThreadExecutorServiceInThreadExecution() 481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throws Exception { 491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final ListeningExecutorService executor = 501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert MoreExecutors.sameThreadExecutor(); 511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final ThreadLocal<Integer> threadLocalCount = new ThreadLocal<Integer>() { 521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert protected Integer initialValue() { 541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return 0; 551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final AtomicReference<Throwable> throwableFromOtherThread = 581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new AtomicReference<Throwable>(null); 591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Runnable incrementTask = 601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new Runnable() { 611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void run() { 631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert threadLocalCount.set(threadLocalCount.get() + 1); 641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Thread otherThread = new Thread( 681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new Runnable() { 691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void run() { 711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Future<?> future = executor.submit(incrementTask); 731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(future.isDone()); 741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, threadLocalCount.get().intValue()); 751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (Throwable Throwable) { 761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throwableFromOtherThread.set(Throwable); 771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }); 801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert otherThread.start(); 821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ListenableFuture<?> future = executor.submit(incrementTask); 841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(future.isDone()); 851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertListenerRunImmediately(future); 861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, threadLocalCount.get().intValue()); 871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert otherThread.join(1000); 881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(Thread.State.TERMINATED, otherThread.getState()); 891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Throwable throwable = throwableFromOtherThread.get(); 901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull("Throwable from other thread: " 911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert + (throwable == null ? null : Throwables.getStackTraceAsString(throwable)), 921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throwableFromOtherThread.get()); 931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testSameThreadExecutorInvokeAll() throws Exception { 961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final ExecutorService executor = MoreExecutors.sameThreadExecutor(); 971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final ThreadLocal<Integer> threadLocalCount = new ThreadLocal<Integer>() { 981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert protected Integer initialValue() { 1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return 0; 1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Callable<Integer> incrementTask = new Callable<Integer>() { 1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Integer call() { 1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int i = threadLocalCount.get(); 1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert threadLocalCount.set(i + 1); 1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return i; 1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert List<Future<Integer>> futures = 1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert executor.invokeAll(Collections.nCopies(10, incrementTask)); 1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < 10; i++) { 1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Future<Integer> future = futures.get(i); 1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue("Task should have been run before being returned", future.isDone()); 1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(i, future.get().intValue()); 1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(10, threadLocalCount.get().intValue()); 1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testSameThreadExecutorServiceTermination() 1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throws Exception { 1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final ExecutorService executor = MoreExecutors.sameThreadExecutor(); 1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final CyclicBarrier barrier = new CyclicBarrier(2); 1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final AtomicReference<Throwable> throwableFromOtherThread = 1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new AtomicReference<Throwable>(null); 1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Runnable doNothingRunnable = new Runnable() { 1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public void run() { 1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }}; 1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Thread otherThread = new Thread(new Runnable() { 1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void run() { 1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Future<?> future = executor.submit(new Callable<Void>() { 1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Void call() throws Exception { 1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // WAIT #1 1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert barrier.await(1, TimeUnit.SECONDS); 1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // WAIT #2 1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert barrier.await(1, TimeUnit.SECONDS); 1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(executor.isShutdown()); 1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(executor.isTerminated()); 1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // WAIT #3 1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert barrier.await(1, TimeUnit.SECONDS); 1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return null; 1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }); 1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(future.isDone()); 1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(executor.isShutdown()); 1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(executor.isTerminated()); 1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (Throwable Throwable) { 1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throwableFromOtherThread.set(Throwable); 1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }}); 1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert otherThread.start(); 1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // WAIT #1 1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert barrier.await(1, TimeUnit.SECONDS); 1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(executor.isShutdown()); 1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(executor.isTerminated()); 1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert executor.shutdown(); 1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(executor.isShutdown()); 1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert executor.submit(doNothingRunnable); 1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fail("Should have encountered RejectedExecutionException"); 1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (RejectedExecutionException ex) { 1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // good to go 1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(executor.isTerminated()); 1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // WAIT #2 1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert barrier.await(1, TimeUnit.SECONDS); 1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(executor.awaitTermination(20, TimeUnit.MILLISECONDS)); 1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // WAIT #3 1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert barrier.await(1, TimeUnit.SECONDS); 1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(executor.awaitTermination(1, TimeUnit.SECONDS)); 1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(executor.awaitTermination(0, TimeUnit.SECONDS)); 1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(executor.isShutdown()); 1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert executor.submit(doNothingRunnable); 1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fail("Should have encountered RejectedExecutionException"); 1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (RejectedExecutionException ex) { 1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // good to go 1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(executor.isTerminated()); 1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert otherThread.join(1000); 1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(Thread.State.TERMINATED, otherThread.getState()); 1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Throwable throwable = throwableFromOtherThread.get(); 2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull("Throwable from other thread: " 2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert + (throwable == null ? null : Throwables.getStackTraceAsString(throwable)), 2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throwableFromOtherThread.get()); 2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testListeningDecorator() throws Exception { 2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ListeningExecutorService service = 2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert listeningDecorator(MoreExecutors.sameThreadExecutor()); 2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(service, listeningDecorator(service)); 2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert List<Callable<String>> callables = 2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ImmutableList.of(Callables.returning("x")); 2111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert List<Future<String>> results; 2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert results = service.invokeAll(callables); 2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ASSERT.that(getOnlyElement(results)).isA(ListenableFutureTask.class); 2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert results = service.invokeAll(callables, 1, SECONDS); 2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ASSERT.that(getOnlyElement(results)).isA(ListenableFutureTask.class); 2181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /* 2201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * TODO(cpovirk): move ForwardingTestCase somewhere common, and use it to 2211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * test the forwarded methods 2221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static void assertListenerRunImmediately(ListenableFuture<?> future) { 2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CountingRunnable listener = new CountingRunnable(); 2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert future.addListener(listener, sameThreadExecutor()); 2281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, listener.count); 2291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final class CountingRunnable implements Runnable { 2321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int count; 2331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 2351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void run() { 2361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert count++; 2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert} 240