/** * Copyright (c) 2002-2012 "Neo Technology," * Network Engine for Objects in Lund AB [http://neotechnology.com] * * This file is part of Neo4j. * * Neo4j is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.neo4j.consistency.store.windowpool; import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import org.junit.Test; import org.neo4j.kernel.impl.nioneo.store.OperationType; import org.neo4j.consistency.store.paging.PageReplacementStrategy; import org.neo4j.consistency.store.paging.StubPageReplacementStrategy; public class ScanResistantWindowPoolTest { @Test public void shouldMapConsecutiveWindowsWithAppropriateBoundaries() throws Exception { // given int bytesPerRecord = 10; int targetBytesPerPage = 1000; FileMapper fileMapper = mock( FileMapper.class ); ScanResistantWindowPool pool = new ScanResistantWindowPool( "storeFileName", bytesPerRecord, targetBytesPerPage, fileMapper, new StubPageReplacementStrategy(), 100000, mock( MappingStatisticsListener.class ) ); // when pool.acquire( 0, OperationType.READ ); // then verify( fileMapper ).mapWindow( 0, 100, 10 ); // when pool.acquire( 100, OperationType.READ ); // then verify( fileMapper ).mapWindow( 100, 100, 10 ); } @Test public void shouldRejectRecordSizeGreaterThanTargetBytesPerPage() throws Exception { // given int targetBytesPerPage = 4096; int bytesPerRecord = targetBytesPerPage + 1; // when try { new ScanResistantWindowPool( "storeFileName", bytesPerRecord, targetBytesPerPage, mock( FileMapper.class ), mock( PageReplacementStrategy.class ), 100000, mock( MappingStatisticsListener.class ) ); fail( "should have thrown exception" ); } // then catch ( IllegalArgumentException expected ) { // expected } } @Test public void shouldRejectRecordSizeOfZero() throws Exception { // when try { new ScanResistantWindowPool( "storeFileName", 0, 4096, mock( FileMapper.class ), mock( PageReplacementStrategy.class ), 100000, mock( MappingStatisticsListener.class ) ); fail( "should have thrown exception" ); } // then catch ( IllegalArgumentException expected ) { // expected } } @Test public void shouldFailIfFileSizeRequiresMoreThanMaxIntPages() throws Exception { // given int targetBytesPerPage = 1; int bytesPerRecord = 1; FileMapper fileMapper = mock( FileMapper.class ); when( fileMapper.fileSizeInBytes() ).thenReturn( Integer.MAX_VALUE * 2L ); // when try { new ScanResistantWindowPool( "storeFileName", bytesPerRecord, targetBytesPerPage, fileMapper, mock( PageReplacementStrategy.class ), 100000, mock( MappingStatisticsListener.class ) ); fail( "should have thrown exception" ); } // then catch ( IllegalArgumentException expected ) { // expected } } @Test public void shouldRejectWriteOperations() throws Exception { // given int recordSize = 9; int targetBytesPerPage = 4096; ScanResistantWindowPool pool = new ScanResistantWindowPool( "storeFileName", recordSize, targetBytesPerPage, mock( FileMapper.class ), mock( PageReplacementStrategy.class ), 100000, mock( MappingStatisticsListener.class ) ); // when try { pool.acquire( 0, OperationType.WRITE ); fail( "should have thrown exception" ); } // then catch ( UnsupportedOperationException e ) { // expected } } @Test public void closingThePoolShouldCloseAllTheWindows() throws Exception { // given int bytesPerRecord = 10; int targetBytesPerPage = 1000; FileMapper fileMapper = mock( FileMapper.class ); MappedWindow window0 = mock( MappedWindow.class ); when( fileMapper.mapWindow( 0, 100, 10 ) ).thenReturn( window0 ); MappedWindow window1 = mock( MappedWindow.class ); when( fileMapper.mapWindow( 100, 100, 10 ) ).thenReturn( window1 ); ScanResistantWindowPool pool = new ScanResistantWindowPool( "storeFileName", bytesPerRecord, targetBytesPerPage, fileMapper, new StubPageReplacementStrategy(), 100000, mock( MappingStatisticsListener.class ) ); pool.acquire( 0, OperationType.READ ); pool.acquire( 100, OperationType.READ ); // when pool.close(); // then verify( window0 ).close(); verify( window1 ).close(); } }