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