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

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

/*
* 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.Map;
import java.util.concurrent.TimeUnit;
import javax.persistence.QueryTimeoutException;

import org.apache.lucene.search.Query;
import org.jboss.byteman.contrib.bmunit.BMRule;
import org.jboss.byteman.contrib.bmunit.BMUnitRunner;
import org.junit.Test;
import org.junit.runner.RunWith;

import org.hibernate.search.jpa.FullTextEntityManager;
import org.hibernate.search.jpa.FullTextQuery;
import org.hibernate.search.jpa.Search;
import org.hibernate.search.query.dsl.QueryBuilder;
import org.hibernate.search.test.jpa.JPATestCase;

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

/**
* @author Emmanuel Bernard
*/
@RunWith(BMUnitRunner.class)
public class JPATimeoutTest extends JPATestCase {

  @Test
  @BMRule(targetClass = "QueryHits",
    targetMethod = "updateTopDocs",
    helper = "org.hibernate.search.testsupport.BytemanHelper",
    action = "sleepASecond();",
    name = "Enable QueryHits slow down")
  public void testQueryTimeoutException() throws Exception {
    FullTextEntityManager em = Search.getFullTextEntityManager( factory.createEntityManager() );
    em.getTransaction().begin();
    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( 2000 + i ) );
      em.persist( clock );
    }
    em.getTransaction().commit();

    em.clear();

    em.getTransaction().begin();
    final QueryBuilder builder = em.getSearchFactory().buildQueryBuilder().forEntity( Clock.class ).get();
    Query query = builder.keyword().onField( "brand" ).matching( "Seiko" ).createQuery();
    FullTextQuery hibernateQuery = em.createFullTextQuery( query, Clock.class );

    hibernateQuery.setHint( "javax.persistence.query.timeout", 100 ); //not too low or we can't reproduce it consistently
    try {
      hibernateQuery.getResultSize();
      fail( "timeout exception should happen" );
    }
    catch (QueryTimeoutException e) {
      //good
      e.printStackTrace();
    }
    catch (Exception e) {
      fail( "Expected a QueryTimeoutException" );
    }
    em.getTransaction().commit();
    em.clear();

    em.getTransaction().begin();
    assertEquals( 1000, em.createQuery( "delete from " + Clock.class.getName() ).executeUpdate() );
    em.getTransaction().commit();

    em.close();

  }

  @Test
  public void testLimitFetchingTime() {
    FullTextEntityManager em = Search.getFullTextEntityManager( factory.createEntityManager() );
    em.getTransaction().begin();
    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( 2000 + i ) );
      em.persist( clock );
    }
    em.getTransaction().commit();

    em.clear();

    em.getTransaction().begin();
    final QueryBuilder builder = em.getSearchFactory().buildQueryBuilder().forEntity( Clock.class ).get();
    Query query = builder.keyword().onField( "brand" ).matching( "Seiko" ).createQuery();
    FullTextQuery hibernateQuery = em.createFullTextQuery( query, Clock.class );
    List results = hibernateQuery.getResultList();
    assertEquals( 500, results.size() );

    em.clear();

    query = builder.keyword().onField( "brand" ).matching( "Swatch" ).createQuery();
    hibernateQuery = em.createFullTextQuery( query, Clock.class );
    hibernateQuery.limitExecutionTimeTo( 1, TimeUnit.NANOSECONDS );
    List result = hibernateQuery.getResultList();
    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() );
    }

    em.clear();

    //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();

    hibernateQuery = em.createFullTextQuery( query, Clock.class );
    hibernateQuery.limitExecutionTimeTo( 30, TimeUnit.SECONDS );
    results = hibernateQuery.getResultList();
    assertEquals( "Test below limit termination", 500, results.size() );
    assertFalse( hibernateQuery.hasPartialResults() );

    em.getTransaction().commit();

    em.clear();

    em.getTransaction().begin();
    assertEquals( 1000, em.createQuery( "delete from " + Clock.class.getName() ).executeUpdate() );
    em.getTransaction().commit();

    em.close();
  }

  @Override
  public Class[] getAnnotatedClasses() {
    return new Class[] { Clock.class };
  }

  @Override
  protected void configure(Map cfg) {
    cfg.put( "hibernate.jdbc.batch_size", "1000" );
    super.configure( cfg );
  }
}
TOP

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

TOP
Copyright © 2015 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.