1 20 21 package org.apache.derbyTesting.functionTests.tests.jdbc4; 22 23 import java.sql.*; 24 import javax.sql.*; 25 26 import java.lang.reflect.Method ; 27 import java.lang.reflect.Modifier ; 28 import java.util.Arrays ; 29 import java.util.HashSet ; 30 import java.util.Set ; 31 import junit.framework.Test; 32 import junit.framework.TestCase; 33 import junit.framework.TestSuite; 34 import org.apache.derbyTesting.functionTests.util.TestUtil; 35 import org.apache.derbyTesting.functionTests.util.TestDataSourceFactory; 36 import org.apache.derbyTesting.junit.BaseJDBCTestCase; 37 import org.apache.derbyTesting.junit.TestConfiguration; 38 39 44 public class VerifySignatures extends BaseJDBCTestCase { 45 46 49 private final static Class [] JDBC_INTERFACES = { 50 java.sql.Array .class, 51 java.sql.Blob .class, 52 java.sql.CallableStatement .class, 53 java.sql.Clob .class, 54 java.sql.Connection .class, 55 java.sql.DatabaseMetaData .class, 56 java.sql.Driver .class, 57 java.sql.NClob .class, 58 java.sql.ParameterMetaData .class, 59 java.sql.PreparedStatement .class, 60 java.sql.Ref .class, 61 java.sql.ResultSet .class, 62 java.sql.ResultSetMetaData .class, 63 java.sql.RowId .class, 64 java.sql.Savepoint .class, 65 java.sql.SQLData .class, 66 java.sql.SQLInput .class, 67 java.sql.SQLOutput .class, 68 java.sql.SQLXML .class, 69 java.sql.Statement .class, 70 java.sql.Struct .class, 71 java.sql.Wrapper .class, 72 javax.sql.CommonDataSource .class, 73 javax.sql.ConnectionEventListener .class, 74 javax.sql.ConnectionPoolDataSource .class, 75 javax.sql.DataSource .class, 76 javax.sql.PooledConnection .class, 77 javax.sql.RowSet .class, 78 javax.sql.RowSetInternal .class, 79 javax.sql.RowSetListener .class, 80 javax.sql.RowSetMetaData .class, 81 javax.sql.RowSetReader .class, 82 javax.sql.RowSetWriter .class, 83 javax.sql.StatementEventListener .class, 84 javax.sql.XAConnection .class, 85 javax.sql.XADataSource .class, 86 }; 87 88 91 public VerifySignatures() { 92 super("VerifySignatures"); 93 } 94 95 101 public static Test suite() throws SQLException { 102 Set <ClassInfo> classes = new HashSet <ClassInfo>(); 104 105 collectClassesFromDataSource(classes); 106 collectClassesFromConnectionPoolDataSource(classes); 107 collectClassesFromXADataSource(classes); 108 addClass(classes, 109 DriverManager.getDriver(TestConfiguration.getCurrent().getJDBCUrl()).getClass(), 110 java.sql.Driver .class); 111 112 TestSuite suite = new TestSuite(); 113 114 Set <Class > interfaces = new HashSet <Class >(); 116 117 for (ClassInfo pair : classes) { 118 Set <Method > methods = new HashSet <Method >(); 121 for (Class iface : getAllInterfaces(pair.jdbcInterface)) { 122 interfaces.add(iface); 123 for (Method method : iface.getMethods()) { 124 methods.add(method); 125 } 126 } 127 for (Method method : methods) { 128 suite.addTest(new MethodTestCase(pair.derbyImplementation, 129 method)); 130 } 131 } 132 suite.addTest(new InterfaceCoverageTestCase(interfaces)); 133 return suite; 134 } 135 136 144 private static void collectClassesFromDataSource(Set <ClassInfo> classes) 145 throws SQLException 146 { 147 DataSource ds = TestDataSourceFactory.getDataSource(); 148 addClass(classes, ds.getClass(), javax.sql.DataSource .class); 149 collectClassesFromConnection(ds.getConnection 150 (TestConfiguration.getCurrent().getUserName(), 151 TestConfiguration.getCurrent().getUserPassword()), 152 classes); 153 } 154 155 163 private static void 164 collectClassesFromConnectionPoolDataSource(Set <ClassInfo> classes) 165 throws SQLException 166 { 167 ConnectionPoolDataSource cpds = TestDataSourceFactory.getConnectionPoolDataSource(); 168 addClass(classes, 169 cpds.getClass(), javax.sql.ConnectionPoolDataSource .class); 170 171 PooledConnection pc = 172 cpds.getPooledConnection(TestConfiguration.getCurrent().getUserName(), 173 TestConfiguration.getCurrent().getUserPassword()); 174 addClass(classes, pc.getClass(), javax.sql.PooledConnection .class); 175 176 collectClassesFromConnection(pc.getConnection(), classes); 177 178 pc.close(); 179 } 180 181 189 private static void collectClassesFromXADataSource(Set <ClassInfo> classes) 190 throws SQLException 191 { 192 XADataSource xads = TestDataSourceFactory.getXADataSource(); 193 addClass(classes, xads.getClass(), javax.sql.XADataSource .class); 194 195 XAConnection xaconn = xads.getXAConnection(TestConfiguration.getCurrent().getUserName(), 196 TestConfiguration.getCurrent().getUserPassword()); 197 addClass(classes, xaconn.getClass(), javax.sql.XAConnection .class); 198 199 collectClassesFromConnection(xaconn.getConnection(), classes); 200 } 201 202 210 private static void collectClassesFromConnection(Connection conn, 211 Set <ClassInfo> classes) 212 throws SQLException 213 { 214 conn.setAutoCommit(false); 215 addClass(classes, conn.getClass(), java.sql.Connection .class); 216 217 Savepoint sp = conn.setSavepoint(); 218 addClass(classes, sp.getClass(), java.sql.Savepoint .class); 219 conn.releaseSavepoint(sp); 220 221 DatabaseMetaData dmd = conn.getMetaData(); 222 addClass(classes, dmd.getClass(), java.sql.DatabaseMetaData .class); 223 224 collectClassesFromStatement(conn, classes); 225 collectClassesFromPreparedStatement(conn, classes); 226 collectClassesFromCallableStatement(conn, classes); 227 conn.rollback(); 228 conn.close(); 229 } 230 231 239 private static void 240 collectClassesFromStatement(Connection conn, Set <ClassInfo> classes) 241 throws SQLException 242 { 243 Statement stmt = conn.createStatement(); 244 addClass(classes, stmt.getClass(), java.sql.Statement .class); 245 246 stmt.execute("CREATE TABLE t (id INT PRIMARY KEY, " + 247 "b BLOB(10), c CLOB(10))"); 248 stmt.execute("INSERT INTO t (id, b, c) VALUES (1, "+ 249 "CAST (" + TestUtil.stringToHexLiteral("101010001101") + 250 "AS BLOB(10)), CAST ('hello' AS CLOB(10)))"); 251 252 ResultSet rs = stmt.executeQuery("SELECT id, b, c FROM t"); 253 addClass(classes, rs.getClass(), java.sql.ResultSet .class); 254 rs.next(); 255 Blob b = rs.getBlob(2); 256 addClass(classes, b.getClass(), java.sql.Blob .class); 257 Clob c = rs.getClob(3); 258 addClass(classes, c.getClass(), java.sql.Clob .class); 259 ResultSetMetaData rsmd = rs.getMetaData(); 260 addClass(classes, rsmd.getClass(), java.sql.ResultSetMetaData .class); 261 rs.close(); 262 263 stmt.close(); 264 conn.rollback(); 265 } 266 267 275 private static void 276 collectClassesFromPreparedStatement(Connection conn, 277 Set <ClassInfo> classes) 278 throws SQLException 279 { 280 PreparedStatement ps = conn.prepareStatement("VALUES(1)"); 281 addClass(classes, ps.getClass(), java.sql.PreparedStatement .class); 282 ResultSet rs = ps.executeQuery(); 283 addClass(classes, rs.getClass(), java.sql.ResultSet .class); 284 rs.close(); 285 286 ParameterMetaData pmd = ps.getParameterMetaData(); 287 addClass(classes, pmd.getClass(), java.sql.ParameterMetaData .class); 288 289 ps.close(); 290 } 291 292 300 private static void 301 collectClassesFromCallableStatement(Connection conn, 302 Set <ClassInfo> classes) 303 throws SQLException 304 { 305 CallableStatement cs = 306 conn.prepareCall("CALL SYSCS_UTIL.SYSCS_SET_RUNTIMESTATISTICS(0)"); 307 addClass(classes, cs.getClass(), java.sql.CallableStatement .class); 308 309 ParameterMetaData pmd = cs.getParameterMetaData(); 310 addClass(classes, pmd.getClass(), java.sql.ParameterMetaData .class); 311 312 cs.close(); 313 } 314 315 322 private static void addClass(Set <ClassInfo> classes, 323 Class implementation, Class iface) { 324 classes.add(new ClassInfo(implementation, iface)); 325 } 326 327 335 private static Set <Class > getAllInterfaces(Class iface) { 336 Set <Class > set = new HashSet <Class >(); 337 set.add(iface); 338 for (Class superIface : iface.getInterfaces()) { 339 set.add(superIface); 340 set.addAll(getAllInterfaces(superIface)); 341 } 342 return set; 343 } 344 345 349 private static class MethodTestCase extends TestCase { 350 351 private final Class derbyImplementation; 352 353 private final Method ifaceMethod; 354 355 361 private MethodTestCase(Class imp, Method method) { 362 super("MethodTestCase{Class=" + imp.getName() + 363 ",Method=" + method + "}"); 364 derbyImplementation = imp; 365 ifaceMethod = method; 366 } 367 368 374 public void runTest() throws NoSuchMethodException { 375 assertFalse("Implementation class is interface", 376 derbyImplementation.isInterface()); 377 378 Method impMethod = 379 derbyImplementation.getMethod(ifaceMethod.getName(), 380 ifaceMethod.getParameterTypes()); 381 382 assertEquals("Incorrect return type", 383 ifaceMethod.getReturnType(), 384 impMethod.getReturnType()); 385 386 int modifiers = impMethod.getModifiers(); 387 assertTrue("Non-public method", Modifier.isPublic(modifiers)); 388 assertFalse("Abstract method", Modifier.isAbstract(modifiers)); 389 assertFalse("Static method", Modifier.isStatic(modifiers)); 390 391 Class [] declaredExceptions = ifaceMethod.getExceptionTypes(); 392 for (Class exception : impMethod.getExceptionTypes()) { 393 if (RuntimeException .class.isAssignableFrom(exception)) { 394 continue; 395 } 396 assertNotNull("Incompatible throws clause", 397 findCompatibleClass(exception, 398 declaredExceptions)); 399 } 400 } 401 402 413 private Class findCompatibleClass(Class exception, Class [] declared) 414 { 415 for (Class <?> dec : declared) { 416 if (dec.isAssignableFrom(exception)) { 417 return dec; 418 } 419 } 420 return null; 421 } 422 } 423 424 428 private static class InterfaceCoverageTestCase extends TestCase { 429 430 432 private final Set <Class > checkedInterfaces; 433 435 private final Set <Class > jdbcInterfaces; 436 437 442 private InterfaceCoverageTestCase(Set <Class > interfaces) { 443 super("InterfaceCoverageTestCase"); 444 checkedInterfaces = interfaces; 445 jdbcInterfaces = new HashSet <Class >(Arrays.asList(JDBC_INTERFACES)); 446 447 449 jdbcInterfaces.remove(java.sql.Array .class); 451 jdbcInterfaces.remove(java.sql.NClob .class); 452 jdbcInterfaces.remove(java.sql.Ref .class); 453 jdbcInterfaces.remove(java.sql.SQLData .class); 454 jdbcInterfaces.remove(java.sql.SQLInput .class); 455 jdbcInterfaces.remove(java.sql.SQLOutput .class); 456 jdbcInterfaces.remove(java.sql.SQLXML .class); 457 jdbcInterfaces.remove(java.sql.Struct .class); 458 jdbcInterfaces.remove(javax.sql.RowSet .class); 459 jdbcInterfaces.remove(javax.sql.RowSetInternal .class); 460 jdbcInterfaces.remove(javax.sql.RowSetListener .class); 461 jdbcInterfaces.remove(javax.sql.RowSetMetaData .class); 462 jdbcInterfaces.remove(javax.sql.RowSetReader .class); 463 jdbcInterfaces.remove(javax.sql.RowSetWriter .class); 464 465 jdbcInterfaces.remove(java.sql.RowId .class); 468 469 jdbcInterfaces.remove(javax.sql.ConnectionEventListener .class); 472 jdbcInterfaces.remove(javax.sql.StatementEventListener .class); 473 } 474 475 479 public void runTest() { 480 jdbcInterfaces.removeAll(checkedInterfaces); 481 assertTrue("Unchecked interfaces: " + jdbcInterfaces, 482 jdbcInterfaces.isEmpty()); 483 } 484 } 485 486 490 private static class ClassInfo { 491 492 Class derbyImplementation; 493 494 Class jdbcInterface; 495 496 502 ClassInfo(Class imp, Class iface) { 503 derbyImplementation = imp; 504 jdbcInterface = iface; 505 } 506 507 514 public boolean equals(Object x) { 515 if (x instanceof ClassInfo) { 516 ClassInfo ci = (ClassInfo) x; 517 return 518 derbyImplementation.equals(ci.derbyImplementation) && 519 jdbcInterface.equals(ci.jdbcInterface); 520 } 521 return false; 522 } 523 524 529 public int hashCode() { 530 return derbyImplementation.hashCode() ^ jdbcInterface.hashCode(); 531 } 532 } 533 } 534 | Popular Tags |