/** * Test the feature of clearing a JEReplicaDB used by a replication server. The clear feature is * used when a replication server receives a request to reset the generationId of a given domain. */ @Test public void testClear() throws Exception { ReplicationServer replicationServer = null; JEReplicaDB replicaDB = null; try { TestCaseUtils.startServer(); replicationServer = configureReplicationServer(100, 5000); replicaDB = newReplicaDB(replicationServer); CSN[] csns = generateCSNs(1, 0, 3); // Add the changes and check they are here replicaDB.add(new DeleteMsg(TEST_ROOT_DN, csns[0], "uid")); replicaDB.add(new DeleteMsg(TEST_ROOT_DN, csns[1], "uid")); replicaDB.add(new DeleteMsg(TEST_ROOT_DN, csns[2], "uid")); assertEquals(csns[0], replicaDB.getOldestCSN()); assertEquals(csns[2], replicaDB.getNewestCSN()); // Clear DB and check it is cleared. replicaDB.clear(); assertEquals(null, replicaDB.getOldestCSN()); assertEquals(null, replicaDB.getNewestCSN()); } finally { shutdown(replicaDB); remove(replicationServer); } }
@Test public void testTrim() throws Exception { ReplicationServer replicationServer = null; JEReplicaDB replicaDB = null; try { TestCaseUtils.startServer(); replicationServer = configureReplicationServer(100, 5000); replicaDB = newReplicaDB(replicationServer); CSN[] csns = generateCSNs(1, 0, 5); replicaDB.add(new DeleteMsg(TEST_ROOT_DN, csns[0], "uid")); replicaDB.add(new DeleteMsg(TEST_ROOT_DN, csns[1], "uid")); replicaDB.add(new DeleteMsg(TEST_ROOT_DN, csns[2], "uid")); DeleteMsg update4 = new DeleteMsg(TEST_ROOT_DN, csns[3], "uid"); // -- // Iterator tests with changes persisted assertFoundInOrder(replicaDB, csns[0], csns[1], csns[2]); assertNotFound(replicaDB, csns[4], AFTER_MATCHING_KEY); assertEquals(replicaDB.getOldestCSN(), csns[0]); assertEquals(replicaDB.getNewestCSN(), csns[2]); // -- // Cursor tests with changes persisted replicaDB.add(update4); assertFoundInOrder(replicaDB, csns[0], csns[1], csns[2], csns[3]); // Test cursor from existing CSN assertFoundInOrder(replicaDB, csns[2], csns[3]); assertFoundInOrder(replicaDB, csns[3]); assertNotFound(replicaDB, csns[4], AFTER_MATCHING_KEY); replicaDB.purgeUpTo(new CSN(Long.MAX_VALUE, 0, 0)); int count = 0; boolean purgeSucceeded = false; final CSN expectedNewestCSN = csns[3]; do { Thread.sleep(10); final CSN oldestCSN = replicaDB.getOldestCSN(); final CSN newestCSN = replicaDB.getNewestCSN(); purgeSucceeded = oldestCSN.equals(expectedNewestCSN) && newestCSN.equals(expectedNewestCSN); count++; } while (!purgeSucceeded && count < 100); assertTrue(purgeSucceeded); } finally { shutdown(replicaDB); remove(replicationServer); } }
/** Test if int value are ok. */ @Test(dataProvider = "persistentSearchChangeTypeData") public void checkIntValueTest(Map<Integer, String> expectedValues) throws Exception { for (Integer i : expectedValues.keySet()) { PersistentSearchChangeType val = PersistentSearchChangeType.valueOf(i); String expected = expectedValues.get(i); assertEquals(val.toString(), expected); } }
@Test( dataProvider = "persistentSearchChangeTypeData", dependsOnMethods = {"checkIntToTypeTest"}) public void checkChangeTypesToStringTest(Map<Integer, String> exceptedValues) throws Exception { for (int i = 1; i <= 15; i++) { Set<PersistentSearchChangeType> returnTypes = PersistentSearchChangeType.intToTypes(i); String ret = PersistentSearchChangeType.changeTypesToString(returnTypes); assertEquals(ret, Utils.joinAsString("|", returnTypes)); } }
/** Test int to type. */ @Test(dataProvider = "persistentSearchChangeTypeData") public void checkIntToTypeTest(Map<Integer, String> exceptedValues) throws Exception { Set<Integer> keys = exceptedValues.keySet(); Set<PersistentSearchChangeType> expectedTypes = new HashSet<>(4); for (int i = 1; i <= 15; i++) { expectedTypes.clear(); for (int key : keys) { if ((i & key) != 0) { expectedTypes.add(PersistentSearchChangeType.valueOf(key)); } } Set<PersistentSearchChangeType> returnTypes = PersistentSearchChangeType.intToTypes(i); assertEquals(expectedTypes.size(), returnTypes.size()); for (PersistentSearchChangeType type : expectedTypes) { assertTrue(returnTypes.contains(type)); } } // We should have an exception try { PersistentSearchChangeType.intToTypes(0); fail(); } catch (LDAPException expected) { assertEquals( expected.getMessage(), "The provided integer value indicated that there were no persistent search change types, which is not allowed"); } // We should have an exception int i = 16; try { PersistentSearchChangeType.intToTypes(i); fail(); } catch (LDAPException expected) { assertEquals( expected.getMessage(), "The provided integer value " + i + " was outside the range of acceptable values for an encoded change type set"); } }
private void checkEntryChangeNotificationControlToString(EntryChangeNotificationControl ecnc) { String toString = "EntryChangeNotificationControl(changeType=" + ecnc.getChangeType(); if (ecnc.getPreviousDN() != null) { toString = toString + ",previousDN=\"" + ecnc.getPreviousDN() + "\""; } if (ecnc.getChangeNumber() > 0) { toString = toString + ",changeNumber=" + ecnc.getChangeNumber(); } toString = toString + ")"; assertEquals(toString, ecnc.toString()); }
/** Test If we have only the required values. */ @Test(dataProvider = "persistentSearchChangeTypeData") public void checkRequiredValuesTest(Map<Integer, String> exceptedValues) throws Exception { // Retrieve the values PersistentSearchChangeType[] vals = PersistentSearchChangeType.values(); // Check if we have the correct number assertEquals(vals.length, exceptedValues.size()); // Check if we have the correct int value for (PersistentSearchChangeType val : vals) { assertTrue(exceptedValues.containsKey(val.intValue())); } }
/** Tests the maximum persistent search limit imposed by the server. */ @Test public void testMaxPSearch() throws Exception { TestCaseUtils.initializeTestBackend(true); // Modify the configuration to allow only 1 concurrent persistent search. InternalClientConnection conn = getRootConnection(); LDAPAttribute attr = new LDAPAttribute("ds-cfg-max-psearches", "1"); ArrayList<RawModification> mods = new ArrayList<>(); mods.add(new LDAPModification(ModificationType.REPLACE, attr)); ModifyOperation modifyOperation = conn.processModify(ByteString.valueOf("cn=config"), mods); assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS); // Create a persistent search request. Set<PersistentSearchChangeType> changeTypes = EnumSet.of(ADD, DELETE, MODIFY, MODIFY_DN); SearchRequest request = newSearchRequest(DN.valueOf("o=test"), SearchScope.BASE_OBJECT) .setTypesOnly(true) .addAttribute("cn") .addControl(new PersistentSearchControl(changeTypes, true, true)); final InternalSearchOperation search = conn.processSearch(request); Thread t = new Thread( new Runnable() { @Override public void run() { try { search.run(); } catch (Exception ex) { } } }, "Persistent Search Test"); t.start(); t.join(2000); // Create a persistent search request. final String[] args = { "-D", "cn=Directory Manager", "-w", "password", "-h", "127.0.0.1", "-p", String.valueOf(TestCaseUtils.getServerLdapPort()), "-b", "o=test", "-s", "sub", "-C", "ps:add:true:true", "--noPropertiesFile", "(objectClass=*)" }; assertEquals(LDAPSearch.mainSearch(args, false, true, null, System.err), 11); // cancel the persisting persistent search. search.cancel(new CancelRequest(true, LocalizableMessage.EMPTY)); }
/** Test EntryChangeNotificationControl. */ @Test(dataProvider = "entryChangeNotificationControl") public void checkEntryChangeNotificationControlTest( boolean isCritical, long changeNumber, String dnString) throws Exception { // Test constructor EntryChangeNotificationControl // (PersistentSearchChangeType changeType,long changeNumber) PersistentSearchChangeType[] types = PersistentSearchChangeType.values(); EntryChangeNotificationControl ecnc = null; EntryChangeNotificationControl newEcnc; ByteStringBuilder bsb = new ByteStringBuilder(); ASN1Writer writer = ASN1.getWriter(bsb); for (PersistentSearchChangeType type : types) { ecnc = new EntryChangeNotificationControl(type, changeNumber); assertNotNull(ecnc); assertEquals(OID_ENTRY_CHANGE_NOTIFICATION, ecnc.getOID()); assertEquals(changeNumber, ecnc.getChangeNumber()); assertEquals(type, ecnc.getChangeType()); assertNull(ecnc.getPreviousDN()); assertEquals(false, ecnc.isCritical()); checkEntryChangeNotificationControlToString(ecnc); // also check encode/decode try { bsb.clear(); ecnc.write(writer); LDAPControl control = LDAPReader.readControl(ASN1.getReader(bsb)); newEcnc = EntryChangeNotificationControl.DECODER.decode(control.isCritical(), control.getValue()); assertNotNull(newEcnc); assertEquals(ecnc.getOID(), newEcnc.getOID()); assertEquals(ecnc.getChangeNumber(), newEcnc.getChangeNumber()); assertEquals(ecnc.getChangeType(), newEcnc.getChangeType()); assertNull(newEcnc.getPreviousDN()); assertEquals(ecnc.isCritical(), newEcnc.isCritical()); } catch (DirectoryException e) { fail(); } } // Test constructor EntryChangeNotificationControl // (PersistentSearchChangeType changeType, DN previousDN, long // changeNumber) DN dn = DN.valueOf(dnString); for (PersistentSearchChangeType type : types) { ecnc = new EntryChangeNotificationControl(type, dn, changeNumber); assertNotNull(ecnc); assertEquals(OID_ENTRY_CHANGE_NOTIFICATION, ecnc.getOID()); assertEquals(changeNumber, ecnc.getChangeNumber()); assertEquals(type, ecnc.getChangeType()); assertEquals(dn, ecnc.getPreviousDN()); assertEquals(false, ecnc.isCritical()); checkEntryChangeNotificationControlToString(ecnc); // also check encode/decode try { bsb.clear(); ecnc.write(writer); LDAPControl control = LDAPReader.readControl(ASN1.getReader(bsb)); newEcnc = EntryChangeNotificationControl.DECODER.decode(control.isCritical(), control.getValue()); assertNotNull(newEcnc); assertEquals(ecnc.getOID(), newEcnc.getOID()); assertEquals(ecnc.getChangeNumber(), newEcnc.getChangeNumber()); assertEquals(ecnc.getChangeType(), newEcnc.getChangeType()); assertEquals(ecnc.getPreviousDN(), newEcnc.getPreviousDN()); assertEquals(ecnc.isCritical(), newEcnc.isCritical()); } catch (DirectoryException e) { assertNotEquals( type.compareTo(MODIFY_DN), 0, "couldn't decode a control with previousDN not null and type=modDN"); } } // Test constructor EntryChangeNotificationControl(boolean // isCritical, PersistentSearchChangeType changeType, // DN previousDN, long changeNumber) for (PersistentSearchChangeType type : types) { ecnc = new EntryChangeNotificationControl(isCritical, type, dn, changeNumber); assertNotNull(ecnc); assertEquals(OID_ENTRY_CHANGE_NOTIFICATION, ecnc.getOID()); assertEquals(changeNumber, ecnc.getChangeNumber()); assertEquals(type, ecnc.getChangeType()); assertEquals(dn, ecnc.getPreviousDN()); assertEquals(isCritical, ecnc.isCritical()); checkEntryChangeNotificationControlToString(ecnc); // also check encode/decode try { bsb.clear(); ecnc.write(writer); LDAPControl control = LDAPReader.readControl(ASN1.getReader(bsb)); newEcnc = EntryChangeNotificationControl.DECODER.decode(control.isCritical(), control.getValue()); assertNotNull(newEcnc); assertEquals(ecnc.getOID(), newEcnc.getOID()); assertEquals(ecnc.getChangeNumber(), newEcnc.getChangeNumber()); assertEquals(ecnc.getChangeType(), newEcnc.getChangeType()); assertEquals(ecnc.getPreviousDN(), newEcnc.getPreviousDN()); assertEquals(ecnc.isCritical(), newEcnc.isCritical()); } catch (DirectoryException e) { assertNotEquals( type.compareTo(PersistentSearchChangeType.MODIFY_DN), 0, "couldn't decode a control with previousDN not null and type=modDN"); } } // Check error on decode try { LDAPControl control = new LDAPControl(OID_ENTRY_CHANGE_NOTIFICATION, isCritical); newEcnc = EntryChangeNotificationControl.DECODER.decode(control.isCritical(), control.getValue()); fail(); } catch (DirectoryException expected) { assertEquals(expected.getMessage(), CANNOT_DECODE_CHANGE_NOTIF_CONTROL_NO_VALUE); } }
/** Test PersistentSearchControl. */ @Test(dataProvider = "persistentSearchControl") public void checkPersistentSearchControlTest( boolean isCritical, boolean changesOnly, boolean returnECs) throws Exception { // Test constructor // CheclPersistentSearchControlTest(Set<PersistentSearchChangeType> // changeTypes, boolean changesOnly, boolean returnECs for (int i = 1; i <= 15; i++) { Set<PersistentSearchChangeType> returnTypes = PersistentSearchChangeType.intToTypes(i); PersistentSearchControl psc = new PersistentSearchControl(returnTypes, changesOnly, returnECs); assertNotNull(psc); assertEquals(changesOnly, psc.getChangesOnly()); assertEquals(returnECs, psc.getReturnECs()); assertEquals(returnTypes.size(), psc.getChangeTypes().size()); assertEquals(OID_PERSISTENT_SEARCH, psc.getOID()); } // Test constructor // CString oid, boolean isCritical, // Set<PersistentSearchChangeType> changeTypes, // boolean changesOnly, boolean returnECs for (int i = 1; i <= 15; i++) { Set<PersistentSearchChangeType> returnTypes = PersistentSearchChangeType.intToTypes(i); PersistentSearchControl psc = new PersistentSearchControl(isCritical, returnTypes, changesOnly, returnECs); assertNotNull(psc); assertEquals(isCritical, psc.isCritical()); assertEquals(OID_PERSISTENT_SEARCH, psc.getOID()); assertEquals(changesOnly, psc.getChangesOnly()); assertEquals(returnECs, psc.getReturnECs()); assertEquals(returnTypes.size(), psc.getChangeTypes().size()); } // Test encode/decode ByteStringBuilder bsb = new ByteStringBuilder(); ASN1Writer writer = ASN1.getWriter(bsb); for (int i = 1; i <= 15; i++) { bsb.clear(); Set<PersistentSearchChangeType> returnTypes = PersistentSearchChangeType.intToTypes(i); PersistentSearchControl psc = new PersistentSearchControl(isCritical, returnTypes, changesOnly, returnECs); psc.write(writer); LDAPControl control = LDAPReader.readControl(ASN1.getReader(bsb)); psc = PersistentSearchControl.DECODER.decode(control.isCritical(), control.getValue()); assertNotNull(psc); assertEquals(isCritical, psc.isCritical()); assertEquals(OID_PERSISTENT_SEARCH, psc.getOID()); assertEquals(changesOnly, psc.getChangesOnly()); assertEquals(returnECs, psc.getReturnECs()); assertEquals(returnTypes.size(), psc.getChangeTypes().size()); // Check the toString String changeTypes = PersistentSearchChangeType.changeTypesToString(psc.getChangeTypes()); String toString = "PersistentSearchControl(changeTypes=\"" + changeTypes + "\",changesOnly=" + psc.getChangesOnly() + ",returnECs=" + psc.getReturnECs() + ")"; assertEquals(psc.toString(), toString); // check null value for the control try { control = new LDAPControl(OID_PERSISTENT_SEARCH, isCritical); psc = PersistentSearchControl.DECODER.decode(control.isCritical(), control.getValue()); fail(); } catch (DirectoryException expected) { assertEquals(expected.getMessage(), CANNOT_DECODE_PERSISTENT_SEARCH_CONTROL_NO_VALUE); } // check invalid value for the control try { control = new LDAPControl(OID_PERSISTENT_SEARCH, isCritical, ByteString.valueOf("invalid value")); psc = PersistentSearchControl.DECODER.decode(control.isCritical(), control.getValue()); fail(); } catch (DirectoryException expected) { assertThat(expected.getMessage()) .contains("Cannot decode the provided persistent search control"); } } }
private void testGetOldestNewestCSNs(final int max, final int counterWindow) throws Exception { String tn = "testDBCount(" + max + "," + counterWindow + ")"; debugInfo(tn, "Starting test"); File testRoot = null; ReplicationServer replicationServer = null; ReplicationDbEnv dbEnv = null; JEReplicaDB replicaDB = null; try { TestCaseUtils.startServer(); replicationServer = configureReplicationServer(100000, 10); testRoot = createCleanDir(); dbEnv = new ReplicationDbEnv(testRoot.getPath(), replicationServer); replicaDB = new JEReplicaDB(1, TEST_ROOT_DN, replicationServer, dbEnv); replicaDB.setCounterRecordWindowSize(counterWindow); // Populate the db with 'max' msg int mySeqnum = 1; CSN csns[] = new CSN[2 * (max + 1)]; long now = System.currentTimeMillis(); for (int i = 1; i <= max; i++) { csns[i] = new CSN(now + i, mySeqnum, 1); replicaDB.add(new DeleteMsg(TEST_ROOT_DN, csns[i], "uid")); mySeqnum += 2; } assertEquals(replicaDB.getOldestCSN(), csns[1], "Wrong oldest CSN"); assertEquals(replicaDB.getNewestCSN(), csns[max], "Wrong newest CSN"); // Now we want to test that after closing and reopening the db, the // counting algo is well reinitialized and when new messages are added // the new counter are correctly generated. debugInfo(tn, "SHUTDOWN replicaDB and recreate"); replicaDB.shutdown(); replicaDB = new JEReplicaDB(1, TEST_ROOT_DN, replicationServer, dbEnv); replicaDB.setCounterRecordWindowSize(counterWindow); assertEquals(replicaDB.getOldestCSN(), csns[1], "Wrong oldest CSN"); assertEquals(replicaDB.getNewestCSN(), csns[max], "Wrong newest CSN"); // Populate the db with 'max' msg for (int i = max + 1; i <= 2 * max; i++) { csns[i] = new CSN(now + i, mySeqnum, 1); replicaDB.add(new DeleteMsg(TEST_ROOT_DN, csns[i], "uid")); mySeqnum += 2; } assertEquals(replicaDB.getOldestCSN(), csns[1], "Wrong oldest CSN"); assertEquals(replicaDB.getNewestCSN(), csns[2 * max], "Wrong newest CSN"); replicaDB.purgeUpTo(new CSN(Long.MAX_VALUE, 0, 0)); String testcase = "AFTER PURGE (oldest, newest)="; debugInfo(tn, testcase + replicaDB.getOldestCSN() + replicaDB.getNewestCSN()); assertEquals(replicaDB.getNewestCSN(), csns[2 * max], "Newest="); // Clear ... debugInfo(tn, "clear:"); replicaDB.clear(); // Check the db is cleared. assertEquals(null, replicaDB.getOldestCSN()); assertEquals(null, replicaDB.getNewestCSN()); debugInfo(tn, "Success"); } finally { shutdown(replicaDB); if (dbEnv != null) { dbEnv.shutdown(); } remove(replicationServer); TestCaseUtils.deleteDirectory(testRoot); } }