@Test
public void testSocketIOWithTimeout() throws Exception {

  
  // first open pipe:
  Pipe pipe = Pipe.open();
  Pipe.SourceChannel source = pipe.source();
  Pipe.SinkChannel sink = pipe.sink();
  
  try {
    final InputStream in = new SocketInputStream(source, TIMEOUT);
    OutputStream out = new SocketOutputStream(sink, TIMEOUT);
    
    byte[] writeBytes = TEST_STRING.getBytes();
    byte[] readBytes = new byte[writeBytes.length];
    byte byteWithHighBit = (byte)0x80;
    
    out.write(writeBytes);
    out.write(byteWithHighBit);
    doIO(null, out, TIMEOUT);
    
    in.read(readBytes);
    assertTrue(Arrays.equals(writeBytes, readBytes));
    assertEquals(byteWithHighBit & 0xff, in.read());
    doIO(in, null, TIMEOUT);
    
    // Change timeout on the read side.
    ((SocketInputStream)in).setTimeout(TIMEOUT * 2);
    doIO(in, null, TIMEOUT * 2);
    
    
    /*
     * Verify that it handles interrupted threads properly.
     * Use a large timeout and expect the thread to return quickly
     * upon interruption.
     */
    ((SocketInputStream)in).setTimeout(0);
    TestingThread thread = new TestingThread(ctx) {
      @Override
      public void doWork() throws Exception {
        try {
          in.read();
          fail("Did not fail with interrupt");
        } catch (InterruptedIOException ste) {
          LOG.info("Got expection while reading as expected : " + 
              ste.getMessage());
        }
      }
    };
    ctx.addThread(thread);
    ctx.startThreads();
    // If the thread is interrupted before it calls read()
    // then it throws ClosedByInterruptException due to
    // some Java quirk. Waiting for it to call read()
    // gets it into select(), so we get the expected
    // InterruptedIOException.
    Thread.sleep(1000);
    thread.interrupt();
    ctx.stop();
    //make sure the channels are still open
    assertTrue(source.isOpen());
    assertTrue(sink.isOpen());
    
    // Nevertheless, the output stream is closed, because
    // a partial write may have succeeded (see comment in
    // SocketOutputStream#write(byte[]), int, int)
    // This portion of the test cannot pass on Windows due to differences in
    // behavior of partial writes.  Windows appears to buffer large amounts of
    // written data and send it all atomically, thus making it impossible to
    // simulate a partial write scenario.  Attempts were made to switch the
    // test from using a pipe to a network socket and also to use larger and
    // larger buffers in doIO.  Nothing helped the situation though.
    if (!Shell.WINDOWS) {
      try {
        out.write(1);
        fail("Did not throw");
      } catch (IOException ioe) {
        GenericTestUtils.assertExceptionContains(
            "stream is closed", ioe);
      }
    }
    
    out.close();
    assertFalse(sink.isOpen());
    
    // close sink and expect -1 from source.read()
    assertEquals(-1, in.read());
    
    // make sure close() closes the underlying channel.
    in.close();
    assertFalse(source.isOpen());
    
  } finally {
    if (source != null) {
      source.close();
    }
    if (sink != null) {
      sink.close();
    }
  }
}