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/07 07:44:10 UTC
svn commit: r683514 [2/2] - in /directory/apacheds/branches/bigbang:
server-integ/
server-integ/src/test/java/org/apache/directory/server/operations/search/
server-integ/src/test/java/org/apache/directory/server/suites/
server-unit/src/test/java/org/ap...
Added: directory/apacheds/branches/bigbang/server-integ/src/test/java/org/apache/directory/server/operations/search/SearchIT.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/server-integ/src/test/java/org/apache/directory/server/operations/search/SearchIT.java?rev=683514&view=auto
==============================================================================
--- directory/apacheds/branches/bigbang/server-integ/src/test/java/org/apache/directory/server/operations/search/SearchIT.java (added)
+++ directory/apacheds/branches/bigbang/server-integ/src/test/java/org/apache/directory/server/operations/search/SearchIT.java Wed Aug 6 22:44:09 2008
@@ -0,0 +1,1420 @@
+/*
+ * 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.search;
+
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.naming.InvalidNameException;
+import javax.naming.NameNotFoundException;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+import javax.naming.ldap.Control;
+import javax.naming.ldap.LdapContext;
+
+import org.apache.directory.server.core.integ.annotations.ApplyLdifs;
+import org.apache.directory.server.core.subtree.SubentryInterceptor;
+import org.apache.directory.server.integ.SiRunner;
+import org.apache.directory.server.newldap.LdapServer;
+
+import static org.apache.directory.server.integ.ServerIntegrationUtils.getWiredContext;
+
+import org.apache.directory.shared.ldap.constants.SchemaConstants;
+import org.apache.directory.shared.ldap.message.AttributeImpl;
+import org.apache.directory.shared.ldap.message.AttributesImpl;
+import org.apache.directory.shared.ldap.message.SubentriesControl;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import static org.junit.Assert.fail;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+
+/**
+ * Testcase with different modify operations on a person entry. Each includes a
+ * single add op only. Created to demonstrate DIREVE-241 ("Adding an already
+ * existing attribute value with a modify operation does not cause an error.").
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev: 682556 $
+ */
+@RunWith ( SiRunner.class )
+@ApplyLdifs( {
+
+ // Entry # 0
+ "dn: cn=Kate Bush,ou=system\n" +
+ "objectClass: person\n" +
+ "objectClass: organizationalPerson\n" +
+ "objectClass: inetOrgPerson\n" +
+ "objectClass: strongAuthenticationUser\n" +
+ "objectClass: top\n" +
+ "userCertificate:: NFZOXw==\n" +
+ "cn: Kate Bush\n" +
+ "description: this is a person\n" +
+ "sn: Bush\n" +
+ "jpegPhoto:: /9j/4AAQSkZJRgABAQEASABIAAD/4QAWRXhpZgAATU0AKgAAAAgAAAAAAAD//gAX\n" +
+ " Q3JlYXRlZCB3aXRoIFRoZSBHSU1Q/9sAQwAQCwwODAoQDg0OEhEQExgoGhgWFhgxIyUdKDozPTw\n" +
+ " 5Mzg3QEhcTkBEV0U3OFBtUVdfYmdoZz5NcXlwZHhcZWdj/9sAQwEREhIYFRgvGhovY0I4QmNjY2\n" +
+ " NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2Nj/8AAEQgAAQABA\n" +
+ " wEiAAIRAQMRAf/EABUAAQEAAAAAAAAAAAAAAAAAAAAF/8QAFBABAAAAAAAAAAAAAAAAAAAAAP/E\n" +
+ " ABUBAQEAAAAAAAAAAAAAAAAAAAUG/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8\n" +
+ " AigC14//Z\n\n" +
+
+ // Entry # 2
+ "dn: cn=Tori Amos,ou=system\n" +
+ "objectClass: person\n" +
+ "objectClass: organizationalPerson\n" +
+ "objectClass: inetOrgPerson\n" +
+ "objectClass: strongAuthenticationUser\n" +
+ "objectClass: top\n" +
+ "userCertificate:: NFZOXw==\n" +
+ "cn: Tori Amos\n" +
+ "description: an American singer-songwriter\n" +
+ "sn: Amos\n" +
+ "jpegPhoto:: /9j/4AAQSkZJRgABAQEASABIAAD/4QAWRXhpZgAATU0AKgAAAAgAAAAAAAD//gAX\n" +
+ " Q3JlYXRlZCB3aXRoIFRoZSBHSU1Q/9sAQwAQCwwODAoQDg0OEhEQExgoGhgWFhgxIyUdKDozPTw\n" +
+ " 5Mzg3QEhcTkBEV0U3OFBtUVdfYmdoZz5NcXlwZHhcZWdj/9sAQwEREhIYFRgvGhovY0I4QmNjY2\n" +
+ " NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2Nj/8AAEQgAAQABA\n" +
+ " wEiAAIRAQMRAf/EABUAAQEAAAAAAAAAAAAAAAAAAAAF/8QAFBABAAAAAAAAAAAAAAAAAAAAAP/E\n" +
+ " ABUBAQEAAAAAAAAAAAAAAAAAAAUG/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8\n" +
+ " AigC14//Z\n\n" +
+
+ // Entry # 3
+ "dn: cn=Rolling-Stones,ou=system\n" +
+ "objectClass: person\n" +
+ "objectClass: organizationalPerson\n" +
+ "objectClass: inetOrgPerson\n" +
+ "objectClass: strongAuthenticationUser\n" +
+ "objectClass: top\n" +
+ "userCertificate:: NFZOXw==\n" +
+ "cn: Rolling-Stones\n" +
+ "description: an English singer-songwriter\n" +
+ "sn: Jagger\n" +
+ "jpegPhoto:: /9j/4AAQSkZJRgABAQEASABIAAD/4QAWRXhpZgAATU0AKgAAAAgAAAAAAAD//gAX\n" +
+ " Q3JlYXRlZCB3aXRoIFRoZSBHSU1Q/9sAQwAQCwwODAoQDg0OEhEQExgoGhgWFhgxIyUdKDozPTw\n" +
+ " 5Mzg3QEhcTkBEV0U3OFBtUVdfYmdoZz5NcXlwZHhcZWdj/9sAQwEREhIYFRgvGhovY0I4QmNjY2\n" +
+ " NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2Nj/8AAEQgAAQABA\n" +
+ " wEiAAIRAQMRAf/EABUAAQEAAAAAAAAAAAAAAAAAAAAF/8QAFBABAAAAAAAAAAAAAAAAAAAAAP/E\n" +
+ " ABUBAQEAAAAAAAAAAAAAAAAAAAUG/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8\n" +
+ " AigC14//Z\n\n" +
+
+ // Entry # 4
+ "dn: cn=Heather Nova,ou=system\n" +
+ "objectClass: person\n" +
+ "objectClass: organizationalPerson\n" +
+ "objectClass: inetOrgPerson\n" +
+ "objectClass: strongAuthenticationUser\n" +
+ "objectClass: top\n" +
+ "userCertificate:: NFZOXw==\n" +
+ "cn: Heather Nova\n" +
+ "sn: Nova\n" +
+ "jpegPhoto:: /9j/4AAQSkZJRgABAQEASABIAAD/4QAWRXhpZgAATU0AKgAAAAgAAAAAAAD//gAX\n" +
+ " Q3JlYXRlZCB3aXRoIFRoZSBHSU1Q/9sAQwAQCwwODAoQDg0OEhEQExgoGhgWFhgxIyUdKDozPTw\n" +
+ " 5Mzg3QEhcTkBEV0U3OFBtUVdfYmdoZz5NcXlwZHhcZWdj/9sAQwEREhIYFRgvGhovY0I4QmNjY2\n" +
+ " NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2Nj/8AAEQgAAQABA\n" +
+ " wEiAAIRAQMRAf/EABUAAQEAAAAAAAAAAAAAAAAAAAAF/8QAFBABAAAAAAAAAAAAAAAAAAAAAP/E\n" +
+ " ABUBAQEAAAAAAAAAAAAAAAAAAAUG/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8\n" +
+ " AigC14//Z\n\n"
+
+ }
+)
+public class SearchIT
+{
+ private static final String BASE = "ou=system";
+
+ public static LdapServer ldapServer;
+
+ private static final String RDN = "cn=Tori Amos";
+ private static final String RDN2 = "cn=Rolling-Stones";
+ private static final String HEATHER_RDN = "cn=Heather Nova";
+ private static final String FILTER = "(objectclass=*)";
+
+
+ private static final byte[] JPEG = new byte[]
+ {
+ (byte)0xff, (byte)0xd8, (byte)0xff, (byte)0xe0, 0x00, 0x10, 0x4a, 0x46,
+ 0x49, 0x46, 0x00, 0x01, 0x01, 0x01, 0x00, 0x48,
+ 0x00, 0x48, 0x00, 0x00, (byte)0xff, (byte)0xe1, 0x00, 0x16,
+ 0x45, 0x78, 0x69, 0x66, 0x00, 0x00, 0x4d, 0x4d,
+ 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, (byte)0xff, (byte)0xfe, 0x00, 0x17,
+ 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20,
+ 0x77, 0x69, 0x74, 0x68, 0x20, 0x54, 0x68, 0x65,
+ 0x20, 0x47, 0x49, 0x4d, 0x50, (byte)0xff, (byte)0xdb, 0x00,
+ 0x43, 0x00, 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a,
+ 0x10, 0x0e, 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13,
+ 0x18, 0x28, 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31,
+ 0x23, 0x25, 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c,
+ 0x39, 0x33, 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e,
+ 0x40, 0x44, 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d,
+ 0x51, 0x57, 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e,
+ 0x4d, 0x71, 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65,
+ 0x67, 0x63, (byte)0xff, (byte)0xdb, 0x00, 0x43, 0x01, 0x11,
+ 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, 0x1a,
+ 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, (byte)0xff,
+ (byte)0xc0, 0x00, 0x11, 0x08, 0x00, 0x01, 0x00, 0x01,
+ 0x03, 0x01, 0x22, 0x00, 0x02, 0x11, 0x01, 0x03,
+ 0x11, 0x01, (byte)0xff, (byte)0xc4, 0x00, 0x15, 0x00, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, (byte)0xff, (byte)0xc4, 0x00, 0x14, 0x10, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte)0xff,
+ (byte)0xc4, 0x00, 0x15, 0x01, 0x01, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x05, 0x06, (byte)0xff, (byte)0xc4,
+ 0x00, 0x14, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, (byte)0xff, (byte)0xda, 0x00, 0x0c,
+ 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00,
+ 0x3f, 0x00, (byte)0x8a, 0x00, (byte)0xb5, (byte)0xe3, (byte)0xff, (byte)0xd9,
+ };
+
+
+
+ /**
+ * Creation of required attributes of 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" );
+ attribute.add( "organizationalPerson" );
+ attribute.add( "inetOrgPerson" );
+ attributes.put( attribute );
+ attributes.put( "cn", cn );
+ attributes.put( "sn", sn );
+ attributes.put( "jpegPhoto", JPEG );
+
+ return attributes;
+ }
+
+
+ private void checkForAttributes( Attributes attrs, String[] attrNames )
+ {
+ for ( String attrName : attrNames )
+ {
+ assertNotNull( "Check if attr " + attrName + " is present", attrs.get( attrName ) );
+ }
+ }
+
+
+ /**
+ * For DIRSERVER-715 and part of DIRSERVER-169. May include other tests
+ * for binary attribute based searching.
+ */
+ @Test
+ public void testSearchByBinaryAttribute() throws Exception
+ {
+ DirContext ctx = ( DirContext ) getWiredContext( ldapServer ).lookup( BASE );
+ byte[] certData = new byte[] { 0x34, 0x56, 0x4e, 0x5f };
+
+ // Search for kate by cn first
+ SearchControls controls = new SearchControls();
+ controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
+ NamingEnumeration<SearchResult> enm = ctx.search( "", "(cn=Kate Bush)", controls );
+ assertTrue( enm.hasMore() );
+ SearchResult sr = enm.next();
+ assertNotNull( sr );
+ assertFalse( enm.hasMore() );
+ assertEquals( "cn=Kate Bush", sr.getName() );
+
+ // TODO enable this test here
+ // Failing here below this due to the frontend interpretting the byte[]
+ // as a String value. I see the value sent to the SearchHandler of the
+ // filter to be a String looking like: "[B@17210a5".
+
+ enm = ctx.search( "", "(&(cn=Kate Bush)(userCertificate={0}))", new Object[] {certData}, controls );
+ assertTrue( enm.hasMore() );
+ sr = ( SearchResult ) enm.next();
+ assertNotNull( sr );
+ assertFalse( enm.hasMore() );
+ assertEquals( "cn=Kate Bush", sr.getName() );
+ }
+
+
+ @Test
+ public void testSearch() throws Exception
+ {
+ LdapContext ctx = getWiredContext( ldapServer );
+ SearchControls controls = new SearchControls();
+ controls.setSearchScope( SearchControls.OBJECT_SCOPE );
+ controls.setTimeLimit( 10 );
+
+ try
+ {
+ ctx.search( "myBadDN", "(objectClass=*)", controls );
+
+ fail(); // We should get an exception here
+ }
+ catch ( InvalidNameException ine )
+ {
+ // Expected.
+ }
+ catch ( NamingException ne )
+ {
+ fail();
+ }
+ catch( Exception e )
+ {
+ fail();
+ }
+
+ try
+ {
+ controls = new SearchControls();
+ controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
+ controls.setTimeLimit( 10 );
+
+ NamingEnumeration<SearchResult> result = ctx.search( "ou=system", "(objectClass=*)", controls );
+
+ assertTrue( result.hasMore() );
+ }
+ catch ( InvalidNameException ine )
+ {
+ fail();
+ // Expected.
+ }
+ catch ( NamingException ne )
+ {
+ fail();
+ }
+ }
+
+
+ /**
+ * Performs a single level search from ou=system base and
+ * returns the set of DNs found.
+ */
+ private Set<String> search( String filter ) throws Exception
+ {
+ LdapContext ctx = ( LdapContext ) getWiredContext( ldapServer ).lookup( BASE );
+ SearchControls controls = new SearchControls();
+ controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
+ NamingEnumeration<SearchResult> ii = ctx.search( "", filter, controls );
+
+ // collect all results
+ HashSet<String> results = new HashSet<String>();
+ while ( ii.hasMore() )
+ {
+ SearchResult result = ii.next();
+ results.add( result.getName() );
+ }
+
+ return results;
+ }
+
+
+ @Test
+ public void testDirserver635() throws Exception
+ {
+ // -------------------------------------------------------------------
+ Set<String> results = search( "(|(cn=Kate*)(cn=Tori*))" );
+ assertEquals( "returned size of results", 2, results.size() );
+ assertTrue( "contains cn=Tori Amos", results.contains( "cn=Tori Amos" ) );
+ assertTrue( "contains cn=Kate Bush", results.contains( "cn=Kate Bush" ) );
+
+ // -------------------------------------------------------------------
+ results = search( "(|(cn=*Amos)(cn=Kate*))" );
+ assertEquals( "returned size of results", 2, results.size() );
+ assertTrue( "contains cn=Tori Amos", results.contains( "cn=Tori Amos" ) );
+ assertTrue( "contains cn=Kate Bush", results.contains( "cn=Kate Bush" ) );
+
+ // -------------------------------------------------------------------
+ results = search( "(|(cn=Kate Bush)(cn=Tori*))" );
+ assertEquals( "returned size of results", 2, results.size() );
+ assertTrue( "contains cn=Tori Amos", results.contains( "cn=Tori Amos" ) );
+ assertTrue( "contains cn=Kate Bush", results.contains( "cn=Kate Bush" ) );
+
+ // -------------------------------------------------------------------
+ results = search( "(|(cn=*Amos))" );
+ assertEquals( "returned size of results", 1, results.size() );
+ assertTrue( "contains cn=Tori Amos", results.contains( "cn=Tori Amos" ) );
+ }
+
+
+ /**
+ * Search operation with a base DN which contains a BER encoded value.
+ */
+ //@Test
+ /*public void testSearchBEREncodedBase() throws NamingException
+ {
+ // create additional entry
+ Attributes attributes = this.getPersonAttributes( "Ferry", "Bryan Ferry" );
+ ctx.createSubcontext( "sn=Ferry", attributes );
+
+ SearchControls sctls = new SearchControls();
+ sctls.setSearchScope( SearchControls.OBJECT_SCOPE );
+ String FILTER = "(cn=Bryan Ferry)";
+
+ // sn=Ferry with BEROctetString values
+ String base = "2.5.4.4=#4665727279";
+
+ try
+ {
+ // Check entry
+ NamingEnumeration enm = ctx.search( base, FILTER, sctls );
+ assertTrue( enm.hasMore() );
+ while ( enm.hasMore() )
+ {
+ SearchResult sr = ( SearchResult ) enm.next();
+ Attributes attrs = sr.getObject();
+ Attribute sn = attrs.get( "sn" );
+ assertNotNull( sn );
+ assertTrue( sn.contains( "Ferry" ) );
+ }
+ }
+ catch ( Exception e )
+ {
+ fail( e.getMessage() );
+ }
+ }*/
+
+
+ /**
+ * Search operation with a base DN which contains a BER encoded value.
+ */
+ @Test
+ public void testSearchWithBackslashEscapedBase() throws Exception
+ {
+ LdapContext ctx = ( LdapContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ // create additional entry
+ Attributes attributes = this.getPersonAttributes( "Ferry", "Bryan Ferry" );
+ ctx.createSubcontext( "sn=Ferry", attributes );
+
+ SearchControls sctls = new SearchControls();
+ sctls.setSearchScope( SearchControls.OBJECT_SCOPE );
+ String filter = "(cn=Bryan Ferry)";
+
+ // sn=Ferry with BEROctetString values
+ String base = "sn=\\46\\65\\72\\72\\79";
+
+ try
+ {
+ // Check entry
+ NamingEnumeration<SearchResult> enm = ctx.search( base, filter, sctls );
+ assertTrue( enm.hasMore() );
+ while ( enm.hasMore() )
+ {
+ SearchResult sr = enm.next();
+ Attributes attrs = sr.getAttributes();
+ Attribute sn = attrs.get( "sn" );
+ assertNotNull( sn );
+ assertTrue( sn.contains( "Ferry" ) );
+ }
+ }
+ catch ( Exception e )
+ {
+ fail( e.getMessage() );
+ }
+ }
+
+
+ /**
+ * Add a new attribute to a person entry.
+ *
+ * @throws NamingException
+ */
+ @Test
+ public void testSearchValue() throws Exception
+ {
+ LdapContext ctx = ( LdapContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ // Setting up search controls for compare op
+ SearchControls ctls = new SearchControls();
+ ctls.setReturningAttributes( new String[]
+ { "*" } ); // no attributes
+ ctls.setSearchScope( SearchControls.OBJECT_SCOPE );
+
+ // Search for all entries
+ NamingEnumeration<SearchResult> results = ctx.search( RDN, "(cn=*)", ctls );
+ assertTrue( results.hasMore() );
+
+ results = ctx.search( RDN2, "(cn=*)", ctls );
+ assertTrue( results.hasMore() );
+
+ // Search for all entries ending by Amos
+ results = ctx.search( RDN, "(cn=*Amos)", ctls );
+ assertTrue( results.hasMore() );
+
+ results = ctx.search( RDN2, "(cn=*Amos)", ctls );
+ assertFalse( results.hasMore() );
+
+ // Search for all entries ending by amos
+ results = ctx.search( RDN, "(cn=*amos)", ctls );
+ assertTrue( results.hasMore() );
+
+ results = ctx.search( RDN2, "(cn=*amos)", ctls );
+ assertFalse( results.hasMore() );
+
+ // Search for all entries starting by Tori
+ results = ctx.search( RDN, "(cn=Tori*)", ctls );
+ assertTrue( results.hasMore() );
+
+ results = ctx.search( RDN2, "(cn=Tori*)", ctls );
+ assertFalse( results.hasMore() );
+
+ // Search for all entries starting by tori
+ results = ctx.search( RDN, "(cn=tori*)", ctls );
+ assertTrue( results.hasMore() );
+
+ results = ctx.search( RDN2, "(cn=tori*)", ctls );
+ assertFalse( results.hasMore() );
+
+ // Search for all entries containing ori
+ results = ctx.search( RDN, "(cn=*ori*)", ctls );
+ assertTrue( results.hasMore() );
+
+ results = ctx.search( RDN2, "(cn=*ori*)", ctls );
+ assertFalse( results.hasMore() );
+
+ // Search for all entries containing o and i
+ results = ctx.search( RDN, "(cn=*o*i*)", ctls );
+ assertTrue( results.hasMore() );
+
+ results = ctx.search( RDN2, "(cn=*o*i*)", ctls );
+ assertTrue( results.hasMore() );
+
+ // Search for all entries containing o, space and o
+ results = ctx.search( RDN, "(cn=*o* *o*)", ctls );
+ assertTrue( results.hasMore() );
+
+ results = ctx.search( RDN2, "(cn=*o* *o*)", ctls );
+ assertFalse( results.hasMore() );
+
+ results = ctx.search( RDN2, "(cn=*o*-*o*)", ctls );
+ assertTrue( results.hasMore() );
+
+ // Search for all entries starting by To and containing A
+ results = ctx.search( RDN, "(cn=To*A*)", ctls );
+ assertTrue( results.hasMore() );
+
+ results = ctx.search( RDN2, "(cn=To*A*)", ctls );
+ assertFalse( results.hasMore() );
+
+ // Search for all entries ending by os and containing ri
+ results = ctx.search( RDN, "(cn=*ri*os)", ctls );
+ assertTrue( results.hasMore() );
+
+ results = ctx.search( RDN2, "(cn=*ri*os)", ctls );
+ assertFalse( results.hasMore() );
+ }
+
+ /**
+ * Search operation with a base DN with quotes
+ *
+ @Test
+ public void testSearchWithQuotesInBase() throws NamingException {
+
+ SearchControls sctls = new SearchControls();
+ sctls.setSearchScope(SearchControls.OBJECT_SCOPE);
+ String filter = "(cn=Tori Amos)";
+
+ // cn="Tori Amos" (with quotes)
+ String base = "cn=\"Tori Amos\"";
+
+ try {
+ // Check entry
+ NamingEnumeration<SearchResult> enm = ctx.search( base, filter, sctls );
+ assertTrue( enm.hasMore() );
+
+ while ( enm.hasMore() ) {
+ SearchResult sr = enm.next();
+ Attributes attrs = sr.getAttributes();
+ Attribute sn = attrs.get("sn");
+ assertNotNull(sn);
+ assertTrue( sn.contains( "Amos" ) );
+ }
+ } catch (Exception e) {
+ fail( e.getMessage() );
+ }
+ }
+
+
+ /**
+ * Tests for <a href="http://issues.apache.org/jira/browse/DIRSERVER-645">
+ * DIRSERVER-645<\a>: Wrong search FILTER evaluation with AND
+ * operator and undefined operands.
+ */
+ @Test
+ public void testUndefinedAvaInBranchFilters() throws Exception
+ {
+ // -------------------------------------------------------------------
+ Set<String> results = search( "(|(sn=Bush)(numberOfOctaves=4))" );
+ assertEquals( "returned size of results", 1, results.size() );
+ assertTrue( "contains cn=Kate Bush", results.contains( "cn=Kate Bush" ) );
+
+ // if numberOfOctaves is undefined then this whole FILTER is undefined
+ results = search( "(&(sn=Bush)(numberOfOctaves=4))" );
+ assertEquals( "returned size of results", 0, results.size() );
+ }
+
+
+ @Test
+ public void testSearchSchema() throws Exception
+ {
+ SearchControls controls = new SearchControls();
+ controls.setSearchScope( SearchControls.OBJECT_SCOPE );
+ controls.setReturningAttributes( new String[] { "objectClasses" } );
+
+ LdapContext ctx = getWiredContext( ldapServer );
+
+ NamingEnumeration<SearchResult> results = ctx.search( "cn=schema", "objectClass=subschema", controls );
+ assertTrue( results.hasMore() );
+ SearchResult result = results.next();
+ assertNotNull( result );
+ assertFalse( results.hasMore() );
+
+ NamingEnumeration<? extends Attribute> attrs = result.getAttributes().getAll();
+
+ while ( attrs.hasMoreElements() )
+ {
+ Attribute attr = ( Attribute ) attrs.next();
+ String ID = attr.getID();
+ assertEquals( "objectClasses", ID );
+ }
+
+ assertNotNull( result.getAttributes().get( "objectClasses" ) );
+ assertEquals( 1, result.getAttributes().size() );
+ }
+
+
+ /**
+ * Creates an access control subentry under ou=system whose subtree covers
+ * the entire naming context.
+ *
+ * @param cn the common name and rdn for the subentry
+ * @param subtree the subtreeSpecification for the subentry
+ * @param aciItem the prescriptive ACI attribute value
+ * @throws NamingException if there is a problem creating the subentry
+ */
+ private void createAccessControlSubentry( String cn, String subtree, String aciItem ) throws Exception
+ {
+ LdapContext ctx = ( LdapContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ DirContext adminCtx = ctx;
+
+ // modify ou=system to be an AP for an A/C AA if it is not already
+ Attributes ap = adminCtx.getAttributes( "", new String[] { "administrativeRole" } );
+ Attribute administrativeRole = ap.get( "administrativeRole" );
+ if ( administrativeRole == null || !administrativeRole.contains( SubentryInterceptor.AC_AREA ) )
+ {
+ Attributes changes = new AttributesImpl( "administrativeRole", SubentryInterceptor.AC_AREA, true );
+ adminCtx.modifyAttributes( "", DirContext.ADD_ATTRIBUTE, changes );
+ }
+
+ // now add the A/C subentry below ou=system
+ Attributes subentry = new AttributesImpl( "cn", cn, true );
+ Attribute objectClass = new AttributeImpl( "objectClass" );
+ subentry.put( objectClass );
+ objectClass.add( "top" );
+ objectClass.add( SchemaConstants.SUBENTRY_OC );
+ objectClass.add( "accessControlSubentry" );
+ subentry.put( "subtreeSpecification", subtree );
+ subentry.put( "prescriptiveACI", aciItem );
+ adminCtx.createSubcontext( "cn=" + cn, subentry );
+ }
+
+
+ /**
+ * Test case to demonstrate DIRSERVER-705 ("object class top missing in search
+ * result, if scope is base and attribute objectClass is requested explicitly").
+ */
+ @Test
+ public void testAddWithObjectclasses() throws Exception
+ {
+ LdapContext ctx = ( LdapContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ // Create entry
+ Attributes wilde = new AttributesImpl();
+ Attribute ocls = new AttributeImpl( "objectClass" );
+ ocls.add( "top" );
+ ocls.add( "person" );
+ wilde.put( ocls );
+ wilde.put( "cn", "Kim Wilde" );
+ wilde.put( "sn", "Wilde" );
+ String rdn = "cn=Kim Wilde";
+ ctx.createSubcontext( rdn, wilde );
+
+ SearchControls ctls = new SearchControls();
+ ctls.setSearchScope( SearchControls.OBJECT_SCOPE );
+ ctls.setReturningAttributes( new String[]
+ { "objectclass" } );
+ String filter = "(objectclass=*)";
+
+ NamingEnumeration<SearchResult> result = ctx.search( rdn, filter, ctls );
+ if ( result.hasMore() )
+ {
+ SearchResult entry = result.next();
+ Attributes heatherReloaded = entry.getAttributes();
+ Attribute loadedOcls = heatherReloaded.get( "objectClass" );
+ assertNotNull( loadedOcls );
+ assertTrue( loadedOcls.contains( "person" ) );
+ assertTrue( loadedOcls.contains( "top" ) );
+ }
+ else
+ {
+ fail( "entry " + rdn + " not found" );
+ }
+
+ ctx.destroySubcontext( rdn );
+ }
+
+
+ /**
+ * Test case to demonstrate DIRSERVER-705 ("object class top missing in search
+ * result, if scope is base and attribute objectClass is requested explicitly").
+ */
+ @Test
+ public void testAddWithMissingObjectclasses() throws Exception
+ {
+ LdapContext ctx = ( LdapContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ String rdn = "cn=Kate Bush";
+ SearchControls ctls = new SearchControls();
+ ctls.setSearchScope( SearchControls.OBJECT_SCOPE );
+ ctls.setReturningAttributes( new String[]
+ { "objectclass" } );
+ String filter = "(objectclass=*)";
+
+ NamingEnumeration<SearchResult> result = ctx.search( rdn, filter, ctls );
+ if ( result.hasMore() )
+ {
+ SearchResult entry = result.next();
+ Attributes kateReloaded = entry.getAttributes();
+ Attribute loadedOcls = kateReloaded.get( "objectClass" );
+ assertNotNull( loadedOcls );
+ assertTrue( loadedOcls.contains( "top" ) );
+ assertTrue( loadedOcls.contains( "person" ) );
+ assertTrue( loadedOcls.contains( "organizationalPerson" ) );
+
+ }
+ else
+ {
+ fail( "entry " + rdn + " not found" );
+ }
+
+ ctx.destroySubcontext( rdn );
+ }
+
+
+ @Test
+ public void testSubentryControl() throws Exception
+ {
+ LdapContext ctx = ( LdapContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ // create a real access control subentry
+ createAccessControlSubentry(
+ "anyBodyAdd",
+ "{}",
+ "{ " +
+ " identificationTag \"addAci\", " +
+ " precedence 14, " +
+ " authenticationLevel none, " +
+ " itemOrUserFirst userFirst: " +
+ " { " +
+ " userClasses " +
+ " { " +
+ " allUsers " +
+ " }, " +
+ " userPermissions " +
+ " { " +
+ " { " +
+ " protectedItems " +
+ " { " +
+ " entry, allUserAttributeTypesAndValues" +
+ " }, " +
+ " grantsAndDenials " +
+ " { " +
+ " grantAdd, grantBrowse " +
+ " } " +
+ " } " +
+ " } " +
+ " } " +
+ "}"
+ );
+
+ // prepare the subentry control to make the subentry visible
+ SubentriesControl control = new SubentriesControl();
+ control.setVisibility( true );
+ Control[] reqControls = new Control[] { control };
+ SearchControls searchControls = new SearchControls();
+ searchControls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
+
+ ctx.setRequestControls( reqControls );
+ NamingEnumeration<SearchResult> enm = ctx.search( "", "(objectClass=*)", searchControls );
+ Set<String> results = new HashSet<String>();
+
+ while ( enm.hasMore() )
+ {
+ SearchResult result = enm.next();
+ results.add( result.getName() );
+ }
+
+ assertEquals( "expected results size of", 1, results.size() );
+ assertTrue( results.contains( "cn=anyBodyAdd" ) );
+ }
+
+
+ /**
+ * Create a person entry with multivalued RDN and check its content. This
+ * testcase was created to demonstrate DIRSERVER-628.
+ */
+ @Test
+ public void testMultiValuedRdnContent() throws Exception
+ {
+ LdapContext ctx = ( LdapContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ Attributes attrs = getPersonAttributes( "Bush", "Kate Bush" );
+ String rdn = "cn=Kate Bush+sn=Bush";
+ ctx.createSubcontext( rdn, attrs );
+
+ SearchControls sctls = new SearchControls();
+ sctls.setSearchScope( SearchControls.SUBTREE_SCOPE );
+ String filter = "(sn=Bush)";
+ String base = "";
+
+ NamingEnumeration<SearchResult> enm = ctx.search( base, filter, sctls );
+ while ( enm.hasMore() )
+ {
+ SearchResult sr = enm.next();
+ attrs = sr.getAttributes();
+ Attribute cn = sr.getAttributes().get( "cn" );
+ assertNotNull( cn );
+ assertTrue( cn.contains( "Kate Bush" ) );
+ Attribute sn = sr.getAttributes().get( "sn" );
+ assertNotNull( sn );
+ assertTrue( sn.contains( "Bush" ) );
+ }
+
+ ctx.destroySubcontext( rdn );
+ }
+
+
+ /**
+ * Create a person entry with multivalued RDN and check its name.
+ */
+ @Test
+ public void testMultiValuedRdnName() throws Exception
+ {
+ LdapContext ctx = ( LdapContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ Attributes attrs = getPersonAttributes( "Bush", "Kate Bush" );
+ String rdn = "cn=Kate Bush+sn=Bush";
+ DirContext entry = ctx.createSubcontext( rdn, attrs );
+ String nameInNamespace = entry.getNameInNamespace();
+
+ SearchControls sctls = new SearchControls();
+ sctls.setSearchScope( SearchControls.OBJECT_SCOPE );
+ String filter = "(sn=Bush)";
+ String base = rdn;
+
+ NamingEnumeration<SearchResult> enm = ctx.search( base, filter, sctls );
+ if ( enm.hasMore() )
+ {
+ SearchResult sr = enm.next();
+ assertNotNull( sr );
+ assertEquals( "Name in namespace", nameInNamespace, sr.getNameInNamespace() );
+ }
+ else
+ {
+ fail( "Entry not found:" + nameInNamespace );
+ }
+
+ ctx.destroySubcontext( rdn );
+ }
+
+
+ @Test
+ public void testSearchJpeg() throws Exception
+ {
+ LdapContext ctx = ( LdapContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ SearchControls controls = new SearchControls();
+ controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
+ NamingEnumeration<SearchResult> res = ctx.search( "", "(cn=Tori*)", controls );
+
+ // collect all results
+ while ( res.hasMore() )
+ {
+ SearchResult result = res.next();
+
+ Attributes attrs = result.getAttributes();
+
+ NamingEnumeration<? extends Attribute> all = attrs.getAll();
+
+ while ( all.hasMoreElements() )
+ {
+ Attribute attr = all.next();
+
+ if ( "jpegPhoto".equalsIgnoreCase( attr.getID() ) )
+ {
+ byte[] jpegVal = (byte[])attr.get();
+
+ assertTrue( Arrays.equals( jpegVal, JPEG ) );
+ }
+ }
+ }
+ }
+
+
+ @Test
+ public void testSearchOID() throws Exception
+ {
+ LdapContext ctx = ( LdapContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ SearchControls controls = new SearchControls();
+ controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
+ NamingEnumeration<SearchResult> res = ctx.search( "", "(2.5.4.3=Tori*)", controls );
+
+ // ensure that the entry "cn=Tori Amos" was found
+ assertTrue( res.hasMore() );
+
+ SearchResult result = ( SearchResult ) res.next();
+
+ // ensure that result is not null
+ assertNotNull( result );
+
+ String rdn = result.getName();
+
+ // ensure that the entry "cn=Tori Amos" was found
+ assertEquals( "cn=Tori Amos", rdn );
+
+ // ensure that no other value was found
+ assertFalse( res.hasMore() );
+ }
+
+ @Test
+ public void testSearchAttrCN() throws Exception
+ {
+ LdapContext ctx = ( LdapContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ SearchControls controls = new SearchControls();
+ controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
+ controls.setReturningAttributes( new String[]{"cn"} );
+
+ NamingEnumeration<SearchResult> res = ctx.search( "", "(commonName=Tori*)", controls );
+
+ assertTrue( res.hasMore() );
+
+ SearchResult result = res.next();
+
+ // ensure that result is not null
+ assertNotNull( result );
+
+ Attributes attrs = result.getAttributes();
+
+ // ensure the one and only attribute is "cn"
+ assertEquals( 1, attrs.size() );
+ assertNotNull( attrs.get( "cn" ) );
+ assertEquals( 1, attrs.get( "cn" ).size() );
+ assertEquals( "Tori Amos", ( String ) attrs.get("cn").get() );
+ }
+
+
+ @Test
+ public void testSearchAttrName() throws Exception
+ {
+ LdapContext ctx = ( LdapContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ SearchControls controls = new SearchControls();
+ controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
+ controls.setReturningAttributes( new String[]{"name"} );
+
+ NamingEnumeration<SearchResult> res = ctx.search( "", "(commonName=Tori*)", controls );
+
+ assertTrue( res.hasMore() );
+
+ SearchResult result = res.next();
+
+ // ensure that result is not null
+ assertNotNull( result );
+
+ Attributes attrs = result.getAttributes();
+
+ // ensure that "cn" and "sn" are returned
+ assertEquals( 2, attrs.size() );
+ assertNotNull( attrs.get( "cn" ) );
+ assertEquals( 1, attrs.get("cn").size() );
+ assertEquals( "Tori Amos", ( String ) attrs.get( "cn" ).get() );
+ assertNotNull( attrs.get( "sn" ) );
+ assertEquals( 1, attrs.get( "sn" ).size() );
+ assertEquals( "Amos", ( String ) attrs.get( "sn" ).get() );
+ }
+
+
+ @Test
+ public void testSearchAttrCommonName() throws Exception
+ {
+ LdapContext ctx = ( LdapContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ SearchControls controls = new SearchControls();
+ controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
+ controls.setReturningAttributes( new String[] { "commonName" } );
+
+ NamingEnumeration<SearchResult> res = ctx.search( "", "(commonName=Tori*)", controls );
+
+ assertTrue( res.hasMore() );
+
+
+ SearchResult result = res.next();
+
+ // ensure that result is not null
+ assertNotNull( result );
+
+ Attributes attrs = result.getAttributes();
+
+ // requested attribute was "commonName", but ADS returns "cn".
+ // Other servers do the following:
+ // - OpenLDAP: also return "cn"
+ // - Siemens DirX: return "commonName"
+ // - Sun Directory 5.2: return "commonName"
+ // ensure the one and only attribute is "cn"
+ assertEquals( 1, attrs.size() );
+ assertNotNull( attrs.get("cn") );
+ assertEquals( 1, attrs.get("cn").size() );
+ assertEquals( "Tori Amos", (String)attrs.get("cn").get() );
+ }
+
+
+ @Test
+ public void testSearchAttrOID() throws Exception
+ {
+ LdapContext ctx = ( LdapContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ SearchControls controls = new SearchControls();
+ controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
+ controls.setReturningAttributes( new String[]{"2.5.4.3"} );
+
+ NamingEnumeration<SearchResult> res = ctx.search( "", "(commonName=Tori*)", controls );
+
+ assertTrue( res.hasMore() );
+
+ SearchResult result = res.next();
+
+ // ensure that result is not null
+ assertNotNull( result );
+
+ Attributes attrs = result.getAttributes();
+
+ // requested attribute was "2.5.4.3", but ADS returns "cn".
+ // Other servers do the following:
+ // - OpenLDAP: also return "cn"
+ // - Siemens DirX: also return "cn"
+ // - Sun Directory 5.2: return "2.5.4.3"
+ // ensure the one and only attribute is "cn"
+ assertEquals( 1, attrs.size() );
+ assertNotNull( attrs.get("cn") );
+ assertEquals( 1, attrs.get("cn").size() );
+ assertEquals( "Tori Amos", (String)attrs.get("cn").get() );
+ }
+
+
+ @Test
+ public void testSearchAttrC_L() throws Exception
+ {
+ LdapContext ctx = ( LdapContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ // create administrative area
+ Attributes aaAttrs = new AttributesImpl();
+ Attribute aaObjectClass = new AttributeImpl( "objectClass" );
+ aaObjectClass.add( "top" );
+ aaObjectClass.add( "organizationalUnit" );
+ aaObjectClass.add( "extensibleObject" );
+ aaAttrs.put( aaObjectClass );
+ aaAttrs.put( "ou", "Collective Area" );
+ aaAttrs.put( "administrativeRole", "collectiveAttributeSpecificArea" );
+ DirContext aaCtx = ctx.createSubcontext( "ou=Collective Area", aaAttrs );
+
+ // create subentry
+ Attributes subentry = new AttributesImpl();
+ Attribute objectClass = new AttributeImpl( "objectClass" );
+ objectClass.add( "top" );
+ objectClass.add( SchemaConstants.SUBENTRY_OC );
+ objectClass.add( "collectiveAttributeSubentry" );
+ subentry.put( objectClass );
+ subentry.put( "c-l", "Munich" );
+ subentry.put( "cn", "Collective Subentry" );
+ subentry.put( "subtreeSpecification", "{ }" );
+ aaCtx.createSubcontext( "cn=Collective Subentry", subentry );
+
+ // create real enty
+ Attributes attributes = this.getPersonAttributes( "Bush", "Kate Bush" );
+ aaCtx.createSubcontext( "cn=Kate Bush", attributes );
+
+ // search
+ SearchControls controls = new SearchControls();
+ controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
+ controls.setReturningAttributes( new String[]{"c-l" } );
+
+ NamingEnumeration<SearchResult> res = aaCtx.search( "", "(cn=Kate Bush)", controls );
+
+ assertTrue( res.hasMore() );
+
+ SearchResult result = res.next();
+
+ // ensure that result is not null
+ assertNotNull( result );
+
+ Attributes attrs = result.getAttributes();
+
+ // ensure the one and only attribute is "c-l"
+ assertEquals( 1, attrs.size() );
+ assertNotNull( attrs.get("c-l") );
+ assertEquals( 1, attrs.get("c-l").size() );
+ assertEquals( "Munich", (String)attrs.get("c-l").get() );
+ }
+
+
+ @Test
+ public void testSearchUsersAttrs() throws Exception
+ {
+ LdapContext ctx = ( LdapContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ SearchControls controls = new SearchControls();
+ controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
+ controls.setReturningAttributes( new String[]{"*"} );
+
+ NamingEnumeration<SearchResult> res = ctx.search( "", "(commonName=Tori Amos)", controls );
+
+ assertTrue( res.hasMore() );
+
+ SearchResult result = res.next();
+
+ // ensure that result is not null
+ assertNotNull( result );
+
+ Attributes attrs = result.getAttributes();
+
+ // ensure that all user attributes are returned
+ assertEquals( 6, attrs.size() );
+ assertNotNull( attrs.get( "cn" ) );
+ assertNotNull( attrs.get( "sn" ) );
+ assertNotNull( attrs.get( "objectClass" ) );
+ assertNotNull( attrs.get( "jpegPhoto" ) );
+ assertNotNull( attrs.get( "description" ) );
+ assertNotNull( attrs.get( "userCertificate" ) );
+ assertNull( attrs.get( "createtimestamp" ) );
+ assertNull( attrs.get( "creatorsname" ) );
+ }
+
+
+ @Test
+ public void testSearchOperationalAttrs() throws Exception
+ {
+ LdapContext ctx = ( LdapContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ SearchControls controls = new SearchControls();
+ controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
+ controls.setReturningAttributes( new String[]{"+"} );
+
+ NamingEnumeration<SearchResult> res = ctx.search( "", "(commonName=Tori Amos)", controls );
+
+ assertTrue( res.hasMore() );
+
+ SearchResult result = res.next();
+
+ // ensure that result is not null
+ assertNotNull( result );
+
+ Attributes attrs = result.getAttributes();
+
+ // ensure that all operational attributes are returned
+ // and no user attributes
+ assertEquals( 2, attrs.size() );
+ assertNull( attrs.get( "cn" ) );
+ assertNull( attrs.get( "sn" ) );
+ assertNull( attrs.get( "objectClass" ) );
+ assertNull( attrs.get( "jpegPhoto" ) );
+ assertNull( attrs.get( "description" ) );
+ assertNotNull( attrs.get( "createtimestamp" ) );
+ assertNotNull( attrs.get( "creatorsname" ) );
+ }
+
+
+ @Test
+ public void testSearchAllAttrs() throws Exception
+ {
+ LdapContext ctx = ( LdapContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ SearchControls controls = new SearchControls();
+ controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
+ controls.setReturningAttributes( new String[]{"+", "*"} );
+
+ NamingEnumeration<SearchResult> res = ctx.search( "", "(commonName=Tori Amos)", controls );
+
+ assertTrue( res.hasMore() );
+
+ SearchResult result = ( SearchResult ) res.next();
+
+ // ensure that result is not null
+ assertNotNull( result );
+
+ Attributes attrs = result.getAttributes();
+
+ // ensure that all user attributes are returned
+ assertEquals( 8, attrs.size() );
+ assertNotNull( attrs.get( "cn" ) );
+ assertNotNull( attrs.get( "sn" ) );
+ assertNotNull( attrs.get( "objectClass" ) );
+ assertNotNull( attrs.get( "jpegPhoto" ) );
+ assertNotNull( attrs.get( "userCertificate" ) );
+ assertNotNull( attrs.get( "description" ) );
+ assertNotNull( attrs.get( "createtimestamp" ) );
+ assertNotNull( attrs.get( "creatorsname" ) );
+ }
+
+
+ @Test
+ public void testSearchBadDN() throws Exception
+ {
+ LdapContext ctx = ( LdapContext ) getWiredContext( ldapServer ).lookup( BASE );
+ SearchControls controls = new SearchControls();
+ controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
+
+ try
+ {
+ ctx.search( "cn=admin", "(objectClass=*)", controls );
+ }
+ catch ( NameNotFoundException nnfe )
+ {
+ assertTrue( true );
+ }
+ }
+
+
+ @Test
+ public void testSearchInvalidDN() throws Exception
+ {
+ LdapContext ctx = ( LdapContext ) getWiredContext( ldapServer ).lookup( BASE );
+
+ SearchControls controls = new SearchControls();
+ controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
+
+ try
+ {
+ ctx.search( "myBadDN", "(objectClass=*)", controls );
+ fail();
+ }
+ catch ( NamingException ne )
+ {
+ assertTrue( true );
+ }
+ }
+
+
+ /**
+ * Check if operational attributes are present, if "+" is requested.
+ */
+ @Test
+ public void testSearchOperationalAttributes() throws Exception
+ {
+ LdapContext ctx = ( LdapContext ) getWiredContext( ldapServer ).lookup( BASE );
+ SearchControls ctls = new SearchControls();
+
+ ctls.setSearchScope( SearchControls.OBJECT_SCOPE );
+ ctls.setReturningAttributes( new String[]
+ { "+" } );
+
+ NamingEnumeration<SearchResult> result = ctx.search( HEATHER_RDN, FILTER, ctls );
+
+ if ( result.hasMore() )
+ {
+ SearchResult entry = result.next();
+
+ String[] opAttrNames =
+ { "creatorsName", "createTimestamp" };
+
+ checkForAttributes( entry.getAttributes(), opAttrNames );
+ }
+ else
+ {
+ fail( "entry " + HEATHER_RDN + " not found" );
+ }
+
+ result.close();
+ }
+
+
+ /**
+ * Check if user attributes are present, if "*" is requested.
+ */
+ @Test
+ public void testSearchUserAttributes() throws Exception
+ {
+ LdapContext ctx = ( LdapContext ) getWiredContext( ldapServer ).lookup( BASE );
+ SearchControls ctls = new SearchControls();
+
+ ctls.setSearchScope( SearchControls.OBJECT_SCOPE );
+ ctls.setReturningAttributes( new String[]
+ { "*" } );
+
+ NamingEnumeration<SearchResult> result = ctx.search( HEATHER_RDN, FILTER, ctls );
+
+ if ( result.hasMore() )
+ {
+ SearchResult entry = result.next();
+
+ String[] userAttrNames =
+ { "objectClass", "sn", "cn" };
+
+ checkForAttributes( entry.getAttributes(), userAttrNames );
+ }
+ else
+ {
+ fail( "entry " + HEATHER_RDN + " not found" );
+ }
+
+ result.close();
+ }
+
+
+ /**
+ * Check if user and operational attributes are present, if both "*" and "+" are requested.
+ */
+ @Test
+ public void testSearchOperationalAndUserAttributes() throws Exception
+ {
+ LdapContext ctx = ( LdapContext ) getWiredContext( ldapServer ).lookup( BASE );
+ SearchControls ctls = new SearchControls();
+
+ ctls.setSearchScope( SearchControls.OBJECT_SCOPE );
+ ctls.setReturningAttributes( new String[]
+ { "+", "*" } );
+
+ String[] userAttrNames =
+ { "objectClass", "sn", "cn" };
+
+ String[] opAttrNames =
+ { "creatorsName", "createTimestamp" };
+
+ NamingEnumeration<SearchResult> result = ctx.search( HEATHER_RDN, FILTER, ctls );
+
+ if ( result.hasMore() )
+ {
+ SearchResult entry = result.next();
+ Attributes attrs = entry.getAttributes();
+
+ assertNotNull( attrs );
+
+ checkForAttributes( attrs, userAttrNames );
+ checkForAttributes( attrs, opAttrNames );
+ }
+ else
+ {
+ fail( "entry " + HEATHER_RDN + " not found" );
+ }
+
+ result.close();
+
+ ctls.setReturningAttributes( new String[]
+ { "*", "+" } );
+
+ result = ctx.search( HEATHER_RDN, FILTER, ctls );
+
+ if ( result.hasMore() )
+ {
+ SearchResult entry = ( SearchResult ) result.next();
+ Attributes attrs = entry.getAttributes();
+
+ assertNotNull( attrs );
+
+ checkForAttributes( attrs, userAttrNames );
+ checkForAttributes( attrs, opAttrNames );
+ }
+ else
+ {
+ fail( "entry " + HEATHER_RDN + " not found" );
+ }
+
+ result.close();
+ }
+
+
+ /**
+ * Test for DIRSERVER-1183.
+ *
+ * @see https://issues.apache.org/jira/browse/DIRSERVER-1183
+ * @throws Exception
+ */
+ @Test
+ public void testDIRSERVER_1183() throws Exception
+ {
+ LdapContext ctx = ( LdapContext ) getWiredContext( ldapServer ).lookup( BASE );
+ Attributes attrs = new AttributesImpl( "objectClass", "inetOrgPerson", true );
+ attrs.get( "objectClass" ).add( "organizationalPerson" );
+ attrs.get( "objectClass" ).add( "person" );
+ attrs.put( "givenName", "Jim" );
+ attrs.put( "sn", "Bean" );
+ attrs.put( "cn", "\"Jim, Bean\"" );
+
+ ctx.createSubcontext( "cn=\"Jim, Bean\"", attrs );
+ }
+
+
+ /**
+ * Test for DIRSERVER-1180 where search hangs when an invalid a substring
+ * expression missing an any field is used in a filter: i.e. (cn=**).
+ *
+ * @see https://issues.apache.org/jira/browse/DIRSERVER-1180
+ */
+ @Test
+ public void testMissingAnyInSubstring_DIRSERVER_1180() throws Exception
+ {
+ LdapContext ctx = ( LdapContext ) getWiredContext( ldapServer ).lookup( BASE );
+ Attributes attrs = new AttributesImpl( "objectClass", "inetOrgPerson", true );
+ attrs.get( "objectClass" ).add( "organizationalPerson" );
+ attrs.get( "objectClass" ).add( "person" );
+ attrs.put( "givenName", "Jim" );
+ attrs.put( "sn", "Bean" );
+ attrs.put( "cn", "jimbean" );
+
+ ctx.createSubcontext( "cn=jimbean", attrs );
+
+ try
+ {
+ ctx.search( "", "(cn=**)", new SearchControls() );
+ fail();
+ }
+ catch ( Exception e )
+ {
+ assertTrue( true );
+ }
+ }
+}
Modified: directory/apacheds/branches/bigbang/server-integ/src/test/java/org/apache/directory/server/suites/StockServerISuite.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/server-integ/src/test/java/org/apache/directory/server/suites/StockServerISuite.java?rev=683514&r1=683513&r2=683514&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/server-integ/src/test/java/org/apache/directory/server/suites/StockServerISuite.java (original)
+++ directory/apacheds/branches/bigbang/server-integ/src/test/java/org/apache/directory/server/suites/StockServerISuite.java Wed Aug 6 22:44:09 2008
@@ -40,6 +40,9 @@
import org.apache.directory.server.operations.modifydn.ModifyDnReferralIT;
import org.apache.directory.server.operations.modifydn.ModifyRdnIT;
import org.apache.directory.server.operations.modifydn.MoveIT;
+import org.apache.directory.server.operations.search.NegationSearchIT;
+import org.apache.directory.server.operations.search.SchemaSearchIT;
+import org.apache.directory.server.operations.search.SearchIT;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@@ -66,6 +69,9 @@
BindIT.class,
SimpleBindIT.class,
MoveIT.class,
+ SearchIT.class,
+ NegationSearchIT.class,
+ SchemaSearchIT.class,
ModifyDnReferralIT.class
} )
@CleanupLevel ( Level.SUITE )