Coverage Summary for Class: TestingExecutors (com.google.common.util.concurrent.testing)

Class Method, % Line, %
TestingExecutors 66.7% (2/3) 66.7% (2/3)
TestingExecutors$NoOpScheduledExecutorService 54.5% (6/11) 53.8% (7/13)
TestingExecutors$NoOpScheduledExecutorService$NeverScheduledFuture 50% (2/4) 50% (2/4)
Total 55.6% (10/18) 55% (11/20)


1 /* 2  * Copyright (C) 2012 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.testing; 18  19 import com.google.common.annotations.Beta; 20 import com.google.common.annotations.GwtIncompatible; 21 import com.google.common.collect.ImmutableList; 22 import com.google.common.primitives.Longs; 23 import com.google.common.util.concurrent.AbstractFuture; 24 import com.google.common.util.concurrent.AbstractListeningExecutorService; 25 import com.google.common.util.concurrent.ListenableScheduledFuture; 26 import com.google.common.util.concurrent.ListeningScheduledExecutorService; 27 import com.google.common.util.concurrent.MoreExecutors; 28 import java.util.List; 29 import java.util.concurrent.Callable; 30 import java.util.concurrent.Delayed; 31 import java.util.concurrent.ScheduledFuture; 32 import java.util.concurrent.TimeUnit; 33  34 /** 35  * Factory methods for {@link ExecutorService} for testing. 36  * 37  * @author Chris Nokleberg 38  * @since 14.0 39  */ 40 @Beta 41 @GwtIncompatible 42 public final class TestingExecutors { 43  private TestingExecutors() {} 44  45  /** 46  * Returns a {@link ScheduledExecutorService} that never executes anything. 47  * 48  * <p>The {@code shutdownNow} method of the returned executor always returns an empty list despite 49  * the fact that everything is still technically awaiting execution. The {@code getDelay} method 50  * of any {@link ScheduledFuture} returned by the executor will always return the max long value 51  * instead of the time until the user-specified delay. 52  */ 53  public static ListeningScheduledExecutorService noOpScheduledExecutor() { 54  return new NoOpScheduledExecutorService(); 55  } 56  57  /** 58  * Creates a scheduled executor service that runs each task in the thread that invokes {@code 59  * execute/submit/schedule}, as in {@link CallerRunsPolicy}. This applies both to individually 60  * submitted tasks and to collections of tasks submitted via {@code invokeAll}, {@code invokeAny}, 61  * {@code schedule}, {@code scheduleAtFixedRate}, and {@code scheduleWithFixedDelay}. In the case 62  * of tasks submitted by {@code invokeAll} or {@code invokeAny}, tasks will run serially on the 63  * calling thread. Tasks are run to completion before a {@code Future} is returned to the caller 64  * (unless the executor has been shutdown). 65  * 66  * <p>The returned executor is backed by the executor returned by {@link 67  * MoreExecutors#newDirectExecutorService} and subject to the same constraints. 68  * 69  * <p>Although all tasks are immediately executed in the thread that submitted the task, this 70  * {@code ExecutorService} imposes a small locking overhead on each task submission in order to 71  * implement shutdown and termination behavior. 72  * 73  * <p>Because of the nature of single-thread execution, the methods {@code scheduleAtFixedRate} 74  * and {@code scheduleWithFixedDelay} are not supported by this class and will throw an 75  * UnsupportedOperationException. 76  * 77  * <p>The implementation deviates from the {@code ExecutorService} specification with regards to 78  * the {@code shutdownNow} method. First, "best-effort" with regards to canceling running tasks is 79  * implemented as "no-effort". No interrupts or other attempts are made to stop threads executing 80  * tasks. Second, the returned list will always be empty, as any submitted task is considered to 81  * have started execution. This applies also to tasks given to {@code invokeAll} or {@code 82  * invokeAny} which are pending serial execution, even the subset of the tasks that have not yet 83  * started execution. It is unclear from the {@code ExecutorService} specification if these should 84  * be included, and it's much easier to implement the interpretation that they not be. Finally, a 85  * call to {@code shutdown} or {@code shutdownNow} may result in concurrent calls to {@code 86  * invokeAll/invokeAny} throwing RejectedExecutionException, although a subset of the tasks may 87  * already have been executed. 88  * 89  * @since 15.0 90  */ 91  public static SameThreadScheduledExecutorService sameThreadScheduledExecutor() { 92  return new SameThreadScheduledExecutorService(); 93  } 94  95  private static final class NoOpScheduledExecutorService extends AbstractListeningExecutorService 96  implements ListeningScheduledExecutorService { 97  98  private volatile boolean shutdown; 99  100  @Override 101  public void shutdown() { 102  shutdown = true; 103  } 104  105  @Override 106  public List<Runnable> shutdownNow() { 107  shutdown(); 108  return ImmutableList.of(); 109  } 110  111  @Override 112  public boolean isShutdown() { 113  return shutdown; 114  } 115  116  @Override 117  public boolean isTerminated() { 118  return shutdown; 119  } 120  121  @Override 122  public boolean awaitTermination(long timeout, TimeUnit unit) { 123  return true; 124  } 125  126  @Override 127  public void execute(Runnable runnable) {} 128  129  @Override 130  public <V> ListenableScheduledFuture<V> schedule( 131  Callable<V> callable, long delay, TimeUnit unit) { 132  return NeverScheduledFuture.create(); 133  } 134  135  @Override 136  public ListenableScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) { 137  return NeverScheduledFuture.create(); 138  } 139  140  @Override 141  public ListenableScheduledFuture<?> scheduleAtFixedRate( 142  Runnable command, long initialDelay, long period, TimeUnit unit) { 143  return NeverScheduledFuture.create(); 144  } 145  146  @Override 147  public ListenableScheduledFuture<?> scheduleWithFixedDelay( 148  Runnable command, long initialDelay, long delay, TimeUnit unit) { 149  return NeverScheduledFuture.create(); 150  } 151  152  private static class NeverScheduledFuture<V> extends AbstractFuture<V> 153  implements ListenableScheduledFuture<V> { 154  155  static <V> NeverScheduledFuture<V> create() { 156  return new NeverScheduledFuture<V>(); 157  } 158  159  @Override 160  public long getDelay(TimeUnit unit) { 161  return Long.MAX_VALUE; 162  } 163  164  @Override 165  public int compareTo(Delayed other) { 166  return Longs.compare(getDelay(TimeUnit.NANOSECONDS), other.getDelay(TimeUnit.NANOSECONDS)); 167  } 168  } 169  } 170 }