1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements.  See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License.  You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.apache.harmony.nio.tests.java.nio.channels;
18
19import java.io.IOException;
20import java.net.InetSocketAddress;
21import java.net.ServerSocket;
22import java.nio.channels.CancelledKeyException;
23import java.nio.channels.SelectableChannel;
24import java.nio.channels.SelectionKey;
25import java.nio.channels.Selector;
26import java.nio.channels.SocketChannel;
27
28import junit.framework.TestCase;
29import tests.support.Support_PortManager;
30
31/*
32 * Tests for SelectionKey and its default implementation
33 */
34public class SelectionKeyTest extends TestCase {
35
36    Selector selector;
37
38    SocketChannel sc;
39
40    SelectionKey selectionKey;
41
42    private static String LOCAL_ADDR = "127.0.0.1";
43
44    protected void setUp() throws Exception {
45        super.setUp();
46        selector = Selector.open();
47        sc = SocketChannel.open();
48        sc.configureBlocking(false);
49        selectionKey = sc.register(selector, SelectionKey.OP_CONNECT);
50    }
51
52    protected void tearDown() throws Exception {
53        selectionKey.cancel();
54        selectionKey = null;
55        selector.close();
56        selector = null;
57        super.tearDown();
58    }
59
60    static class MockSelectionKey extends SelectionKey {
61        private int interestOps;
62
63        MockSelectionKey(int ops) {
64            interestOps = ops;
65        }
66
67        public void cancel() {
68            // do nothing
69        }
70
71        public SelectableChannel channel() {
72            return null;
73        }
74
75        public int interestOps() {
76            return 0;
77        }
78
79        public SelectionKey interestOps(int operations) {
80            return null;
81        }
82
83        public boolean isValid() {
84            return true;
85        }
86
87        public int readyOps() {
88            return interestOps;
89        }
90
91        public Selector selector() {
92            return null;
93        }
94    }
95
96    /**
97     * @tests java.nio.channels.SelectionKey#attach(Object)
98     */
99    public void test_attach() {
100        MockSelectionKey mockSelectionKey = new MockSelectionKey(SelectionKey.OP_ACCEPT);
101        // no previous, return null
102        Object o = new Object();
103        Object check = mockSelectionKey.attach(o);
104        assertNull(check);
105
106        // null parameter is ok
107        check = mockSelectionKey.attach(null);
108        assertSame(o, check);
109
110        check = mockSelectionKey.attach(o);
111        assertNull(check);
112    }
113
114    /**
115     * @tests java.nio.channels.SelectionKey#attachment()
116     */
117    public void test_attachment() {
118        MockSelectionKey mockSelectionKey = new MockSelectionKey(SelectionKey.OP_ACCEPT);
119        assertNull(mockSelectionKey.attachment());
120        Object o = new Object();
121        mockSelectionKey.attach(o);
122        assertSame(o, mockSelectionKey.attachment());
123    }
124
125    /**
126     * @tests java.nio.channels.SelectionKey#channel()
127     */
128    public void test_channel() {
129        assertSame(sc, selectionKey.channel());
130        // can be invoked even canceled
131        selectionKey.cancel();
132        assertSame(sc, selectionKey.channel());
133    }
134
135    /**
136     * @tests java.nio.channels.SelectionKey#interestOps()
137     */
138    public void test_interestOps() {
139        assertEquals(SelectionKey.OP_CONNECT, selectionKey.interestOps());
140    }
141
142    /**
143     * @tests java.nio.channels.SelectionKey#interestOps(int)
144     */
145    public void test_interestOpsI() {
146        selectionKey.interestOps(SelectionKey.OP_WRITE);
147        assertEquals(SelectionKey.OP_WRITE, selectionKey.interestOps());
148
149        try {
150            selectionKey.interestOps(SelectionKey.OP_ACCEPT);
151            fail("should throw IAE.");
152        } catch (IllegalArgumentException ex) {
153            // expected;
154        }
155
156        try {
157            selectionKey.interestOps(~sc.validOps());
158            fail("should throw IAE.");
159        } catch (IllegalArgumentException ex) {
160            // expected;
161        }
162        try {
163            selectionKey.interestOps(-1);
164            fail("should throw IAE.");
165        } catch (IllegalArgumentException ex) {
166            // expected;
167        }
168
169    }
170
171    /**
172     * @tests java.nio.channels.SelectionKey#isValid()
173     */
174    public void test_isValid() {
175        assertTrue(selectionKey.isValid());
176    }
177
178    /**
179     * @tests java.nio.channels.SelectionKey#isValid()
180     */
181    public void test_isValid_KeyCancelled() {
182        selectionKey.cancel();
183        assertFalse(selectionKey.isValid());
184    }
185
186    /**
187     * @tests java.nio.channels.SelectionKey#isValid()
188     */
189    public void test_isValid_ChannelColsed() throws IOException {
190        sc.close();
191        assertFalse(selectionKey.isValid());
192    }
193
194    /**
195     * @tests java.nio.channels.SelectionKey#isValid()
196     */
197    public void test_isValid_SelectorClosed() throws IOException {
198        selector.close();
199        assertFalse(selectionKey.isValid());
200    }
201
202    /**
203     * @tests java.nio.channels.SelectionKey#isAcceptable()
204     */
205    public void test_isAcceptable() throws IOException {
206        MockSelectionKey mockSelectionKey1 = new MockSelectionKey(SelectionKey.OP_ACCEPT);
207        assertTrue(mockSelectionKey1.isAcceptable());
208        MockSelectionKey mockSelectionKey2 = new MockSelectionKey(SelectionKey.OP_CONNECT);
209        assertFalse(mockSelectionKey2.isAcceptable());
210    }
211
212    /**
213     * @tests java.nio.channels.SelectionKey#isConnectable()
214     */
215    public void test_isConnectable() {
216        MockSelectionKey mockSelectionKey1 = new MockSelectionKey(SelectionKey.OP_CONNECT);
217        assertTrue(mockSelectionKey1.isConnectable());
218        MockSelectionKey mockSelectionKey2 = new MockSelectionKey(SelectionKey.OP_ACCEPT);
219        assertFalse(mockSelectionKey2.isConnectable());
220    }
221
222    /**
223     * @tests java.nio.channels.SelectionKey#isReadable()
224     */
225    public void test_isReadable() {
226        MockSelectionKey mockSelectionKey1 = new MockSelectionKey(SelectionKey.OP_READ);
227        assertTrue(mockSelectionKey1.isReadable());
228        MockSelectionKey mockSelectionKey2 = new MockSelectionKey(SelectionKey.OP_ACCEPT);
229        assertFalse(mockSelectionKey2.isReadable());
230    }
231
232    /**
233     * @tests java.nio.channels.SelectionKey#isWritable()
234     */
235    public void test_isWritable() {
236        MockSelectionKey mockSelectionKey1 = new MockSelectionKey(SelectionKey.OP_WRITE);
237        assertTrue(mockSelectionKey1.isWritable());
238        MockSelectionKey mockSelectionKey2 = new MockSelectionKey(SelectionKey.OP_ACCEPT);
239        assertFalse(mockSelectionKey2.isWritable());
240    }
241
242    /**
243     * @tests java.nio.channels.SelectionKey#cancel()
244     */
245    public void test_cancel() {
246        selectionKey.cancel();
247        try {
248            selectionKey.isAcceptable();
249            fail("should throw CancelledKeyException.");
250        } catch (CancelledKeyException ex) {
251            // expected
252        }
253        try {
254            selectionKey.isConnectable();
255            fail("should throw CancelledKeyException.");
256        } catch (CancelledKeyException ex) {
257            // expected
258        }
259        try {
260            selectionKey.isReadable();
261            fail("should throw CancelledKeyException.");
262        } catch (CancelledKeyException ex) {
263            // expected
264        }
265        try {
266            selectionKey.isWritable();
267            fail("should throw CancelledKeyException.");
268        } catch (CancelledKeyException ex) {
269            // expected
270        }
271
272        try {
273            selectionKey.readyOps();
274            fail("should throw CancelledKeyException.");
275        } catch (CancelledKeyException ex) {
276            // expected
277        }
278
279        try {
280            selectionKey.interestOps(SelectionKey.OP_CONNECT);
281            fail("should throw CancelledKeyException.");
282        } catch (CancelledKeyException ex) {
283            // expected
284        }
285
286        try {
287            selectionKey.interestOps();
288            fail("should throw CancelledKeyException.");
289        } catch (CancelledKeyException ex) {
290            // expected
291        }
292    }
293
294    /**
295     * @tests java.nio.channels.SelectionKey#readyOps()
296     */
297    public void test_readyOps() throws IOException {
298        int port = Support_PortManager.getNextPort();
299        ServerSocket ss = new ServerSocket(port);
300        try {
301            sc.connect(new InetSocketAddress(LOCAL_ADDR, port));
302            assertEquals(0, selectionKey.readyOps());
303            assertFalse(selectionKey.isConnectable());
304            selector.select();
305            assertEquals(SelectionKey.OP_CONNECT, selectionKey.readyOps());
306        } finally {
307            ss.close();
308            ss = null;
309        }
310
311    }
312
313    /**
314     * @tests java.nio.channels.SelectionKey#selector()
315     */
316    public void test_selector() {
317        assertSame(selector, selectionKey.selector());
318        selectionKey.cancel();
319        assertSame(selector, selectionKey.selector());
320    }
321}
322