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