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