package net.jxta.impl.cm; import java.io.File; import java.io.IOException; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; import net.jxta.id.IDFactory; import net.jxta.peergroup.PeerGroup; import net.jxta.peergroup.PeerGroupID; import net.jxta.test.util.JUnitRuleMockery; import org.jmock.Expectations; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; public abstract class AbstractSrdiIndexBackendConcurrencyTest { @Rule public JUnitRuleMockery mockContext = new JUnitRuleMockery(); private static final int NUM_INDICES = 8; private static final int NUM_GROUPS = 8; private static final int OPS_PER_INDEX = 500; private static final long TEST_TIMEOUT = 120L; @Rule public TemporaryFolder testFileStore = new TemporaryFolder(); protected File storeRoot; private ScheduledExecutorService executorService; @Before public void setUp() throws Exception { storeRoot = testFileStore.getRoot(); executorService = new ScheduledThreadPoolExecutor(2); } @After public void tearDown() throws Exception { executorService.shutdownNow(); } @Test public void testSeparateIndexConcurrentSafety() throws Exception { PeerGroup group = createGroup(PeerGroupID.defaultNetPeerGroupID, "group1"); Srdi[] indices = new Srdi[NUM_INDICES]; for(int i=0; i < NUM_INDICES; i++) { indices[i] = new Srdi(createBackend(group, "index" + i), Srdi.NO_AUTO_GC, executorService); } randomLoadTest(indices); } private void randomLoadTest(Srdi[] indices) throws InterruptedException { CountDownLatch completionLatch = new CountDownLatch(indices.length); IndexRandomLoadTester[] testers = new IndexRandomLoadTester[indices.length]; try { for(int i=0; i < indices.length; i++) { testers[i] = new IndexRandomLoadTester(indices[i], OPS_PER_INDEX, completionLatch); new Thread(testers[i]).start(); } Assert.assertTrue("Timed out waiting for thread completion", completionLatch.await(TEST_TIMEOUT, TimeUnit.SECONDS)); for(int i=0; i < indices.length; i++) { Assert.assertTrue(testers[i].isSuccessful()); } } finally { for(int i=0; i < indices.length; i++) { if(indices[i] != null) { indices[i].stop(); } } } } /* this test is particularly slow running for the in memory srdi index test, which * perhaps isn't optimised for this kind of multi-threaded brutality. * FIXME: revisit this, improve performance of in-memory index so that this can be * run. */ @Ignore @Test public void testSeparateGroupConcurrentSafety() throws Exception { Srdi[] indices = new Srdi[NUM_INDICES * NUM_GROUPS]; for(int groupNum = 0; groupNum < NUM_GROUPS; groupNum++) { PeerGroup group = createGroup(IDFactory.newPeerGroupID(), "group" + groupNum); for(int indexNum = 0; indexNum < NUM_INDICES; indexNum++) { indices[NUM_INDICES * groupNum + indexNum] = new Srdi(createBackend(group, "index" + indexNum), Srdi.NO_AUTO_GC, executorService); } } randomLoadTest(indices); } private PeerGroup createGroup(final PeerGroupID groupId, final String name) { final PeerGroup group = mockContext.mock(PeerGroup.class, name); mockContext.checking(new Expectations() {{ ignoring(group).getStoreHome(); will(returnValue(storeRoot.toURI())); ignoring(group).getPeerGroupName(); will(returnValue(name)); ignoring(group).getPeerGroupID(); will(returnValue(groupId)); // ignoring(group).getHomeThreadGroup(); will(returnValue(Thread.currentThread().getThreadGroup())); }}); return group; } protected abstract SrdiAPI createBackend(PeerGroup group, String indexName) throws IOException; }