/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at legal-notices/CDDLv1_0.txt.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information:
* Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
*
* Copyright 2006-2008 Sun Microsystems, Inc.
* Portions Copyright 2011-2015 ForgeRock AS.
*/
/**
* A set of test cases for add operations.
*/
@SuppressWarnings("javadoc")
public class AddOperationTestCase
extends OperationTestCase
{
/** Some of the tests disable the backends, so we reenable them here. */
@AfterMethod(alwaysRun=true)
}
/**
* Retrieves a set of add operations that may be used for testing.
*
* @return A set of add operations that may be used for testing.
*
* @throws Exception If an unexpected problem occurs.
*/
{
"dn: ou=People,o=test",
"objectClass: top",
"objectClass: organizationalUnit",
"ou: People");
{
};
{
}
return objArray;
}
/** {@inheritDoc} */
{
{
}
return ops;
}
/**
* Tests the <CODE>getRawEntryDN</CODE> and <CODE>setRawEntryDN</CODE>
* methods.
*
* @param addOperation The add operation to be tested.
*/
{
}
/**
* Tests the <CODE>getEntryDN</CODE> method for the case in which we expect
* the rawEntryDN to be decoded.
*/
@Test
public void testGetEntryDNInitiallyNull()
{
}
{
return newArrayList(attributes);
}
{
for (String s : v)
{
}
return values;
}
/**
* Tests the <CODE>getEntryDN</CODE> method for the case in which we expect
* the DN to be initially non-null.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
"dn: ou=People,o=test",
"objectClass: top",
"objectClass: organizationalUnit",
"ou: People");
}
/**
* Tests the <CODE>getEntryDN</CODE> method for the case in which we expect
* the DN to be initially non-null but then becomes null after the raw DN is
* changed, and <CODE>getEntryDN</CODE> method recomputes it again
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
"dn: ou=People,o=test",
"objectClass: top",
"objectClass: organizationalUnit",
"ou: People");
}
/**
* Tests the <CODE>getRawAttributes</CODE>, <CODE>addRawAttribute</CODE>, and
* <CODE>setRawAttributes</CODE> methods.
*
* @param addOperation The add operation to be tested.
*/
{
}
{
{
{
return true;
}
}
return false;
}
/**
* Tests the <CODE>addObjectClass</CODE> method.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
"dn: ou=People,o=test",
"objectClass: top",
"objectClass: organizationalUnit",
"ou: People");
}
/**
* Tests the <CODE>removeObjectClass</CODE> method.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
"dn: ou=People,o=test",
"objectClass: top",
"objectClass: organizationalUnit",
"objectClass: extensibleObject",
"ou: People");
}
/**
* Tests the <CODE>setAttribute</CODE> method for an attribute that already
* exists.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
"dn: ou=People,o=test",
"objectClass: top",
"objectClass: organizationalUnit",
"ou: People",
"description: foo");
boolean foundFoo = false;
boolean foundBar = false;
{
{
foundFoo = true;
}
{
foundBar = true;
}
}
}
/**
* Tests the <CODE>setAttribute</CODE> method for an attribute that doesn't
* exist.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
"dn: ou=People,o=test",
"objectClass: top",
"objectClass: organizationalUnit",
"ou: People");
}
/**
* Tests the <CODE>removeAttribute</CODE> method.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
"dn: ou=People,o=test",
"objectClass: top",
"objectClass: organizationalUnit",
"ou: People",
"description: foo");
}
/**
* Invokes methods to retrieve members of an add operation after it has
* completed.
*
* @param addOperation The add operation to examine. It should have
* completed successfully.
*/
{
}
/**
* Tests an internal add operation that should be successful using raw
* arguments.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
}
/**
* Tests an internal add operation that should be successful using processed
* arguments.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
"dn: ou=People,o=test",
"objectClass: top",
"objectClass: organizationalUnit",
"ou: People");
}
/**
* Tests an internal add operation that fails because it contains a malformed
* DN.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
}
/**
* Tests an internal add operation that fails because it contains the DN of
* an entry that already exists.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
}
/**
* Tests an internal add operation that fails because it is a suffix that
* doesn't exist.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
}
/**
* Tests an internal add operation that fails because it is below a suffix
* that doesn't exist.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
}
/**
* Tests an internal add operation that fails because its parent does not exist.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
}
/**
* Tests an external add operation that fails because it contains an attribute
* that is marked no-user-modification.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
LDAPReader r = new LDAPReader(s);
LDAPWriter w = new LDAPWriter(s);
bind(r, w);
addSuccess(r, w, attrs);
StaticUtils.close(s);
}
/**
* Tests an internal add operation that fails because it has an undefined
* objectclass.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
AddOperation addOperation = getRootConnection().processAdd(ByteString.valueOfUtf8("ou=People,o=test"), attrs);
}
/**
* Tests a successful internal add operation that contains a user-modifiable
* operational attribute.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password",
"ds-pwp-password-policy-dn: cn=Clear UserPassword Policy," +
"cn=Password Policies,cn=config");
}
/**
* Tests a successful internal add operation that contains an attribute with
* multiple values where the values are spread throughout the entry.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
AddOperation addOperation = getRootConnection().processAdd(ByteString.valueOfUtf8("ou=People,o=test"), attrs);
}
/**
* Tests a successful internal add operation that contains raw attributes with
* options.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
AddOperation addOperation = getRootConnection().processAdd(ByteString.valueOfUtf8("ou=People,o=test"), attrs);
}
/**
* Tests a successful internal add operation that contains raw attributes with
* options and an attribute that doesn't have any values without options.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
AddOperation addOperation = getRootConnection().processAdd(ByteString.valueOfUtf8("ou=People,o=test"), attrs);
}
/**
* Tests a successful internal add operation that contains attributes with
* options.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"uid;lang-en-us: test.user",
"givenName: Test",
"givenName;lang-en-us: Test",
"sn: User",
"sn;lang-en-us: User",
"cn: Test User",
"cn;lang-en-us: Test User",
"userPassword: password");
}
/**
* Tests an internal add operation that fails because it attempts to add the
* root DSE.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
}
/**
* Tests a successful internal add operation that is missing RDN attributes.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
"dn: ou=People,o=test",
"objectClass: top",
"objectClass: organizationalUnit");
}
/**
* Tests a failed internal add operation that is missing RDN attributes.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
"dn: ou=People,o=test",
"objectClass: top",
"objectClass: organizationalUnit");
}
/**
* Tests a successful internal add operation that is missing an objectclass
* in the hierarchical chain.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
"dn: uid=test.user,o=test",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password");
boolean found = false;
{
for (ByteString v : a)
{
{
found = true;
break;
}
}
}
}
/**
* Tests a failed internal add operation that doesn't have any objectclasses.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
"dn: ou=People,o=test",
"ou: People");
}
/**
* Tests a failed internal add operation that only has an abstract
* objectclass.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
"dn: ou=People,o=test",
"objectClass: top",
"ou: People");
}
/**
* Tests a failed internal add operation that doesn't have any structural
* objectclass (only abstract and auxiliary).
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
"dn: ou=People,o=test",
"objectClass: top",
"objectClass: extensibleObject",
"ou: People");
}
/**
* Tests a failed internal add operation that has multiple structural
* objectclasses.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
"dn: ou=People,o=test",
"objectClass: top",
"objectClass: organizationalUnit",
"objectClass: person",
"ou: People",
"cn: Test User",
"sn: User");
}
/**
* Tests a failed internal add operation that is missing a required attribute.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"userPassword: password"); // Missing cn
}
/**
* Tests a failed internal add operation that is missing a required attribute
* but has the extensibleObject objectClass (which shouldn't change anything).
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"objectClass: extensibleObject",
"uid: test.user",
"givenName: Test",
"sn: User",
"userPassword: password"); // Missing cn
}
/**
* Tests a failed internal add operation that contains an attribute not
* allowed by any objectclass.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password",
"dc: Not allowed by inetOrgPerson");
}
/**
* Tests a successful internal add operation that contains an attribute not
* allowed by any standard objectclass in the entry but is allowed by
* extensibleObject.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"objectClass: extensibleObject",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password",
"dc: Not allowed by inetOrgPerson but allowed by extensibleObject");
}
/**
* Tests the behavior of the server when attempting to perform an add \
* operation with an entry containing an attribute with zero values.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
TestCaseUtils.initializeTestBackend(false);
"dn: o=test",
"objectClass: top",
"objectClass: organization",
"o: test");
}
/**
* Tests a failed internal add operation with the server in complete read-only
* mode.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password");
}
/**
* Tests a successful internal add operation with the server in read-only mode
* for external operations but allowed for internal operations.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password");
}
/**
* Tests a failed external add operation with the server in read-only mode
* for external operations but allowed for internal operations.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
LDAPReader r = new LDAPReader(s);
LDAPWriter w = new LDAPWriter(s);
bind(r, w);
addSuccess(r, w, attrs);
StaticUtils.close(s);
}
{
}
{
}
/**
* Tests a failed internal add operation with the backend in complete
* read-only mode.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password");
}
/**
* Tests a successful internal add operation with the backend in read-only
* mode for external operations but allowed for internal operations.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
"dn: uid=test.user,o=test",
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
"objectClass: inetOrgPerson",
"uid: test.user",
"givenName: Test",
"sn: User",
"cn: Test User",
"userPassword: password");
}
/**
* Tests a failed external add operation with the backend in read-only mode
* for external operations but allowed for internal operations.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
LDAPReader r = new LDAPReader(s);
LDAPWriter w = new LDAPWriter(s);
bind(r, w);
addSuccess(r, w, attrs);
StaticUtils.close(s);
}
/**
* Tests to ensure that any registered add notification listeners are invoked
* for a successful add operation.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
try{
"dn: ou=People,o=test",
"objectClass: top",
"objectClass: organizationalUnit",
"ou: People");
}finally {
}
}
/**
* Tests to ensure that any registered add notification listeners are not
* invoked for a failed add operation.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
try{
"dn: ou=People,ou=nonexistent,o=test",
"objectClass: top",
"objectClass: organizationalUnit",
"ou: People");
}finally {
}
}
/**
* Tests an add operation that gets canceled before startup.
*
* @throws Exception If an unexpected probem occurs.
*/
@Test
{
"dn: ou=People,o=test",
"objectClass: top",
"objectClass: organizationalUnit",
"ou: People");
addOperation.run();
}
/**
* Tests an add operation that gets canceled before startup.
*
* @throws Exception If an unexpected probem occurs.
*/
@Test
{
"dn: ou=People,o=test",
"objectClass: top",
"objectClass: organizationalUnit",
"ou: People");
addOperation.run();
}
/**
* Tests an add operation in which the server cannot obtain a lock on the
* target entry because there is already a read lock held on it.
*
* @throws Exception If an unexpected problem occurs.
*/
{
final DNLock entryLock = DirectoryServer.getLockManager().tryReadLockEntry(DN.valueOf("ou=People,o=test"));
try
{
"dn: ou=People,o=test",
"objectClass: top",
"objectClass: organizationalUnit",
"ou: People");
}
finally
{
}
}
/**
* Tests an add operation that should be disconnected in a pre-parse plugin.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
LDAPReader r = new LDAPReader(s);
LDAPWriter w = new LDAPWriter(s);
bind(r, w);
StaticUtils.close(s);
}
{
{
// If we got an element back, then it must be a notice of disconnect
// unsolicited notification.
}
}
{
AddRequestProtocolOp addRequest = new AddRequestProtocolOp(ByteString.valueOfUtf8("ou=People,o=test"), attrs);
: null;
}
/**
* Tests an add operation that should be disconnected in a pre-operation
* plugin.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
LDAPReader r = new LDAPReader(s);
LDAPWriter w = new LDAPWriter(s);
bind(r, w);
StaticUtils.close(s);
}
/**
* Tests an add operation that should be disconnected in a post-operation
* plugin.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
LDAPReader r = new LDAPReader(s);
LDAPWriter w = new LDAPWriter(s);
bind(r, w);
StaticUtils.close(s);
}
/**
* Tests an add operation that should be disconnected in a post-response
* plugin.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
LDAPReader r = new LDAPReader(s);
LDAPWriter w = new LDAPWriter(s);
//TestCaseUtils.configureSocket(s);
bind(r, w);
while (true)
{
{
// The connection has been closed.
break responseLoop;
}
switch (message.getProtocolOpType())
{
case OP_TYPE_ADD_RESPONSE:
// This was expected. The disconnect didn't happen until after the
// response was sent.
break;
// The server is notifying us that it will be closing the connection.
break responseLoop;
default:
// This is a problem. It's an unexpected response.
StaticUtils.close(s);
" encountered in " +
"testDisconnectInPostResponseAdd");
}
}
StaticUtils.close(s);
}
/**
* Tests an add operation that attempts to add an entry with a user attribute
* marked OBSOLETE in the server schema.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
TestCaseUtils.initializeTestBackend(false);
"dn: cn=schema",
"changetype: modify",
"add: attributeTypes",
"attributeTypes: ( testaddobsoleteuserattribute-oid " +
"NAME 'testAddObsoleteUserAttribute' OBSOLETE " +
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE " +
"X-ORGIN 'SchemaBackendTestCase' )");
{
"-h", "127.0.0.1",
"-D", "cn=Directory Manager",
"-w", "password",
"-f", path
};
"dn: o=test",
"changetype: add",
"objectClass: top",
"objectClass: organization",
"objectClass: extensibleObject",
"o: test",
"testAddObsoleteUserAttribute: foo");
{
"-h", "127.0.0.1",
"-D", "cn=Directory Manager",
"-w", "password",
"-f", path
};
}
/**
* Tests an add operation that attempts to add an entry with an operational
* attribute marked OBSOLETE in the server schema.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
TestCaseUtils.initializeTestBackend(false);
"dn: cn=schema",
"changetype: modify",
"add: attributeTypes",
"attributeTypes: ( testaddobsoleteoperationalattribute-oid " +
"NAME 'testAddObsoleteOperationalAttribute' OBSOLETE " +
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE " +
"USAGE directoryOperation X-ORGIN 'SchemaBackendTestCase' )");
{
"-h", "127.0.0.1",
"-D", "cn=Directory Manager",
"-w", "password",
"-f", path
};
"dn: o=test",
"changetype: add",
"objectClass: top",
"objectClass: organization",
"objectClass: extensibleObject",
"o: test",
"testAddObsoleteOperationalAttribute: foo");
{
"-h", "127.0.0.1",
"-D", "cn=Directory Manager",
"-w", "password",
"-f", path
};
}
/**
* Tests an add operation that attempts to add an entry with an auxiliary
* objectclass marked OBSOLETE in the server schema.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
TestCaseUtils.initializeTestBackend(false);
"dn: cn=schema",
"changetype: modify",
"add: objectClasses",
"objectClasses: ( testaddobsoleteobjectclass-oid " +
"NAME 'testAddObsoleteObjectClass' OBSOLETE AUXILIARY " +
"MAY description X-ORGIN 'SchemaBackendTestCase' )");
{
"-h", "127.0.0.1",
"-D", "cn=Directory Manager",
"-w", "password",
"-f", path
};
"dn: o=test",
"changetype: add",
"objectClass: top",
"objectClass: organization",
"objectClass: testAddObsoleteObjectClass",
"o: test");
{
"-h", "127.0.0.1",
"-D", "cn=Directory Manager",
"-w", "password",
"-f", path
};
}
/**
* Tests the behavior of the server when short-circuiting out of an add
* operation in the pre-parse phase with a success result code.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test
{
TestCaseUtils.initializeTestBackend(false);
addOperation.run();
}
}