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  package org.apache.directory.server.core.partition.impl.btree.jdbm;
20  
21  
22  import org.slf4j.Logger;
23  import org.slf4j.LoggerFactory;
24  import org.apache.directory.server.xdbm.Tuple;
25  import org.apache.directory.server.core.cursor.Cursor;
26  import org.apache.directory.server.core.cursor.InvalidCursorPositionException;
27  import org.apache.directory.server.schema.SerializableComparator;
28  import org.apache.directory.server.schema.registries.ComparatorRegistry;
29  import org.apache.directory.shared.ldap.schema.syntax.ComparatorDescription;
30  import org.junit.Before;
31  import org.junit.After;
32  import org.junit.Test;
33  
34  import static org.junit.Assert.*;
35  
36  import java.io.File;
37  import java.util.Comparator;
38  import java.util.Iterator;
39  
40  import jdbm.RecordManager;
41  import jdbm.helper.IntegerSerializer;
42  import jdbm.recman.BaseRecordManager;
43  
44  import javax.naming.NamingException;
45  
46  
47  /**
48   * Tests the DupsContainerCursor.
49   *
50   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
51   * @version $Rev$, $Date$
52   */
53  public class DupsContainerCursorTest
54  {
55      private static final Logger LOG = LoggerFactory.getLogger( NoDupsCursorTest.class.getSimpleName() );
56      private static final String TEST_OUTPUT_PATH = "test.output.path";
57  
58      transient JdbmTable<Integer,Integer> table;
59      transient File dbFile;
60      transient RecordManager recman;
61      private static final int SIZE = 15;
62  
63  
64      @Before
65      public void createTable() throws Exception
66      {
67          File tmpDir = null;
68          
69          if ( System.getProperty( TEST_OUTPUT_PATH, null ) != null )
70          {
71              tmpDir = new File( System.getProperty( TEST_OUTPUT_PATH ) );
72              tmpDir.deleteOnExit();
73          }
74  
75          dbFile = File.createTempFile( getClass().getSimpleName(), "db", tmpDir );
76          dbFile.deleteOnExit();
77          recman = new BaseRecordManager( dbFile.getAbsolutePath() );
78  
79          // gosh this is a terrible use of a global static variable
80          SerializableComparator.setRegistry( new MockComparatorRegistry() );
81  
82          table = new JdbmTable<Integer,Integer>( "test", SIZE, recman,
83                  new SerializableComparator<Integer>( "" ),
84                  new SerializableComparator<Integer>( "" ),
85                  null, new IntegerSerializer() );
86          LOG.debug( "Created new table and populated it with data" );
87  
88      }
89  
90  
91      @After
92      public void destroyTable() throws Exception
93      {
94          table.close();
95          table = null;
96          recman.close();
97          recman = null;
98          String fileToDelete = dbFile.getAbsolutePath();
99          new File( fileToDelete ).delete();
100         new File( fileToDelete + ".db" ).delete();
101         new File( fileToDelete + ".lg" ).delete();
102         dbFile = null;
103     }
104 
105 
106     @Test( expected=IllegalStateException.class )
107     public void testUsingNoDuplicates() throws Exception
108     {
109         recman = new BaseRecordManager( dbFile.getAbsolutePath() );
110 
111         // gosh this is a terrible use of a global static variable
112         SerializableComparator.setRegistry( new MockComparatorRegistry() );
113         table = new JdbmTable<Integer,Integer>( "test", recman, new SerializableComparator<Integer>( "" ), null, null );
114 
115         Cursor<Tuple<Integer,DupsContainer<Integer>>> cursor =
116             new DupsContainerCursor<Integer,Integer>( table );
117         assertNotNull( cursor );
118     }
119 
120 
121     @Test( expected=InvalidCursorPositionException.class )
122     public void testEmptyTable() throws Exception
123     {
124         Cursor<Tuple<Integer,DupsContainer<Integer>>> cursor =
125             new DupsContainerCursor<Integer,Integer>( table );
126         assertNotNull( cursor );
127 
128         assertFalse( cursor.available() );
129         assertFalse( cursor.isClosed() );
130         assertTrue( cursor.isElementReused() );
131 
132         cursor = new DupsContainerCursor<Integer,Integer>( table );
133         assertFalse( cursor.previous() );
134 
135         cursor = new DupsContainerCursor<Integer,Integer>( table );
136         assertFalse( cursor.next() );
137 
138         cursor.after( new Tuple<Integer,DupsContainer<Integer>>( 7, null ) );
139         cursor.get();
140     }
141 
142 
143     @Test
144     public void testOnTableWithSingleEntry() throws Exception
145     {
146         table.put( 1, 1 );
147         Cursor<Tuple<Integer,DupsContainer<Integer>>> cursor =
148             new DupsContainerCursor<Integer,Integer>( table );
149         assertTrue( cursor.first() );
150 
151         Tuple<Integer,DupsContainer<Integer>> tuple = cursor.get();
152         assertTrue( tuple.getKey().equals( 1 ) );
153         assertEquals( 1, ( int ) tuple.getValue().getAvlTree().getFirst().getKey() );
154 
155         cursor.beforeFirst();
156         assertFalse( cursor.previous() );
157         assertTrue( cursor.next() );
158     }
159 
160 
161     @Test
162     public void testOnTableWithMultipleEntries() throws Exception
163     {
164         for( int i=1; i < 10; i++ )
165         {
166             table.put( i, i );
167         }
168 
169         Cursor<Tuple<Integer,DupsContainer<Integer>>> cursor =
170             new DupsContainerCursor<Integer,Integer>( table );
171 
172         cursor.after( new Tuple<Integer,DupsContainer<Integer>>( 2, null ) );
173         assertTrue( cursor.next() );
174 
175         Tuple<Integer,DupsContainer<Integer>> tuple = cursor.get();
176         assertTrue( tuple.getKey().equals( 3 ) );
177         assertEquals( 3, ( int ) tuple.getValue().getAvlTree().getFirst().getKey() );
178 
179         cursor.before( new Tuple<Integer,DupsContainer<Integer>>( 7, null ) );
180         cursor.next();
181         tuple = cursor.get();
182         assertTrue( tuple.getKey().equals( 7 ) );
183         assertEquals( 7, ( int ) tuple.getValue().getAvlTree().getFirst().getKey() );
184 
185         cursor.last();
186         cursor.next();
187         assertFalse( cursor.available() );
188        /* tuple = cursor.get();
189         assertTrue( tuple.getKey().equals( 9 ) );
190         assertEquals( 9, ( int ) tuple.getValue().getAvlTree().getFirst().getKey() ); */
191         
192         cursor.beforeFirst();
193         cursor.next();
194         tuple = cursor.get();
195         assertTrue( tuple.getKey().equals( 1 ) );
196         assertEquals( 1, ( int ) tuple.getValue().getAvlTree().getFirst().getKey() );
197 
198         cursor.afterLast();
199         assertFalse( cursor.next() );
200 
201         cursor.beforeFirst();
202         assertFalse( cursor.previous() );
203 
204         // just to clear the jdbmTuple value so that line 127 inside after(tuple) method
205         // can be executed as part of the below after(tuple) call
206         cursor.before(new Tuple<Integer,DupsContainer<Integer>>( 1, null ) );
207         cursor.after( new Tuple<Integer,DupsContainer<Integer>>( 0, null ) ); // this positions on tuple with key 1
208 
209         cursor.next(); // this moves onto tuple with key 2
210         tuple = cursor.get();
211         assertTrue( tuple.getKey().equals( 2 ) );
212         assertEquals( 2, ( int ) tuple.getValue().getAvlTree().getFirst().getKey() );
213     }
214 
215 
216     @Test
217     public void testMiscellaneous() throws Exception
218     {
219     }
220 
221 
222     private class MockComparatorRegistry implements ComparatorRegistry
223     {
224         private Comparator<Integer> comparator = new Comparator<Integer>()
225         {
226             public int compare( Integer i1, Integer i2 )
227             {
228                 return i1.compareTo( i2 );
229             }
230         };
231 
232         public String getSchemaName( String oid ) throws NamingException
233         {
234             return null;
235         }
236 
237 
238         public void register( ComparatorDescription description, Comparator comparator ) throws NamingException
239         {
240         }
241 
242 
243         public Comparator lookup( String oid ) throws NamingException
244         {
245             return comparator;
246         }
247 
248 
249         public boolean hasComparator( String oid )
250         {
251             return true;
252         }
253 
254 
255         public Iterator<String> oidIterator()
256         {
257             return null;
258         }
259 
260 
261         public Iterator<ComparatorDescription> comparatorDescriptionIterator()
262         {
263             return null;
264         }
265 
266 
267         public void unregister( String oid ) throws NamingException
268         {
269         }
270 
271 
272         public void unregisterSchemaElements( String schemaName )
273         {
274         }
275 
276 
277         public void renameSchema( String originalSchemaName, String newSchemaName )
278         {
279         }
280     }
281 }