source: gs2-extensions/tdb/trunk/src/java/org/greenstone/tdbjava/TDBJavaTest.java@ 30274

Last change on this file since 30274 was 30274, checked in by jmt12, 9 years ago

Adding in tests to open multiple connections to the same database (inode) at the same time. This triggered issues within GSDL3 due to the tdb library itself erroring out if the same process tries to open the same database more than once. Note that multiple opens from different processes is fine.

File size: 8.7 KB
Line 
1/*
2 * class: TDBJavaTest -- Test suite for this package
3 * Copyright (C) 2015 Greenstone Digital Library, University of Waikato
4 * $Id$
5 *
6 * Based on: javagdbm/GdbmTest.java
7 * Original author: Martin Pool, 1997 Pharos IP Pty Ltd
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24package org.greenstone.tdbjava;
25
26import java.io.File;
27import java.io.PrintStream;
28import java.util.Enumeration;
29import java.util.Random;
30
31import org.greenstone.tdbjava.TDBJava;
32import org.greenstone.tdbjava.TDBJavaException;
33import org.greenstone.tdbjava.Test;
34
35/** Test harness for the TDBJava/JNI layer.
36 *
37 * <P>The source of this class forms a useful demonstration of the
38 * TDBJava library and is commended to the intending programmer.
39 *
40 */
41public class TDBJavaTest
42{
43
44 static final int MANY_RECORDS = 200;
45
46 /**
47 * Don't instantiate
48 */
49 private TDBJavaTest() {;}
50 /** TDBJavaTest() **/
51
52
53 /** @function testLongData(TDBJava)
54 */
55 private static void testLongData(TDBJava db)
56 throws Exception
57 {
58 // generate some long random content
59 StringBuffer buffer = new StringBuffer();
60 Random r = new Random();
61 for (int i = 0; i < 3600; i++) {
62 buffer.append((char)(r.nextInt(26) + 'a'));
63 }
64 String value = buffer.toString();
65 buffer = null;
66 String key = "LargeDatum";
67
68 db.store(key, value);
69 String retrieved = db.fetch(key);
70
71 Test.ok(160, retrieved.hashCode() == value.hashCode());
72 Test.ok(161, retrieved.equals(value));
73
74 db.delete(key);
75 Test.ok(162, true);
76 }
77 /** testLongData(TDBJava) **/
78
79
80 /** @function testBigFile(TDBJava)
81 */
82 private static void testBigFile(TDBJava db)
83 throws Exception
84 {
85 String key;
86
87 // Test a lot of data
88 byte[] data = new byte[10000];
89 for (int i = 0; i < data.length; i++) {
90 data[i] = (byte)((i & 63) + 32);
91 }
92 Test.ok(150, true);
93
94 // Store a series of records in the file
95 for (int i = 0; i < MANY_RECORDS; i++) {
96 if ((i % 100) == 0) {
97 System.out.print(Integer.toString(i)+ " ");
98 }
99 db.store(Integer.toString(i, 16), data.toString());
100 }
101 System.out.println();
102 Test.ok(151, true);
103
104 // Enumerate keys and values out of the file
105 int count = 0;
106 Enumeration keys = db.keys();
107 while ( keys.hasMoreElements() ) {
108 key = (String) keys.nextElement();
109 count++;
110 if ((count % 100) == 0) {
111 System.out.print(Integer.toString(count)+ " ");
112 }
113 }
114 System.out.println();
115 Test.ok(152, count==MANY_RECORDS);
116
117 // Delete all the records from the file
118 count = 0;
119 while ( (key = (String) db.getFirstKey()) != null ) {
120 db.delete(key);
121 count++;
122 if ((count % 100) == 0) {
123 System.out.print(Integer.toString(count)+ " ");
124 }
125 }
126 System.out.println();
127 Test.ok(153, count==MANY_RECORDS);
128 }
129 /** testBigFile(TDBJava) **/
130
131
132 public static void ensureNoDatabase(String file_path)
133 {
134 try {
135 File delete_me = new File(file_path);
136 if (delete_me.exists()) {
137 delete_me.delete();
138 }
139 }
140 catch (Exception e) {
141 System.err.println("Failed to remove existing database: " + file_path);
142 System.exit(0);
143 }
144 }
145 /** ensureNoDatabase(String) **/
146
147
148 /** @function main()
149 */
150 public static void main(String[] argv)
151 {
152 final String db_path = "/tmp/java.tdb";
153 String key, value;
154 boolean found;
155
156 // Test cases, inspired by db-hash.t in the Perl5.003_93
157 // distribution
158 System.out.println("===== TDBJava Database tests =====");
159 System.out.println(" - Library version: " + TDBJava.getLibraryVersion());
160 System.out.println(" - Driver version: " + TDBJava.getWrapperVersion());
161 ensureNoDatabase(db_path);
162
163 try {
164 // Create a simple database
165 TDBJava db = TDBJava.getConnection(db_path);
166 Test.ok(1, db != null);
167
168 // Check database is open
169 Test.ok(1.5, db.isOpen());
170
171 // Store some data in the file
172 db.store("mountain", "Kosciusko");
173 Test.ok(2, true);
174
175 // Store and read back data
176 db.store("abc", "ABC");
177 value = db.fetch("abc");
178 Test.ok(3, value.equals("ABC"));
179
180 // Check whether keys exist or not
181 Test.ok(4, db.exists("abc"));
182 Test.ok(5, !db.exists("jimmy"));
183 Test.ok(6, !db.exists("abc\0"));
184
185 // Open a second handle to the same database
186 TDBJava db4 = TDBJava.getConnection(db_path);
187 Test.ok(701, db4 != null);
188 // read an existing key
189 value = db4.fetch("abc");
190 Test.ok(702, value.equals("ABC"));
191 // write a new key
192 db4.store("breakfast", "Bacon");
193 Test.ok(703, true);
194 // read it out
195 value = db4.fetch("breakfast");
196 Test.ok(704, value.equals("Bacon"));
197 // delete a record
198 db4.delete("mountain");
199 Test.ok(705, !db4.exists("mountain"));
200 // close it
201 db4.close();
202 // test added record still exists
203 value = db.fetch("breakfast");
204 Test.ok(706, value.equals("Bacon"));
205
206 // Delete those records
207 db.delete("breakfast");
208 Test.ok(9, !db.exists("breakfast"));
209 db.delete("abc");
210 Test.ok(10, !db.exists("abc"));
211
212 // Store a series of records in the file
213 for (int i = 100; i < 200; i++) {
214 db.store(Integer.toString(i, Character.MAX_RADIX),
215 Integer.toString(i, Character.MIN_RADIX));
216 }
217
218 // Enumerate keys and values out of the file
219 int count = 0;
220 Enumeration keys = db.keys();
221 while (keys.hasMoreElements()) {
222 key = (String) keys.nextElement();
223 // System.out.print(key + "=");
224 // value = (String) db.fetch(key);
225 // System.out.println(value);
226 count++;
227 }
228 Test.ok(20, count==100);
229
230 // Delete all the records from the file
231 count = 0;
232 while ((key = (String) db.getFirstKey()) != null) {
233 db.delete(key);
234 count++;
235 }
236 Test.ok(30, count==100);
237
238 // Try to fetch a non-existent key
239 boolean caught = false;
240 try {
241 db.fetch("larry!");
242 }
243 catch (Exception e) {
244 // TODO: Check the exception was the one we expected?
245 ///ystem.out.println("caught: " + e.toString());
246 caught = true;
247 }
248 Test.ok(40, caught);
249
250 // Store some very large data
251 testLongData(db);
252
253 // Store strings containing non-ASCII characters
254 final String euro_string = "Some funny characters: «¡ Ê Þ â ß !»";
255 db.store("high ASCII", euro_string);
256 Test.ok(50, db.fetch("high ASCII").equals(euro_string));
257
258 // Store for later
259 db.store("mountain", "Pirongia");
260
261 // Close the database
262 db.close();
263 Test.ok(60, true);
264
265 // Try to read from a database that is closed
266 caught = false;
267 try {
268 db.fetch("larry!");
269 }
270 catch (Exception e) {
271 ///ystem.out.println("caught: " + e.toString());
272 caught = true;
273 }
274 Test.ok(70, caught);
275
276 /* No longer applicable
277 // Try to open a non-existent database
278 String bogus_db_path = "/tmp/somenonexistentdatabase.tdb";
279 ensureNoDatabase(bogus_db_path);
280 caught = false;
281 try {
282 db = TDBJava.getConnection(bogus_db_path, TDBJava.TDB_DEFAULT, TDBJava.O_READONLY);
283 }
284 catch (Exception e) {
285 ///ystem.out.println("caught: " + e.toString());
286 caught = true;
287 }
288 Test.ok(80, caught);
289
290 // Open a database read-only
291 db = TDBJava.getConnection(db_path, TDBJava.TDB_DEFAULT, TDBJava.O_READONLY);
292 Test.ok(90);
293
294 // Try to insert
295 caught = false;
296 try {
297 db.store("apple", "crumble");
298 }
299 catch (Exception e) {
300 System.out.println("caught: " + e.toString());
301 caught = true;
302 }
303 Test.ok(91, caught);
304
305 db.close();
306 */
307
308 // Replace an existing database
309 db = TDBJava.newConnection(db_path);
310 Test.ok(100, !db.exists("mountain"));
311
312 // Juggle three databases at once
313 final String db_path2 = "/tmp/java2.tdb";
314 ensureNoDatabase(db_path2);
315 TDBJava db2 = TDBJava.getConnection(db_path2);
316 final String db_path3 = "/tmp/java3.tdb";
317 ensureNoDatabase(db_path3);
318 TDBJava db3 = TDBJava.getConnection(db_path3);
319 Test.ok(110, true);
320
321 keys = db.keys();
322 while (keys.hasMoreElements()) {
323 key = (String) keys.nextElement();
324 value = db.fetch(key);
325 db2.store(key, value);
326 db3.store(key, value);
327 }
328 Test.ok(120, true);
329
330 keys = db2.keys();
331 found = true;
332 while (keys.hasMoreElements()) {
333 found &= db3.exists((String)keys.nextElement());
334 }
335 Test.ok(130, found);
336
337 db2.close();
338 db3.close();
339
340 Test.ok(140, true);
341
342 testBigFile(db);
343
344 db.close();
345 Test.ok(160, true);
346 }
347 catch (Exception e) {
348 e.printStackTrace();
349 }
350 Test.summary();
351 }
352}
Note: See TracBrowser for help on using the repository browser.