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   */
20  package org.apache.mina.core;
21  
22  import java.io.IOException;
23  
24  import org.apache.mina.core.future.DefaultCloseFuture;
25  import org.apache.mina.core.future.DefaultConnectFuture;
26  import org.apache.mina.core.future.DefaultWriteFuture;
27  import org.apache.mina.core.future.IoFuture;
28  import org.apache.mina.core.future.IoFutureListener;
29  import org.apache.mina.core.session.DummySession;
30  import org.apache.mina.core.session.IoSession;
31  import org.junit.Test;
32  
33  import static org.junit.Assert.assertFalse;
34  import static org.junit.Assert.assertTrue;
35  import static org.junit.Assert.assertNull;
36  import static org.junit.Assert.assertEquals;
37  import static org.junit.Assert.assertSame;
38  import static org.junit.Assert.fail;
39  
40  /**
41   * Tests {@link IoFuture} implementations.
42   *
43   * @author The Apache MINA Project (dev@mina.apache.org)
44   * @version $Rev:671827 $, $Date:2008-06-26 09:49:48 +0100 (jeu., 26 juin 2008) $
45   */
46  public class FutureTest {
47  
48      @Test
49      public void testCloseFuture() throws Exception {
50          DefaultCloseFuture future = new DefaultCloseFuture(null);
51          assertFalse(future.isDone());
52          assertFalse(future.isClosed());
53  
54          TestThread thread = new TestThread(future);
55          thread.start();
56  
57          future.setClosed();
58          thread.join();
59  
60          assertTrue(thread.success);
61          assertTrue(future.isDone());
62          assertTrue(future.isClosed());
63      }
64  
65      @Test
66      public void testConnectFuture() throws Exception {
67          DefaultConnectFuture future = new DefaultConnectFuture();
68          assertFalse(future.isDone());
69          assertFalse(future.isConnected());
70          assertNull(future.getSession());
71          assertNull(future.getException());
72  
73          TestThread thread = new TestThread(future);
74          thread.start();
75  
76          IoSession session = new DummySession();
77  
78          future.setSession(session);
79          thread.join();
80  
81          assertTrue(thread.success);
82          assertTrue(future.isDone());
83          assertTrue(future.isConnected());
84          assertEquals(session, future.getSession());
85          assertNull(future.getException());
86  
87          future = new DefaultConnectFuture();
88          thread = new TestThread(future);
89          thread.start();
90          future.setException(new IOException());
91          thread.join();
92  
93          assertTrue(thread.success);
94          assertTrue(future.isDone());
95          assertFalse(future.isConnected());
96          assertTrue(future.getException() instanceof IOException);
97  
98          try {
99              future.getSession();
100             fail("IOException should be thrown.");
101         } catch (Exception e) {
102         }
103     }
104 
105     @Test
106     public void testWriteFuture() throws Exception {
107         DefaultWriteFuture future = new DefaultWriteFuture(null);
108         assertFalse(future.isDone());
109         assertFalse(future.isWritten());
110 
111         TestThread thread = new TestThread(future);
112         thread.start();
113 
114         future.setWritten();
115         thread.join();
116 
117         assertTrue(thread.success);
118         assertTrue(future.isDone());
119         assertTrue(future.isWritten());
120 
121         future = new DefaultWriteFuture(null);
122         thread = new TestThread(future);
123         thread.start();
124 
125         future.setException(new Exception());
126         thread.join();
127 
128         assertTrue(thread.success);
129         assertTrue(future.isDone());
130         assertFalse(future.isWritten());
131         assertTrue(future.getException().getClass() == Exception.class);
132     }
133 
134     @Test
135     public void testAddListener() throws Exception {
136         DefaultCloseFuture future = new DefaultCloseFuture(null);
137         assertFalse(future.isDone());
138         assertFalse(future.isClosed());
139 
140         TestListener listener1 = new TestListener();
141         TestListener listener2 = new TestListener();
142         future.addListener(listener1);
143         future.addListener(listener2);
144 
145         TestThread thread = new TestThread(future);
146         thread.start();
147 
148         future.setClosed();
149         thread.join();
150 
151         assertTrue(thread.success);
152         assertTrue(future.isDone());
153         assertTrue(future.isClosed());
154 
155         assertSame(future, listener1.notifiedFuture);
156         assertSame(future, listener2.notifiedFuture);
157     }
158 
159     @Test
160     public void testLateAddListener() throws Exception {
161         DefaultCloseFuture future = new DefaultCloseFuture(null);
162         assertFalse(future.isDone());
163         assertFalse(future.isClosed());
164 
165         TestThread thread = new TestThread(future);
166         thread.start();
167 
168         future.setClosed();
169         thread.join();
170 
171         assertTrue(thread.success);
172         assertTrue(future.isDone());
173         assertTrue(future.isClosed());
174 
175         TestListener listener = new TestListener();
176         future.addListener(listener);
177         assertSame(future, listener.notifiedFuture);
178     }
179 
180     @Test
181     public void testRemoveListener1() throws Exception {
182         DefaultCloseFuture future = new DefaultCloseFuture(null);
183         assertFalse(future.isDone());
184         assertFalse(future.isClosed());
185 
186         TestListener listener1 = new TestListener();
187         TestListener listener2 = new TestListener();
188         future.addListener(listener1);
189         future.addListener(listener2);
190         future.removeListener(listener1);
191 
192         TestThread thread = new TestThread(future);
193         thread.start();
194 
195         future.setClosed();
196         thread.join();
197 
198         assertTrue(thread.success);
199         assertTrue(future.isDone());
200         assertTrue(future.isClosed());
201 
202         assertSame(null, listener1.notifiedFuture);
203         assertSame(future, listener2.notifiedFuture);
204     }
205 
206     @Test
207     public void testRemoveListener2() throws Exception {
208         DefaultCloseFuture future = new DefaultCloseFuture(null);
209         assertFalse(future.isDone());
210         assertFalse(future.isClosed());
211 
212         TestListener listener1 = new TestListener();
213         TestListener listener2 = new TestListener();
214         future.addListener(listener1);
215         future.addListener(listener2);
216         future.removeListener(listener2);
217 
218         TestThread thread = new TestThread(future);
219         thread.start();
220 
221         future.setClosed();
222         thread.join();
223 
224         assertTrue(thread.success);
225         assertTrue(future.isDone());
226         assertTrue(future.isClosed());
227 
228         assertSame(future, listener1.notifiedFuture);
229         assertSame(null, listener2.notifiedFuture);
230     }
231 
232     private static class TestThread extends Thread {
233         private final IoFuture future;
234 
235         private boolean success;
236 
237         public TestThread(IoFuture future) {
238             this.future = future;
239         }
240 
241         @Override
242         public void run() {
243             success = future.awaitUninterruptibly(10000);
244         }
245     }
246 
247     private static class TestListener implements IoFutureListener<IoFuture> {
248         private IoFuture notifiedFuture;
249 
250         public void operationComplete(IoFuture future) {
251             this.notifiedFuture = future;
252         }
253     }
254 }