001: /*
002:
003: Derby - Class org.apache.derby.jdbc.EmbeddedDriver
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to You under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derbyTesting.functionTests.tests.jdbcapi;
023:
024: import org.apache.derbyTesting.functionTests.util.TestUtil;
025:
026: import java.io.File;
027: import java.sql.DatabaseMetaData;
028: import java.sql.Driver;
029: import java.sql.DriverManager;
030: import java.sql.Connection;
031: import java.sql.ResultSet;
032: import java.sql.SQLException;
033: import java.util.Properties;
034: import org.apache.derby.tools.JDBCDisplayUtil;
035:
036: /**
037: * @author marsden
038: *
039: * This test tests java.sql.Driver methods.
040: * Right now it just tests acceptsURL and some attributes
041: * Tests for getPropertyInfo need to be added. as well as connection attributes
042: *
043: */
044:
045: public class checkDriver {
046:
047: private static String hostName;
048: private static String EMBEDDED_URL = "jdbc:derby:wombat;create=true";
049: private static String CLIENT_URL;
050: private static String JCC_URL;
051: private static String INVALID_URL = "jdbc:db2j:wombat;create=true";
052:
053: private static String DERBY_SYSTEM_HOME = System
054: .getProperty("derby.system.home");
055:
056: private static String CLIENT_URL_WITH_COLON1;
057: private static String CLIENT_URL_WITH_COLON2;
058: private static String CLIENT_URL_WITH_DOUBLE_QUOTES1;
059: private static String CLIENT_URL_WITH_DOUBLE_QUOTES2;
060: private static String CLIENT_URL_WITH_SINGLE_QUOTES1;
061: private static String CLIENT_URL_WITH_SINGLE_QUOTES2;
062:
063: // DERBY-618 - Database name with spaces
064: private static String DB_NAME_WITH_SPACES = "db name with spaces";
065: private static String EMBEDDED_URL_WITH_SPACES = "jdbc:derby:"
066: + DB_NAME_WITH_SPACES + ";create=true";
067: private static String CLIENT_URL_WITH_SPACES;
068: private static String JCC_URL_WITH_SPACES;
069:
070: /**
071: * url prefix for this framework
072: */
073: private static String frameworkPrefix;
074:
075: // The acceptsURLTable uses the frameworkOffset column int he table
076: // to check for valid results for each framework
077: private static int frameworkOffset;
078:
079: private static int EMBEDDED_OFFSET = 0;
080: private static int DERBYNETCLIENT_OFFSET = 1;
081: private static int DERBYNET_OFFSET = 2; // JCC
082:
083: static {
084: frameworkPrefix = TestUtil.getJdbcUrlPrefix();
085: if (TestUtil.isEmbeddedFramework())
086: frameworkOffset = EMBEDDED_OFFSET;
087: else if (TestUtil.isDerbyNetClientFramework())
088: frameworkOffset = DERBYNETCLIENT_OFFSET;
089: else if (TestUtil.isJCCFramework())
090: frameworkOffset = DERBYNET_OFFSET; // JCC
091:
092: hostName = TestUtil.getHostName();
093: CLIENT_URL = "jdbc:derby://" + hostName
094: + ":1527/wombat;create=true";
095: JCC_URL = "jdbc:derby:net://" + hostName
096: + ":1527/wombat;create=true";
097: CLIENT_URL_WITH_COLON1 = "jdbc:derby://" + hostName
098: + ":1527/wombat:create=true";
099: CLIENT_URL_WITH_COLON2 = "jdbc:derby://" + hostName + ":1527/"
100: + DERBY_SYSTEM_HOME + File.separator
101: + "wombat:create=true";
102: CLIENT_URL_WITH_DOUBLE_QUOTES1 = "jdbc:derby://" + hostName
103: + ":1527/\"wombat\";create=true";
104: CLIENT_URL_WITH_DOUBLE_QUOTES2 = "jdbc:derby://" + hostName
105: + ":1527/\"" + DERBY_SYSTEM_HOME + File.separator
106: + "wombat\";create=true";
107: CLIENT_URL_WITH_SINGLE_QUOTES1 = "jdbc:derby://" + hostName
108: + ":1527/'" + DERBY_SYSTEM_HOME + File.separator
109: + "wombat';create=true";
110: CLIENT_URL_WITH_SINGLE_QUOTES2 = "jdbc:derby://" + hostName
111: + ":1527/'wombat';create=true";
112:
113: CLIENT_URL_WITH_SPACES = "jdbc:derby://" + hostName + ":1527/"
114: + DB_NAME_WITH_SPACES + ";create=true";
115: JCC_URL_WITH_SPACES = "jdbc:derby:net://" + hostName + ":1527/"
116: + DB_NAME_WITH_SPACES + ";create=true";
117: }
118:
119: // URLS to check. New urls need to also be added to the acceptsUrl table
120: private static String[] urls = new String[] { EMBEDDED_URL,
121: CLIENT_URL, JCC_URL, INVALID_URL, };
122:
123: //Client URLS
124: private static String[] clientUrls = new String[] {
125: CLIENT_URL_WITH_COLON1,
126: //CLIENT_URL_WITH_COLON2,
127: //CLIENT_URL_WITH_DOUBLE_QUOTES1,
128: //CLIENT_URL_WITH_DOUBLE_QUOTES2,
129: //CLIENT_URL_WITH_SINGLE_QUOTES1,
130: CLIENT_URL_WITH_SINGLE_QUOTES2 };
131:
132: // Table that shows whether tested urls should return true for acceptsURL
133: // under the given framework
134: private static boolean[][] acceptsURLTable = new boolean[][] {
135: // Framework/url EMBEDDED DERBYNETCLIENT DERBYNET (JCC)
136: /*EMBEDDED_URL */{ true, false, false },
137: /*CLIENT_URL */{ false, true, false },
138: /* JCC_URL */{ false, false, true },
139: /* INVALID_URL */{ false, false, false } };
140:
141: public static void main(String[] args) {
142:
143: try {
144: Driver driver = loadAndCheckDriverForFramework();
145: checkAcceptsURL(driver);
146: testEmbeddedAttributes(driver);
147: testClientAttributes(driver);
148: doClientURLTest(driver);
149: testDbNameWithSpaces(driver);
150: } catch (SQLException se) {
151: while (se != null) {
152: se.printStackTrace(System.out);
153: se = se.getNextException();
154: }
155: } catch (Throwable e) {
156: e.printStackTrace(System.out);
157: }
158:
159: }
160:
161: /**
162: * Tests that client side attributes cann be specified in either url or info argument to connect.
163: * DERBY"-530.
164: *
165: * TODO: Add more comprehensive client attribute testing and enhance to handle jcc attributes in url.
166: *
167: * @param driver
168: */
169: private static void testClientAttributes(Driver driver)
170: throws SQLException {
171: if (!TestUtil.isDerbyNetClientFramework())
172: return;
173:
174: System.out.println("\ntestClientAttributes()");
175: Properties info = new Properties();
176:
177: // Note: we have to put the trace file in an absolute path because the
178: // test harness sets user.dir and this confuses the File api greatly.
179: // We put it in DERBY_SYSTEM_HOME since that is always available when
180: // tests are run
181: String traceDirectory = DERBY_SYSTEM_HOME + File.separator;
182: String traceFile = traceDirectory + "trace.out";
183:
184: // traceFile attribute in url
185: testConnect(driver, frameworkPrefix + "testpropdb;traceFile="
186: + traceFile, info);
187: assertTraceFileExists(traceFile);
188:
189: traceFile = traceDirectory + "trace2.out";
190:
191: // traceFile attribute in property
192: info.setProperty("traceFile", traceFile);
193: testConnect(driver, frameworkPrefix + "testpropdb", info);
194: assertTraceFileExists(traceFile);
195:
196: }
197:
198: /**
199: * Check that trace file exists in <framework> directory
200: *
201: * @param filename Name of trace file
202: */
203: private static void assertTraceFileExists(String filename) {
204: File traceFile = new File(filename);
205: //System.out.println("user.dir=" + System.getProperty("user.dir"));
206: //System.out.println("fullpath = " + traceFile.getAbsolutePath());
207: boolean exists = traceFile.exists();
208: if (!exists)
209: new Exception("FAILED trace file: " + filename
210: + " does not exist").printStackTrace(System.out);
211: else
212: System.out.println(" trace file exists");
213:
214: }
215:
216: /**
217: * Tests that embedded attributes can be specified in either url or info argument to connect
218: * DERBY-530. Only valid for emebedded driver and client. JCC has a different url format for
219: * embedded attributes
220: *
221: * @param driver
222: */
223: private static void testEmbeddedAttributes(Driver driver)
224: throws SQLException {
225: // JCC can't take embedded attributes in info or as normal url attributes,
226: // so not tested here.
227: if (TestUtil.isJCCFramework())
228: return;
229:
230: System.out.println("\ntestEmbeddedAttributes()");
231: Properties info = new Properties();
232: // create attribute as property
233: info.setProperty("create", "true");
234: testConnect(driver, frameworkPrefix + "testcreatedb1", info);
235:
236: // create attribute in url
237: testConnect(driver, frameworkPrefix
238: + "testcreatedb2;create=true", null);
239:
240: // user/password in properties
241: // testpropdb was created in load and test driver
242: info.clear();
243: info.setProperty("user", "APP");
244: info.setProperty("password", "xxxx");
245: testConnect(driver, frameworkPrefix + "testpropdb", info);
246:
247: // user/password in url
248: testConnect(driver, frameworkPrefix
249: + "testpropdb;user=testuser;password=testpass", null);
250:
251: // user in url, password in property
252: info.clear();
253: info.setProperty("password", "testpass");
254: testConnect(driver,
255: frameworkPrefix + "testpropdb;user=testusr", info);
256:
257: // different users in url and in properties. URL is the winner
258: info.clear();
259: info.setProperty("user", "APP");
260: info.setProperty("password", "xxxx");
261: testConnect(driver, frameworkPrefix
262: + "testpropdb;user=testuser;password=testpass", null);
263:
264: // shutdown with properties
265: info.clear();
266: info.setProperty("shutdown", "true");
267: try {
268: testConnect(driver, frameworkPrefix + "testcreatedb1", info);
269: } catch (SQLException se) {
270: System.out.println("Expected Exception:" + se.getSQLState()
271: + ":" + se.getMessage());
272: }
273: }
274:
275: /**
276: * Check that drivers accept the correct urls and reject those for other supported drivers.
277: *
278: * @param driver driver we are testing.
279: *
280: * @throws SQLException
281: */
282: private static void checkAcceptsURL(Driver driver)
283: throws SQLException {
284: for (int u = 0; u < urls.length; u++) {
285: String url = urls[u];
286: //System.out.println("acceptsURLTable[" + u +"][" + frameworkOffset+ "]");
287: boolean expectedAcceptance = acceptsURLTable[u][frameworkOffset];
288: boolean actualAcceptance = driver.acceptsURL(url);
289: System.out.println("checking acceptsURL(" + url + ")");
290: assertExpectedURLAcceptance(url, expectedAcceptance,
291: actualAcceptance);
292:
293: }
294:
295: }
296:
297: /**
298: * Load the driver and check java.sql.Driver methods,
299: * @return
300: * @throws Exception
301: */
302: private static Driver loadAndCheckDriverForFramework()
303: throws Exception {
304: TestUtil.loadDriver();
305: String frameworkURL = TestUtil.getJdbcUrlPrefix()
306: + "testpropdb;create=true";
307:
308: // Test that we loaded the right driver by making a connection
309: Driver driver = DriverManager.getDriver(frameworkURL);
310: Properties props = new Properties();
311: props.put("user", "testuser");
312: props.put("password", "testpass");
313: Connection conn = DriverManager.getConnection(frameworkURL,
314: props);
315: DatabaseMetaData dbmd = conn.getMetaData();
316: System.out.println("jdbcCompliant() = "
317: + driver.jdbcCompliant());
318:
319: // Just check versions against database metadata to avoid more master updates.
320: // Metadata test prints the actual version.
321:
322: int majorVersion = driver.getMajorVersion();
323: if (majorVersion == dbmd.getDriverMajorVersion())
324: System.out
325: .println("driver.getMajorVersion() = EXPECTED VERSION");
326: else
327: new Exception(
328: "FAILED: unexpected value for getMajorVersion(): "
329: + majorVersion).printStackTrace();
330:
331: int minorVersion = driver.getMinorVersion();
332: if (minorVersion == dbmd.getDriverMinorVersion())
333: System.out
334: .println("driver.getMinorVersion() = EXPECTED VERSION");
335: else
336: new Exception(
337: "FAILED: unexpected value for getMinorVersion()"
338: + minorVersion).printStackTrace(System.out);
339:
340: conn.close();
341: return driver;
342: }
343:
344: /**
345: * Check the actual return value of acceptsURL against the expected value and error and stack
346: * trace if they don't match
347: *
348: * @param url URL that was checked for acceptsURL
349: * @param expectedAcceptance expected return value
350: * @param actualAcceptance actual return value
351: *
352: */
353: private static void assertExpectedURLAcceptance(String url,
354: boolean expectedAcceptance, boolean actualAcceptance) {
355: if (actualAcceptance != expectedAcceptance) {
356: new Exception("FAILED acceptsURL check. url = " + url
357: + " expectedAcceptance = " + expectedAcceptance
358: + " actualAcceptance = " + actualAcceptance)
359: .printStackTrace(System.out);
360: }
361:
362: }
363:
364: /**
365: * Tests client URLs to see connection is successful or the correct exception is thrown.
366: *
367: * @param driver
368: * @throws SQLException
369: */
370: private static void doClientURLTest(Driver driver) {
371: if (!TestUtil.isDerbyNetClientFramework())
372: return;
373:
374: System.out.println("doClientURLTest()");
375: Properties info = null; //test with null Properties object
376:
377: for (int i = 0; i < clientUrls.length; i++) {
378: String url = clientUrls[i];
379: System.out.println("doClientURLTest with url: "
380: + replaceSystemHome(url));
381: try {
382: Connection conn = testConnect(driver, url, info);
383: if (conn != null)
384: System.out
385: .println("PASSED:Connection Successful with url: "
386: + replaceSystemHome(url));
387: } catch (SQLException se) {
388: System.out.println("EXPECTED EXCEPTION:"
389: + replaceSystemHome(se.getMessage()));
390: }
391: }
392: }
393:
394: /**
395: * Tests URL with spaces in database name to check create and connect works.
396: * (DERBY-618). Make sure that the specified database gets created. We need
397: * to check this because even without the patch for DERBY-618, no exception
398: * gets thrown when we try to connect to a database name with spaces.
399: * Instead, client driver extracts the database name as the string before
400: * the first occurence of space separator. Hence the database which gets
401: * created is wrong. e.g, if we specified database name as
402: * "db name with spaces", the database that got created by client driver
403: * was "db", which was wrong. We can check this by checking the correct URL
404: * is returned by call to conn.getMetaData().getURL(). This is currently
405: * checked inside the testConnect method. We do not explicilty check the
406: * database directory creation since this check fails in remote server
407: * testing.
408: *
409: * @param driver
410: * @throws SQLException
411: */
412: private static void testDbNameWithSpaces(Driver driver)
413: throws SQLException {
414: System.out.println("START testDbNameWithSpaces ...");
415:
416: Connection conn = null;
417: Properties info = null;
418: String url = null;
419:
420: if (TestUtil.isEmbeddedFramework())
421: url = EMBEDDED_URL_WITH_SPACES;
422: else if (TestUtil.isDerbyNetClientFramework())
423: url = CLIENT_URL_WITH_SPACES;
424: else if (TestUtil.isJCCFramework()) {
425: url = JCC_URL_WITH_SPACES;
426: // JCC requires user and password
427: info = new Properties();
428: info.put("user", "tester");
429: info.put("password", "testpass");
430: }
431:
432: conn = testConnect(driver, url, info);
433: if (conn != null)
434: System.out
435: .println("PASSED:Connection Successful with url: "
436: + url);
437: }
438:
439: /**
440: * Make java.sql.Driver.connect(String url, Properties info call) and print the status of
441: * the connection.
442: *
443: * @param driver driver for framework
444: * @param url url to pass to Driver.connect()
445: * @param info properties to pass to Driver.Connect()
446: *
447: * @throws SQLException on error.
448: */
449: private static Connection testConnect(Driver driver, String url,
450: Properties info) throws SQLException {
451: String infoString = null;
452: if (info != null)
453: infoString = replaceSystemHome(info.toString());
454: String urlString = replaceSystemHome(url);
455: Connection conn = driver.connect(url, info);
456:
457: if (conn == null) {
458: System.out.println("Null connection returned for url "
459: + urlString);
460: return conn;
461: }
462:
463: System.out.println("\nConnection info for connect(" + urlString
464: + ", " + infoString + ")");
465: String getUrlValue = conn.getMetaData().getURL();
466: // URL may include path of DERBY_SYSTEM_HOME for traceFile
467: // filter it out.
468: getUrlValue = replaceSystemHome(getUrlValue);
469: System.out.println("getURL() = " + getUrlValue);
470: System.out.println("getUserName() = "
471: + conn.getMetaData().getUserName());
472: // CURRENT SCHEMA should match getUserName()
473: ResultSet rs = conn.createStatement().executeQuery(
474: "VALUES(CURRENT SCHEMA)");
475: rs.next();
476: System.out.println("CURRENT SCHEMA = " + rs.getString(1));
477: conn.close();
478: return conn;
479: }
480:
481: /**
482: * @param origString
483: *
484: * @return origString with derby.system.home path replaed with [DERBY_SYSTEM_HOME]
485: */
486: private static String replaceSystemHome(String origString) {
487: String replaceString = DERBY_SYSTEM_HOME + File.separator;
488: int offset = origString.indexOf(replaceString);
489: if (offset == -1)
490: return origString;
491: else
492: return origString.substring(0, offset)
493: + "[DERBY_SYSTEM_HOME]/"
494: + origString.substring(offset
495: + replaceString.length());
496: }
497:
498: }
|