/* * 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.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.Arrays; import org.junit.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("Wrong buffer length", 0, stream.getTail().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); assertTrue("Wrong content", Arrays.equals(data, stream.getTail())); 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("Wrong buffer", generateText(count, count), new String( stream.getTail(), UTF_8)); } /** * 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("Wrong number of bytes read", 8, read); while (read != -1) { read = stream.read(buf); } assertEquals("Wrong buffer", generateText(count - tailSize, tailSize), new String(stream.getTail(), UTF_8)); 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("Wrong buffer", generateText(tailSize, tailSize), new String(stream.getTail(), UTF_8)); } /** * 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("Wrong buffer", generateText(count - tailSize, tailSize), new String(stream.getTail(), UTF_8)); 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("Wrong skip result", skipCount, stream.skip(skipCount)); assertEquals("Wrong buffer", generateText(skipCount - tailSize, tailSize), new String(stream.getTail(), UTF_8)); 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("Wrong skip result", count, stream.skip(2 * count)); assertEquals("Wrong buffer", generateText(0, count), new String(stream.getTail(), UTF_8)); 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("Wrong result", -1, stream.skip(1)); } }