1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package org.apache.harmony.sql.tests.java.sql;
19
20import java.io.ByteArrayOutputStream;
21import java.io.IOException;
22import java.io.PrintStream;
23import java.io.PrintWriter;
24import java.lang.reflect.Method;
25import java.security.Permission;
26import java.sql.Connection;
27import java.sql.Driver;
28import java.sql.DriverManager;
29import java.sql.DriverPropertyInfo;
30import java.sql.SQLException;
31import java.sql.SQLPermission;
32import java.util.Enumeration;
33import java.util.Properties;
34import tests.support.Support_Exec;
35
36import junit.framework.TestCase;
37
38/**
39 * JUnit Testcase for the java.sql.DriverManager class
40 *
41 */
42public class DriverManagerTest extends TestCase {
43
44    // Set of driver names to use
45    static final String DRIVER1 = "org.apache.harmony.sql.tests.java.sql.TestHelper_Driver1";
46
47    static final String DRIVER2 = "org.apache.harmony.sql.tests.java.sql.TestHelper_Driver2";
48
49    static final String DRIVER3 = "org.apache.harmony.sql.tests.java.sql.TestHelper_Driver3";
50
51    static final String DRIVER4 = "org.apache.harmony.sql.tests.java.sql.TestHelper_Driver4";
52
53    static final String DRIVER5 = "org.apache.harmony.sql.tests.java.sql.TestHelper_Driver5";
54
55    static final String INVALIDDRIVER1 = "abc.klm.Foo";
56
57    static String[] driverNames = { DRIVER1, DRIVER2, DRIVER4, DRIVER5 };
58
59    static int numberLoaded;
60
61    static String baseURL1 = "jdbc:mikes1";
62
63    static String baseURL4 = "jdbc:mikes4";
64
65    static final String JDBC_PROPERTY = "jdbc.drivers";
66
67    static TestHelper_ClassLoader testClassLoader = new TestHelper_ClassLoader();
68
69    // Static initializer to load the drivers so that they are available to all
70    // the
71    // test methods as needed.
72    @Override
73    public void setUp() {
74        numberLoaded = loadDrivers();
75    } // end setUp()
76
77    /**
78     * Test for the method DriverManager.deregisterDriver
79     *
80     * @throws SQLException
81     */
82    public void testDeregisterDriver() throws Exception {
83        // First get one of the drivers loaded by the test
84        Driver aDriver;
85        aDriver = DriverManager.getDriver(baseURL4);
86
87        // Deregister this driver
88        DriverManager.deregisterDriver(aDriver);
89
90        assertFalse("testDeregisterDriver: Driver was not deregistered.",
91                isDriverLoaded(aDriver));
92
93        // Re-register this driver (so subsequent tests have it available)
94        DriverManager.registerDriver(aDriver);
95        assertTrue("testDeregisterDriver: Driver did not reload.",
96                isDriverLoaded(aDriver));
97
98        // Test deregistering a null driver
99        DriverManager.deregisterDriver(null);
100
101        // Test deregistering a driver which was not loaded by this test's
102        // classloader
103        // TODO - need to load a driver with a different classloader!!
104        aDriver = DriverManager.getDriver(baseURL1);
105
106        Class<?> driverClass = Class
107                .forName(
108                        "org.apache.harmony.sql.tests.java.sql.TestHelper_DriverManager",
109                        true, testClassLoader);
110
111        // Give the Helper class one of our drivers....
112        Class<?>[] methodClasses = { Class.forName("java.sql.Driver") };
113        Method theMethod = driverClass.getDeclaredMethod("setDriver",
114                methodClasses);
115        Object[] args = { aDriver };
116        theMethod.invoke(null, args);
117
118        // Check that the driver was not deregistered
119        assertTrue(
120                "testDeregisterDriver: Driver was incorrectly deregistered.",
121                DriverManagerTest.isDriverLoaded(aDriver));
122
123    } // end method testDeregisterDriver()
124
125    static void printClassLoader(Object theObject) {
126        Class<? extends Object> theClass = theObject.getClass();
127        ClassLoader theClassLoader = theClass.getClassLoader();
128        System.out.println("ClassLoader is: " + theClassLoader.toString()
129                + " for object: " + theObject.toString());
130    } // end method printClassLoader( Object )
131
132    static boolean isDriverLoaded(Driver theDriver) {
133        Enumeration<?> driverList = DriverManager.getDrivers();
134        while (driverList.hasMoreElements()) {
135            if ((Driver) driverList.nextElement() == theDriver) {
136                return true;
137            }
138        } // end while
139        return false;
140    } // end method isDriverLoaded( Driver )
141
142    /*
143     * Class under test for Connection getConnection(String)
144     */
145    // valid connection - data1 does not require a user and password...
146    static String validConnectionURL = "jdbc:mikes1:data1";
147
148    // invalid connection - data2 requires a user & password
149    static String invalidConnectionURL1 = "jdbc:mikes1:data2";
150
151    // invalid connection - URL is gibberish
152    static String invalidConnectionURL2 = "xyz1:abc3:456q";
153
154    // invalid connection - URL is null
155    static String invalidConnectionURL3 = null;
156
157    static String[] invalidConnectionURLs = { invalidConnectionURL2,
158            invalidConnectionURL3 };
159
160    public void testGetConnectionString() throws SQLException {
161        Connection theConnection = null;
162        // validConnection - no user & password required
163        theConnection = DriverManager.getConnection(validConnectionURL);
164        assertNotNull(theConnection);
165        assertNotNull(DriverManager.getConnection(invalidConnectionURL1));
166
167        for (String element : invalidConnectionURLs) {
168            try {
169                theConnection = DriverManager.getConnection(element);
170                fail("Should throw SQLException");
171            } catch (SQLException e) {
172                // expected
173            } // end try
174        } // end for
175    } // end method testGetConnectionString()
176
177    /**
178     * @tests java.sql.DriverManager#getConnection(String, Properties)
179     */
180    public void test_getConnection_LStringLProperties() {
181        try {
182            DriverManager.getConnection("fff", //$NON-NLS-1$
183                    new Properties());
184            fail("Should throw SQLException.");
185        } catch (SQLException e) {
186            assertEquals("08001", e.getSQLState()); //$NON-NLS-1$
187        }
188
189        try {
190            DriverManager.getConnection(null, new Properties());
191            fail("Should throw SQLException.");
192        } catch (SQLException e) {
193            assertEquals("08001", e.getSQLState()); //$NON-NLS-1$
194        }
195    }
196
197    /*
198     * Class under test for Connection getConnection(String, Properties)
199     */
200    public void testGetConnectionStringProperties() throws SQLException {
201        String validURL1 = "jdbc:mikes1:data2";
202        String validuser1 = "theuser";
203        String validpassword1 = "thepassword";
204        String invalidURL1 = "xyz:abc1:foo";
205        String invalidURL2 = "jdbc:mikes1:crazyone";
206        String invalidURL3 = "";
207        String invaliduser1 = "jonny nouser";
208        String invalidpassword1 = "whizz";
209        Properties nullProps = null;
210        Properties validProps = new Properties();
211        validProps.setProperty("user", validuser1);
212        validProps.setProperty("password", validpassword1);
213        Properties invalidProps1 = new Properties();
214        invalidProps1.setProperty("user", invaliduser1);
215        invalidProps1.setProperty("password", invalidpassword1);
216        String[] invalidURLs = { null, invalidURL1, invalidURL2, invalidURL3 };
217        Properties[] invalidProps = { nullProps, invalidProps1 };
218
219        Connection theConnection = null;
220        // validConnection - user & password required
221        theConnection = DriverManager.getConnection(validURL1, validProps);
222        assertNotNull(theConnection);
223
224        // invalid Connections
225        for (int i = 0; i < invalidURLs.length; i++) {
226            theConnection = null;
227            try {
228                theConnection = DriverManager.getConnection(invalidURLs[i],
229                        validProps);
230                fail("Should throw SQLException");
231            } catch (SQLException e) {
232                // expected
233            } // end try
234        } // end for
235        for (Properties invalidProp : invalidProps) {
236            assertNotNull(DriverManager.getConnection(validURL1, invalidProp));
237        }
238    } // end method testGetConnectionStringProperties()
239
240    /*
241     * Class under test for Connection getConnection(String, String, String)
242     */
243    public void testGetConnectionStringStringString() throws SQLException {
244        String validURL1 = "jdbc:mikes1:data2";
245        String validuser1 = "theuser";
246        String validpassword1 = "thepassword";
247        String invalidURL1 = "xyz:abc1:foo";
248        String invaliduser1 = "jonny nouser";
249        String invalidpassword1 = "whizz";
250        String[] invalid1 = { null, validuser1, validpassword1 };
251        String[] invalid2 = { validURL1, null, validpassword1 };
252        String[] invalid3 = { validURL1, validuser1, null };
253        String[] invalid4 = { invalidURL1, validuser1, validpassword1 };
254        String[] invalid5 = { validURL1, invaliduser1, invalidpassword1 };
255        String[] invalid6 = { validURL1, validuser1, invalidpassword1 };
256        String[][] invalids1 = { invalid1, invalid4 };
257        String[][] invalids2 = { invalid2, invalid3, invalid5, invalid6 };
258
259        Connection theConnection = null;
260        // validConnection - user & password required
261        theConnection = DriverManager.getConnection(validURL1, validuser1,
262                validpassword1);
263        assertNotNull(theConnection);
264        for (String[] theData : invalids1) {
265            theConnection = null;
266            try {
267                theConnection = DriverManager.getConnection(theData[0],
268                        theData[1], theData[2]);
269                fail("Should throw SQLException.");
270            } catch (SQLException e) {
271                // expected
272            } // end try
273        } // end for
274        for (String[] theData : invalids2) {
275            assertNotNull(DriverManager.getConnection(theData[0], theData[1],
276                    theData[2]));
277        }
278    } // end method testGetConnectionStringStringString()
279
280    static String validURL1 = "jdbc:mikes1";
281
282    static String validURL2 = "jdbc:mikes2";
283
284    static String invalidURL1 = "xyz:acb";
285
286    static String invalidURL2 = null;
287
288    static String[] validURLs = { validURL1, validURL2 };
289
290    static String[] invalidURLs = { invalidURL1, invalidURL2 };
291
292    static String exceptionMsg1 = "No suitable driver";
293
294    public void testGetDriver() throws SQLException {
295        for (String element : validURLs) {
296            Driver validDriver = DriverManager.getDriver(element);
297            assertNotNull(validDriver);
298        } // end for
299
300//      Comment out since it depends on the drivers providered
301//        for (String element : invalidURLs) {
302//            System.out.println(element);
303//            try {
304//                DriverManager.getDriver(element);
305//                fail("Should throw SQLException");
306//            } catch (SQLException e) {
307//                assertEquals("08001", e.getSQLState());
308//                assertEquals(exceptionMsg1, e.getMessage());
309//            } // end try
310//        } // end for
311
312    } // end method testGetDriver()
313
314    public void testGetDrivers() {
315        // Load a driver manager
316        Enumeration<Driver> driverList = DriverManager.getDrivers();
317        int i = 0;
318        while (driverList.hasMoreElements()) {
319            Driver theDriver = driverList.nextElement();
320            assertNotNull(theDriver);
321            i++;
322        } // end while
323
324        // Check that all the drivers are in the list...
325        // There might be other drivers loaded in other classes
326        assertTrue("testGetDrivers: Don't see all the loaded drivers - ",
327                i >= numberLoaded);
328    } // end method testGetDrivers()
329
330    static int timeout1 = 25;
331
332    public void testGetLoginTimeout() {
333        DriverManager.setLoginTimeout(timeout1);
334        assertEquals(timeout1, DriverManager.getLoginTimeout());
335    } // end method testGetLoginTimeout()
336
337    @SuppressWarnings("deprecation")
338    public void testGetLogStream() {
339        assertNull(DriverManager.getLogStream());
340
341        DriverManager.setLogStream(testPrintStream);
342        assertTrue(DriverManager.getLogStream() == testPrintStream);
343
344        DriverManager.setLogStream(null);
345    } // end method testGetLogStream()
346
347    public void testGetLogWriter() {
348        assertNull(DriverManager.getLogWriter());
349
350        DriverManager.setLogWriter(testPrintWriter);
351
352        assertTrue(DriverManager.getLogWriter() == testPrintWriter);
353
354        DriverManager.setLogWriter(null);
355    } // end method testGetLogWriter()
356
357    static String testMessage = "DriverManagerTest: test message for print stream";
358
359    @SuppressWarnings("deprecation")
360    public void testPrintln() {
361        // System.out.println("testPrintln");
362        DriverManager.println(testMessage);
363
364        DriverManager.setLogWriter(testPrintWriter);
365        DriverManager.println(testMessage);
366
367        String theOutput = outputStream.toString();
368        // System.out.println("testPrintln: output= " + theOutput );
369        assertTrue(theOutput.startsWith(testMessage));
370
371        DriverManager.setLogWriter(null);
372
373        DriverManager.setLogStream(testPrintStream);
374        DriverManager.println(testMessage);
375
376        theOutput = outputStream2.toString();
377        // System.out.println("testPrintln: output= " + theOutput );
378        assertTrue(theOutput.startsWith(testMessage));
379
380        DriverManager.setLogStream(null);
381    } // end method testPrintln()
382
383    public void testRegisterDriver() throws ClassNotFoundException,
384            SQLException, IllegalAccessException, InstantiationException {
385        String EXTRA_DRIVER_NAME = "org.apache.harmony.sql.tests.java.sql.TestHelper_Driver3";
386
387        try {
388            DriverManager.registerDriver(null);
389            fail("Should throw NullPointerException.");
390        } catch (NullPointerException e) {
391            // expected
392        } // end try
393
394        Driver theDriver = null;
395        // Load another Driver that isn't in the basic set
396        Class<?> driverClass = Class.forName(EXTRA_DRIVER_NAME);
397        theDriver = (Driver) driverClass.newInstance();
398        DriverManager.registerDriver(theDriver);
399
400        assertTrue("testRegisterDriver: driver not in loaded set",
401                isDriverLoaded(theDriver));
402
403    } // end testRegisterDriver()
404
405    static int validTimeout1 = 15;
406
407    static int validTimeout2 = 0;
408
409    static int[] validTimeouts = { validTimeout1, validTimeout2 };
410
411    static int invalidTimeout1 = -10;
412
413    public void testSetLoginTimeout() {
414        for (int element : validTimeouts) {
415            DriverManager.setLoginTimeout(element);
416
417            assertEquals(element, DriverManager.getLoginTimeout());
418        } // end for
419        // Invalid timeouts
420        DriverManager.setLoginTimeout(invalidTimeout1);
421        assertEquals(invalidTimeout1, DriverManager.getLoginTimeout());
422    } // end testSetLoginTimeout()
423
424    static ByteArrayOutputStream outputStream2 = new ByteArrayOutputStream();
425
426    static PrintStream testPrintStream = new PrintStream(outputStream2);
427
428    @SuppressWarnings("deprecation")
429    public void testSetLogStream() {
430        // System.out.println("testSetLogStream");
431        DriverManager.setLogStream(testPrintStream);
432
433        assertSame(testPrintStream, DriverManager.getLogStream());
434
435        DriverManager.setLogStream(null);
436
437        assertNull(DriverManager.getLogStream());
438    } // end method testSetLogStream()
439
440    static ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
441
442    static PrintWriter testPrintWriter = new PrintWriter(outputStream);
443
444    /**
445     * Test for the setLogWriter method
446     */
447    public void testSetLogWriter() {
448        // System.out.println("testSetLogWriter");
449        DriverManager.setLogWriter(testPrintWriter);
450
451        assertSame(testPrintWriter, DriverManager.getLogWriter());
452
453        DriverManager.setLogWriter(null);
454
455        assertNull("testDriverManager: Log writer not null:", DriverManager
456                .getLogWriter());
457    } // end method testSetLogWriter()
458
459    /*
460     * Method which loads a set of JDBC drivers ready for use by the various
461     * tests @return the number of drivers loaded
462     */
463    static boolean driversLoaded = false;
464
465    private static int loadDrivers() {
466        if (driversLoaded) {
467            return numberLoaded;
468        }
469        /*
470         * First define a value for the System property "jdbc.drivers" - before
471         * the DriverManager class is loaded - this property defines a set of
472         * drivers which the DriverManager will load during its initialization
473         * and which will be loaded on the System ClassLoader - unlike the ones
474         * loaded later by this method which are loaded on the Application
475         * ClassLoader.
476         */
477        int numberLoaded = 0;
478
479        for (String element : driverNames) {
480            try {
481                Class<?> driverClass = Class.forName(element);
482                assertNotNull(driverClass);
483                // System.out.println("Loaded driver - classloader = " +
484                // driverClass.getClassLoader());
485                numberLoaded++;
486            } catch (ClassNotFoundException e) {
487                System.out.println("DriverManagerTest: failed to load Driver: "
488                        + element);
489            } // end try
490        } // end for
491        /*
492         * System.out.println("DriverManagerTest: number of drivers loaded: " +
493         * numberLoaded);
494         */
495        driversLoaded = true;
496        return numberLoaded;
497    } // end method loadDrivers()
498
499    /**
500     * @tests {@link java.sql.DriverManager#registerDriver(Driver)}
501     *
502     * Registers a driver for multiple times and deregisters it only once.
503     *
504     * Regression for HARMONY-4205
505     */
506    public void test_registerDriver_MultiTimes() throws SQLException {
507        int register_count = 10;
508        int deregister_count = 1;
509
510        Driver dummy = new DummyDriver();
511        DriverManager.registerDriver(new BadDummyDriver());
512        for (int i = 0; i < register_count; i++) {
513            DriverManager.registerDriver(dummy);
514        }
515        DriverManager.registerDriver(new BadDummyDriver());
516        for (int i = 0; i < deregister_count; i++) {
517            DriverManager.deregisterDriver(dummy);
518        }
519        Driver d = DriverManager.getDriver("jdbc:dummy_protocol:dummy_subname");
520        assertNotNull(d);
521    }
522
523    /**
524     * Regression for HARMONY-4303
525     */
526    public void test_initClass() throws Exception {
527        String[] arg = new String[1];
528        arg[0] = "org/apache/harmony/sql/tests/java/sql/TestMainForDriver";
529        String result = Support_Exec.execJava(arg, null, true);
530        assertEquals("", result);
531    }
532
533    private static class BadDummyDriver extends DummyDriver {
534        public boolean acceptsURL(String url) {
535            return false;
536        }
537    }
538
539    private static class DummyDriver implements Driver {
540
541        String goodurl = "jdbc:dummy_protocol:dummy_subname";
542
543        public boolean acceptsURL(String url) {
544            return url.equals(goodurl);
545        }
546
547        public Connection connect(String url, Properties info) {
548            return null;
549        }
550
551        public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) {
552            return null;
553        }
554
555        public int getMajorVersion() {
556            return 0;
557        }
558
559        public int getMinorVersion() {
560            return 0;
561        }
562
563        public boolean jdbcCompliant() {
564            return true;
565        }
566
567    }
568
569} // end class DriverManagerTest
570