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