You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by dj...@apache.org on 2006/11/09 00:51:46 UTC
svn commit: r472704 - in
/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang:
DatabaseClassLoadingTest.java _Suite.java
Author: djd
Date: Wed Nov 8 15:51:46 2006
New Revision: 472704
URL: http://svn.apache.org/viewvc?view=rev&rev=472704
Log:
DERBY-2033 (partial) All of the test cases from dcl.sql are converted to DatabaseClassLoadingTest
except those related to jarring up the database and runing tests against that read-only database.
Add DatabaseClassLoadingTest into lang._Suite.
Modified:
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/DatabaseClassLoadingTest.java
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/DatabaseClassLoadingTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/DatabaseClassLoadingTest.java?view=diff&rev=472704&r1=472703&r2=472704
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/DatabaseClassLoadingTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/DatabaseClassLoadingTest.java Wed Nov 8 15:51:46 2006
@@ -18,7 +18,8 @@
/**
* Test database class loading, executing routines from the
- * installed jars including accessing resources.
+ * installed jars including accessing resources. Replacing
+ * jars and handling signed jars is also tested.
*
*/
public class DatabaseClassLoadingTest extends BaseJDBCTestCase {
@@ -61,12 +62,33 @@
suite.addTest(SecurityManagerSetup.noSecurityManager(
new DatabaseClassLoadingTest("testAlterTable")));
- }
+
+ suite.addTest(SecurityManagerSetup.noSecurityManager(
+ new DatabaseClassLoadingTest("testClassPathRollback")));
+
+ suite.addTest(SecurityManagerSetup.noSecurityManager(
+ new DatabaseClassLoadingTest("testReplaceJar")));
+
+ suite.addTest(SecurityManagerSetup.noSecurityManager(
+ new DatabaseClassLoadingTest("testReplacedClass")));
+ suite.addTest(SecurityManagerSetup.noSecurityManager(
+ new DatabaseClassLoadingTest("testSecondJar")));
+ suite.addTest(SecurityManagerSetup.noSecurityManager(
+ new DatabaseClassLoadingTest("testSignedJar")));
+
+ suite.addTest(SecurityManagerSetup.noSecurityManager(
+ new DatabaseClassLoadingTest("testHackedJarReplacedClass")));
+ suite.addTest(SecurityManagerSetup.noSecurityManager(
+ new DatabaseClassLoadingTest("testInvalidJar")));
+ suite.addTest(SecurityManagerSetup.noSecurityManager(
+ new DatabaseClassLoadingTest("testRemoveJar")));
+ }
return new CleanDatabaseTestSetup(suite) {
protected void decorateSQL(Statement s) throws SQLException
{
s.executeUpdate("create schema emc");
+ s.executeUpdate("create schema \"emcAddOn\"");
s.executeUpdate("create table emc.contacts " +
"(id int primary key, e_mail varchar(30))");
s.executeUpdate(
@@ -81,6 +103,17 @@
"NO SQL " +
"external name 'org.apache.derbyTesting.databaseclassloader.emc.getArticle' " +
"language java parameter style java");
+
+ // function that gets the signers of the class (loaded from the jar)
+ s.executeUpdate("CREATE FUNCTION EMC.GETSIGNERS(" +
+ "CLASS_NAME VARCHAR(256)) RETURNS VARCHAR(60) "+
+ "NO SQL LANGUAGE JAVA PARAMETER STYLE JAVA " +
+ "EXTERNAL NAME 'org.apache.derbyTesting.databaseclassloader.emc.getSigners'");
+
+ s.executeUpdate("CREATE FUNCTION \"emcAddOn\".VALIDCONTACT(E_MAIL VARCHAR(30)) "+
+ "RETURNS SMALLINT "+
+ "READS SQL DATA LANGUAGE JAVA PARAMETER STYLE JAVA " +
+ "EXTERNAL NAME 'org.apache.derbyTesting.databaseclassloader.addon.vendor.util.valid'");
}
};
}
@@ -111,16 +144,7 @@
*/
public void testWithNoClasspath() throws SQLException
{
- URL jar =
- getTestResource("org/apache/derbyTesting/functionTests/tests/lang/dcl_emc1.jar");
-
- assertNotNull(jar);
- CallableStatement cs = prepareCall("CALL SQLJ.INSTALL_JAR(?, ?, 0)");
-
- cs.setString(1, jar.toExternalForm());
- cs.setString(2, "EMC.MAIL_APP");
- cs.executeUpdate();
- cs.close();
+ installJar("dcl_emc1.jar", "EMC.MAIL_APP");
testWithNoInstalledJars();
}
@@ -247,6 +271,260 @@
});
s.close();
+ }
+
+ /**
+ * check the roll back of class loading.
+ * install a new jar in a transaction, see
+ * that the new class is used and then rollback
+ * the old class should be used after the rollback.
+ * @throws SQLException
+ */
+ public void testClassPathRollback() throws SQLException
+ {
+ getConnection().setAutoCommit(false);
+ replaceJar("dcl_emc2.jar", "EMC.MAIL_APP");
+
+
+ // This version checks the e-mail address.
+ CallableStatement cs = prepareCall("CALL EMC.ADDCONTACT(?, ?)");
+ cs.setInt(1, 99);
+ cs.setString(2, "wormspam@soil.com");
+ cs.executeUpdate();
+
+ Statement s = createStatement();
+
+ JDBC.assertFullResultSet(
+ s.executeQuery("SELECT id, e_mail, ok from EMC.CONTACTS WHERE ID = 99"),
+ new String[][] {
+ {"99", "wormspam@soil.com", "0"},
+ });
+
+ rollback();
+ getConnection().setAutoCommit(true);
+
+ // execute again but reverted to the version that does not
+ // check the email address.
+ cs.executeUpdate();
+ cs.close();
+
+ JDBC.assertFullResultSet(
+ s.executeQuery("SELECT id, e_mail, ok from EMC.CONTACTS WHERE ID = 99"),
+ new String[][] {
+ {"99", "wormspam@soil.com", null},
+ });
+
+ s.executeUpdate("DELETE FROM EMC.CONTACTS WHERE ID = 99");
+ s.close();
+ }
+
+ /**
+ * Replace the jar to later test the prepare from a different
+ * connection picks up the new version.
+ * @throws SQLException
+ */
+ public void testReplaceJar() throws SQLException
+ {
+ replaceJar("dcl_emc2.jar", "EMC.MAIL_APP");
+ }
+
+ /**
+ * Change of class due to testReplaceJar that
+ * changes the application to run checks on the e-mail
+ * to ensure it is valid (in this case by seeing if
+ * it simply includes 'spam' in the title).
+ * @throws SQLException
+ */
+ public void testReplacedClass() throws SQLException {
+ // This version checks the e-mail address.
+ CallableStatement cs = prepareCall("CALL EMC.ADDCONTACT(?, ?)");
+ cs.setInt(1, 4);
+ cs.setString(2, "spammer@ripoff.com");
+ cs.executeUpdate();
+ cs.setInt(1, 5);
+ cs.setString(2, "open@source.org");
+ cs.executeUpdate();
+
+ Statement s = createStatement();
+ JDBC.assertFullResultSet(
+ s.executeQuery("SELECT id, e_mail, ok from EMC.CONTACTS ORDER BY 1"),
+ new String[][] {
+ {"0", "now@classpathchange.com", null},
+ {"1", "bill@ruletheworld.com", null},
+ {"2", "penguin@antartic.com", null},
+ {"3", "big@blue.com", null},
+ {"4", "spammer@ripoff.com", "0"},
+ {"5", "open@source.org", "1"},
+ });
+
+ s.close();
+ }
+
+ /**
+ * now add another jar in to test two jars and
+ * a quoted identifer for the jar names.
+ */
+ public void testSecondJar() throws SQLException {
+
+ installJar("dcl_emcaddon.jar", "\"emcAddOn\".\"MailAddOn\"");
+
+ setDBClasspath("EMC.MAIL_APP:\"emcAddOn\".\"MailAddOn\"");
+ Statement s = createStatement();
+ JDBC.assertFullResultSet(
+ s.executeQuery("SELECT E_MAIL, \"emcAddOn\".VALIDCONTACT(E_MAIL) FROM EMC.CONTACTS ORDER BY 1"),
+ new String[][] {
+ {"big@blue.com", "0"},
+ {"bill@ruletheworld.com", "0"},
+ {"now@classpathchange.com", "0"},
+ {"open@source.org", "1"},
+ {"penguin@antartic.com", "0"},
+ {"spammer@ripoff.com", "0"},
+ });
+
+ s.close();
+ }
+
+ /**
+ * Test to see if the jar signatures can be obtained from the jar file.
+ * The jar was signed with a self signed certificate
+ * <code>
+ keytool -delete -alias emccto -keystore emcks -storepass ab987c
+ keytool -genkey -dname "cn=EMC CTO, ou=EMC APP, o=Easy Mail Company, c=US" -alias emccto -keypass kpi135 -keystore emcks -storepass ab987c
+ keytool -selfcert -alias emccto -keypass kpi135 -validity 36500 -keystore emcks -storepass ab987c
+ keytool -keystore emcks -storepass ab987c -list -v
+ jarsigner -keystore emcks -storepass ab987c -keypass kpi135 -signedjar dcl_emc2s.jar dcl_emc2.jar emccto
+ keytool -delete -alias emccto -keystore emcks -storepass ab987c
+ </code>
+ * @throws SQLException
+ */
+ public void testSignedJar() throws SQLException
+ {
+ // Statement to get the signers for a class loaded from a jar file
+ PreparedStatement ps = prepareStatement("VALUES EMC.GETSIGNERS(?)");
+
+ // current jar is unsigned.
+ ps.setString(1, "org.apache.derbyTesting.databaseclassloader.emc");
+ JDBC.assertSingleValueResultSet(ps.executeQuery(), null);
+
+ // replace with a signed jar
+ replaceJar("dcl_emc2s.jar", "EMC.MAIL_APP");
+
+ ps.close();
+ ps = prepareStatement("VALUES EMC.GETSIGNERS(?)");
+ ps.setString(1, "org.apache.derbyTesting.databaseclassloader.emc");
+
+ // now class is signed
+ JDBC.assertSingleValueResultSet(ps.executeQuery(),
+ "CN=EMC CTO, OU=EMC APP, O=Easy Mail Company, C=US");
+
+ // verify the other jar is still not signed
+ ps.setString(1, "org.apache.derbyTesting.databaseclassloader.addon.vendor.util");
+ JDBC.assertSingleValueResultSet(ps.executeQuery(), null);
+
+ ps.close();
+ }
+
+ /**
+ * Replace the signed jar with a hacked jar. emc.class modified to diable
+ * valid e-mail address check but using same signatures within jar.
+ * Class loader should reject.
+ *
+ * rejects it.
+ * @throws SQLException
+ */
+ public void testHackedJarReplacedClass() throws SQLException {
+
+ replaceJar("dcl_emc2sm.jar", "EMC.MAIL_APP");
+
+ try {
+ CallableStatement cs = prepareCall("CALL EMC.ADDCONTACT(?, ?)");
+ cs.setInt(1, 99);
+ cs.setString(2, "spamking@cracker.org");
+ cs.executeUpdate();
+ cs.close();
+ fail("procedure call worked on hacked jar");
+ } catch (SQLException e) {
+ assertSQLState("Class load should fail due to invalid signature", "42X51", e);
+ }
+ }
+
+ /**
+ * replace with a hacked jar file, emc.class modified to
+ be an invalid class (no signing on this jar).
+ */
+ public void testInvalidJar() throws SQLException
+ {
+ replaceJar("dcl_emc2l.jar", "EMC.MAIL_APP");
+
+ try {
+ CallableStatement cs = prepareCall("CALL EMC.ADDCONTACT(?, ?)");
+ cs.setInt(1, 999);
+ cs.setString(2, "spamking2@cracker.org");
+ cs.executeUpdate();
+ cs.close();
+ fail("procedure call worked on invalid jar");
+ } catch (SQLException e) {
+ assertSQLState("Class load should fail due to invalid jar", "42X51", e);
+
+ }
+ }
+
+ public void testRemoveJar() throws SQLException
+ {
+ CallableStatement cs = prepareCall("CALL SQLJ.REMOVE_JAR(?, 0)");
+
+ cs.setString(1, "EMC.MAIL_APP");
+
+ // fail if jar is on classpath
+ try {
+ cs.executeUpdate();
+ fail("REMOVE_JAR on jar in derby.database.classpath worked");
+ } catch (SQLException e) {
+ assertSQLState("X0X07", e);
+ }
+
+ // remove from classpath
+ setDBClasspath("\"emcAddOn\".\"MailAddOn\"");
+ testWithNoInstalledJars();
+ cs.executeUpdate();
+ testWithNoInstalledJars();
+
+ // remove the second jar
+ setDBClasspath(null);
+ cs.setString(1, "\"emcAddOn\".\"MailAddOn\"");
+ cs.executeUpdate();
+
+ cs.close();
+ }
+
+ private void installJar(String resource, String jarName) throws SQLException
+ {
+ URL jar =
+ getTestResource(
+ "org/apache/derbyTesting/functionTests/tests/lang/" + resource);
+
+ assertNotNull(resource, jar);
+
+ CallableStatement cs = prepareCall("CALL SQLJ.INSTALL_JAR(?, ?, 0)");
+ cs.setString(1, jar.toExternalForm());
+ cs.setString(2, jarName);
+ cs.executeUpdate();
+ cs.close();
+ }
+
+ private void replaceJar(String resource, String jarName) throws SQLException
+ {
+ URL jar =
+ getTestResource(
+ "org/apache/derbyTesting/functionTests/tests/lang/" + resource);
+
+ assertNotNull(resource, jar);
+
+ CallableStatement cs = prepareCall("CALL SQLJ.REPLACE_JAR(?, ?)");
+ cs.setString(1, jar.toExternalForm());
+ cs.setString(2, jarName);
+ cs.executeUpdate();
+ cs.close();
}
private void setDBClasspath(String cp) throws SQLException
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java?view=diff&rev=472704&r1=472703&r2=472704
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java Wed Nov 8 15:51:46 2006
@@ -59,7 +59,7 @@
// suite.addTest(largeCodeGen.suite());
- //suite.addTest(DatabaseClassLoadingTest.suite());
+ suite.addTest(DatabaseClassLoadingTest.suite());
suite.addTest(GroupByExpressionTest.suite());
suite.addTest(LangScripts.suite());
suite.addTest(MathTrigFunctionsTest.suite());