Package org.hibernate.search.test.query.timeout

Source Code of org.hibernate.search.test.query.timeout.TimeoutTest

/*
* 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.query.timeout;

import java.util.List;
import java.util.concurrent.TimeUnit;

import org.apache.lucene.search.Query;

import org.hibernate.QueryTimeoutException;
import org.hibernate.Transaction;

import org.hibernate.cfg.Configuration;
import org.hibernate.dialect.PostgreSQLDialect;
import org.hibernate.search.FullTextQuery;
import org.hibernate.search.FullTextSession;
import org.hibernate.search.Search;
import org.hibernate.search.query.dsl.QueryBuilder;
import org.hibernate.search.test.SearchTestBase;
import org.hibernate.testing.SkipForDialect;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

/**
* @author Emmanuel Bernard
*/
public class TimeoutTest extends SearchTestBase {

  private FullTextSession fts;
  private Query allSeikoClocksQuery;
  private Query allSwatchClocksQuery;
  private Query noMatchQuery;
  private Query matchAllQuery;

  @Override
  @Before
  public void setUp() throws Exception {
    super.setUp();
    fts = Search.getFullTextSession( openSession() );
    QueryBuilder builder = fts.getSearchFactory().buildQueryBuilder().forEntity( Clock.class ).get();
    allSeikoClocksQuery = builder.keyword().onField( "brand" ).matching( "Seiko" ).createQuery();
    allSwatchClocksQuery = builder.keyword().onField( "brand" ).matching( "Swatch" ).createQuery();
    noMatchQuery = builder.keyword().onField( "brand" ).matching( "Blah" ).createQuery();
    matchAllQuery = builder.all().createQuery();
    storeClocks( fts );
  }

  @Override
  @After
  public void tearDown() throws Exception {
    try {
      Transaction tx = fts.getTransaction();
      if ( !tx.isActive() ) {
        tx = fts.beginTransaction();
      }
      assertEquals( 1000, fts.createQuery( "delete from " + Clock.class.getName() ).executeUpdate() );
      fts.purgeAll( Clock.class );
      tx.commit();
      fts.close();
    }
    finally {
      super.tearDown();
    }
  }

  @Test
  public void testTimeout() {
    Transaction tx = fts.beginTransaction();

    assertCorrectNumberOfClocksNoTimeout();
    assertTimeoutOccursOnList();
    assertTimeoutOccursOnIterate();
    assertTimeoutOccursOnScroll();

    tx.commit();
  }

  @Test
  public void testLimitFetchingTime() {
    Transaction tx = fts.beginTransaction();

    assertCorrectNumberOfClocksNoTimeout();
    assertExecutionTimeoutOccursOnList();
    assertExecutionTimeoutHasNoPartialResult();

    tx.commit();

    //We cannot test intermediate limit, Lucene / hibernate: too unpredictable

//    hibernateQuery = fts.createFullTextQuery( query, Clock.class );
//    hibernateQuery.limitFetchingTime( 1000, TimeUnit.NANOSECONDS );
//    results = hibernateQuery.list();
//    System.out.println("Result size partial: " + results.size() );
//    assertTrue("Regular failure when some elements are fetched", 0 < results.size() && results.size() < 500 );
//    assertTrue( hibernateQuery.hasPartialResults() );
//
//    fts.clear();
  }

  @SkipForDialect(value = PostgreSQLDialect.class,
      jiraKey = "JBPAPP-2945",
      comment = "PostgreSQL driver does not implement query timeout")
  @Test
  public void testEnoughTime() {
    Transaction tx = fts.beginTransaction();

    FullTextQuery hibernateQuery = fts.createFullTextQuery( matchAllQuery, Clock.class );
    hibernateQuery.setTimeout( 5, TimeUnit.MINUTES );
    List results = hibernateQuery.list();
    assertFalse( hibernateQuery.hasPartialResults() );
    assertEquals( 1000, results.size() );

    tx.commit();
  }

  private void assertTimeoutOccursOnScroll() {
    FullTextQuery hibernateQuery = fts.createFullTextQuery( noMatchQuery, Clock.class );
    hibernateQuery.setTimeout( 10, TimeUnit.MICROSECONDS );
    try {
      hibernateQuery.scroll();
      fail( "timeout exception should happen" );
    }
    catch (QueryTimeoutException e) {
      //good
    }
    catch (Exception e) {
      fail( "Expected a QueryTimeoutException" );
    }
    fts.clear();
  }

  private void assertTimeoutOccursOnIterate() {
    FullTextQuery hibernateQuery = fts.createFullTextQuery( allSwatchClocksQuery, Clock.class );
    hibernateQuery.setTimeout( 10, TimeUnit.MICROSECONDS );

    try {
      hibernateQuery.iterate();
      fail( "timeout exception should happen" );
    }
    catch (QueryTimeoutException e) {
      //good
    }
    catch (Exception e) {
      fail( "Expected a QueryTimeoutException" );
    }
    fts.clear();
  }

  private void assertTimeoutOccursOnList() {
    FullTextQuery hibernateQuery = fts.createFullTextQuery( allSeikoClocksQuery, Clock.class );
    hibernateQuery.setTimeout( 10, TimeUnit.MICROSECONDS );
    try {
      hibernateQuery.list();
      fail( "timeout exception should happen" );
    }
    catch (QueryTimeoutException e) {
      //good
    }
    catch (Exception e) {
      fail( "Expected a QueryTimeoutException" );
    }
    fts.clear();
  }

  private void assertCorrectNumberOfClocksNoTimeout() {
    FullTextQuery hibernateQuery = fts.createFullTextQuery( allSeikoClocksQuery, Clock.class );
    final List results = hibernateQuery.list();
    assertEquals( 500, results.size() );
    fts.clear();
  }

  /**
   * Use to add some initial data
   *
   * @param fts the fulltext session
   */
  private static void storeClocks(FullTextSession fts) {
    Transaction tx = fts.beginTransaction();
    for ( long i = 0; i < 1000; i++ ) {
      Clock clock = new Clock(
          Long.valueOf( i ),
          "Model cat A" + i,
          ( i % 2 == 0 ) ? "Seiko" : "Swatch",
          Long.valueOf( i + 2000 )
      );
      fts.persist( clock );
    }
    tx.commit();
    fts.clear();
  }

  private void assertExecutionTimeoutHasNoPartialResult() {
    FullTextQuery hibernateQuery = fts.createFullTextQuery( allSeikoClocksQuery, Clock.class );
    hibernateQuery.limitExecutionTimeTo( 30, TimeUnit.SECONDS );
    List results = hibernateQuery.list();
    assertEquals( "Test below limit termination", 500, results.size() );
    assertFalse( hibernateQuery.hasPartialResults() );
    fts.clear();
  }

  private void assertExecutionTimeoutOccursOnList() {
    FullTextQuery hibernateQuery = fts.createFullTextQuery( allSwatchClocksQuery, Clock.class );
    hibernateQuery.limitExecutionTimeTo( 1, TimeUnit.NANOSECONDS );
    List result = hibernateQuery.list();
    System.out.println( "Result size early: " + result.size() );
    assertEquals( "Test early failure, before the number of results are even fetched", 0, result.size() );
    if ( result.size() == 0 ) {
      //sometimes, this
      assertTrue( hibernateQuery.hasPartialResults() );
    }
    fts.clear();
  }

  @Override
  protected Class<?>[] getAnnotatedClasses() {
    return new Class<?>[] { Clock.class };
  }

  @Override
  protected void configure(Configuration cfg) {
    cfg.setProperty( "hibernate.jdbc.batch_size", "1000" );
    super.configure( cfg );
  }

}
TOP

Related Classes of org.hibernate.search.test.query.timeout.TimeoutTest

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.