package com.github.kristofa.brave.p6spy; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verifyZeroInteractions; import com.github.kristofa.brave.ClientTracer; import com.twitter.zipkin.gen.Endpoint; import org.junit.Before; import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InOrder; import org.mockito.runners.MockitoJUnitRunner; import zipkin.TraceKeys; import java.sql.ResultSet; @RunWith(MockitoJUnitRunner.class) public class BraveP6SpyTest { //Get rid of annoying derby.log static { DerbyUtils.disableLog(); } private static final String SERVICE_NAME = "customerDb"; private static final int HOST = -968622079; private static final int PORT = 3306; private static final String SQL = "select * from customers"; private static final String PREPARED_SQL = "select * from customers where id > ?"; private static final String INSERT_SQL = "insert into customers values (12, 'bob')"; private static final String PREPARED_INSERT_SQL = "insert into customers values (?, ?)"; @ClassRule public static TestDatabaseRule db = new TestDatabaseRule(); private ClientTracer clientTracer; @Before public void setup() { clientTracer = mock(ClientTracer.class); BraveP6SpyListener.setClientTracer(clientTracer); } @Test public void listenerShouldNotFailIfNoClientTracer() throws Exception { BraveP6SpyListener.setClientTracer(null); db.executeStatement(ps -> { boolean result = ps.execute(SQL); assertTrue(result); }); verifyZeroInteractions(clientTracer); } @Test public void queryIsTraced() throws Exception { db.executeStatement(ps -> { ResultSet resultSet = ps.executeQuery(SQL); assertTrue(resultSet.next()); resultSet.close(); }); validateTraced(clientTracer, SQL); } @Test public void psIsTraced() throws Exception { db.executeStatement(ps -> { boolean result = ps.execute(SQL); assertTrue(result); }); validateTraced(clientTracer, SQL); } @Test public void preparedStatementIsTraced() throws Exception { db.executePreparedStatement(ps -> { ps.setInt(1, 0); ResultSet resultSet = ps.executeQuery(); assertTrue(resultSet.next()); resultSet.close(); }, PREPARED_SQL); validateTraced(clientTracer, PREPARED_SQL); } @Test public void insertStatementIsTraced() throws Exception { db.executeStatement(ps -> { int count = ps.executeUpdate(INSERT_SQL); assertEquals(count, 1); }); validateTraced(clientTracer, INSERT_SQL); } @Test public void preparedInsertStatementIsTraced() throws Exception { db.executePreparedStatement(ps -> { ps.setInt(1, 13); ps.setString(2, "sarah"); int count = ps.executeUpdate(); assertEquals(count, 1); }, PREPARED_INSERT_SQL); validateTraced(clientTracer, PREPARED_INSERT_SQL); } @Test public void batchStatementIsTraced() throws Exception { db.executePreparedStatement(ps -> { ps.setInt(1, 20); ps.setString(2, "barack"); ps.addBatch(); ps.setInt(1, 21); ps.setString(2, "michelle"); ps.addBatch(); int[] count = ps.executeBatch(); assertEquals(count[0], 1); assertEquals(count[1], 1); }, PREPARED_INSERT_SQL); validateTraced(clientTracer, PREPARED_INSERT_SQL); } private void validateTraced(ClientTracer clientTracer, String sql) { final InOrder order = inOrder(clientTracer); order.verify(clientTracer).startNewSpan("query"); order.verify(clientTracer).submitBinaryAnnotation(eq(TraceKeys.SQL_QUERY), eq(sql)); order.verify(clientTracer).setClientSent(Endpoint.builder() .ipv4(HOST).port(PORT).serviceName(SERVICE_NAME).build()); order.verify(clientTracer).setClientReceived(); order.verifyNoMoreInteractions(); } }