View Javadoc

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;
18  
19  
20  import java.io.File;
21  import java.io.FileInputStream;
22  import java.io.FileNotFoundException;
23  import java.io.IOException;
24  import java.io.InputStream;
25  import java.util.ArrayList;
26  import java.util.Hashtable;
27  import java.util.List;
28  
29  import javax.naming.Context;
30  import javax.naming.InitialContext;
31  import javax.naming.NamingException;
32  import javax.naming.directory.Attributes;
33  import javax.naming.ldap.InitialLdapContext;
34  import javax.naming.ldap.LdapContext;
35  
36  import junit.framework.TestCase;
37  
38  import org.apache.commons.io.FileUtils;
39  import org.apache.commons.lang.exception.NestableRuntimeException;
40  import org.apache.ldap.common.ldif.LdifIterator;
41  import org.apache.ldap.common.ldif.LdifParserImpl;
42  import org.apache.ldap.common.message.LockableAttributesImpl;
43  import org.apache.ldap.server.configuration.Configuration;
44  import org.apache.ldap.server.configuration.MutableStartupConfiguration;
45  import org.apache.ldap.server.configuration.ShutdownConfiguration;
46  
47                                                                                                              
48  /***
49   * A simple testcase for testing JNDI provider functionality.
50   *
51   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
52   * @version $Rev: 280870 $
53   */
54  public abstract class AbstractTestCase extends TestCase
55  {
56      public static final String LDIF = "dn: uid=akarasulu,ou=users,ou=system\n" +
57              "cn: Alex Karasulu\n" +
58              "sn: Karasulu\n" +
59              "givenname: Alex\n" +
60              "objectclass: top\n" +
61              "objectclass: person\n" +
62              "objectclass: organizationalPerson\n" +
63              "objectclass: inetOrgPerson\n" +
64              "ou: Engineering\n" +
65              "ou: People\n" +
66              "l: Bogusville\n" +
67              "uid: akarasulu\n" +
68              "mail: akarasulu@apache.org\n" +
69              "telephonenumber: +1 408 555 4798\n" +
70              "facsimiletelephonenumber: +1 408 555 9751\n" +
71              "roomnumber: 4612\n" +
72              "userpassword: test\n";
73      
74      private final String username;
75      
76      private final String password;
77  
78      /*** the context root for the system partition */
79      protected LdapContext sysRoot;
80      
81      /*** flag whether to delete database files for each test or not */
82      protected boolean doDelete = true;
83      
84      protected MutableStartupConfiguration configuration = new MutableStartupConfiguration();
85  
86      /*** A testEntries of entries as Attributes to add to the DIT for testing */
87      protected List testEntries = new ArrayList();
88  
89      /*** An optional LDIF file path if set and present is read to add more test entries */
90      private String ldifPath;
91  
92      /*** Load resources relative to this class */
93      private Class loadClass;
94  
95      private Hashtable overrides = new Hashtable(); 
96  
97      protected AbstractTestCase( String username, String password )
98      {
99          if( username == null || password == null )
100         {
101             throw new NullPointerException();
102         }
103 
104         this.username = username;
105         this.password = password;
106     }
107 
108     /***
109      * Sets the LDIF path as a relative resource path to use with the
110      * loadClass parameter to load the resource.
111      *
112      * @param ldifPath the relative resource path to the LDIF file
113      * @param loadClass the class used to load the LDIF as a resource stream
114      */
115     protected void setLdifPath( String ldifPath, Class loadClass )
116     {
117         this.loadClass = loadClass;
118 
119         this.ldifPath = ldifPath;
120     }
121 
122 
123     /***
124      * Sets the LDIF path to use.  If the path is relative to this class then it
125      * is first tested
126      *
127      * @param ldifPath the path to the LDIF file
128      */
129     protected void setLdifPath( String ldifPath )
130     {
131         this.ldifPath = ldifPath;
132     }
133 
134 
135     /***
136      * Get's the initial context factory for the provider's ou=system context
137      * root.
138      *
139      * @see junit.framework.TestCase#setUp()
140      */
141     protected void setUp() throws Exception
142     {
143         super.setUp();
144 
145         // -------------------------------------------------------------------
146         // Add a single test entry
147         // -------------------------------------------------------------------
148 
149         Attributes attributes = new LockableAttributesImpl();
150 
151         LdifParserImpl parser = new LdifParserImpl();
152 
153         try
154         {
155             parser.parse( attributes, LDIF );
156         }
157         catch ( NamingException e )
158         {
159             throw new NestableRuntimeException( e );
160         }
161 
162         testEntries.add( attributes );
163 
164         // -------------------------------------------------------------------
165         // Add more from an optional LDIF file if they exist
166         // -------------------------------------------------------------------
167 
168         InputStream in = null;
169 
170         if ( loadClass == null && ldifPath != null )
171         {
172             File ldifFile = new File( ldifPath );
173 
174             if ( ldifFile.exists() )
175             {
176                 in = new FileInputStream( ldifPath );
177             }
178             else
179             {
180                 in = getClass().getResourceAsStream( ldifPath );
181             }
182 
183             throw new FileNotFoundException( ldifPath );
184         }
185         else if ( loadClass != null && ldifPath != null )
186         {
187             in = loadClass.getResourceAsStream( ldifPath );
188         }
189 
190         if ( in != null )
191         {
192             LdifIterator list = new LdifIterator( in );
193 
194             while ( list.hasNext() )
195             {
196                 String ldif = ( String ) list.next();
197 
198                 attributes = new LockableAttributesImpl();
199 
200                 parser.parse( attributes, ldif );
201 
202                 testEntries.add( attributes );
203             }
204         }
205 
206         // -------------------------------------------------------------------
207         // Add key for extra entries to the testEntries of extras
208         // -------------------------------------------------------------------
209 
210         configuration.setTestEntries( testEntries );
211         doDelete( configuration.getWorkingDirectory() );
212         setSysRoot( username, password, configuration );
213     }
214 
215 
216     /***
217      * Deletes the Eve working directory.
218      */
219     protected void doDelete( File wkdir ) throws IOException
220     {
221         if ( doDelete )
222         {
223             if ( wkdir.exists() )
224             {
225                 FileUtils.deleteDirectory( wkdir );
226             }
227             if ( wkdir.exists() )
228             {
229                 throw new IOException( "Failed to delete: " + wkdir );
230             }
231         }
232     }
233 
234 
235     /***
236      * Sets and returns the system root.  Values of user and password used to
237      * set the respective JNDI properties.  These values can be overriden by the
238      * overrides properties.
239      *
240      * @param user the username for authenticating as this user
241      * @param passwd the password of the user
242      * @return the sysRoot context which is also set
243      * @throws NamingException if there is a failure of any kind
244      */
245     protected LdapContext setSysRoot( String user, String passwd, Configuration cfg ) throws NamingException
246     {
247         Hashtable env = new Hashtable( cfg.toJndiEnvironment() );
248         env.put( Context.SECURITY_PRINCIPAL, user );
249         env.put( Context.SECURITY_CREDENTIALS, passwd );
250         env.put( Context.SECURITY_AUTHENTICATION, "simple" );
251         return setSysRoot( env );
252     }
253 
254 
255     /***
256      * Sets the system root taking into account the extras and overrides
257      * properties.  In between these it sets the properties for the working
258      * directory, the provider URL and the JNDI InitialContexFactory to use.
259      *
260      * @param env an environment to use while setting up the system root.
261      * @return the sysRoot context which is also set
262      * @throws NamingException if there is a failure of any kind
263      */
264     protected LdapContext setSysRoot( Hashtable env ) throws NamingException
265     {
266         Hashtable envFinal = new Hashtable( env );
267         if ( ! envFinal.containsKey( Context.PROVIDER_URL ) )
268         {
269             envFinal.put( Context.PROVIDER_URL, "ou=system" );
270         }
271         
272         envFinal.put( Context.INITIAL_CONTEXT_FACTORY, "org.apache.ldap.server.jndi.CoreContextFactory" );
273         envFinal.putAll( overrides );
274         
275         // We have to initiate the first run as an admin at least.
276         Hashtable adminEnv = new Hashtable( envFinal );
277         adminEnv.put( Context.SECURITY_PRINCIPAL, "uid=admin,ou=system" );
278         adminEnv.put( Context.SECURITY_CREDENTIALS, "secret" );
279         adminEnv.put( Context.SECURITY_AUTHENTICATION, "simple" );
280         new InitialLdapContext( adminEnv, null );
281 
282         // OK, now let's get an appropriate context.
283         return sysRoot = new InitialLdapContext( envFinal, null );
284     }
285 
286     /***
287      * Overrides default JNDI environment properties.  Please call this method
288      * to override any JNDI environment properties this test case will set.
289      */
290     protected void overrideEnvironment( String key, Object value )
291     {
292         overrides.put( key, value );
293     }
294 
295 
296     protected Hashtable getOverriddenEnvironment()
297     {
298         return ( Hashtable ) overrides.clone();
299     }
300 
301 
302     /***
303      * Sets the system context root to null.
304      *
305      * @see junit.framework.TestCase#tearDown()
306      */
307     protected void tearDown() throws Exception
308     {
309         super.tearDown();
310 
311         Hashtable env = new Hashtable();
312 
313         env.put( Context.PROVIDER_URL, "ou=system" );
314         env.put( Context.INITIAL_CONTEXT_FACTORY, "org.apache.ldap.server.jndi.CoreContextFactory" );
315         env.putAll( new ShutdownConfiguration().toJndiEnvironment() );
316         env.put( Context.SECURITY_PRINCIPAL, "uid=admin,ou=system" );
317         env.put( Context.SECURITY_CREDENTIALS, "secret" );
318         env.put( Context.SECURITY_AUTHENTICATION, "simple" );
319 
320         try { new InitialContext( env ); } catch( Exception e ) {}
321 
322         sysRoot = null;
323 
324         Runtime.getRuntime().gc();
325 
326         testEntries.clear();
327 
328         ldifPath = null;
329 
330         loadClass = null;
331         
332         overrides.clear();
333         
334         configuration = new MutableStartupConfiguration();
335         
336         doDelete( configuration.getWorkingDirectory() );
337     }
338 }