View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.io.input.buffer;
18  
19  import static org.junit.jupiter.api.Assertions.assertEquals;
20  import static org.junit.jupiter.api.Assertions.assertTrue;
21  
22  import java.io.ByteArrayInputStream;
23  import java.io.IOException;
24  import java.util.Random;
25  
26  import org.junit.jupiter.api.Test;
27  
28  public class CircularBufferInputStreamTest {
29      private final Random rnd = new Random(1530960934483L); // System.currentTimeMillis(), when this test was written.
30                                                             // Always using the same seed should ensure a reproducible test.
31  
32      /**
33       * Create a large, but random input buffer.
34       */
35      private byte[] newInputBuffer() {
36          final byte[] buffer = new byte[16 * 512 + rnd.nextInt(512)];
37          rnd.nextBytes(buffer);
38          return buffer;
39      }
40  
41      @Test
42      public void testIO683() throws IOException {
43          final byte[] buffer = {0, 1, -2, -2, -1, 4};
44          try (ByteArrayInputStream bais = new ByteArrayInputStream(buffer); final CircularBufferInputStream cbis = new CircularBufferInputStream(bais)) {
45              int b;
46              int i = 0;
47              while ((b = cbis.read()) != -1) {
48                  assertEquals(buffer[i] & 0xFF, b, "byte at index " + i + " should be equal");
49                  i++;
50              }
51              assertEquals(buffer.length, i, "Should have read all the bytes");
52          }
53      }
54  
55      @Test
56      public void testRandomRead() throws Exception {
57          final byte[] inputBuffer = newInputBuffer();
58          final byte[] bufferCopy = new byte[inputBuffer.length];
59          final ByteArrayInputStream bais = new ByteArrayInputStream(inputBuffer);
60          @SuppressWarnings("resource")
61          final CircularBufferInputStream cbis = new CircularBufferInputStream(bais, 253);
62          int offset = 0;
63          final byte[] readBuffer = new byte[256];
64          while (offset < bufferCopy.length) {
65              switch (rnd.nextInt(2)) {
66              case 0: {
67                  final int res = cbis.read();
68                  if (res == -1) {
69                      throw new IllegalStateException("Unexpected EOF at offset " + offset);
70                  }
71                  if (inputBuffer[offset] != (byte) res) { // compare as bytes
72                      throw new IllegalStateException("Expected " + inputBuffer[offset] + " at offset " + offset + ", got " + res);
73                  }
74                  ++offset;
75                  break;
76              }
77              case 1: {
78                  final int res = cbis.read(readBuffer, 0, rnd.nextInt(readBuffer.length + 1));
79                  if (res == -1) {
80                      throw new IllegalStateException("Unexpected EOF at offset " + offset);
81                  }
82                  if (res == 0) {
83                      throw new IllegalStateException("Unexpected zero-byte-result at offset " + offset);
84                  }
85                  for (int i = 0; i < res; i++) {
86                      if (inputBuffer[offset] != readBuffer[i]) {
87                          throw new IllegalStateException("Expected " + inputBuffer[offset] + " at offset " + offset + ", got " + readBuffer[i]);
88                      }
89                      ++offset;
90                  }
91                  break;
92              }
93              default:
94                  throw new IllegalStateException("Unexpected random choice value");
95              }
96          }
97          assertTrue(true, "Test finished OK");
98      }
99  }