Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
HSEARCH-1090 Testcase for unclosed files
- Loading branch information
Showing
4 changed files
with
481 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
182 changes: 182 additions & 0 deletions
182
...e-search-engine/src/test/java/org/hibernate/search/test/fileleaks/AllFilesClosedTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
/* | ||
* Hibernate, Relational Persistence for Idiomatic Java | ||
* | ||
* JBoss, Home of Professional Open Source | ||
* Copyright 2012 Red Hat Inc. and/or its affiliates and other contributors | ||
* as indicated by the @authors tag. All rights reserved. | ||
* See the copyright.txt in the distribution for a | ||
* full listing of individual contributors. | ||
* | ||
* This copyrighted material is made available to anyone wishing to use, | ||
* modify, copy, or redistribute it subject to the terms and conditions | ||
* of the GNU Lesser General Public License, v. 2.1. | ||
* This program is distributed in the hope that it will be useful, but WITHOUT A | ||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A | ||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. | ||
* You should have received a copy of the GNU Lesser General Public License, | ||
* v.2.1 along with this distribution; if not, write to the Free Software | ||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
* MA 02110-1301, USA. | ||
*/ | ||
package org.hibernate.search.test.fileleaks; | ||
|
||
import java.io.Serializable; | ||
import java.util.Arrays; | ||
|
||
import junit.framework.Assert; | ||
|
||
import org.apache.lucene.search.MatchAllDocsQuery; | ||
import org.hibernate.search.annotations.DocumentId; | ||
import org.hibernate.search.annotations.Field; | ||
import org.hibernate.search.annotations.Indexed; | ||
import org.hibernate.search.backend.spi.Work; | ||
import org.hibernate.search.backend.spi.WorkType; | ||
import org.hibernate.search.engine.spi.SearchFactoryImplementor; | ||
import org.hibernate.search.indexes.impl.DirectoryBasedIndexManager; | ||
import org.hibernate.search.query.engine.spi.HSQuery; | ||
import org.hibernate.search.spi.SearchFactoryBuilder; | ||
import org.hibernate.search.test.util.ManualConfiguration; | ||
import org.hibernate.search.test.util.ManualTransactionContext; | ||
import org.hibernate.search.test.util.leakdetection.FileMonitoringDirectory; | ||
import org.hibernate.search.test.util.leakdetection.FileMonitoringDirectoryProvider; | ||
import org.junit.Test; | ||
|
||
/** | ||
* Test for HSEARCH-1090: IndexReader leaks file handles on close | ||
* | ||
* @author Sanne Grinovero <sanne@hibernate.org> (C) 2012 Red Hat Inc. | ||
*/ | ||
public class AllFilesClosedTest { | ||
|
||
private SearchFactoryImplementor searchFactory; | ||
|
||
@Test | ||
public void testFileHandlesReleased() { | ||
//We initialize the SearchFactory in the test itself as we want to test it's state *after* shutdown | ||
searchFactory = initializeSearchFactory(); | ||
//extract the directories now, as they won't be available after SearchFactory#close : | ||
FileMonitoringDirectory directoryOne = getDirectory( "index1" ); | ||
FileMonitoringDirectory directoryTwo = getDirectory( "index2" ); | ||
try { | ||
doSomeOperations(); | ||
assertDirectoryOpen( directoryOne ); | ||
assertDirectoryOpen( directoryTwo ); | ||
assertAllFilesClosed( directoryTwo ); | ||
// directoryOne is using resource pooling | ||
} | ||
finally { | ||
searchFactory.close(); | ||
} | ||
assertAllFilesClosed( directoryOne ); | ||
assertAllFilesClosed( directoryTwo ); | ||
assertDirectoryClosed( directoryOne ); | ||
assertDirectoryClosed( directoryTwo ); | ||
} | ||
|
||
/** | ||
* Verifies all files in the Directory were closed | ||
*/ | ||
private void assertAllFilesClosed(FileMonitoringDirectory directory) { | ||
Assert.assertTrue( directory.allFilesWereClosed() ); | ||
} | ||
|
||
/** | ||
* Verifies the directory is closed | ||
*/ | ||
private void assertDirectoryClosed(FileMonitoringDirectory directory) { | ||
Assert.assertTrue( directory.isClosed() ); | ||
} | ||
|
||
/** | ||
* Verifies the directory is open | ||
*/ | ||
private void assertDirectoryOpen(FileMonitoringDirectory directory) { | ||
Assert.assertFalse( directory.isClosed() ); | ||
} | ||
|
||
private FileMonitoringDirectory getDirectory(String indexName) { | ||
DirectoryBasedIndexManager indexManager = (DirectoryBasedIndexManager) searchFactory.getAllIndexesManager().getIndexManager( indexName ); | ||
FileMonitoringDirectoryProvider directoryProvider = (FileMonitoringDirectoryProvider) indexManager.getDirectoryProvider(); | ||
FileMonitoringDirectory directory = (FileMonitoringDirectory) directoryProvider.getDirectory(); | ||
return directory; | ||
} | ||
|
||
/** | ||
* The reported bugs were related to multithreaded operations, but | ||
* we can actually trigger it with a sequence of read/writes: we need to re-open | ||
* a dirty index to run some query on it. | ||
*/ | ||
private void doSomeOperations() { | ||
assertElementsInIndex( 0 ); | ||
storeDvd( 1, "Aliens" ); | ||
storeDvd( 2, "Predators" ); | ||
storeBook( 1, "Hibernate Search, second edition" ); | ||
assertElementsInIndex( 3 ); | ||
storeDvd( 2, "Prometheus" ); // This is an update | ||
storeBook( 2, "Prometheus and the Eagle" ); | ||
assertElementsInIndex( 4 ); | ||
} | ||
|
||
/** | ||
* Run the actual query. Assert sizes to verify everything else is working. | ||
* @param expected number of elements found in the index | ||
*/ | ||
private void assertElementsInIndex(int expected) { | ||
HSQuery hsQuery = searchFactory.createHSQuery(); | ||
hsQuery | ||
.luceneQuery( new MatchAllDocsQuery() ) | ||
.targetedEntities( Arrays.asList( new Class<?>[]{ Book.class, Dvd.class } ) ); | ||
int resultSize = hsQuery.queryResultSize(); | ||
Assert.assertEquals( expected, resultSize ); | ||
} | ||
|
||
private void storeBook(int id, String string) { | ||
Book book = new Book(); | ||
book.id = id; | ||
book.title = string; | ||
storeObject( book, id ); | ||
} | ||
|
||
private void storeDvd(int id, String dvdTitle) { | ||
Dvd dvd1 = new Dvd(); | ||
dvd1.id = id; | ||
dvd1.title = dvdTitle; | ||
storeObject( dvd1, id ); | ||
} | ||
|
||
private void storeObject(Object entity, Serializable id) { | ||
Work work = new Work( entity, id, WorkType.UPDATE, false ); | ||
ManualTransactionContext tc = new ManualTransactionContext(); | ||
searchFactory.getWorker().performWork( work, tc ); | ||
tc.end(); | ||
} | ||
|
||
private SearchFactoryImplementor initializeSearchFactory() { | ||
ManualConfiguration cfg = new ManualConfiguration() | ||
.addProperty( "hibernate.search.default.directory_provider", FileMonitoringDirectoryProvider.class.getName() ) | ||
.addProperty( "hibernate.search.default.reader.strategy", "shared" ) | ||
.addProperty( "hibernate.search.index2.reader.strategy", "not-shared" ) //close all readers closed aggressively | ||
.addProperty( "hibernate.search.index2.exclusive_index_use", "false" ) //close all writers closed aggressively | ||
.addClass( Book.class ) | ||
.addClass( Dvd.class ) | ||
; | ||
return new SearchFactoryBuilder() | ||
.configuration( cfg ) | ||
.buildSearchFactory(); | ||
} | ||
|
||
/** Two mapped entities on two differently configured indexes **/ | ||
|
||
@Indexed(index="index1") | ||
public static final class Dvd { | ||
@DocumentId long id; | ||
@Field String title; | ||
} | ||
|
||
@Indexed(index="index2") | ||
public static final class Book { | ||
@DocumentId long id; | ||
@Field String title; | ||
} | ||
|
||
} |
Oops, something went wrong.