Package org.hibernate.search.test.fileleaks

Source Code of org.hibernate.search.test.fileleaks.AllFilesClosedTest$Book

/*
* Hibernate Search, full-text search for your domain model
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.search.test.fileleaks;

import java.io.Serializable;
import java.util.Arrays;

import org.junit.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.testsupport.setup.SearchConfigurationForTest;
import org.hibernate.search.testsupport.setup.TransactionContextForTest;
import org.hibernate.search.testsupport.leakdetection.FileMonitoringDirectory;
import org.hibernate.search.testsupport.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 );
      if ( nrtNotEnabled() ) {
        assertAllFilesClosed( directoryTwo );
      }
      // directoryOne is using resource pooling
    }
    finally {
      searchFactory.close();
    }
    assertAllFilesClosed( directoryOne );
    assertAllFilesClosed( directoryTwo );
    assertDirectoryClosed( directoryOne );
    assertDirectoryClosed( directoryTwo );
  }

  /**
   * Override point for extending test
   */
  protected boolean nrtNotEnabled() {
    return true;
  }

  /**
   * Verifies all files in the Directory were closed
   */
  private void assertAllFilesClosed(FileMonitoringDirectory directory) {
    Assert.assertTrue( "not all files were closed", 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.getIndexManagerHolder().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 );
    TransactionContextForTest tc = new TransactionContextForTest();
    searchFactory.getWorker().performWork( work, tc );
    tc.end();
  }

  protected SearchFactoryImplementor initializeSearchFactory() {
    SearchConfigurationForTest cfg = new SearchConfigurationForTest()
      .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 )
      ;
    overrideProperties( cfg ); //allow extending tests with different configuration
    return new SearchFactoryBuilder()
      .configuration( cfg )
      .buildSearchFactory();
  }

  protected void overrideProperties(SearchConfigurationForTest cfg) {
    //nothing to do
  }

  /** 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;
  }

}
TOP

Related Classes of org.hibernate.search.test.fileleaks.AllFilesClosedTest$Book

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.