1/*
2 * Copyright (C) 2008 The Guava Authors
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License.  You may obtain a copy
6 * 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, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
13 * License for the specific language governing permissions and limitations under
14 * the License.
15 */
16
17package com.google.common.util.concurrent.testing;
18
19import com.google.common.annotations.Beta;
20import com.google.common.util.concurrent.ListenableFuture;
21import com.google.common.util.concurrent.MoreExecutors;
22
23import junit.framework.Assert;
24
25import java.util.concurrent.CountDownLatch;
26import java.util.concurrent.ExecutionException;
27import java.util.concurrent.TimeUnit;
28
29/**
30 * A simple mock implementation of {@code Runnable} that can be used for
31 * testing ListenableFutures.
32 *
33 * @author Nishant Thakkar
34 * @since 10.0
35 */
36@Beta
37public class MockFutureListener implements Runnable {
38  private final CountDownLatch countDownLatch;
39  private final ListenableFuture<?> future;
40
41  public MockFutureListener(ListenableFuture<?> future) {
42    this.countDownLatch = new CountDownLatch(1);
43    this.future = future;
44
45    future.addListener(this, MoreExecutors.sameThreadExecutor());
46  }
47
48  @Override
49  public void run() {
50    countDownLatch.countDown();
51  }
52
53  /**
54   * Verify that the listener completes in a reasonable amount of time, and
55   * Asserts that the future returns the expected data.
56   * @throws Throwable if the listener isn't called or if it resulted in a
57   *     throwable or if the result doesn't match the expected value.
58   */
59  public void assertSuccess(Object expectedData) throws Throwable {
60    // Verify that the listener executed in a reasonable amount of time.
61    Assert.assertTrue(countDownLatch.await(1L, TimeUnit.SECONDS));
62
63    try {
64      Assert.assertEquals(expectedData, future.get());
65    } catch (ExecutionException e) {
66      throw e.getCause();
67    }
68  }
69
70  /**
71   * Verify that the listener completes in a reasonable amount of time, and
72   * Asserts that the future throws an {@code ExecutableException} and that the
73   * cause of the {@code ExecutableException} is {@code expectedCause}.
74   */
75  public void assertException(Throwable expectedCause) throws Exception {
76    // Verify that the listener executed in a reasonable amount of time.
77    Assert.assertTrue(countDownLatch.await(1L, TimeUnit.SECONDS));
78
79    try {
80      future.get();
81      Assert.fail("This call was supposed to throw an ExecutionException");
82    } catch (ExecutionException expected) {
83      Assert.assertSame(expectedCause, expected.getCause());
84    }
85  }
86
87  public void assertTimeout() throws Exception {
88    // Verify that the listener does not get called in a reasonable amount of
89    // time.
90    Assert.assertFalse(countDownLatch.await(1L, TimeUnit.SECONDS));
91  }
92}
93