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)); } }