/* * ==================== * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2008-2009 Sun Microsystems, Inc. All rights reserved. * * The contents of this file are subject to the terms of the Common Development * and Distribution License("CDDL") (the "License"). You may not use this file * except in compliance with the License. * * You can obtain a copy of the License at * http://opensource.org/licenses/cddl1.php * See the License for the specific language governing permissions and limitations * under the License. * * When distributing the Covered Code, include this CDDL Header Notice in each file * and include the License file at http://opensource.org/licenses/cddl1.php. * If applicable, add the following below this CDDL Header, with the fields * enclosed by brackets [] replaced by your own identifying information: * "Portions Copyrighted [year] [name of copyright owner]" * ==================== */ package org.identityconnectors.dbcommon; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertNotNull; import static org.testng.AssertJUnit.assertTrue; import java.io.ByteArrayInputStream; import java.math.BigDecimal; import java.sql.Blob; import java.sql.Connection; import java.sql.Date; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import java.sql.Time; import java.sql.Timestamp; import java.sql.Types; import java.util.ArrayList; import java.util.Hashtable; import java.util.List; import java.util.Map; import javax.naming.Context; import javax.naming.NamingException; import javax.naming.spi.InitialContextFactory; import javax.sql.DataSource; import org.testng.Assert; import org.testng.annotations.Test; /** * The SQL util tests * * @since 1.0 */ public class SQLUtilTests { /** * Test method for {@link SQLUtil#closeQuietly(Connection)}. * * @throws Exception */ @Test public void quietConnectionClose() throws Exception { ExpectProxy<Connection> tp = new ExpectProxy<Connection>(); tp.expectAndReturn("isClosed", Boolean.FALSE); tp.expectAndThrow("close", new SQLException("expected")); Connection c = tp.getProxy(Connection.class); DatabaseConnection dbc = new DatabaseConnection(c); SQLUtil.closeQuietly(dbc); Assert.assertTrue(tp.isDone(), "close not called"); tp = new ExpectProxy<Connection>(); tp.expectAndReturn("isClosed", Boolean.TRUE); c = tp.getProxy(Connection.class); dbc = new DatabaseConnection(c); SQLUtil.closeQuietly(dbc); Assert.assertTrue(tp.isDone(), "isClosed not called"); // null tests dbc = null; SQLUtil.closeQuietly(dbc); } /** * Test method for {@link SQLUtil#rollbackQuietly(Connection)}. * * @throws Exception */ @Test public void quietConnectionRolback() throws Exception { ExpectProxy<Connection> tp = new ExpectProxy<Connection>(); tp.expectAndReturn("isClosed", Boolean.FALSE); tp.expectAndThrow("rollback", new SQLException("expected")); Connection s = tp.getProxy(Connection.class); DatabaseConnection dbc = new DatabaseConnection(s); SQLUtil.rollbackQuietly(dbc); Assert.assertTrue(tp.isDone(), "rollback not called"); tp = new ExpectProxy<Connection>(); tp.expectAndReturn("isClosed", Boolean.TRUE); s = tp.getProxy(Connection.class); dbc = new DatabaseConnection(s); SQLUtil.rollbackQuietly(dbc); Assert.assertTrue(tp.isDone()); // null tests dbc = null; SQLUtil.rollbackQuietly(dbc); } /** * Test method for {@link SQLUtil#closeQuietly(Statement)}. */ @Test @SuppressWarnings("deprecation") public void quietStatementClose() { ExpectProxy<Statement> tp = new ExpectProxy<Statement>().expectAndThrow("close", new SQLException("expected")); Statement s = tp.getProxy(Statement.class); SQLUtil.closeQuietly(s); Assert.assertTrue(tp.isDone()); } /** * Test method for {@link SQLUtil#closeQuietly(ResultSet)}. */ @Test @SuppressWarnings("deprecation") public void quietResultSetClose() { ExpectProxy<ResultSet> tp = new ExpectProxy<ResultSet>().expectAndThrow("close", new SQLException("expected")); ResultSet c = tp.getProxy(ResultSet.class); SQLUtil.closeQuietly(c); Assert.assertTrue(tp.isDone()); } /** * Test method for {@link SQLUtil#closeQuietly(Connection)}. Test method for * {@link SQLUtil#closeQuietly(ResultSet)}. Test method for * {@link SQLUtil#closeQuietly(Statement)}. */ @Test @SuppressWarnings("deprecation") public void withNull() { // attempt to close on a null.. SQLUtil.closeQuietly((Connection) null); SQLUtil.closeQuietly((ResultSet) null); SQLUtil.closeQuietly((Statement) null); } /** * Test method * * @throws SQLException */ @Test(expectedExceptions = NullPointerException.class) public void testBuildConnectorObjectBuilderNull() throws SQLException { SQLUtil.getColumnValues(null); } /** * Test method * * @throws SQLException */ @Test public void testConvertBlob() throws SQLException { ExpectProxy<Blob> tb = new ExpectProxy<Blob>(); byte[] expected = new byte[] { 'a', 'h', 'o', 'j' }; final ByteArrayInputStream is = new ByteArrayInputStream(expected); tb.expectAndReturn("getBinaryStream", is); Blob blob = tb.getProxy(Blob.class); final Object object = SQLUtil.jdbc2AttributeValue(blob); assertEquals(expected[0], ((byte[]) object)[0]); assertEquals(expected[3], ((byte[]) object)[3]); assertTrue("getBinaryStream not called", tb.isDone()); } /** * Test method * * @throws SQLException */ @Test public void testConvertBooleanToAttribute() throws SQLException { String expected = "test"; final Object object = SQLUtil.jdbc2AttributeValue(expected); assertEquals(expected, object); } /** * Test method * * @throws SQLException */ @Test public void testConvertDateToAttribute() throws SQLException { java.sql.Date src = new java.sql.Date(System.currentTimeMillis()); final Object object = SQLUtil.jdbc2AttributeValue(src); assertEquals(src.toString(), object); } /** * Test method * * @throws SQLException */ @Test public void testString2Timestamp() throws SQLException { final String src = "2008-12-31 23:59:59.999999999"; final Timestamp timestamp = SQLUtil.string2Timestamp(src); assertEquals(src, SQLUtil.timestamp2String(timestamp)); } /** * Test method * * @throws SQLException */ @Test public void testString2Date() throws SQLException { final String src = "2008-12-31"; final Date date = SQLUtil.string2Date(src); assertEquals(src, SQLUtil.date2String(date)); } /** * Test method * * @throws SQLException */ @Test public void testString2Time() throws SQLException { final String src = "23:59:59"; final Time time = SQLUtil.string2Time(src); assertEquals(src, SQLUtil.time2String(time)); } /** * Test method * * @throws SQLException */ @Test public void testConvertTimestampToAttribute() throws SQLException { Timestamp src = new Timestamp(System.currentTimeMillis()); final Object object = SQLUtil.jdbc2AttributeValue(src); assertEquals(src.toString(), object); } /** * Test method * * @throws SQLException */ @Test public void testConvertTimestampToJDBC() { Timestamp expected = new Timestamp(System.currentTimeMillis()); String src = SQLUtil.timestamp2String(expected); Object actual = SQLUtil.string2Timestamp(src); assertNotNull(actual); assertEquals(expected.getClass(), actual.getClass()); assertEquals(expected, actual); } /** * Test method * * @throws SQLException */ @Test public void testConvertSqlDateToJDBC() { java.sql.Date expected = new java.sql.Date(System.currentTimeMillis()); String src = SQLUtil.date2String(expected); Object actual = SQLUtil.string2Date(src); assertNotNull(actual); assertEquals(expected.getClass(), actual.getClass()); assertEquals(expected.toString(), actual.toString()); } /** * Test method * * @throws SQLException */ @Test public void testNormalizeNullValues() { final String sql = "insert into table values(?, ?, ?)"; final List<SQLParam> params = new ArrayList<SQLParam>(); params.add(new SQLParam("test", "test")); params.add(new SQLParam("null", null)); // Null unspecified should be // normalized params.add(new SQLParam("null2", null, Types.VARCHAR)); // Null typed // should remain final List<SQLParam> out = new ArrayList<SQLParam>(); String actual = SQLUtil.normalizeNullValues(sql, params, out); assertNotNull("sql", actual); assertEquals("sql", "insert into table values(?, null, ?)", actual); assertEquals("out value", 2, out.size()); } /** * Test method * * @throws SQLException */ @Test public void testNormalizeNullValuesSame() { final String sql = "insert into table values(?, ?, ?)"; final List<SQLParam> params = new ArrayList<SQLParam>(); params.add(new SQLParam("test1", "test")); params.add(new SQLParam("test2", 1)); params.add(new SQLParam("test3", 5, Types.VARCHAR)); final List<SQLParam> out = new ArrayList<SQLParam>(); String actual = SQLUtil.normalizeNullValues(sql, params, out); assertNotNull("sql", actual); assertEquals("sql", "insert into table values(?, ?, ?)", actual); assertEquals("out value", 3, out.size()); } /** * Test method * * @throws SQLException */ @Test public void testNormalizeNullValuesLess() { final String sql = "insert into table values(?, ?, ?)"; final List<SQLParam> params = new ArrayList<SQLParam>(); params.add(new SQLParam("test1", "test")); params.add(new SQLParam("test2", 3)); final List<SQLParam> out = new ArrayList<SQLParam>(); try { SQLUtil.normalizeNullValues(sql, params, out); Assert.fail("IllegalStateException expected"); } catch (IllegalStateException expected) { // expected } params.add(new SQLParam("test3", 3)); params.add(new SQLParam("test4", 3)); try { SQLUtil.normalizeNullValues(sql, params, out); Assert.fail("IllegalStateException expected"); } catch (IllegalStateException expected) { // expected } } /** * GetAttributeSet test method * * @throws SQLException */ @Test public void testGetAttributeSet() throws SQLException { final String TEST1 = "test1"; final String TEST_VAL1 = "testValue1"; final String TEST2 = "test2"; final String TEST_VAL2 = "testValue2"; // Resultset final ExpectProxy<ResultSet> trs = new ExpectProxy<ResultSet>(); ResultSet resultSetProxy = trs.getProxy(ResultSet.class); // Metadata final ExpectProxy<ResultSetMetaData> trsmd = new ExpectProxy<ResultSetMetaData>(); ResultSetMetaData metaDataProxy = trsmd.getProxy(ResultSetMetaData.class); trs.expectAndReturn("getMetaData", metaDataProxy); trsmd.expectAndReturn("getColumnCount", 2); trsmd.expectAndReturn("getColumnName", TEST1); trsmd.expectAndReturn("getColumnType", Types.VARCHAR); trs.expectAndReturn("getString", TEST_VAL1); trsmd.expectAndReturn("getColumnName", TEST2); trsmd.expectAndReturn("getColumnType", Types.VARCHAR); trs.expectAndReturn("getString", TEST_VAL2); final Map<String, SQLParam> actual = SQLUtil.getColumnValues(resultSetProxy); assertTrue("getString not called", trs.isDone()); assertTrue("getColumnType not called", trsmd.isDone()); assertEquals(2, actual.size()); assertNotNull(actual.get(TEST1)); assertNotNull(actual.get(TEST2)); assertEquals(TEST_VAL1, actual.get(TEST1).getValue()); assertEquals(TEST_VAL2, actual.get(TEST2).getValue()); } /** * GetAttributeSet test method * * @throws SQLException */ @Test public void testGetSQLParam() throws SQLException { final String TEST_STR = "testValue1"; final Timestamp TEST_TMS = new Timestamp(System.currentTimeMillis()); final Date TEST_DATE = new Date(System.currentTimeMillis()); final Time TEST_TIME = new Time(System.currentTimeMillis()); // Resultset final ExpectProxy<ResultSet> trs = new ExpectProxy<ResultSet>(); ResultSet resultSetProxy = trs.getProxy(ResultSet.class); trs.expectAndReturn("getObject", TEST_STR); SQLParam actual = SQLUtil.getSQLParam(resultSetProxy, 0, TEST_STR, Types.NULL); assertTrue("getObject not called", trs.isDone()); assertNotNull(actual); assertEquals(TEST_STR, actual.getValue()); trs.expectAndReturn("getString", TEST_STR); actual = SQLUtil.getSQLParam(resultSetProxy, 0, TEST_STR, Types.VARCHAR); assertTrue("getString not called", trs.isDone()); assertNotNull(actual); assertEquals(TEST_STR, actual.getValue()); trs.expectAndReturn("getObject", TEST_STR); actual = SQLUtil.getSQLParam(resultSetProxy, 0, TEST_STR, Types.DOUBLE); assertTrue("getObject not called", trs.isDone()); assertNotNull(actual); assertEquals(TEST_STR, actual.getValue()); trs.expectAndReturn("getObject", TEST_STR); actual = SQLUtil.getSQLParam(resultSetProxy, 0, TEST_STR, Types.BLOB); assertTrue("getObject not called", trs.isDone()); assertNotNull(actual); assertEquals(TEST_STR, actual.getValue()); trs.expectAndReturn("getTimestamp", TEST_TMS); actual = SQLUtil.getSQLParam(resultSetProxy, 0, TEST_STR, Types.TIMESTAMP); assertTrue("getTimestamp not callled", trs.isDone()); assertNotNull(actual); assertEquals(TEST_TMS, actual.getValue()); trs.expectAndReturn("getDate", TEST_DATE); actual = SQLUtil.getSQLParam(resultSetProxy, 0, TEST_STR, Types.DATE); assertTrue("getDate not called", trs.isDone()); assertNotNull(actual); assertEquals(TEST_DATE, actual.getValue()); trs.expectAndReturn("getTime", TEST_TIME); actual = SQLUtil.getSQLParam(resultSetProxy, 0, TEST_STR, Types.TIME); assertTrue("getTime not callled", trs.isDone()); assertNotNull(actual); assertEquals(TEST_TIME, actual.getValue()); trs.expectAndReturn("getBoolean", Boolean.TRUE); actual = SQLUtil.getSQLParam(resultSetProxy, 0, TEST_STR, Types.BOOLEAN); assertTrue("getBoolean not called", trs.isDone()); assertNotNull(actual); assertEquals(Boolean.TRUE, actual.getValue()); } /** * GetAttributeSet test method * * @throws SQLException */ @Test public void testSetSQLParam() throws SQLException { final String TEST_STR = "testValue1"; final Timestamp TEST_TMS = new Timestamp(System.currentTimeMillis()); final Date TEST_DATE = new Date(System.currentTimeMillis()); final Time TEST_TIME = new Time(System.currentTimeMillis()); // Resultset final ExpectProxy<PreparedStatement> trs = new ExpectProxy<PreparedStatement>(); PreparedStatement resultSetProxy = trs.getProxy(PreparedStatement.class); trs.expect("setNull"); SQLUtil.setSQLParam(resultSetProxy, 0, new SQLParam(TEST_STR, null, Types.CHAR)); assertTrue("setNull not called", trs.isDone()); trs.expect("setObject"); SQLUtil.setSQLParam(resultSetProxy, 0, new SQLParam(TEST_STR, TEST_STR)); assertTrue("setObject not called", trs.isDone()); trs.expect("setString"); SQLUtil.setSQLParam(resultSetProxy, 0, new SQLParam(TEST_STR, TEST_STR, Types.CHAR)); assertTrue("setString not called", trs.isDone()); trs.expect("setBoolean"); SQLUtil.setSQLParam(resultSetProxy, 0, new SQLParam(TEST_STR, Boolean.TRUE, Types.BOOLEAN)); assertTrue("setBoolean not called", trs.isDone()); trs.expect("setTimestamp"); SQLUtil.setSQLParam(resultSetProxy, 0, new SQLParam(TEST_STR, TEST_TMS, Types.TIMESTAMP)); assertTrue("setTimestamp not callled", trs.isDone()); trs.expect("setTime"); SQLUtil.setSQLParam(resultSetProxy, 0, new SQLParam(TEST_STR, TEST_TIME, Types.TIME)); assertTrue("setTime not callled", trs.isDone()); trs.expect("setDate"); SQLUtil.setSQLParam(resultSetProxy, 0, new SQLParam(TEST_STR, TEST_DATE, Types.DATE)); assertTrue("setDate not callled", trs.isDone()); } /** * GetAttributeSet test method * * @throws SQLException */ @Test public void testGetSQLAttributeType() { assertEquals(BigDecimal.class, SQLUtil.getSQLAttributeType(Types.DECIMAL)); assertEquals(BigDecimal.class, SQLUtil.getSQLAttributeType(Types.NUMERIC)); assertEquals(Double.class, SQLUtil.getSQLAttributeType(Types.DOUBLE)); assertEquals(BigDecimal.class, SQLUtil.getSQLAttributeType(Types.NUMERIC)); assertEquals(Float.class, SQLUtil.getSQLAttributeType(Types.FLOAT)); assertEquals(Float.class, SQLUtil.getSQLAttributeType(Types.REAL)); assertEquals(Integer.class, SQLUtil.getSQLAttributeType(Types.INTEGER)); assertEquals(Long.class, SQLUtil.getSQLAttributeType(Types.BIGINT)); assertEquals(Byte.class, SQLUtil.getSQLAttributeType(Types.TINYINT)); assertEquals(byte[].class, SQLUtil.getSQLAttributeType(Types.BLOB)); assertEquals(byte[].class, SQLUtil.getSQLAttributeType(Types.BINARY)); assertEquals(byte[].class, SQLUtil.getSQLAttributeType(Types.LONGVARBINARY)); assertEquals(byte[].class, SQLUtil.getSQLAttributeType(Types.VARBINARY)); assertEquals(Boolean.class, SQLUtil.getSQLAttributeType(Types.BIT)); assertEquals(Boolean.class, SQLUtil.getSQLAttributeType(Types.BOOLEAN)); assertEquals(String.class, SQLUtil.getSQLAttributeType(Types.CHAR)); assertEquals(String.class, SQLUtil.getSQLAttributeType(Types.CLOB)); assertEquals(String.class, SQLUtil.getSQLAttributeType(Types.VARCHAR)); } /** * GetAttributeSet test method * * @throws SQLException */ @Test public void testJdbc2Attribute() throws SQLException { final String TEST_STR = "testValue1"; final Timestamp TEST_TMS = new Timestamp(System.currentTimeMillis()); final Date TEST_DATE = new Date(System.currentTimeMillis()); final Time TEST_TIME = new Time(System.currentTimeMillis()); Object actual = SQLUtil.jdbc2AttributeValue(TEST_STR); assertEquals(TEST_STR, actual); actual = SQLUtil.jdbc2AttributeValue(TEST_TMS); assertEquals(TEST_TMS.toString(), actual); actual = SQLUtil.jdbc2AttributeValue(TEST_DATE); assertEquals(TEST_DATE.toString(), actual); actual = SQLUtil.jdbc2AttributeValue(TEST_TIME); assertEquals(TEST_TIME.toString(), actual); actual = SQLUtil.jdbc2AttributeValue(1); assertEquals(1, actual); actual = SQLUtil.jdbc2AttributeValue(1L); assertEquals(1L, actual); actual = SQLUtil.jdbc2AttributeValue(1d); assertEquals(1d, actual); actual = SQLUtil.jdbc2AttributeValue(1f); assertEquals(1f, actual); actual = SQLUtil.jdbc2AttributeValue(true); assertEquals(true, actual); } /** * GetAttributeSet test method * * @throws SQLException */ @Test public void testAttribute2JdbcValue() throws SQLException { final String TEST_STR = "testValue1"; final Timestamp TEST_TMS = new Timestamp(System.currentTimeMillis()); final Date TEST_DATE = new Date(System.currentTimeMillis()); final Time TEST_TIME = new Time(System.currentTimeMillis()); Object actual = SQLUtil.attribute2jdbcValue(TEST_STR, Types.CHAR); assertEquals(TEST_STR, actual); actual = SQLUtil.attribute2jdbcValue(TEST_TMS.toString(), Types.TIMESTAMP); assertEquals(TEST_TMS, actual); actual = SQLUtil.attribute2jdbcValue(TEST_TIME.toString(), Types.TIME); assertEquals(TEST_TIME.toString(), actual.toString()); actual = SQLUtil.attribute2jdbcValue(TEST_DATE.toString(), Types.DATE); assertEquals(TEST_DATE.toString(), actual.toString()); actual = SQLUtil.attribute2jdbcValue("55.55", Types.DOUBLE); assertEquals(55.55d, actual); actual = SQLUtil.attribute2jdbcValue("true", Types.BIT); assertEquals(true, actual); } /** * We need this helper class as InitialContextFactory class name value to * Hashtable into InitialContext. We must use instantiable classname and * class must be accessible * * @author kitko * */ public static class MockContextFactory implements InitialContextFactory { public Context getInitialContext(Hashtable<?, ?> environment) throws NamingException { ExpectProxy<DataSource> dsProxy = new ExpectProxy<DataSource>(); dsProxy.expectAndReturn("getConnection", new ExpectProxy<Connection>() .getProxy(Connection.class)); ExpectProxy<Context> ctxProxy = new ExpectProxy<Context>(); ctxProxy.expectAndReturn("lookup", dsProxy.getProxy(DataSource.class)); return ctxProxy.getProxy(Context.class); } } /** * Tests getting connection from dataSource */ @Test public void testGetConnectionFromDS() { Hashtable<String, String> properties = new Hashtable<String, String>(); properties.put("java.naming.factory.initial", MockContextFactory.class.getName()); final Connection conn = SQLUtil.getDatasourceConnection("", properties); assertNotNull("Connection returned from datasource is null", conn); } }