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.tests.java.nio.channels.spi;
18
19import java.io.IOException;
20import java.nio.channels.ClosedChannelException;
21import java.nio.channels.IllegalBlockingModeException;
22import java.nio.channels.IllegalSelectorException;
23import java.nio.channels.SelectableChannel;
24import java.nio.channels.SelectionKey;
25import java.nio.channels.Selector;
26import java.nio.channels.SocketChannel;
27import java.nio.channels.spi.AbstractSelectableChannel;
28import java.nio.channels.spi.SelectorProvider;
29
30import junit.framework.TestCase;
31
32/**
33 * Tests for AbstractSelectableChannel
34 */
35public class AbstractSelectableChannelTest extends TestCase {
36
37    private MockSelectableChannel testChannel;
38
39    protected void setUp() throws Exception {
40        super.setUp();
41        testChannel = new MockSelectableChannel(SelectorProvider.provider());
42    }
43
44    protected void tearDown() throws Exception {
45        if (testChannel.isOpen()) {
46            testChannel.close();
47        }
48    }
49
50    /**
51     * @tests AbstractSelectableChannel#implCloseChannel()
52     */
53    public void test_implClose() throws IOException {
54        testChannel.isImplCloseSelectableChannelCalled = false;
55        testChannel.implCloseSelectableChannelCount = 0;
56        testChannel.close();
57        assertFalse(testChannel.isOpen());
58        assertTrue(testChannel.isImplCloseSelectableChannelCalled);
59        assertEquals(1, testChannel.implCloseSelectableChannelCount);
60
61        testChannel = new MockSelectableChannel(SelectorProvider.provider());
62        testChannel.isImplCloseSelectableChannelCalled = false;
63        testChannel.implCloseSelectableChannelCount = 0;
64        // close twice.
65        // make sure implCloseSelectableChannelCount is called only once.
66        testChannel.close();
67        testChannel.close();
68        assertFalse(testChannel.isOpen());
69        assertTrue(testChannel.isImplCloseSelectableChannelCalled);
70        assertEquals(1, testChannel.implCloseSelectableChannelCount);
71    }
72
73    /**
74     * @tests AbstractSelectableChannel#provider()
75     */
76    public void test_provider() {
77        SelectorProvider provider = testChannel.provider();
78        assertSame(SelectorProvider.provider(), provider);
79        testChannel = new MockSelectableChannel(null);
80        provider = testChannel.provider();
81        assertNull(provider);
82    }
83
84    /**
85     * @tests AbstractSelectableChannel#isBlocking()
86     */
87    public void test_isBlocking() throws IOException {
88        assertTrue(testChannel.isBlocking());
89        testChannel.configureBlocking(false);
90        assertFalse(testChannel.isBlocking());
91        testChannel.configureBlocking(true);
92        assertTrue(testChannel.isBlocking());
93    }
94
95    /**
96     *
97     * @tests AbstractSelectableChannel#blockingLock()
98     */
99    public void test_blockingLock() {
100        Object gotObj = testChannel.blockingLock();
101        assertNotNull(gotObj);
102    }
103
104    /**
105     * @tests AbstractSelectableChannel#register(Selector, int, Object)
106     */
107    public void test_register_LSelectorILObject() throws IOException {
108        assertFalse(testChannel.isRegistered());
109        Selector acceptSelector1 = SelectorProvider.provider().openSelector();
110        Selector acceptSelector2 = new MockAbstractSelector(SelectorProvider
111                .provider());
112        SocketChannel sc = SocketChannel.open();
113        sc.configureBlocking(false);
114        SelectionKey acceptKey = sc.register(acceptSelector1,
115                SelectionKey.OP_READ, null);
116        assertNotNull(acceptKey);
117        assertTrue(acceptKey.isValid());
118        assertSame(sc, acceptKey.channel());
119
120        //test that sc.register invokes Selector.register()
121        acceptKey = sc.register(acceptSelector2, SelectionKey.OP_READ, null);
122        assertNull(acceptKey);
123
124        // Regression test to ensure acceptance of a selector with empty
125        // interest set.
126        SocketChannel channel = SocketChannel.open();
127        channel.configureBlocking(false);
128        Selector selector = Selector.open();
129        channel.register(selector, 0);
130        selector.close();
131        channel.close();
132    }
133
134    /**
135     * @tests AbstractSelectableChannel#register(Selector, int, Object)
136     */
137    public void test_register_LSelectorILObject_IllegalArgument()
138            throws IOException {
139        Selector acceptSelector = SelectorProvider.provider().openSelector();
140        assertTrue(acceptSelector.isOpen());
141        MockSelectableChannel msc = new MockSelectableChannel(SelectorProvider
142                .provider());
143        msc.configureBlocking(false);
144        // in nonblocking mode
145        try {
146            //different SelectionKey with validOps
147            msc.register(acceptSelector, SelectionKey.OP_READ, null);
148            fail("Should throw IllegalArgumentException");
149        } catch (IllegalArgumentException e) {
150            // expected
151        }
152        try {
153            msc.register(null, 0, null);
154            fail("Should throw NullPointerException");
155        } catch (NullPointerException e) {
156            // expected
157        }
158        // in nonblocking mode, if selector closed
159        acceptSelector.close();
160        try {
161            msc.register(acceptSelector, SelectionKey.OP_READ, null);
162            fail("Should throw IllegalArgumentException");
163        } catch (IllegalArgumentException e) {
164            // expected
165        }
166        try {
167            msc.register(null, 0, null);
168            fail("Should throw NullPointerException");
169        } catch (NullPointerException e) {
170            // expected
171        }
172        try {
173            msc.register(acceptSelector, 0, null);
174            fail("Should throw IllegalSelectorException");
175        } catch (IllegalSelectorException e) {
176            // expected
177        }
178
179        acceptSelector = SelectorProvider.provider().openSelector();
180        // test in blocking mode
181        msc.configureBlocking(true);
182        try {
183            msc.register(acceptSelector, SelectionKey.OP_READ, null);
184            fail("Should throw IllegalArgumentException");
185        } catch (IllegalArgumentException e) {
186            // expected
187        }
188        try {
189            msc.register(null, 0, null);
190            fail("Should throw IllegalBlockingModeException");
191        } catch (IllegalBlockingModeException e) {
192            // expected
193        }
194        acceptSelector.close();
195        // in blocking mode, if selector closed
196        try {
197            msc.register(acceptSelector, SelectionKey.OP_READ, null);
198            fail("Should throw IllegalArgumentException");
199        } catch (IllegalArgumentException e) {
200            // expected
201        }
202        try {
203            msc.register(null, 0, null);
204            fail("Should throw IllegalBlockingModeException");
205        } catch (IllegalBlockingModeException e) {
206            // expected
207        }
208
209        // register with an object
210        Object argObj = new Object();
211        SocketChannel sc = SocketChannel.open();
212        sc.configureBlocking(false);
213        try {
214            sc.register(null, SelectionKey.OP_READ, argObj);
215            fail("Should throw NullPointerException");
216        } catch (NullPointerException e) {
217            // expected
218        }
219
220        // if channel closed
221        msc.close();
222        try {
223            msc.register(acceptSelector, SelectionKey.OP_READ, null);
224            fail("Should throw ClosedChannelException");
225        } catch (ClosedChannelException e) {
226            // expected
227        }
228
229    }
230
231    /**
232     * @tests AbstractSelectableChannel#keyFor(Selector)
233     */
234    public void test_keyfor_LSelector() throws Exception {
235        SocketChannel sc = SocketChannel.open();
236        Object argObj = new Object();
237        sc.configureBlocking(false);
238        Selector acceptSelector = SelectorProvider.provider().openSelector();
239        Selector acceptSelectorOther = SelectorProvider.provider()
240                .openSelector();
241        SelectionKey acceptKey = sc.register(acceptSelector,
242                SelectionKey.OP_READ, argObj);
243        assertEquals(sc.keyFor(acceptSelector), acceptKey);
244        SelectionKey acceptKeyObjNull = sc.register(acceptSelector,
245                SelectionKey.OP_READ, null);
246        assertSame(sc.keyFor(acceptSelector), acceptKeyObjNull);
247        assertSame(acceptKeyObjNull, acceptKey);
248        SelectionKey acceptKeyOther = sc.register(acceptSelectorOther,
249                SelectionKey.OP_READ, null);
250        assertSame(sc.keyFor(acceptSelectorOther), acceptKeyOther);
251    }
252
253    /**
254     * @tests AbstractSelectableChannel#configureBlocking(boolean)
255     */
256    public void test_configureBlocking_Z_IllegalBlockingMode() throws Exception {
257        SocketChannel sc = SocketChannel.open();
258        sc.configureBlocking(false);
259        Selector acceptSelector = SelectorProvider.provider().openSelector();
260        SelectionKey acceptKey = sc.register(acceptSelector,
261                SelectionKey.OP_READ, null);
262        assertEquals(sc.keyFor(acceptSelector), acceptKey);
263        SelectableChannel getChannel = sc.configureBlocking(false);
264        assertEquals(getChannel, sc);
265        try {
266            sc.configureBlocking(true);
267            fail("Should throw IllegalBlockingModeException");
268        } catch (IllegalBlockingModeException e) {
269            // expected
270        }
271    }
272
273    /**
274     * @tests AbstractSelectableChannel#configureBlocking(boolean)
275     */
276    public void test_configureBlocking_Z() throws Exception {
277        MockSelectableChannel mock = new MockSelectableChannel(SelectorProvider
278                .provider());
279        //default blocking mode is true
280        //the implConfigureBlocking is only invoked if the given mode is different with current one
281        mock.configureBlocking(true);
282        assertFalse(mock.implConfigureBlockingCalled);
283        mock.configureBlocking(false);
284        assertTrue(mock.implConfigureBlockingCalled);
285    }
286
287    private class MockSelectableChannel extends AbstractSelectableChannel {
288
289        private boolean isImplCloseSelectableChannelCalled = false;
290
291        private int implCloseSelectableChannelCount = 0;
292
293        private boolean implConfigureBlockingCalled = false;
294
295        public MockSelectableChannel(SelectorProvider arg0) {
296            super(arg0);
297        }
298
299        protected void implCloseSelectableChannel() throws IOException {
300            isImplCloseSelectableChannelCalled = true;
301            ++implCloseSelectableChannelCount;
302        }
303
304        protected void implConfigureBlocking(boolean arg0) throws IOException {
305            implConfigureBlockingCalled = true;
306        }
307
308        public int validOps() {
309            return SelectionKey.OP_ACCEPT;
310        }
311
312    }
313}
314