package org.jgroups.tests; import org.jgroups.Global; import org.jgroups.util.BlockingInputStream; import org.jgroups.util.Util; import org.testng.annotations.Test; import java.io.IOException; import java.io.InputStream; import java.util.concurrent.CountDownLatch; /** * Tests {@link org.jgroups.util.BlockingInputStream} * @author Bela Ban */ @Test(groups=Global.FUNCTIONAL,sequential=false) public class BlockingInputStreamTest { public void testCreation() throws IOException { BlockingInputStream in=new BlockingInputStream(2000); System.out.println("in = " + in); assert in.available() == 0 && in.capacity() == 2000; in.write(new byte[]{'b', 'e', 'l', 'a'}); System.out.println("in = " + in); assert in.available() == 4 && in.capacity() == 2000; } public void testRead() throws IOException { final BlockingInputStream in=new BlockingInputStream(100); byte[] input=new byte[]{'B', 'e', 'l', 'a'}; in.write(input); in.close(); assert in.available() == 4; for(int i=0; i < input.length; i++) { int b=in.read(); assert b == input[i]; } int b=in.read(); assert b == -1; } public void testBlockingReadAndClose() throws IOException { final BlockingInputStream in=new BlockingInputStream(100); final CountDownLatch latch=new CountDownLatch(1); byte[] buf=new byte[100]; new Closer(latch, in, 1000L).start(); // closes input stream after 1 sec latch.countDown(); int num=in.read(buf, 0, buf.length); assert num == -1 : " expected -1 (EOF) but got " + num; } public void testBlockingWriteAndClose() throws IOException { final BlockingInputStream in=new BlockingInputStream(3); final CountDownLatch latch=new CountDownLatch(1); byte[] buf=new byte[]{'B', 'e', 'l', 'a'}; new Closer(latch, in, 1000L).start(); // closes input stream after 1 sec latch.countDown(); in.write(buf, 0, buf.length); } public void testReadOnClosedInputStream() throws IOException { final BlockingInputStream in=new BlockingInputStream(100); in.close(); byte[] buf=new byte[100]; int num=in.read(buf, 0, buf.length); assert num == -1 : " expected -1 (EOF) but got " + num; } public void testWriteCloseRead() throws IOException { final BlockingInputStream in=new BlockingInputStream(100); for(int i=1; i <= 5; i++) { byte[] buf=("Hello world " + i).getBytes(); in.write(buf); } in.close(); int size=in.available(); byte[] buf=new byte[100]; int num=in.read(buf); assert num == size; } public void testWriteCloseRead2() throws IOException { final BlockingInputStream in=new BlockingInputStream(100); StringBuilder sb=new StringBuilder(); for(int i=1; i <=10; i++) sb.append("Hello world " + i); byte[] buffer=sb.toString().getBytes(); new Writer(in, buffer).start(); Util.sleep(500); int size=in.available(); byte[] buf=new byte[200]; int num=in.read(buf); assert num == size; } public void testSimpleTransfer() throws IOException { final BlockingInputStream in=new BlockingInputStream(100); byte[] buffer=new byte[500]; for(int i=0; i < buffer.length; i++) buffer[i]=(byte)(i % 2 == 0? 0 : 1); new Writer(in, buffer).start(); byte[] tmp=new byte[500]; int offset=0; while(true) { int bytes=in.read(tmp, offset, tmp.length - offset); if(bytes == -1) break; offset+=bytes; } System.out.println("read " + offset + " bytes"); assert offset == 500 : "offset is " + offset + " but expected 500"; for(int i=0; i < tmp.length; i++) { if(i % 2 == 0) assert tmp[i] == 0; else assert tmp[i] == 1; } } public void testLargeTransfer() throws IOException { final BlockingInputStream in=new BlockingInputStream(2048); final byte[] buffer=generateBuffer(100000); new Writer(in, buffer).start(); byte[] tmp=new byte[buffer.length]; int offset=0; while(true) { int bytes=in.read(tmp, offset, tmp.length - offset); if(bytes == -1) break; offset+=bytes; } System.out.println("read " + offset + " bytes"); assert offset == buffer.length : "offset is " + offset + " but expected " + buffer.length; System.out.print("Verifying that the buffers are the same: "); for(int i=0; i < tmp.length; i++) assert buffer[i] == tmp[i]; System.out.println("OK"); } public void testWriteExceedingCapacity() throws IOException { final BlockingInputStream in=new BlockingInputStream(10); new Thread() { public void run() { byte[] tmp=new byte[20]; int num=0; try { while(true) { int read=in.read(tmp); if(read == -1) break; num+=read; } System.out.println("read " + num + " bytes"); } catch(IOException e) { e.printStackTrace(); } } }.start(); byte[] buffer=new byte[15]; try { in.write(buffer); } finally { Util.close(in); } } protected byte[] generateBuffer(int size) { byte[] buf=new byte[size]; for(int i=0; i < buf.length; i++) buf[i]=(byte)(Util.random(size) % Byte.MAX_VALUE); return buf; } protected static final class Closer extends Thread { protected final CountDownLatch latch; protected final InputStream in; protected final long timeout; public Closer(CountDownLatch latch, InputStream in, long timeout) { this.latch=latch; this.in=in; this.timeout=timeout; } public void run() { try { latch.await(); Util.sleep(timeout); in.close(); } catch(Exception e) { e.printStackTrace(); } } } protected static final class Writer extends Thread { protected final BlockingInputStream in; protected final byte[] buffer; public Writer(BlockingInputStream in, byte[] buffer) { this.in=in; this.buffer=buffer; } public void run() { try { in.write(buffer); } catch(IOException e) { } finally { Util.close(in); } } } }