View Javadoc

    1   /**
    2    * Licensed to the Apache Software Foundation (ASF) under one
    3    * or more contributor license agreements.  See the NOTICE file
    4    * distributed with this work for additional information
    5    * regarding copyright ownership.  The ASF licenses this file
    6    * to you under the Apache License, Version 2.0 (the
    7    * "License"); you may not use this file except in compliance
    8    * with the License.  You may obtain a copy of the License at
    9    *
    10   *   http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   * Unless required by applicable law or agreed to in writing,
    13   * software distributed under the License is distributed on an
    14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    15   * KIND, either express or implied.  See the License for the
    16   * specific language governing permissions and limitations
    17   * under the License.
    18   */
    19  package org.apache.mina.util;
    20
    21  import static org.junit.Assert.assertFalse;
    22  import static org.junit.Assert.assertTrue;
    23  import static org.junit.Assert.fail;
    24  import static org.mockito.Matchers.anyBoolean;
    25  import static org.mockito.Matchers.argThat;
    26  import static org.mockito.Mockito.doReturn;
    27  import static org.mockito.Mockito.mock;
    28  import static org.mockito.Mockito.never;
    29  import static org.mockito.Mockito.spy;
    30  import static org.mockito.Mockito.verify;
    31
    32  import java.util.concurrent.CancellationException;
    33  import java.util.concurrent.ExecutionException;
    34  import java.util.concurrent.TimeUnit;
    35  import java.util.concurrent.TimeoutException;
    36
    37  import org.apache.mina.api.IoFutureListener;
    38  import org.hamcrest.BaseMatcher;
    39  import org.hamcrest.Description;
    40  import org.hamcrest.Matcher;
    41  import org.junit.Test;
    42  import org.mockito.Matchers;
    43
    44  /**
    45   * @author <a href="http://mina.apache.org">Apache MINA Project</a>
    46   */
    47  public class AbstractIoFutureTest {
    48
    49      @Test
    50      public void testSet() {
    51          final MockAbstractIoFuture<Boolean> future = spy(new MockAbstractIoFuture<Boolean>());
    52
    53          assertFalse(future.isCancelled());
    54          assertFalse(future.isDone());
    55
    56          future.setResult(true);
    57
    58          assertFalse(future.isCancelled());
    59          assertTrue(future.isDone());
    60      }
    61
    62      @Test
    63      @SuppressWarnings({ "unchecked" })
    64      public void testSetListeners() {
    65          final MockAbstractIoFuture<Boolean> future = spy(new MockAbstractIoFuture<Boolean>());
    66          final IoFutureListener<Boolean> listener = mock(IoFutureListener.class);
    67
    68          future.register(listener);
    69
    70          assertFalse(future.isCancelled());
    71          assertFalse(future.isDone());
    72
    73          future.setResult(true);
    74
    75          assertFalse(future.isCancelled());
    76          assertTrue(future.isDone());
    77
    78          verify(listener).completed(true);
    79          verify(listener, never()).exception(Matchers.<Throwable> any());
    80      }
    81
    82      @Test
    83      @SuppressWarnings({ "unchecked" })
    84      public void testSetListenersAlreadySet() {
    85          final MockAbstractIoFuture<Boolean> future = spy(new MockAbstractIoFuture<Boolean>());
    86          final IoFutureListener<Boolean> listener = mock(IoFutureListener.class);
    87
    88          assertFalse(future.isCancelled());
    89          assertFalse(future.isDone());
    90
    91          future.setResult(true);
    92          future.register(listener);
    93
    94          assertFalse(future.isCancelled());
    95          assertTrue(future.isDone());
    96
    97          verify(listener).completed(true);
    98          verify(listener, never()).exception(Matchers.<Throwable> any());
    99      }
    100
    101     @Test
    102     public void testTimedGet() {
    103         final MockAbstractIoFuture<Boolean> future = spy(new MockAbstractIoFuture<Boolean>());
    104
    105         assertFalse(future.isCancelled());
    106         assertFalse(future.isDone());
    107
    108         new Thread(new Runnable() {
    109             @Override
    110             public void run() {
    111                 try {
    112                     Thread.sleep(1000);
    113                     future.setResult(true);
    114                 } catch (final InterruptedException ignored) {
    115                 }
    116             }
    117         }).start();
    118
    119         try {
    120             assertTrue(future.get(1, TimeUnit.DAYS));
    121             assertFalse(future.isCancelled());
    122             assertTrue(future.isDone());
    123         } catch (final InterruptedException e) {
    124             fail("This future was not interrupted");
    125         } catch (final ExecutionException ee) {
    126             fail("This future did not have an execution exception");
    127         } catch (final TimeoutException e) {
    128             fail("This future was not interrupted");
    129         }
    130     }
    131
    132     @Test
    133     public void testException() {
    134         final MockAbstractIoFuture<Boolean> future = spy(new MockAbstractIoFuture<Boolean>());
    135
    136         assertFalse(future.isCancelled());
    137         assertFalse(future.isDone());
    138
    139         future.setException(new NullPointerException());
    140
    141         assertFalse(future.isCancelled());
    142         assertTrue(future.isDone());
    143
    144         try {
    145             future.get();
    146             fail("This future had an execution exception");
    147         } catch (final InterruptedException e) {
    148             fail("This future was not interrupted");
    149         } catch (final ExecutionException ee) {
    150             assertTrue(ee.getCause() instanceof NullPointerException);
    151         }
    152
    153         assertFalse(future.isCancelled());
    154         assertTrue(future.isDone());
    155     }
    156
    157     @Test
    158     @SuppressWarnings({ "unchecked" })
    159     public void testExceptionListeners() {
    160         final MockAbstractIoFuture<Boolean> future = spy(new MockAbstractIoFuture<Boolean>());
    161         final IoFutureListener<Boolean> listener = mock(IoFutureListener.class);
    162
    163         future.register(listener);
    164
    165         assertFalse(future.isCancelled());
    166         assertFalse(future.isDone());
    167
    168         future.setException(new NullPointerException());
    169
    170         assertFalse(future.isCancelled());
    171         assertTrue(future.isDone());
    172
    173         verify(listener).exception(argThat(matchesExecutionException()));
    174         verify(listener, never()).completed(Matchers.<Boolean> any());
    175     }
    176
    177     @Test
    178     @SuppressWarnings({ "unchecked" })
    179     public void testExceptionListenersExceptionAlreadySet() {
    180         final MockAbstractIoFuture<Boolean> future = spy(new MockAbstractIoFuture<Boolean>());
    181         final IoFutureListener<Boolean> listener = mock(IoFutureListener.class);
    182
    183         assertFalse(future.isCancelled());
    184         assertFalse(future.isDone());
    185
    186         future.setException(new NullPointerException());
    187         future.register(listener);
    188
    189         assertFalse(future.isCancelled());
    190         assertTrue(future.isDone());
    191
    192         verify(listener).exception(argThat(matchesExecutionException()));
    193         verify(listener, never()).completed(Matchers.<Boolean> any());
    194     }
    195
    196     @Test
    197     public void testImmediateExceptionForTimedGet() {
    198         final MockAbstractIoFuture<Boolean> future = spy(new MockAbstractIoFuture<Boolean>());
    199
    200         assertFalse(future.isCancelled());
    201         assertFalse(future.isDone());
    202
    203         future.setException(new NullPointerException());
    204
    205         assertFalse(future.isCancelled());
    206         assertTrue(future.isDone());
    207
    208         try {
    209             future.get(1, TimeUnit.DAYS);
    210             fail("This future had an execution exception");
    211         } catch (final InterruptedException e) {
    212             fail("This future was not interrupted");
    213         } catch (final ExecutionException ee) {
    214             assertTrue(ee.getCause() instanceof NullPointerException);
    215         } catch (final TimeoutException e) {
    216             fail("This future was not interrupted");
    217         }
    218
    219         assertFalse(future.isCancelled());
    220         assertTrue(future.isDone());
    221     }
    222
    223     @Test
    224     public void testTimedExceptionForTimedGet() {
    225         final MockAbstractIoFuture<Boolean> future = spy(new MockAbstractIoFuture<Boolean>());
    226
    227         assertFalse(future.isCancelled());
    228         assertFalse(future.isDone());
    229
    230         new Thread(new Runnable() {
    231             @Override
    232             public void run() {
    233                 try {
    234                     Thread.sleep(1000);
    235                     future.setException(new NullPointerException());
    236                 } catch (final InterruptedException ignored) {
    237                 }
    238             }
    239         }).start();
    240
    241         try {
    242             assertTrue(future.get(1, TimeUnit.DAYS));
    243         } catch (final InterruptedException e) {
    244             fail("This future was not interrupted");
    245         } catch (final ExecutionException ee) {
    246         } catch (final TimeoutException e) {
    247             fail("This future was not interrupted");
    248         }
    249
    250         assertFalse(future.isCancelled());
    251         assertTrue(future.isDone());
    252     }
    253
    254     @Test
    255     public void testCancel() throws Exception {
    256         final MockAbstractIoFuture<Boolean> future = spy(new MockAbstractIoFuture<Boolean>());
    257         doReturn(true).when(future).cancelOwner(anyBoolean());
    258
    259         assertFalse(future.isCancelled());
    260         assertFalse(future.isDone());
    261         assertTrue(future.cancel(false));
    262         assertTrue(future.isCancelled());
    263         assertTrue(future.isDone());
    264         assertFalse(future.cancel(false));
    265         assertTrue(future.isCancelled());
    266         assertTrue(future.isDone());
    267
    268         try {
    269             future.get();
    270             fail("This future was canceled");
    271         } catch (final CancellationException ignore) {
    272         }
    273     }
    274
    275     @Test
    276     public void testCancelUncancelableOwner() throws Exception {
    277         final MockAbstractIoFuture<Boolean> future = spy(new MockAbstractIoFuture<Boolean>());
    278         doReturn(false).when(future).cancelOwner(anyBoolean());
    279
    280         assertFalse(future.isCancelled());
    281         assertFalse(future.isDone());
    282         assertFalse(future.cancel(false));
    283         assertFalse(future.isCancelled());
    284         assertTrue(future.isDone());
    285     }
    286
    287     @Test
    288     public void testCancelFinishedFuture() throws Exception {
    289         final MockAbstractIoFuture<Boolean> future = spy(new MockAbstractIoFuture<Boolean>());
    290         doReturn(true).when(future).cancelOwner(anyBoolean());
    291
    292         future.setResult(true);
    293
    294         assertFalse(future.isCancelled());
    295         assertTrue(future.isDone());
    296         assertFalse(future.cancel(false));
    297         assertFalse(future.isCancelled());
    298         assertTrue(future.isDone());
    299
    300         assertTrue(future.get());
    301     }
    302
    303     @Test
    304     @SuppressWarnings({ "unchecked" })
    305     public void testCanceledListeners() {
    306         final MockAbstractIoFuture<Boolean> future = spy(new MockAbstractIoFuture<Boolean>());
    307         doReturn(true).when(future).cancelOwner(anyBoolean());
    308         final IoFutureListener<Boolean> listener = mock(IoFutureListener.class);
    309
    310         future.register(listener);
    311
    312         assertFalse(future.isCancelled());
    313         assertFalse(future.isDone());
    314
    315         future.cancel(true);
    316
    317         assertTrue(future.isCancelled());
    318         assertTrue(future.isDone());
    319
    320         verify(listener).exception(Matchers.<CancellationException> any());
    321         verify(listener, never()).completed(Matchers.<Boolean> any());
    322     }
    323
    324     @Test
    325     @SuppressWarnings({ "unchecked" })
    326     public void testCanceledListenersAlreadySet() {
    327         final MockAbstractIoFuture<Boolean> future = spy(new MockAbstractIoFuture<Boolean>());
    328         doReturn(true).when(future).cancelOwner(anyBoolean());
    329         final IoFutureListener<Boolean> listener = mock(IoFutureListener.class);
    330
    331         assertFalse(future.isCancelled());
    332         assertFalse(future.isDone());
    333
    334         future.cancel(true);
    335         future.register(listener);
    336
    337         assertTrue(future.isCancelled());
    338         assertTrue(future.isDone());
    339
    340         verify(listener).exception(Matchers.<CancellationException> any());
    341         verify(listener, never()).completed(Matchers.<Boolean> any());
    342     }
    343
    344     @Test
    345     public void testTimeout() {
    346         final MockAbstractIoFuture<Boolean> future = spy(new MockAbstractIoFuture<Boolean>());
    347
    348         assertFalse(future.isCancelled());
    349         assertFalse(future.isDone());
    350
    351         try {
    352             future.get(10, TimeUnit.MILLISECONDS);
    353             fail("This future has timed out");
    354         } catch (final InterruptedException e) {
    355             fail("This future was not interrupted");
    356         } catch (final ExecutionException ee) {
    357             fail("This future did not have an execution exception");
    358         } catch (final TimeoutException e) {
    359         }
    360     }
    361
    362     private static Matcher<Throwable> matchesExecutionException() {
    363         return new BaseMatcher<Throwable>() {
    364             @Override
    365             public boolean matches(final Object item) {
    366                 return item instanceof ExecutionException
    367                         && ((ExecutionException) item).getCause() instanceof NullPointerException;
    368             }
    369
    370             @Override
    371             public void describeTo(final Description description) {
    372                 description.appendText("ExecutionException(NullPointerException)");
    373             }
    374         };
    375     }
    376
    377     public static class MockAbstractIoFuture<V> extends AbstractIoFuture<V> {
    378
    379         @Override
    380         protected boolean cancelOwner(final boolean mayInterruptIfRunning) {
    381             throw new UnsupportedOperationException();
    382         }
    383     }
    384 }