mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

boli
08.35.2006 e0e234ca0ce765eaa531f4bdc641b402077a3dfa
Additional test cases for the JE Backend. 
1 files added
2 files modified
1799 ■■■■■ changed files
opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestBackendImpl.java 1277 ●●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestEntryContainer.java 2 ●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestImportJob.java 520 ●●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestBackendImpl.java
@@ -26,23 +26,37 @@
 */
package org.opends.server.backends.jeb;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.util.*;
import org.opends.server.TestCaseUtils;
import org.opends.server.api.Backend;
import static
    org.opends.server.messages.ConfigMessages.MSGID_CONFIG_BACKEND_ATTR_DESCRIPTION_BASE_DNS;
import static org.opends.server.messages.MessageHandler.getMessage;
import org.opends.server.core.DeleteOperation;
import org.opends.server.core.ModifyOperation;
import org.opends.server.core.ModifyDNOperation;
import org.opends.server.protocols.internal.InternalClientConnection;
import org.opends.server.protocols.internal.InternalSearchOperation;
import org.opends.server.protocols.ldap.LDAPFilter;
import org.opends.server.protocols.ldap.LDAPControl;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.config.ConfigEntry;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
import org.opends.server.types.LDIFImportConfig;
import org.opends.server.config.DNConfigAttribute;
import static org.opends.server.config.ConfigConstants.ATTR_BACKEND_BASE_DN;
import org.opends.server.types.*;
import org.opends.server.util.Base64;
import org.opends.server.util.LDIFReader;
import org.opends.server.util.StaticUtils;
import static
    org.opends.server.util.ServerConstants.OID_SUBTREE_DELETE_CONTROL;
import org.testng.annotations.Test;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.AfterTest;
import org.testng.annotations.AfterClass;
import static org.testng.Assert.*;
import static org.testng.Assert.assertEquals;
import com.sleepycat.je.DatabaseEntry;
/**
 * BackendImpl Tester.
 */
@@ -50,75 +64,1218 @@
  private File tempDir;
  private String homeDirName;
  private static final String ldifString =
    "dn: cn=JE Backend,cn=Backends,cn=config\n"
      + "objectClass: top\n"
      + "objectClass: ds-cfg-backend\n"
      + "objectClass: extensibleObject\n"
      + "cn: JE Backend\n"
      + "ds-cfg-backend-enabled: true\n"
      + "ds-cfg-backend-class: org.opends.server.backends.jeb.BackendImpl\n"
      + "ds-cfg-backend-directory: db\n";
  private DN[] baseDNs;
  private BackendImpl backend;
  private Entry entry;
  private List<Entry> topEntries;
  private List<Entry> entries;
  private List<Entry> additionalEntries;
  private Entry replaceEntry;
  private Entry newTop;
  /**
   * Set up the environment for performing the tests in this suite.
   *
   * @throws Exception
   *           If the environment could not be set up.
   * The attribute used to return a search index debug string to the client.
   */
  public static final String ATTR_DEBUG_SEARCH_INDEX = "debugsearchindex";
  @BeforeClass
  public void setUp() throws Exception {
    // Make sure that the server is up and running.
    // This test suite depends on having the schema available, so we'll make
    // sure the server is started.
    TestCaseUtils.startServer();
    tempDir = TestCaseUtils.createTemporaryDirectory("jebtest");
    tempDir = TestCaseUtils.createTemporaryDirectory("jebimporttest");
    homeDirName = tempDir.getAbsolutePath();
    final String s = ldifString.replaceAll("ds-cfg-backend-directory: db",
        "ds-cfg-backend-directory:: "
            + Base64.encode(homeDirName.getBytes()));
    byte[] bytes = StaticUtils.getBytes(s);
    EnvManager.createHomeDir(homeDirName);
    LDIFReader reader = new LDIFReader(new LDIFImportConfig(
        new ByteArrayInputStream(bytes)));
    Entry configEntry = TestCaseUtils.makeEntry(
        "dn: ds-cfg-backend-id=userRoot,cn=Backends,cn=config",
        "objectClass: top",
        "objectClass: ds-cfg-backend",
        "objectClass: ds-cfg-je-backend",
        "ds-cfg-backend-index-entry-limit: 13",
        "ds-cfg-backend-enabled: true",
        "ds-cfg-backend-class: org.opends.server.backends.jeb.BackendImpl",
        "ds-cfg-backend-id: userRoot",
        "ds-cfg-backend-directory:: " +
            Base64.encode(homeDirName.getBytes()));
    entry = reader.readEntry(false);
    reader.close();
    ConfigEntry backendConfigEntry = new ConfigEntry(configEntry, null);
    Entry indexEntry = TestCaseUtils.makeEntry(
        "dn: cn=Index,ds-cfg-backend-id=userRoot,cn=Backends,cn=config\n" +
            "objectClass: top\n" +
            "objectClass: ds-cfg-branch\n" +
            "cn: Index\n");
    ConfigEntry indexConfigEntry = new ConfigEntry(indexEntry,
        backendConfigEntry);
    backendConfigEntry.addChild(indexConfigEntry);
    List<Entry> indexEntries = TestCaseUtils.makeEntries(
        "dn: ds-cfg-index-attribute=cn,cn=Index,ds-cfg-backend-id=userRoot,cn=Backends,cn=config\n" +
            "objectClass: top\n" +
            "objectClass: ds-cfg-je-index\n" +
            "ds-cfg-index-attribute: cn\n" +
            "ds-cfg-index-type: presence\n" +
            "ds-cfg-index-type: equality\n" +
            "ds-cfg-index-type: substring\n" +
            "ds-cfg-index-type: ordering\n" +
            "\n" +
            "dn: ds-cfg-index-attribute=employeeNumber,cn=Index,ds-cfg-backend-id=userRoot,cn=Backends,cn=config\n" +
            "objectClass: top\n" +
            "objectClass: ds-cfg-je-index\n" +
            "ds-cfg-index-attribute: employeeNumber\n" +
            "ds-cfg-index-type: presence\n" +
            "ds-cfg-index-type: equality\n" +
            "ds-cfg-index-type: substring\n" +
            "ds-cfg-index-type: ordering\n" +
            "\n" +
            "dn: ds-cfg-index-attribute=title,cn=Index,ds-cfg-backend-id=userRoot,cn=Backends,cn=config\n" +
            "objectClass: top\n" +
            "objectClass: ds-cfg-je-index\n" +
            "ds-cfg-index-attribute: title\n" +
            "ds-cfg-index-type: presence\n" +
            "ds-cfg-index-type: equality\n" +
            "ds-cfg-index-type: substring\n" +
            "ds-cfg-index-type: ordering\n");
    ConfigEntry attribIndexConfigEntry;
    for (Entry attribIndexEntry : indexEntries) {
      attribIndexConfigEntry = new ConfigEntry(attribIndexEntry,
          indexConfigEntry);
      indexConfigEntry.addChild(attribIndexConfigEntry);
    }
    baseDNs = new DN[]
        {
            DN.decode("dc=test,dc=com"),
            DN.decode("dc=test1,dc=com")
        };
    backend = new BackendImpl();
    backend.initializeBackend(backendConfigEntry, baseDNs);
    topEntries = TestCaseUtils.makeEntries(
        "dn: dc=test,dc=com",
        "objectclass: top",
        "objectclass: domain",
        "dc: example",
        "",
        "dn: ou=People,dc=test,dc=com",
        "objectclass: top",
        "objectclass: organizationalUnit",
        "ou: People",
        "",
        "dn: dc=test1,dc=com",
        "objectclass: top",
        "objectclass: domain",
        "dc: example1");
    entries = TestCaseUtils.makeEntries(
        "dn: uid=user.0,ou=People,dc=test,dc=com",
        "objectClass: top",
        "objectClass: person",
        "objectClass: organizationalPerson",
        "objectClass: inetOrgPerson",
        "givenName: Aaccf",
        "sn: Amar",
        "cn: Aaccf Amar",
        "initials: AQA",
        "employeeNumber: 0",
        "uid: user.0",
        "mail: user.0@example.com",
        "userPassword: password",
        "telephoneNumber: 380-535-2354",
        "homePhone: 707-626-3913",
        "pager: 456-345-7750",
        "mobile: 366-674-7274",
        "street: 99262 Eleventh Street",
        "l: Salem",
        "st: NM",
        "postalCode: 36530",
        "postalAddress: Aaccf Amar$99262 Eleventh Street$Salem, NM  36530",
        "description: This is the description for Aaccf Amar.",
        "",
        "dn: uid=user.1,ou=People,dc=test,dc=com",
        "objectClass: top",
        "objectClass: person",
        "objectClass: organizationalPerson",
        "objectClass: inetOrgPerson",
        "givenName: Aaren",
        "sn: Atp",
        "cn: Aaren Atp",
        "initials: APA",
        "employeeNumber: 1",
        "uid: user.1",
        "mail: user.1@example.com",
        "userPassword: password",
        "telephoneNumber: 643-278-6134",
        "homePhone: 546-786-4099",
        "pager: 508-261-3187",
        "mobile: 377-267-7824",
        "street: 78113 Fifth Street",
        "l: Chico",
        "st: TN",
        "postalCode: 72322",
        "postalAddress: Aaren Atp$78113 Fifth Street$Chico, TN  72322",
        "description: This is the description for Aaren Atp.",
        "",
        "dn: uid=user.2,ou=People,dc=test,dc=com",
        "objectClass: top",
        "objectClass: person",
        "objectClass: organizationalPerson",
        "objectClass: inetOrgPerson",
        "givenName: Aarika",
        "sn: Atpco",
        "cn: Aarika Atpco",
        "initials: ARA",
        "employeeNumber: 2",
        "uid: user.2",
        "mail: user.2@example.com",
        "userPassword: password",
        "telephoneNumber: 547-504-3498",
        "homePhone: 955-899-7308",
        "pager: 710-832-9316",
        "mobile: 688-388-4525",
        "street: 59208 Elm Street",
        "l: Youngstown",
        "st: HI",
        "postalCode: 57377",
        "postalAddress: Aarika Atpco$59208 Elm Street$Youngstown, HI  57377",
        "description: This is the description for Aarika Atpco.",
        "",
        "dn: uid=user.3,ou=People,dc=test,dc=com",
        "objectClass: top",
        "objectClass: person",
        "objectClass: organizationalPerson",
        "objectClass: inetOrgPerson",
        "givenName: Aaron",
        "sn: Atrc",
        "cn: Aaron Atrc",
        "initials: AIA",
        "employeeNumber: 3",
        "uid: user.3",
        "mail: user.3@example.com",
        "userPassword: password",
        "telephoneNumber: 128-108-4939",
        "homePhone: 512-782-9966",
        "pager: 322-646-5118",
        "mobile: 360-957-9137",
        "street: 25074 Hill Street",
        "l: Toledo",
        "st: OR",
        "postalCode: 55237",
        "postalAddress: Aaron Atrc$25074 Hill Street$Toledo, OR  55237",
        "description: This is the description for Aaron Atrc.",
        "",
        "dn: uid=user.4,ou=People,dc=test,dc=com",
        "objectClass: top",
        "objectClass: person",
        "objectClass: organizationalPerson",
        "objectClass: inetOrgPerson",
        "givenName: Aartjan",
        "sn: Aalders",
        "cn: Aartjan Aalders",
        "initials: ALA",
        "employeeNumber: 4",
        "uid: user.4",
        "mail: user.4@example.com",
        "userPassword: password",
        "telephoneNumber: 981-148-3303",
        "homePhone: 196-877-2684",
        "pager: 910-998-4607",
        "mobile: 123-239-8262",
        "street: 81512 Sunset Street",
        "l: Chattanooga",
        "st: WV",
        "postalCode: 29530",
        "postalAddress: Aartjan Aalders$81512 Sunset Street$Chattanooga, WV  29530",
        "description: This is the description for Aartjan Aalders.",
        "",
        "dn: uid=user.5,ou=People,dc=test,dc=com",
        "objectClass: top",
        "objectClass: person",
        "objectClass: organizationalPerson",
        "objectClass: inetOrgPerson",
        "givenName: Abagael",
        "sn: Aasen",
        "cn: Abagael Aasen",
        "initials: AKA",
        "employeeNumber: 5",
        "uid: user.5",
        "mail: user.5@example.com",
        "userPassword: password",
        "telephoneNumber: 930-493-2391",
        "homePhone: 078-254-3960",
        "pager: 281-936-8197",
        "mobile: 559-822-7712",
        "street: 31988 Central Street",
        "l: Chico",
        "st: MS",
        "postalCode: 20135",
        "postalAddress: Abagael Aasen$31988 Central Street$Chico, MS  20135",
        "description: This is the description for Abagael Aasen.",
        "",
        "dn: uid=user.6,ou=People,dc=test,dc=com",
        "objectClass: top",
        "objectClass: person",
        "objectClass: organizationalPerson",
        "objectClass: inetOrgPerson",
        "givenName: Abagail",
        "sn: Abadines",
        "cn: Abagail Abadines",
        "initials: AQA",
        "employeeNumber: 6",
        "uid: user.6",
        "mail: user.6@example.com",
        "userPassword: password",
        "telephoneNumber: 110-761-3861",
        "homePhone: 459-123-0553",
        "pager: 799-151-2688",
        "mobile: 953-582-7252",
        "street: 60100 Dogwood Street",
        "l: Hartford",
        "st: NE",
        "postalCode: 79353",
        "postalAddress: Abagail Abadines$60100 Dogwood Street$Hartford, NE  79353",
        "description: This is the description for Abagail Abadines.",
        "",
        "dn: uid=user.7,ou=People,dc=test,dc=com",
        "objectClass: top",
        "objectClass: person",
        "objectClass: organizationalPerson",
        "objectClass: inetOrgPerson",
        "givenName: Abahri",
        "sn: Abazari",
        "cn: Abahri Abazari",
        "initials: AXA",
        "employeeNumber: 7",
        "uid: user.7",
        "mail: user.7@example.com",
        "userPassword: password",
        "telephoneNumber: 594-537-4292",
        "homePhone: 174-724-6390",
        "pager: 733-217-8194",
        "mobile: 879-706-0172",
        "street: 77693 Oak Street",
        "l: Philadelphia",
        "st: MN",
        "postalCode: 78550",
        "postalAddress: Abahri Abazari$77693 Oak Street$Philadelphia, MN  78550",
        "description: This is the description for Abahri Abazari.",
        "",
        "dn: uid=user.8,ou=People,dc=test,dc=com",
        "objectClass: top",
        "objectClass: person",
        "objectClass: organizationalPerson",
        "objectClass: inetOrgPerson",
        "givenName: Abbas",
        "sn: Abbatantuono",
        "cn: Abbas Abbatantuono",
        "initials: AVA",
        "employeeNumber: 8",
        "uid: user.8",
        "mail: user.8@example.com",
        "userPassword: password",
        "telephoneNumber: 246-674-8407",
        "homePhone: 039-769-3372",
        "pager: 226-950-2371",
        "mobile: 587-709-2996",
        "street: 23230 Hill Street",
        "l: Little Rock",
        "st: AR",
        "",
        "dn: uid=user.9,ou=People,dc=test,dc=com",
        "objectClass: top",
        "objectClass: person",
        "objectClass: organizationalPerson",
        "objectClass: inetOrgPerson",
        "givenName: Abbe",
        "sn: Abbate",
        "cn: Abbe Abbate",
        "initials: AWA",
        "employeeNumber: 9",
        "uid: user.9",
        "mail: user.9@example.com",
        "userPassword: password",
        "telephoneNumber: 205-805-3357",
        "homePhone: 770-780-5917",
        "pager: 537-074-8005",
        "mobile: 120-204-7597",
        "street: 47952 Center Street",
        "l: Butte",
        "st: TN",
        "postalCode: 69384",
        "postalAddress: Abbe Abbate$47952 Center Street$Butte, TN  69384",
        "description: This is the description for Abbe Abbate.",
        "",
        "dn: uid=user.10,ou=People,dc=test,dc=com",
        "objectClass: top",
        "objectClass: person",
        "objectClass: organizationalPerson",
        "objectClass: inetOrgPerson",
        "givenName: Abbey",
        "sn: Abbie",
        "cn: Abbey Abbie",
        "initials: AZA",
        "employeeNumber: 10",
        "uid: user.10",
        "mail: user.10@example.com",
        "userPassword: password",
        "telephoneNumber: 457-819-0832",
        "homePhone: 931-305-5452",
        "pager: 118-165-7194",
        "mobile: 553-729-5572",
        "street: 54262 Highland Street",
        "l: Spartanburg",
        "st: PA",
        "postalCode: 38151",
        "postalAddress: Abbey Abbie$54262 Highland Street$Spartanburg, PA  38151",
        "description: This is the description for Abbey Abbie.",
        "",
        "dn: uid=user.539,ou=People,dc=test,dc=com",
        "objectClass: top",
        "objectClass: person",
        "objectClass: organizationalPerson",
        "objectClass: inetOrgPerson",
        "givenName: Ardyth",
        "sn: Bainton",
        "cn: Ardyth Bainton",
        "initials: AIB",
        "employeeNumber: 539",
        "uid: user.539",
        "mail: user.539@example.com",
        "userPassword: password",
        "telephoneNumber: 641-433-7404",
        "homePhone: 524-765-8780",
        "pager: 985-331-1308",
        "mobile: 279-423-0188",
        "street: 81170 Taylor Street",
        "l: Syracuse",
        "st: WV",
        "postalCode: 93507",
        "postalAddress: Ardyth Bainton$81170 Taylor Street$Syracuse, WV  93507",
        "description: This is the description for Ardyth Bainton.",
        "",
        "dn: uid=user.446,dc=test1,dc=com",
        "objectClass: top",
        "objectClass: person",
        "objectClass: organizationalPerson",
        "objectClass: inetOrgPerson",
        "givenName: Annalee",
        "sn: Avard",
        "cn: Annalee Avard",
        "initials: ANA",
        "employeeNumber: 446",
        "uid: user.446",
        "mail: user.446@example.com",
        "userPassword: password",
        "telephoneNumber: 875-335-2712",
        "homePhone: 181-995-6635",
        "pager: 586-905-4185",
        "mobile: 826-857-7592",
        "street: 46168 Mill Street",
        "l: Charleston",
        "st: CO",
        "postalCode: 60948",
        "postalAddress: Annalee Avard$46168 Mill Street$Charleston, CO  60948",
        "description: This is the description for Annalee Avard.",
        "",
        "dn: uid=user.362,dc=test1,dc=com",
        "objectClass: top",
        "objectClass: person",
        "objectClass: organizationalPerson",
        "objectClass: inetOrgPerson",
        "givenName: Andaree",
        "sn: Asawa",
        "cn: Andaree Asawa",
        "initials: AEA",
        "employeeNumber: 362",
        "uid: user.362",
        "mail: user.362@example.com",
        "userPassword: password",
        "telephoneNumber: 399-788-7334",
        "homePhone: 798-076-5683",
        "pager: 034-026-9411",
        "mobile: 948-743-9197",
        "street: 81028 Forest Street",
        "l: Wheeling",
        "st: IA",
        "postalCode: 60905",
        "postalAddress: Andaree Asawa$81028 Forest Street$Wheeling, IA  60905",
        "description: This is the description for Andaree Asawa.");
    replaceEntry = TestCaseUtils.makeEntry(
        "dn: uid=user.0,ou=People,dc=test,dc=com",
        "objectClass: top",
        "objectClass: person",
        "objectClass: organizationalPerson",
        "objectClass: inetOrgPerson",
        "givenName: Testing",
        "sn: Test",
        "cn: Testing Test",
        "initials: TT",
        "employeeNumber: 777",
        "uid: user.0",
        "mail: user.0@example.com",
        "userPassword: password",
        "telephoneNumber: 380-535-2354",
        "homePhone: 707-626-3913",
        "pager: 456-345-7750",
        "mobile: 366-674-7274",
        "street: 99262 Eleventh Street",
        "l: Salem",
        "st: NM",
        "postalCode: 36530",
        "postalAddress: Aaccf Amar$99262 Eleventh Street$Salem, NM  36530",
        "description: This is the description for Aaccf Amar.");
    additionalEntries = TestCaseUtils.makeEntries(
        "dn: uid=user.446,ou=People,dc=test,dc=com",
        "objectClass: top",
        "objectClass: person",
        "objectClass: organizationalPerson",
        "objectClass: inetOrgPerson",
        "givenName: Annalee",
        "sn: Avard",
        "cn: Annalee Avard",
        "initials: ANA",
        "employeeNumber: 446",
        "uid: user.446",
        "mail: user.446@example.com",
        "userPassword: password",
        "telephoneNumber: 875-335-2712",
        "homePhone: 181-995-6635",
        "pager: 586-905-4185",
        "mobile: 826-857-7592",
        "street: 46168 Mill Street",
        "l: Charleston",
        "st: CO",
        "postalCode: 60948",
        "postalAddress: Annalee Avard$46168 Mill Street$Charleston, CO  60948",
        "description: This is the description for Annalee Avard.",
        "",
        "dn: uid=user.362,ou=People,dc=test,dc=com",
        "objectClass: top",
        "objectClass: person",
        "objectClass: organizationalPerson",
        "objectClass: inetOrgPerson",
        "givenName: Andaree",
        "sn: Asawa",
        "cn: Andaree Asawa",
        "initials: AEA",
        "employeeNumber: 362",
        "uid: user.362",
        "mail: user.362@example.com",
        "userPassword: password",
        "telephoneNumber: 399-788-7334",
        "homePhone: 798-076-5683",
        "pager: 034-026-9411",
        "mobile: 948-743-9197",
        "street: 81028 Forest Street",
        "l: Wheeling",
        "st: IA",
        "postalCode: 60905",
        "postalAddress: Andaree Asawa$81028 Forest Street$Wheeling, IA  60905",
        "description: This is the description for Andaree Asawa.");
    newTop = TestCaseUtils.makeEntry(
        "dn: ou=JEB Testers,dc=test,dc=com",
        "objectclass: top",
        "objectclass: organizationalUnit",
        "ou: People"
    );
  }
  /**
   * Tears down the environment for performing the tests in this suite.
   *
   * @throws Exception
   *           If the environment could not be finalized.
   */
  @AfterClass
  public void tearDown() throws Exception {
  public void cleanUp() throws Exception {
    backend.finalizeBackend();
    TestCaseUtils.deleteDirectory(tempDir);
  }
  /**
   * Test backend finalization.
   *
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test()
  public void testFinalize() throws Exception {
    File homeDir = new File(homeDirName);
    homeDir.mkdir();
    ConfigEntry configEntry = new ConfigEntry(entry, null);
    DN[] baseDNs = new DN[] { DN.decode("dc=com") };
    Backend backend = new BackendImpl();
    for (int i = 0; i < 10; i++) {
      backend.initializeBackend(configEntry, baseDNs);
      try {
        backend.getEntry(DN.decode("dc=com"));
      } catch (DirectoryException e) {
      }
      backend.finalizeBackend();
  @Test(expectedExceptions = DirectoryException.class)
  public void testAddNoParent() throws Exception {
    for (Entry entry : entries) {
      backend.addEntry(entry, null);
    }
  }
}
  @Test(dependsOnMethods = "testAddNoParent")
  public void testAdd() throws Exception {
    for (Entry topEntry : topEntries) {
      backend.addEntry(topEntry, null);
      assertNotNull(backend.getEntry(topEntry.getDN()));
    }
    for (Entry entry : entries) {
      backend.addEntry(entry, null);
      assertNotNull(backend.getEntry(entry.getDN()));
    }
  }
  @Test(dependsOnMethods = "testAdd")
  public void testSearchScope() throws Exception {
    ArrayList<Control> noControls = new ArrayList<Control>(0);
    InternalClientConnection conn =
        InternalClientConnection.getRootConnection();
    InternalSearchOperation search =
        conn.processSearch(DN.decode("dc=test,dc=com"), SearchScope.BASE_OBJECT,
            LDAPFilter.decode("(objectClass=*)").toSearchFilter());
    LinkedList<SearchResultEntry> result = search.getSearchEntries();
    assertEquals(result.size(), 1);
    assertEquals(result.get(0).getDN().toString(), "dc=test,dc=com");
    search = conn.processSearch(DN.decode("dc=test,dc=com"),
        SearchScope.BASE_OBJECT, LDAPFilter.decode("(ou=People)").toSearchFilter());
    result = search.getSearchEntries();
    assertEquals(result.size(), 0);
    search = conn.processSearch(DN.decode("dc=test,dc=com"),
        SearchScope.SINGLE_LEVEL,
        LDAPFilter.decode("(objectClass=*)").toSearchFilter());
    result = search.getSearchEntries();
    assertEquals(result.size(), 1);
    assertEquals(result.get(0).getDN().toString(),
        "ou=People,dc=test,dc=com");
    search = conn.processSearch(DN.decode("dc=test,dc=com"),
        SearchScope.SUBORDINATE_SUBTREE,
        LDAPFilter.decode("(objectClass=*)").toSearchFilter());
    result = search.getSearchEntries();
    assertEquals(result.size(), 13);
    for (Entry entry : result) {
      assertNotSame(entry.getDN().toString(), "dc=test,dc=com");
    }
    search = conn.processSearch(DN.decode("dc=test,dc=com"),
        SearchScope.WHOLE_SUBTREE,
        LDAPFilter.decode("(objectClass=*)").toSearchFilter());
    result = search.getSearchEntries();
    assertEquals(result.size(), 14);
  }
  @Test(dependsOnMethods = "testAdd")
  public void testSearchIndex() throws Exception {
    ArrayList<Control> noControls = new ArrayList<Control>(0);
    InternalClientConnection conn =
        InternalClientConnection.getRootConnection();
    LinkedHashSet<String> attribs = new LinkedHashSet<String>();
    String debugString;
    int finalStartPos;
    int finalEndPos;
    int finalCount;
    InternalSearchOperation search =
        conn.processSearch(DN.decode("dc=test,dc=com"),
            SearchScope.WHOLE_SUBTREE,
            DereferencePolicy.NEVER_DEREF_ALIASES,
            0,
            0,
            false,
            LDAPFilter.decode("(&(cn=Aaccf Amar)(cn=Ardyth Bainton))").toSearchFilter(),
            attribs);
    LinkedList<SearchResultEntry> result = search.getSearchEntries();
    assertEquals(result.size(), 0);
    attribs.add(ATTR_DEBUG_SEARCH_INDEX);
    search = conn.processSearch(DN.decode("dc=test,dc=com"),
        SearchScope.WHOLE_SUBTREE,
        DereferencePolicy.NEVER_DEREF_ALIASES,
        0,
        0,
        false,
        LDAPFilter.decode("(&(cn=Aaccf Amar)(employeeNumber=222))").toSearchFilter(),
        attribs);
    result = search.getSearchEntries();
    //Only one index should be used because it is below the FILTER_CANDIDATEassertEquals(ec.getDN2URI().)_THRESHOLD.
    debugString =
        result.get(0).getAttribute("debugsearchindex").get(0).getValues().toString();
    assertTrue(debugString.split("cn").length <= 2);
    finalStartPos = debugString.indexOf("final=") + 13;
    finalEndPos = debugString.indexOf("]", finalStartPos);
    finalCount = Integer.valueOf(debugString.substring(finalStartPos,
        finalEndPos));
    assertEquals(finalCount, 1);
    search = conn.processSearch(DN.decode("dc=test,dc=com"),
        SearchScope.WHOLE_SUBTREE,
        DereferencePolicy.NEVER_DEREF_ALIASES,
        0,
        0,
        false,
        LDAPFilter.decode("(|(cn=Aaccf Amar)(cn=Ardyth Bainton))").toSearchFilter(),
        attribs);
    result = search.getSearchEntries();
    debugString =
        result.get(0).getAttribute("debugsearchindex").get(0).getValues().toString();
    assertTrue(!debugString.contains("NOT-INDEXED"));
    finalStartPos = debugString.indexOf("final=") + 13;
    finalEndPos = debugString.indexOf("]", finalStartPos);
    finalCount = Integer.valueOf(debugString.substring(finalStartPos,
        finalEndPos));
    assertEquals(finalCount, 2);
    search = conn.processSearch(DN.decode("dc=test,dc=com"),
        SearchScope.WHOLE_SUBTREE,
        DereferencePolicy.NEVER_DEREF_ALIASES,
        0,
        0,
        false,
        LDAPFilter.decode("(&(employeeNumber=*)(cn=A*)(employeeNumber>=0)(employeeNumber<=z))").toSearchFilter(),
        attribs);
    result = search.getSearchEntries();
    debugString =
        result.get(0).getAttribute("debugsearchindex").get(0).getValues().toString();
    assertTrue(!debugString.contains("NOT-INDEXED"));
    finalStartPos = debugString.indexOf("final=") + 13;
    finalEndPos = debugString.indexOf("]", finalStartPos);
    finalCount = Integer.valueOf(debugString.substring(finalStartPos,
        finalEndPos));
    assertEquals(finalCount, 12);
    search = conn.processSearch(DN.decode("dc=test,dc=com"),
        SearchScope.WHOLE_SUBTREE,
        DereferencePolicy.NEVER_DEREF_ALIASES,
        0,
        0,
        false,
        LDAPFilter.decode("(&(employeeNumber<=z)(cn<=Abbey Abbie)(cn>=0)(|(cn>=Abahri Abazari)(employeeNumber<=9)))").toSearchFilter(),
        attribs);
    result = search.getSearchEntries();
    debugString =
        result.get(0).getAttribute("debugsearchindex").get(0).getValues().toString();
    assertTrue(!debugString.contains("NOT-INDEXED"));
    finalStartPos = debugString.indexOf("final=") + 13;
    finalEndPos = debugString.indexOf("]", finalStartPos);
    finalCount = Integer.valueOf(debugString.substring(finalStartPos,
        finalEndPos));
    assertEquals(finalCount, 11);
  }
  @Test(dependsOnMethods = {"testAdd", "testSearchIndex",
      "testSearchScope", "testSearchNotIndexed", "testModifyDNNewSuperior"})
  public void testDeleteSubtree() throws Exception {
    Control control = new Control(OID_SUBTREE_DELETE_CONTROL, false);
    ArrayList<Control> deleteSubTreeControl = new ArrayList<Control>();
    deleteSubTreeControl.add(control);
    InternalClientConnection conn =
        InternalClientConnection.getRootConnection();
    DeleteOperation delete = new DeleteOperation(conn,
        conn.nextOperationID(),
        conn.nextMessageID(),
        deleteSubTreeControl,
        DN.decode("dc=test1,dc=com"));
    backend.deleteEntry(DN.decode("dc=test1,dc=com"), delete);
    EntryContainer ec =
        backend.getRootContainer().getEntryContainer(DN.decode("dc=test1,dc=com"));
    assertFalse(ec.entryExists(DN.decode("dc=test1,dc=com")));
    assertFalse(ec.entryExists(DN.decode("uid=user.362,dc=test1,dc=com")));
  }
  @Test(dependsOnMethods = {"testAdd", "testSearchIndex",
      "testSearchScope"})
  public void testDeleteEntry() throws Exception {
    ArrayList<Control> noControls = new ArrayList<Control>(0);
    InternalClientConnection conn =
        InternalClientConnection.getRootConnection();
    Entry entry;
    EntryID entryID;
    AttributeType attribute;
    AttributeIndex index;
    HashSet<ASN1OctetString> addKeys;
    DatabaseEntry key;
    PresenceIndexer presenceIndexer;
    EqualityIndexer equalityIndexer;
    SubstringIndexer substringIndexer;
    OrderingIndexer orderingIndexer;
    EntryContainer ec =
        backend.getRootContainer().getEntryContainer(DN.decode("ou=People,dc=test,dc=com"));
    entry = ec.getEntry(DN.decode("uid=user.539,ou=People,dc=test,dc=com"));
    entryID = ec.getDN2ID().get(null,
        DN.decode("uid=user.539,ou=People,dc=test,dc=com"));
    DeleteOperation delete = new DeleteOperation(conn,
        conn.nextOperationID(),
        conn.nextMessageID(),
        noControls,
        DN.decode("uid=user.539,ou=People,dc=test,dc=com"));
    backend.deleteEntry(DN.decode("uid=user.539,ou=People,dc=test,dc=com"),
        delete);
    assertFalse(ec.entryExists(DN.decode("uid=user.539,ou=People,dc=test,dc=com")));
    assertNull(ec.getDN2ID().get(null,
        DN.decode("uid=user.539,ou=People,dc=test,dc=com")));
    assertFalse(ec.getDN2URI().delete(null,
        DN.decode("uid=user.539,ou=People,dc=test,dc=com")));
    attribute = entries.get(0).getAttribute("cn").get(0).getAttributeType();
    index = ec.getAttributeIndex(attribute);
    addKeys = new HashSet<ASN1OctetString>();
    presenceIndexer = new PresenceIndexer(index.indexConfig);
    presenceIndexer.indexEntry(null, entry, addKeys);
    key = new DatabaseEntry();
    for (ASN1OctetString keyBytes : addKeys) {
      key.setData(keyBytes.value());
    }
    assertEquals(index.presenceIndex.containsID(null, key, entryID),
        ConditionResult.FALSE);
    addKeys = new HashSet<ASN1OctetString>();
    equalityIndexer = new EqualityIndexer(index.indexConfig);
    equalityIndexer.indexEntry(null, entry, addKeys);
    key = new DatabaseEntry();
    for (ASN1OctetString keyBytes : addKeys) {
      key.setData(keyBytes.value());
    }
    assertEquals(index.equalityIndex.containsID(null, key, entryID),
        ConditionResult.FALSE);
    addKeys = new HashSet<ASN1OctetString>();
    substringIndexer = new SubstringIndexer(index.indexConfig);
    substringIndexer.indexEntry(null, entry, addKeys);
    key = new DatabaseEntry();
    for (ASN1OctetString keyBytes : addKeys) {
      key.setData(keyBytes.value());
    }
    assertEquals(index.substringIndex.containsID(null, key, entryID),
        ConditionResult.FALSE);
    addKeys = new HashSet<ASN1OctetString>();
    orderingIndexer = new OrderingIndexer(index.indexConfig);
    orderingIndexer.indexEntry(null, entry, addKeys);
    key = new DatabaseEntry();
    for (ASN1OctetString keyBytes : addKeys) {
      key.setData(keyBytes.value());
    }
    assertEquals(index.orderingIndex.containsID(null, key, entryID),
        ConditionResult.FALSE);
  }
  @Test(dependsOnMethods = {"testSearchNotIndexed", "testAdd", "testSearchIndex", "testSearchScope"})
  public void testReplaceEntry() throws Exception {
    Entry entry;
    Entry oldEntry;
    EntryID entryID;
    AttributeType attribute;
    AttributeIndex index;
    HashSet<ASN1OctetString> addKeys;
    DatabaseEntry key;
    PresenceIndexer presenceIndexer;
    EqualityIndexer equalityIndexer;
    SubstringIndexer substringIndexer;
    OrderingIndexer orderingIndexer;
    backend.replaceEntry(replaceEntry, null);
    EntryContainer ec =
        backend.getRootContainer().getEntryContainer(DN.decode("dc=test,dc=com"));
    entry = ec.getEntry(DN.decode("uid=user.0,ou=People,dc=test,dc=com"));
    oldEntry = entries.get(0);
    entryID = ec.getDN2ID().get(null,
        DN.decode("uid=user.0,ou=People,dc=test,dc=com"));
    assertNotNull(entry);
    LinkedHashSet<AttributeValue> values =
        entry.getAttribute("cn").get(0).getValues();
    for (AttributeValue value : values) {
      assertEquals(value.getStringValue(), "Testing Test");
    }
    values = entry.getAttribute("sn").get(0).getValues();
    for (AttributeValue value : values) {
      assertEquals(value.getStringValue(), "Test");
    }
    values = entry.getAttribute("givenname").get(0).getValues();
    for (AttributeValue value : values) {
      assertEquals(value.getStringValue(), "Testing");
    }
    values = entry.getAttribute("employeenumber").get(0).getValues();
    for (AttributeValue value : values) {
      assertEquals(value.getStringValue(), "777");
    }
    attribute = entry.getAttribute("cn").get(0).getAttributeType();
    index = ec.getAttributeIndex(attribute);
    addKeys = new HashSet<ASN1OctetString>();
    orderingIndexer = new OrderingIndexer(index.indexConfig);
    orderingIndexer.indexEntry(null, entry, addKeys);
    key = new DatabaseEntry();
    for (ASN1OctetString keyBytes : addKeys) {
      key.setData(keyBytes.value());
    }
    assertEquals(index.orderingIndex.containsID(null, key, entryID),
        ConditionResult.TRUE);
    addKeys = new HashSet<ASN1OctetString>();
    orderingIndexer = new OrderingIndexer(index.indexConfig);
    orderingIndexer.indexEntry(null, oldEntry, addKeys);
    key = new DatabaseEntry();
    for (ASN1OctetString keyBytes : addKeys) {
      key.setData(keyBytes.value());
    }
    assertEquals(index.orderingIndex.containsID(null, key, entryID),
        ConditionResult.FALSE);
    addKeys = new HashSet<ASN1OctetString>();
    substringIndexer = new SubstringIndexer(index.indexConfig);
    substringIndexer.indexEntry(null, entry, addKeys);
    key = new DatabaseEntry();
    for (ASN1OctetString keyBytes : addKeys) {
      key.setData(keyBytes.value());
    }
    assertEquals(index.substringIndex.containsID(null, key, entryID),
        ConditionResult.TRUE);
    addKeys = new HashSet<ASN1OctetString>();
    substringIndexer = new SubstringIndexer(index.indexConfig);
    substringIndexer.indexEntry(null, oldEntry, addKeys);
    key = new DatabaseEntry();
    for (ASN1OctetString keyBytes : addKeys) {
      key.setData(keyBytes.value());
    }
    assertEquals(index.substringIndex.containsID(null, key, entryID),
        ConditionResult.FALSE);
    addKeys = new HashSet<ASN1OctetString>();
    equalityIndexer = new EqualityIndexer(index.indexConfig);
    equalityIndexer.indexEntry(null, entry, addKeys);
    key = new DatabaseEntry();
    for (ASN1OctetString keyBytes : addKeys) {
      key.setData(keyBytes.value());
    }
    assertEquals(index.equalityIndex.containsID(null, key, entryID),
        ConditionResult.TRUE);
    addKeys = new HashSet<ASN1OctetString>();
    equalityIndexer = new EqualityIndexer(index.indexConfig);
    equalityIndexer.indexEntry(null, oldEntry, addKeys);
    key = new DatabaseEntry();
    for (ASN1OctetString keyBytes : addKeys) {
      key.setData(keyBytes.value());
    }
    assertEquals(index.equalityIndex.containsID(null, key, entryID),
        ConditionResult.FALSE);
  }
  @Test(dependsOnMethods = {"testSearchNotIndexed", "testAdd", "testSearchIndex", "testSearchScope"})
  public void testModifyEntry() throws Exception {
    Entry entry;
    Entry newEntry;
    EntryID entryID;
    AttributeType attribute;
    AttributeIndex index;
    HashSet<ASN1OctetString> addKeys;
    DatabaseEntry key;
    PresenceIndexer presenceIndexer;
    EqualityIndexer equalityIndexer;
    SubstringIndexer substringIndexer;
    OrderingIndexer orderingIndexer;
    EntryContainer ec =
        backend.getRootContainer().getEntryContainer(DN.decode("dc=test,dc=com"));
    ArrayList<Modification> modifications = new ArrayList<Modification>();
    modifications.add(new Modification(ModificationType.ADD, new
        Attribute("title", "debugger")));
    modifications.add(new Modification(ModificationType.DELETE, new
        Attribute("cn", "Aaren Atp")));
    modifications.add(new Modification(ModificationType.ADD, new
        Attribute("cn", "Aaren Rigor")));
    modifications.add(new Modification(ModificationType.ADD, new
        Attribute("cn", "Aarenister Rigor")));
    modifications.add(new Modification(ModificationType.REPLACE, new
        Attribute("employeenumber", "222")));
    newEntry = entries.get(1);
    newEntry.applyModifications(modifications);
    entry = ec.getEntry(DN.decode("uid=user.1,ou=People,dc=test,dc=com"));
    entryID = ec.getDN2ID().get(null, DN.decode("uid=user.1,ou=People,dc=test,dc=com"));
    assertNotNull(entryID);
    attribute = newEntry.getAttribute("title").get(0).getAttributeType();
    index = ec.getAttributeIndex(attribute);
    //This current entry in the DB shouldn't be in the presence index.
    addKeys = new HashSet<ASN1OctetString>();
    addKeys.add(new ASN1OctetString(AttributeIndex.presenceKey.getData()));
    key = new DatabaseEntry();
    for (ASN1OctetString keyBytes : addKeys) {
      key.setData(keyBytes.value());
    }
    assertEquals(index.presenceIndex.containsID(null, key, entryID),
        ConditionResult.FALSE);
    ArrayList<Control> noControls = new ArrayList<Control>(0);
    InternalClientConnection conn =
        InternalClientConnection.getRootConnection();
    ModifyOperation modifyOp = new ModifyOperation(conn,
        conn.nextOperationID(),
        conn.nextMessageID(),
        noControls,
        DN.decode("uid=user.1,ou=People,dc=test,dc=com"),
        modifications);
    backend.replaceEntry(newEntry, modifyOp);
    entry = ec.getEntry(DN.decode("uid=user.1,ou=People,dc=test,dc=com"));
    assertTrue(entry.getAttribute("title").contains(new
        Attribute("title", "debugger")));
    assertTrue(entry.getAttribute("cn").get(0).getValues().contains(
        new AttributeValue(
            entry.getAttribute("cn").get(0).getAttributeType(),
            "Aaren Rigor")));
    assertTrue(entry.getAttribute("cn").get(0).getValues().contains(
        new AttributeValue(
            entry.getAttribute("cn").get(0).getAttributeType(),
            "Aarenister Rigor")));
    assertFalse(entry.getAttribute("cn").get(0).getValues().contains(
        new AttributeValue(
            entry.getAttribute("cn").get(0).getAttributeType(),
            "Aaren Atp")));
    assertTrue(entry.getAttribute("employeenumber").contains(new
        Attribute("employeenumber", "222")));
    assertFalse(entry.getAttribute("employeenumber").contains(new
        Attribute("employeenumber", "1")));
    addKeys = new HashSet<ASN1OctetString>();
    presenceIndexer = new PresenceIndexer(index.indexConfig);
    presenceIndexer.indexEntry(null, entry, addKeys);
    key = new DatabaseEntry();
    for (ASN1OctetString keyBytes : addKeys) {
      key.setData(keyBytes.value());
    }
    assertEquals(index.presenceIndex.containsID(null, key, entryID),
        ConditionResult.TRUE);
    addKeys = new HashSet<ASN1OctetString>();
    orderingIndexer = new OrderingIndexer(index.indexConfig);
    orderingIndexer.indexEntry(null, entry, addKeys);
    key = new DatabaseEntry();
    for (ASN1OctetString keyBytes : addKeys) {
      key.setData(keyBytes.value());
    }
    assertEquals(index.orderingIndex.containsID(null, key, entryID),
        ConditionResult.TRUE);
    addKeys = new HashSet<ASN1OctetString>();
    equalityIndexer = new EqualityIndexer(index.indexConfig);
    equalityIndexer.indexEntry(null, entry, addKeys);
    key = new DatabaseEntry();
    for (ASN1OctetString keyBytes : addKeys) {
      key.setData(keyBytes.value());
    }
    assertEquals(index.equalityIndex.containsID(null, key, entryID),
        ConditionResult.TRUE);
    addKeys = new HashSet<ASN1OctetString>();
    substringIndexer = new SubstringIndexer(index.indexConfig);
    substringIndexer.indexEntry(null, entry, addKeys);
    key = new DatabaseEntry();
    for (ASN1OctetString keyBytes : addKeys) {
      key.setData(keyBytes.value());
    }
    assertEquals(index.substringIndex.containsID(null, key, entryID),
        ConditionResult.TRUE);
  }
  @Test(dependsOnMethods = {"testAdd", "testSearchIndex", "testSearchScope"})
  public void testModifyDN() throws Exception {
    EntryContainer ec =
        backend.getRootContainer().getEntryContainer(DN.decode("dc=test,dc=com"));
    Entry entry =
        ec.getEntry(DN.decode("uid=user.2,ou=People,dc=test,dc=com"));
    entry.setDN(DN.decode("cn=Abbey Abbie,ou=People,dc=test,dc=com"));
    backend.renameEntry(DN.decode("uid=user.2,ou=People,dc=test,dc=com"),
        entry, null);
    assertNotNull(backend.getEntry(DN.decode("cn=Abbey Abbie,ou=People,dc=test,dc=com")));
    assertNotNull(ec.getDN2ID().get(null, DN.decode("cn=Abbey Abbie,ou=People,dc=test,dc=com")));
    assertNull(backend.getEntry(DN.decode("uid=user.2,ou=People,dc=test,dc=com")));
    assertNull(ec.getDN2ID().get(null,
        DN.decode("uid=user.2,ou=People,dc=test,dc=com")));
  }
  @Test(dependsOnMethods = {"testSearchNotIndexed", "testAdd", "testSearchIndex",
      "testSearchScope", "testModifyEntry", "testModifyDN", "testReplaceEntry",
      "testDeleteEntry"})
  public void testModifyDNNewSuperior() throws Exception {
    //Add the new superior entry we want to move to. Test to see if the child ID
    //always above parent invarient is preseved.
    backend.addEntry(newTop, null);
    EntryContainer ec =
        backend.getRootContainer().getEntryContainer(DN.decode("dc=test,dc=com"));
    EntryID newSuperiorID = ec.getDN2ID().get(null, DN.decode("ou=JEB Testers,dc=test,dc=com"));
    EntryID oldID = ec.getDN2ID().get(null,
        DN.decode("ou=People,dc=test,dc=com"));
    assertTrue(newSuperiorID.compareTo(oldID) > 0);
    ArrayList<Control> noControls = new ArrayList<Control>(0);
    InternalClientConnection conn =
        InternalClientConnection.getRootConnection();
    ModifyDNOperation modifyDN = new ModifyDNOperation(conn,
        conn.nextOperationID(),
        conn.nextMessageID(),
        noControls,
        DN.decode("ou=People,dc=test,dc=com"),
        RDN.decode("ou=Good People"),
        false,
        DN.decode("ou=JEB Testers,dc=test,dc=com"));
    modifyDN.run();
    assertNotNull(backend.getEntry(DN.decode("ou=Good People,ou=JEB Testers,dc=test,dc=com")));
    EntryID newID = ec.getDN2ID().get(null, DN.decode("ou=Good People,ou=JEB Testers,dc=test,dc=com"));
    assertNotNull(newID);
    assertTrue(newID.compareTo(newSuperiorID) > 0);
    assertNotNull(backend.getEntry(DN.decode("uid=user.0,ou=Good People,ou=JEB Testers,dc=test,dc=com")));
    EntryID newSubordinateID = ec.getDN2ID().get(null,
        DN.decode("uid=user.0,ou=Good People,ou=JEB Testers,dc=test,dc=com"));
    assertTrue(newSubordinateID.compareTo(newID) > 0);
    assertNull(backend.getEntry(DN.decode("ou=People,dc=test,dc=com")));
    assertNull(ec.getDN2ID().get(null,
        DN.decode("ou=People,dc=test,dc=com")));
  }
  @Test(dependsOnMethods = {"testModifyDN",
      "testSearchScope", "testSearchIndex", "testReplaceEntry",
      "testModifyEntry", "testModifyDN", "testDeleteSubtree",
      "testDeleteEntry", "testAddNoParent", "testAdd",
      "testSearchNotIndexed",
      "testModifyDNNewSuperior"})
  public void testApplyConfig() throws Exception {
    Entry configEntry = TestCaseUtils.makeEntry(
        "dn: ds-cfg-backend-id=userRoot,cn=Backends,cn=config",
        "objectClass: top",
        "objectClass: ds-cfg-backend",
        "objectClass: ds-cfg-je-backend",
        "ds-cfg-backend-base-dn: dc=test,dc=com",
        "ds-cfg-backend-base-dn: dc=newsuffix,dc=com",
        "ds-cfg-backend-enabled: true",
        "ds-cfg-backend-class: org.opends.server.backends.jeb.BackendImpl",
        "ds-cfg-backend-id: userRoot",
        "ds-cfg-backend-directory:: " +
            Base64.encode(homeDirName.getBytes()));
    ConfigEntry backendConfigEntry = new ConfigEntry(configEntry, null);
    backend.applyNewConfiguration(backendConfigEntry, true);
    RootContainer rootContainer = backend.getRootContainer();
    assertNull(rootContainer.getEntryContainer(DN.decode("dc=test1,dc=com")));
    assertNotNull(rootContainer.getEntryContainer(DN.decode("dc=newsuffix,dc=com")));
  }
  @Test(dependsOnMethods = {"testDeleteEntry", "testSearchScope",
      "testSearchIndex"})
  public void testSearchNotIndexed() throws Exception {
    //Add 2 more entries to overflow the index entry limit.
    for (Entry entry : additionalEntries) {
      backend.addEntry(entry, null);
      assertNotNull(backend.getEntry(entry.getDN()));
    }
    ArrayList<Control> noControls = new ArrayList<Control>(0);
    InternalClientConnection conn =
        InternalClientConnection.getRootConnection();
    LinkedHashSet<String> attribs = new LinkedHashSet<String>();
    attribs.add(ATTR_DEBUG_SEARCH_INDEX);
    String debugString;
    int finalStartPos;
    int finalEndPos;
    int finalCount;
    InternalSearchOperation search =
        conn.processSearch(DN.decode("dc=test,dc=com"),
            SearchScope.SUBORDINATE_SUBTREE,
            DereferencePolicy.NEVER_DEREF_ALIASES,
            0,
            0,
            false,
            LDAPFilter.decode("(mobile=377*)").toSearchFilter(),
            attribs);
    LinkedList<SearchResultEntry> result = search.getSearchEntries();
    //No indexes should be used.
    debugString =
        result.get(0).getAttribute("debugsearchindex").get(0).getValues().toString();
    assertTrue(debugString.contains("NOT-INDEXED"));
  }
}
opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestEntryContainer.java
@@ -195,7 +195,6 @@
    EntryID actualHighestID = entryContainer.getHighestEntryID();
    assertTrue(actualHighestID.equals(new EntryID(0)));
    EntryID.initialize(actualHighestID);
    for (Entry entry : entryList) {
      entryContainer.addEntry(entry, null);
      Entry afterEntry = entryContainer.getEntry(entry.getDN());
@@ -204,6 +203,7 @@
    actualHighestID = entryContainer.getHighestEntryID();
    assertTrue(actualHighestID.equals(new EntryID(calculatedHighestID)));
    rootContainer.close();
    EnvManager.removeFiles(homeDirName);
  }
opends/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestImportJob.java
New file
@@ -0,0 +1,520 @@
/*
 * 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
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * 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
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  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
 *
 *
 *      Portions Copyright 2006 Sun Microsystems, Inc.
 */
package org.opends.server.backends.jeb;
import org.opends.server.TestCaseUtils;
import org.opends.server.core.DirectoryServer;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.config.ConfigEntry;
import org.opends.server.util.Base64;
import static org.opends.server.util.ServerConstants.OC_TOP;
import static org.opends.server.util.ServerConstants.OC_EXTENSIBLE_OBJECT;
import org.opends.server.types.*;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.testng.annotations.AfterTest;
import org.testng.annotations.AfterClass;
import static org.testng.Assert.*;
import static org.testng.Assert.assertEquals;
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.io.ByteArrayOutputStream;
import java.util.*;
import com.sleepycat.je.DatabaseEntry;
public class TestImportJob extends JebTestCase
{
  private File tempDir;
  private String homeDirName;
  private String importDirName;
  private LDIFImportConfig ldifImportConfig;
  private Config backendConfig;
  private DN[] baseDNs;
  private  String errorCount="verify-error-count";
  private String top = "dn: dc=example,dc=com\n" +
      "objectclass: top\n" +
      "objectclass: domain\n" +
      "dc: example\n" +
      "\n" +
      "dn: ou=People,dc=example,dc=com\n" +
      "objectclass: top\n" +
      "objectclass: organizationalUnit\n" +
      "ou: People\n" +
      "\n" +
      "dn: dc=example1,dc=com\n" +
      "objectclass: top\n" +
      "objectclass: domain\n" +
      "dc: example1\n";
  private String entries1 =
      "dn: uid=user.0,ou=People,dc=example,dc=com\n" +
      "objectClass: top\n" +
      "objectClass: person\n" +
      "objectClass: organizationalPerson\n" +
      "objectClass: inetOrgPerson\n" +
      "givenName: Aaccf\n" +
      "sn: Amar\n" +
      "cn: Aaccf Amar\n" +
      "initials: AQA\n" +
      "employeeNumber: 0\n" +
      "uid: user.0\n" +
      "mail: user.0@example.com\n" +
      "userPassword: password\n" +
      "telephoneNumber: 380-535-2354\n" +
      "homePhone: 707-626-3913\n" +
      "pager: 456-345-7750\n" +
      "mobile: 366-674-7274\n" +
      "street: 99262 Eleventh Street\n" +
      "l: Salem\n" +
      "st: NM\n" +
      "postalCode: 36530\n" +
      "postalAddress: Aaccf Amar$99262 Eleventh Street$Salem, NM  36530\n" +
      "description: This is the description for Aaccf Amar.\n" +
      "\n" +
      "dn: uid=user.539,ou=People,dc=example,dc=com\n" +
      "objectClass: top\n" +
      "objectClass: person\n" +
      "objectClass: organizationalPerson\n" +
      "objectClass: inetOrgPerson\n" +
      "givenName: Ardyth\n" +
      "sn: Bainton\n" +
      "cn: Ardyth Bainton\n" +
      "initials: AIB\n" +
      "employeeNumber: 539\n" +
      "uid: user.539\n" +
      "mail: user.539@example.com\n" +
      "userPassword: password\n" +
      "telephoneNumber: 641-433-7404\n" +
      "homePhone: 524-765-8780\n" +
      "pager: 985-331-1308\n" +
      "mobile: 279-423-0188\n" +
      "street: 81170 Taylor Street\n" +
      "l: Syracuse\n" +
      "st: WV\n" +
      "postalCode: 93507\n" +
      "postalAddress: Ardyth Bainton$81170 Taylor Street$Syracuse, WV  93507\n" +
      "description: This is the description for Ardyth Bainton.\n" +
      "\n" +
      "dn: uid=user.446,dc=example1,dc=com\n" +
      "objectClass: top\n" +
      "objectClass: person\n" +
      "objectClass: organizationalPerson\n" +
      "objectClass: inetOrgPerson\n" +
      "givenName: Annalee\n" +
      "sn: Avard\n" +
      "cn: Annalee Avard\n" +
      "initials: ANA\n" +
      "employeeNumber: 446\n" +
      "uid: user.446\n" +
      "mail: user.446@example.com\n" +
      "userPassword: password\n" +
      "telephoneNumber: 875-335-2712\n" +
      "homePhone: 181-995-6635\n" +
      "pager: 586-905-4185\n" +
      "mobile: 826-857-7592\n" +
      "street: 46168 Mill Street\n" +
      "l: Charleston\n" +
      "st: CO\n" +
      "postalCode: 60948\n" +
      "postalAddress: Annalee Avard$46168 Mill Street$Charleston, CO  60948\n" +
      "description: This is the description for Annalee Avard.\n" +
      "\n" +
      "dn: uid=user.362,dc=example1,dc=com\n" +
      "objectClass: top\n" +
      "objectClass: person\n" +
      "objectClass: organizationalPerson\n" +
      "objectClass: inetOrgPerson\n" +
      "givenName: Andaree\n" +
      "sn: Asawa\n" +
      "cn: Andaree Asawa\n" +
      "initials: AEA\n" +
      "employeeNumber: 362\n" +
      "uid: user.362\n" +
      "mail: user.362@example.com\n" +
      "userPassword: password\n" +
      "telephoneNumber: 399-788-7334\n" +
      "homePhone: 798-076-5683\n" +
      "pager: 034-026-9411\n" +
      "mobile: 948-743-9197\n" +
      "street: 81028 Forest Street\n" +
      "l: Wheeling\n" +
      "st: IA\n" +
      "postalCode: 60905\n" +
      "postalAddress: Andaree Asawa$81028 Forest Street$Wheeling, IA  60905\n" +
      "description: This is the description for Andaree Asawa.\n";
  private String replacement1 =
      "dn: uid=user.446,dc=example1,dc=com\n" +
      "objectClass: top\n" +
      "objectClass: person\n" +
      "objectClass: organizationalPerson\n" +
      "objectClass: inetOrgPerson\n" +
      "givenName: Annalee\n" +
      "sn: Bogard\n" +
      "cn: Annalee Bogard\n" +
      "initials: ANG\n" +
      "employeeNumber: 446\n" +
      "uid: user.446\n" +
      "mail: user.446@example.com\n" +
      "userPassword: password\n" +
      "telephoneNumber: 875-335-8882\n" +
      "homePhone: 181-995-6635\n" +
      "pager: 586-905-4185\n" +
      "mobile: 826-857-7592\n" +
      "street: 43221 Hill Street\n" +
      "l: Charleston\n" +
      "st: CO\n" +
      "postalCode: 60918\n" +
      "postalAddress: Annalee Avard$43221 Hill Street$Charleston, CO  60918\n" +
      "description: This is the description for Annalee Bogard.\n";
  @BeforeClass
  public void setUp() throws Exception
  {
    // This test suite depends on having the schema available, so we'll make
    // sure the server is started.
    TestCaseUtils.startServer();
    tempDir = TestCaseUtils.createTemporaryDirectory("jebimporttest");
    homeDirName = tempDir.getAbsolutePath();
    importDirName = homeDirName + File.separator + "importTmp";
    EnvManager.createHomeDir(homeDirName);
    FileOutputStream ldifFile = new FileOutputStream(homeDirName + File.separator + "top.ldif");
    PrintStream writer = new PrintStream(ldifFile);
    writer.println(top);
    writer.close();
    ldifFile.close();
    ldifFile = new FileOutputStream(homeDirName + File.separator + "entries1.ldif");
    writer = new PrintStream(ldifFile);
    writer.println(entries1);
    writer.close();
    ldifFile.close();
    ldifFile = new FileOutputStream(homeDirName + File.separator + "replacement1.ldif");
    writer = new PrintStream(ldifFile);
    writer.println(replacement1);
    writer.close();
    ldifFile.close();
    Entry configEntry = TestCaseUtils.makeEntry(
      "dn: ds-cfg-backend-id=userRoot,cn=Backends,cn=config",
      "objectClass: top",
      "objectClass: ds-cfg-backend",
      "objectClass: ds-cfg-je-backend",
      "ds-cfg-backend-enabled: true",
      "ds-cfg-backend-class: org.opends.server.backends.jeb.BackendImpl",
      "ds-cfg-backend-id: userRoot",
      "ds-cfg-backend-directory:: " + Base64.encode(homeDirName.getBytes()),
      "ds-cfg-backend-import-temp-directory:: " + Base64.encode(importDirName.getBytes()));
    ConfigEntry backendConfigEntry = new ConfigEntry(configEntry, null);
    Entry indexEntry = TestCaseUtils.makeEntry(
      "dn: cn=Index,ds-cfg-backend-id=userRoot,cn=Backends,cn=config\n" +
      "objectClass: top\n" +
      "objectClass: ds-cfg-branch\n" +
      "cn: Index");
    ConfigEntry indexConfigEntry = new ConfigEntry(indexEntry, backendConfigEntry);
    Entry cnIndexEntry = TestCaseUtils.makeEntry(
      "dn: ds-cfg-index-attribute=cn,cn=Index,ds-cfg-backend-id=userRoot,cn=Backends,cn=config\n" +
      "objectClass: top\n" +
      "objectClass: ds-cfg-je-index\n" +
      "ds-cfg-index-attribute: cn\n" +
      "ds-cfg-index-type: presence\n" +
      "ds-cfg-index-type: equality\n" +
      "ds-cfg-index-type: substring\n" +
      "ds-cfg-index-type: ordering");
    ConfigEntry cnIndexConfigEntry = new ConfigEntry(cnIndexEntry, indexConfigEntry);
    indexConfigEntry.addChild(cnIndexConfigEntry);
    backendConfigEntry.addChild(indexConfigEntry);
    baseDNs = new DN[]
    {
      DN.decode("dc=example,dc=com"),
      DN.decode("dc=example1,dc=com")
    };
    backendConfig = new Config();
    backendConfig.initializeConfig(backendConfigEntry, baseDNs);
  }
  @AfterClass
  public void cleanUp() throws Exception
  {
    TestCaseUtils.deleteDirectory(tempDir);
  }
  @Test
  public void testImportAll() throws Exception
  {
    ArrayList<String> fileList = new ArrayList<String>();
    fileList.add(homeDirName + File.separator + "top.ldif");
    fileList.add(homeDirName + File.separator + "entries1.ldif");
    ByteArrayOutputStream rejectedEntries = new ByteArrayOutputStream();
    LDIFImportConfig importConfig = new LDIFImportConfig(fileList);
    importConfig.setAppendToExistingData(false);
    importConfig.setReplaceExistingEntries(false);
    importConfig.setValidateSchema(true);
    importConfig.writeRejectedEntries(rejectedEntries);
    ImportJob importJob = new ImportJob(null, backendConfig, importConfig);
    importJob.importLDIF();
    RootContainer rootContainer = new RootContainer(backendConfig, null);
    rootContainer.open();
    EntryContainer entryContainer;
    assertTrue(rejectedEntries.size() <= 0);
    for(DN baseDN : baseDNs)
    {
      entryContainer = rootContainer.openEntryContainer(baseDN);
      assertNotNull(entryContainer);
      if(baseDN.toString().equals("dc=example,dc=com"))
      {
        assertEquals(entryContainer.getEntryCount(), 4);
        assertTrue(entryContainer.entryExists(baseDN));
        assertTrue(entryContainer.entryExists(DN.decode("ou=People,dc=example,dc=com")));
        assertTrue(entryContainer.entryExists(DN.decode("uid=user.0,ou=People,dc=example,dc=com")));
        assertTrue(entryContainer.entryExists(DN.decode("uid=user.539,ou=People,dc=example,dc=com")));
        VerifyConfig verifyConfig = new VerifyConfig();
        verifyConfig.setBaseDN(baseDN);
        VerifyJob verifyJob = new VerifyJob(backendConfig, verifyConfig);
        Entry statEntry=bldStatEntry("");
        verifyJob.verifyBackend(rootContainer, statEntry);
        assertEquals(getStatEntryCount(statEntry, errorCount), 0);
      }
      else if(baseDN.toString().equals("dc=example1,dc=com"))
      {
        assertEquals(entryContainer.getEntryCount(), 3);
        assertTrue(entryContainer.entryExists(baseDN));
        assertTrue(entryContainer.entryExists(DN.decode("uid=user.446,dc=example1,dc=com")));
        assertTrue(entryContainer.entryExists(DN.decode("uid=user.362,dc=example1,dc=com")));
        VerifyConfig verifyConfig = new VerifyConfig();
        verifyConfig.setBaseDN(baseDN);
        VerifyJob verifyJob = new VerifyJob(backendConfig, verifyConfig);
        Entry statEntry=bldStatEntry("");
        verifyJob.verifyBackend(rootContainer, statEntry);
        assertEquals(getStatEntryCount(statEntry, errorCount), 0);
      }
    }
    rootContainer.close();
  }
  @Test(dependsOnMethods = "testImportAll")
  public void testImportReplaceExisting() throws Exception
  {
    ByteArrayOutputStream rejectedEntries = new ByteArrayOutputStream();
    LDIFImportConfig importConfig = new LDIFImportConfig(homeDirName + File.separator + "replacement1.ldif");
    importConfig.setAppendToExistingData(true);
    importConfig.setReplaceExistingEntries(true);
    importConfig.setValidateSchema(true);
    importConfig.writeRejectedEntries(rejectedEntries);
    ImportJob importJob = new ImportJob(null, backendConfig, importConfig);
    importJob.importLDIF();
    RootContainer rootContainer = new RootContainer(backendConfig, null);
    rootContainer.open();
    EntryContainer entryContainer;
    entryContainer = rootContainer.openEntryContainer(DN.decode("dc=example1,dc=com"));
    assertNotNull(entryContainer);
    assertTrue(rejectedEntries.size() <= 0);
    Entry entry = entryContainer.getEntry(DN.decode("uid=user.446,dc=example1,dc=com"));
    assertNotNull(entry);
    AttributeType attribute = entry.getAttribute("cn").get(0).getAttributeType();
    assertTrue(entry.hasValue(attribute, null, new AttributeValue(attribute,"Annalee Bogard")));
    VerifyConfig verifyConfig = new VerifyConfig();
    verifyConfig.setBaseDN(DN.decode("dc=example1,dc=com"));
    VerifyJob verifyJob = new VerifyJob(backendConfig, verifyConfig);
    Entry statEntry=bldStatEntry("");
    verifyJob.verifyBackend(rootContainer, statEntry);
    assertEquals(getStatEntryCount(statEntry, errorCount), 0);
    rootContainer.close();
  }
  @Test(dependsOnMethods = "testImportReplaceExisting")
  public void testImportNoParent() throws Exception
  {
    ByteArrayOutputStream rejectedEntries = new ByteArrayOutputStream();
    LDIFImportConfig importConfig = new LDIFImportConfig(homeDirName + File.separator + "replacement1.ldif");
    importConfig.setAppendToExistingData(false);
    importConfig.setReplaceExistingEntries(true);
    importConfig.setValidateSchema(true);
    importConfig.writeRejectedEntries(rejectedEntries);
    ImportJob importJob = new ImportJob(null, backendConfig, importConfig);
    importJob.importLDIF();
    assertTrue(rejectedEntries.toString().contains("uid=user.446,dc=example1,dc=com"));
  }
  @Test(dependsOnMethods = "testImportReplaceExisting")
  public void testImportAppend() throws Exception
  {
    LDIFImportConfig importConfig = new LDIFImportConfig(homeDirName + File.separator + "top.ldif");
    importConfig.setAppendToExistingData(false);
    importConfig.setReplaceExistingEntries(false);
    importConfig.setValidateSchema(true);
    ImportJob importJob = new ImportJob(null, backendConfig, importConfig);
    importJob.importLDIF();
    importConfig = new LDIFImportConfig(homeDirName + File.separator + "entries1.ldif");
    importConfig.setAppendToExistingData(true);
    importConfig.setReplaceExistingEntries(false);
    importConfig.setValidateSchema(true);
    importJob = new ImportJob(null, backendConfig, importConfig);
    importJob.importLDIF();
    RootContainer rootContainer = new RootContainer(backendConfig, null);
    rootContainer.open();
    EntryContainer entryContainer;
    for(DN baseDN : baseDNs)
    {
      entryContainer = rootContainer.openEntryContainer(baseDN);
      assertNotNull(entryContainer);
      if(baseDN.toString().equals("dc=example,dc=com"))
      {
        assertEquals(entryContainer.getEntryCount(), 4);
        assertTrue(entryContainer.entryExists(baseDN));
        assertTrue(entryContainer.entryExists(DN.decode("ou=People,dc=example,dc=com")));
        assertTrue(entryContainer.entryExists(DN.decode("uid=user.0,ou=People,dc=example,dc=com")));
        assertTrue(entryContainer.entryExists(DN.decode("uid=user.539,ou=People,dc=example,dc=com")));
      }
      else if(baseDN.toString().equals("dc=example1,dc=com"))
      {
        assertEquals(entryContainer.getEntryCount(), 3);
        assertTrue(entryContainer.entryExists(baseDN));
        assertTrue(entryContainer.entryExists(DN.decode("uid=user.446,dc=example1,dc=com")));
        assertTrue(entryContainer.entryExists(DN.decode("uid=user.362,dc=example1,dc=com")));
      }
    }
    rootContainer.close();
  }
  @Test(dependsOnMethods = "testImportAll")
  public void testImportNotReplaceExisting() throws Exception
  {
    ByteArrayOutputStream rejectedEntries = new ByteArrayOutputStream();
    LDIFImportConfig importConfig = new LDIFImportConfig(homeDirName + File.separator + "replacement1.ldif");
    importConfig.setAppendToExistingData(true);
    importConfig.setReplaceExistingEntries(false);
    importConfig.setValidateSchema(true);
    importConfig.writeRejectedEntries(rejectedEntries);
    ImportJob importJob = new ImportJob(null, backendConfig, importConfig);
    importJob.importLDIF();
    assertTrue(rejectedEntries.toString().contains("uid=user.446,dc=example1,dc=com"));
  }
      /**
     * 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));
    }
    /**
     * 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);
    }
}