TestVerifyJob.java revision 8ac57ee1cd50fcc3d02b36bea4ab1335924f1d7a
/*
* 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: <last>",
"cn: {givenName} {sn}",
"initials: {givenName:1}<random:chars:" +
"ABCDEFGHIJKLMNOPQRSTUVWXYZ:1>{sn:1}",
"employeeNumber: <sequential:0>",
"uid: user.{employeeNumber}",
"mail: {uid}@[maildomain]",
"userPassword: password",
"telephoneNumber: <random:telephone>",
"homePhone: <random:telephone>",
"pager: <random:telephone>",
"mobile: <random:telephone>",
"street: <random:numeric:5> <file:streets> Street",
"l: <file:cities>",
"st: <file:states>",
"postalCode: <random:numeric:5>",
"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<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));
}
}