package org.geoserver.jdbcconfig.internal; import static org.junit.Assert.*; import static org.easymock.classextension.EasyMock.*; import static org.hamcrest.CoreMatchers.*; import java.sql.Connection; import javax.naming.Context; import javax.naming.NamingException; import javax.sql.DataSource; import org.apache.commons.dbcp.BasicDataSource; import org.easymock.classextension.EasyMock; import org.geoserver.jdbcloader.DataSourceFactoryBean; import org.junit.Test; import com.google.common.base.Optional; import java.sql.DatabaseMetaData; /** * * @author Kevin Smith, OpenGeo * */ public class DataSourceFactoryBeanTest { @Test public void testBasic() throws Exception { final BasicDataSource ds = EasyMock.createMock(BasicDataSource.class); JDBCConfigProperties config = EasyMock.createMock(JDBCConfigProperties.class); Context jndi = EasyMock.createMock(Context.class); expect(config.isEnabled()).andReturn(true); expectJndi(config, null); expect(config.getJdbcUrl()).andStubReturn(Optional.of("jdbc:test")); ds.setUrl("jdbc:test"); expectLastCall(); expect(config.getProperty("driverClassName")).andStubReturn("org.geoserver.jdbcconfig.internal.MockJDBCDriver"); ds.setDriverClassName("org.geoserver.jdbcconfig.internal.MockJDBCDriver"); expectLastCall(); expect(config.getProperty("username")).andStubReturn("testUser"); ds.setUsername("testUser"); expect(config.getProperty("password")).andStubReturn("swordfish"); ds.setPassword("swordfish"); expect(config.getProperty("pool.minIdle")).andStubReturn(null); expect(config.getProperty("pool.maxActive")).andStubReturn(null); expect(config.getProperty("pool.poolPreparedStatements")).andStubReturn(null); expect(config.getProperty("pool.maxOpenPreparedStatements")).andStubReturn(null); expect(config.getProperty("pool.testOnBorrow")).andStubReturn(null); config.setDatasourceId("jdbc:test"); expectLastCall(); ds.setMinIdle(1); expectLastCall(); ds.setMaxActive(10); expectLastCall(); ds.setPoolPreparedStatements(true); expectLastCall(); ds.setMaxOpenPreparedStatements(50); expectLastCall(); expectVerifyConnect(ds); replay(ds, config, jndi); DataSourceFactoryBean fact = new DataSourceFactoryBean(config, jndi) { @Override protected BasicDataSource createBasicDataSource() { return ds; } }; // Check that we get the DataSource assertThat(fact.getObject(), is((DataSource)ds)); verify(ds); reset(ds); replay(ds); // Check that the same DataSource is returned on subsequent calls without any changes assertThat(fact.getObject(), is((DataSource)ds)); verify(ds, config, jndi); // Check that destruction properly closes the DataSource reset(ds); ds.close(); expectLastCall(); replay(ds); fact.destroy(); verify(ds); } @Test public void testJNDI() throws Exception { DataSource ds = EasyMock.createMock(DataSource.class); JDBCConfigProperties config = EasyMock.createMock(JDBCConfigProperties.class); Context jndi = EasyMock.createMock(Context.class); expect(config.isEnabled()).andReturn(true); expectJndi(config, "java:comp/env/jdbc/test"); expect(jndi.lookup("java:comp/env/jdbc/test")).andStubReturn(ds); config.setDatasourceId("java:comp/env/jdbc/test"); expectLastCall(); expectVerifyConnect(ds); replay(ds, config, jndi); DataSourceFactoryBean fact = new DataSourceFactoryBean(config, jndi); // Check that we get the DataSource assertThat(fact.getObject(), is((DataSource)ds)); verify(ds); reset(ds); replay(ds); // Check that the same DataSource is returned on subsequent calls without any changes assertThat(fact.getObject(), is((DataSource)ds)); verify(ds, config, jndi); // Destruction shouldn't do anything to the DataSource reset(ds); replay(ds); fact.destroy(); verify(ds); } /** * If JNDI lookup fails, fall back to properties file */ @Test public void testJNDIFail() throws Exception { final BasicDataSource ds = EasyMock.createMock(BasicDataSource.class); JDBCConfigProperties config = EasyMock.createMock(JDBCConfigProperties.class); Context jndi = EasyMock.createMock(Context.class); expect(config.isEnabled()).andReturn(true); expectJndi(config, "java:comp/env/jdbc/test"); expect(jndi.lookup("java:comp/env/jdbc/test")).andStubThrow(new NamingException()); expect(config.getJdbcUrl()).andStubReturn(Optional.of("jdbc:test")); ds.setUrl("jdbc:test"); expectLastCall(); expect(config.getProperty("driverClassName")).andStubReturn("org.geoserver.jdbcconfig.internal.MockJDBCDriver"); ds.setDriverClassName("org.geoserver.jdbcconfig.internal.MockJDBCDriver"); expectLastCall(); expect(config.getProperty("username")).andStubReturn("testUser"); ds.setUsername("testUser"); expect(config.getProperty("password")).andStubReturn("swordfish"); ds.setPassword("swordfish"); expect(config.getProperty("pool.minIdle")).andStubReturn(null); expect(config.getProperty("pool.maxActive")).andStubReturn(null); expect(config.getProperty("pool.poolPreparedStatements")).andStubReturn(null); expect(config.getProperty("pool.maxOpenPreparedStatements")).andStubReturn(null); expect(config.getProperty("pool.testOnBorrow")).andStubReturn(null); config.setDatasourceId("jdbc:test"); expectLastCall(); ds.setMinIdle(1); expectLastCall(); ds.setMaxActive(10); expectLastCall(); ds.setPoolPreparedStatements(true); expectLastCall(); ds.setMaxOpenPreparedStatements(50); expectLastCall(); expectVerifyConnect(ds); replay(ds, config, jndi); DataSourceFactoryBean fact = new DataSourceFactoryBean(config, jndi) { @Override protected BasicDataSource createBasicDataSource() { return ds; } }; // Check that we get the DataSource assertThat(fact.getObject(), is((DataSource)ds)); verify(ds); reset(ds); replay(ds); // Check that the same DataSource is returned on subsequent calls without any changes assertThat(fact.getObject(), is((DataSource)ds)); verify(ds, config, jndi); // Check that destruction properly closes the DataSource reset(ds); ds.close(); expectLastCall(); replay(ds); fact.destroy(); verify(ds); } private void expectJndi(JDBCConfigProperties config, String name) { expect(config.getProperty("jndiName")).andStubReturn(name); expect(config.getJndiName()).andStubReturn(Optional.fromNullable(name)); } private void expectVerifyConnect(DataSource ds) throws Exception { Connection conn = createMock(Connection.class); // the 2 times expectations are due to checking the database metadata // during Dialect initialization conn.close();expectLastCall(); DatabaseMetaData metadata = EasyMock.createMock(DatabaseMetaData.class); expect(metadata.getDriverName()).andReturn("test"); expect(conn.getMetaData()).andReturn(metadata); replay(conn); replay(metadata); expect(ds.getConnection()).andReturn(conn); } }