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 static junit.framework.Assert.assertEquals;
23  import static junit.framework.Assert.assertFalse;
24  import static junit.framework.Assert.assertTrue;
25  
26  import java.io.File;
27  import java.util.Comparator;
28  import java.util.Iterator;
29  
30  import javax.naming.NamingException;
31  
32  import jdbm.RecordManager;
33  import jdbm.btree.BTree;
34  import jdbm.helper.IntegerSerializer;
35  import jdbm.recman.BaseRecordManager;
36  
37  import org.apache.directory.server.core.cursor.InvalidCursorPositionException;
38  import org.apache.directory.server.schema.SerializableComparator;
39  import org.apache.directory.server.schema.registries.ComparatorRegistry;
40  import org.apache.directory.server.xdbm.Tuple;
41  import org.apache.directory.shared.ldap.schema.syntax.ComparatorDescription;
42  import org.junit.After;
43  import org.junit.Before;
44  import org.junit.Test;
45  
46  
47  /**
48   * Test case for KeyTupleBTreeCursor.
49   *
50   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
51   * @version $Rev$, $Date$
52   */
53  public class KeyTupleBTreeCursorTest
54  {
55  
56      JdbmTable<Integer,Integer> table;
57      Comparator<Integer> comparator;
58      KeyTupleBTreeCursor<Integer, Integer> cursor;
59      File dbFile;
60      RecordManager recman;
61      
62      private static final Integer KEY = 1;
63      private static final String TEST_OUTPUT_PATH = "test.output.path";
64      
65      @Before
66      public void createTree() throws Exception
67      {
68        comparator = new Comparator<Integer>() 
69        {
70  
71            public int compare( Integer i1, Integer i2 )
72            {
73                return i1.compareTo( i2 );
74            }
75          
76          };
77  
78          File tmpDir = null;
79          if ( System.getProperty( TEST_OUTPUT_PATH, null ) != null )
80          {
81              tmpDir = new File( System.getProperty( TEST_OUTPUT_PATH ) );
82          }
83  
84          dbFile = File.createTempFile( getClass().getSimpleName(), "db", tmpDir );
85          recman = new BaseRecordManager( dbFile.getAbsolutePath() );
86          
87          SerializableComparator.setRegistry( new MockComparatorRegistry() );
88          
89          table = new JdbmTable<Integer,Integer>( "test", 6, recman,
90                  new SerializableComparator<Integer>( "" ),
91                  new SerializableComparator<Integer>( "" ),
92                  new IntegerSerializer(), new IntegerSerializer() );
93  
94          cursor = new KeyTupleBTreeCursor<Integer, Integer>( table.getBTree(), KEY, comparator );
95      }
96      
97      
98      @After 
99      public void destroytable() throws Exception
100     {
101         recman.close();
102         recman = null;
103         dbFile.deleteOnExit();
104 
105         String fileToDelete = dbFile.getAbsolutePath();
106         new File( fileToDelete + ".db" ).delete();
107         new File( fileToDelete + ".lg" ).delete();
108 
109         dbFile = null;
110     }
111     
112 
113     @Test( expected = InvalidCursorPositionException.class )
114     public void testEmptyCursor() throws Exception
115     {
116         assertFalse( cursor.next() );
117         assertFalse( cursor.available() );
118         
119         assertTrue( cursor.isElementReused() );
120         assertFalse( cursor.isClosed() );
121         
122         assertFalse( cursor.first() );
123         assertFalse( cursor.last() );
124         
125         cursor.get(); // should throw InvalidCursorPositionException
126     }
127     
128 
129     @Test
130     public void testNonEmptyCursor() throws Exception
131     {
132         table.put( KEY, 3 );
133         table.put( KEY, 5 );
134         table.put( KEY, 7 );
135         table.put( KEY, 12 );
136         table.put( KEY, 0 );
137         table.put( KEY, 30 );
138         table.put( KEY, 25 );
139        
140         cursor = new KeyTupleBTreeCursor<Integer, Integer>( getDupsContainer(), KEY, comparator );
141    
142         cursor.before( new Tuple<Integer, Integer>( KEY, 3) );
143         assertTrue( cursor.next() );
144         assertEquals( 3, ( int ) cursor.get().getValue() );
145         
146         cursor.after( new Tuple<Integer, Integer>( KEY, 100 ) );
147         assertFalse( cursor.next() );
148         
149         cursor.beforeFirst();
150         cursor.after( new Tuple<Integer, Integer>( KEY, 13 ) );
151         assertTrue( cursor.next() );
152         assertEquals( 25, ( int ) cursor.get().getValue() );
153         
154         cursor.beforeFirst();
155         assertFalse( cursor.previous() );
156         assertTrue( cursor.next() );
157         assertEquals( 0, ( int ) cursor.get().getValue() );
158         
159         cursor.afterLast();
160         assertFalse( cursor.next() );
161         
162         assertTrue( cursor.first() );
163         assertTrue( cursor.available() );
164         assertEquals( 0, ( int ) cursor.get().getValue() );
165         
166         assertTrue( cursor.last() );
167         assertTrue( cursor.available() );
168         assertEquals( 30, ( int ) cursor.get().getValue() );
169         
170         assertTrue( cursor.previous() );
171         assertEquals( 25, ( int ) cursor.get().getValue() );
172     
173         assertTrue( cursor.next() );
174         assertEquals( 30, ( int ) cursor.get().getValue() ); 
175     
176     }
177 
178     private BTree getDupsContainer() throws Exception
179     {
180         BTree tree = table.getBTree();
181         
182         DupsContainer<Integer> values = table.getDupsContainer( ( byte[] ) tree.find( KEY ) );
183         
184         return table.getBTree( values.getBTreeRedirect() );   
185     }
186     
187     private class MockComparatorRegistry implements ComparatorRegistry
188     {
189         private Comparator<Integer> comparator = new Comparator<Integer>()
190         {
191             public int compare( Integer i1, Integer i2 )
192             {
193                 return i1.compareTo( i2 );
194             }
195         };
196 
197         public String getSchemaName( String oid ) throws NamingException
198         {
199             return null;
200         }
201 
202 
203         public void register( ComparatorDescription description, Comparator comparator ) throws NamingException
204         {
205         }
206 
207 
208         public Comparator lookup( String oid ) throws NamingException
209         {
210             return comparator;
211         }
212 
213 
214         public boolean hasComparator( String oid )
215         {
216             return true;
217         }
218 
219 
220         public Iterator<String> oidIterator()
221         {
222             return null;
223         }
224 
225 
226         public Iterator<ComparatorDescription> comparatorDescriptionIterator()
227         {
228             return null;
229         }
230 
231 
232         public void unregister( String oid ) throws NamingException
233         {
234         }
235 
236 
237         public void unregisterSchemaElements( String schemaName )
238         {
239         }
240 
241 
242         public void renameSchema( String originalSchemaName, String newSchemaName )
243         {
244         }
245     }
246 }