1bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay/* 2bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay * Copyright (C) 2016 The Android Open Source Project 3bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay * 4bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay * Licensed under the Apache License, Version 2.0 (the "License"); 5bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay * you may not use this file except in compliance with the License. 6bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay * You may obtain a copy of the License at 7bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay * 8bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay * http://www.apache.org/licenses/LICENSE-2.0 9bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay * 10bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay * Unless required by applicable law or agreed to in writing, software 11bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay * distributed under the License is distributed on an "AS IS" BASIS, 12bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay * See the License for the specific language governing permissions and 14bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay * limitations under the License. 15bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay */ 16bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 17edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tanpackage com.android.documentsui.testing; 18bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 19bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKayimport static junit.framework.Assert.assertFalse; 20894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tanimport static junit.framework.Assert.assertTrue; 21894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tan 22894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tanimport android.os.Handler; 23894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tanimport android.os.Looper; 24894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tanimport android.os.SystemClock; 25bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 26bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKayimport java.util.ArrayList; 27bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKayimport java.util.Collection; 28894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tanimport java.util.Collections; 29bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKayimport java.util.List; 30bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKayimport java.util.concurrent.Callable; 31894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tanimport java.util.concurrent.CountDownLatch; 32bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKayimport java.util.concurrent.Delayed; 33bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKayimport java.util.concurrent.ExecutionException; 34bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKayimport java.util.concurrent.Future; 35bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKayimport java.util.concurrent.ScheduledExecutorService; 36bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKayimport java.util.concurrent.ScheduledFuture; 37bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKayimport java.util.concurrent.TimeUnit; 38bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKayimport java.util.concurrent.TimeoutException; 39bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 40bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKaypublic class TestScheduledExecutorService implements ScheduledExecutorService { 41bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 42bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay private List<TestFuture> scheduled = new ArrayList<>(); 43bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay private boolean shutdown; 44bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 45bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay @Override 46bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public void shutdown() { 47bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay this.shutdown = true; 48bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 49bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 50bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay @Override 51bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public List<Runnable> shutdownNow() { 52bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay this.shutdown = true; 53894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tan return Collections.emptyList(); 54bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 55bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 56edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan public void assertShutdown() { 57894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tan assertTrue("Executor wasn't shut down.", shutdown); 58bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 59bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 60bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay @Override 61bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public boolean isShutdown() { 62bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay return shutdown; 63bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 64bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 65bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay @Override 66bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public boolean isTerminated() { 67bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay throw new UnsupportedOperationException(); 68bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 69bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 70bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay @Override 71bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException { 72bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay throw new UnsupportedOperationException(); 73bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 74bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 75bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay @Override 76bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public <T> Future<T> submit(Callable<T> task) { 77bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay throw new UnsupportedOperationException(); 78bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 79bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 80bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay @Override 81bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public <T> Future<T> submit(Runnable task, T result) { 82bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay throw new UnsupportedOperationException(); 83bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 84bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 85bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay @Override 86bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public Future<?> submit(Runnable task) { 87810fb82f4461544ce34a5702668cf0e3123582c2Garfield, Tan return schedule(task, 0, TimeUnit.MILLISECONDS); 88bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 89bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 90bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay @Override 91bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) 92bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay throws InterruptedException { 93bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay throw new UnsupportedOperationException(); 94bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 95bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 96bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay @Override 97bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, 98bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay TimeUnit unit) throws InterruptedException { 99bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay throw new UnsupportedOperationException(); 100bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 101bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 102bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay @Override 103bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public <T> T invokeAny(Collection<? extends Callable<T>> tasks) 104bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay throws InterruptedException, ExecutionException { 105bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay throw new UnsupportedOperationException(); 106bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 107bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 108bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay @Override 109bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) 110bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay throws InterruptedException, ExecutionException, TimeoutException { 111bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay throw new UnsupportedOperationException(); 112bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 113bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 114bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay @Override 115bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public void execute(Runnable command) { 116edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan schedule(command, 0, TimeUnit.MILLISECONDS); 117bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 118bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 119bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay @Override 120bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) { 121bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay TestFuture future = new TestFuture(command, delay, unit); 122bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay scheduled.add(future); 123bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay return future; 124bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 125bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 126bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay @Override 127bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) { 128bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay throw new UnsupportedOperationException(); 129bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 130bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 131bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay @Override 132bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, 133bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay TimeUnit unit) { 134bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay throw new UnsupportedOperationException(); 135bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 136bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 137bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay @Override 138bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, 139bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay long delay, TimeUnit unit) { 140bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay throw new UnsupportedOperationException(); 141bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 142bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 143edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan public void runAll() { 144894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tan while (!scheduled.isEmpty()) { 145894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tan TestFuture future = scheduled.remove(scheduled.size() - 1); 146bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay future.runnable.run(); 147bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 148bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 149bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 150edce554c3eaff20a9bf349c1bc18c0b49e812c74Garfield, Tan public void run(int taskIndex) { 151bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay scheduled.get(taskIndex).runnable.run(); 152d79ef7f8da3f13cdd219901252bfb7cfd62456a5Garfield Tan 153d79ef7f8da3f13cdd219901252bfb7cfd62456a5Garfield Tan scheduled.remove(taskIndex); 154bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 155bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 15697b4be4638f1697895e5d1f3fdf8bf28a3bb9c13Steve McKay public void assertAlive() { 157bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay assertFalse(isShutdown()); 158bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 159bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 160894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tan public void waitForTasks(long millisTimeout) throws Exception { 161894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tan millisTimeout = (millisTimeout > 0) ? millisTimeout : Long.MAX_VALUE; 162894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tan 163894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tan final long startTime = SystemClock.uptimeMillis(); 164894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tan 165894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tan // We need to wait on all AsyncTasks to finish AND to post results back. 166894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tan // *** Results are posted on main thread ***, but tests run in their own 167894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tan // thread. So even with our test executor we still have races. 168894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tan // 169894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tan // To work around this issue post our own runnable to the main thread 170894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tan // which we presume will be the *last* runnable (after any from AsyncTasks) 171894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tan // and then wait for our runnable to be called. 172894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tan while (!scheduled.isEmpty() && millisTimeout > 0) { 173894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tan CountDownLatch latch = new CountDownLatch(1); 174894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tan runAll(); 175894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tan new Handler(Looper.getMainLooper()).post(latch::countDown); 176894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tan latch.await(millisTimeout, TimeUnit.MILLISECONDS); 177894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tan 178894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tan millisTimeout -= (SystemClock.uptimeMillis() - startTime); 179894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tan } 180894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tan } 181894d487698ff5c7052f499602fb74ad89f1d2d15Garfield Tan 182bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay static class TestFuture implements ScheduledFuture<Void> { 183bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 184bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay final Runnable runnable; 185bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay final long delay; 186bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay final TimeUnit unit; 187bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 188bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public TestFuture(Runnable runnable, long delay, TimeUnit unit) { 189bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay this.runnable = runnable; 190bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay this.delay = delay; 191bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay this.unit = unit; 192bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 193bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 194bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay @Override 195bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public long getDelay(TimeUnit unit) { 196bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay return 0; 197bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 198bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 199bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay @Override 200bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public int compareTo(Delayed arg0) { 201bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay return 0; 202bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 203bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 204bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay @Override 205bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public boolean cancel(boolean mayInterruptIfRunning) { 206bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay return false; 207bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 208bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 209bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay @Override 210bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public boolean isCancelled() { 211bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay return false; 212bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 213bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 214bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay @Override 215bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public boolean isDone() { 216bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay return false; 217bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 218bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 219bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay @Override 220bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public Void get() throws InterruptedException, ExecutionException { 221bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay return null; 222bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 223bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay 224bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay @Override 225bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay public Void get(long timeout, TimeUnit unit) 226bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay throws InterruptedException, ExecutionException, TimeoutException { 227bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay return null; 228bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 229bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay } 230bbeba5265c5baa42c6db93fc8030c6055747da4dSteve McKay} 231