package compasstest; import java.util.List; import java.util.ArrayList; import java.util.Random; import java.util.Set; import java.util.HashSet; import java.util.concurrent.Future; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.compass.core.CompassTemplate; import org.compass.core.CompassDetachedHits; import org.compass.core.Compass; import org.compass.core.CompassHits; import org.compass.core.config.CompassConfiguration; import junit.framework.TestCase; public class CompassTest extends TestCase { private static final String ALIAS_TOBESEARCHED_NAME_UNIQUE_NAME = "+alias:tobesearched +name:"; private String id; private String name; protected void setUp() throws Exception { super.setUp(); CompassConfiguration compassConfiguration = new CompassConfiguration(); compassConfiguration.addClass(ToBeSearched.class); compassConfiguration.setSetting("compass.engine.connection", "./testindex"); compassConfiguration.setSetting("compass.transaction.factory", "org.compass.core.transaction.LocalTransactionFactory"); Compass compass = compassConfiguration.buildCompass(); compass.getSearchEngineIndexManager().deleteIndex(); compass.getSearchEngineIndexManager().createIndex(); compassTemplate = new CompassTemplate(compass); id = "uniqueid" ; name = "uniqueName" ; } private CompassTemplate compassTemplate; public void testSearchingObjectsAtTheSameTimeAsChangingThemCanCauseTheSameObjectToBeReturnedTwiceInCompassHits() throws Exception { ToBeSearched toBeSearched = new ToBeSearched(); toBeSearched.setId(id); toBeSearched.setName(name); toBeSearched.setDescription("description"); compassTemplate.save(toBeSearched); CompassDetachedHits hits = compassTemplate.findWithDetach(ALIAS_TOBESEARCHED_NAME_UNIQUE_NAME+name); assertEquals("before",1,hits.length()); ExecutorService executorService = Executors.newFixedThreadPool(20); 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 < 1000; i++) { search(searchDelay); } } }; List> results= new ArrayList>(); results.add(executorService.submit(search)); results.add(executorService.submit(mutate)); for (Future future : results) { future.get(); } } private void mutate(String description,long delay) { ToBeSearched reloaded = (ToBeSearched) compassTemplate.load("tobesearched", id); reloaded.setDescription(description); compassTemplate.save(reloaded); try { Thread.sleep(delay); } catch (InterruptedException e) { } } private void search(long delay) { CompassHits hitsAfter = compassTemplate.find(ALIAS_TOBESEARCHED_NAME_UNIQUE_NAME+name); if(hitsAfter.length()>1){ Set cps = new HashSet(); ArrayList results = new ArrayList(); for (int i=0;i