TailStreamTest.java
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.tika.io;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import org.junit.jupiter.api.Test;
/**
* Test class for {@code TailStream}.
*/
public class TailStreamTest {
/**
* Constant for generating test text.
*/
private static final String TEXT = "Lorem ipsum dolor sit amet, consetetur " +
"sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut " +
"labore et dolore magna aliquyam erat, sed diam voluptua. At vero" +
" eos et accusam et justo duo dolores et ea rebum. Stet clita " +
"kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor " + "sit amet.";
/**
* Generates a test text using the specified parameters.
*
* @param from the start index of the text
* @param length the length of the text
* @return the generated test text
*/
private static String generateText(int from, int length) {
int count = from + length;
StringBuilder buf = new StringBuilder(count);
while (buf.length() < count) {
buf.append(TEXT);
}
return buf.substring(from, from + length);
}
/**
* Generates a stream which contains a test text.
*
* @param from the start index of the text
* @param length the length of the generated stream
* @return the stream with the test text
*/
private static InputStream generateStream(int from, int length) {
return new ByteArrayInputStream(generateText(from, length).getBytes(UTF_8));
}
/**
* Helper method for reading the content of an input stream.
*
* @param in the stream to be read
* @return an array with the content of the stream
* @throws IOException if an error occurs
*/
private static byte[] readStream(InputStream in) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int c;
while ((c = in.read()) != -1) {
bos.write(c);
}
return bos.toByteArray();
}
/**
* Tests whether the tail buffer can be obtained before data was read.
*/
@Test
public void testTailBeforeRead() throws IOException {
TailStream stream = new TailStream(generateStream(0, 100), 50);
assertEquals(0, stream.getTail().length, "Wrong buffer length");
stream.close();
}
/**
* Tests the content of the tail buffer if it is only partly filled.
*/
@Test
public void testTailBufferPartlyRead() throws IOException {
final int count = 64;
TailStream stream = new TailStream(generateStream(0, count), 2 * count);
byte[] data = readStream(stream);
assertArrayEquals(data, stream.getTail(), "Wrong buffer length");
stream.close();
}
/**
* Tests the content of the tail buffer if only single bytes were read.
*/
@Test
public void testTailSingleByteReads() throws IOException {
final int count = 128;
TailStream stream = new TailStream(generateStream(0, 2 * count), count);
readStream(stream);
assertEquals(generateText(count, count), new String(stream.getTail(), UTF_8),
"Wrong buffer");
}
/**
* Tests the content of the tail buffer if larger chunks are read.
*/
@Test
public void testTailChunkReads() throws IOException {
final int count = 16384;
final int tailSize = 61;
final int bufSize = 100;
TailStream stream = new TailStream(generateStream(0, count), tailSize);
byte[] buf = new byte[bufSize];
int read = stream.read(buf, 10, 8);
assertEquals(8, read, "Wrong number of bytes read");
while (read != -1) {
read = stream.read(buf);
}
assertEquals(generateText(count - tailSize, tailSize),
new String(stream.getTail(), UTF_8), "Wrong buffer");
stream.close();
}
/**
* Tests whether mark() and reset() work as expected.
*/
@Test
public void testReadWithMarkAndReset() throws IOException {
final int tailSize = 64;
TailStream stream = new TailStream(generateStream(0, 2 * tailSize), tailSize);
byte[] buf = new byte[tailSize / 2];
stream.read(buf);
stream.mark(tailSize);
stream.read(buf);
stream.reset();
readStream(stream);
assertEquals(generateText(tailSize, tailSize),
new String(stream.getTail(), UTF_8), "Wrong buffer");
}
/**
* Tests whether a reset() operation without a mark is simply ignored.
*/
@Test
public void testResetWithoutMark() throws IOException {
final int tailSize = 75;
final int count = 128;
TailStream stream = new TailStream(generateStream(0, count), tailSize);
stream.reset();
byte[] buf = new byte[count];
stream.read(buf);
assertEquals(generateText(count - tailSize, tailSize),
new String(stream.getTail(), UTF_8), "Wrong buffer");
stream.close();
}
/**
* Tests whether skip() also fills the tail buffer.
*/
@Test
public void testSkip() throws IOException {
final int tailSize = 128;
final int count = 1024;
final int skipCount = 512;
TailStream stream = new TailStream(generateStream(0, count), tailSize);
assertEquals(skipCount, stream.skip(skipCount), "Wrong skip result");
assertEquals(generateText(skipCount - tailSize, tailSize),
new String(stream.getTail(), UTF_8), "Wrong buffer");
stream.close();
}
/**
* Tests a skip operation at the end of the stream.
*/
@Test
public void testSkipEOS() throws IOException {
final int count = 128;
TailStream stream = new TailStream(generateStream(0, count), 2 * count);
assertEquals(count, stream.skip(2 * count), "Wrong skip result");
assertEquals(generateText(0, count), new String(stream.getTail(), UTF_8),
"Wrong buffer");
stream.close();
}
/**
* Tests skip() if read reaches the end of the stream and returns -1.
*/
@Test
public void testSkipReadEnd() throws IOException {
final int count = 128;
TailStream stream = new TailStream(generateStream(0, count), 2 * count);
readStream(stream);
assertEquals(-1, stream.skip(1), "Wrong result");
}
}