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; 18 19import java.io.IOException; 20import java.net.InetAddress; 21import java.net.InetSocketAddress; 22import java.nio.ByteBuffer; 23import java.nio.channels.ClosedChannelException; 24import java.nio.channels.Pipe; 25import java.nio.channels.SelectionKey; 26import java.nio.channels.ServerSocketChannel; 27import java.nio.channels.SocketChannel; 28 29import junit.framework.TestCase; 30 31/** 32 * Tests for Pipe.SinkChannel class 33 */ 34public class SinkChannelTest extends TestCase { 35 36 private static final int BUFFER_SIZE = 5; 37 38 private static final String ISO8859_1 = "ISO8859-1"; 39 40 private Pipe pipe; 41 42 private Pipe.SinkChannel sink; 43 44 private Pipe.SourceChannel source; 45 46 private ByteBuffer buffer; 47 48 private ByteBuffer positionedBuffer; 49 50 protected void setUp() throws Exception { 51 super.setUp(); 52 pipe = Pipe.open(); 53 sink = pipe.sink(); 54 source = pipe.source(); 55 buffer = ByteBuffer.wrap("bytes".getBytes(ISO8859_1)); 56 positionedBuffer = ByteBuffer.wrap("12345bytes".getBytes(ISO8859_1)); 57 positionedBuffer.position(BUFFER_SIZE); 58 } 59 60 /** 61 * @tests java.nio.channels.Pipe.SinkChannel#validOps() 62 */ 63 public void test_validOps() { 64 assertEquals(SelectionKey.OP_WRITE, sink.validOps()); 65 } 66 67 /** 68 * @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer) 69 */ 70 public void test_write_LByteBuffer() throws IOException { 71 ByteBuffer[] bufArray = { buffer, positionedBuffer }; 72 boolean[] sinkBlockingMode = { true, true, false, false }; 73 boolean[] sourceBlockingMode = { true, false, true, false }; 74 int oldPosition; 75 int currentPosition; 76 for (int i = 0; i < sinkBlockingMode.length; ++i) { 77 sink.configureBlocking(sinkBlockingMode[i]); 78 source.configureBlocking(sourceBlockingMode[i]); 79 // if sink and source both are blocking mode, source only needs read 80 // once to get what sink write. 81 boolean isBlocking = sinkBlockingMode[i] && sourceBlockingMode[i]; 82 for (ByteBuffer buf : bufArray) { 83 buf.mark(); 84 oldPosition = buf.position(); 85 sink.write(buf); 86 ByteBuffer readBuf = ByteBuffer.allocate(BUFFER_SIZE); 87 int totalCount = 0; 88 do { 89 int count = source.read(readBuf); 90 if (count > 0) { 91 totalCount += count; 92 } 93 } while (totalCount != BUFFER_SIZE && !isBlocking); 94 currentPosition = buf.position(); 95 assertEquals(BUFFER_SIZE, currentPosition - oldPosition); 96 assertEquals("bytes", new String(readBuf.array(), ISO8859_1)); 97 buf.reset(); 98 } 99 } 100 } 101 102 /** 103 * @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer) 104 */ 105 public void test_write_LByteBuffer_mutliThread() throws IOException, 106 InterruptedException { 107 final int THREAD_NUM = 20; 108 final byte[] strbytes = "bytes".getBytes(ISO8859_1); 109 Thread[] thread = new Thread[THREAD_NUM]; 110 for (int i = 0; i < THREAD_NUM; i++) { 111 thread[i] = new Thread() { 112 public void run() { 113 try { 114 sink.write(ByteBuffer.wrap(strbytes)); 115 } catch (IOException e) { 116 throw new RuntimeException(e); 117 } 118 } 119 }; 120 } 121 for (int i = 0; i < THREAD_NUM; i++) { 122 thread[i].start(); 123 } 124 for (int i = 0; i < THREAD_NUM; i++) { 125 thread[i].join(); 126 } 127 ByteBuffer readBuf = ByteBuffer.allocate(THREAD_NUM * BUFFER_SIZE); 128 129 long totalCount = 0; 130 do { 131 long count = source.read(readBuf); 132 if (count < 0) { 133 break; 134 } 135 totalCount += count; 136 } while (totalCount != (THREAD_NUM * BUFFER_SIZE)); 137 138 StringBuffer buf = new StringBuffer(); 139 for (int i = 0; i < THREAD_NUM; i++) { 140 buf.append("bytes"); 141 } 142 String readString = buf.toString(); 143 assertEquals(readString, new String(readBuf.array(), ISO8859_1)); 144 } 145 146 /** 147 * @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer) 148 */ 149 public void test_write_LByteBuffer_Exception() throws IOException { 150 // write null ByteBuffer 151 ByteBuffer nullBuf = null; 152 try { 153 sink.write(nullBuf); 154 fail("should throw NullPointerException"); 155 } catch (NullPointerException e) { 156 // expected 157 } 158 } 159 160 public void test_write_LByteBuffer_SourceClosed() throws IOException { 161 source.close(); 162 try { 163 int written = sink.write(buffer); 164 fail(); 165 } catch (IOException expected) { 166 } 167 } 168 169 public void test_write_LByteBuffer_SinkClosed() throws IOException { 170 sink.close(); 171 try { 172 sink.write(buffer); 173 fail("should throw ClosedChannelException"); 174 } catch (ClosedChannelException expected) { 175 } 176 } 177 178 /** 179 * @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer[]) 180 */ 181 public void test_write_$LByteBuffer() throws IOException { 182 ByteBuffer[] bufArray = { buffer, positionedBuffer }; 183 boolean[] sinkBlockingMode = { true, true, false, false }; 184 boolean[] sourceBlockingMode = { true, false, true, false }; 185 for (int i = 0; i < sinkBlockingMode.length; ++i) { 186 sink.configureBlocking(sinkBlockingMode[i]); 187 source.configureBlocking(sourceBlockingMode[i]); 188 buffer.position(0); 189 positionedBuffer.position(BUFFER_SIZE); 190 sink.write(bufArray); 191 // if sink and source both are blocking mode, source only needs read 192 // once to get what sink write. 193 boolean isBlocking = sinkBlockingMode[i] && sourceBlockingMode[i]; 194 for (int j = 0; j < bufArray.length; ++j) { 195 ByteBuffer readBuf = ByteBuffer.allocate(BUFFER_SIZE); 196 int totalCount = 0; 197 do { 198 int count = source.read(readBuf); 199 if (count < 0) { 200 break; 201 } 202 totalCount += count; 203 } while (totalCount != BUFFER_SIZE && !isBlocking); 204 assertEquals("bytes", new String(readBuf.array(), ISO8859_1)); 205 } 206 assertEquals(BUFFER_SIZE, buffer.position()); 207 assertEquals(10, positionedBuffer.position()); 208 } 209 } 210 211 /** 212 * @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer[]) 213 */ 214 public void test_write_$LByteBuffer_Exception() throws IOException { 215 // write null ByteBuffer[] 216 ByteBuffer[] nullBufArrayRef = null; 217 try { 218 sink.write(nullBufArrayRef); 219 fail("should throw NullPointerException"); 220 } catch (NullPointerException e) { 221 // expected 222 } 223 224 // write ByteBuffer[] contains null element 225 ByteBuffer nullBuf = null; 226 ByteBuffer[] nullBufArray = { buffer, nullBuf }; 227 try { 228 sink.write(nullBufArray); 229 fail("should throw NullPointerException"); 230 } catch (NullPointerException e) { 231 // expected 232 } 233 } 234 235 public void test_write_$LByteBuffer_SourceClosed() throws IOException { 236 ByteBuffer[] bufArray = { buffer }; 237 source.close(); 238 try { 239 long written = sink.write(bufArray); 240 fail(); 241 } catch (IOException expected) { 242 } 243 } 244 245 /** 246 * @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer[]) 247 */ 248 public void test_write_$LByteBuffer_SinkClosed() throws IOException { 249 ByteBuffer[] bufArray = { buffer }; 250 sink.close(); 251 try { 252 sink.write(bufArray); 253 fail("should throw ClosedChannelException"); 254 } catch (ClosedChannelException e) { 255 // expected 256 } 257 258 ByteBuffer[] nullBufArrayRef = null; 259 try { 260 sink.write(nullBufArrayRef); 261 fail("should throw NullPointerException"); 262 } catch (NullPointerException e) { 263 // expected 264 } 265 266 ByteBuffer nullBuf = null; 267 ByteBuffer[] nullBufArray = { nullBuf }; 268 // write ByteBuffer[] contains null element 269 try { 270 sink.write(nullBufArray); 271 fail("should throw ClosedChannelException"); 272 } catch (ClosedChannelException e) { 273 // expected 274 } 275 } 276 277 /** 278 * @tests java.nio.channels.Pipe.SinkChannel#write(ByteBuffer[], int, int) 279 */ 280 public void test_write_$LByteBufferII() throws IOException { 281 ByteBuffer[] bufArray = { buffer, positionedBuffer }; 282 boolean[] sinkBlockingMode = { true, true, false, false }; 283 boolean[] sourceBlockingMode = { true, false, true, false }; 284 for (int i = 0; i < sinkBlockingMode.length; ++i) { 285 sink.configureBlocking(sinkBlockingMode[i]); 286 source.configureBlocking(sourceBlockingMode[i]); 287 positionedBuffer.position(BUFFER_SIZE); 288 sink.write(bufArray, 1, 1); 289 // if sink and source both are blocking mode, source only needs read 290 // once to get what sink write. 291 boolean isBlocking = sinkBlockingMode[i] && sourceBlockingMode[i]; 292 ByteBuffer readBuf = ByteBuffer.allocate(BUFFER_SIZE); 293 int totalCount = 0; 294 do { 295 int count = source.read(readBuf); 296 if (count < 0) { 297 break; 298 } 299 totalCount += count; 300 } while (totalCount != BUFFER_SIZE && !isBlocking); 301 assertEquals("bytes", new String(readBuf.array(), ISO8859_1)); 302 assertEquals(10, positionedBuffer.position()); 303 } 304 } 305 306 public void test_write_$LByteBufferII_Exception() throws IOException { 307 try { 308 sink.write(null, 0, 1); 309 fail(); 310 } catch (NullPointerException expected) { 311 } 312 313 try { 314 sink.write(new ByteBuffer[2], 0, -1); 315 fail(); 316 } catch (IndexOutOfBoundsException expected) { 317 } 318 319 // write ByteBuffer[] contains null element 320 ByteBuffer nullBuf = null; 321 ByteBuffer[] nullBufArray = { nullBuf }; 322 try { 323 sink.write(nullBufArray, 0, 1); 324 fail("should throw NullPointerException"); 325 } catch (NullPointerException e) { 326 // expected 327 } 328 329 try { 330 sink.write(nullBufArray, 0, -1); 331 fail("should throw IndexOutOfBoundsException"); 332 } catch (IndexOutOfBoundsException e) { 333 // expected 334 } 335 336 ByteBuffer[] bufArray = { buffer, nullBuf }; 337 try { 338 sink.write(bufArray, 0, -1); 339 fail("should throw IndexOutOfBoundsException"); 340 } catch (IndexOutOfBoundsException e) { 341 // expected 342 } 343 344 try { 345 sink.write(bufArray, -1, 0); 346 fail("should throw IndexOutOfBoundsException"); 347 } catch (IndexOutOfBoundsException e) { 348 // expected 349 } 350 351 try { 352 sink.write(bufArray, -1, 1); 353 fail("should throw IndexOutOfBoundsException"); 354 } catch (IndexOutOfBoundsException e) { 355 // expected 356 } 357 358 try { 359 sink.write(bufArray, 0, 3); 360 fail("should throw IndexOutOfBoundsException"); 361 } catch (IndexOutOfBoundsException e) { 362 // expected 363 } 364 365 try { 366 sink.write(bufArray, 0, 2); 367 fail("should throw NullPointerException"); 368 } catch (NullPointerException e) { 369 // expected 370 } 371 } 372 373 public void test_write_$LByteBufferII_SourceClosed() throws IOException { 374 ByteBuffer[] bufArray = { buffer }; 375 source.close(); 376 377 try { 378 long written = sink.write(bufArray, 0, 1); 379 fail(); 380 } catch (IOException expected) { 381 } 382 } 383 384 public void test_write_$LByteBufferII_SinkClosed() throws IOException { 385 ByteBuffer[] bufArray = { buffer }; 386 sink.close(); 387 try { 388 sink.write(bufArray, 0, 1); 389 fail(); 390 } catch (ClosedChannelException expected) { 391 } 392 393 try { 394 sink.write(null, 0, 1); 395 fail(); 396 } catch (NullPointerException expected) { 397 } 398 try { 399 sink.write(new ByteBuffer[2], 0, -1); 400 fail(); 401 } catch (IndexOutOfBoundsException expected) { 402 } 403 404 // write ByteBuffer[] contains null element 405 ByteBuffer nullBuf = null; 406 ByteBuffer[] nullBufArray = { nullBuf }; 407 try { 408 sink.write(nullBufArray, 0, 1); 409 fail("should throw ClosedChannelException"); 410 } catch (ClosedChannelException e) { 411 // expected 412 } 413 // illegal array index 414 try { 415 sink.write(nullBufArray, 0, -1); 416 fail("should throw IndexOutOfBoundsException"); 417 } catch (IndexOutOfBoundsException e) { 418 // expected 419 } 420 421 ByteBuffer[] bufArray2 = { buffer, nullBuf }; 422 // illegal array index 423 try { 424 sink.write(bufArray2, 0, -1); 425 fail("should throw IndexOutOfBoundsException"); 426 } catch (IndexOutOfBoundsException e) { 427 // expected 428 } 429 430 try { 431 sink.write(bufArray2, -1, 0); 432 fail("should throw IndexOutOfBoundsException"); 433 } catch (IndexOutOfBoundsException e) { 434 // expected 435 } 436 437 try { 438 sink.write(bufArray2, -1, 1); 439 fail("should throw IndexOutOfBoundsException"); 440 } catch (IndexOutOfBoundsException e) { 441 // expected 442 } 443 444 try { 445 sink.write(bufArray2, 0, 3); 446 fail("should throw IndexOutOfBoundsException"); 447 } catch (IndexOutOfBoundsException e) { 448 // expected 449 } 450 451 try { 452 sink.write(bufArray2, 0, 2); 453 fail("should throw ClosedChannelException"); 454 } catch (ClosedChannelException e) { 455 // expected 456 } 457 } 458 459 public void test_close() throws IOException { 460 sink.close(); 461 assertFalse(sink.isOpen()); 462 } 463 464 public void test_socketChannel_read_close() throws Exception { 465 ServerSocketChannel ssc = ServerSocketChannel.open(); 466 ssc.socket().bind(new InetSocketAddress(InetAddress.getLocalHost(),49999)); 467 SocketChannel sc = SocketChannel.open(); 468 ByteBuffer buf = null; 469 try{ 470 sc.write(buf); 471 fail("should throw NPE"); 472 }catch (NullPointerException e){ 473 // expected 474 } 475 sc.connect(new InetSocketAddress(InetAddress.getLocalHost(),49999)); 476 SocketChannel sock = ssc.accept(); 477 ssc.close(); 478 sc.close(); 479 try{ 480 sc.write(buf); 481 fail("should throw NPE"); 482 }catch (NullPointerException e){ 483 // expected 484 } 485 sock.close(); 486 } 487 488 public void test_socketChannel_read_write() throws Exception { 489 ServerSocketChannel ssc = ServerSocketChannel.open(); 490 ssc.socket().bind(new InetSocketAddress(InetAddress.getLocalHost(),49999)); 491 SocketChannel sc = SocketChannel.open(); 492 sc.connect(new InetSocketAddress(InetAddress.getLocalHost(),49999)); 493 SocketChannel sock = ssc.accept(); 494 ByteBuffer[] buf = {ByteBuffer.allocate(10),null}; 495 try { 496 sc.write(buf,0,2); 497 fail("should throw NPE"); 498 } catch (NullPointerException expected) { 499 } 500 ssc.close(); 501 sc.close(); 502 ByteBuffer target = ByteBuffer.allocate(10); 503 assertEquals(-1, sock.read(target)); 504 } 505} 506