From cefda5c4f4605b8768d75b226d2471f2eab8f99a Mon Sep 17 00:00:00 2001
From: dugan <dugan@localhost>
Date: Mon, 23 Oct 2006 02:48:31 +0000
Subject: [PATCH] Add new TestVerifyJob unit tests that adds deliberate errors to various index files and examines the stat entry passed into the verifyBackend to see if all of the errors are caught. Tests perform both complete index checking and clean index checking.

---
 opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestVerifyJob.java |  715 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 672 insertions(+), 43 deletions(-)

diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestVerifyJob.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestVerifyJob.java
index 058f7cf..b2540c0 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestVerifyJob.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestVerifyJob.java
@@ -29,25 +29,68 @@
 import org.opends.server.config.ConfigEntry;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.TestCaseUtils;
-import org.opends.server.types.DN;
+import org.opends.server.types.*;
+import org.opends.server.util.StaticUtils;
+
+import static org.opends.server.util.ServerConstants.OC_TOP;
+import static org.opends.server.util.ServerConstants.OC_EXTENSIBLE_OBJECT;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+import com.sleepycat.je.Database;
+import com.sleepycat.je.DatabaseConfig;
+import com.sleepycat.je.DatabaseEntry;
+import com.sleepycat.je.OperationStatus;
+import com.sleepycat.je.Transaction;
+
+import java.util.*;
 
 public class TestVerifyJob extends JebTestCase
 {
-    private static String cfgDN="ds-cfg-backend-id=userRoot,cn=Backends,cn=config";
-    /* number of entries to test with */
-    private static int numEntries=10;
-    private static String vBranch = "ou=verify";
-    private static String suffix="dc=example,dc=com";
-    private static String beID="userRoot";
-    
+	private  String cfgDN=
+		"ds-cfg-backend-id=verifyRoot,cn=Backends,cn=config";
+	//Root suffix for verify backend
+	private static String suffix="dc=verify,dc=jeb";
+	private static  String vBranch="ou=verify tests," + suffix;
+	private  String beID="verifyRoot";
+	private  String numUsersLine="define numusers= #numEntries#";
+	//Attribute type in stat entry containing error count
+	private  String errorCount="verify-error-count";
+	private  DN configDN;
+	private  DN[] baseDNs;
+	private ConfigEntry configEntry;
+	private BackendImpl be;
+	private RootContainer rContainer;
+	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"}
@@ -57,11 +100,11 @@
     private static String[] template = new String[] {
         "define suffix="+suffix,
         "define maildomain=example.com",
-        "define numusers=" + numEntries,
+        "define numusers= #numEntries#",
         "",
         "branch: [suffix]",
         "",
-       "branch: " + vBranch +",[suffix]",
+        "branch: " + vBranch,
         "subordinateTemplate: person:[numusers]",
         "",
         "template: person",
@@ -70,7 +113,7 @@
         "objectClass: person",
         "objectClass: organizationalPerson",
         "objectClass: inetOrgPerson",
-        "givenName: <first>",
+        "givenName: ABOVE LIMIT",
         "sn: <last>",
         "cn: {givenName} {sn}",
         "initials: {givenName:1}<random:chars:" +
@@ -90,55 +133,641 @@
         "postalAddress: {cn}${street}${l}, {st}  {postalCode}",
         "description: This is the description for {cn}.",
         ""};
-    
+
     @BeforeClass
     public void setup() throws Exception {
       TestCaseUtils.startServer();
-      createLoadEntries(template, numEntries);
+      configDN = DN.decode(cfgDN);
+      baseDNs = new DN[] {
+              DN.decode(suffix)
+      };
+      configEntry = DirectoryServer.getConfigEntry(configDN);
     }
     
     @AfterClass
     public void cleanUp() throws Exception {
-        removeLoadedEntries();
+    	TestCaseUtils.clearJEBackend(false, beID, suffix);
     }
     
     /**
-     * Performs a non-clean verify against a backend using the
+     * Performs a ncomplete verify against a backend using the
      * entries loaded in the setup initializer.
      * 
-     * @throws Exception if the verify fails.
+     * @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]);
+    	Entry statEntry=bldStatEntry("");
+    	be=(BackendImpl) DirectoryServer.getBackend(beID);
+    	be.verifyBackend(verifyConfig, configEntry, baseDNs, statEntry);
+    	assertEquals(getStatEntryCount(statEntry, errorCount), 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 testVerifyJob()  throws Exception {
-        DN configDN= DN.decode(cfgDN);
-        DN[] baseDNs = new DN[] {
-                DN.decode(suffix)
-        };
-        VerifyConfig verifyConfig = new VerifyConfig();
-        verifyConfig.setBaseDN(baseDNs[0]);
-        ConfigEntry configEntry = DirectoryServer.getConfigEntry(configDN);
-        BackendImpl be=(BackendImpl) DirectoryServer.getBackend(beID);
-        be.verifyBackend(verifyConfig, configEntry, baseDNs, null);
+    public void testEntryLimitVerifyJob()  throws Exception {
+    	cleanAndLoad(25);
+    	VerifyConfig verifyConfig = new VerifyConfig();
+    	verifyConfig.setBaseDN(baseDNs[0]);
+    	verifyConfig.addCleanIndex("telephoneNumber");
+    	verifyConfig.addCleanIndex("givenName");
+    	Entry statEntry=bldStatEntry("");
+    	be=(BackendImpl) DirectoryServer.getBackend(beID);
+    	be.verifyBackend(verifyConfig, configEntry, baseDNs, statEntry);
+    	assertEquals(getStatEntryCount(statEntry, errorCount), 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);
+    	Entry statEntry=bldStatEntry("");
+    	be=(BackendImpl) DirectoryServer.getBackend(beID);
+    	be.verifyBackend(verifyConfig, configEntry, baseDNs, statEntry);
+    	assertEquals(getStatEntryCount(statEntry, errorCount), 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);
+    	//Add a junk DN and non-existent entry id to DN2ID index
+    	DN testDN=DN.decode(junkDN);
+    	EntryID id=new EntryID(45);      
+    	assertTrue(dn2id.insert(txn, testDN, id));
+    	//Make two DN keys point at same entry.
+    	testDN=DN.decode(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();  
+    	assertTrue(dn2id.putRaw(txn, key, data));
+    	//Add DN key with malformed entryID
+    	key=new DatabaseEntry(StaticUtils.getBytes(junkDN2));
+    	data= new DatabaseEntry(new byte[3]);
+    	assertTrue(dn2id.putRaw(txn, key, data));
+    	//Try to break JebFormat version
+    	addID2EntryReturnKey(junkDN3, 20, true);
+    	id=new EntryID(20);
+    	assertTrue(dn2id.insert(txn, DN.decode(junkDN3), id));
+    	performBECleanVerify("dn2id", 5); 
+    }
+
+    /**
+     * 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);
+    	//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);
+    }
+
+    /**
+     * 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);
+    	//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);
+    }
+
+    /**
+     * 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);  	
+    	//Need to open a second database against this index
+    	//so we can manipulate it. We can't get the index DB handle
+    	//any other way.
+    	DatabaseConfig config = new DatabaseConfig();
+        config.setAllowCreate(true);
+        config.setTransactional(true);
+        Database db=
+        	eContainer.openDatabase(config, phoneType + ".equality");
+		//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 = EntryContainer.put(db, txn, key, data);
+		assertTrue(status == OperationStatus.SUCCESS);	
+       	//really 5 errors, but duplicate reference doesn't increment error
+    	//count for some reason
+    	performBECleanVerify(phoneType, 4);
+    }
+   
+    /*
+     * 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);    	
+    	//Add entry with short id
+       	byte[] shortBytes = new byte[3];
+    	DatabaseEntry key= new DatabaseEntry(shortBytes);
+    	Entry testEntry=bldStatEntry(junkDN);
+    	byte []entryBytes = 
+    		JebFormat.entryToDatabase(testEntry, new DataConfig());
+    	DatabaseEntry data= new DatabaseEntry(entryBytes);
+    	assertTrue(id2entry.putRaw(txn, key, data));
+ 
+    	//add entry with ramdom 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);
+    	assertTrue(id2entry.putRaw(txn, key1, data1));
+    	performBECompleteVerify("telephoneNumber", 3);
+    }
+    
+    /**
+     * Change the stored count to invalid value in the telephoneNumber
+     * index.
+     * @throws Exception if the error count is not equal 1.
+     */
+    @Test() public void testBadStoredCount() throws Exception {
+    	preTest(2);
+    	//whack the count
+    	setStoredCount(100);
+    	performBECompleteVerify("telephoneNumber", 1);
+    }
+
+    /**
+     * 
+     * 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);
+    	//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.decode(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.decode(noParentDN);
+    	id=new EntryID(12);      
+    	assertTrue(dn2id.insert(txn, testDN, id));
+    	setStoredCount(12);
+    	performBECompleteVerify("dn2id", 3);
+    }
+    
+    /**
+     * 
+     * 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);
+    	//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);   	
+    	setStoredCount(12);  	
+    	performBECompleteVerify("id2children", 3);
+    }
+    
+    /**
+     * 
+     * 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);
+    	//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);
+    	setStoredCount(3);  	
+    	performBECompleteVerify("id2children", 0);
+    }
+  
+    /**
+     * 
+     * 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);
+    	//Add entry with no parent
+    	addID2EntryReturnKey(noParentDN, 3, false);  	
+    	setStoredCount(3);
+    	performBECompleteVerify("id2subtree", 3);
+    }
+  
+    /**
+     * 
+     * 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);
+       	//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);
+    	setStoredCount(3);
+    	performBECompleteVerify("id2subtree", 1);
+    }
+
+    /**
+     * 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);  	
+    	//Need to open a second databases against this index
+    	//so we can manipulate it. 
+    	DatabaseConfig config = new DatabaseConfig();
+        config.setAllowCreate(true);
+        config.setTransactional(true);
+        //Get db handles to each index.
+        Database dbEq=
+        	eContainer.openDatabase(config, mailType + ".equality");
+        Database dbPres=
+        	eContainer.openDatabase(config, mailType + ".presence");
+        Database dbSub=
+        	eContainer.openDatabase(config, mailType + ".substring");
+        Database dbOr=
+        	eContainer.openDatabase(config, mailType + ".ordering");
+        //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 = EntryContainer.put(dbEq, txn, key, data);
+		assertTrue(status == OperationStatus.SUCCESS);	
+	   	status = EntryContainer.put(dbOr, txn, key, data);
+		assertTrue(status == OperationStatus.SUCCESS);
+	    //Add null idlist to both equality and ordering indexes.  
+    	key = 
+    		new DatabaseEntry(StaticUtils.getBytes("user.1@example.com"));
+    	data= new DatabaseEntry(new EntryIDSet().toDatabase());  	
+    	status = EntryContainer.put(dbEq, txn, key, data);
+		assertTrue(status == OperationStatus.SUCCESS);	
+	   	status = EntryContainer.put(dbOr, txn, key, data);
+		assertTrue(status == OperationStatus.SUCCESS);
+		//Add invalid idlist ids to presence index.		
+    	 key = 
+    		new DatabaseEntry(StaticUtils.getBytes("+"));
+    	data = new DatabaseEntry(dataBytes);
+       	status = EntryContainer.put(dbPres, txn, key, data);
+		assertTrue(status == OperationStatus.SUCCESS);	
+	    //Add invalid idlist ids to substring index.
+		key = 
+			new DatabaseEntry(StaticUtils.getBytes("@examp"));
+		data = new DatabaseEntry(dataBytes);
+		status = EntryContainer.put(dbSub, txn, key, data);
+		assertTrue(status == OperationStatus.SUCCESS);	
+		performBECompleteVerify(mailType, 6);
+    }
+
+    /* 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");
+    	Entry statEntry=bldStatEntry("");
+    	be=(BackendImpl) DirectoryServer.getBackend(beID);
+    	be.verifyBackend(verifyConfig, configEntry, baseDNs, statEntry);
+    	assertEquals(getStatEntryCount(statEntry, errorCount), 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);
+    	Entry statEntry=bldStatEntry("");
+    	be=(BackendImpl) DirectoryServer.getBackend(beID);
+    	be.verifyBackend(verifyConfig, configEntry, baseDNs, statEntry);
+    }
+  
+    /* 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=bldStatEntry(dn);
+    	byte []entryBytes = 
+    		JebFormat.entryToDatabase(testEntry, new DataConfig());
+    	if(trashFormat)
+    		entryBytes[0] = 0x67;
+    	DatabaseEntry data= new DatabaseEntry(entryBytes);
+    	assertTrue(id2entry.putRaw(txn, key, data));
+    	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);
+    	Entry statEntry=bldStatEntry("");
+    	be.verifyBackend(verifyConfig, configEntry, baseDNs, statEntry);     
+    	assertEquals(getStatEntryCount(statEntry, errorCount), expectedErrors);
     }
     
     
     /**
-     * Performs a clean verify against a backend using the index
-     * name passed into it from the indexes array above.
-     * @param index Index name to verify.
-     * @throws Exception if the backend index cannot be verified.
+     * Adjust stored entry count in the id2entry file.
+     * @param c new count.
+     * @throws Exception if the putRaw method fails.
      */
-    @Test(dataProvider = "indexes")
-    public void testCleanVerifyJob(String index)  throws Exception {
-        DN configDN= DN.decode(cfgDN);
-        DN[] baseDNs = new DN[] {
-                DN.decode(suffix)
-        };
-        VerifyConfig verifyConfig = new VerifyConfig();
-        verifyConfig.setBaseDN(baseDNs[0]);
-        verifyConfig.addCleanIndex(index);
-        ConfigEntry configEntry = DirectoryServer.getConfigEntry(configDN);
-        BackendImpl be=(BackendImpl) DirectoryServer.getBackend(beID);
-        be.verifyBackend(verifyConfig, configEntry, baseDNs, null);
+    private void setStoredCount(long c) throws Exception {
+    	DatabaseEntry keyS= new EntryID(0).getDatabaseEntry();
+    	DatabaseEntry dataS= new EntryID(c).getDatabaseEntry();
+    	assertTrue(id2entry.putRaw(txn, keyS, dataS));
     }
-}
+ 
+    /**
+     * 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);
+    	be=(BackendImpl) DirectoryServer.getBackend(beID);
+    	rContainer= be.getRootContainer();
+    	eContainer= rContainer.getEntryContainer(DN.decode(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(false, beID, suffix);
+    	template[2]=numUsersLine;
+    	template[2]=
+    		template[2].replaceAll("#numEntries#", String.valueOf(numEntries));
+    	createLoadEntries(template, numEntries);
+    }
+
+    /**
+     * Gets information from the stat entry and returns that value as a Long.
+     * @param e entry to search.
+     * @param type attribute type
+     * @return Long
+     * @throws NumberFormatException if the attribute value cannot be parsed.
+     */
+    private long getStatEntryCount(Entry e, String type) 
+    throws NumberFormatException {
+    	AttributeType attrType =
+    		DirectoryServer.getAttributeType(type);
+    	if (attrType == null)
+    		attrType = DirectoryServer.getDefaultAttributeType(type);
+    	List<Attribute> attrList = e.getAttribute(attrType, null);
+    	LinkedHashSet<AttributeValue> values =
+    		attrList.get(0).getValues();
+    	AttributeValue v = values.iterator().next();
+    	long retVal = Long.parseLong(v.getStringValue());
+    	return (retVal);
+    }
+
+    /**
+     * Builds an entry suitable for using in the verify job to gather statistics about
+     * the verify.
+     * @param dn to put into the entry.
+     * @return a suitable entry.
+     * @throws DirectoryException if the cannot be created.
+     */
+    private Entry bldStatEntry(String dn) throws DirectoryException {
+    	DN entryDN = DN.decode(dn);
+    	HashMap<ObjectClass, String> ocs = new HashMap<ObjectClass, String>(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<AttributeType, List<Attribute>>(0),
+    			new HashMap<AttributeType, List<Attribute>>(0));
+    }
+}
\ No newline at end of file

--
Gitblit v1.10.0