/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt * or http://forgerock.org/license/CDDLv1.0.html. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at legal-notices/CDDLv1_0.txt. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Copyright 2006-2010 Sun Microsystems, Inc. * Portions Copyright 2011-2015 ForgeRock AS */ package org.opends.server.backends.jeb; import static org.opends.server.schema.SchemaConstants.*; import static org.opends.server.util.ServerConstants.*; import static org.testng.Assert.*; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import org.forgerock.opendj.ldap.ByteString; import org.opends.server.TestCaseUtils; import org.opends.server.api.Backend; import org.opends.server.backends.VerifyConfig; import org.opends.server.core.DirectoryServer; import org.opends.server.types.*; import org.opends.server.util.StaticUtils; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import com.sleepycat.je.DatabaseEntry; import com.sleepycat.je.DatabaseException; import com.sleepycat.je.LockMode; import com.sleepycat.je.OperationStatus; import com.sleepycat.je.Transaction; @SuppressWarnings("javadoc") public class TestVerifyJob extends JebTestCase { private static final String EQUALITY_CASE_IGNORE = EMR_CASE_IGNORE_NAME; private static final String EQUALITY_TELEPHONE = EMR_TELEPHONE_NAME; private static final String ORDERING_CASE_IGNORE = OMR_CASE_IGNORE_NAME; private static final String SUBSTRING_CASE_IGNORE_IA5 = SMR_CASE_IGNORE_IA5_NAME; /** Root suffix for verify backend. */ private static String suffix="dc=verify,dc=jeb"; private static String vBranch="ou=verify tests," + suffix; private String backendID = "verifyRoot"; private String numUsersLine="define numusers= #numEntries#"; private DN[] baseDNs; private Backend backend; private EntryContainer eContainer; private DN2ID dn2id; private ID2Entry id2entry; private Index id2child; private Index id2subtree; private Transaction txn; /** Some DNs needed mostly for DN2ID tests. */ private String junkDN="cn=junk," + vBranch; private String junkDN1="cn=junk1," + vBranch; private String junkDN2="cn=junk2," + vBranch; private String junkDN3="cn=junk3," + vBranch; /** This DN has no parent. */ private String noParentDN="cn=junk1,cn=junk22," + vBranch; /** Parent child combo for id2child/subtree type tests. */ private String pDN="cn=junk222," + vBranch; private String cDN="cn=junk4,cn=junk222," + vBranch; /** Bad DN. */ private String badDN="this is a bad DN"; /** This index file should not exist. */ private String badIndexName="badIndexName"; @DataProvider(name = "indexes") public Object[][] indexes() { return new Object[][] { { "telephoneNumber"}, {"givenName"}, { "id2subtree"}, {"id2children"}, {"dn2id"} }; } private static String[] template = new String[] { "define suffix="+suffix, "define maildomain=example.com", "define numusers= #numEntries#", "", "branch: [suffix]", "", "branch: " + vBranch, "subordinateTemplate: person:[numusers]", "", "template: person", "rdnAttr: uid", "objectClass: top", "objectClass: person", "objectClass: organizationalPerson", "objectClass: inetOrgPerson", "givenName: ABOVE LIMIT", "sn: ", "cn: {givenName} {sn}", "initials: {givenName:1}{sn:1}", "employeeNumber: ", "uid: user.{employeeNumber}", "mail: {uid}@[maildomain]", "userPassword: password", "telephoneNumber: ", "homePhone: ", "pager: ", "mobile: ", "street: Street", "l: ", "st: ", "postalCode: ", "postalAddress: {cn}${street}${l}, {st} {postalCode}", "description: This is the description for {cn}.", ""}; @BeforeClass public void setup() throws Exception { TestCaseUtils.startServer(); TestCaseUtils.enableBackend(backendID); baseDNs = new DN[] { DN.valueOf(suffix) }; } @AfterClass public void cleanUp() throws Exception { TestCaseUtils.clearJEBackend(backendID); TestCaseUtils.disableBackend(backendID); } /** * Performs a complete verify against a backend using the entries loaded in * the setup initializer. * * @throws Exception * if error count is not equal to 0. */ @Test public void testCompleteVerifyJob() throws Exception { cleanAndLoad(9); VerifyConfig verifyConfig = new VerifyConfig(); verifyConfig.setBaseDN(baseDNs[0]); backend = DirectoryServer.getBackend(backendID); assertEquals(backend.verifyBackend(verifyConfig), 0); } /** * Adds more than "entry limit" number of entries and runs clean * verify against two indexes. * * @throws Exception if error count is not equal to 0. */ @Test public void testEntryLimitVerifyJob() throws Exception { cleanAndLoad(25); VerifyConfig verifyConfig = new VerifyConfig(); verifyConfig.setBaseDN(baseDNs[0]); verifyConfig.addCleanIndex("telephoneNumber"); verifyConfig.addCleanIndex("givenName"); backend = DirectoryServer.getBackend(backendID); assertEquals(backend.verifyBackend(verifyConfig), 0); } /** * Runs clean verify jobs against a set of indexes (defined in * indexes array). * @param index An element of the indexes array. * @throws Exception if the error count is not equal to 0. */ @Test(dataProvider = "indexes") public void testCleanVerifyJob(String index) throws Exception { cleanAndLoad(9); VerifyConfig verifyConfig = new VerifyConfig(); verifyConfig.setBaseDN(baseDNs[0]); verifyConfig.addCleanIndex(index); backend = DirectoryServer.getBackend(backendID); assertEquals(backend.verifyBackend(verifyConfig), 0); } /* * Begin Clean index tests. These are tests that cursor through an index * file and validate it's keys and idlists against the id2entry database entries. * The complete index tests go the other way. They cursor the id2entry database * and validate each entry against the various index files. */ /** * Runs clean verify against the dn2id index after adding * various errors in that index file. * * @throws Exception if the error count is not equal to 5. */ @Test public void testCleanDN2ID() throws Exception { preTest(3); eContainer.sharedLock.lock(); try { //Add a junk DN and non-existent entry id to DN2ID index DN testDN=DN.valueOf(junkDN); EntryID id=new EntryID(45); assertTrue(dn2id.insert(txn, testDN, id)); //Make two DN keys point at same entry. testDN=DN.valueOf(junkDN1); id=new EntryID(3); assertTrue(dn2id.insert(txn, testDN, id)); //Add badDN key with bad entry id DatabaseEntry key = new DatabaseEntry(StaticUtils.getBytes(badDN)); DatabaseEntry data = new EntryID(37).getDatabaseEntry(); assertEquals(dn2id.put(txn, key, data), OperationStatus.SUCCESS); //Add DN key with malformed entryID key=new DatabaseEntry(StaticUtils.getBytes(junkDN2)); data= new DatabaseEntry(new byte[3]); assertEquals(dn2id.put(txn, key, data), OperationStatus.SUCCESS); //Try to break JebFormat version addID2EntryReturnKey(junkDN3, 20, true); id=new EntryID(20); assertTrue(dn2id.insert(txn, DN.valueOf(junkDN3), id)); performBECleanVerify("dn2id", 5); } finally { eContainer.sharedLock.unlock(); } } /** * Runs clean verify against the id2children index after adding * various errors in that index file. * * @throws Exception if the error count is not equal to 6. */ @Test public void testCleanID2Children() throws Exception { preTest(3); eContainer.sharedLock.lock(); try { //Add malformed key byte[] shortBytes = new byte[3]; DatabaseEntry key= new DatabaseEntry(shortBytes); EntryIDSet idSet=new EntryIDSet(); id2child.writeKey(txn, key, idSet); //Try to break JebFormat version of key entry key=addID2EntryReturnKey(junkDN, 4, true); idSet=new EntryIDSet(new byte[16], new byte[16]); id2child.writeKey(txn, key, idSet); //put invalid key -- no EntryID matches key= new EntryID(45).getDatabaseEntry(); id2child.writeKey(txn, key, idSet); //invalid ids in id list key=addID2EntryReturnKey(junkDN1, 5, false); byte[] idBytes=new byte[24]; //doesn't exist idBytes[3] = (byte)0xff; //not a child idBytes[15] = (byte)1; //bad jeb format idBytes[23] = (byte) 0x04; idSet = new EntryIDSet(null, idBytes); id2child.writeKey(txn, key, idSet); performBECleanVerify("id2children", 6); } finally { eContainer.sharedLock.unlock(); } } /** * Runs clean verify against the id2subtree index after adding * various errors in that index file. * * @throws Exception if the error count is not equal to 7. */ @Test public void testCleanID2Subtree() throws Exception { preTest(4); eContainer.sharedLock.lock(); try { //break key byte[] shortBytes = new byte[3]; DatabaseEntry key= new DatabaseEntry(shortBytes); EntryIDSet idSet=new EntryIDSet(); id2subtree.writeKey(txn, key, idSet); //put invalid ids into entry 3 idlist key= new EntryID(3).getDatabaseEntry(); byte[] idBytes=new byte[16]; //invalid id idBytes[3] = (byte)0xff; //non-subordinate idBytes[15] = (byte)1; idSet = new EntryIDSet(null, idBytes); id2subtree.writeKey(txn, key, idSet); //Try to break JebFormat version of key entry key=addID2EntryReturnKey(junkDN, 4, true); idBytes[3]=(byte) 0x04; idBytes[15]=(byte)0x00; EntryIDSet idSet1 = new EntryIDSet(null, idBytes); id2subtree.writeKey(txn, key, idSet1); //put invalid key -- no EntryID matches key= new EntryID(45).getDatabaseEntry(); idSet = new EntryIDSet(null, idBytes); id2subtree.writeKey(txn, key, idSet); performBECleanVerify("id2subtree", 7); } finally { eContainer.sharedLock.unlock(); } } /** * Runs clean verify against the telephoneNumber.equality index * after adding various errors in that index file. * * @throws Exception if the error count is not equal to 4. */ @Test public void testCleanAttrIndex() throws Exception { String phoneType="telephonenumber"; preTest(3); eContainer.sharedLock.lock(); try { AttributeType attributeType = DirectoryServer.getAttributeType(phoneType); Index index = eContainer.getAttributeIndex(attributeType).getIndex(EQUALITY_TELEPHONE); //Add entry with bad JEB format Version addID2EntryReturnKey(junkDN, 4, true); //Add phone number with various bad id list entryIDs byte[] subBytes = StaticUtils.getBytes("0009999999"); DatabaseEntry key= new DatabaseEntry(subBytes); byte[] dataBytes=new byte[32]; //put duplicate ids in list dataBytes[7] = (byte)1; dataBytes[15] = (byte)1; //put id that doesn't exist dataBytes[23] = (byte)0xff; //point to bad entry added above dataBytes[31] = (byte) 0x04; DatabaseEntry data= new DatabaseEntry(dataBytes); OperationStatus status = index.put(txn, key, data); assertEquals(status, OperationStatus.SUCCESS); //really 5 errors, but duplicate reference doesn't increment error //count for some reason performBECleanVerify(phoneType, 4); } finally { eContainer.sharedLock.unlock(); } } /** * Runs clean verify against the testvlvindex VLV index * after adding various errors to each of these index files. * @throws Exception if the error count is not equal to 6. */ @Test public void testCleanVLV() throws Exception { String indexName = "testvlvindex"; preTest(4); eContainer.sharedLock.lock(); try { VLVIndex vlvIndex = eContainer.getVLVIndex(indexName); AttributeType[] types = vlvIndex.getSortTypes(); // Add an incorrectly ordered values. SortValuesSet svs = vlvIndex.getSortValuesSet(null, 0, new ByteString[3], new AttributeType[3]); long id = svs.getEntryIDs()[0]; Entry entry = eContainer.getID2Entry().get(null, new EntryID(id), LockMode.DEFAULT); SortValuesSet svs2 = svs.split(2); svs2.add(id, vlvIndex.getSortValues(entry), types); // Add an invalid ID svs2.add(1000, vlvIndex.getSortValues(entry), types); // Muck up the values of another ID id = svs.getEntryIDs()[0]; entry = eContainer.getID2Entry().get(null, new EntryID(id), LockMode.DEFAULT); ByteString[] values = vlvIndex.getSortValues(entry); ByteString[] badValues = new ByteString[values.length]; System.arraycopy(values, 1, badValues, 0, values.length - 1); badValues[badValues.length-1] = values[0]; remove(svs, id, values); svs.add(id, badValues, types); putSortValuesSet(vlvIndex, svs); putSortValuesSet(vlvIndex, svs2); performBECleanVerify("vlv." + indexName, 3); } finally { eContainer.sharedLock.unlock(); } } /* * Begin complete verify index tests. As described above, these are * tests that cursor through the id2entry database and validate * each entry against the various index files. * */ /** * Runs complete verify against the telephoneNumber index * after adding various errors in the id2entry file. * * @throws Exception if the error count is not equal to 3. */ @Test public void testVerifyID2Entry() throws Exception { preTest(3); eContainer.sharedLock.lock(); try { //Add entry with short id byte[] shortBytes = new byte[3]; DatabaseEntry key= new DatabaseEntry(shortBytes); Entry testEntry = buildEntry(junkDN); DataConfig dataConfig = new DataConfig(false, false, null); ByteString entryBytes = ID2Entry.entryToDatabase(testEntry, dataConfig); DatabaseEntry data= new DatabaseEntry(entryBytes.toByteArray()); assertEquals(id2entry.put(txn, key, data), OperationStatus.SUCCESS); // add entry with random bytes DatabaseEntry key1= new EntryID(4).getDatabaseEntry(); byte []eBytes = new byte[459]; for(int i=0;i<459;i++) { eBytes[i]=(byte) (i*2); } //set version correctly eBytes[0]=0x01; DatabaseEntry data1= new DatabaseEntry(eBytes); assertEquals(id2entry.put(txn, key1, data1), OperationStatus.SUCCESS); performBECompleteVerify("telephoneNumber", 3); } finally { eContainer.sharedLock.unlock(); } } /** * * Runs complete verify against the dn2id index * after adding various errors in the dn2id file. * * @throws Exception if the error count is not equal to 3. */ @Test public void testVerifyDN2ID() throws Exception { preTest(9); eContainer.sharedLock.lock(); try { //add entry but no corresponding dn2id key addID2EntryReturnKey(junkDN, 10, false); //entry has dn2id key but its entryID -- don't need key addID2EntryReturnKey(junkDN1, 11, false); //insert key with bad entry id (45 instead of 10) DN testDN=DN.valueOf(junkDN1); EntryID id=new EntryID(45); assertTrue(dn2id.insert(txn, testDN, id)); //entry has no parent in dn2id addID2EntryReturnKey(noParentDN, 12, false); //add the key/id testDN=DN.valueOf(noParentDN); id=new EntryID(12); assertTrue(dn2id.insert(txn, testDN, id)); performBECompleteVerify("dn2id", 3); } finally { eContainer.sharedLock.unlock(); } } /** * * Runs complete verify against the id2children index * after adding various errors in the id2children file. * * @throws Exception if the error count is not equal to 3. */ @Test public void testVerifyID2Children() throws Exception { preTest(9); eContainer.sharedLock.lock(); try { //Add dn with no parent DatabaseEntry key=addID2EntryReturnKey(noParentDN, 10, false); byte[] idBytes=new byte[16]; idBytes[7]=(byte) 0x0A; EntryIDSet idSet = new EntryIDSet(null, idBytes); id2child.writeKey(txn, key, idSet); //Add child entry - don't worry about key addID2EntryReturnKey(cDN, 11, false); //Add its parent entry -- need the key DatabaseEntry keyp=addID2EntryReturnKey(pDN, 12, false); //add parent key/IDSet with bad IDset id byte[] idBytesp=new byte[16]; idBytesp[7]=(byte) 0xFF; EntryIDSet idSetp = new EntryIDSet(null, idBytesp); id2child.writeKey(txn, keyp, idSetp); performBECompleteVerify("id2children", 3); } finally { eContainer.sharedLock.unlock(); } } /** * * Runs complete verify against the id2children index * after adding various errors in the id2children file. * This is a second test because the key needed to have * null idlist. This test is really just for coverage and * should have a 0 error count. * * @throws Exception if the error count is not equal to 0. */ @Test public void testVerifyID2Children1() throws Exception { preTest(2); eContainer.sharedLock.lock(); try { //Add child entry - don't worry about key addID2EntryReturnKey(pDN, 10, false); //add parent key/IDSet with null keyset EntryIDSet idSetp=new EntryIDSet(); DatabaseEntry key= new EntryID(2).getDatabaseEntry(); id2child.writeKey(txn, key, idSetp); performBECompleteVerify("id2children", 0); } finally { eContainer.sharedLock.unlock(); } } /** * * Runs complete verify against the id2subtree index * after adding various errors in the id2subtree file. * * @throws Exception if the error count is not equal to 3. */ @Test public void testVerifyID2Subtree() throws Exception { preTest(2); eContainer.sharedLock.lock(); try { //Add entry with no parent addID2EntryReturnKey(noParentDN, 3, false); performBECompleteVerify("id2subtree", 3); } finally { eContainer.sharedLock.unlock(); } } /** * * Runs complete verify against the id2subtree index * after adding various errors in the id2subtree file. * This is a second test because the key needed to have * null idlist. * * @throws Exception if the error count is not equal to 1. */ @Test public void testVerifyID2Subtree1() throws Exception { preTest(2); eContainer.sharedLock.lock(); try { //Add child entry - don't worry about key addID2EntryReturnKey(pDN, 3, false); //add parent key/IDSet with null keyset EntryIDSet idSet=new EntryIDSet(); DatabaseEntry key= new EntryID(2).getDatabaseEntry(); id2subtree.writeKey(txn, key, idSet); performBECompleteVerify("id2subtree", 1); } finally { eContainer.sharedLock.unlock(); } } /** * Runs complete verify against the mail indexes * (equality, presence, substring, ordering) * after adding various errors to each of these index files. * @throws Exception if the error count is not equal to 6. */ @Test public void testVerifyAttribute() throws Exception { String mailType="mail"; preTest(4); eContainer.sharedLock.lock(); try { AttributeType attributeType = DirectoryServer.getAttributeType(mailType); //Get db handles to each index. AttributeIndex attributeIndex = eContainer.getAttributeIndex(attributeType); Index eqIndex = attributeIndex.getIndex(EQUALITY_CASE_IGNORE); Index presIndex = attributeIndex.getIndex("presence"); Index subIndex = attributeIndex.getIndex(SUBSTRING_CASE_IGNORE_IA5 + ":6"); // Ordering is processed by equality since OPENDJ-1864 assertNull(attributeIndex.getIndex(ORDERING_CASE_IGNORE)); //Add invalid idlist ids to both equality and ordering indexes. DatabaseEntry key= new DatabaseEntry(StaticUtils.getBytes("user.0@example.com")); byte[] dataBytes=new byte[16]; //put duplicate ids in list dataBytes[7] = (byte)0xff; dataBytes[15] = (byte)0xfe; DatabaseEntry data= new DatabaseEntry(dataBytes); OperationStatus status = eqIndex.put(txn, key, data); assertEquals(status, OperationStatus.SUCCESS); //Add null idlist to equality index. key = new DatabaseEntry(StaticUtils.getBytes("user.1@example.com")); data= new DatabaseEntry(new EntryIDSet().toDatabase()); status = eqIndex.put(txn, key, data); assertEquals(status, OperationStatus.SUCCESS); //Add invalid idlist ids to presence index. key = new DatabaseEntry(StaticUtils.getBytes("+")); data = new DatabaseEntry(dataBytes); status = presIndex.put(txn, key, data); assertEquals(status, OperationStatus.SUCCESS); //Add invalid idlist ids to substring index. key = new DatabaseEntry(StaticUtils.getBytes("@examp")); data = new DatabaseEntry(dataBytes); status = subIndex.put(txn, key, data); assertEquals(status, OperationStatus.SUCCESS); performBECompleteVerify(mailType, 5); } finally { eContainer.sharedLock.unlock(); } } /** * Runs complete verify against the testvlvindex VLV index * after adding various errors to each of these index files. * @throws Exception if the error count is not equal to 6. */ @Test public void testVerifyVLV() throws Exception { String indexName = "testvlvindex"; preTest(4); eContainer.sharedLock.lock(); try { VLVIndex vlvIndex = eContainer.getVLVIndex(indexName); AttributeType[] types = vlvIndex.getSortTypes(); // Remove an ID SortValuesSet svs = vlvIndex.getSortValuesSet(null, 0, new ByteString[3], types); long id = svs.getEntryIDs()[0]; Entry entry = eContainer.getID2Entry().get(null, new EntryID(id), LockMode.DEFAULT); remove(svs, id, vlvIndex.getSortValues(entry)); // Add an incorrectly ordered values. SortValuesSet svs2 = svs.split(2); svs2.add(1000, vlvIndex.getSortValues(entry), types); // Muck up the values of another ID id = svs.getEntryIDs()[0]; entry = eContainer.getID2Entry().get(null, new EntryID(id), LockMode.DEFAULT); ByteString[] values = vlvIndex.getSortValues(entry); ByteString[] badValues = new ByteString[values.length]; System.arraycopy(values, 1, badValues, 0, values.length - 1); badValues[badValues.length-1] = values[0]; remove(svs, id, values); svs.add(id, badValues, types); putSortValuesSet(vlvIndex, svs); putSortValuesSet(vlvIndex, svs2); performBECompleteVerify("vlv." + indexName, 3); } finally { eContainer.sharedLock.unlock(); } } private void remove(SortValuesSet svs, long id, ByteString[] values) throws DirectoryException { svs.remove(new SortValues(new EntryID(id), values, new SortOrder())); } /** * Put a sort values set in this VLV index. * * @param txn * The transaction to use when retrieving the set or NULL if it is * not required. * @param sortValuesSet * The SortValuesSet to put. * @return True if the sortValuesSet was put successfully or False otherwise. * @throws JebException * If an error occurs during an operation on a JE database. * @throws DatabaseException * If an error occurs during an operation on a JE database. * @throws DirectoryException * If a Directory Server error occurs. */ private void putSortValuesSet(VLVIndex vlvIndex, SortValuesSet sortValuesSet) throws JebException, DirectoryException { DatabaseEntry key = new DatabaseEntry(sortValuesSet.getKeyBytes()); DatabaseEntry data = new DatabaseEntry(sortValuesSet.toDatabase()); vlvIndex.put(null, key, data); } /* Various tests not either clean or complete */ /** * Try to verify a non-indexed attribute. * @throws Exception if error count is not equal to 0. */ @Test(expectedExceptions=Exception.class) public void testVerifyNotIndexed() throws Exception { cleanAndLoad(2); VerifyConfig verifyConfig = new VerifyConfig(); verifyConfig.setBaseDN(baseDNs[0]); verifyConfig.addCleanIndex("userPassword"); backend = DirectoryServer.getBackend(backendID); assertEquals(backend.verifyBackend(verifyConfig), 0); } /** * Try to verify an nonexistent attribute. * @throws Exception if verify backend fails. */ @Test(expectedExceptions=Exception.class) public void testInvalidIndex() throws Exception { cleanAndLoad(2); VerifyConfig verifyConfig = new VerifyConfig(); verifyConfig.setBaseDN(baseDNs[0]); verifyConfig.addCleanIndex(badIndexName); backend = DirectoryServer.getBackend(backendID); backend.verifyBackend(verifyConfig); } /* end tests */ /** * Adds an entry to the id2entry database with a dn and id passed into the * method. Optional flag to set the Jeb version byte for those types of tests. * @param dn the dn string to put in the entry. * @param id to use as the id2entry key, * @param trashFormat true if first byte should be changed to invalid value. * @return Database entry key of the entry. * @throws Exception if the entry is not added to the id2entry database. */ private DatabaseEntry addID2EntryReturnKey(String dn, long id, boolean trashFormat) throws Exception { DatabaseEntry key= new EntryID(id).getDatabaseEntry(); Entry testEntry = buildEntry(dn); DataConfig dataConfig = new DataConfig(false, false, null); byte []entryBytes = ID2Entry.entryToDatabase(testEntry, dataConfig).toByteArray(); if(trashFormat) { entryBytes[0] = 0x67; } DatabaseEntry data= new DatabaseEntry(entryBytes); assertEquals(id2entry.put(txn, key, data), OperationStatus.SUCCESS); return key; } /** * Wrapper to do a clean verify. * @param indexToDo index file to run verify against. * @param expectedErrors number of errors expected for this test. * @throws Exception if the verify fails. */ private void performBECleanVerify(String indexToDo, int expectedErrors) throws Exception { performBEVerify(indexToDo, expectedErrors, true); } /** * Wrapper to do a complete verify. * @param indexToDo index file to run verify against. * @param expectedErrors number of errors expected for this test. * @throws Exception if the verify fails. */ private void performBECompleteVerify(String indexToDo, int expectedErrors) throws Exception { performBEVerify(indexToDo, expectedErrors, false); } /** * Performs either a clean or complete verify depending on * flag passed in. * * @param indexToDo index file to run verify against. * @param expectedErrors number of errors expected for this test. * @param clean do clean verify if true. * @throws Exception if the verify fails. */ private void performBEVerify(String indexToDo, int expectedErrors, boolean clean) throws Exception { EntryContainer.transactionCommit(txn); VerifyConfig verifyConfig = new VerifyConfig(); verifyConfig.setBaseDN(baseDNs[0]); if(!clean) { verifyConfig.addCompleteIndex(indexToDo); } else { verifyConfig.addCleanIndex(indexToDo); } assertEquals(backend.verifyBackend(verifyConfig), expectedErrors); } /** * Does a pretest setup. Creates some number of entries, gets * backend, rootcontainer, entryContainer objects, as well as * various index objects. * Also starts a transaction. * @param numEntries number of entries to add to the verify backend. * @throws Exception if entries cannot be loaded. */ private void preTest(int numEntries) throws Exception { cleanAndLoad(numEntries); backend = DirectoryServer.getBackend(backendID); RootContainer rContainer = ((BackendImpl) backend).getRootContainer(); eContainer= rContainer.getEntryContainer(DN.valueOf(suffix)); id2child=eContainer.getID2Children(); id2entry=eContainer.getID2Entry(); id2subtree=eContainer.getID2Subtree(); dn2id=eContainer.getDN2ID(); txn = eContainer.beginTransaction(); } /** * Cleans verify backend and loads some number of entries. * @param numEntries number of entries to load into the backend. * @throws Exception if the entries are not loaded or created. */ private void cleanAndLoad(int numEntries) throws Exception { TestCaseUtils.clearJEBackend(backendID); template[2]=numUsersLine; template[2]= template[2].replaceAll("#numEntries#", String.valueOf(numEntries)); createLoadEntries(template, numEntries); } /** * Builds an entry. * * @param dn to put into the entry. * @return a new entry. * @throws DirectoryException if the entry cannot be created. */ private Entry buildEntry(String dn) throws DirectoryException { DN entryDN = DN.valueOf(dn); HashMap ocs = new HashMap<>(2); ObjectClass topOC = DirectoryServer.getObjectClass(OC_TOP); if (topOC == null) { topOC = DirectoryServer.getDefaultObjectClass(OC_TOP); } ocs.put(topOC, OC_TOP); ObjectClass extensibleObjectOC = DirectoryServer .getObjectClass(OC_EXTENSIBLE_OBJECT); if (extensibleObjectOC == null) { extensibleObjectOC = DirectoryServer .getDefaultObjectClass(OC_EXTENSIBLE_OBJECT); } ocs.put(extensibleObjectOC, OC_EXTENSIBLE_OBJECT); return new Entry(entryDN, ocs, new LinkedHashMap>(0), new HashMap>(0)); } }