private void testOn(Directory dir, int writeSize, int readSize, Cache cache) throws IOException {
   if (cache != null)
     cache
         .clear(); // needed to make sure no chunks are left over in case of Infinispan
                   // implementation
   final String filename = "chunkTest";
   IndexOutput indexOutput = dir.createOutput(filename);
   byte[] toWrite = fillBytes(writeSize);
   indexOutput.writeBytes(toWrite, writeSize);
   indexOutput.close();
   if (cache != null) {
     AssertJUnit.assertEquals(
         writeSize,
         DirectoryIntegrityCheck.deepCountFileSize(new FileCacheKey(INDEXNAME, filename), cache));
   }
   AssertJUnit.assertEquals(writeSize, indexOutput.length());
   byte[] results = new byte[readSize];
   IndexInput openInput = dir.openInput(filename);
   try {
     openInput.readBytes(results, 0, readSize);
     for (int i = 0; i < writeSize && i < readSize; i++) {
       AssertJUnit.assertEquals(results[i], toWrite[i]);
     }
     if (readSize > writeSize)
       AssertJUnit.fail("should have thrown an IOException for reading past EOF");
   } catch (IOException ioe) {
     if (readSize <= writeSize)
       AssertJUnit.fail("should not have thrown an IOException" + ioe.getMessage());
   }
 }
  @Test
  public void testWriteUsingSeekMethod() throws IOException {
    final int BUFFER_SIZE = 64;

    Cache cache = cacheManager.getCache();
    Directory dir =
        DirectoryBuilder.newDirectoryInstance(cache, cache, cache, INDEXNAME)
            .chunkSize(BUFFER_SIZE)
            .create();

    String fileName = "SomeText.txt";
    IndexOutput io = dir.createOutput(fileName);
    RepeatableLongByteSequence bytesGenerator = new RepeatableLongByteSequence();
    // It writes repeatable text
    final int REPEATABLE_BUFFER_SIZE = 1501;
    for (int i = 0; i < REPEATABLE_BUFFER_SIZE; i++) {
      io.writeByte(bytesGenerator.nextByte());
    }
    io.flush();
    assert io.length() == REPEATABLE_BUFFER_SIZE;

    // Text to write on file with repeatable text
    final String someText = "This is some text";
    final byte[] someTextAsBytes = someText.getBytes();
    // 4 points in random order where writing someText: at begin of file, at end of file, within a
    // single chunk,
    // between 2 chunks
    final int[] pointers = {0, 635, REPEATABLE_BUFFER_SIZE, 135};
    for (int i = 0; i < pointers.length; i++) {
      io.seek(pointers[i]);
      io.writeBytes(someTextAsBytes, someTextAsBytes.length);
    }

    io.close();
    bytesGenerator.reset();
    final long finalSize = REPEATABLE_BUFFER_SIZE + someTextAsBytes.length;
    assert io.length() == finalSize;
    assert io.length()
        == DirectoryIntegrityCheck.deepCountFileSize(new FileCacheKey(INDEXNAME, fileName), cache);

    int indexPointer = 0;
    Arrays.sort(pointers);
    byte[] buffer = null;
    int chunkIndex = -1;
    // now testing the stream is equal to the produced repeatable but including the edits at pointed
    // positions
    for (int i = 0; i < REPEATABLE_BUFFER_SIZE + someTextAsBytes.length; i++) {
      if (i % BUFFER_SIZE == 0) {
        buffer =
            (byte[]) cache.get(new ChunkCacheKey(INDEXNAME, fileName, ++chunkIndex, BUFFER_SIZE));
      }

      byte predictableByte = bytesGenerator.nextByte();
      if (i < pointers[indexPointer]) {
        // Assert predictable text
        AssertJUnit.assertEquals(predictableByte, buffer[i % BUFFER_SIZE]);
      } else if (pointers[indexPointer] <= i
          && i < pointers[indexPointer] + someTextAsBytes.length) {
        // Assert someText
        AssertJUnit.assertEquals(
            someTextAsBytes[i - pointers[indexPointer]], buffer[i % BUFFER_SIZE]);
      }

      if (i == pointers[indexPointer] + someTextAsBytes.length) {
        // Change pointer
        indexPointer++;
      }
    }

    dir.close();
    DirectoryIntegrityCheck.verifyDirectoryStructure(cache, INDEXNAME);
  }