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