/* * Copyright (c) 2004, PostgreSQL Global Development Group * See the LICENSE file in the project root for more information. */ package org.postgresql.test.jdbc2; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import org.postgresql.Driver; import org.postgresql.test.TestUtil; import org.postgresql.util.NullOutputStream; import org.postgresql.util.WriterHandler; import org.junit.Test; import java.io.PrintWriter; import java.lang.reflect.Method; import java.sql.Connection; import java.sql.DriverManager; import java.util.ArrayList; import java.util.Collections; import java.util.Properties; import java.util.logging.Handler; import java.util.logging.Logger; /* * Tests the dynamically created class org.postgresql.Driver * */ public class DriverTest { /* * This tests the acceptsURL() method with a couple of well and poorly formed jdbc urls. */ @Test public void testAcceptsURL() throws Exception { TestUtil.initDriver(); // Set up log levels, etc. // Load the driver (note clients should never do it this way!) org.postgresql.Driver drv = new org.postgresql.Driver(); assertNotNull(drv); // These are always correct verifyUrl(drv, "jdbc:postgresql:test", "localhost", "5432", "test"); verifyUrl(drv, "jdbc:postgresql://localhost/test", "localhost", "5432", "test"); verifyUrl(drv, "jdbc:postgresql://localhost:5432/test", "localhost", "5432", "test"); verifyUrl(drv, "jdbc:postgresql://127.0.0.1/anydbname", "127.0.0.1", "5432", "anydbname"); verifyUrl(drv, "jdbc:postgresql://127.0.0.1:5433/hidden", "127.0.0.1", "5433", "hidden"); verifyUrl(drv, "jdbc:postgresql://[::1]:5740/db", "[::1]", "5740", "db"); // Badly formatted url's assertTrue(!drv.acceptsURL("jdbc:postgres:test")); assertTrue(!drv.acceptsURL("postgresql:test")); assertTrue(!drv.acceptsURL("db")); assertTrue(!drv.acceptsURL("jdbc:postgresql://localhost:5432a/test")); // failover urls verifyUrl(drv, "jdbc:postgresql://localhost,127.0.0.1:5432/test", "localhost,127.0.0.1", "5432,5432", "test"); verifyUrl(drv, "jdbc:postgresql://localhost:5433,127.0.0.1:5432/test", "localhost,127.0.0.1", "5433,5432", "test"); verifyUrl(drv, "jdbc:postgresql://[::1],[::1]:5432/db", "[::1],[::1]", "5432,5432", "db"); verifyUrl(drv, "jdbc:postgresql://[::1]:5740,127.0.0.1:5432/db", "[::1],127.0.0.1", "5740,5432", "db"); } private void verifyUrl(Driver drv, String url, String hosts, String ports, String dbName) throws Exception { assertTrue(url, drv.acceptsURL(url)); Method parseMethod = drv.getClass().getDeclaredMethod("parseURL", String.class, Properties.class); parseMethod.setAccessible(true); Properties p = (Properties) parseMethod.invoke(drv, url, null); assertEquals(url, dbName, p.getProperty("PGDBNAME")); assertEquals(url, hosts, p.getProperty("PGHOST")); assertEquals(url, ports, p.getProperty("PGPORT")); } /** * Tests the connect method by connecting to the test database */ @Test public void testConnect() throws Exception { TestUtil.initDriver(); // Set up log levels, etc. // Test with the url, username & password Connection con = DriverManager.getConnection(TestUtil.getURL(), TestUtil.getUser(), TestUtil.getPassword()); assertNotNull(con); con.close(); // Test with the username in the url con = DriverManager.getConnection( TestUtil.getURL() + "&user=" + TestUtil.getUser() + "&password=" + TestUtil.getPassword()); assertNotNull(con); con.close(); // Test with failover url } /** * Tests that pgjdbc performs connection failover if unable to connect to the first host in the * URL. * * @throws Exception if something wrong happens */ @Test public void testConnectFailover() throws Exception { String url = "jdbc:postgresql://invalidhost.not.here," + TestUtil.getServer() + ":" + TestUtil.getPort() + "/" + TestUtil.getDatabase() + "?connectTimeout=5"; Connection con = DriverManager.getConnection(url, TestUtil.getUser(), TestUtil.getPassword()); assertNotNull(con); con.close(); } /* * Test that the readOnly property works. */ @Test public void testReadOnly() throws Exception { TestUtil.initDriver(); // Set up log levels, etc. Connection con = DriverManager.getConnection(TestUtil.getURL() + "&readOnly=true", TestUtil.getUser(), TestUtil.getPassword()); assertNotNull(con); assertTrue(con.isReadOnly()); con.close(); con = DriverManager.getConnection(TestUtil.getURL() + "&readOnly=false", TestUtil.getUser(), TestUtil.getPassword()); assertNotNull(con); assertFalse(con.isReadOnly()); con.close(); con = DriverManager.getConnection(TestUtil.getURL(), TestUtil.getUser(), TestUtil.getPassword()); assertNotNull(con); assertFalse(con.isReadOnly()); con.close(); } @Test public void testRegistration() throws Exception { TestUtil.initDriver(); // Driver is initially registered because it is automatically done when class is loaded assertTrue(org.postgresql.Driver.isRegistered()); ArrayList<java.sql.Driver> drivers = Collections.list(DriverManager.getDrivers()); searchInstanceOf: { for (java.sql.Driver driver : drivers) { if (driver instanceof org.postgresql.Driver) { break searchInstanceOf; } } fail("Driver has not been found in DriverManager's list but it should be registered"); } // Deregister the driver Driver.deregister(); assertFalse(Driver.isRegistered()); drivers = Collections.list(DriverManager.getDrivers()); for (java.sql.Driver driver : drivers) { if (driver instanceof org.postgresql.Driver) { fail("Driver should be deregistered but it is still present in DriverManager's list"); } } // register again the driver Driver.register(); assertTrue(Driver.isRegistered()); drivers = Collections.list(DriverManager.getDrivers()); for (java.sql.Driver driver : drivers) { if (driver instanceof org.postgresql.Driver) { return; } } fail("Driver has not been found in DriverManager's list but it should be registered"); } @Test public void testSetLogWriter() throws Exception { // this is a dummy to make sure TestUtil is initialized Connection con = DriverManager.getConnection(TestUtil.getURL(), TestUtil.getUser(), TestUtil.getPassword()); con.close(); String loggerLevel = System.getProperty("loggerLevel"); String loggerFile = System.getProperty("loggerFile"); try { PrintWriter printWriter = new PrintWriter(new NullOutputStream(System.err)); DriverManager.setLogWriter(printWriter); assertEquals(DriverManager.getLogWriter(), printWriter); System.clearProperty("loggerFile"); System.clearProperty("loggerLevel"); Properties props = new Properties(); props.setProperty("user", TestUtil.getUser()); props.setProperty("password", TestUtil.getPassword()); props.setProperty("loggerLevel", "DEBUG"); con = DriverManager.getConnection(TestUtil.getURL(), props); Logger logger = Logger.getLogger("org.postgresql"); Handler[] handlers = logger.getHandlers(); assertTrue(handlers[0] instanceof WriterHandler ); con.close(); } finally { DriverManager.setLogWriter(null); System.setProperty("loggerLevel", loggerLevel); System.setProperty("loggerFile", loggerFile); } } @Test public void testSetLogStream() throws Exception { // this is a dummy to make sure TestUtil is initialized Connection con = DriverManager.getConnection(TestUtil.getURL(), TestUtil.getUser(), TestUtil.getPassword()); con.close(); String loggerLevel = System.getProperty("loggerLevel"); String loggerFile = System.getProperty("loggerFile"); try { DriverManager.setLogStream(new NullOutputStream(System.err)); System.clearProperty("loggerFile"); System.clearProperty("loggerLevel"); Properties props = new Properties(); props.setProperty("user", TestUtil.getUser()); props.setProperty("password", TestUtil.getPassword()); props.setProperty("loggerLevel", "DEBUG"); con = DriverManager.getConnection(TestUtil.getURL(), props); Logger logger = Logger.getLogger("org.postgresql"); Handler []handlers = logger.getHandlers(); assertTrue( handlers[0] instanceof WriterHandler ); con.close(); } finally { DriverManager.setLogStream(null); System.setProperty("loggerLevel", loggerLevel); System.setProperty("loggerFile", loggerFile); } } }