You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ak...@apache.org on 2008/08/06 00:40:37 UTC
svn commit: r683013 - in /directory/apacheds/branches/bigbang:
server-integ/src/test/java/org/apache/directory/server/operations/modifydn/
server-unit/src/test/java/org/apache/directory/server/
Author: akarasulu
Date: Tue Aug 5 15:40:37 2008
New Revision: 683013
URL: http://svn.apache.org/viewvc?rev=683013&view=rev
Log:
converted modify rdn tests to use server-integ but some failures occur due to international characters which was working before
Added:
directory/apacheds/branches/bigbang/server-integ/src/test/java/org/apache/directory/server/operations/modifydn/
directory/apacheds/branches/bigbang/server-integ/src/test/java/org/apache/directory/server/operations/modifydn/ModifyRdnIT.java
Removed:
directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/ModifyRdnTest.java
Added: directory/apacheds/branches/bigbang/server-integ/src/test/java/org/apache/directory/server/operations/modifydn/ModifyRdnIT.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/server-integ/src/test/java/org/apache/directory/server/operations/modifydn/ModifyRdnIT.java?rev=683013&view=auto
==============================================================================
--- directory/apacheds/branches/bigbang/server-integ/src/test/java/org/apache/directory/server/operations/modifydn/ModifyRdnIT.java (added)
+++ directory/apacheds/branches/bigbang/server-integ/src/test/java/org/apache/directory/server/operations/modifydn/ModifyRdnIT.java Tue Aug 5 15:40:37 2008
@@ -0,0 +1,1043 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.directory.server.operations.modifydn;
+
+
+import javax.naming.NameNotFoundException;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.NoPermissionException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.SchemaViolationException;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+
+import org.apache.directory.shared.ldap.message.AttributeImpl;
+import org.apache.directory.shared.ldap.message.AttributesImpl;
+
+import org.apache.directory.server.core.integ.Level;
+import org.apache.directory.server.core.integ.annotations.CleanupLevel;
+import org.apache.directory.server.integ.SiRunner;
+import org.apache.directory.server.newldap.LdapServer;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.apache.directory.server.integ.ServerIntegrationUtils.getWiredContext;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+
+/**
+ * Test case with different modify DN operations on a person entry.
+ * Originally created to demonstrate DIREVE-173.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev: 679049 $
+ */
+@RunWith ( SiRunner.class )
+@CleanupLevel ( Level.SUITE )
+public class ModifyRdnIT
+{
+ private static final String BASE = "ou=system";
+
+ public static LdapServer ldapServer;
+
+
+ /**
+ * Create attributes for a person entry.
+ */
+ private Attributes getPersonAttributes( String sn, String cn )
+ {
+ Attributes attributes = new AttributesImpl();
+ Attribute attribute = new AttributeImpl( "objectClass" );
+ attribute.add( "top" );
+ attribute.add( "person" );
+ attributes.put( attribute );
+ attributes.put( "cn", cn );
+ attributes.put( "sn", sn );
+ attributes.put( "description", cn + " is a person." );
+
+ return attributes;
+ }
+
+
+ /**
+ * Create attributes for a organizational unit entry.
+ */
+ private Attributes getOrganizationalUnitAttributes( String ou )
+ {
+ Attributes attributes = new AttributesImpl();
+ Attribute attribute = new AttributeImpl( "objectClass" );
+ attribute.add( "top" );
+ attribute.add( "organizationalUnit" );
+ attributes.put( attribute );
+ attributes.put( "ou", ou );
+ attributes.put( "description", ou + " is an organizational unit." );
+
+ return attributes;
+ }
+
+
+ /**
+ * Modify Rdn of an entry, delete its old rdn value.
+ */
+ @Test
+ public void testModifyRdnAndDeleteOld() throws Exception
+ {
+ DirContext ctx = ( DirContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ // Create a person, cn value is rdn
+ String oldCn = "Myra Ellen Amos";
+ String oldRdn = "cn=" + oldCn;
+ Attributes attributes = this.getPersonAttributes( "Amos", oldCn );
+ ctx.createSubcontext( oldRdn, attributes );
+
+ // modify Rdn
+ String newCn = "Tori Amos";
+ String newRdn = "cn=" + newCn;
+ ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "true" );
+ ctx.rename( oldRdn, newRdn );
+
+ // Check, whether old Entry does not exists
+ try
+ {
+ ctx.lookup( oldRdn );
+ fail( "Entry must not exist" );
+ }
+ catch ( NameNotFoundException ignored )
+ {
+ // expected behaviour
+ assertTrue( true );
+ }
+
+ // Check, whether new Entry exists
+ DirContext tori = ( DirContext ) ctx.lookup( newRdn );
+ assertNotNull( tori );
+
+ // Check values of cn
+ Attribute cn = tori.getAttributes( "" ).get( "cn" );
+ assertTrue( cn.contains( newCn ) );
+ assertTrue( !cn.contains( oldCn ) ); // old value is gone
+ assertEquals( 1, cn.size() );
+
+ // Remove entry (use new rdn)
+ ctx.unbind( newRdn );
+ }
+
+
+ /**
+ * Modify Rdn of an entry, without deleting its old rdn value.
+ *
+ * The JNDI property is set with 'False'
+ */
+ @Test
+ public void testModifyRdnAndDontDeleteOldFalse() throws Exception
+ {
+ DirContext ctx = ( DirContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ // Create a person, cn value is rdn
+ String oldCn = "Myra Ellen Amos";
+ String oldRdn = "cn=" + oldCn;
+ Attributes attributes = this.getPersonAttributes( "Amos", oldCn );
+ ctx.createSubcontext( oldRdn, attributes );
+
+ // modify Rdn
+ String newCn = "Tori Amos";
+ String newRdn = "cn=" + newCn;
+ ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "False" );
+ ctx.rename( oldRdn, newRdn );
+
+ // Check, whether old Entry does not exists
+ try
+ {
+ ctx.lookup( oldRdn );
+ fail( "Entry must not exist" );
+ }
+ catch ( NameNotFoundException ignored )
+ {
+ // expected behaviour
+ assertTrue( true );
+ }
+
+ // Check, whether new Entry exists
+ DirContext tori = ( DirContext ) ctx.lookup( newRdn );
+ assertNotNull( tori );
+
+ // Check values of cn
+ Attribute cn = tori.getAttributes( "" ).get( "cn" );
+ assertTrue( cn.contains( newCn ) );
+ assertTrue( cn.contains( oldCn ) ); // old value is still there
+ assertEquals( 2, cn.size() );
+
+ // Remove entry (use new rdn)
+ ctx.unbind( newRdn );
+ }
+
+
+ /**
+ * Modify Rdn of an entry, keep its old rdn value.
+ */
+ @Test
+ public void testModifyRdnAndKeepOld() throws Exception
+ {
+ DirContext ctx = ( DirContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ // Create a person, cn value is rdn
+ String oldCn = "Myra Ellen Amos";
+ String oldRdn = "cn=" + oldCn;
+ Attributes attributes = this.getPersonAttributes( "Amos", oldCn );
+ ctx.createSubcontext( oldRdn, attributes );
+
+ // modify Rdn
+ String newCn = "Tori Amos";
+ String newRdn = "cn=" + newCn;
+ ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "false" );
+ ctx.rename( oldRdn, newRdn );
+
+ // Check, whether old entry does not exist
+ try
+ {
+ ctx.lookup( oldRdn );
+ fail( "Entry must not exist" );
+ }
+ catch ( NameNotFoundException ignored )
+ {
+ // expected behaviour
+ assertTrue( true );
+ }
+
+ // Check, whether new entry exists
+ DirContext tori = ( DirContext ) ctx.lookup( newRdn );
+ assertNotNull( tori );
+
+ // Check values of cn
+ Attribute cn = tori.getAttributes( "" ).get( "cn" );
+ assertTrue( cn.contains( newCn ) );
+ assertTrue( cn.contains( oldCn ) ); // old value is still there
+ assertEquals( 2, cn.size() );
+
+ // Remove entry (use new rdn)
+ ctx.unbind( newRdn );
+ }
+
+
+ /**
+ * Modify Rdn of an entry, delete its old rdn value. Here, the rdn attribute
+ * cn has another value as well.
+ */
+ @Test
+ public void testModifyRdnAndDeleteOldVariant() throws Exception
+ {
+ DirContext ctx = ( DirContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ // Create a person, cn value is rdn
+ String oldCn = "Myra Ellen Amos";
+ String oldRdn = "cn=" + oldCn;
+ Attributes attributes = this.getPersonAttributes( "Amos", oldCn );
+
+ // add a second cn value
+ String alternateCn = "Myra E. Amos";
+ Attribute cn = attributes.get( "cn" );
+ cn.add( alternateCn );
+ assertEquals( 2, cn.size() );
+
+ ctx.createSubcontext( oldRdn, attributes );
+
+ // modify Rdn
+ String newCn = "Tori Amos";
+ String newRdn = "cn=" + newCn;
+ ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "true" );
+ ctx.rename( oldRdn, newRdn );
+
+ // Check, whether old Entry does not exist anymore
+ try
+ {
+ ctx.lookup( oldRdn );
+ fail( "Entry must not exist" );
+ }
+ catch ( NameNotFoundException ignored )
+ {
+ // expected behaviour
+ assertTrue( true );
+ }
+
+ // Check, whether new Entry exists
+ DirContext tori = ( DirContext ) ctx.lookup( newRdn );
+ assertNotNull( tori );
+
+ // Check values of cn
+ cn = tori.getAttributes( "" ).get( "cn" );
+ assertTrue( cn.contains( newCn ) );
+ assertTrue( !cn.contains( oldCn ) ); // old value is gone
+ assertTrue( cn.contains( alternateCn ) ); // alternate value is still available
+ assertEquals( 2, cn.size() );
+
+ // Remove entry (use new rdn)
+ ctx.unbind( newRdn );
+ }
+
+
+ /**
+ * Modify DN of an entry, changing RDN from cn to sn.
+ */
+ @Test
+ public void testModifyRdnDifferentAttribute() throws Exception
+ {
+ DirContext ctx = ( DirContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ // Create a person, cn value is rdn
+ String cnVal = "Tori Amos";
+ String snVal = "Amos";
+ String oldRdn = "cn=" + cnVal;
+ Attributes attributes = this.getPersonAttributes( snVal, cnVal );
+ ctx.createSubcontext( oldRdn, attributes );
+
+ // modify Rdn from cn=... to sn=...
+ String newRdn = "sn=" + snVal;
+ ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "false" );
+ ctx.rename( oldRdn, newRdn );
+
+ // Check, whether old Entry does not exists
+ try
+ {
+ ctx.lookup( oldRdn );
+ fail( "Entry must not exist" );
+ }
+ catch ( NameNotFoundException ignored )
+ {
+ // expected behaviour
+ }
+
+ // Check, whether new Entry exists
+ DirContext tori = ( DirContext ) ctx.lookup( newRdn );
+ assertNotNull( tori );
+
+ // Check values of cn and sn
+ // especially the number of cn and sn occurences
+ Attribute cn = tori.getAttributes( "" ).get( "cn" );
+ assertTrue( cn.contains( cnVal ) );
+ assertEquals( "Number of cn occurences", 1, cn.size() );
+ Attribute sn = tori.getAttributes( "" ).get( "sn" );
+ assertTrue( sn.contains( snVal ) );
+ assertEquals( "Number of sn occurences", 1, sn.size() );
+
+ // Remove entry (use new rdn)
+ ctx.unbind( newRdn );
+ }
+
+
+ /**
+ * Modify DN of an entry, changing RDN from cn to sn,
+ * delete old RDn, must fail because cn can not be deleted.
+ */
+ @Test
+ public void testModifyRdnDifferentAttributeDeleteOldFails() throws Exception
+ {
+ DirContext ctx = ( DirContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ // Create a person, cn value is rdn
+ String cnVal = "Tori Amos";
+ String snVal = "Amos";
+ String oldRdn = "cn=" + cnVal;
+ Attributes attributes = this.getPersonAttributes( snVal, cnVal );
+ ctx.createSubcontext( oldRdn, attributes );
+
+ // modify Rdn from cn=... to sn=...
+ String newRdn = "sn=" + snVal;
+ ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "true" );
+ try
+ {
+ ctx.rename( oldRdn, newRdn );
+ fail( "Rename must fail, mandatory attirbute cn can not be deleted." );
+ }
+ catch ( SchemaViolationException ignored )
+ {
+ // expected behaviour
+ }
+
+ // Remove entry (use old rdn)
+ ctx.unbind( oldRdn );
+ }
+
+
+ /**
+ * Test for DIRSERVER-1086.
+ * Modify Rdn of an entry that has a child entry, delete its old rdn value.
+ * Ensure that the tree is not broken.
+ */
+ @Test
+ public void testModifyRdnAndDeleteOldWithChild() throws Exception
+ {
+ DirContext ctx = ( DirContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ // Create an organizational unit, ou value is rdn
+ String oldOu = "Writers";
+ String oldRdn = "ou=" + oldOu;
+ Attributes attributes = this.getOrganizationalUnitAttributes( oldOu );
+ DirContext createdCtx = ctx.createSubcontext( oldRdn, attributes );
+
+ // Create a child
+ String childCn = "Tori Amos";
+ String childRdn = "cn=" + childCn;
+ Attributes childAttributes = this.getPersonAttributes( "Amos", childCn );
+ createdCtx.createSubcontext( childRdn, childAttributes );
+
+ // modify Rdn
+ String newOu = "Singers";
+ String newRdn = "ou=" + newOu;
+ ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "true" );
+ ctx.rename( oldRdn, newRdn );
+
+ // Check, whether old Entry does not exists
+ try
+ {
+ ctx.lookup( oldRdn );
+ fail( "Entry must not exist" );
+ }
+ catch ( NameNotFoundException ignored )
+ {
+ // expected behaviour
+ assertTrue( true );
+ }
+
+ // Check, whether new Entry exists
+ DirContext org = ( DirContext ) ctx.lookup( newRdn );
+ assertNotNull( org );
+
+ // Check values of ou
+ Attribute ou = org.getAttributes( "" ).get( "ou" );
+ assertTrue( ou.contains( newOu ) );
+ assertTrue( !ou.contains( oldOu ) ); // old value is gone
+ assertEquals( 1, ou.size() );
+
+ // Perform a search under renamed ou and check whether exactly one child entry exist
+ SearchControls searchControls = new SearchControls();
+ searchControls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
+ searchControls.setReturningAttributes( new String[]
+ { "objectClass" } );
+ NamingEnumeration<SearchResult> results = org.search( "", "(objectClass=*)", searchControls );
+ assertTrue( results.hasMore() );
+ results.next();
+ assertTrue( !results.hasMore() );
+
+ // Check whether Tori exists
+ DirContext tori = ( DirContext ) org.lookup( childRdn );
+ assertNotNull( tori );
+
+ // Remove entry (use new rdn)
+ ctx.unbind( childRdn + "," + newRdn );
+ ctx.unbind( newRdn );
+ }
+
+
+ /**
+ * Test for DIRSERVER-1096.
+ * Modify the RDN of an entry with an escaped new RDN.
+ * Ensure that the attribute itself contains the unescaped value.
+ */
+ @Test
+ public void testModifyRdnWithEncodedNewRdn() throws Exception
+ {
+ DirContext ctx = ( DirContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ // Create a person "cn=Tori Amos", cn value is rdn
+ String cnVal = "Tori Amos";
+ String snVal = "Amos";
+ String oldRdn = "cn=" + cnVal;
+ Attributes attributes = this.getPersonAttributes( snVal, cnVal );
+ ctx.createSubcontext( oldRdn, attributes );
+
+ // modify Rdn from cn=Tori Amos to cn=<a Umlaut>\+
+ String newCnEscapedVal = new String( new byte[]
+ { ( byte ) 0xC3, ( byte ) 0xA4, '\\', '+' }, "UTF-8" );
+ ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "true" );
+ String newRdn = "cn=" + newCnEscapedVal;
+ ctx.rename( oldRdn, newRdn );
+
+ // Check, whether old Entry does not exists
+ try
+ {
+ ctx.lookup( oldRdn );
+ fail( "Entry must not exist" );
+ }
+ catch ( NameNotFoundException ignored )
+ {
+ // expected behaviour
+ }
+
+ // Check, whether new Entry exists
+ DirContext newCtx = ( DirContext ) ctx.lookup( newRdn );
+ assertNotNull( newCtx );
+
+ // Check that the DN contains the escaped value
+ assertEquals( "cn=" + newCnEscapedVal + "," + ctx.getNameInNamespace(), newCtx.getNameInNamespace() );
+
+ // Check that cn contains the unescaped value
+ Attribute cn = newCtx.getAttributes( "" ).get( "cn" );
+ assertEquals( "Number of cn occurences", 1, cn.size() );
+ assertTrue( cn.contains( newCnEscapedVal ) );
+
+ // Remove entry (use new rdn)
+ ctx.unbind( newRdn );
+ }
+
+
+ /**
+ * Test for DIRSERVER-1096.
+ * Modify the RDN of an entry with an escaped new RDN.
+ * Ensure that the attribute itself contains the unescaped value.
+ */
+ @Test
+ public void testModifyRdnWithEscapedPoundNewRdn() throws Exception
+ {
+ DirContext ctx = ( DirContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ // Create a person "cn=Tori Amos", cn value is rdn
+ String cnVal = "Tori Amos";
+ String snVal = "Amos";
+ String oldRdn = "cn=" + cnVal;
+ Attributes attributes = this.getPersonAttributes( snVal, cnVal );
+ ctx.createSubcontext( oldRdn, attributes );
+
+ // modify Rdn from cn=Tori Amos to cn=\#test\+
+ ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "true" );
+ String newRdn = "cn=\\23test";
+ ctx.rename( oldRdn, newRdn );
+
+ // Check, whether old Entry does not exists
+ try
+ {
+ ctx.lookup( oldRdn );
+ fail( "Entry must not exist" );
+ }
+ catch ( NameNotFoundException ignored )
+ {
+ // expected behaviour
+ }
+
+ // Check, whether new Entry exists
+ DirContext newCtx = ( DirContext ) ctx.lookup( newRdn );
+ assertNotNull( newCtx );
+
+ // Check that the DN contains the escaped value
+ assertEquals( "cn=\\23test," + ctx.getNameInNamespace(), newCtx.getNameInNamespace() );
+
+ // Check that cn contains the unescaped value
+ Attribute cn = newCtx.getAttributes( "" ).get( "cn" );
+ assertEquals( "Number of cn occurences", 1, cn.size() );
+ assertTrue( cn.contains( "\\#test" ) );
+
+ // Remove entry (use new rdn)
+ ctx.unbind( newRdn );
+ }
+
+
+ /**
+ * Test for DIRSERVER-1162 and DIRSERVER-1085.
+ *
+ * Modify single valued RDN to a multi valued RDN.
+ * - Old Rdn: cn
+ * - New Rdn: cn+sn
+ * - Keep old Rdn
+ * - Attributes: cn, sn, description must exist
+ */
+ @Test
+ public void testModifyMultiValuedRdnVariant1() throws Exception
+ {
+ DirContext ctx = ( DirContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ Attributes attributes = createPerson( "cn" );
+ String oldRdn = getRdn( attributes, "cn" );
+ String newRdn = getRdn( attributes, "cn", "sn" );
+
+ ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "false" );
+ ctx.rename( oldRdn, newRdn );
+
+ // Check whether new Entry exists
+ DirContext newCtx = ( DirContext ) ctx.lookup( newRdn );
+ assertNotNull( newCtx );
+
+ // Check attributes
+ Attribute cnAttr = newCtx.getAttributes( "" ).get( "cn" );
+ assertEquals( 1, cnAttr.size() );
+ assertTrue( cnAttr.contains( "Tori Amos" ) );
+ Attribute snAttr = newCtx.getAttributes( "" ).get( "sn" );
+ assertEquals( 1, snAttr.size() );
+ assertTrue( snAttr.contains( "Amos" ) );
+ Attribute descriptionAttr = newCtx.getAttributes( "" ).get( "description" );
+ assertEquals( 1, descriptionAttr.size() );
+
+ // Remove entry (use new rdn)
+ ctx.unbind( newRdn );
+ }
+
+
+ /**
+ * Test for DIRSERVER-1162 and DIRSERVER-1085.
+ *
+ * Modify single valued RDN to a multi valued RDN.
+ * - Old Rdn: cn
+ * - New Rdn: cn+sn
+ * - Delete old Rdn
+ * - Attributes: cn, sn, description must exist
+ */
+ @Test
+ public void testModifyMultiValuedRdnVariant2() throws Exception
+ {
+ DirContext ctx = ( DirContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ Attributes attributes = createPerson( "cn" );
+ String oldRdn = getRdn( attributes, "cn" );
+ String newRdn = getRdn( attributes, "cn", "sn" );
+
+ ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "true" );
+ ctx.rename( oldRdn, newRdn );
+
+ // Check whether new Entry exists
+ DirContext newCtx = ( DirContext ) ctx.lookup( newRdn );
+ assertNotNull( newCtx );
+
+ // Check attributes
+ Attribute cnAttr = newCtx.getAttributes( "" ).get( "cn" );
+ assertEquals( 1, cnAttr.size() );
+ assertTrue( cnAttr.contains( "Tori Amos" ) );
+ Attribute snAttr = newCtx.getAttributes( "" ).get( "sn" );
+ assertEquals( 1, snAttr.size() );
+ assertTrue( snAttr.contains( "Amos" ) );
+ Attribute descriptionAttr = newCtx.getAttributes( "" ).get( "description" );
+ assertEquals( 1, descriptionAttr.size() );
+
+ // Remove entry (use new rdn)
+ ctx.unbind( newRdn );
+ }
+
+
+ /**
+ * Test for DIRSERVER-1162 and DIRSERVER-1085.
+ *
+ * Modify single valued RDN to a multi valued RDN.
+ * - Old Rdn: description
+ * - New Rdn: cn+sn
+ * - Keep old Rdn
+ * - Attributes: cn, sn, description must exist
+ */
+ @Test
+ public void testModifyMultiValuedRdnVariant3() throws Exception
+ {
+ DirContext ctx = ( DirContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ Attributes attributes = createPerson( "description" );
+ String oldRdn = getRdn( attributes, "description" );
+ String newRdn = getRdn( attributes, "cn", "sn" );
+
+ ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "false" );
+ ctx.rename( oldRdn, newRdn );
+
+ // Check whether new Entry exists
+ DirContext newCtx = ( DirContext ) ctx.lookup( newRdn );
+ assertNotNull( newCtx );
+
+ // Check attributes
+ Attribute cnAttr = newCtx.getAttributes( "" ).get( "cn" );
+ assertEquals( 1, cnAttr.size() );
+ assertTrue( cnAttr.contains( "Tori Amos" ) );
+ Attribute snAttr = newCtx.getAttributes( "" ).get( "sn" );
+ assertEquals( 1, snAttr.size() );
+ assertTrue( snAttr.contains( "Amos" ) );
+ Attribute descriptionAttr = newCtx.getAttributes( "" ).get( "description" );
+ assertEquals( 1, descriptionAttr.size() );
+
+ // Remove entry (use new rdn)
+ ctx.unbind( newRdn );
+ }
+
+
+ /**
+ * Test for DIRSERVER-1162 and DIRSERVER-1085.
+ *
+ * Modify single valued RDN to a multi valued RDN.
+ * - Old Rdn: description
+ * - New Rdn: cn+sn
+ * - Delete old Rdn
+ * - Attributes: cn, sn must exist; descriptions must not exist
+ */
+ @Test
+ public void testModifyMultiValuedRdnVariant4() throws Exception
+ {
+ DirContext ctx = ( DirContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ Attributes attributes = createPerson( "description" );
+ String oldRdn = getRdn( attributes, "description" );
+ String newRdn = getRdn( attributes, "cn", "sn" );
+
+ ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "true" );
+ ctx.rename( oldRdn, newRdn );
+
+ // Check whether new Entry exists
+ DirContext newCtx = ( DirContext ) ctx.lookup( newRdn );
+ assertNotNull( newCtx );
+
+ // Check attributes
+ Attribute cnAttr = newCtx.getAttributes( "" ).get( "cn" );
+ assertEquals( 1, cnAttr.size() );
+ assertTrue( cnAttr.contains( "Tori Amos" ) );
+ Attribute snAttr = newCtx.getAttributes( "" ).get( "sn" );
+ assertEquals( 1, snAttr.size() );
+ assertTrue( snAttr.contains( "Amos" ) );
+ Attribute descriptionAttr = newCtx.getAttributes( "" ).get( "description" );
+ assertNull( descriptionAttr );
+
+ // Remove entry (use new rdn)
+ ctx.unbind( newRdn );
+ }
+
+
+ /**
+ * Test for DIRSERVER-1162 and DIRSERVER-1085.
+ *
+ * Modify single valued RDN to a multi valued RDN.
+ * - Old Rdn: cn
+ * - New Rdn: sn+telephoneNumber
+ * - Keep old Rdn
+ * - Attributes: cn, sn, description, telephoneNumber must exist
+ *
+ * @throws NamingException
+ */
+ @Test
+ public void testModifyMultiValuedRdnVariant5() throws Exception
+ {
+ DirContext ctx = ( DirContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ Attributes attributes = createPerson( "cn" );
+ attributes.put( "telephoneNumber", "12345" );
+ String oldRdn = getRdn( attributes, "cn" );
+ String newRdn = getRdn( attributes, "sn", "telephoneNumber" );
+
+ ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "false" );
+ ctx.rename( oldRdn, newRdn );
+
+ // Check whether new Entry exists
+ DirContext newCtx = ( DirContext ) ctx.lookup( newRdn );
+ assertNotNull( newCtx );
+
+ // Check attributes
+ Attribute cnAttr = newCtx.getAttributes( "" ).get( "cn" );
+ assertEquals( 1, cnAttr.size() );
+ assertTrue( cnAttr.contains( "Tori Amos" ) );
+ Attribute snAttr = newCtx.getAttributes( "" ).get( "sn" );
+ assertEquals( 1, snAttr.size() );
+ assertTrue( snAttr.contains( "Amos" ) );
+ Attribute descriptionAttr = newCtx.getAttributes( "" ).get( "description" );
+ assertEquals( 1, descriptionAttr.size() );
+ Attribute telephoneNumberAttr = newCtx.getAttributes( "" ).get( "telephoneNumber" );
+ assertEquals( 1, telephoneNumberAttr.size() );
+ assertTrue( telephoneNumberAttr.contains( "12345" ) );
+
+ // Remove entry (use new rdn)
+ ctx.unbind( newRdn );
+ }
+
+
+ /**
+ * Test for DIRSERVER-1162 and DIRSERVER-1085.
+ *
+ * Modify single valued RDN to a multi valued RDN.
+ * - Old Rdn: cn
+ * - New Rdn: sn+telephoneNumber
+ * - Delete old Rdn
+ * - Must fail with schema violation, cn cannot be deleted
+ *
+ * @throws NamingException
+ */
+ @Test
+ public void testModifyMultiValuedRdnVariant6() throws Exception
+ {
+ DirContext ctx = ( DirContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ Attributes attributes = createPerson( "cn" );
+ attributes.put( "telephoneNumber", "12345" );
+ String oldRdn = getRdn( attributes, "cn" );
+ String newRdn = getRdn( attributes, "sn", "telephoneNumber" );
+
+ ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "true" );
+ try
+ {
+ ctx.rename( oldRdn, newRdn );
+ fail( "Rename must fail, cn can not be deleted from a person." );
+ }
+ catch ( SchemaViolationException ignored )
+ {
+ // expected behaviour
+ }
+
+ // Check that entry was not changed
+ try
+ {
+ ctx.lookup( newRdn );
+ fail( "Previous rename failed as expected, entry must not exist" );
+ }
+ catch ( NameNotFoundException ignored )
+ {
+ // expected behaviour
+ }
+
+ // Check that entry was not changed
+ DirContext oldCtx = ( DirContext ) ctx.lookup( oldRdn );
+ assertNotNull( oldCtx );
+ Attribute cnAttr = oldCtx.getAttributes( "" ).get( "cn" );
+ assertEquals( 1, cnAttr.size() );
+ assertTrue( cnAttr.contains( "Tori Amos" ) );
+ Attribute snAttr = oldCtx.getAttributes( "" ).get( "sn" );
+ assertEquals( 1, snAttr.size() );
+ assertTrue( snAttr.contains( "Amos" ) );
+ Attribute descriptionAttr = oldCtx.getAttributes( "" ).get( "description" );
+ assertEquals( 1, descriptionAttr.size() );
+
+ // Remove entry (use old rdn)
+ ctx.unbind( oldRdn );
+ }
+
+
+ /**
+ * Test for DIRSERVER-1162 and DIRSERVER-1085.
+ *
+ * Modify multi valued RDN to a single valued RDN.
+ * - Old Rdn: cn+sn
+ * - New Rdn: cn
+ * - Keep old Rdn
+ * - Attributes: cn, sn, description must exist
+ *
+ * @throws NamingException
+ */
+ @Test
+ public void testModifyMultiValuedRdnVariant7() throws Exception
+ {
+ DirContext ctx = ( DirContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ Attributes attributes = createPerson( "cn", "sn" );
+ String oldRdn = getRdn( attributes, "cn", "sn" );
+ String newRdn = getRdn( attributes, "cn" );
+
+ ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "false" );
+ ctx.rename( oldRdn, newRdn );
+
+ // Check whether new Entry exists
+ DirContext newCtx = ( DirContext ) ctx.lookup( newRdn );
+ assertNotNull( newCtx );
+
+ // Check attributes
+ Attribute cnAttr = newCtx.getAttributes( "" ).get( "cn" );
+ assertEquals( 1, cnAttr.size() );
+ assertTrue( cnAttr.contains( "Tori Amos" ) );
+ Attribute snAttr = newCtx.getAttributes( "" ).get( "sn" );
+ assertEquals( 1, snAttr.size() );
+ assertTrue( snAttr.contains( "Amos" ) );
+ Attribute descriptionAttr = newCtx.getAttributes( "" ).get( "description" );
+ assertEquals( 1, descriptionAttr.size() );
+
+ // Remove entry (use new rdn)
+ ctx.unbind( newRdn );
+ }
+
+
+ /**
+ * Test for DIRSERVER-1162 and DIRSERVER-1085.
+ *
+ * Modify multi valued RDN to a single valued RDN.
+ * - Old Rdn: cn+sn
+ * - New Rdn: cn
+ * - Delete old Rdn
+ * - Must fail with schema violation, cn cannot be deleted
+ *
+ * @throws NamingException
+ */
+ @Test
+ public void testModifyMultiValuedRdnVariant8() throws Exception
+ {
+ DirContext ctx = ( DirContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ Attributes attributes = createPerson( "cn", "sn" );
+ String oldRdn = getRdn( attributes, "cn", "sn" );
+ String newRdn = getRdn( attributes, "cn" );
+
+ ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "true" );
+ try
+ {
+ ctx.rename( oldRdn, newRdn );
+ fail( "Rename must fail, cn can not be deleted from a person." );
+ }
+ catch ( SchemaViolationException ignored )
+ {
+ // expected behaviour
+ }
+
+ // Check that entry was not changed
+ try
+ {
+ ctx.lookup( newRdn );
+ fail( "Previous rename failed as expected, entry must not exist" );
+ }
+ catch ( NameNotFoundException ignored )
+ {
+ // expected behaviour
+ }
+
+ // Check that entry was not changed
+ DirContext oldCtx = ( DirContext ) ctx.lookup( oldRdn );
+ assertNotNull( oldCtx );
+ Attribute cnAttr = oldCtx.getAttributes( "" ).get( "cn" );
+ assertEquals( 1, cnAttr.size() );
+ assertTrue( cnAttr.contains( "Tori Amos" ) );
+ Attribute snAttr = oldCtx.getAttributes( "" ).get( "sn" );
+ assertEquals( 1, snAttr.size() );
+ assertTrue( snAttr.contains( "Amos" ) );
+ Attribute descriptionAttr = oldCtx.getAttributes( "" ).get( "description" );
+ assertEquals( 1, descriptionAttr.size() );
+
+ // Remove entry (use old rdn)
+ ctx.unbind( oldRdn );
+ }
+
+
+ /**
+ * Test for DIRSERVER-1162 and DIRSERVER-1085.
+ *
+ * Tries to rename+deleteOldRdn an entry that has an operational attribute
+ * in its RDN. Must fail because an operational attribute can not be
+ * deleted.
+ *
+ * @throws NamingException
+ */
+ @Test
+ public void testModifyRdnOperationalAttribute() throws Exception
+ {
+ DirContext ctx = ( DirContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ // create the entry
+ Attributes attributes = createPerson( "cn" );
+ String oldRdn = getRdn( attributes, "cn" );
+
+ // read createTimestamp
+ String createTimestamp = ( String ) ctx.getAttributes( oldRdn, new String[]
+ { "createTimestamp" } ).get( "createTimestamp" ).get();
+
+ // rename to createTimstamp=YYYYMMDDHHMMSSZ
+ String newRdn = "createTimestamp=" + createTimestamp;
+ ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "false" );
+ ctx.rename( oldRdn, newRdn );
+
+ // rename back to old Rdn, enable deleteOldRdn,
+ // must fail with NoPermisionException
+ ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "true" );
+ try
+ {
+ ctx.rename( newRdn, oldRdn );
+ fail( "Rename must fail, operational attribute createTimestamp can not be deleted." );
+ }
+ catch ( NoPermissionException ignored )
+ {
+ // expected behaviour
+ }
+
+ // Remove entry (use new rdn)
+ ctx.unbind( newRdn );
+ }
+
+
+ /**
+ * Test for DIRSERVER-1162 and DIRSERVER-1085.
+ *
+ * Tries to rename+deleteOldRdn an entry that has the structural object class
+ * person in its RDN (objectClass=person,ou=system). Must fail because the
+ * structural object class can not be deleted.
+ *
+ * @throws NamingException
+ */
+ @Test
+ public void testModifyRdnObjectClassAttribute() throws Exception
+ {
+ DirContext ctx = ( DirContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ // create the entry
+ Attributes attributes = createPerson( "cn" );
+ String oldRdn = getRdn( attributes, "cn" );
+
+ // rename to objectClass=person
+ String newRdn = "objectClass=person";
+ ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "false" );
+ ctx.rename( oldRdn, newRdn );
+
+ // rename back to old Rdn, enable deleteOldRdn,
+ // must fail with NoPermisionException
+ ctx.addToEnvironment( "java.naming.ldap.deleteRDN", "true" );
+ try
+ {
+ ctx.rename( newRdn, oldRdn );
+ fail( "Rename must fail, structural objectClass person can not be deleted." );
+ }
+ catch ( SchemaViolationException ignored )
+ {
+ // expected behaviour
+ }
+
+ // Remove entry (use new rdn)
+ ctx.unbind( newRdn );
+ }
+
+
+ private String getRdn( Attributes attributes, String... rdnTypes ) throws Exception
+ {
+ String rdn = "";
+
+ for ( String type : rdnTypes )
+ {
+ rdn += type + "=" + attributes.get( type ).get() + "+";
+ }
+
+ rdn = rdn.substring( 0, rdn.length() - 1 );
+ return rdn;
+ }
+
+
+ private Attributes createPerson( String... rdnTypes ) throws Exception
+ {
+ DirContext ctx = ( DirContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ Attributes attributes = new AttributesImpl();
+ Attribute attribute = new AttributeImpl( "objectClass" );
+ attribute.add( "top" );
+ attribute.add( "person" );
+ attributes.put( attribute );
+ attributes.put( "cn", "Tori Amos" );
+ attributes.put( "sn", "Amos" );
+ attributes.put( "description", "Tori Amos is a person." );
+
+ String rdn = getRdn( attributes, rdnTypes );
+
+ ctx.createSubcontext( rdn, attributes );
+
+ return attributes;
+ }
+}