/* * Copyright 2004-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.compass.core.test.concurrency.duplicatehits; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import junit.framework.TestCase; import org.compass.core.Compass; import org.compass.core.CompassDetachedHits; import org.compass.core.CompassTemplate; import org.compass.core.config.CompassConfiguration; import org.compass.core.config.CompassEnvironment; public class DuplicateHitsTests extends TestCase { private static final String ALIAS_A_NAME_UNIQUE_NAME = "+alias:a +name:"; private static final String UNIQUE_ID = "uniqueid"; private static final String UNIQUE_NAME = "uniqueName"; private CompassTemplate compassTemplate; private Compass compass; protected void setUp() throws Exception { super.setUp(); CompassConfiguration compassConfiguration = new CompassConfiguration(); compassConfiguration.addClass(A.class); compassConfiguration.setSetting(CompassEnvironment.CONNECTION, "target/test-index"); compassConfiguration.setSetting(CompassEnvironment.Transaction.FACTORY, "org.compass.core.transaction.LocalTransactionFactory"); compass = compassConfiguration.buildCompass(); compass.getSearchEngineIndexManager().deleteIndex(); compass.getSearchEngineIndexManager().createIndex(); compassTemplate = new CompassTemplate(compass); } protected void tearDown() throws Exception { compass.close(); compass.getSearchEngineIndexManager().deleteIndex(); } public void testSearchingObjectsAtTheSameTimeAsChangingThemWontCauseTheSameObjectToBeReturnedTwiceInCompassHits() throws Exception { A toBeSearched = new A(); toBeSearched.setId(UNIQUE_ID); toBeSearched.setName(UNIQUE_NAME); toBeSearched.setDescription("description"); compassTemplate.save(toBeSearched); CompassDetachedHits hits = compassTemplate.findWithDetach(ALIAS_A_NAME_UNIQUE_NAME + UNIQUE_NAME); assertEquals("before", 1, hits.length()); ExecutorService executorService = Executors.newFixedThreadPool(5); final long mutateDelay = 1; final long searchDelay = 1; Runnable mutate = new Runnable() { public void run() { for (int i = 0; i < 100; i++) { mutate("desc" + i, mutateDelay); } } }; Runnable search = new Runnable() { public void run() { for (int i = 0; i < 100; i++) { search(searchDelay); } } }; List results = new ArrayList(); results.add(executorService.submit(search)); for (int i = 1; i <= 1; i++) { results.add(executorService.submit(mutate)); } for (Iterator it = results.iterator(); it.hasNext();) { Future future = (Future) it.next(); future.get(); } executorService.shutdown(); } private void mutate(String description, long delay) { A reloaded = (A) compassTemplate.load("a", UNIQUE_ID); reloaded.setDescription(description); compassTemplate.save(reloaded); try { Thread.sleep(delay); } catch (InterruptedException e) { } } private void search(long delay) { CompassDetachedHits hitsAfter = compassTemplate.findWithDetach(ALIAS_A_NAME_UNIQUE_NAME + UNIQUE_NAME); if (hitsAfter.length() > 1) { Set cps = new HashSet(); ArrayList results = new ArrayList(); for (int i = 0; i < hitsAfter.length(); i++) { A toBeSearched = (A) hitsAfter.data(i); cps.add(toBeSearched.getId()); results.add(toBeSearched); } assertTrue("the ids for the returned objects should be unique" + results, cps.size() == hitsAfter.length()); } try { Thread.sleep(delay); } catch (InterruptedException e) { } } }