/*
|
* 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
|
*
|
*
|
* Copyright 2006-2009 Sun Microsystems, Inc.
|
* Portions Copyright 2011-2013 ForgeRock AS
|
*/
|
package org.opends.server.backends.jeb;
|
|
import static org.assertj.core.api.Assertions.*;
|
import static org.opends.server.types.ConditionResult.*;
|
import static org.testng.Assert.*;
|
|
import java.util.*;
|
|
import org.opends.server.TestCaseUtils;
|
import org.opends.server.admin.server.AdminTestCaseUtils;
|
import org.opends.server.admin.std.meta.LocalDBBackendCfgDefn;
|
import org.opends.server.admin.std.server.LocalDBBackendCfg;
|
import org.opends.server.controls.SubtreeDeleteControl;
|
import org.opends.server.core.DeleteOperationBasis;
|
import org.opends.server.core.DirectoryServer;
|
import org.opends.server.core.ModifyDNOperationBasis;
|
import org.opends.server.core.ModifyOperationBasis;
|
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.types.*;
|
import org.opends.server.util.Base64;
|
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.LockMode;
|
|
/**
|
* BackendImpl Tester.
|
*/
|
@SuppressWarnings("javadoc")
|
public class TestBackendImpl extends JebTestCase {
|
private String homeDirName;
|
|
private BackendImpl backend;
|
|
private List<Entry> topEntries;
|
private List<Entry> entries;
|
private List<Entry> additionalEntries;
|
private Entry replaceEntry;
|
private Entry newTop;
|
|
/**
|
* 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 {
|
// This test suite depends on having the schema available, so we'll make
|
// sure the server is started.
|
TestCaseUtils.startServer();
|
TestCaseUtils.enableBackend("indexRoot");
|
|
homeDirName = "db_index_test";
|
|
backend = (BackendImpl)DirectoryServer.getBackend("indexRoot");
|
|
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",
|
"givenName;lang-fr: test2",
|
"givenName;lang-cn: test2",
|
"givenName;lang-es: test3",
|
"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",
|
"carLicense: 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",
|
"carLicense: 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",
|
"carLicense: 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",
|
"carLicense: 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",
|
"carLicense: 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",
|
"carLicense: 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",
|
"carLicense: 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",
|
"carLicense: 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",
|
"carLicense: 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",
|
"carLicense: 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",
|
"carLicense: 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",
|
"carLicense: 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",
|
"carLicense: 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",
|
"carLicense: 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",
|
"carLicense: 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",
|
"carLicense: 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"
|
);
|
|
}
|
|
@AfterClass
|
public void cleanUp() throws Exception {
|
TestCaseUtils.disableBackend("importRoot");
|
}
|
|
@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 {
|
InternalClientConnection conn =
|
InternalClientConnection.getRootConnection();
|
|
InternalSearchOperation search =
|
conn.processSearch(DN.decode("dc=test,dc=com"), SearchScope.BASE_OBJECT,
|
LDAPFilter.decode("(objectClass=*)").toSearchFilter());
|
List<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) {
|
assertThat(entry.getDN().toString()).isNotEqualTo("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 testNumSubordinates() throws Exception
|
{
|
DN dn = DN.decode("dc=test,dc=com");
|
assertEquals(backend.numSubordinates(dn, false), 1);
|
assertEquals(backend.numSubordinates(dn, true), 13);
|
dn = DN.decode("ou=People,dc=test,dc=com");
|
assertEquals(backend.numSubordinates(dn, false), 12);
|
assertEquals(backend.numSubordinates(dn, true), 12);
|
dn = DN.decode("dc=com");
|
assertEquals(backend.numSubordinates(dn, false), -1);
|
assertEquals(backend.numSubordinates(dn, true), -1);
|
dn = DN.decode("dc=test1,dc=com");
|
assertEquals(backend.numSubordinates(dn, false), 2);
|
assertEquals(backend.numSubordinates(dn, true), 2);
|
dn = DN.decode("uid=user.10,ou=People,dc=test,dc=com");
|
assertEquals(backend.numSubordinates(dn, false), 0);
|
assertEquals(backend.numSubordinates(dn, true), 0);
|
dn = DN.decode("uid=does not exist,ou=People,dc=test,dc=com");
|
assertEquals(backend.numSubordinates(dn, false), -1);
|
assertEquals(backend.numSubordinates(dn, true), -1);
|
}
|
|
@Test(dependsOnMethods = "testAdd")
|
public void testSearchIndex() throws Exception {
|
InternalClientConnection conn =
|
InternalClientConnection.getRootConnection();
|
Set<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);
|
|
List<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).toString();
|
assertTrue(debugString.split("cn").length <= 3);
|
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).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).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).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);
|
|
search = conn.processSearch(DN.decode("dc=test,dc=com"),
|
SearchScope.WHOLE_SUBTREE,
|
DereferencePolicy.NEVER_DEREF_ALIASES,
|
0,
|
0,
|
false,
|
LDAPFilter.decode("(cn~=Aartjan)").toSearchFilter(),
|
attribs);
|
result = search.getSearchEntries();
|
|
debugString =
|
result.get(0).getAttribute("debugsearchindex").get(0).toString();
|
assertTrue(!debugString.contains("NOT-INDEXED"));
|
finalStartPos = debugString.indexOf("final=") + 13;
|
finalEndPos = debugString.indexOf("]", finalStartPos);
|
finalCount = Integer.valueOf(debugString.substring(finalStartPos,
|
finalEndPos));
|
assertEquals(finalCount, 1);
|
}
|
|
@Test(dependsOnMethods = {"testAdd", "testSearchIndex",
|
"testSearchScope", "testSearchNotIndexed", "testModifyDNNewSuperior",
|
"testMatchedDN", "testNumSubordinates",
|
"testNumSubordinatesIndexEntryLimitExceeded"})
|
public void testDeleteSubtree() throws Exception {
|
Control control = new SubtreeDeleteControl(false);
|
List<Control> deleteSubTreeControl = new ArrayList<Control>();
|
deleteSubTreeControl.add(control);
|
InternalClientConnection conn =
|
InternalClientConnection.getRootConnection();
|
|
DeleteOperationBasis delete = new DeleteOperationBasis(conn,
|
InternalClientConnection.nextOperationID(),
|
InternalClientConnection.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"));
|
ec.sharedLock.lock();
|
try
|
{
|
assertFalse(ec.entryExists(DN.decode("dc=test1,dc=com")));
|
assertFalse(ec.entryExists(DN.decode("uid=user.362,dc=test1,dc=com")));
|
}
|
finally
|
{
|
ec.sharedLock.unlock();
|
}
|
}
|
|
@Test(dependsOnMethods = {"testAdd", "testSearchIndex",
|
"testSearchScope", "testMatchedDN"})
|
public void testDeleteEntry() throws Exception {
|
List<Control> noControls = new ArrayList<Control>(0);
|
InternalClientConnection conn =
|
InternalClientConnection.getRootConnection();
|
|
EntryContainer ec =
|
backend.getRootContainer().getEntryContainer(DN.decode("ou=People,dc=test,dc=com"));
|
|
ec.sharedLock.lock();
|
try
|
{
|
Entry entry =
|
ec.getEntry(DN.decode("uid=user.539,ou=People,dc=test,dc=com"));
|
EntryID entryID = ec.getDN2ID().get(null,
|
DN.decode("uid=user.539,ou=People,dc=test,dc=com"), LockMode.DEFAULT);
|
|
DeleteOperationBasis delete = new DeleteOperationBasis(conn,
|
InternalClientConnection.nextOperationID(),
|
InternalClientConnection.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"), LockMode.DEFAULT));
|
assertFalse(ec.getDN2URI().delete(null,
|
DN.decode("uid=user.539,ou=People,dc=test,dc=com")));
|
|
AttributeType attribute =
|
entries.get(0).getAttribute("cn").get(0).getAttributeType();
|
AttributeIndex index = ec.getAttributeIndex(attribute);
|
|
|
Indexer presenceIndexer = new PresenceIndexer(index.getAttributeType());
|
assertIndexContainsID(presenceIndexer, entry, index.presenceIndex,
|
entryID, FALSE);
|
|
Indexer equalityIndexer = new EqualityIndexer(index.getAttributeType());
|
assertIndexContainsID(equalityIndexer, entry, index.equalityIndex,
|
entryID, FALSE);
|
|
Indexer substringIndexer =
|
new SubstringIndexer(index.getAttributeType(),
|
index.getConfiguration().getSubstringLength());
|
assertIndexContainsID(substringIndexer, entry, index.substringIndex,
|
entryID, FALSE);
|
|
Indexer orderingIndexer = new OrderingIndexer(index.getAttributeType());
|
assertIndexContainsID(orderingIndexer, entry, index.orderingIndex,
|
entryID, FALSE);
|
}
|
finally
|
{
|
ec.sharedLock.unlock();
|
}
|
}
|
|
private void assertIndexContainsID(Indexer indexer, Entry entry, Index index,
|
EntryID entryID)
|
{
|
Set<byte[]> addKeys = new HashSet<byte[]>();
|
indexer.indexEntry(entry, addKeys);
|
|
DatabaseEntry key = new DatabaseEntry();
|
for (byte[] keyBytes : addKeys)
|
{
|
key.setData(keyBytes);
|
assertEquals(index.containsID(null, key, entryID), TRUE);
|
}
|
}
|
|
private void assertIndexContainsID(Indexer indexer, Entry entry,
|
Index index, EntryID entryID, ConditionResult expected)
|
{
|
Set<byte[]> addKeys = new HashSet<byte[]>();
|
indexer.indexEntry(entry, addKeys);
|
|
assertIndexContainsID(addKeys, index, entryID, expected);
|
}
|
|
private void assertIndexContainsID(Set<byte[]> addKeys, Index index,
|
EntryID entryID, ConditionResult expected)
|
{
|
DatabaseEntry key = new DatabaseEntry();
|
for (byte[] keyBytes : addKeys) {
|
key.setData(keyBytes);
|
}
|
assertEquals(index.containsID(null, key, entryID), expected);
|
}
|
|
@Test(dependsOnMethods = {"testSearchNotIndexed", "testAdd",
|
"testSearchIndex", "testSearchScope", "testMatchedDN",
|
"testNumSubordinates", "testNumSubordinatesIndexEntryLimitExceeded"})
|
public void testReplaceEntry() throws Exception {
|
Entry oldEntry = entries.get(0);
|
backend.replaceEntry(oldEntry, replaceEntry, null);
|
|
EntryContainer ec =
|
backend.getRootContainer().getEntryContainer(DN.decode("dc=test,dc=com"));
|
ec.sharedLock.lock();
|
try
|
{
|
Entry entry =
|
ec.getEntry(DN.decode("uid=user.0,ou=People,dc=test,dc=com"));
|
EntryID entryID = ec.getDN2ID().get(null,
|
DN.decode("uid=user.0,ou=People,dc=test,dc=com"), LockMode.DEFAULT);
|
|
assertNotNull(entry);
|
for (AttributeValue value : entry.getAttribute("cn").get(0)) {
|
assertEquals(value.getValue().toString(), "Testing Test");
|
}
|
for (AttributeValue value : entry.getAttribute("sn").get(0)) {
|
assertEquals(value.getValue().toString(), "Test");
|
}
|
for (AttributeValue value : entry.getAttribute("givenname").get(0)) {
|
assertEquals(value.getValue().toString(), "Testing");
|
}
|
for (AttributeValue value : entry.getAttribute("employeenumber").get(0)) {
|
assertEquals(value.getValue().toString(), "777");
|
}
|
|
AttributeType attribute =
|
entry.getAttribute("cn").get(0).getAttributeType();
|
AttributeIndex index = ec.getAttributeIndex(attribute);
|
|
Indexer orderingIndexer = new OrderingIndexer(index.getAttributeType());
|
assertIndexContainsID(orderingIndexer, entry, index.orderingIndex,
|
entryID, TRUE);
|
assertIndexContainsID(orderingIndexer, oldEntry, index.orderingIndex,
|
entryID, FALSE);
|
|
Indexer substringIndexer = new SubstringIndexer(index.getAttributeType(),
|
index.getConfiguration().getSubstringLength());
|
assertIndexContainsID(substringIndexer, entry, index.substringIndex,
|
entryID, TRUE);
|
assertIndexContainsID(substringIndexer, oldEntry, index.substringIndex,
|
entryID, FALSE);
|
|
Indexer equalityIndexer = new EqualityIndexer(index.getAttributeType());
|
assertIndexContainsID(equalityIndexer, entry, index.equalityIndex,
|
entryID, TRUE);
|
assertIndexContainsID(equalityIndexer, oldEntry, index.equalityIndex,
|
entryID, FALSE);
|
}
|
finally
|
{
|
ec.sharedLock.unlock();
|
}
|
}
|
|
@Test(dependsOnMethods = {"testSearchNotIndexed", "testAdd",
|
"testSearchIndex", "testSearchScope", "testMatchedDN",
|
"testNumSubordinates", "testNumSubordinatesIndexEntryLimitExceeded"})
|
public void testModifyEntry() throws Exception
|
{
|
Entry entry;
|
Entry newEntry;
|
EntryID entryID;
|
AttributeType attribute;
|
AttributeIndex titleIndex;
|
AttributeIndex nameIndex;
|
Set<byte[]> addKeys;
|
PresenceIndexer presenceIndexer;
|
EqualityIndexer equalityIndexer;
|
SubstringIndexer substringIndexer;
|
OrderingIndexer orderingIndexer;
|
|
EntryContainer ec = backend.getRootContainer().getEntryContainer(
|
DN.decode("dc=test,dc=com"));
|
ec.sharedLock.lock();
|
try
|
{
|
List<Modification> modifications = new ArrayList<Modification>();
|
modifications.add(new Modification(ModificationType.ADD, Attributes
|
.create("title", "debugger")));
|
|
AttributeBuilder builder = new AttributeBuilder("title");
|
builder.setOption("lang-en");
|
builder.add("debugger2");
|
|
modifications.add(new Modification(ModificationType.ADD, builder
|
.toAttribute()));
|
modifications.add(new Modification(ModificationType.DELETE,
|
Attributes.create("cn", "Aaren Atp")));
|
modifications.add(new Modification(ModificationType.ADD, Attributes
|
.create("cn", "Aaren Rigor")));
|
modifications.add(new Modification(ModificationType.ADD, Attributes
|
.create("cn", "Aarenister Rigor")));
|
|
builder = new AttributeBuilder("givenname");
|
builder.add("test");
|
builder.setOption("lang-de");
|
modifications.add(new Modification(ModificationType.ADD, builder
|
.toAttribute()));
|
|
builder = new AttributeBuilder("givenname");
|
builder.add("test2");
|
builder.setOption("lang-cn");
|
modifications.add(new Modification(ModificationType.DELETE, builder
|
.toAttribute()));
|
|
builder = new AttributeBuilder("givenname");
|
builder.add("newtest3");
|
builder.setOption("lang-es");
|
modifications.add(new Modification(ModificationType.REPLACE, builder
|
.toAttribute()));
|
|
modifications.add(new Modification(ModificationType.REPLACE,
|
Attributes.create("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"), LockMode.DEFAULT);
|
|
assertNotNull(entryID);
|
|
attribute = DirectoryServer.getAttributeType("title");
|
titleIndex = ec.getAttributeIndex(attribute);
|
attribute = DirectoryServer.getAttributeType("name");
|
nameIndex = ec.getAttributeIndex(attribute);
|
|
// This current entry in the DB shouldn't be in the presence
|
// titleIndex.
|
addKeys = new HashSet<byte[]>();
|
addKeys.add(AttributeIndex.presenceKey.getData());
|
assertIndexContainsID(addKeys, titleIndex.presenceIndex, entryID, FALSE);
|
|
// This current entry should be in the presence nameIndex.
|
addKeys = new HashSet<byte[]>();
|
addKeys.add(AttributeIndex.presenceKey.getData());
|
assertIndexContainsID(addKeys, nameIndex.presenceIndex, entryID, TRUE);
|
|
List<Control> noControls = new ArrayList<Control>(0);
|
InternalClientConnection conn = InternalClientConnection
|
.getRootConnection();
|
|
ModifyOperationBasis modifyOp = new ModifyOperationBasis(conn, InternalClientConnection
|
.nextOperationID(), InternalClientConnection.nextMessageID(), noControls, DN
|
.decode("uid=user.1,ou=People,dc=test,dc=com"), modifications);
|
|
backend.replaceEntry(entry, newEntry, modifyOp);
|
|
entry = ec.getEntry(DN.decode("uid=user.1,ou=People,dc=test,dc=com"));
|
|
assertTrue(entry.getAttribute("title").contains(
|
Attributes.create("title", "debugger")));
|
|
final Attribute cnAttr = entry.getAttribute("cn").get(0);
|
assertTrue(cnAttr.contains(AttributeValues.create(
|
cnAttr.getAttributeType(), "Aaren Rigor")));
|
assertTrue(cnAttr.contains(AttributeValues.create(
|
cnAttr.getAttributeType(), "Aarenister Rigor")));
|
assertFalse(cnAttr.contains(AttributeValues.create(
|
cnAttr.getAttributeType(), "Aaren Atp")));
|
|
Set<String> options = Collections.singleton("lang-de");
|
assertTrue(entry.getAttribute("givenname", options).get(0).contains(
|
AttributeValues.create(entry.getAttribute("givenname", options).get(0)
|
.getAttributeType(), "test")));
|
options = Collections.singleton("lang-cn");
|
assertNull(entry.getAttribute("givenname", options));
|
options = Collections.singleton("lang-es");
|
assertTrue(entry.getAttribute("givenname", options).get(0).contains(
|
AttributeValues.create(entry.getAttribute("givenname", options).get(0)
|
.getAttributeType(), "newtest3")));
|
options = Collections.singleton("lang-fr");
|
assertTrue(entry.getAttribute("givenname", options).get(0).contains(
|
AttributeValues.create(entry.getAttribute("givenname", options).get(0)
|
.getAttributeType(), "test2")));
|
|
assertTrue(entry.getAttribute("employeenumber").contains(
|
Attributes.create("employeenumber", "222")));
|
assertFalse(entry.getAttribute("employeenumber").contains(
|
Attributes.create("employeenumber", "1")));
|
|
presenceIndexer = new PresenceIndexer(titleIndex.getAttributeType());
|
assertIndexContainsID(presenceIndexer, entry, titleIndex.presenceIndex, entryID);
|
|
presenceIndexer = new PresenceIndexer(nameIndex.getAttributeType());
|
assertIndexContainsID(presenceIndexer, entry, nameIndex.presenceIndex, entryID);
|
|
orderingIndexer = new OrderingIndexer(titleIndex.getAttributeType());
|
assertIndexContainsID(orderingIndexer, entry, titleIndex.orderingIndex, entryID);
|
|
orderingIndexer = new OrderingIndexer(nameIndex.getAttributeType());
|
assertIndexContainsID(orderingIndexer, entry, nameIndex.orderingIndex, entryID);
|
|
equalityIndexer = new EqualityIndexer(titleIndex.getAttributeType());
|
assertIndexContainsID(equalityIndexer, entry, titleIndex.equalityIndex, entryID);
|
|
equalityIndexer = new EqualityIndexer(nameIndex.getAttributeType());
|
assertIndexContainsID(equalityIndexer, entry, nameIndex.equalityIndex, entryID);
|
|
substringIndexer = new SubstringIndexer(titleIndex.getAttributeType(),
|
titleIndex.getConfiguration().getSubstringLength());
|
assertIndexContainsID(substringIndexer, entry, titleIndex.substringIndex, entryID);
|
|
substringIndexer = new SubstringIndexer(nameIndex.getAttributeType(),
|
nameIndex.getConfiguration().getSubstringLength());
|
assertIndexContainsID(substringIndexer, entry, nameIndex.substringIndex, entryID);
|
}
|
finally
|
{
|
ec.sharedLock.unlock();
|
}
|
}
|
|
@Test(dependsOnMethods = {"testAdd", "testSearchIndex", "testSearchScope",
|
"testMatchedDN"})
|
public void testModifyDN() throws Exception {
|
EntryContainer ec =
|
backend.getRootContainer().getEntryContainer(DN.decode("dc=test,dc=com"));
|
ec.sharedLock.lock();
|
try
|
{
|
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"), LockMode.DEFAULT));
|
|
|
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"), LockMode.DEFAULT));
|
}
|
finally
|
{
|
ec.sharedLock.unlock();
|
}
|
}
|
|
@Test(dependsOnMethods = {"testSearchNotIndexed", "testAdd", "testSearchIndex",
|
"testSearchScope", "testModifyEntry", "testModifyDN", "testReplaceEntry",
|
"testDeleteEntry", "testMatchedDN", "testNumSubordinates",
|
"testNumSubordinatesIndexEntryLimitExceeded"})
|
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"));
|
ec.sharedLock.lock();
|
try
|
{
|
EntryID newSuperiorID = ec.getDN2ID().get(null, DN.decode("ou=JEB Testers,dc=test,dc=com"), LockMode.DEFAULT);
|
EntryID oldID = ec.getDN2ID().get(null,
|
DN.decode("ou=People,dc=test,dc=com"), LockMode.DEFAULT);
|
assertTrue(newSuperiorID.compareTo(oldID) > 0);
|
|
List<Control> noControls = new ArrayList<Control>(0);
|
InternalClientConnection conn =
|
InternalClientConnection.getRootConnection();
|
|
ModifyDNOperationBasis modifyDN = new ModifyDNOperationBasis(conn,
|
InternalClientConnection.nextOperationID(),
|
InternalClientConnection.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"), LockMode.DEFAULT);
|
assertNotNull(newID);
|
assertTrue(newID.compareTo(newSuperiorID) > 0);
|
DN subDN = DN.decode("uid=user.0,ou=Good People,ou=JEB Testers,dc=test,dc=com");
|
Entry subEntry = backend.getEntry(subDN);
|
assertNotNull(subEntry);
|
assertEquals(subDN, subEntry.getDN());
|
EntryID newSubordinateID = ec.getDN2ID().get(null, subDN, LockMode.DEFAULT);
|
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"), LockMode.DEFAULT));
|
}
|
finally
|
{
|
ec.sharedLock.unlock();
|
}
|
}
|
|
@Test(dependsOnMethods = {"testModifyDN",
|
"testSearchScope", "testSearchIndex", "testReplaceEntry",
|
"testModifyEntry", "testModifyDN", "testDeleteSubtree",
|
"testDeleteEntry", "testAddNoParent", "testAdd",
|
"testSearchNotIndexed",
|
"testModifyDNNewSuperior", "testApplyIndexConfig", "testMatchedDN"})
|
public void testApplyConfig() throws Exception {
|
Entry configEntry = TestCaseUtils.makeEntry(
|
"dn: ds-cfg-backend-id=indexRoot,cn=Backends,cn=config",
|
"objectClass: top",
|
"objectClass: ds-cfg-backend",
|
"objectClass: ds-cfg-local-db-backend",
|
"ds-cfg-base-dn: dc=test,dc=com",
|
"ds-cfg-base-dn: dc=newsuffix,dc=com",
|
"ds-cfg-enabled: true",
|
"ds-cfg-writability-mode: enabled",
|
"ds-cfg-java-class: org.opends.server.backends.jeb.BackendImpl",
|
"ds-cfg-backend-id: indexRoot",
|
"ds-cfg-db-directory:: " +
|
Base64.encode(homeDirName.getBytes()),
|
"ds-cfg-import-temp-directory: import-tmp");
|
|
LocalDBBackendCfg cfg = AdminTestCaseUtils.getConfiguration(
|
LocalDBBackendCfgDefn.getInstance(), configEntry);
|
|
backend.applyConfigurationChange(cfg);
|
|
RootContainer rootContainer = backend.getRootContainer();
|
|
assertNull(rootContainer.getEntryContainer(DN.decode("dc=test1,dc=com")));
|
|
assertNotNull(rootContainer.getEntryContainer(DN.decode("dc=newsuffix,dc=com")));
|
}
|
|
@Test(dependsOnMethods = {"testModifyDN",
|
"testSearchScope", "testSearchIndex", "testReplaceEntry",
|
"testModifyEntry", "testModifyDN", "testDeleteSubtree",
|
"testDeleteEntry", "testAddNoParent", "testAdd",
|
"testSearchNotIndexed",
|
"testModifyDNNewSuperior", "testMatchedDN"})
|
public void testApplyIndexConfig() throws Exception {
|
int resultCode = TestCaseUtils.applyModifications(true,
|
"dn: ds-cfg-attribute=givenName,cn=Index," +
|
"ds-cfg-backend-id=indexRoot,cn=Backends,cn=config",
|
"changetype: modify",
|
"replace: ds-cfg-index-type",
|
"ds-cfg-index-type: approximate");
|
|
assertEquals(resultCode, 0);
|
|
RootContainer rootContainer = backend.getRootContainer();
|
EntryContainer ec = rootContainer.getEntryContainer(DN.decode("dc=test,dc=com"));
|
|
AttributeIndex index =
|
ec.getAttributeIndex(DirectoryServer.getAttributeType("givenname"));
|
assertNull(index.equalityIndex);
|
assertNull(index.presenceIndex);
|
assertNull(index.substringIndex);
|
assertNull(index.orderingIndex);
|
assertNotNull(index.approximateIndex);
|
List<DatabaseContainer> databases = new ArrayList<DatabaseContainer>();
|
ec.listDatabases(databases);
|
boolean eqfound = false;
|
boolean prfound = false;
|
boolean subfound = false;
|
boolean orfound = false;
|
boolean apfound = false;
|
for(DatabaseContainer dc : databases)
|
{
|
if(dc.getName().toLowerCase().contains("givenname.approximate"))
|
{
|
apfound = true;
|
}
|
if(dc.getName().toLowerCase().contains("givenname.presence"))
|
{
|
prfound = true;
|
}
|
if(dc.getName().toLowerCase().contains("givenname.substring"))
|
{
|
subfound = true;
|
}
|
if(dc.getName().toLowerCase().contains("givenname.ordering"))
|
{
|
orfound = true;
|
}
|
if(dc.getName().toLowerCase().contains("givenname.equality"))
|
{
|
eqfound = true;
|
}
|
}
|
assertFalse(eqfound);
|
assertFalse(prfound);
|
assertFalse(subfound);
|
assertFalse(orfound);
|
assertTrue(apfound);
|
|
InternalClientConnection conn =
|
InternalClientConnection.getRootConnection();
|
Set<String> attribs = new LinkedHashSet<String>();
|
attribs.add(ATTR_DEBUG_SEARCH_INDEX);
|
|
InternalSearchOperation search =
|
conn.processSearch(DN.decode("dc=test,dc=com"),
|
|
SearchScope.SUBORDINATE_SUBTREE,
|
|
DereferencePolicy.NEVER_DEREF_ALIASES,
|
0,
|
0,
|
false,
|
|
LDAPFilter.decode("(givenName~=Aaccf)").
|
toSearchFilter(),
|
attribs);
|
|
List<SearchResultEntry> result = search.getSearchEntries();
|
|
//No indexes should be used.
|
String debugString =
|
result.get(0).getAttribute("debugsearchindex").get(0).toString();
|
assertTrue(debugString.contains("NOT-INDEXED"));
|
|
resultCode = TestCaseUtils.applyModifications(true,
|
"dn: ds-cfg-attribute=givenName,cn=Index," +
|
"ds-cfg-backend-id=indexRoot,cn=Backends,cn=config",
|
"changetype: modify",
|
"replace: ds-cfg-index-type",
|
"ds-cfg-index-type: equality",
|
"ds-cfg-index-type: presence",
|
"ds-cfg-index-type: ordering",
|
"ds-cfg-index-type: substring");
|
|
assertEquals(resultCode, 0);
|
|
assertNotNull(index.equalityIndex);
|
assertNotNull(index.presenceIndex);
|
assertNotNull(index.substringIndex);
|
assertNotNull(index.orderingIndex);
|
assertNull(index.approximateIndex);
|
databases = new ArrayList<DatabaseContainer>();
|
ec.listDatabases(databases);
|
eqfound = false;
|
prfound = false;
|
subfound = false;
|
orfound = false;
|
apfound = false;
|
for(DatabaseContainer dc : databases)
|
{
|
if(dc.getName().toLowerCase().contains("givenname.approximate"))
|
{
|
apfound = true;
|
}
|
if(dc.getName().toLowerCase().contains("givenname.presence"))
|
{
|
prfound = true;
|
}
|
if(dc.getName().toLowerCase().contains("givenname.substring"))
|
{
|
subfound = true;
|
}
|
if(dc.getName().toLowerCase().contains("givenname.ordering"))
|
{
|
orfound = true;
|
}
|
if(dc.getName().toLowerCase().contains("givenname.equality"))
|
{
|
eqfound = true;
|
}
|
}
|
assertTrue(eqfound);
|
assertTrue(prfound);
|
assertTrue(subfound);
|
assertTrue(orfound);
|
assertFalse(apfound);
|
|
// Delete the entries attribute index.
|
resultCode = TestCaseUtils.applyModifications(true,
|
"dn: ds-cfg-attribute=givenName,cn=Index," +
|
"ds-cfg-backend-id=indexRoot,cn=Backends,cn=config",
|
"changetype: delete");
|
|
assertEquals(resultCode, 0);
|
|
assertNull(ec.getAttributeIndex(
|
DirectoryServer.getAttributeType("givenname")));
|
databases = new ArrayList<DatabaseContainer>();
|
ec.listDatabases(databases);
|
for(DatabaseContainer dc : databases)
|
{
|
assertFalse(dc.getName().toLowerCase().contains("givenname"));
|
}
|
|
// Add it back
|
resultCode = TestCaseUtils.applyModifications(true,
|
"dn: ds-cfg-attribute=givenName,cn=Index," +
|
"ds-cfg-backend-id=indexRoot,cn=Backends,cn=config",
|
"changetype: add",
|
"objectClass: top",
|
"objectClass: ds-cfg-local-db-index",
|
"ds-cfg-attribute: givenName",
|
"ds-cfg-index-type: equality",
|
"ds-cfg-index-type: presence",
|
"ds-cfg-index-type: ordering",
|
"ds-cfg-index-type: substring");
|
|
assertEquals(resultCode, 0);
|
|
assertNotNull(ec.getAttributeIndex(
|
DirectoryServer.getAttributeType("givenname")));
|
databases = new ArrayList<DatabaseContainer>();
|
ec.listDatabases(databases);
|
eqfound = false;
|
prfound = false;
|
subfound = false;
|
orfound = false;
|
apfound = false;
|
for(DatabaseContainer dc : databases)
|
{
|
if(dc.getName().toLowerCase().contains("givenname.approximate"))
|
{
|
apfound = true;
|
}
|
if(dc.getName().toLowerCase().contains("givenname.presence"))
|
{
|
prfound = true;
|
}
|
if(dc.getName().toLowerCase().contains("givenname.substring"))
|
{
|
subfound = true;
|
}
|
if(dc.getName().toLowerCase().contains("givenname.ordering"))
|
{
|
orfound = true;
|
}
|
if(dc.getName().toLowerCase().contains("givenname.equality"))
|
{
|
eqfound = true;
|
}
|
}
|
assertTrue(eqfound);
|
assertTrue(prfound);
|
assertTrue(subfound);
|
assertTrue(orfound);
|
assertFalse(apfound);
|
|
// Make sure changing the index entry limit on an index where the limit
|
// is already exceeded causes warnings.
|
resultCode = TestCaseUtils.applyModifications(true,
|
"dn: ds-cfg-attribute=mail,cn=Index," +
|
"ds-cfg-backend-id=indexRoot,cn=Backends,cn=config",
|
"changetype: modify",
|
"replace: ds-cfg-index-entry-limit",
|
"ds-cfg-index-entry-limit: 30");
|
|
assertEquals(resultCode, 0);
|
|
// Make sure removing a index entry limit for an index makes it use the
|
// backend wide setting.
|
resultCode = TestCaseUtils.applyModifications(true,
|
"dn: ds-cfg-attribute=mail,cn=Index," +
|
"ds-cfg-backend-id=indexRoot,cn=Backends,cn=config",
|
"changetype: modify",
|
"delete: ds-cfg-index-entry-limit");
|
|
assertEquals(resultCode, 0);
|
}
|
|
|
|
@Test(dependsOnMethods = {"testDeleteEntry", "testSearchScope",
|
"testSearchIndex", "testMatchedDN"})
|
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()));
|
}
|
|
InternalClientConnection conn =
|
InternalClientConnection.getRootConnection();
|
Set<String> attribs = new LinkedHashSet<String>();
|
attribs.add(ATTR_DEBUG_SEARCH_INDEX);
|
|
InternalSearchOperation search =
|
conn.processSearch(DN.decode("dc=test,dc=com"),
|
SearchScope.SUBORDINATE_SUBTREE,
|
DereferencePolicy.NEVER_DEREF_ALIASES,
|
0,
|
0,
|
false,
|
LDAPFilter.decode("(carLicense=377*)").toSearchFilter(),
|
attribs);
|
|
List<SearchResultEntry> result = search.getSearchEntries();
|
|
//No indexes should be used.
|
String debugString =
|
result.get(0).getAttribute("debugsearchindex").get(0).toString();
|
assertThat(debugString).contains("NOT-INDEXED");
|
}
|
|
@Test(dependsOnMethods = "testSearchNotIndexed")
|
public void testNumSubordinatesIndexEntryLimitExceeded() throws Exception
|
{
|
DN dn = DN.decode("dc=test,dc=com");
|
assertEquals(backend.numSubordinates(dn, false), 1);
|
assertEquals(backend.numSubordinates(dn, true), 14);
|
|
// 1 entry was deleted and 2 added for a total of 13
|
dn = DN.decode("ou=People,dc=test,dc=com");
|
assertEquals(backend.numSubordinates(dn, false), 13);
|
assertEquals(backend.numSubordinates(dn, true), 13);
|
dn = DN.decode("dc=com");
|
assertEquals(backend.numSubordinates(dn, false), -1);
|
assertEquals(backend.numSubordinates(dn, true), -1);
|
dn = DN.decode("dc=test1,dc=com");
|
assertEquals(backend.numSubordinates(dn, false), 2);
|
assertEquals(backend.numSubordinates(dn, true), 2);
|
dn = DN.decode("uid=user.10,ou=People,dc=test,dc=com");
|
assertEquals(backend.numSubordinates(dn, false), 0);
|
assertEquals(backend.numSubordinates(dn, true), 0);
|
dn = DN.decode("uid=does not exist,ou=People,dc=test,dc=com");
|
assertEquals(backend.numSubordinates(dn, false), -1);
|
assertEquals(backend.numSubordinates(dn, true), -1);
|
}
|
|
|
/**
|
* Provides a set of DNs for the matched DN test case.
|
*
|
* @return set of DNs
|
* @throws Exception when DN.decode fails
|
*/
|
@DataProvider(name = "MatchedDNs")
|
public Object[][] initMatchedDNs() throws Exception {
|
|
ResultCode success = ResultCode.SUCCESS;
|
ResultCode noSuchObject = ResultCode.NO_SUCH_OBJECT;
|
|
DN testComDN = DN.decode( "dc=test,dc=com");
|
DN dummyTestComDN = DN.decode( "cn=dummy,dc=test,dc=com");
|
DN peopleTestComDN = DN.decode( "ou=people,dc=test,dc=com");
|
DN dummyPeopleTestComDN = DN.decode("cn=dummy,ou=people,dc=test,dc=com");
|
|
// Sets of DNs
|
return new Object[][] {
|
{testComDN, null, success},
|
{peopleTestComDN, null, success},
|
{dummyTestComDN, testComDN, noSuchObject},
|
{dummyPeopleTestComDN, peopleTestComDN, noSuchObject},
|
};
|
}
|
|
|
/**
|
* Executes an internal search operation and check the result code and
|
* matched DN field.
|
*
|
* @param searchBaseDN the search base DN to use for the current test
|
* @param expectedResultCode the expected LDAP result code
|
* @param expectedMatchedDN the expected matched DN, may be <code>null</code>
|
*/
|
@Test(dataProvider = "MatchedDNs", dependsOnMethods = "testAdd")
|
public void testMatchedDN(
|
DN searchBaseDN,
|
DN expectedMatchedDN,
|
ResultCode expectedResultCode
|
) throws Exception
|
{
|
InternalClientConnection conn =
|
InternalClientConnection.getRootConnection();
|
|
// Filter for the search
|
SearchFilter filter = LDAPFilter.decode("(objectClass=*)").toSearchFilter();
|
|
// Test is performed with each and every scope
|
for (SearchScope scope: SearchScope.values())
|
{
|
InternalSearchOperation searchOperation =
|
conn.processSearch(searchBaseDN, scope, filter);
|
|
assertEquals(searchOperation.getResultCode(), expectedResultCode);
|
assertEquals(searchOperation.getMatchedDN(), expectedMatchedDN);
|
}
|
}
|
|
}
|