@Test
public void testSeek() {

	final IOManager ioManager = new IOManagerAsync();
	final int PAGE_SIZE = 16 * 1024;
	final int NUM_RECORDS = 120000;
	// integers across 7.x pages (7 pages = 114.688 bytes, 8 pages = 131.072 bytes)
	
	try {
		MemoryManager memMan = new MemoryManager(4 * PAGE_SIZE, 1, PAGE_SIZE, MemoryType.HEAP, true);
		List<MemorySegment> memory = new ArrayList<MemorySegment>();
		memMan.allocatePages(new DummyInvokable(), memory, 4);
		
		FileIOChannel.ID channel = ioManager.createChannel();
		BlockChannelWriter<MemorySegment> writer = ioManager.createBlockChannelWriter(channel);
		FileChannelOutputView out = new FileChannelOutputView(writer, memMan, memory, memMan.getPageSize());
		
		// write some integers across 7.5 pages (7 pages = 114.688 bytes, 8 pages = 131.072 bytes)
		for (int i = 0; i < NUM_RECORDS; i += 4) {
			out.writeInt(i);
		}
		// close for the first time, make sure all memory returns
		out.close();
		assertTrue(memMan.verifyEmpty());
		
		memMan.allocatePages(new DummyInvokable(), memory, 4);
		SeekableFileChannelInputView in = new SeekableFileChannelInputView(ioManager, channel, memMan, memory, out.getBytesInLatestSegment());
		
		// read first, complete
		for (int i = 0; i < NUM_RECORDS; i += 4) {
			assertEquals(i, in.readInt());
		}
		try {
			in.readInt();
			fail("should throw EOF exception");
		} catch (EOFException ignored) {}
		
		// seek to the middle of the 3rd page
		int i = 2 * PAGE_SIZE + PAGE_SIZE / 4;
		in.seek(i);
		for (; i < NUM_RECORDS; i += 4) {
			assertEquals(i, in.readInt());
		}
		try {
			in.readInt();
			fail("should throw EOF exception");
		} catch (EOFException ignored) {}
		
		// seek to the end
		i = 120000 - 4;
		in.seek(i);
		for (; i < NUM_RECORDS; i += 4) {
			assertEquals(i, in.readInt());
		}
		try {
			in.readInt();
			fail("should throw EOF exception");
		} catch (EOFException ignored) {}
		
		// seek to the beginning
		i = 0;
		in.seek(i);
		for (; i < NUM_RECORDS; i += 4) {
			assertEquals(i, in.readInt());
		}
		try {
			in.readInt();
			fail("should throw EOF exception");
		} catch (EOFException ignored) {}
		
		// seek to after a page
		i = PAGE_SIZE;
		in.seek(i);
		for (; i < NUM_RECORDS; i += 4) {
			assertEquals(i, in.readInt());
		}
		try {
			in.readInt();
			fail("should throw EOF exception");
		} catch (EOFException ignored) {}
		
		// seek to after a page
		i = 3 * PAGE_SIZE;
		in.seek(i);
		for (; i < NUM_RECORDS; i += 4) {
			assertEquals(i, in.readInt());
		}
		try {
			in.readInt();
			fail("should throw EOF exception");
		} catch (EOFException ignored) {}
		
		// seek to the end
		i = NUM_RECORDS;
		in.seek(i);
		try {
			in.readInt();
			fail("should throw EOF exception");
		} catch (EOFException ignored) {}
		
		// seek out of bounds
		try {
			in.seek(-10);
			fail("should throw an exception");
		} catch (IllegalArgumentException ignored) {}
		try {
			in.seek(NUM_RECORDS + 1);
			fail("should throw an exception");
		} catch (IllegalArgumentException ignored) {}
	}
	catch (Exception e) {
		e.printStackTrace();
		fail(e.getMessage());
	}
	finally {
		ioManager.shutdown();
	}
}