package net.jxta.impl.cm; import java.io.File; import java.net.URI; import java.util.List; import net.jxta.impl.cm.SrdiIndex.Entry; import net.jxta.peergroup.PeerGroup; import net.jxta.peergroup.PeerGroupID; import net.jxta.test.util.FileSystemTest; import org.jmock.Expectations; public class XIndiceSrdiIndexBackendTest extends AbstractSrdiIndexBackendTest { private File storeHome; @Override protected void setUp() throws Exception { storeHome = FileSystemTest.createTempDirectory("DefaultSrdiIndexBackendTest"); super.setUp(); } @Override protected void tearDown() throws Exception { super.tearDown(); FileSystemTest.deleteDir(storeHome); } @Override public String getBackendClassname() { return XIndiceSrdiIndexBackend.class.getName(); } @Override protected SrdiIndexBackend createBackend(PeerGroup group, String indexName) { return new XIndiceSrdiIndexBackend(group, indexName); } /** * Checks that expired entries recorded under the same primary key, attribute and * value combination are removed on a call to add. * <p> * It may not make sense for all implementations to remove expired entries on add - * it is done in the XIndice implementation simply because it is convenient. It * should be possible to copy this test to the test class of an alternate implementation * if it too should remove expired entries. */ public void testAdd_removesExpiredEntries() throws Exception { srdiIndex.add("a", "b", "c", PEER_ID, 10000L); srdiIndex.add("a", "b", "c", PEER_ID_2, 5000L); // this entry should not be deleted automatically as it is under a different // (pkey, attr, value) combination. srdiIndex.add("a", "d", "x", PEER_ID_2, 5000L); clock.currentTime = 8000L; srdiIndex.add("a", "b", "c", PEER_ID_3, 12000L); List<Entry> record = srdiIndex.getRecord("a", "b", "c"); assertNotNull(record); assertEquals(2, record.size()); assertContains(record, new Entry(PEER_ID, 10000L), new Entry(PEER_ID_3, 20000L)); } /** * Check that if the entries for a peer ID are marked for removal, that * the remove is cancelled if another add for that peer occurs before * the garbage collect. * <p> * This behaviour is commented as "FIXME" in XIndiceSrdiIndexBackend, so it * may not be desirable for all implementations to follow these semantics. */ public void testRemove_isCancelledBySubsequentAdd() throws Exception { srdiIndex.add("a", "b", "c", PEER_ID, 1000L); srdiIndex.remove(PEER_ID); srdiIndex.add("a", "d", "e", PEER_ID, 1000L); srdiIndex.garbageCollect(); List<Entry> results = srdiIndex.getRecord("a", "b", "c"); assertEquals(1, results.size()); assertContains(results, new Entry(PEER_ID, 1000L)); } public void testConstruction_withNoBackendOverride() { String oldBackend = System.getProperty(SrdiIndex.SRDI_INDEX_BACKEND_SYSPROP); try { System.clearProperty(SrdiIndex.SRDI_INDEX_BACKEND_SYSPROP); final PeerGroup group = mock(PeerGroup.class); checking(createExpectationsForConstruction_withPeerGroup_IndexName(group, GROUP_ID_1, "testGroup")); SrdiIndex srdiIndex = new SrdiIndex(group, "testIndex"); assertEquals("net.jxta.impl.cm.XIndiceSrdiIndexBackend", srdiIndex.getBackendClassName()); srdiIndex.stop(); } finally { if(oldBackend != null) { System.setProperty(SrdiIndex.SRDI_INDEX_BACKEND_SYSPROP, oldBackend); } else { System.clearProperty(SrdiIndex.SRDI_INDEX_BACKEND_SYSPROP); } } } @Override public Expectations createExpectationsForConstruction_withPeerGroup_IndexName(final PeerGroup mockGroup, final PeerGroupID groupId, String groupName) { final URI storeHomeURI = storeHome.toURI(); return new Expectations() {{ ignoring(mockGroup).getPeerGroupName(); will(returnValue("testGroup")); atLeast(1).of(mockGroup).getPeerGroupID(); will(returnValue(groupId)); atLeast(1).of(mockGroup).getStoreHome(); will(returnValue(storeHomeURI)); ignoring(mockGroup).getHomeThreadGroup(); will(returnValue(Thread.currentThread().getThreadGroup())); }}; } public void testConstruction_withSrdiIndexBackendMissingConstructor_PeerGroup_IndexName() { System.setProperty(SrdiIndex.SRDI_INDEX_BACKEND_SYSPROP, SrdiIndexBackendWithoutConstructor_PeerGroup_IndexName.class.getName()); final PeerGroup group = mock(PeerGroup.class); checking(createExpectationsForConstruction_withPeerGroup_IndexName(group, GROUP_ID_1, "testGroup")); SrdiIndex index = new SrdiIndex(group, "testIndex"); // should fall back to default assertEquals(index.getBackendClassName(), SrdiIndex.DEFAULT_SRDI_INDEX_BACKEND); } public void testConstruction_withSrdiIndexBackendMissingStaticMethod_clearSrdi() { System.setProperty(SrdiIndex.SRDI_INDEX_BACKEND_SYSPROP, SrdiIndexBackendWithoutStaticMethod_clearSrdi.class.getName()); final PeerGroup group = mock(PeerGroup.class); checking(createExpectationsForConstruction_withPeerGroup_IndexName(group, GROUP_ID_1, "testGroup")); SrdiIndex index = new SrdiIndex(group, "testIndex"); // should fall back to default assertEquals(index.getBackendClassName(), SrdiIndex.DEFAULT_SRDI_INDEX_BACKEND); } public void testConstruction_withBackendThatDoesNotImplementSrdiIndexBackend() { System.setProperty(SrdiIndex.SRDI_INDEX_BACKEND_SYSPROP, BackendThatDoesNotImplementSrdiIndexBackend.class.getName()); final PeerGroup group = mock(PeerGroup.class); checking(createExpectationsForConstruction_withPeerGroup_IndexName(group, GROUP_ID_1, "testGroup")); SrdiIndex index = new SrdiIndex(group, "testIndex"); // should fall back to default assertEquals(index.getBackendClassName(), SrdiIndex.DEFAULT_SRDI_INDEX_BACKEND); } /** * has everything needed except for the constructor that takes a peer group and string as parameters. */ public static class SrdiIndexBackendWithoutConstructor_PeerGroup_IndexName extends NullSrdiIndexBackend { public static void clearSrdi(PeerGroup group) {} } /** * has everything needed except for the static method to clear all indices for a given group */ public static class SrdiIndexBackendWithoutStaticMethod_clearSrdi extends NullSrdiIndexBackend { public SrdiIndexBackendWithoutStaticMethod_clearSrdi(PeerGroup group, String indexName) {} } /** * Has all the required constructors and static methods but does not implement SrdiIndexBackend */ public static class BackendThatDoesNotImplementSrdiIndexBackend { public BackendThatDoesNotImplementSrdiIndexBackend(PeerGroup group, String indexName) {} public static void clearSrdi(PeerGroup group) {} } }