Example #1
0
 /**
  * Reads data starting from {@code offsetToStartRead} of {@code segment} and matches it with
  * {@code original}.
  *
  * @param segment the {@link LogSegment} to read from.
  * @param offsetToStartRead the offset in {@code segment} to start reading from.
  * @param original the byte array to compare against.
  * @throws IOException
  */
 private void readAndEnsureMatch(LogSegment segment, long offsetToStartRead, byte[] original)
     throws IOException {
   ByteBuffer readBuf = ByteBuffer.wrap(new byte[original.length]);
   segment.readInto(readBuf, offsetToStartRead);
   assertArrayEquals("Data read does not match data written", original, readBuf.array());
 }
Example #2
0
  /**
   * Tests {@link LogSegment#readInto(ByteBuffer, long)} for various cases.
   *
   * @throws IOException
   */
  @Test
  public void readTest() throws IOException {
    Random random = new Random();
    String segmentName = "log_current";
    LogSegment segment = getSegment(segmentName, STANDARD_SEGMENT_SIZE, true);
    try {
      long writeStartOffset = segment.getStartOffset();
      byte[] data = appendRandomData(segment, 2 * STANDARD_SEGMENT_SIZE / 3);
      readAndEnsureMatch(segment, writeStartOffset, data);
      int readCount = 10;
      for (int i = 0; i < readCount; i++) {
        int position = random.nextInt(data.length);
        int size = random.nextInt(data.length - position);
        readAndEnsureMatch(
            segment,
            writeStartOffset + position,
            Arrays.copyOfRange(data, position, position + size));
      }

      // error scenarios
      ByteBuffer readBuf = ByteBuffer.wrap(new byte[data.length]);
      // data cannot be read at invalid offsets.
      long[] invalidOffsets = {
        writeStartOffset - 1, segment.getEndOffset(), segment.getEndOffset() + 1
      };
      ByteBuffer buffer = ByteBuffer.wrap(TestUtils.getRandomBytes(1));
      for (long invalidOffset : invalidOffsets) {
        try {
          segment.readInto(readBuf, invalidOffset);
          fail("Should have failed to read because position provided is invalid");
        } catch (IndexOutOfBoundsException e) {
          assertEquals("Position of buffer has changed", 0, buffer.position());
        }
      }

      // position + buffer.remaining() > endOffset.
      long readOverFlowCount = metrics.overflowReadError.getCount();
      try {
        segment.readInto(readBuf, writeStartOffset + 1);
        fail("Should have failed to read because position + buffer.remaining() > endOffset");
      } catch (IndexOutOfBoundsException e) {
        assertEquals(
            "Read overflow should have been reported",
            readOverFlowCount + 1,
            metrics.overflowReadError.getCount());
        assertEquals("Position of buffer has changed", 0, readBuf.position());
      }

      segment.close();
      // read after close
      buffer = ByteBuffer.allocate(1);
      try {
        segment.readInto(buffer, writeStartOffset);
        fail("Should have failed to read because segment is closed");
      } catch (ClosedChannelException e) {
        assertEquals("Position of buffer has changed", 0, buffer.position());
      }
    } finally {
      closeSegmentAndDeleteFile(segment);
    }
  }