1 5 package org.h2.test; 6 7 import java.io.File ; 8 import java.io.FileWriter ; 9 import java.io.PrintWriter ; 10 import java.io.Reader ; 11 import java.sql.Connection ; 12 import java.sql.DriverManager ; 13 import java.sql.ResultSet ; 14 import java.sql.ResultSetMetaData ; 15 import java.sql.SQLException ; 16 import java.sql.Statement ; 17 import java.sql.Types ; 18 import java.text.SimpleDateFormat ; 19 import java.util.Properties ; 20 21 import org.h2.jdbc.JdbcConnection; 22 import org.h2.message.TraceSystem; 23 import org.h2.store.FileLock; 24 import org.h2.tools.DeleteDbFiles; 25 26 29 30 public abstract class TestBase { 31 32 protected static String BASE_DIR = "data"; 33 34 protected TestAll config; 35 private long start; 36 37 protected void startServerIfRequired() throws SQLException { 38 config.beforeTest(); 39 } 40 41 protected void stopServerIfRequired() { 42 config.afterTest(); 43 } 44 45 public TestBase init(TestAll conf) throws Exception { 46 this.config = conf; 47 return this; 48 } 49 50 public void testCase(int i) throws Exception { 51 } 53 54 public void runTest(TestAll conf) { 55 try { 56 init(conf); 57 start = System.currentTimeMillis(); 58 printlnWithTime("start"); 59 test(); 60 println("done "); 61 } catch(Exception e) { 62 fail("FAIL " + e.toString(), e); 63 if(config.stopOnError) { 64 throw new Error ("ERROR"); 65 } 66 } 67 } 68 69 public Connection getConnection(String name) throws Exception { 70 return getConnectionInternal(getURL(name, true), getUser(), getPassword()); 71 } 72 73 protected Connection getConnection(String name, String user, String password) throws Exception { 74 return getConnectionInternal(getURL(name, false), user, password); 75 } 76 77 protected String getPassword() { 78 return "123"; 79 } 80 81 private void deleteIndexFiles(String name) throws SQLException { 82 if(name.indexOf(";")>0) { 83 name = name.substring(0, name.indexOf(';')); 84 } 85 name += ".index.db"; 86 if(new File (name).canWrite()) { 87 new File (name).delete(); 88 } 89 } 90 91 protected String getURL(String name, boolean admin) throws SQLException { 92 String url; 93 if(name.startsWith("jdbc:")) { 94 return name; 95 } 96 if(config.memory) { 97 url = "mem:" + name; 98 } else { 99 if(!name.startsWith("inmemory:") && !name.startsWith(BASE_DIR + "/")) { 100 name = BASE_DIR + "/" + name; 101 } 102 if(config.deleteIndex) { 103 deleteIndexFiles(name); 104 } 105 if(config.networked) { 106 if(config.ssl) { 107 url = "ssl://localhost:9092/" + name; 108 } else { 109 url = "tcp://localhost:9092/" + name; 110 } 111 } else { 112 url = name; 113 } 114 if(config.traceSystemOut) { 115 url += ";TRACE_LEVEL_SYSTEM_OUT=2"; 116 } 117 if(config.traceLevelFile>0 && admin) { 118 url += ";TRACE_LEVEL_FILE="+config.traceLevelFile; 119 } 120 } 121 if(config.throttle>0) { 122 url += ";THROTTLE=" + config.throttle; 123 } 124 if(config.textStorage) { 125 url += ";STORAGE=TEXT"; 126 } 127 url += ";LOCK_TIMEOUT=50"; 128 if(admin) { 129 url += ";LOG=" + config.logMode; 130 } 131 if(config.smallLog && admin) { 132 url += ";MAX_LOG_SIZE=1"; 133 } 134 if(config.diskUndo && admin) { 135 url += ";MAX_MEMORY_UNDO=3"; 136 } 137 if(config.diskResult && admin) { 138 url += ";MAX_MEMORY_ROWS=100;CACHE_SIZE=0"; 139 } 140 return "jdbc:h2:"+url; 141 } 142 143 private Connection getConnectionInternal(String url, String user, String password) throws Exception { 144 Class.forName("org.h2.Driver"); 145 Connection conn; 149 if(config.cipher != null) { 150 url += ";cipher=" + config.cipher; 151 password = "filePassword " + password; 152 Properties info = new Properties (); 153 info.setProperty("user", user); 154 info.put("password", password.toCharArray()); 155 conn = DriverManager.getConnection(url, info); 156 } else { 157 conn = DriverManager.getConnection(url, user, password); 158 } 159 return conn; 160 } 161 162 protected int getSize(int small, int big) throws Exception { 163 return config.big ? big : small; 164 } 165 166 protected String getUser() { 167 return "sa"; 168 } 169 170 protected void trace(int x) { 171 trace(""+x); 172 } 173 174 public void trace(String s) { 175 if(config.traceTest) { 176 println(s); 177 } 178 } 179 180 protected void traceMemory() { 181 if(config.traceTest) { 182 trace("mem="+getMemoryUsed()); 183 } 184 } 185 186 public void printTimeMemory(String s, long time) { 187 if(config.big) { 188 println(time+" ms; " + getMemoryUsed()+" MB: " + s); 189 } 190 } 191 192 public static int getMemoryUsed() { 193 Runtime rt = Runtime.getRuntime(); 194 long memory = Long.MAX_VALUE; 195 for(int i=0; i<8; i++) { 196 rt.gc(); 197 long memNow = rt.totalMemory() - rt.freeMemory(); 198 if(memNow >= memory) { 199 break; 200 } 201 memory = memNow; 202 } 203 int mb = (int)(memory / 1024 / 1024); 204 return mb; 205 } 206 207 protected void error(String string) throws Exception { 208 println(string); 209 throw new Exception (string); 210 } 211 212 protected void fail(String s, Throwable e) { 213 println(s); 214 logError(s, e); 215 } 216 217 public static void logError(String s, Throwable e) { 218 if(e==null) { 219 e = new Exception (s); 220 } 221 System.out.println("ERROR: " + s + " " + e.toString() + " ------------------------------"); 222 e.printStackTrace(); 223 try { 224 TraceSystem ts = new TraceSystem(null); 225 FileLock lock = new FileLock(ts, 1000); 226 lock.lock("error.lock", false); 227 FileWriter fw = new FileWriter ("ERROR.txt", true); 228 PrintWriter pw = new PrintWriter (fw); 229 e.printStackTrace(pw); 230 pw.close(); 231 fw.close(); 232 lock.unlock(); 233 } catch(Throwable t) { 234 t.printStackTrace(); 235 } 236 } 237 238 protected void println(String s) { 239 printlnWithTime(s); 240 } 241 242 private void printlnWithTime(String s) { 243 long time = System.currentTimeMillis() - start; 244 String t = " " + time; 245 t = t.substring(t.length()-6); 246 System.out.println(s+" ("+t+" ms) "+getClass().getName()); 247 } 248 249 protected static void printTime(String s) { 250 SimpleDateFormat sdf = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss"); 251 System.out.println(sdf.format(new java.util.Date ()) + " " + s); 252 } 253 254 protected void deleteDb(String name) throws Exception { 255 DeleteDbFiles.execute(BASE_DIR, name, true); 256 } 257 258 protected void deleteDb(String dir, String name) throws Exception { 259 DeleteDbFiles.execute(dir, name, true); 260 } 261 262 public abstract void test() throws Exception ; 263 264 public void check(int a, int b) throws Exception { 265 if(a != b) { 266 error("int a: "+a+" b: "+b); 267 } 268 } 269 270 protected void check(byte[] a, byte[] b) throws Exception { 271 check(a.length == b.length); 272 for(int i=0; i<a.length; i++) { 273 if(a[i] != b[i]) { 274 error("byte["+i+"]: a="+(int)a[i]+" b="+(int)b[i]); 275 } 276 } 277 } 278 279 protected void check(String a, String b) throws Exception { 280 if(a==null && b==null) { 281 return; 282 } else if(a==null || b==null) { 283 error("string a: "+a+" b: "+b); 284 } 285 if(!a.equals(b)) { 286 for(int i=0; i<a.length(); i++) { 287 String s = a.substring(0, i); 288 if(!b.startsWith(s)) { 289 a = a.substring(0, i) + "<*>" + a.substring(i); 290 break; 291 } 292 } 293 error("string a: "+a+" ("+a.length()+") b: "+b+" (" + b.length() +")"); 294 } 295 } 296 297 protected void checkFalse(String a, String b) throws Exception { 298 if(a.equals(b)) { 299 error("string false a: "+a+" b: "+b); 300 } 301 } 302 303 protected void check(long a, long b) throws Exception { 304 if(a != b) { 305 error("long a: "+a+" b: "+b); 306 } 307 } 308 309 protected void checkSmaller(long a, long b) throws Exception { 310 if(a >= b) { 311 error("a: "+a+" is not smaller than b: "+b); 312 } 313 } 314 315 protected void check(double a, double b) throws Exception { 316 if(a != b) { 317 error("double a: "+a+" b: "+b); 318 } 319 } 320 321 protected void check(float a, float b) throws Exception { 322 if(a != b) { 323 error("float a: "+a+" b: "+b); 324 } 325 } 326 327 protected void check(boolean a, boolean b) throws Exception { 328 if(a != b) { 329 error("boolean a: "+a+" b: "+b); 330 } 331 } 332 333 protected void check(boolean value) throws Exception { 334 if(!value) { 335 error("expected: true got: false"); 336 } 337 } 338 339 protected void checkFalse(boolean value) throws Exception { 340 if(value) { 341 error("expected: false got: true"); 342 } 343 } 344 345 protected void checkResultRowCount(ResultSet rs, int expected) throws Exception { 346 int i=0; 347 while(rs.next()) { 348 i++; 349 } 350 check(i, expected); 351 } 352 353 protected void checkSingleValue(Statement stat, String sql, int value) throws Exception { 354 ResultSet rs = stat.executeQuery(sql); 355 check(rs.next()); 356 check(rs.getInt(1), value); 357 checkFalse(rs.next()); 358 } 359 360 protected void testResultSetMeta(ResultSet rs, int columncount, String [] labels, 361 int[] datatypes, int[] precision, int[] scale) throws Exception { 362 ResultSetMetaData meta = rs.getMetaData(); 363 int cc = meta.getColumnCount(); 364 if (cc != columncount) { 365 error("result set contains " + cc + " columns not " + columncount); 366 } 367 for (int i = 0; i < columncount; i++) { 368 if (labels != null) { 369 String l = meta.getColumnLabel(i + 1); 370 if (!labels[i].equals(l)) { 371 error("column label " + i + " is " + l + " not " 372 + labels[i]); 373 } 374 } 375 if (datatypes != null) { 376 int t = meta.getColumnType(i + 1); 377 if (datatypes[i] != t) { 378 error("column datatype " + i + " is " + t + " not " 379 + datatypes[i] + " (prec=" 380 + meta.getPrecision(i + 1) + " scale=" 381 + meta.getScale(i + 1) + ")"); 382 } 383 String typeName = meta.getColumnTypeName(i+1); 384 String className = meta.getColumnClassName(i+1); 385 switch(t) { 386 case Types.INTEGER: 387 check(typeName, "INTEGER"); 388 check(className, "java.lang.Integer"); 389 break; 390 case Types.VARCHAR: 391 check(typeName, "VARCHAR"); 392 check(className, "java.lang.String"); 393 break; 394 case Types.SMALLINT: 395 check(typeName, "SMALLINT"); 396 check(className, "java.lang.Short"); 397 break; 398 case Types.TIMESTAMP: 399 check(typeName, "TIMESTAMP"); 400 check(className, "java.sql.Timestamp"); 401 break; 402 case Types.DECIMAL: 403 check(typeName, "DECIMAL"); 404 check(className, "java.math.BigDecimal"); 405 break; 406 } 407 } 408 if (precision != null) { 409 int p = meta.getPrecision(i + 1); 410 if (precision[i] != p) { 411 error("column precision " + i + " is " + p + " not " 412 + precision[i]); 413 } 414 } 415 if (scale != null) { 416 int s = meta.getScale(i + 1); 417 if (scale[i] != s) { 418 error("column scale " + i + " is " + s + " not " + scale[i]); 419 } 420 } 421 422 } 423 } 424 425 protected void testResultSetOrdered(ResultSet rs, String [][] data) throws Exception { 426 testResultSet(true, rs, data); 427 } 428 429 void testResultSetUnordered(ResultSet rs, String [][] data) throws Exception { 430 testResultSet(false, rs, data); 431 } 432 433 void testResultSet(boolean ordered, ResultSet rs, String [][] data) 434 throws Exception { 435 int len = rs.getMetaData().getColumnCount(); 436 int rows = data.length; 437 if (rows == 0) { 438 if (rs.next()) { 440 error("testResultSet expected rowcount:" + rows + " got:0"); 441 } 442 } 443 int len2 = data[0].length; 444 if (len < len2) { 445 error("testResultSet expected columncount:" + len2 + " got:" + len); 446 } 447 for (int i = 0; i < rows; i++) { 448 if (!rs.next()) { 449 error("testResultSet expected rowcount:" + rows + " got:" + i); 450 } 451 String [] row = getData(rs, len); 452 if (ordered) { 453 String [] good = data[i]; 454 if (!testRow(good, row, good.length)) { 455 error("testResultSet row not equal, got:\n" 456 + formatRow(row) + "\n" + formatRow(good)); 457 } 458 } else { 459 boolean found = false; 460 for (int j = 0; j < rows; j++) { 461 String [] good = data[i]; 462 if (testRow(good, row, good.length)) { 463 found = true; 464 break; 465 } 466 } 467 if (!found) { 468 error("testResultSet no match for row:" + formatRow(row)); 469 } 470 } 471 } 472 if (rs.next()) { 473 String [] row = getData(rs, len); 474 error("testResultSet expected rowcount:" + rows + " got:>=" 475 + (rows + 1) + " data:" + formatRow(row)); 476 } 477 } 478 479 boolean testRow(String [] a, String [] b, int len) { 480 for (int i = 0; i < len; i++) { 481 String sa = a[i]; 482 String sb = b[i]; 483 if (sa == null || sb == null) { 484 if (sa != sb) { 485 return false; 486 } 487 } else { 488 if (!sa.equals(sb)) { 489 return false; 490 } 491 } 492 } 493 return true; 494 } 495 496 String [] getData(ResultSet rs, int len) throws SQLException { 497 String [] data = new String [len]; 498 for (int i = 0; i < len; i++) { 499 data[i] = rs.getString(i + 1); 500 rs.getObject(i + 1); 502 } 503 return data; 504 } 505 506 String formatRow(String [] row) { 507 String sb = ""; 508 for (int i = 0; i < row.length; i++) { 509 sb += "{" + row[i] + "}"; 510 } 511 return "{" + sb + "}"; 512 } 513 514 protected void crash(Connection conn) throws Exception { 515 ((JdbcConnection)conn).setPowerOffCount(1); 516 try { 517 conn.createStatement().execute("SET WRITE_DELAY 0"); 518 conn.createStatement().execute("CREATE TABLE AAA(ID INT)"); 519 error("should be crashed already"); 520 } catch(SQLException e) { 521 } 523 try { 524 conn.close(); 525 } catch(SQLException e) { 526 } 528 } 529 530 protected String readString(Reader reader) throws Exception { 531 if(reader==null) { 532 return null; 533 } 534 StringBuffer buffer=new StringBuffer (); 535 try { 536 while(true) { 537 int c=reader.read(); 538 if(c==-1) { 539 break; 540 } 541 buffer.append((char)c); 542 } 543 return buffer.toString(); 544 } catch(Exception e) { 545 check(false); 546 return null; 547 } 548 } 549 550 protected void checkNotGeneralException(SQLException e) throws Exception { 551 if(e!=null && e.getSQLState().startsWith("HY000")) { 552 TestBase.logError("Unexpected General error", e); 553 } 554 } 555 556 protected void check(Integer a, Integer b) throws Exception { 557 if(a == null || b == null) { 558 check(a==b); 559 } else { 560 check(a.intValue(), b.intValue()); 561 } 562 } 563 564 } 565 | Popular Tags |