001 /* 002 * Copyright 2001-2002,2004 The Apache Software Foundation 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 */ 017 package org.apache.tools.ant.taskdefs; 018 019 import java.sql.Driver; 020 import java.sql.Connection; 021 import java.sql.SQLException; 022 import java.sql.DriverPropertyInfo; 023 import java.util.Properties; 024 import java.io.File; 025 import java.net.URL; 026 027 import junit.framework.TestCase; 028 029 import org.apache.tools.ant.Project; 030 import org.apache.tools.ant.BuildException; 031 032 /** 033 * Simple testcase to test for driver caching. 034 * To test for your own database, you may need to tweak getProperties(int) 035 * and add a couple of keys. see testOracle and testMySQL for an example. 036 * 037 * It would be much better to extend this testcase by using HSQL 038 * as the test db, so that a db is really used. 039 * 040 */ 041 public class SQLExecTest extends TestCase { 042 043 // some database keys, see #getProperties(int) 044 public final static int NULL = 0; 045 public final static int ORACLE = 1; 046 public final static int MYSQL = 2; 047 048 // keys used in properties. 049 public final static String DRIVER = "driver"; 050 public final static String USER = "user"; 051 public final static String PASSWORD = "password"; 052 public final static String URL = "url"; 053 public final static String PATH = "path"; 054 public final static String SQL = "sql"; 055 056 public SQLExecTest(String s) { 057 super(s); 058 } 059 060 protected void setUp() throws Exception { 061 // make sure the cache is cleared. 062 SQLExec.getLoaderMap().clear(); 063 } 064 065 // simple test to ensure that the caching does work... 066 public void testDriverCaching(){ 067 SQLExec sql = createTask(getProperties(NULL)); 068 assertTrue(!SQLExec.getLoaderMap().containsKey(NULL_DRIVER)); 069 try { 070 sql.execute(); 071 } catch (BuildException e){ 072 assertTrue(e.getException().getMessage().indexOf("No suitable Driver") != -1); 073 } 074 assertTrue(SQLExec.getLoaderMap().containsKey(NULL_DRIVER)); 075 assertSame(sql.getLoader(), SQLExec.getLoaderMap().get(NULL_DRIVER)); 076 ClassLoader loader1 = sql.getLoader(); 077 078 // 2nd run.. 079 sql = createTask(getProperties(NULL)); 080 // the driver must still be cached. 081 assertTrue(sql.getLoaderMap().containsKey(NULL_DRIVER)); 082 try { 083 sql.execute(); 084 } catch (BuildException e){ 085 assertTrue(e.getException().getMessage().indexOf("No suitable Driver") != -1); 086 } 087 assertTrue(sql.getLoaderMap().containsKey(NULL_DRIVER)); 088 assertSame(sql.getLoader(), sql.getLoaderMap().get(NULL_DRIVER)); 089 assertSame(loader1, sql.getLoader()); 090 } 091 092 public void testNull() throws Exception { 093 doMultipleCalls(1000, NULL, true, true); 094 } 095 096 /* 097 public void testOracle(){ 098 doMultipleCalls(1000, ORACLE, true, false); 099 }*/ 100 101 /* 102 public void testMySQL(){ 103 doMultipleCalls(1000, MYSQL, true, false); 104 }*/ 105 106 107 /** 108 * run a sql tasks multiple times. 109 * @param calls number of times to execute the task 110 * @param database the database to execute on. 111 * @param caching should caching be enabled ? 112 * @param catchexception true to catch exception for each call, false if not. 113 */ 114 protected void doMultipleCalls(int calls, int database, boolean caching, boolean catchexception){ 115 Properties props = getProperties(database); 116 for (int i = 0; i < calls; i++){ 117 SQLExec sql = createTask(props); 118 sql.setCaching(caching); 119 try { 120 sql.execute(); 121 } catch (BuildException e){ 122 if (!catchexception){ 123 throw e; 124 } 125 } 126 } 127 } 128 129 /** 130 * Create a task from a set of properties 131 * @see #getProperties(int) 132 */ 133 protected SQLExec createTask(Properties props){ 134 SQLExec sql = new SQLExec(); 135 sql.setProject( new Project() ); 136 sql.setDriver( props.getProperty(DRIVER) ); 137 sql.setUserid( props.getProperty(USER) ); 138 sql.setPassword( props.getProperty(PASSWORD) ); 139 sql.setUrl( props.getProperty(URL) ); 140 sql.createClasspath().setLocation( new File(props.getProperty(PATH)) ); 141 sql.addText( props.getProperty(SQL) ); 142 return sql; 143 } 144 145 /** 146 * try to find the path from a resource (jar file or directory name) 147 * so that it can be used as a classpath to load the resource. 148 */ 149 protected String findResourcePath(String resource){ 150 resource = resource.replace('.', '/') + ".class"; Rate151 URL url = getClass().getClassLoader().getResource(resource); 152 if (url == null) { 153 return null; 154 } 155 String u = url.toString(); 156 if (u.startsWith("jar:file:")) { 157 int pling = u.indexOf("!"); 158 return u.substring("jar:file:".length(), pling); 159 } else if (u.startsWith("file:")) { 160 int tail = u.indexOf(resource); 161 return u.substring("file:".length(), tail); 162 } 163 return null; 164 } 165 166 /** 167 * returns a configuration associated to a specific database. 168 * If you want to test on your specific base, you'd better 169 * tweak this to make it run or add your own database. 170 * The driver lib should be dropped into the system classloader. 171 */ 172 protected Properties getProperties(int database){ 173 Properties props = null; 174 switch (database){ 175 case ORACLE: 176 props = getProperties("oracle.jdbc.driver.OracleDriver", "test", "test", "jdbc:oracle:thin:@127.0.0.1:1521:orcl"); 177 break; 178 case MYSQL: 179 props = getProperties("org.gjt.mm.mysql.Driver", "test", "test", "jdbc:mysql://127.0.0.1:3306/test"); 180 break; 181 case NULL: 182 default: 183 props = getProperties(NULL_DRIVER, "test", "test", "jdbc:database://hostname:port/name"); 184 } 185 // look for the driver path... 186 String path = findResourcePath(props.getProperty(DRIVER)); 187 props.put(PATH, path); 188 props.put(SQL, "create table OOME_TEST(X INTEGER NOT NULL);\ndrop table if exists OOME_TEST;"); 189 return props; 190 } 191 192 /** helper method to build properties */ 193 protected Properties getProperties(String driver, String user, String pwd, String url){ 194 Properties props = new Properties(); 195 props.put(DRIVER, driver); 196 props.put(USER, user); 197 props.put(PASSWORD, pwd); 198 props.put(URL, url); 199 return props; 200 } 201 202 203 //--- NULL JDBC driver just for simple test since there are no db driver 204 // available as a default in Ant :) 205 206 public final static String NULL_DRIVER = NullDriver.class.getName(); 207 208 public static class NullDriver implements Driver { 209 public Connection connect(String url, Properties info) 210 throws SQLException { 211 return null; 212 } 213 214 public boolean acceptsURL(String url) throws SQLException { 215 return false; 216 } 217 218 public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) 219 throws SQLException { 220 return new DriverPropertyInfo[0]; 221 } 222 223 public int getMajorVersion() { 224 return 0; 225 } 226 227 public int getMinorVersion() { 228 return 0; 229 } 230 231 public boolean jdbcCompliant() { 232 return false; 233 } 234 } 235 236 }