1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.server.core.partition.impl.btree.jdbm;
21
22
23 import org.junit.Before;
24 import org.junit.Test;
25 import org.junit.After;
26 import static org.junit.Assert.assertEquals;
27 import static org.junit.Assert.assertFalse;
28 import static org.junit.Assert.assertNull;
29 import static org.junit.Assert.assertTrue;
30 import static org.junit.Assert.fail;
31
32 import org.apache.commons.io.FileUtils;
33 import org.apache.directory.server.schema.bootstrap.*;
34 import org.apache.directory.server.schema.registries.*;
35 import org.apache.directory.server.schema.SerializableComparator;
36 import org.apache.directory.server.xdbm.Index;
37 import org.apache.directory.server.xdbm.IndexEntry;
38 import org.apache.directory.server.core.cursor.Cursor;
39 import org.apache.directory.server.core.entry.ServerEntry;
40 import org.apache.directory.shared.ldap.constants.SchemaConstants;
41
42 import java.util.Set;
43 import java.util.HashSet;
44 import java.io.File;
45 import java.io.IOException;
46
47
48
49
50
51
52
53
54 public class JdbmIndexTest
55 {
56 AttributeTypeRegistry registry;
57 File dbFileDir;
58 Index<String,ServerEntry> idx;
59
60
61 @Before
62 public void setup() throws Exception
63 {
64 BootstrapSchemaLoader loader = new BootstrapSchemaLoader();
65 OidRegistry oidRegistry = new DefaultOidRegistry();
66 Registries registries = new DefaultRegistries( "bootstrap", loader, oidRegistry );
67 SerializableComparator.setRegistry( registries.getComparatorRegistry() );
68
69
70 Set<Schema> bootstrapSchemas = new HashSet<Schema>();
71 bootstrapSchemas.add( new ApachemetaSchema() );
72 bootstrapSchemas.add( new ApacheSchema() );
73 bootstrapSchemas.add( new CoreSchema() );
74 bootstrapSchemas.add( new SystemSchema() );
75 loader.loadWithDependencies( bootstrapSchemas, registries );
76 this.registry = registries.getAttributeTypeRegistry();
77
78 if ( dbFileDir != null )
79 {
80 dbFileDir.delete();
81 }
82
83 File tmpIndexFile = File.createTempFile( JdbmIndexTest.class.getSimpleName(), "db" );
84 tmpIndexFile.deleteOnExit();
85 dbFileDir = new File( tmpIndexFile.getParentFile(),
86 JdbmIndexTest.class.getSimpleName() );
87
88 dbFileDir.mkdirs();
89 }
90
91
92 @After
93 public void teardown() throws Exception
94 {
95 registry = null;
96 destroyIndex();
97
98 if ( ( dbFileDir != null ) && dbFileDir.exists() )
99 {
100 FileUtils.deleteDirectory( dbFileDir );
101 }
102 }
103
104
105 void destroyIndex() throws Exception
106 {
107 if ( idx != null )
108 {
109 idx.sync();
110 idx.close();
111 File file = new File( idx.getWkDirPath(), idx.getAttribute().getName() + ".db" );
112 file.delete();
113 }
114
115 idx = null;
116 }
117
118
119 void initIndex() throws Exception
120 {
121 initIndex( new JdbmIndex<String,ServerEntry>() );
122 }
123
124
125 void initIndex( JdbmIndex<String,ServerEntry> jdbmIdx ) throws Exception
126 {
127 if ( jdbmIdx == null )
128 {
129 jdbmIdx = new JdbmIndex<String,ServerEntry>();
130 }
131
132 jdbmIdx.init( registry.lookup( SchemaConstants.OU_AT ), dbFileDir );
133 this.idx = jdbmIdx;
134 }
135
136
137
138
139
140
141
142 @Test
143 public void testAttributeId() throws Exception
144 {
145
146 JdbmIndex jdbmIndex = new JdbmIndex();
147 jdbmIndex.setAttributeId( "foo" );
148 assertEquals( "foo", jdbmIndex.getAttributeId() );
149
150 jdbmIndex = new JdbmIndex( "bar" );
151 assertEquals( "bar", jdbmIndex.getAttributeId() );
152
153
154 initIndex();
155 try
156 {
157 idx.setAttributeId( "foo" );
158 fail( "Should not be able to set attributeId after initialization." );
159 }
160 catch ( Exception e )
161 {
162 }
163 assertEquals( "ou", idx.getAttributeId() );
164
165 destroyIndex();
166 initIndex( new JdbmIndex<String,ServerEntry>( "foo" ) );
167 assertEquals( "foo", idx.getAttributeId() );
168 }
169
170
171 @Test
172 public void testCacheSize() throws Exception
173 {
174
175 JdbmIndex jdbmIndex = new JdbmIndex();
176 jdbmIndex.setCacheSize( 337 );
177 assertEquals( 337, jdbmIndex.getCacheSize() );
178
179
180 initIndex();
181 try
182 {
183 idx.setCacheSize( 30 );
184 fail( "Should not be able to set cacheSize after initialization." );
185 }
186 catch ( Exception e )
187 {
188 }
189 assertEquals( Index.DEFAULT_INDEX_CACHE_SIZE, idx.getCacheSize() );
190 }
191
192
193 @Test
194 public void testWkDirPath() throws Exception
195 {
196
197 JdbmIndex<String,ServerEntry> jdbmIndex = new JdbmIndex<String,ServerEntry>();
198 jdbmIndex.setWkDirPath( new File( dbFileDir, "foo" ) );
199 assertEquals( "foo", jdbmIndex.getWkDirPath().getName() );
200
201
202 initIndex();
203 try
204 {
205 idx.setWkDirPath( new File( dbFileDir, "foo" ) );
206 fail( "Should not be able to set wkDirPath after initialization." );
207 }
208 catch ( Exception e )
209 {
210 }
211 assertEquals( dbFileDir, idx.getWkDirPath() );
212
213 destroyIndex();
214 jdbmIndex = new JdbmIndex<String,ServerEntry>();
215 File wkdir = new File( dbFileDir, "foo" );
216 wkdir.mkdirs();
217 jdbmIndex.setWkDirPath( wkdir );
218 initIndex( jdbmIndex );
219 assertEquals( wkdir, idx.getWkDirPath() );
220 }
221
222
223 @Test
224 public void testNumDupLimit() throws Exception
225 {
226
227 JdbmIndex jdbmIndex = new JdbmIndex();
228 jdbmIndex.setNumDupLimit( 337 );
229 assertEquals( 337, jdbmIndex.getNumDupLimit() );
230
231
232 initIndex();
233 try
234 {
235 ( ( JdbmIndex ) idx).setNumDupLimit( 30 );
236 fail( "Should not be able to set numDupLimit after initialization." );
237 }
238 catch ( Exception e )
239 {
240 }
241 assertEquals( JdbmIndex.DEFAULT_DUPLICATE_LIMIT, ( ( JdbmIndex ) idx).getNumDupLimit() );
242 }
243
244
245 @Test
246 public void testGetAttribute() throws Exception
247 {
248
249 JdbmIndex jdbmIndex = new JdbmIndex();
250 assertNull( jdbmIndex.getAttribute() );
251
252 initIndex();
253 assertEquals( registry.lookup( "ou" ), idx.getAttribute() );
254 }
255
256
257 @Test
258 public void testIsCountExact() throws Exception
259 {
260 assertFalse( new JdbmIndex().isCountExact() );
261 }
262
263
264
265
266
267
268
269 @Test
270 public void testCount() throws Exception
271 {
272 initIndex();
273 assertEquals( 0, idx.count() );
274
275 idx.add( "foo", 1234L );
276 assertEquals( 1, idx.count() );
277
278 idx.add( "foo", 333L );
279 assertEquals( 2, idx.count() );
280
281 idx.add( "bar", 555L );
282 assertEquals( 3, idx.count() );
283 }
284
285
286 @Test
287 public void testCountOneArg() throws Exception
288 {
289 initIndex();
290 assertEquals( 0, idx.count( "foo" ) );
291
292 idx.add( "bar", 1234L );
293 assertEquals( 0, idx.count( "foo" ) );
294
295 idx.add( "foo", 1234L );
296 assertEquals( 1, idx.count( "foo" ) );
297
298 idx.add( "foo", 333L );
299 assertEquals( 2, idx.count( "foo" ) );
300 }
301
302
303 @Test
304 public void testGreaterThanCount() throws Exception
305 {
306 initIndex();
307 assertEquals( 0, idx.greaterThanCount( "a" ) );
308
309 for ( char ch = 'a'; ch <= 'z'; ch++ )
310 {
311 idx.add( String.valueOf( ch ), ( long ) ch );
312 }
313 assertEquals( 26, idx.greaterThanCount( "a" ) );
314 }
315
316
317 @Test
318 public void testLessThanCount() throws Exception
319 {
320 initIndex();
321 assertEquals( 0, idx.lessThanCount( "z" ) );
322
323 for ( char ch = 'a'; ch <= 'z'; ch++ )
324 {
325 idx.add( String.valueOf( ch ), ( long ) ch );
326 }
327 assertEquals( 26, idx.lessThanCount( "z" ) );
328 }
329
330
331
332
333
334
335
336 @Test
337 public void testLookups() throws Exception
338 {
339 initIndex();
340 assertNull( idx.forwardLookup( "foo" ) );
341 assertNull( idx.forwardLookup( "bar" ) );
342 assertNull( idx.reverseLookup( 0L ) );
343 assertFalse( idx.forwardGreaterOrEq( "foo", 0L ) );
344 assertFalse( idx.forwardGreaterOrEq( "foo", -24L ) );
345 assertFalse( idx.forwardGreaterOrEq( "foo", 24L ) );
346 assertFalse( idx.forwardLessOrEq( "foo", 0L ) );
347 assertFalse( idx.forwardLessOrEq( "foo", 24L ) );
348 assertFalse( idx.forwardLessOrEq( "foo", -24L ) );
349
350 idx.add( "foo", 0L );
351 assertEquals( 0L, ( long ) idx.forwardLookup( "foo" ) );
352 assertEquals( "foo", idx.reverseLookup( 0L ) );
353 assertTrue( idx.forward( "foo", 0L ) );
354 assertTrue( idx.forwardGreaterOrEq( "foo", 0L ) );
355 assertTrue( idx.forwardGreaterOrEq( "foo", -1L ) );
356 assertFalse( idx.forwardGreaterOrEq( "foo", 1L ) );
357 assertTrue( idx.forwardLessOrEq( "foo", 0L ) );
358 assertTrue( idx.forwardLessOrEq( "foo", 1L ) );
359 assertFalse( idx.forwardLessOrEq( "foo", -1L ) );
360
361 idx.add( "foo", 1L );
362 assertEquals( 0L, ( long ) idx.forwardLookup( "foo" ) );
363 assertEquals( "foo", idx.reverseLookup( 0L ) );
364 assertEquals( "foo", idx.reverseLookup( 1L ) );
365 assertTrue( idx.forward( "foo", 0L ) );
366 assertTrue( idx.forward( "foo", 1L ) );
367 assertTrue( idx.forwardGreaterOrEq( "foo", 0L ) );
368 assertTrue( idx.forwardGreaterOrEq( "foo", 1L ) );
369 assertTrue( idx.forwardGreaterOrEq( "foo", -1L ) );
370 assertFalse( idx.forwardGreaterOrEq( "foo", 2L ) );
371 assertTrue( idx.forwardLessOrEq( "foo", 0L ) );
372 assertTrue( idx.forwardLessOrEq( "foo", 1L ) );
373 assertTrue( idx.forwardLessOrEq( "foo", 2L ) );
374 assertFalse( idx.forwardLessOrEq( "foo", -1L ) );
375
376 idx.add( "bar", 0L );
377 assertEquals( 0L, ( long ) idx.forwardLookup( "bar" ) );
378 assertEquals( "bar", idx.reverseLookup( 0L ) );
379 assertTrue( idx.forward( "bar", 0L ) );
380 assertTrue( idx.forward( "foo", 0L ) );
381 assertTrue( idx.forward( "foo", 1L ) );
382 assertTrue( idx.forwardGreaterOrEq( "bar", 0L ) );
383 assertTrue( idx.forwardGreaterOrEq( "foo", 0L ) );
384 assertTrue( idx.forwardGreaterOrEq( "foo", 1L ) );
385 assertTrue( idx.forwardGreaterOrEq( "foo", -1L ) );
386 assertFalse( idx.forwardGreaterOrEq( "foo", 2L ) );
387 assertFalse( idx.forwardGreaterOrEq( "bar", 1L ) );
388 assertTrue( idx.forwardLessOrEq( "bar", 0L ) );
389 assertTrue( idx.forwardLessOrEq( "foo", 0L ) );
390 assertTrue( idx.forwardLessOrEq( "foo", 1L ) );
391 assertTrue( idx.forwardLessOrEq( "foo", 2L ) );
392 assertFalse( idx.forwardLessOrEq( "foo", -1L ) );
393 assertFalse( idx.forwardLessOrEq( "bar", -1L ) );
394 }
395
396
397 @Test
398 public void testAddDropById() throws Exception
399 {
400 initIndex();
401 assertNull( idx.forwardLookup( "foo" ) );
402 assertNull( idx.forwardLookup( "bar" ) );
403 assertNull( idx.reverseLookup( 0L ) );
404 assertNull( idx.reverseLookup( 1L ) );
405
406
407 idx.add( "foo", 0L );
408 assertEquals( 0L, ( long ) idx.forwardLookup( "foo" ) );
409 assertEquals( "foo", idx.reverseLookup( 0L ) );
410
411 idx.drop( 0L );
412 assertNull( idx.forwardLookup( "foo" ) );
413 assertNull( idx.reverseLookup( 0L ) );
414
415
416 idx.add( "foo", 0L );
417 idx.add( "foo", 1L );
418 idx.add( "bar", 0L );
419 assertEquals( 0L, ( long ) idx.forwardLookup( "foo" ) );
420 assertEquals( 0L, ( long ) idx.forwardLookup( "bar" ) );
421 assertEquals( "bar", idx.reverseLookup( 0L ) );
422 assertEquals( "foo", idx.reverseLookup( 1L ) );
423
424 idx.drop( 0L );
425 assertEquals( "foo", idx.reverseLookup( 1L ) );
426 assertFalse( idx.forward( "bar", 0L ) );
427 assertFalse( idx.forward( "foo", 0L ) );
428
429 idx.drop( 1L );
430 assertNull( idx.forwardLookup( "foo" ) );
431 assertNull( idx.forwardLookup( "bar" ) );
432 assertNull( idx.reverseLookup( 0L ) );
433 assertNull( idx.reverseLookup( 1L ) );
434 assertEquals( 0, idx.count() );
435 }
436
437
438 @Test
439 public void testAddDropOneByOne() throws Exception
440 {
441 initIndex();
442 assertNull( idx.forwardLookup( "foo" ) );
443 assertNull( idx.forwardLookup( "bar" ) );
444 assertNull( idx.reverseLookup( 0L ) );
445 assertNull( idx.reverseLookup( 1L ) );
446
447
448 idx.add( "foo", 0L );
449 assertEquals( 0L, ( long ) idx.forwardLookup( "foo" ) );
450 assertEquals( "foo", idx.reverseLookup( 0L ) );
451
452 idx.drop( "foo", 0L );
453 assertNull( idx.forwardLookup( "foo" ) );
454 assertNull( idx.reverseLookup( 0L ) );
455
456
457 idx.add( "foo", 0L );
458 idx.add( "foo", 1L );
459 idx.add( "bar", 0L );
460 assertEquals( 0L, ( long ) idx.forwardLookup( "foo" ) );
461 assertEquals( 0L, ( long ) idx.forwardLookup( "bar" ) );
462 assertEquals( "bar", idx.reverseLookup( 0L ) );
463 assertEquals( "foo", idx.reverseLookup( 1L ) );
464
465 idx.drop( "bar", 0L );
466 assertEquals( 0L, ( long ) idx.forwardLookup( "foo" ) );
467 assertEquals( "foo", idx.reverseLookup( 0L ) );
468 assertEquals( "foo", idx.reverseLookup( 1L ) );
469 assertFalse( idx.forward( "bar", 0L ) );
470
471 idx.drop( "foo", 0L );
472 assertEquals( 1L, ( long ) idx.forwardLookup( "foo" ) );
473 assertEquals( "foo", idx.reverseLookup( 1L ) );
474 assertFalse( idx.forward( "foo", 0L ) );
475
476 idx.drop( "foo", 1L );
477 assertNull( idx.forwardLookup( "foo" ) );
478 assertNull( idx.forwardLookup( "bar" ) );
479 assertNull( idx.reverseLookup( 0L ) );
480 assertNull( idx.reverseLookup( 1L ) );
481 assertEquals( 0, idx.count() );
482 }
483
484
485
486
487
488
489
490 @Test
491 public void testCursors() throws Exception
492 {
493 initIndex();
494 assertEquals( 0, idx.count() );
495
496 idx.add( "foo", 1234L );
497 assertEquals( 1, idx.count() );
498
499 idx.add( "foo", 333L );
500 assertEquals( 2, idx.count() );
501
502 idx.add( "bar", 555L );
503 assertEquals( 3, idx.count() );
504
505
506 Cursor<IndexEntry<String,ServerEntry>> cursor = idx.forwardCursor();
507 cursor.beforeFirst();
508
509 cursor.next();
510 IndexEntry<String,ServerEntry> e1 = cursor.get();
511 assertEquals( 555L, ( long ) e1.getId() );
512 assertEquals( "bar", e1.getValue() );
513
514 cursor.next();
515 IndexEntry<String,ServerEntry> e2 = cursor.get();
516 assertEquals( 333L, ( long ) e2.getId() );
517 assertEquals( "foo", e2.getValue() );
518
519 cursor.next();
520 IndexEntry<String,ServerEntry> e3 = cursor.get();
521 assertEquals( 1234L, ( long ) e3.getId() );
522 assertEquals( "foo", e3.getValue() );
523
524
525 cursor = idx.reverseCursor();
526 cursor.beforeFirst();
527
528 cursor.next();
529 e1 = cursor.get();
530 assertEquals( 333L, ( long ) e1.getId() );
531 assertEquals( "foo", e1.getValue() );
532
533 cursor.next();
534 e2 = cursor.get();
535 assertEquals( 555L, ( long ) e2.getId() );
536 assertEquals( "bar", e2.getValue() );
537
538 cursor.next();
539 e3 = cursor.get();
540 assertEquals( 1234L, ( long ) e3.getId() );
541 assertEquals( "foo", e3.getValue() );
542 }
543
544
545 @Test
546 public void testNoEqualityMatching() throws Exception
547 {
548 JdbmIndex jdbmIndex = new JdbmIndex();
549
550 try
551 {
552 jdbmIndex.init( new NoEqMatchAttribute(), dbFileDir );
553 fail( "should not get here" );
554 }
555 catch( IOException e )
556 {
557 }
558 }
559
560
561
562
563
564
565
566 @Test
567 public void testSingleValuedAttribute() throws Exception
568 {
569 JdbmIndex jdbmIndex = new JdbmIndex();
570 jdbmIndex.init( registry.lookup( SchemaConstants.CREATORS_NAME_AT ), dbFileDir );
571 }
572 }