/* * #%L * P6Spy * %% * Copyright (C) 2013 P6Spy * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * #L% */ package com.p6spy.engine.spy; import com.p6spy.engine.common.ConnectionInformation; import com.p6spy.engine.common.StatementInformation; import com.p6spy.engine.event.JdbcEventListener; import com.p6spy.engine.logging.P6LogOptions; import com.p6spy.engine.test.P6TestFramework; import com.p6spy.engine.wrapper.AbstractWrapper; import com.p6spy.engine.wrapper.ConnectionWrapper; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import java.io.IOException; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @RunWith(Parameterized.class) public class P6TestStatement extends P6TestFramework { public P6TestStatement(String db) throws SQLException, IOException { super(db); } @Test public void testExecute() throws SQLException { String query= "insert into customers(name,id) values ('bob', 100)"; P6TestUtil.execute(connection, query); // validate logging assertTrue(super.getLastLogEntry().contains(query)); // validate that the sql executed against the db assertEquals(1, P6TestUtil.queryForInt(connection, "select count(*) from customers where id=100")); } @Test public void testExecuteUpdate() throws SQLException { String query = "update customers set name='xyz' where id=1"; final int[] eventListenerRowCount = {0}; final Connection connectionWrapper = ConnectionWrapper.wrap(this.connection, new JdbcEventListener() { @Override public void onAfterExecuteUpdate(StatementInformation statementInformation, long timeElapsedNanos, String sql, int rowCount, SQLException e) { eventListenerRowCount[0] = rowCount; } }, ConnectionInformation.fromTestConnection(this.connection)); int rowCount = P6TestUtil.executeUpdate(connectionWrapper, query); assertEquals(1, rowCount); assertEquals(1, eventListenerRowCount[0]); // validate logging assertTrue(super.getLastLogEntry().contains(query)); // validate that the sql executed against the db assertEquals(1, P6TestUtil.queryForInt(this.connection, "select count(*) from customers where id=1 and name='xyz'")); } @Test public void testExecuteBatch() throws SQLException { P6LogOptions.getActiveInstance().setExcludecategories(""); // test batch inserts final int[] eventListenerUpdateCounts = new int[2]; Statement stmt = ConnectionWrapper.wrap(connection, new JdbcEventListener() { @Override public void onAfterExecuteBatch(StatementInformation statementInformation, long timeElapsedNanos, int[] updateCounts, SQLException e) { eventListenerUpdateCounts[0] = updateCounts[0]; eventListenerUpdateCounts[1] = updateCounts[1]; } }, ConnectionInformation.fromTestConnection(connection)).createStatement(); String sql = "insert into customers(name,id) values ('jim', 101)"; stmt.addBatch(sql); assertTrue(super.getLastLogEntry().contains(sql)); assertTrue(super.getLastLogEntry().contains("|batch|")); sql = "insert into customers(name,id) values ('billy', 102)"; stmt.addBatch(sql); assertTrue(super.getLastLogEntry().contains(sql)); assertTrue(super.getLastLogEntry().contains("|batch|")); final int[] updateCounts = stmt.executeBatch(); assertTrue(super.getLastLogEntry().contains(sql)); assertArrayEquals(new int[]{1, 1}, updateCounts); assertArrayEquals(new int[]{1, 1}, eventListenerUpdateCounts); assertEquals(2, P6TestUtil.queryForInt(connection,"select count(*) from customers where id > 100")); stmt.close(); } @Test public void testExecuteEmptyBatchWithIncludeExcludeEmpty() throws SQLException { Statement stmt = connection.createStatement(); stmt.executeBatch(); stmt.close(); } @Test public void testExecuteEmptyBatchWithIncludeExcludeNonEmpty() throws SQLException { P6LogOptions.getActiveInstance().setExclude("foo"); P6LogOptions.getActiveInstance().setInclude("foo"); Statement stmt = connection.createStatement(); stmt.executeBatch(); stmt.close(); P6LogOptions.getActiveInstance().setExclude(""); P6LogOptions.getActiveInstance().setInclude(""); } @Test public void testExecuteQuery() throws SQLException { Statement stmt = connection.createStatement(); String query = "select count(*) from customers where id=1"; ResultSet rs = stmt.executeQuery(query); // verify that we got back a proxy for the result set assertTrue("Resultset was not a proxy", AbstractWrapper.isProxy(rs.getClass())); // verify statement logging assertTrue(super.getLastLogEntry().contains(query)); rs.close(); stmt.close(); } @Test public void testExecutionThreshold() throws SQLException { Statement statement = connection.createStatement(); try { // set the execution threshold very low P6LogOptions.getActiveInstance().setExecutionThreshold("0"); // test a basic select String query = "select count(*) from customers"; ResultSet rs = statement.executeQuery(query); assertTrue(super.getLastLogEntry().contains(query)); // finally just make sure the query executed! rs.next(); assertTrue(rs.getInt(1) > 0); rs.close(); // now increase the execution threshold and make sure the query is not captured P6LogOptions.getActiveInstance().setExecutionThreshold("10000"); // test a basic select String nextQuery = "select count(*) from customers where 1 = 2"; rs = statement.executeQuery(nextQuery); // make sure the previous query is still the last query assertTrue(super.getLastLogEntry().contains(query)); // and of course that the new query isn't assertFalse(super.getLastLogEntry().contains(nextQuery)); // finally just make sure the query executed! rs.next(); assertEquals(0, rs.getInt(1)); rs.close(); P6LogOptions.getActiveInstance().setExecutionThreshold("0"); // finally, just make sure it now works as expected rs = statement.executeQuery(nextQuery); assertTrue(super.getLastLogEntry().contains(nextQuery)); rs.next(); assertEquals(0, rs.getInt(1)); rs.close(); } finally { if (statement != null) { statement.close(); } } } }