package org.infinispan.all.embeddedquery;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.NoSuchElementException;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.PrefixFilter;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.TermQuery;
import org.hibernate.search.filter.FullTextFilter;
import org.infinispan.all.embeddedquery.testdomain.Person;
import org.infinispan.all.embeddedquery.testdomain.StaticTestingErrorHandler;
import org.infinispan.query.CacheQuery;
import org.infinispan.query.FetchOptions;
import org.infinispan.query.ResultIterator;
import org.infinispan.query.Search;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* Clone of LocalCacheTest for uber-jars.
*
* @author Jiri Holusa (jholusa@redhat.com)
*/
public class LocalCacheTest extends AbstractQueryTest {
private Person person1;
private Person person2;
private Person person3;
private Person person4;
private String key1 = "Navin";
private String key2 = "BigGoat";
private String key3 = "MiniGoat";
@Before
public void init() throws Exception {
cache = createCacheManager().getCache();
}
@After
public void after() {
cache.clear();
}
@Test
public void testSimple() {
loadTestingData();
CacheQuery<?> cacheQuery = createCacheQuery(cache, "blurb", "playing" );
List<?> found = cacheQuery.list();
assertPeopleInList(found, person1);
StaticTestingErrorHandler.assertAllGood(cache);
}
@Test
public void testSimpleForNonField() {
loadTestingData();
CacheQuery<?> cacheQuery = createCacheQuery(cache, "nonSearchableField", "test1");
List<?> found = cacheQuery.list();
int elems = found.size();
assertEquals("Expected 0 but was " + elems, 0, elems);
StaticTestingErrorHandler.assertAllGood(cache);
}
@Test
public void testEagerIterator() {
loadTestingData();
CacheQuery<?> cacheQuery = createCacheQuery(cache, "blurb", "playing" );
ResultIterator<?> found = cacheQuery.iterator(new FetchOptions().fetchMode(FetchOptions.FetchMode.EAGER));
try {
assertTrue(found.hasNext());
found.next();
assertTrue(!found.hasNext());
} finally {
found.close();
}
StaticTestingErrorHandler.assertAllGood(cache);
}
@Test(expected = UnsupportedOperationException.class)
public void testEagerIteratorRemove() {
loadTestingData();
CacheQuery<?> cacheQuery = createCacheQuery(cache, "blurb", "playing" );
ResultIterator<?> found = cacheQuery.iterator(new FetchOptions().fetchMode(FetchOptions.FetchMode.EAGER));
try {
assertTrue(found.hasNext());
found.remove();
} finally {
found.close();
}
}
@Test(expected = NoSuchElementException.class)
public void testEagerIteratorExCase() {
loadTestingData();
CacheQuery<?> cacheQuery = createCacheQuery(cache, "blurb", "playing" );
ResultIterator<?> found = cacheQuery.iterator(new FetchOptions().fetchMode(FetchOptions.FetchMode.EAGER));
try {
assertTrue(found.hasNext());
found.next();
assertTrue(!found.hasNext());
found.next();
} finally {
found.close();
}
}
@Test
public void testModified() {
loadTestingData();
CacheQuery<?> cacheQuery = createCacheQuery(cache, "blurb", "playing");
List<?> found = cacheQuery.list();
assertPeopleInList(found, person1);
person1.setBlurb("Likes pizza");
cache.put(key1, person1);
cacheQuery = createCacheQuery(cache, "blurb", "pizza");
found = cacheQuery.list();
assertPeopleInList(found, person1);
StaticTestingErrorHandler.assertAllGood(cache);
}
@Test
public void testAdded() {
loadTestingData();
CacheQuery<?> cacheQuery = createCacheQuery(cache, "name", "Goat");
List<?> found = cacheQuery.list();
assertPeopleInList(found, person2, person3);
person4 = new Person();
person4.setName("Mighty Goat");
person4.setBlurb("Also eats grass");
cache.put("mighty", person4);
cacheQuery = createCacheQuery(cache, "name", "Goat");
found = cacheQuery.list();
assertPeopleInList(found, person2, person3, person4);
StaticTestingErrorHandler.assertAllGood(cache);
}
@Test
public void testRemoved() {
loadTestingData();
CacheQuery<?> cacheQuery = createCacheQuery(cache, "name", "Goat");
List<?> found = cacheQuery.list();
assertPeopleInList(found, person2, person3);
cache.remove(key3);
cacheQuery = createCacheQuery(cache, "name", "Goat");
found = cacheQuery.list();
assertPeopleInList(found, person2);
StaticTestingErrorHandler.assertAllGood(cache);
}
@Test
public void testUpdated() {
loadTestingData();
CacheQuery<?> cacheQuery = createCacheQuery(cache, "name", "Goat");
List<?> found = cacheQuery.list();
assertPeopleInList(found, person2, person3);
cache.put(key2, person1);
cacheQuery = createCacheQuery(cache, "name", "Goat");
found = cacheQuery.list();
assertPeopleInList(found, person3);
StaticTestingErrorHandler.assertAllGood(cache);
}
@Test
public void testSetSort() {
loadTestingData();
Sort sort = new Sort( new SortField("age", SortField.Type.STRING));
{
CacheQuery<?> cacheQuery = createCacheQuery(cache, "name", "Goat");
List<?> found = cacheQuery.list();
assertPeopleInList(found, person2, person3);
cacheQuery.sort( sort );
found = cacheQuery.list();
// person3 is 25 and named Goat
// person2 is 30 and named Goat
assertPeopleInSortedList(found, person3, person2);
}
StaticTestingErrorHandler.assertAllGood(cache);
//Now change the stored values:
person2.setAge(10);
cache.put(key2, person2);
{
CacheQuery<?> cacheQuery = createCacheQuery(cache, "name", "Goat");
List<?> found = cacheQuery.list();
assertPeopleInList(found, person2, person3);
cacheQuery.sort( sort );
found = cacheQuery.list();
// person2 is 30 and named Goat
// person3 is 25 and named Goat
assertPeopleInSortedList(found, person2, person3);
}
StaticTestingErrorHandler.assertAllGood(cache);
}
@Test
public void testSetFilter() {
loadTestingData();
CacheQuery<?> cacheQuery = createCacheQuery(cache, "name", "Goat");
List<?> found = cacheQuery.list();
assertPeopleInList(found, person2, person3);
Filter filter = new PrefixFilter(new Term("blurb", "cheese"));
cacheQuery.filter(filter);
found = cacheQuery.list();
assertPeopleInList(found, person3);
StaticTestingErrorHandler.assertAllGood(cache);
}
@Test
public void testLazyIterator() {
loadTestingData();
CacheQuery<?> cacheQuery = createCacheQuery(cache, "blurb", "playing");
ResultIterator<?> found = cacheQuery.iterator(new FetchOptions().fetchMode(FetchOptions.FetchMode.LAZY));
try {
assertTrue(found.hasNext());
found.next();
assertTrue(!found.hasNext());
} finally {
found.close();
}
StaticTestingErrorHandler.assertAllGood(cache);
}
@Test(expected = IllegalArgumentException.class)
public void testUnknownFetchModeIterator() {
loadTestingData();
CacheQuery<?> cacheQuery = createCacheQuery(cache, "blurb", "playing");
ResultIterator<?> found = cacheQuery.iterator(new FetchOptions(){
public FetchOptions fetchMode(FetchMode fetchMode) {
return null;
}
});
try {
assertTrue(found.hasNext());
found.next();
assertTrue(!found.hasNext());
} finally {
found.close();
}
}
@Test
public void testIteratorWithDefaultOptions() {
loadTestingData();
CacheQuery<?> cacheQuery = createCacheQuery(cache, "blurb", "playing");
ResultIterator<?> found = cacheQuery.iterator();
try {
assertTrue(found.hasNext());
found.next();
assertTrue(!found.hasNext());
} finally {
found.close();
}
StaticTestingErrorHandler.assertAllGood(cache);
}
@Test
public void testExplain() {
loadTestingData();
CacheQuery<?> cacheQuery = createCacheQuery(cache, "blurb", "Eats");
int matchCounter = 0;
int i = 0;
//The implementation is changed to this way as in case of NRT index manager the number of created documents may
//differ comparing to the simple configuration.
// Note: we cannot get rid of this dirty loop since there is no way how to get all the
// explanations.
while (true) {
try {
Explanation found = cacheQuery.explain(i);
if (found.isMatch())
matchCounter++;
i++;
if (i >= 10 || matchCounter == 2)
break;
} catch(ArrayIndexOutOfBoundsException ex) {
break;
}
}
assertEquals(2, matchCounter);
StaticTestingErrorHandler.assertAllGood(cache);
}
@Test
public void testFullTextFilterOnOff() {
loadTestingData();
CacheQuery<?> query = createCacheQuery(cache, "blurb", "Eats");
FullTextFilter filter = query.enableFullTextFilter("personFilter");
filter.setParameter("blurbText", "cheese");
List<?> found = query.list();
assertPeopleInList(found, person3);
//Disabling the fullTextFilter.
query.disableFullTextFilter("personFilter");
found = query.list();
assertPeopleInList(found, person2, person3);
StaticTestingErrorHandler.assertAllGood(cache);
}
@Test(expected = UnsupportedOperationException.class)
public void testIteratorRemove() {
loadTestingData();
CacheQuery<?> cacheQuery = createCacheQuery(cache, "blurb", "Eats");
ResultIterator<?> iterator = cacheQuery.iterator();
try {
if (iterator.hasNext()) {
iterator.next();
iterator.remove();
}
} finally {
iterator.close();
}
StaticTestingErrorHandler.assertAllGood(cache);
}
@Test(expected = IllegalArgumentException.class)
public void testSearchManagerWithNullCache() {
loadTestingData();
Query luceneQuery = new BooleanQuery();
CacheQuery<?> cacheQuery = Search.getSearchManager(null).getQuery(luceneQuery).firstResult(1);
}
@Test(expected = IllegalArgumentException.class)
public void testLazyIteratorWithInvalidFetchSize() {
loadTestingData();
CacheQuery<?> cacheQuery = createCacheQuery(cache, "blurb", "Eats").firstResult(1);
ResultIterator<?> found = cacheQuery.iterator(new FetchOptions().fetchMode(FetchOptions.FetchMode.LAZY).fetchSize(0));
}
@Test(expected = NoSuchElementException.class)
public void testLazyIteratorWithNoElementsFound() {
loadTestingData();
CacheQuery<?> cacheQuery = createCacheQuery(cache, "blurb", "fish").firstResult(1);
ResultIterator<?> found = cacheQuery.iterator(new FetchOptions().fetchMode(FetchOptions.FetchMode.LAZY));
try {
found.next();
} finally {
found.close();
}
}
@Test(expected = IllegalArgumentException.class)
public void testIteratorWithNullFetchMode() {
loadTestingData();
CacheQuery<?> cacheQuery = createCacheQuery(cache, "blurb", "Eats").firstResult(1);
ResultIterator<?> found = cacheQuery.iterator(new FetchOptions().fetchMode(null));
try {
found.next();
} finally {
found.close();
}
}
@Test
public void testGetResultSize() {
loadTestingData();
CacheQuery<?> cacheQuery = createCacheQuery(cache, "blurb", "playing");
assertEquals(1, cacheQuery.getResultSize());
StaticTestingErrorHandler.assertAllGood(cache);
}
@Test
public void testMaxResults() {
loadTestingData();
CacheQuery<?> cacheQuery = createCacheQuery(cache, "blurb", "eats").maxResults(1);
assertEquals(2, cacheQuery.getResultSize()); // NOTE: getResultSize() ignores pagination (maxResults, firstResult)
assertEquals(1, cacheQuery.list().size());
ResultIterator<?> eagerIterator = cacheQuery.iterator(new FetchOptions().fetchMode(FetchOptions.FetchMode.EAGER));
try {
assertEquals(1, countElements(eagerIterator));
} finally {
eagerIterator.close();
}
ResultIterator<?> lazyIterator = cacheQuery.iterator(new FetchOptions().fetchMode(FetchOptions.FetchMode.LAZY));
try {
assertEquals(1, countElements(lazyIterator));
} finally {
lazyIterator.close();
}
ResultIterator<?> defaultIterator = cacheQuery.iterator();
try {
assertEquals(1, countElements(defaultIterator));
} finally {
defaultIterator.close();
}
StaticTestingErrorHandler.assertAllGood(cache);
}
private int countElements(ResultIterator<?> iterator) {
int count = 0;
while (iterator.hasNext()) {
iterator.next();
count++;
}
return count;
}
@Test
public void testClear() {
loadTestingData();
// Create a term that will return me everyone called Navin.
Term navin = new Term("name", "navin");
// Create a term that I know will return me everything with name goat.
Term goat = new Term ("name", "goat");
BooleanQuery luceneQuery = new BooleanQuery();
luceneQuery.add(new TermQuery(goat), Occur.SHOULD);
luceneQuery.add(new TermQuery(navin), Occur.SHOULD);
CacheQuery<?> cacheQuery = Search.getSearchManager(cache).getQuery(luceneQuery);
// We know that we've got all 3 hits.
assertEquals("Expected 3, got " + cacheQuery.getResultSize(), 3, cacheQuery.getResultSize());
cache.clear();
cacheQuery = Search.getSearchManager(cache).getQuery(luceneQuery);
assertEquals(0, cacheQuery.getResultSize());
StaticTestingErrorHandler.assertAllGood(cache);
}
protected void loadTestingData() {
prepareTestingData();
cache.put(key1, person1);
// person2 is verified as number of matches in multiple tests,
// so verify duplicate insertion doesn't affect result counts:
cache.put(key2, person2);
cache.put(key2, person2);
cache.put(key2, person2);
cache.put(key3, person3);
StaticTestingErrorHandler.assertAllGood(cache);
}
private void prepareTestingData() {
person1 = new Person();
person1.setName("Navin Surtani");
person1.setAge(20);
person1.setBlurb("Likes playing WoW");
person1.setNonSearchableField("test1");
person2 = new Person();
person2.setName("Big Goat");
person2.setAge(30);
person2.setBlurb("Eats grass");
person2.setNonSearchableField("test2");
person3 = new Person();
person3.setName("Mini Goat");
person3.setAge(25);
person3.setBlurb("Eats cheese");
person3.setNonSearchableField("test3");
}
private void assertPeopleInSortedList(List<?> actualList, Object... expected) {
List<?> expectedList = new ArrayList<>(Arrays.asList(expected));
assertEquals("Result doesn't match expected result.", expectedList, actualList);
}
private void assertPeopleInList(List<?> actualList, Object... expected) {
List<?> expectedList = new ArrayList<>(Arrays.asList(expected));
assertEquals("Size of the result doesn't match.", expected.length, actualList.size());
//collections are not disjoint = they are the same
assertTrue("Result doesn't match expected result. Expected: <" + expectedList + ">, was: <" + actualList + ">",
!Collections.disjoint(actualList, expectedList));
}
}