11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/* 21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2009 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.base.Preconditions.checkState; 201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.util.concurrent.Futures.immediateFuture; 211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.util.concurrent.JdkFutureAdapters.listenInPoolThread; 221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.util.concurrent.MoreExecutors.sameThreadExecutor; 231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static java.util.concurrent.Executors.newCachedThreadPool; 241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static java.util.concurrent.TimeUnit.SECONDS; 251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.testing.NullPointerTester; 271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.util.concurrent.FuturesTest.ExecutorSpy; 281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.util.concurrent.FuturesTest.SingleCallListener; 291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport junit.framework.AssertionFailedError; 311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport junit.framework.TestCase; 321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.CountDownLatch; 341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.ExecutorService; 351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.Future; 361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.TimeUnit; 371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/** 391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unit tests for {@link JdkFutureAdapters}. 401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Sven Mawson 421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Kurt Alfred Kluever 431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic class JdkFutureAdaptersTest extends TestCase { 451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final String DATA1 = "data"; 461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testListenInPoolThreadReturnsSameFuture() throws Exception { 481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ListenableFuture<String> listenableFuture = immediateFuture(DATA1); 491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(listenableFuture, listenInPoolThread(listenableFuture)); 501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testListenInPoolThreadIgnoresExecutorWhenDelegateIsDone() 531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throws Exception { 541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert NonListenableSettableFuture<String> abstractFuture = 551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert NonListenableSettableFuture.create(); 561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert abstractFuture.set(DATA1); 571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ExecutorSpy spy = new ExecutorSpy(sameThreadExecutor()); 581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ListenableFuture<String> listenableFuture = 591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert listenInPoolThread(abstractFuture, spy); 601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SingleCallListener singleCallListener = new SingleCallListener(); 621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert singleCallListener.expectCall(); 631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(spy.wasExecuted); 651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(singleCallListener.wasCalled()); 661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(listenableFuture.isDone()); // We call AbstractFuture#set above. 671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // #addListener() will run the listener immediately because the Future is 691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // already finished (we explicitly set the result of it above). 701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert listenableFuture.addListener(singleCallListener, sameThreadExecutor()); 711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(DATA1, listenableFuture.get()); 721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // 'spy' should have been ignored since 'abstractFuture' was done before 741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // a listener was added. 751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(spy.wasExecuted); 761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(singleCallListener.wasCalled()); 771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(listenableFuture.isDone()); 781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testListenInPoolThreadUsesGivenExecutor() throws Exception { 811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ExecutorService executorService = newCachedThreadPool( 821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new ThreadFactoryBuilder().setDaemon(true).build()); 831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert NonListenableSettableFuture<String> abstractFuture = 841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert NonListenableSettableFuture.create(); 851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ExecutorSpy spy = new ExecutorSpy(executorService); 861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ListenableFuture<String> listenableFuture = 871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert listenInPoolThread(abstractFuture, spy); 881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SingleCallListener singleCallListener = new SingleCallListener(); 901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert singleCallListener.expectCall(); 911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(spy.wasExecuted); 931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(singleCallListener.wasCalled()); 941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(listenableFuture.isDone()); 951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert listenableFuture.addListener(singleCallListener, executorService); 971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert abstractFuture.set(DATA1); 981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(DATA1, listenableFuture.get()); 991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert singleCallListener.waitForCall(); 1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(spy.wasExecuted); 1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(singleCallListener.wasCalled()); 1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(listenableFuture.isDone()); 1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * A Future that doesn't implement ListenableFuture, useful for testing 1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * listenInPoolThread. 1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final class NonListenableSettableFuture<V> 1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert extends ForwardingFuture<V> { 1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static <V> NonListenableSettableFuture<V> create() { 1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new NonListenableSettableFuture<V>(); 1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final SettableFuture<V> delegate = SettableFuture.create(); 1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected Future<V> delegate() { 1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return delegate; 1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert void set(V value) { 1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert delegate.set(value); 1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final class RuntimeExceptionThrowingFuture<V> 1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert implements Future<V> { 1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final CountDownLatch allowGetToComplete = new CountDownLatch(1); 1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean cancel(boolean mayInterruptIfRunning) { 1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new AssertionFailedError(); 1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V get() throws InterruptedException { 1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /* 1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Wait a little to give us time to call addListener before the future's 1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * value is set in addition to the call we'll make after then. 1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert allowGetToComplete.await(1, SECONDS); 1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new RuntimeException("expected, should be caught"); 1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V get(long timeout, TimeUnit unit) { 1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new AssertionFailedError(); 1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean isCancelled() { 1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new AssertionFailedError(); 1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean isDone() { 1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /* 1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * If isDone is true during the call to listenInPoolThread, 1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * listenInPoolThread doesn't start a thread. Make sure it's false the 1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * first time through (and forever after, since no one else cares about 1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * it). 1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final class RecordingRunnable implements Runnable { 1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final CountDownLatch wasRun = new CountDownLatch(1); 1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // synchronized so that checkState works as expected. 1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public synchronized void run() { 1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkState(wasRun.getCount() > 0); 1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert wasRun.countDown(); 1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testListenInPoolThreadRunsListenerAfterRuntimeException() 1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throws Exception { 1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert RuntimeExceptionThrowingFuture<String> input = 1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new RuntimeExceptionThrowingFuture<String>(); 1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /* 1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * The compiler recognizes that "input instanceof ListenableFuture" is 1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * impossible. We want the test, though, in case that changes in the future, 1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * so we use isInstance instead. 1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse("Can't test the main listenInPoolThread path " 1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert + "if the input is already a ListenableFuture", 1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ListenableFuture.class.isInstance(input)); 1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ListenableFuture<String> listenable = listenInPoolThread(input); 1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /* 1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * This will occur before the waiting get() in the 1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * listenInPoolThread-spawned thread completes: 1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert RecordingRunnable earlyListener = new RecordingRunnable(); 1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert listenable.addListener(earlyListener, sameThreadExecutor()); 1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert input.allowGetToComplete.countDown(); 2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Now give the get() thread time to finish: 2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(earlyListener.wasRun.await(1, SECONDS)); 2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Now test an additional addListener call, which will be run in-thread: 2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert RecordingRunnable lateListener = new RecordingRunnable(); 2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert listenable.addListener(lateListener, sameThreadExecutor()); 2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(lateListener.wasRun.await(1, SECONDS)); 2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testNullArguments() throws Exception { 2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert NullPointerTester tester = new NullPointerTester(); 2111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert tester.setDefault(Future.class, immediateFuture(DATA1)); 2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert tester.testAllPublicStaticMethods(JdkFutureAdapters.class); 2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert} 215