### Question:
GBPTree implements Closeable { public static void readHeader( PageCache pageCache, File indexFile, Header.Reader headerReader ) throws IOException, MetadataMismatchException { try ( PagedFile pagedFile = openExistingIndexFile( pageCache, indexFile ) ) { Pair<TreeState,TreeState> states = loadStatePages( pagedFile ); TreeState state = TreeStatePair.selectNewestValidState( states ); try ( PageCursor cursor = pagedFile.io( state.pageId(), PagedFile.PF_SHARED_READ_LOCK ) ) { PageCursorUtil.goTo( cursor, "header data", state.pageId() ); doReadHeader( headerReader, cursor ); } } catch ( Throwable t ) { withMessage( t, t.getMessage() + " | " + format( "GBPTree[file:%s]", indexFile ) ); throw t; } } GBPTree( PageCache pageCache, File indexFile, Layout<KEY,VALUE> layout, int tentativePageSize,
            Monitor monitor, Header.Reader headerReader, Consumer<PageCursor> headerWriter,
            RecoveryCleanupWorkCollector recoveryCleanupWorkCollector, boolean readOnly ); static void readHeader( PageCache pageCache, File indexFile, Header.Reader headerReader ); RawCursor<Hit<KEY,VALUE>,IOException> seek( KEY fromInclusive, KEY toExclusive ); void checkpoint( IOLimiter ioLimiter, Consumer<PageCursor> headerWriter ); void checkpoint( IOLimiter ioLimiter ); @Override void close(); Writer<KEY,VALUE> writer(); Writer<KEY,VALUE> writer( double ratioToKeepInLeftOnSplit ); VISITOR visit( VISITOR visitor ); @SuppressWarnings( "unused" ) void printTree(); void printState(); boolean consistencyCheck(); boolean consistencyCheck( boolean reportCrashPointers ); boolean consistencyCheck( GBPTreeConsistencyCheckVisitor<KEY> visitor ); boolean consistencyCheck( GBPTreeConsistencyCheckVisitor<KEY> visitor, boolean reportCrashPointers ); @VisibleForTesting void unsafe( GBPTreeUnsafe<KEY,VALUE> unsafe ); @Override String toString(); boolean wasDirtyOnStartup(); int keyValueSizeCap(); static final Monitor NO_MONITOR; static final Header.Reader NO_HEADER_READER; static final Consumer<PageCursor> NO_HEADER_WRITER; }### Answer:
@Test public void readHeaderMustThrowIfFileDoesNotExist() throws Exception { File doesNotExist = new File( "Does not exist" ); try { GBPTree.readHeader( createPageCache( DEFAULT_PAGE_SIZE ), doesNotExist, NO_HEADER_READER ); fail( "Should have failed" ); } catch ( NoSuchFileException e ) { } }
@Test public void openWithReadHeaderMustThrowMetadataMismatchExceptionIfFileIsEmpty() throws Exception { openMustThrowMetadataMismatchExceptionIfFileIsEmpty( pageCache -> GBPTree.readHeader( pageCache, indexFile, NO_HEADER_READER ) ); }
@Test public void readHeaderMustThrowMetadataMismatchExceptionIfSomeMetaPageIsMissing() throws Exception { openMustThrowMetadataMismatchExceptionIfSomeMetaPageIsMissing( pageCache -> GBPTree.readHeader( pageCache, indexFile, NO_HEADER_READER ) ); }
@Test public void readHeaderMustThrowIOExceptionIfStatePagesAreAllZeros() throws Exception { openMustThrowMetadataMismatchExceptionIfStatePagesAreAllZeros( pageCache -> GBPTree.readHeader( pageCache, indexFile, NO_HEADER_READER ) ); }
@Test public void readHeaderMustWorkWithOpenIndex() throws Exception { byte[] headerBytes = new byte[12]; ThreadLocalRandom.current().nextBytes( headerBytes ); Consumer<PageCursor> headerWriter = pc -> pc.putBytes( headerBytes ); PageCache pageCache = createPageCache( DEFAULT_PAGE_SIZE ); try ( GBPTree<MutableLong,MutableLong> ignore = index( pageCache ).with( headerWriter ).build() ) { byte[] readHeader = new byte[headerBytes.length]; AtomicInteger length = new AtomicInteger(); Header.Reader headerReader = headerData -> { length.set( headerData.limit() ); headerData.get( readHeader ); }; GBPTree.readHeader( pageCache, indexFile, headerReader ); assertEquals( headerBytes.length, length.get() ); assertArrayEquals( headerBytes, readHeader); } }