package io.lumify.core.util;
import org.junit.Test;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Arrays;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
public class TeeInputStreamTest {
@Test
public void testReads() throws Exception {
byte[] temp = new byte[100];
int readLen;
byte[] data = createMockData(10);
InputStream source = new ByteArrayInputStream(data);
TeeInputStream in = new TeeInputStream(source, 2);
in.loop(); // force a read
in.loop(); // force setting source complete
InputStream[] tees = in.getTees();
assertEquals(0, tees[0].read());
assertEquals(0, tees[1].read());
readLen = tees[0].read(temp, 0, 5);
assertEquals(5, readLen);
assertArrayEquals(Arrays.copyOfRange(data, 1, 6), Arrays.copyOfRange(temp, 0, 5));
readLen = tees[0].read(temp);
assertEquals(4, readLen);
assertArrayEquals(Arrays.copyOfRange(data, 6, 10), Arrays.copyOfRange(temp, 0, 4));
readLen = tees[1].read(temp);
assertEquals(9, readLen);
assertArrayEquals(Arrays.copyOfRange(data, 1, 10), Arrays.copyOfRange(temp, 0, 9));
in.close();
}
@Test
public void testLoopUntilTeesAreClosed() throws Exception {
final byte[] data = createMockData(10);
InputStream source = new ByteArrayInputStream(data);
TeeInputStream in = new TeeInputStream(source, 2) {
int loopCount = 0;
@Override
protected void loop() throws Exception {
byte[] temp = new byte[10];
int read;
super.loop();
switch (loopCount) {
case 0:
read = getTees()[0].read(temp);
assertEquals(10, read);
assertArrayEquals(data, temp);
break;
case 1:
read = getTees()[1].read(temp);
assertEquals(10, read);
assertArrayEquals(data, temp);
break;
case 2:
getTees()[0].close();
break;
case 3:
getTees()[1].close();
break;
}
loopCount++;
}
};
in.loopUntilTeesAreClosed();
}
@Test
public void testReadsWithSmallBufferSize() throws Exception {
byte[] temp = new byte[100];
int readLen;
byte[] data = createMockData(20);
InputStream source = new ByteArrayInputStream(data);
TeeInputStream in = new TeeInputStream(source, 2, 10);
in.loop(); // force a read
in.loop(); // force setting source complete
InputStream[] tees = in.getTees();
assertEquals(10, in.getMaxNonblockingReadLength(0));
assertEquals(10, in.getMaxNonblockingReadLength(1));
assertEquals(0, tees[0].read());
in.loop(); // doesn't move offset since tees[1] hasn't read yet
assertEquals(9, in.getMaxNonblockingReadLength(0));
assertEquals(10, in.getMaxNonblockingReadLength(1));
assertEquals(0, tees[1].read());
assertEquals(9, in.getMaxNonblockingReadLength(0));
assertEquals(9, in.getMaxNonblockingReadLength(1));
in.loop();
assertEquals(10, in.getMaxNonblockingReadLength(0));
assertEquals(10, in.getMaxNonblockingReadLength(1));
readLen = tees[0].read(temp, 0, 10);
assertEquals(10, readLen);
assertArrayEquals(Arrays.copyOfRange(data, 1, 11), Arrays.copyOfRange(temp, 0, 10));
assertEquals(0, in.getMaxNonblockingReadLength(0));
assertEquals(10, in.getMaxNonblockingReadLength(1));
readLen = tees[1].read(temp, 0, 10);
assertEquals(10, readLen);
assertArrayEquals(Arrays.copyOfRange(data, 1, 11), Arrays.copyOfRange(temp, 0, 10));
assertEquals(0, in.getMaxNonblockingReadLength(0));
assertEquals(0, in.getMaxNonblockingReadLength(1));
in.loop();
assertEquals(9, in.getMaxNonblockingReadLength(0));
assertEquals(9, in.getMaxNonblockingReadLength(1));
in.close();
}
@Test
public void testAsyncLoops() throws Exception {
byte[] temp = new byte[100];
int readLen;
byte[] data = createMockData(10);
InputStream source = new ByteArrayInputStream(data);
final TeeInputStream in = new TeeInputStream(source, 2);
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
in.loopUntilTeesAreClosed();
} catch (Exception e) {
System.out.println("Fail");
}
}
});
t.start();
InputStream[] tees = in.getTees();
assertEquals(0, tees[0].read());
Thread.sleep(1);
assertEquals(0, tees[1].read());
Thread.sleep(1);
readLen = tees[0].read(temp, 0, 5);
Thread.sleep(1);
assertEquals(5, readLen);
assertArrayEquals(Arrays.copyOfRange(data, 1, 6), Arrays.copyOfRange(temp, 0, 5));
readLen = tees[0].read(temp);
Thread.sleep(1);
assertEquals(4, readLen);
assertArrayEquals(Arrays.copyOfRange(data, 6, 10), Arrays.copyOfRange(temp, 0, 4));
readLen = tees[1].read(temp);
Thread.sleep(1);
assertEquals(9, readLen);
assertArrayEquals(Arrays.copyOfRange(data, 1, 10), Arrays.copyOfRange(temp, 0, 9));
Thread.sleep(1);
in.close();
}
@Test
public void testCloseBeforeReadAll() throws Exception {
byte[] data = createMockData(4);
InputStream source = new ByteArrayInputStream(data);
TeeInputStream in = new TeeInputStream(source, 2, 2);
in.loop();
InputStream[] tees = in.getTees();
tees[0].close();
in.loop();
assertEquals(0, tees[1].read());
in.loop();
assertEquals(1, tees[1].read());
in.loop();
assertEquals(2, tees[1].read());
in.loop();
assertEquals(3, tees[1].read());
in.loop();
in.close();
}
private byte[] createMockData(int len) {
byte[] data = new byte[len];
for (int i = 0; i < len; i++) {
data[i] = (byte) i;
}
return data;
}
}