1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *  
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *  
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License. 
18   *  
19   */
20  package org.apache.directory.server.xdbm.search.impl;
21  
22  
23  import org.slf4j.Logger;
24  import org.slf4j.LoggerFactory;
25  import org.apache.directory.server.schema.registries.*;
26  import org.apache.directory.server.schema.SerializableComparator;
27  import org.apache.directory.server.schema.bootstrap.*;
28  import org.apache.directory.server.xdbm.Store;
29  import org.apache.directory.server.xdbm.ForwardIndexEntry;
30  import org.apache.directory.server.xdbm.tools.StoreUtils;
31  import org.apache.directory.server.core.partition.impl.btree.jdbm.JdbmIndex;
32  import org.apache.directory.server.core.partition.impl.btree.jdbm.JdbmStore;
33  import org.apache.directory.server.core.cursor.InvalidCursorPositionException;
34  import org.apache.directory.server.core.entry.ServerEntry;
35  import org.apache.directory.shared.ldap.constants.SchemaConstants;
36  import org.apache.directory.shared.ldap.filter.PresenceNode;
37  import org.apache.commons.io.FileUtils;
38  import org.junit.Before;
39  import org.junit.After;
40  import org.junit.Test;
41  import static org.junit.Assert.*;
42  
43  import java.io.File;
44  import java.util.Set;
45  import java.util.HashSet;
46  
47  
48  /**
49   * Tests PresenceCursor and PresenceEvaluator functionality.
50   *
51   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
52   * @version $$Rev$$
53   */
54  public class PresenceTest
55  {
56      private static final Logger LOG = LoggerFactory.getLogger( PresenceTest.class.getSimpleName() );
57  
58      File wkdir;
59      Store<ServerEntry> store;
60      Registries registries = null;
61      AttributeTypeRegistry attributeRegistry;
62  
63  
64      public PresenceTest() throws Exception
65      {
66          // setup the standard registries
67          BootstrapSchemaLoader loader = new BootstrapSchemaLoader();
68          OidRegistry oidRegistry = new DefaultOidRegistry();
69          registries = new DefaultRegistries( "bootstrap", loader, oidRegistry );
70          SerializableComparator.setRegistry( registries.getComparatorRegistry() );
71  
72          // load essential bootstrap schemas
73          Set<Schema> bootstrapSchemas = new HashSet<Schema>();
74          bootstrapSchemas.add( new ApachemetaSchema() );
75          bootstrapSchemas.add( new ApacheSchema() );
76          bootstrapSchemas.add( new CoreSchema() );
77          bootstrapSchemas.add( new SystemSchema() );
78          bootstrapSchemas.add( new CollectiveSchema() );
79          loader.loadWithDependencies( bootstrapSchemas, registries );
80          attributeRegistry = registries.getAttributeTypeRegistry();
81      }
82  
83  
84      @Before
85      public void createStore() throws Exception
86      {
87          destryStore();
88  
89          // setup the working directory for the store
90          wkdir = File.createTempFile( getClass().getSimpleName(), "db" );
91          wkdir.delete();
92          wkdir = new File( wkdir.getParentFile(), getClass().getSimpleName() );
93          wkdir.mkdirs();
94  
95          // initialize the store
96          store = new JdbmStore<ServerEntry>();
97          store.setName( "example" );
98          store.setCacheSize( 10 );
99          store.setWorkingDirectory( wkdir );
100         store.setSyncOnWrite( false );
101 
102         store.addIndex( new JdbmIndex( SchemaConstants.OU_AT_OID ) );
103         store.addIndex( new JdbmIndex( SchemaConstants.CN_AT_OID ) );
104         StoreUtils.loadExampleData( store, registries );
105         LOG.debug( "Created new store" );
106     }
107 
108 
109     @After
110     public void destryStore() throws Exception
111     {
112         if ( store != null )
113         {
114             store.destroy();
115         }
116 
117         store = null;
118         if ( wkdir != null )
119         {
120             FileUtils.deleteDirectory( wkdir );
121         }
122 
123         wkdir = null;
124     }
125 
126 
127     @Test
128     public void testIndexedServerEntry() throws Exception
129     {
130         PresenceNode node = new PresenceNode( SchemaConstants.CN_AT_OID );
131         PresenceEvaluator evaluator = new PresenceEvaluator( node, store, registries );
132         PresenceCursor cursor = new PresenceCursor( store, evaluator );
133 
134         assertEquals( node, evaluator.getExpression() );
135         assertTrue( cursor.isElementReused() );
136 
137         cursor.beforeFirst();
138         assertTrue( cursor.next() );
139         assertTrue( cursor.available() );
140         assertEquals( 5, ( long ) cursor.get().getId() );
141         assertTrue( cursor.next() );
142         assertTrue( cursor.available() );
143         assertEquals( 6, ( long ) cursor.get().getId() );
144         assertTrue( cursor.next() );
145         assertTrue( cursor.available() );
146         assertEquals( 8, ( long ) cursor.get().getId() );
147         assertTrue( cursor.next() );
148         assertTrue( cursor.available() );
149         assertEquals( 9, ( long ) cursor.get().getId() );
150         assertTrue( cursor.next() );
151         assertTrue( cursor.available() );
152         assertEquals( 10, ( long ) cursor.get().getId() );
153         assertTrue( cursor.next() );
154         assertTrue( cursor.available() );
155         assertEquals( 11, ( long ) cursor.get().getId() );
156         assertFalse( cursor.next() );
157         assertFalse( cursor.available() );
158 
159         // test first()
160         cursor.first();
161         assertTrue( cursor.available() );
162         assertEquals( SchemaConstants.CN_AT_OID, cursor.get().getValue() );
163 
164         // test last()
165         cursor.last();
166         assertTrue( cursor.available() );
167         assertEquals( SchemaConstants.CN_AT_OID, cursor.get().getValue() );
168 
169         // test beforeFirst()
170         cursor.beforeFirst();
171         assertFalse( cursor.available() );
172         assertTrue( cursor.next() );
173         assertTrue( cursor.available() );
174         assertEquals( SchemaConstants.CN_AT_OID, cursor.get().getValue() );
175 
176         // test afterLast()
177         cursor.afterLast();
178         assertFalse( cursor.available() );
179         assertTrue( cursor.previous() );
180         assertTrue( cursor.available() );
181         assertEquals( SchemaConstants.CN_AT_OID, cursor.get().getValue() );
182 
183         // test before()
184         ForwardIndexEntry<String,ServerEntry> entry = new ForwardIndexEntry<String,ServerEntry>();
185         entry.setValue( SchemaConstants.CN_AT_OID );
186         cursor.before( entry );
187         assertTrue( cursor.next() );
188         assertTrue( cursor.available() );
189         assertEquals( SchemaConstants.CN_AT_OID, cursor.get().getValue() );
190 
191         // test after()
192         entry = new ForwardIndexEntry<String,ServerEntry>();
193         cursor.after( entry );
194         assertTrue( cursor.previous() );
195         assertTrue( cursor.available() );
196         assertEquals( SchemaConstants.CN_AT_OID, cursor.get().getValue() );
197 
198         node = new PresenceNode( SchemaConstants.OU_AT_OID );
199         evaluator = new PresenceEvaluator( node, store, registries );
200         cursor = new PresenceCursor( store, evaluator );
201 
202         assertTrue( cursor.isElementReused() );
203 
204         cursor.beforeFirst();
205         assertTrue( cursor.next() );
206         assertTrue( cursor.available() );
207         assertEquals( 2, ( long ) cursor.get().getId() );
208         assertTrue( cursor.next() );
209         assertTrue( cursor.available() );
210         assertEquals( 3, ( long ) cursor.get().getId() );
211         assertTrue( cursor.next() );
212         assertTrue( cursor.available() );
213         assertEquals( 4, ( long ) cursor.get().getId() );
214         assertTrue( cursor.next() );
215         assertTrue( cursor.available() );
216         assertEquals( 5, ( long ) cursor.get().getId() );
217         assertTrue( cursor.next() );
218         assertTrue( cursor.available() );
219         assertEquals( 6, ( long ) cursor.get().getId() );
220         assertTrue( cursor.next() );
221         assertTrue( cursor.available() );
222         assertEquals( 7, ( long ) cursor.get().getId() );
223         assertTrue( cursor.next() );
224         assertTrue( cursor.available() );
225         assertEquals( 8, ( long ) cursor.get().getId() );
226         assertTrue( cursor.next() );
227         assertTrue( cursor.available() );
228         assertEquals( 9, ( long ) cursor.get().getId() );
229         assertTrue( cursor.next() );
230         assertTrue( cursor.available() );
231         assertEquals( 11, ( long ) cursor.get().getId() );
232         assertFalse( cursor.next() );
233         assertFalse( cursor.available() );
234 
235         assertFalse( cursor.isClosed() );
236         cursor.close();
237         assertTrue( cursor.isClosed() );
238     }
239 
240 
241     @Test
242     public void testNonIndexedServerEntry() throws Exception
243     {
244         PresenceNode node = new PresenceNode( SchemaConstants.SN_AT_OID );
245         PresenceEvaluator evaluator = new PresenceEvaluator( node, store, registries );
246         PresenceCursor cursor = new PresenceCursor( store, evaluator );
247 
248         assertEquals( node, evaluator.getExpression() );
249         assertTrue( cursor.isElementReused() );
250 
251         cursor.beforeFirst();
252         assertTrue( cursor.next() );
253         assertTrue( cursor.available() );
254         assertEquals( 8, ( long ) cursor.get().getId() );
255         assertTrue( cursor.next() );
256         assertTrue( cursor.available() );
257         assertEquals( 6, ( long ) cursor.get().getId() );
258         assertTrue( cursor.next() );
259         assertTrue( cursor.available() );
260         assertEquals( 5, ( long ) cursor.get().getId() );
261         assertFalse( cursor.next() );
262         assertFalse( cursor.available() );
263 
264         // test first()
265         cursor.first();
266         assertTrue( cursor.available() );
267         assertEquals( SchemaConstants.SN_AT_OID, cursor.get().getValue() );
268 
269         // test last()
270         cursor.last();
271         assertTrue( cursor.available() );
272         assertEquals( SchemaConstants.SN_AT_OID, cursor.get().getValue() );
273 
274         // test beforeFirst()
275         cursor.beforeFirst();
276         assertFalse( cursor.available() );
277         assertTrue( cursor.next() );
278         assertTrue( cursor.available() );
279         assertEquals( SchemaConstants.SN_AT_OID, cursor.get().getValue() );
280 
281         // test afterLast()
282         cursor.afterLast();
283         assertFalse( cursor.available() );
284         assertTrue( cursor.previous() );
285         assertTrue( cursor.available() );
286         assertEquals( SchemaConstants.SN_AT_OID, cursor.get().getValue() );
287         assertEquals( 5, (long) cursor.get().getId() );
288 
289         // keep testing previous
290         assertTrue( cursor.previous() );
291         assertTrue( cursor.available() );
292         assertEquals( SchemaConstants.SN_AT_OID, cursor.get().getValue() );
293         assertEquals( 6, (long) cursor.get().getId() );
294 
295         assertTrue( cursor.previous() );
296         assertTrue( cursor.available() );
297         assertEquals( SchemaConstants.SN_AT_OID, cursor.get().getValue() );
298         assertEquals( 8, (long) cursor.get().getId() );
299 
300         assertFalse( cursor.previous() );
301         assertFalse( cursor.available() );
302 
303         // ----------- organizationName attribute
304 
305         node = new PresenceNode( SchemaConstants.O_AT_OID );
306         evaluator = new PresenceEvaluator( node, store, registries );
307         cursor = new PresenceCursor( store, evaluator );
308 
309         assertTrue( cursor.isElementReused() );
310 
311         cursor.beforeFirst();
312         assertTrue( cursor.next() );
313         assertTrue( cursor.available() );
314         assertEquals( 1, ( long ) cursor.get().getId() );
315         assertFalse( cursor.next() );
316         assertFalse( cursor.available() );
317 
318         assertFalse( cursor.isClosed() );
319         cursor.close();
320         assertTrue( cursor.isClosed() );
321     }
322 
323 
324     @Test
325     public void testEvaluatorIndexed() throws Exception
326     {
327         PresenceNode node = new PresenceNode( SchemaConstants.CN_AT_OID );
328         PresenceEvaluator evaluator = new PresenceEvaluator( node, store, registries );
329         ForwardIndexEntry<String,ServerEntry> entry = new ForwardIndexEntry<String,ServerEntry>();
330         entry.setValue( SchemaConstants.CN_AT_OID );
331         entry.setId( ( long ) 3 );
332         assertFalse( evaluator.evaluate( entry ) );
333         entry = new ForwardIndexEntry<String,ServerEntry>();
334         entry.setValue( SchemaConstants.CN_AT_OID );
335         entry.setId( ( long ) 5 );
336         assertTrue( evaluator.evaluate( entry ) );
337     }
338 
339 
340     @Test
341     public void testEvaluatorNotIndexed() throws Exception
342     {
343         PresenceNode node = new PresenceNode( SchemaConstants.NAME_AT_OID );
344         PresenceEvaluator evaluator = new PresenceEvaluator( node, store, registries );
345         ForwardIndexEntry<String,ServerEntry> entry = new ForwardIndexEntry<String,ServerEntry>();
346         entry.setValue( SchemaConstants.NAME_AT_OID );
347         entry.setId( ( long ) 3 );
348         assertTrue( evaluator.evaluate( entry ) );
349         entry = new ForwardIndexEntry<String,ServerEntry>();
350         entry.setValue( SchemaConstants.NAME_AT_OID );
351         entry.setId( ( long ) 5 );
352         assertTrue( evaluator.evaluate( entry ) );
353 
354         node = new PresenceNode( SchemaConstants.SEARCHGUIDE_AT_OID );
355         evaluator = new PresenceEvaluator( node, store, registries );
356         entry = new ForwardIndexEntry<String,ServerEntry>();
357         entry.setValue( SchemaConstants.SEARCHGUIDE_AT_OID );
358         entry.setId( ( long ) 3 );
359         assertFalse( evaluator.evaluate( entry ) );
360         entry = new ForwardIndexEntry<String,ServerEntry>();
361         entry.setValue( SchemaConstants.SEARCHGUIDE_AT_OID );
362         entry.setId( ( long ) 5 );
363         entry.setObject( store.lookup( ( long ) 5 ));
364         assertFalse( evaluator.evaluate( entry ) );
365 
366         node = new PresenceNode( SchemaConstants.ST_AT_OID );
367         evaluator = new PresenceEvaluator( node, store, registries );
368         entry = new ForwardIndexEntry<String,ServerEntry>();
369         entry.setValue( SchemaConstants.ST_AT_OID );
370         entry.setId( ( long ) 3 );
371         assertFalse( evaluator.evaluate( entry ) );
372         entry = new ForwardIndexEntry<String,ServerEntry>();
373         entry.setValue( SchemaConstants.ST_AT_OID );
374         entry.setId( ( long ) 5 );
375         entry.setObject( store.lookup( ( long ) 5 ));
376         assertFalse( evaluator.evaluate( entry ) );
377     }
378 
379 
380     @Test ( expected = InvalidCursorPositionException.class )
381     public void testInvalidCursorPositionException() throws Exception
382     {
383         PresenceNode node = new PresenceNode( SchemaConstants.SN_AT_OID );
384         PresenceEvaluator evaluator = new PresenceEvaluator( node, store, registries );
385         PresenceCursor cursor = new PresenceCursor( store, evaluator );
386         cursor.get();
387     }
388 
389 
390     @Test ( expected = InvalidCursorPositionException.class )
391     public void testInvalidCursorPositionException2() throws Exception
392     {
393         PresenceNode node = new PresenceNode( SchemaConstants.CN_AT_OID );
394         PresenceEvaluator evaluator = new PresenceEvaluator( node, store, registries );
395         PresenceCursor cursor = new PresenceCursor( store, evaluator );
396         cursor.get();
397     }
398 
399 
400     @Test ( expected = UnsupportedOperationException.class )
401     public void testUnsupportBeforeWithoutIndex() throws Exception
402     {
403         PresenceNode node = new PresenceNode( SchemaConstants.SN_AT_OID );
404         PresenceEvaluator evaluator = new PresenceEvaluator( node, store, registries );
405         PresenceCursor cursor = new PresenceCursor( store, evaluator );
406 
407         // test before()
408         ForwardIndexEntry<String,ServerEntry> entry = new ForwardIndexEntry<String,ServerEntry>();
409         entry.setValue( SchemaConstants.SN_AT_OID );
410         cursor.before( entry );
411     }
412 
413 
414     @Test ( expected = UnsupportedOperationException.class )
415     public void testUnsupportAfterWithoutIndex() throws Exception
416     {
417         PresenceNode node = new PresenceNode( SchemaConstants.SN_AT_OID );
418         PresenceEvaluator evaluator = new PresenceEvaluator( node, store, registries );
419         PresenceCursor cursor = new PresenceCursor( store, evaluator );
420 
421         // test before()
422         ForwardIndexEntry<String,ServerEntry> entry = new ForwardIndexEntry<String,ServerEntry>();
423         entry.setValue( SchemaConstants.SN_AT_OID );
424         cursor.after( entry );
425     }
426 }