Return-Path: X-Original-To: apmail-directory-commits-archive@www.apache.org Delivered-To: apmail-directory-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 4327410D1B for ; Tue, 2 Dec 2014 00:12:35 +0000 (UTC) Received: (qmail 75801 invoked by uid 500); 2 Dec 2014 00:12:35 -0000 Delivered-To: apmail-directory-commits-archive@directory.apache.org Received: (qmail 75765 invoked by uid 500); 2 Dec 2014 00:12:35 -0000 Mailing-List: contact commits-help@directory.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@directory.apache.org Delivered-To: mailing list commits@directory.apache.org Received: (qmail 75756 invoked by uid 99); 2 Dec 2014 00:12:35 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 02 Dec 2014 00:12:35 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 02 Dec 2014 00:12:10 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 3751223889E9; Tue, 2 Dec 2014 00:11:07 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1642792 - in /directory/apacheds/trunk/core-integ/src/test: java/org/apache/directory/server/core/operations/search/SortedSearchIT.java resources/sortedsearch-test-data.ldif Date: Tue, 02 Dec 2014 00:11:07 -0000 To: commits@directory.apache.org From: elecharny@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20141202001107.3751223889E9@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: elecharny Date: Tue Dec 2 00:11:06 2014 New Revision: 1642792 URL: http://svn.apache.org/r1642792 Log: Added tests using the Sort Control with core-integ. Two failing tests are @Ignored (but they need to be fixed) Added: directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/operations/search/SortedSearchIT.java directory/apacheds/trunk/core-integ/src/test/resources/sortedsearch-test-data.ldif Added: directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/operations/search/SortedSearchIT.java URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/operations/search/SortedSearchIT.java?rev=1642792&view=auto ============================================================================== --- directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/operations/search/SortedSearchIT.java (added) +++ directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/operations/search/SortedSearchIT.java Tue Dec 2 00:11:06 2014 @@ -0,0 +1,423 @@ +/* + * 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.core.operations.search; + + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.directory.api.ldap.model.constants.SchemaConstants; +import org.apache.directory.api.ldap.model.cursor.SearchCursor; +import org.apache.directory.api.ldap.model.entry.Entry; +import org.apache.directory.api.ldap.model.filter.ExprNode; +import org.apache.directory.api.ldap.model.filter.PresenceNode; +import org.apache.directory.api.ldap.model.message.ResultCodeEnum; +import org.apache.directory.api.ldap.model.message.SearchRequest; +import org.apache.directory.api.ldap.model.message.SearchRequestImpl; +import org.apache.directory.api.ldap.model.message.SearchResultDone; +import org.apache.directory.api.ldap.model.message.SearchResultEntry; +import org.apache.directory.api.ldap.model.message.SearchScope; +import org.apache.directory.api.ldap.model.message.controls.SortKey; +import org.apache.directory.api.ldap.model.message.controls.SortRequest; +import org.apache.directory.api.ldap.model.message.controls.SortRequestControlImpl; +import org.apache.directory.api.ldap.model.message.controls.SortResponse; +import org.apache.directory.api.ldap.model.message.controls.SortResultCode; +import org.apache.directory.api.ldap.model.name.Dn; +import org.apache.directory.ldap.client.api.LdapConnection; +import org.apache.directory.server.core.annotations.ApplyLdifFiles; +import org.apache.directory.server.core.annotations.CreateDS; +import org.apache.directory.server.core.annotations.LoadSchema; +import org.apache.directory.server.core.integ.AbstractLdapTestUnit; +import org.apache.directory.server.core.integ.FrameworkRunner; +import org.apache.directory.server.core.integ.IntegrationUtils; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; + + +/** + * Tests for searching with server side sort control. + * + * @author Apache Directory Project + */ +@RunWith(FrameworkRunner.class) +@CreateDS(name = "SearchDS", + loadedSchemas = + { @LoadSchema(name = "nis", enabled = true) }) +@ApplyLdifFiles( + { "sortedsearch-test-data.ldif" }) +public class SortedSearchIT extends AbstractLdapTestUnit +{ + private Dn baseDn; + + private ExprNode filter; + + /** A direct connecion to the server */ + private static LdapConnection connection; + + private SearchRequest req; + + private SortKey sk; + + private SortRequest ctrl; + + + @Before + public void createConnection() throws Exception + { + connection = IntegrationUtils.getAdminConnection( getService() ); + + baseDn = new Dn( "ou=parent,ou=system" ); + filter = new PresenceNode( "objectClass" ); + + req = new SearchRequestImpl(); + req.setBase( baseDn ); + req.setFilter( filter ); + req.setScope( SearchScope.SUBTREE ); + + // let the tests also test for DIRSERVER-1953 + req.addAttributes( SchemaConstants.ALL_USER_ATTRIBUTES_ARRAY ); + req.addAttributes( SchemaConstants.ENTRY_DN_AT ); + + // tests may overwrite the fields of the below SortKey instance + sk = new SortKey( "entryDn" ); + ctrl = new SortRequestControlImpl(); + ctrl.addSortKey( sk ); + req.addControl( ctrl ); + } + + + @AfterClass + public static void closeConnection() throws Exception + { + connection.close(); + } + + + /** + * section #2 scenario #3 + * + * @throws Exception + */ + @Test + @Ignore + public void testWithInvalidAttributeAndCriticality() throws Exception + { + sk.setAttributeTypeDesc( "Non-existing-At" ); + ctrl.setCritical( true ); + + SearchCursor cursor = connection.search( req ); + assertFalse( cursor.next() ); + + SearchResultDone sd = cursor.getSearchResultDone(); + + cursor.close(); + + SortResponse resp = ( SortResponse ) sd.getControl( SortResponse.OID ); + assertNotNull( resp ); + + assertEquals( SortResultCode.NOSUCHATTRIBUTE, resp.getSortResult() ); + assertEquals( sk.getAttributeTypeDesc(), resp.getAttributeName() ); + assertEquals( ResultCodeEnum.UNAVAILABLE_CRITICAL_EXTENSION, sd.getLdapResult().getResultCode() ); + } + + + /** + * section #2 scenario #4 + * + * @throws Exception + */ + @Test + @Ignore + public void testWithInvalidAttributeAndNoCriticality() throws Exception + { + sk.setAttributeTypeDesc( "Non-existing-At" ); + ctrl.setCritical( false ); + + SearchCursor cursor = connection.search( req ); + + int count = 0; + + while ( cursor.next() ) + { + cursor.get(); + count++; + } + + cursor.close(); + + assertEquals( 14, count ); + + SearchResultDone sd = cursor.getSearchResultDone(); + + SortResponse resp = ( SortResponse ) sd.getControl( SortResponse.OID ); + assertNotNull( resp ); + + assertEquals( SortResultCode.NOSUCHATTRIBUTE, resp.getSortResult() ); + assertEquals( sk.getAttributeTypeDesc(), resp.getAttributeName() ); + assertEquals( ResultCodeEnum.SUCCESS, sd.getLdapResult().getResultCode() ); + } + + + /** + * section #2 scenario #6 + * + * @throws Exception + */ + @Test + public void testWithInvalidFilter() throws Exception + { + req.setFilter( new PresenceNode( "mail" ) ); + + SearchCursor cursor = connection.search( req ); + + assertFalse( cursor.next() ); + + cursor.close(); + + SearchResultDone sd = cursor.getSearchResultDone(); + + SortResponse resp = ( SortResponse ) sd.getControl( SortResponse.OID ); + assertNull( resp ); + + assertEquals( ResultCodeEnum.SUCCESS, sd.getLdapResult().getResultCode() ); + } + + + ///////////////////////////// Tests for section #2 scenario #5 \\\\\\\\\\\\\\\\\\\\\\\\\\\\\ + + @Test + public void testSortBySn() throws Exception + { + sk.setAttributeTypeDesc( "sn" ); + SearchCursor cursor = connection.search( req ); + + List expectedOrder = new ArrayList(); + expectedOrder.add( "uid=person1,ou=parent,ou=system" ); + expectedOrder.add( "uid=person2,ou=parent,ou=system" ); + expectedOrder.add( "uid=person3,ou=parent,ou=system" ); + expectedOrder.add( "uid=user0,ou=parent,ou=system" ); + expectedOrder.add( "uid=user1,ou=parent,ou=system" ); + expectedOrder.add( "uid=user2,ou=children,ou=parent,ou=system" ); + expectedOrder.add( "uid=user3,ou=children,ou=parent,ou=system" ); + expectedOrder.add( "uid=user4,ou=grandchildren,ou=children,ou=parent,ou=system" ); + expectedOrder.add( "uid=user5,ou=grandchildren,ou=children,ou=parent,ou=system" ); + expectedOrder.add( "uid=user6,ou=parent,ou=system" ); + expectedOrder.add( "uid=user7,ou=parent,ou=system" ); + + int expectedCount = expectedOrder.size(); + + List actualOrder = new ArrayList(); + + while ( cursor.next() ) + { + SearchResultEntry se = ( SearchResultEntry ) cursor.get(); + Entry entry = se.getEntry(); + actualOrder.add( entry.getDn().getName() ); + } + + cursor.close(); + + // remove the LAST 3 entries present in the actualOrder list, they exist on top cause they don't have "sn" attribute + // NOTE: there is no guaranteed order for these LAST 3 entries + actualOrder.remove( actualOrder.size() - 1 ); + actualOrder.remove( actualOrder.size() - 1 ); + actualOrder.remove( actualOrder.size() - 1 ); + + assertEquals( expectedCount, actualOrder.size() ); + + for ( int i = 0; i < expectedOrder.size(); i++ ) + { + assertEquals( expectedOrder.get( i ), actualOrder.get( i ) ); + } + + // check reverse order + actualOrder.clear(); + + sk.setReverseOrder( true ); + cursor = connection.search( req ); + + while ( cursor.next() ) + { + SearchResultEntry se = ( SearchResultEntry ) cursor.get(); + Entry entry = se.getEntry(); + actualOrder.add( entry.getDn().getName() ); + } + + cursor.close(); + + // remove the FIRST 3 entries present in the actualOrder list, they exist on top cause they don't have "sn" attribute + // NOTE: there is no guaranteed order for these FIRST 3 entries + actualOrder.remove( 0 ); + actualOrder.remove( 0 ); + actualOrder.remove( 0 ); + + assertEquals( expectedCount, actualOrder.size() ); + + expectedCount--; + for ( int i = expectedOrder.size() - 1; i >= 0; i-- ) + { + assertEquals( expectedOrder.get( i ), actualOrder.get( expectedCount - i ) ); + } + } + + + // though "sn" is also multi-valued, the test data has only one value for "sn" in each entry + // so using "cn" for this test + @Test + public void testSortByMultiValuedAttribute() throws Exception + { + sk.setAttributeTypeDesc( "cn" ); + SearchCursor cursor = connection.search( req ); + + List expectedOrder = new ArrayList(); + expectedOrder.add( "uid=user6,ou=parent,ou=system" ); + expectedOrder.add( "uid=user0,ou=parent,ou=system" ); + expectedOrder.add( "uid=user1,ou=parent,ou=system" ); + expectedOrder.add( "uid=person3,ou=parent,ou=system" ); + expectedOrder.add( "uid=user2,ou=children,ou=parent,ou=system" ); + expectedOrder.add( "uid=user3,ou=children,ou=parent,ou=system" ); + expectedOrder.add( "uid=user4,ou=grandchildren,ou=children,ou=parent,ou=system" ); + expectedOrder.add( "uid=user5,ou=grandchildren,ou=children,ou=parent,ou=system" ); + expectedOrder.add( "uid=user7,ou=parent,ou=system" ); + expectedOrder.add( "uid=person1,ou=parent,ou=system" ); + expectedOrder.add( "uid=person2,ou=parent,ou=system" ); + + int expectedCount = expectedOrder.size(); + + List actualOrder = new ArrayList(); + + while ( cursor.next() ) + { + SearchResultEntry se = ( SearchResultEntry ) cursor.get(); + Entry entry = se.getEntry(); + actualOrder.add( entry.getDn().getName() ); + } + + cursor.close(); + + // remove the LAST 3 entries present in the actualOrder list, they exist on top cause they don't have "sn" attribute + // NOTE: there is no guaranteed order for these LAST 3 entries + actualOrder.remove( actualOrder.size() - 1 ); + actualOrder.remove( actualOrder.size() - 1 ); + actualOrder.remove( actualOrder.size() - 1 ); + + assertEquals( expectedCount, actualOrder.size() ); + + for ( int i = 0; i < expectedOrder.size(); i++ ) + { + assertEquals( expectedOrder.get( i ), actualOrder.get( i ) ); + } + + // check reverse order + actualOrder.clear(); + + sk.setReverseOrder( true ); + cursor = connection.search( req ); + + while ( cursor.next() ) + { + SearchResultEntry se = ( SearchResultEntry ) cursor.get(); + Entry entry = se.getEntry(); + actualOrder.add( entry.getDn().getName() ); + } + + cursor.close(); + + // remove the FIRST 3 entries present in the actualOrder list, they exist on top cause they don't have "sn" attribute + // NOTE: there is no guaranteed order for these FIRST 3 entries + actualOrder.remove( 0 ); + actualOrder.remove( 0 ); + actualOrder.remove( 0 ); + + assertEquals( expectedCount, actualOrder.size() ); + + expectedCount--; + for ( int i = expectedOrder.size() - 1; i >= 0; i-- ) + { + assertEquals( expectedOrder.get( i ), actualOrder.get( expectedCount - i ) ); + } + } + + + @Test + public void testSortByDn() throws Exception + { + sk.setAttributeTypeDesc( "entryDn" ); + sk.setMatchingRuleId( "2.5.13.1" ); + SearchCursor cursor = connection.search( req ); + + List actualOrder = new ArrayList(); + + while ( cursor.next() ) + { + SearchResultEntry se = ( SearchResultEntry ) cursor.get(); + Entry entry = se.getEntry(); + actualOrder.add( entry ); + } + + cursor.close(); + + // start deleting from the first entry + // SHOULD succeeded if the order is as expected + for ( int i = 0; i < actualOrder.size(); i++ ) + { + connection.delete( actualOrder.get( i ).getDn() ); + } + + // now insert from the last entry, SHOULD succeed + for ( int i = actualOrder.size() - 1; i >= 0; i-- ) + { + connection.add( actualOrder.get( i ) ); + } + + actualOrder.clear(); + + sk.setReverseOrder( true ); + cursor = connection.search( req ); + + while ( cursor.next() ) + { + SearchResultEntry se = ( SearchResultEntry ) cursor.get(); + Entry entry = se.getEntry(); + actualOrder.add( entry ); + } + + // now delete again, this time from the end, SHOULD succeed + for ( int i = actualOrder.size() - 1; i >= 0; i-- ) + { + connection.delete( actualOrder.get( i ).getDn() ); + } + + // now insert again, but from the beginning, SHOULD succeed + for ( int i = 0; i < actualOrder.size(); i++ ) + { + connection.add( actualOrder.get( i ) ); + } + } + +} Added: directory/apacheds/trunk/core-integ/src/test/resources/sortedsearch-test-data.ldif URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core-integ/src/test/resources/sortedsearch-test-data.ldif?rev=1642792&view=auto ============================================================================== --- directory/apacheds/trunk/core-integ/src/test/resources/sortedsearch-test-data.ldif (added) +++ directory/apacheds/trunk/core-integ/src/test/resources/sortedsearch-test-data.ldif Tue Dec 2 00:11:06 2014 @@ -0,0 +1,136 @@ +dn: ou=parent,ou=system +objectclass: top +objectclass: organizationalUnit +ou: parent + +dn: ou=children,ou=parent,ou=system +objectclass: top +objectclass: organizationalUnit +ou: children + +dn: ou=grandchildren,ou=children,ou=parent,ou=system +objectclass: top +objectclass: organizationalUnit +ou: grandchildren + +dn: uid=user0,ou=parent,ou=system +objectClass: top +objectClass: person +objectClass: organizationalPerson +objectClass: inetOrgPerson +givenName: user0_user0 +sn: user0_sn +cn: user0_cn +cn: cn_0 +uid: user0 + +dn: uid=user1,ou=parent,ou=system +objectClass: top +objectClass: person +objectClass: organizationalPerson +objectClass: inetOrgPerson +givenName: user1_user1 +sn: user1_sn +cn: user1_cn +cn: cn_1 +uid: user1 + +dn: uid=user2,ou=children,ou=parent,ou=system +objectClass: top +objectClass: person +objectClass: organizationalPerson +objectClass: inetOrgPerson +givenName: user0_user0 +sn: user2_sn +cn: user2_cn +cn: cn_2 +uid: user0 + +dn: uid=user3,ou=children,ou=parent,ou=system +objectClass: top +objectClass: person +objectClass: organizationalPerson +objectClass: inetOrgPerson +givenName: user3_user3 +sn: user3_sn +cn: user3_cn +cn: cn_3 +uid: user3 + +dn: uid=user4,ou=grandchildren,ou=children,ou=parent,ou=system +objectClass: top +objectClass: person +objectClass: organizationalPerson +objectClass: inetOrgPerson +givenName: user4_user4 +sn: user4_sn +cn: user4_cn +cn: cn_4 +uid: user4 + +dn: uid=user5,ou=grandchildren,ou=children,ou=parent,ou=system +objectClass: top +objectClass: person +objectClass: organizationalPerson +objectClass: inetOrgPerson +givenName: user5_user5 +sn: user5_sn +cn: user5_cn +cn: cn_5 +uid: user5 + +dn: uid=user6,ou=parent,ou=system +objectClass: top +objectClass: person +objectClass: organizationalPerson +objectClass: inetOrgPerson +givenName: user6_user6 +sn: user6_sn +cn: a_cn +cn: cn_6 +uid: user6 + +dn: uid=user7,ou=parent,ou=system +objectClass: top +objectClass: person +objectClass: organizationalPerson +objectClass: inetOrgPerson +givenName: user7_user7 +sn: user7_sn +cn: user7_cn +cn: cn_7 +uid: user7 + +dn: uid=person1,ou=parent,ou=system +objectClass: top +objectClass: person +objectClass: organizationalPerson +objectClass: inetOrgPerson +givenName: person0_person0 +sn: person1_sn +cn: person1_cn +cn: cn_8 +uid: person1 + +dn: uid=person2,ou=parent,ou=system +objectClass: top +objectClass: person +objectClass: organizationalPerson +objectClass: inetOrgPerson +givenName: person1_person1 +sn: person2_sn +cn: person2_cn +cn: cn_9 +uid: person2 + +dn: uid=person3,ou=parent,ou=system +objectClass: top +objectClass: person +objectClass: organizationalPerson +objectClass: inetOrgPerson +givenName: person2_person2 +sn: person3_sn +cn: person3_cn +cn: cn_10 +uid: person3 +