Organize Imports to be Checkstyle compliant in utils
[yangtools.git] / common / util / src / test / java / org / opendaylight / yangtools / util / concurrent / MappingCheckedFutureTest.java
1 /*
2  * Copyright (c) 2014 Brocade Communications Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.yangtools.util.concurrent;
10
11
12 import static org.junit.Assert.assertEquals;
13 import static org.junit.Assert.assertNotNull;
14 import static org.junit.Assert.assertNull;
15 import static org.junit.Assert.assertSame;
16 import static org.junit.Assert.fail;
17
18 import com.google.common.util.concurrent.CheckedFuture;
19 import com.google.common.util.concurrent.SettableFuture;
20 import java.util.concurrent.CancellationException;
21 import java.util.concurrent.CountDownLatch;
22 import java.util.concurrent.ExecutionException;
23 import java.util.concurrent.TimeUnit;
24 import java.util.concurrent.atomic.AtomicReference;
25 import org.junit.Test;
26
27 /**
28  * Unit tests for MappingCheckedFuture.
29  *
30  * @author Thomas Pantelis
31  */
32 public class MappingCheckedFutureTest {
33
34     interface FutureInvoker {
35         void invokeGet( CheckedFuture<?,?> future ) throws Exception;
36         Throwable extractWrappedTestEx( Exception from );
37     }
38
39     @SuppressWarnings("serial")
40     static class TestException extends Exception {
41         TestException( final String message, final Throwable cause ) {
42             super( message, cause );
43         }
44     }
45
46     static final ExceptionMapper<TestException> MAPPER =  new ExceptionMapper<TestException>(
47                                                                       "Test", TestException.class ) {
48
49         @Override
50         protected TestException newWithCause( final String message, final Throwable cause ) {
51             return new TestException( message, cause );
52         }
53     };
54
55     static final FutureInvoker GET = new FutureInvoker() {
56         @Override
57         public void invokeGet( final CheckedFuture<?,?> future ) throws Exception {
58             future.get();
59         }
60
61         @Override
62         public Throwable extractWrappedTestEx( final Exception from ) {
63             if (from instanceof ExecutionException ) {
64                 return ((ExecutionException)from).getCause();
65             }
66
67             return from;
68         }
69     };
70
71     static final FutureInvoker TIMED_GET = new FutureInvoker() {
72         @Override
73         public void invokeGet( final CheckedFuture<?,?> future ) throws Exception {
74             future.get( 1, TimeUnit.HOURS );
75         }
76
77         @Override
78         public Throwable extractWrappedTestEx( final Exception from ) {
79             if (from instanceof ExecutionException ) {
80                 return ((ExecutionException)from).getCause();
81             }
82
83             return from;
84         }
85     };
86
87     static final FutureInvoker CHECKED_GET = new FutureInvoker() {
88         @Override
89         public void invokeGet( final CheckedFuture<?,?> future ) throws Exception {
90             future.checkedGet();
91         }
92
93         @Override
94         public Throwable extractWrappedTestEx( final Exception from ) {
95             return from;
96         }
97     };
98
99     static final FutureInvoker TIMED_CHECKED_GET = new FutureInvoker() {
100         @Override
101         public void invokeGet( final CheckedFuture<?,?> future ) throws Exception {
102             future.checkedGet( 50, TimeUnit.MILLISECONDS );
103         }
104
105         @Override
106         public Throwable extractWrappedTestEx( final Exception from ) {
107             return from;
108         }
109     };
110
111     @Test
112     public void testGet() throws Exception {
113
114         SettableFuture<String> delegate = SettableFuture.create();
115         MappingCheckedFuture<String,TestException> future = MappingCheckedFuture.create( delegate, MAPPER );
116         delegate.set( "test" );
117         assertEquals( "get", "test", future.get() );
118     }
119
120     @Test
121     public void testGetWithExceptions() throws Exception {
122
123         testExecutionException( GET, new RuntimeException() );
124         testExecutionException( GET, new TestException( "mock", null ) );
125         testCancellationException( GET );
126         testInterruptedException( GET );
127     }
128
129     @Test
130     public void testTimedGet() throws Exception {
131
132         SettableFuture<String> delegate = SettableFuture.create();
133         MappingCheckedFuture<String,TestException> future = MappingCheckedFuture.create( delegate, MAPPER );
134         delegate.set( "test" );
135         assertEquals( "get", "test", future.get( 50, TimeUnit.MILLISECONDS ) );
136     }
137
138     @Test
139     public void testTimedGetWithExceptions() throws Exception {
140
141         testExecutionException( TIMED_GET, new RuntimeException() );
142         testCancellationException( TIMED_GET );
143         testInterruptedException( TIMED_GET );
144     }
145
146     @Test
147     public void testCheckedGetWithExceptions() throws Exception {
148
149         testExecutionException( CHECKED_GET, new RuntimeException() );
150         testCancellationException( CHECKED_GET );
151         testInterruptedException( CHECKED_GET );
152     }
153
154     @Test
155     public void testTimedCheckedWithExceptions() throws Exception {
156
157         testExecutionException( TIMED_CHECKED_GET, new RuntimeException() );
158         testCancellationException( TIMED_CHECKED_GET );
159         testInterruptedException( TIMED_CHECKED_GET );
160     }
161
162     private static void testExecutionException( final FutureInvoker invoker, final Throwable cause ) {
163
164         SettableFuture<String> delegate = SettableFuture.create();
165         MappingCheckedFuture<String,TestException> mappingFuture =
166                                                         MappingCheckedFuture.create( delegate, MAPPER );
167
168         delegate.setException( cause );
169
170         try {
171             invoker.invokeGet( mappingFuture );
172             fail( "Expected exception thrown" );
173         } catch( Exception e ) {
174             Throwable expectedTestEx = invoker.extractWrappedTestEx( e );
175             assertNotNull( "Expected returned exception is null", expectedTestEx );
176             assertEquals( "Exception type", TestException.class, expectedTestEx.getClass() );
177
178             if (cause instanceof TestException ) {
179                 assertNull( "Expected null cause", expectedTestEx.getCause() );
180             } else {
181                 assertSame( "TestException cause", cause, expectedTestEx.getCause() );
182             }
183         }
184     }
185
186     private static void testCancellationException( final FutureInvoker invoker ) {
187
188         SettableFuture<String> delegate = SettableFuture.create();
189         MappingCheckedFuture<String,TestException> mappingFuture =
190                                                         MappingCheckedFuture.create( delegate, MAPPER );
191
192         mappingFuture.cancel( false );
193
194         try {
195             invoker.invokeGet( mappingFuture );
196             fail( "Expected exception thrown" );
197         } catch( Exception e ) {
198             Throwable expectedTestEx = invoker.extractWrappedTestEx( e );
199             assertNotNull( "Expected returned exception is null", expectedTestEx );
200             assertEquals( "Exception type", TestException.class, expectedTestEx.getClass() );
201             assertEquals( "TestException cause type", CancellationException.class,
202                           expectedTestEx.getCause().getClass() );
203         }
204     }
205
206     private static void testInterruptedException( final FutureInvoker invoker ) throws Exception {
207
208         SettableFuture<String> delegate = SettableFuture.create();
209         final MappingCheckedFuture<String,TestException> mappingFuture =
210                                                         MappingCheckedFuture.create( delegate, MAPPER );
211
212         final AtomicReference<AssertionError> assertError = new AtomicReference<>();
213         final CountDownLatch doneLatch = new CountDownLatch( 1 );
214         Thread thread = new Thread() {
215
216             @Override
217             public void run() {
218                 try {
219                     doInvoke();
220                 } catch( AssertionError e ) {
221                     assertError.set( e );
222                 } finally {
223                     doneLatch.countDown();
224                 }
225             }
226
227             void doInvoke() {
228                 try {
229                     invoker.invokeGet( mappingFuture );
230                     fail( "Expected exception thrown" );
231                 } catch( Exception e ) {
232                     Throwable expectedTestEx = invoker.extractWrappedTestEx( e );
233                     assertNotNull( "Expected returned exception is null", expectedTestEx );
234                     assertEquals( "Exception type", TestException.class, expectedTestEx.getClass() );
235                     assertEquals( "TestException cause type", InterruptedException.class,
236                                   expectedTestEx.getCause().getClass() );
237                 }
238             }
239         };
240         thread.start();
241
242         thread.interrupt();
243         assertEquals( "get call completed", true, doneLatch.await( 5, TimeUnit.SECONDS ) );
244
245         if (assertError.get() != null ) {
246             throw assertError.get();
247         }
248     }
249 }