1   /*
2    *   Copyright 2004 The Apache Software Foundation
3    *
4    *   Licensed under the Apache License, Version 2.0 (the "License");
5    *   you may not use this file except in compliance with the License.
6    *   You may obtain a copy of the License at
7    *
8    *       http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *   Unless required by applicable law or agreed to in writing, software
11   *   distributed under the License is distributed on an "AS IS" BASIS,
12   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *   See the License for the specific language governing permissions and
14   *   limitations under the License.
15   *
16   */
17  package org.apache.ldap.server.exception;
18  
19  
20  import org.apache.ldap.common.exception.LdapContextNotEmptyException;
21  import org.apache.ldap.common.exception.LdapNameAlreadyBoundException;
22  import org.apache.ldap.common.exception.LdapNameNotFoundException;
23  import org.apache.ldap.common.exception.LdapNamingException;
24  import org.apache.ldap.common.message.ResultCodeEnum;
25  import org.apache.ldap.server.AbstractCoreTest;
26  
27  import javax.naming.Context;
28  import javax.naming.NamingEnumeration;
29  import javax.naming.NamingException;
30  import javax.naming.directory.*;
31  import javax.naming.ldap.LdapContext;
32  
33  
34  /***
35   * Tests the correct operation of the ServerExceptionService.
36   *
37   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
38   * @version $Rev$
39   */
40  public class ExceptionServiceTest extends AbstractCoreTest
41  {
42      // ------------------------------------------------------------------------
43      // Search Operation Tests
44      // ------------------------------------------------------------------------
45  
46  
47      /***
48       * Test search operation failure when the search base is non-existant.
49       */
50      public void testFailSearchNoSuchObject() throws NamingException
51      {
52          SearchControls ctls = new SearchControls();
53          try
54          {
55              sysRoot.search( "ou=blah", "(objectClass=*)", ctls );
56              fail( "Execution should never get here due to exception!" );
57          }
58          catch( LdapNameNotFoundException e )
59          {
60              assertEquals( "ou=system", e.getResolvedName().toString() );
61              assertEquals( ResultCodeEnum.NOSUCHOBJECT, e.getResultCode() );
62          }
63      }
64  
65  
66      /***
67       * Search operation control to test if normal search operations occur
68       * correctly.
69       */
70      public void testSearchControl() throws NamingException
71      {
72          SearchControls ctls = new SearchControls();
73          NamingEnumeration list = sysRoot.search( "ou=users", "(objectClass=*)", ctls );
74  
75          if ( list.hasMore() )
76          {
77              SearchResult result = ( SearchResult ) list.next();
78              assertNotNull( result.getAttributes() );
79              assertEquals( "uid=akarasulu,ou=users,ou=system", result.getName().toString() );
80          }
81  
82          assertFalse( list.hasMore() );
83      }
84  
85  
86      // ------------------------------------------------------------------------
87      // Move Operation Tests
88      // ------------------------------------------------------------------------
89  
90  
91      /***
92       * Test move operation failure when the object moved is non-existant.
93       */
94      public void testFailMoveEntryAlreadyExists() throws NamingException
95      {
96          try
97          {
98              sysRoot.createSubcontext( "ou=users,ou=groups" );
99              sysRoot.rename( "ou=users", "ou=users,ou=groups" );
100             fail( "Execution should never get here due to exception!" );
101         }
102         catch( LdapNameAlreadyBoundException e )
103         {
104             assertEquals( "ou=users,ou=groups,ou=system", e.getResolvedName().toString() );
105             assertEquals( ResultCodeEnum.ENTRYALREADYEXISTS, e.getResultCode() );
106         }
107 
108         try
109         {
110             sysRoot.createSubcontext( "ou=uzerz,ou=groups" );
111             sysRoot.addToEnvironment( "java.naming.ldap.deleteRDN", "false" );
112             sysRoot.rename( "ou=users", "ou=uzerz,ou=groups" );
113             sysRoot.removeFromEnvironment( "java.naming.ldap.deleteRDN" );
114             fail( "Execution should never get here due to exception!" );
115         }
116         catch( LdapNameAlreadyBoundException e )
117         {
118             assertEquals( "ou=uzerz,ou=groups,ou=system", e.getResolvedName().toString() );
119             assertEquals( ResultCodeEnum.ENTRYALREADYEXISTS, e.getResultCode() );
120         }
121     }
122 
123 
124     /***
125      * Test move operation failure when the object moved is non-existant.
126      */
127     public void testFailMoveNoSuchObject() throws NamingException
128     {
129         try
130         {
131             sysRoot.rename( "ou=blah", "ou=blah,ou=groups" );
132             fail( "Execution should never get here due to exception!" );
133         }
134         catch( LdapNameNotFoundException e )
135         {
136             assertEquals( "ou=system", e.getResolvedName().toString() );
137             assertEquals( ResultCodeEnum.NOSUCHOBJECT, e.getResultCode() );
138         }
139 
140         try
141         {
142             sysRoot.addToEnvironment( "java.naming.ldap.deleteRDN", "false" );
143             sysRoot.rename( "ou=blah", "ou=blah2,ou=groups" );
144             sysRoot.removeFromEnvironment( "java.naming.ldap.deleteRDN" );
145             fail( "Execution should never get here due to exception!" );
146         }
147         catch( LdapNameNotFoundException e )
148         {
149             assertEquals( "ou=system", e.getResolvedName().toString() );
150             assertEquals( ResultCodeEnum.NOSUCHOBJECT, e.getResultCode() );
151         }
152     }
153 
154 
155     /***
156      * Move operation control to test if normal move operations occur
157      * correctly.
158      */
159     public void testMoveControl() throws NamingException
160     {
161         sysRoot.rename( "ou=users", "ou=users,ou=groups" );
162         assertNotNull( sysRoot.lookup( "ou=users,ou=groups" ) );
163 
164         try
165         {
166             sysRoot.lookup( "ou=users" );
167             fail( "Execution should never get here due to exception!" );
168         }
169         catch( NamingException e )
170         {
171             assertEquals( "ou=system", e.getResolvedName().toString() );
172             assertTrue( e instanceof LdapNameNotFoundException );
173         }
174     }
175 
176 
177     // ------------------------------------------------------------------------
178     // ModifyRdn Operation Tests
179     // ------------------------------------------------------------------------
180 
181     /***
182      * Test modifyRdn operation failure when the object renamed is non-existant.
183      */
184     public void testFailModifyRdnEntryAlreadyExists() throws NamingException
185     {
186         try
187         {
188             sysRoot.rename( "ou=users", "ou=groups" );
189             fail( "Execution should never get here due to exception!" );
190         }
191         catch( LdapNameAlreadyBoundException e )
192         {
193             assertEquals( "ou=groups,ou=system", e.getResolvedName().toString() );
194             assertEquals( ResultCodeEnum.ENTRYALREADYEXISTS, e.getResultCode() );
195         }
196     }
197 
198 
199     /***
200      * Test modifyRdn operation failure when the object renamed is non-existant.
201      */
202     public void testFailModifyRdnNoSuchObject() throws NamingException
203     {
204         try
205         {
206             sysRoot.rename( "ou=blah", "ou=asdf" );
207             fail( "Execution should never get here due to exception!" );
208         }
209         catch( LdapNameNotFoundException e )
210         {
211             assertEquals( "ou=system", e.getResolvedName().toString() );
212             assertEquals( ResultCodeEnum.NOSUCHOBJECT, e.getResultCode() );
213         }
214     }
215 
216 
217     /***
218      * Modify operation control to test if normal modify operations occur
219      * correctly.
220      */
221     public void testModifyRdnControl() throws NamingException
222     {
223         sysRoot.rename( "ou=users", "ou=asdf" );
224         assertNotNull( sysRoot.lookup( "ou=asdf" ) );
225 
226         try
227         {
228             sysRoot.lookup( "ou=users" );
229             fail( "Execution should never get here due to exception!" );
230         }
231         catch( NamingException e )
232         {
233             assertEquals( "ou=system", e.getResolvedName().toString() );
234             assertTrue( e instanceof LdapNameNotFoundException );
235         }
236     }
237 
238 
239     // ------------------------------------------------------------------------
240     // Modify Operation Tests
241     // ------------------------------------------------------------------------
242 
243     /***
244      * Test modify operation failure when the object modified is non-existant.
245      */
246     public void testFailModifyNoSuchObject() throws NamingException
247     {
248         Attributes attrs = new BasicAttributes();
249         Attribute ou = new BasicAttribute( "ou" );
250         ou.add( "users" );
251         ou.add( "dummyValue" );
252         attrs.put( ou );
253 
254         try
255         {
256             sysRoot.modifyAttributes( "ou=blah", DirContext.ADD_ATTRIBUTE, attrs );
257             fail( "Execution should never get here due to exception!" );
258         }
259         catch( LdapNameNotFoundException e )
260         {
261             assertEquals( "ou=system", e.getResolvedName().toString() );
262             assertEquals( ResultCodeEnum.NOSUCHOBJECT, e.getResultCode() );
263         }
264 
265 
266         ModificationItem[] mods = new ModificationItem[] {
267             new ModificationItem( DirContext.ADD_ATTRIBUTE, ou )
268         };
269 
270         try
271         {
272             sysRoot.modifyAttributes( "ou=blah", mods );
273             fail( "Execution should never get here due to exception!" );
274         }
275         catch( LdapNameNotFoundException e )
276         {
277             assertEquals( "ou=system", e.getResolvedName().toString() );
278             assertEquals( ResultCodeEnum.NOSUCHOBJECT, e.getResultCode() );
279         }
280     }
281 
282 
283     /***
284      * Modify operation control to test if normal modify operations occur
285      * correctly.
286      */
287     public void testModifyControl() throws NamingException
288     {
289         Attributes attrs = new BasicAttributes();
290         Attribute attr = new BasicAttribute( "ou" );
291         attr.add( "users" );
292         attr.add( "dummyValue" );
293         attrs.put( attr );
294         sysRoot.modifyAttributes( "ou=users", DirContext.ADD_ATTRIBUTE, attrs );
295         Attribute ou = sysRoot.getAttributes( "ou=users" ).get( "ou" );
296         assertTrue( ou.contains( "users" ) );
297         assertTrue( ou.contains( "dummyValue" ) );
298 
299         attr.add( "another" );
300         ModificationItem[] mods = new ModificationItem[] {
301             new ModificationItem( DirContext.ADD_ATTRIBUTE, attr )
302         };
303 
304         sysRoot.modifyAttributes( "ou=users", mods );
305         ou = sysRoot.getAttributes( "ou=users" ).get( "ou" );
306         assertTrue( ou.contains( "users" ) );
307         assertTrue( ou.contains( "dummyValue" ) );
308         assertTrue( ou.contains( "another" ) );
309     }
310 
311 
312     // ------------------------------------------------------------------------
313     // Lookup Operation Tests
314     // ------------------------------------------------------------------------
315 
316     /***
317      * Test lookup operation failure when the object looked up is non-existant.
318      */
319     public void testFailLookupNoSuchObject() throws NamingException
320     {
321         try
322         {
323             sysRoot.lookup( "ou=blah" );
324             fail( "Execution should never get here due to exception!" );
325         }
326         catch( LdapNameNotFoundException e )
327         {
328             assertEquals( "ou=system", e.getResolvedName().toString() );
329             assertEquals( ResultCodeEnum.NOSUCHOBJECT, e.getResultCode() );
330         }
331     }
332 
333 
334     /***
335      * Lookup operation control to test if normal lookup operations occur
336      * correctly.
337      */
338     public void testLookupControl() throws NamingException
339     {
340         LdapContext ctx = ( LdapContext ) sysRoot.lookup( "ou=users" );
341         assertNotNull( ctx );
342         assertEquals( "users", ctx.getAttributes("").get( "ou" ).get() );
343     }
344 
345 
346     // ------------------------------------------------------------------------
347     // List Operation Tests
348     // ------------------------------------------------------------------------
349 
350 
351     /***
352      * Test list operation failure when the base searched is non-existant.
353      */
354     public void testFailListNoSuchObject() throws NamingException
355     {
356         try
357         {
358             sysRoot.list( "ou=blah" );
359             fail( "Execution should never get here due to exception!" );
360         }
361         catch( LdapNameNotFoundException e )
362         {
363             assertEquals( "ou=system", e.getResolvedName().toString() );
364             assertEquals( ResultCodeEnum.NOSUCHOBJECT, e.getResultCode() );
365         }
366     }
367 
368 
369     /***
370      * List operation control to test if normal list operations occur correctly.
371      */
372     public void testListControl() throws NamingException
373     {
374         NamingEnumeration list = sysRoot.list( "ou=users" );
375 
376         if ( list.hasMore() )
377         {
378             SearchResult result = ( SearchResult ) list.next();
379             assertNotNull( result.getAttributes() );
380             assertEquals( "uid=akarasulu,ou=users,ou=system", result.getName().toString() );
381         }
382 
383         assertFalse( list.hasMore() );
384     }
385 
386 
387     // ------------------------------------------------------------------------
388     // Add Operation Tests
389     // ------------------------------------------------------------------------
390 
391 
392     /***
393      * Tests for add operation failure when the parent of the entry to add does
394      * not exist.
395      */
396     public void testFailAddOnAlias() throws NamingException
397     {
398         Attributes attrs = new BasicAttributes();
399         Attribute attr = new BasicAttribute( "objectClass" );
400         attr.add( "top" );
401         attr.add( "alias" );
402         attrs.put( attr );
403         attrs.put( "aliasedObjectName", "ou=users,ou=system" );
404 
405         sysRoot.createSubcontext( "cn=toanother", attrs );
406 
407         try
408         {
409             sysRoot.createSubcontext( "ou=blah,cn=toanother" );
410             fail( "Execution should never get here due to exception!" );
411         }
412         catch( LdapNamingException e )
413         {
414             assertEquals( "cn=toanother,ou=system", e.getResolvedName().toString() );
415             assertEquals( ResultCodeEnum.ALIASPROBLEM, e.getResultCode() );
416         }
417     }
418 
419 
420     /***
421      * Tests for add operation failure when the parent of the entry to add does
422      * not exist.
423      */
424     public void testFailAddNoSuchEntry() throws NamingException
425     {
426         try
427         {
428             sysRoot.createSubcontext( "ou=blah,ou=abc" );
429             fail( "Execution should never get here due to exception!" );
430         }
431         catch( LdapNameNotFoundException e )
432         {
433             assertEquals( "ou=system", e.getResolvedName().toString() );
434             assertEquals( ResultCodeEnum.NOSUCHOBJECT, e.getResultCode() );
435         }
436     }
437 
438 
439     /***
440      * Tests for add operation failure when the entry to add already exists.
441      */
442     public void testFailAddEntryAlreadyExists() throws NamingException
443     {
444         sysRoot.createSubcontext( "ou=blah" );
445 
446         try
447         {
448             sysRoot.createSubcontext( "ou=blah" );
449             fail( "Execution should never get here due to exception!" );
450         }
451         catch( LdapNameAlreadyBoundException e )
452         {
453             assertEquals( "ou=blah,ou=system", e.getResolvedName().toString() );
454             assertEquals( ResultCodeEnum.ENTRYALREADYEXISTS, e.getResultCode() );
455         }
456     }
457 
458 
459     /***
460      * Add operation control to test if normal add operations occur correctly.
461      */
462     public void testAddControl() throws NamingException
463     {
464         Context ctx = sysRoot.createSubcontext( "ou=blah" );
465         ctx.createSubcontext( "ou=subctx" );
466         Object obj = sysRoot.lookup( "ou=subctx,ou=blah" );
467         assertNotNull( obj );
468     }
469 
470 
471     // ------------------------------------------------------------------------
472     // Delete Operation Tests
473     // ------------------------------------------------------------------------
474 
475 
476     /***
477      * Tests for delete failure when the entry to be deleted has child entires.
478      */
479     public void testFailDeleteNotAllowedOnNonLeaf() throws NamingException
480     {
481         Context ctx = sysRoot.createSubcontext( "ou=blah" );
482         ctx.createSubcontext( "ou=subctx" );
483 
484         try
485         {
486             sysRoot.destroySubcontext( "ou=blah" );
487             fail( "Execution should never get here due to exception!" );
488         }
489         catch( LdapContextNotEmptyException e )
490         {
491             assertEquals( "ou=blah,ou=system", e.getResolvedName().toString() );
492             assertEquals( ResultCodeEnum.NOTALLOWEDONNONLEAF, e.getResultCode() );
493         }
494     }
495 
496 
497     /***
498      * Tests delete to make sure it fails when we try to delete an entry that
499      * does not exist.
500      */
501     public void testFailDeleteNoSuchObject() throws NamingException
502     {
503         try
504         {
505             sysRoot.destroySubcontext( "ou=blah" );
506             fail( "Execution should never get here due to exception!" );
507         }
508         catch( LdapNameNotFoundException e )
509         {
510             assertEquals( "ou=system", e.getResolvedName().toString() );
511             assertEquals( ResultCodeEnum.NOSUCHOBJECT, e.getResultCode() );
512         }
513     }
514 
515 
516     /***
517      * Delete operation control to test if normal delete operations occur.
518      */
519     public void testDeleteControl() throws NamingException
520     {
521         sysRoot.createSubcontext( "ou=blah" );
522         Object obj = sysRoot.lookup( "ou=blah" );
523         assertNotNull( obj );
524         sysRoot.destroySubcontext( "ou=blah" );
525 
526         try
527         {
528             sysRoot.lookup( "ou=blah" );
529             fail( "Execution should never get here due to exception!" );
530         }
531         catch( LdapNameNotFoundException e )
532         {
533             assertEquals( "ou=system", e.getResolvedName().toString() );
534             assertEquals( ResultCodeEnum.NOSUCHOBJECT, e.getResultCode() );
535         }
536     }
537 }