Mercurial > hg > release > thermostat-1.0
changeset 1278:341b73a2b354
Extend ThreadDao API
Reviewed-by: jerboaa
Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2013-October/008431.html
author | Omair Majid <omajid@redhat.com> |
---|---|
date | Wed, 16 Oct 2013 12:40:04 -0400 |
parents | 6f704bf1d5ac |
children | 7b91182a8455 |
files | thread/collector/src/main/java/com/redhat/thermostat/thread/dao/ThreadDao.java thread/collector/src/main/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoImpl.java thread/collector/src/main/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoImplStatementDescriptorRegistration.java thread/collector/src/test/java/com/redhat/thermostat/thread/dao/impl/ThreadDAOImplStatementDescriptorRegistrationTest.java thread/collector/src/test/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoImplTest.java |
diffstat | 5 files changed, 343 insertions(+), 154 deletions(-) [+] |
line wrap: on
line diff
--- a/thread/collector/src/main/java/com/redhat/thermostat/thread/dao/ThreadDao.java Fri Oct 04 19:34:29 2013 +0200 +++ b/thread/collector/src/main/java/com/redhat/thermostat/thread/dao/ThreadDao.java Wed Oct 16 12:40:04 2013 -0400 @@ -38,15 +38,15 @@ import java.util.List; +import com.redhat.thermostat.common.model.Range; import com.redhat.thermostat.storage.core.Category; import com.redhat.thermostat.storage.core.Key; -import com.redhat.thermostat.storage.core.Storage; import com.redhat.thermostat.storage.core.VmRef; -import com.redhat.thermostat.thread.model.VmDeadLockData; +import com.redhat.thermostat.thread.model.ThreadHarvestingStatus; import com.redhat.thermostat.thread.model.ThreadInfoData; -import com.redhat.thermostat.thread.model.ThreadHarvestingStatus; import com.redhat.thermostat.thread.model.ThreadSummary; import com.redhat.thermostat.thread.model.VMThreadCapabilities; +import com.redhat.thermostat.thread.model.VmDeadLockData; public interface ThreadDao { @@ -121,15 +121,24 @@ void saveSummary(ThreadSummary summary); ThreadSummary loadLastestSummary(VmRef ref); List<ThreadSummary> loadSummary(VmRef ref, long since); + + /** Save the specified thread info */ void saveThreadInfo(ThreadInfoData info); + /** Get the time interval for the entire data */ + Range<Long> getThreadInfoTimeRange(VmRef ref); + /** Get the thread info data with a timestamp greated than the one specified */ List<ThreadInfoData> loadThreadInfo(VmRef ref, long since); + /** Get the thread info data with a timestamp in the given time range (inclusive) */ + List<ThreadInfoData> loadThreadInfo(VmRef ref, Range<Long> time); + ThreadHarvestingStatus getLatestHarvestingStatus(VmRef vm); void saveHarvestingStatus(ThreadHarvestingStatus status); + VMThreadCapabilities loadCapabilities(VmRef ref); void saveCapabilities(VMThreadCapabilities caps); + void saveDeadLockStatus(VmDeadLockData deadLockInfo); VmDeadLockData loadLatestDeadLockStatus(VmRef ref); - Storage getStorage(); }
--- a/thread/collector/src/main/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoImpl.java Fri Oct 04 19:34:29 2013 +0200 +++ b/thread/collector/src/main/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoImpl.java Wed Oct 16 12:40:04 2013 -0400 @@ -42,6 +42,7 @@ import java.util.logging.Level; import java.util.logging.Logger; +import com.redhat.thermostat.common.model.Range; import com.redhat.thermostat.common.utils.LoggingUtils; import com.redhat.thermostat.storage.core.Category; import com.redhat.thermostat.storage.core.Cursor; @@ -86,12 +87,29 @@ + Key.AGENT_ID.getName() + "' = ?s AND '" + Key.VM_ID.getName() + "' = ?s SORT '" + Key.TIMESTAMP.getName() + "' DSC LIMIT 1"; - static final String QUERY_THREAD_INFO = "QUERY " + static final String QUERY_THREAD_INFO_SINCE = "QUERY " + THREAD_INFO.getName() + " WHERE '" + Key.AGENT_ID.getName() + "' = ?s AND '" + Key.VM_ID.getName() + "' = ?s AND '" + Key.TIMESTAMP.getName() + "' > ?l SORT '" + Key.TIMESTAMP.getName() + "' DSC"; + static final String QUERY_THREAD_INFO_INTERVAL = "QUERY " + + THREAD_INFO.getName() + " WHERE '" + + Key.AGENT_ID.getName() + "' = ?s AND '" + + Key.VM_ID.getName() + "' = ?s AND '" + + Key.TIMESTAMP.getName() + "' > ?l AND '" + + Key.TIMESTAMP.getName() + "' < ?l SORT '" + + Key.TIMESTAMP.getName() + "' DSC"; + static final String QUERY_OLDEST_THREAD_INFO = "QUERY " + + THREAD_INFO.getName() + " WHERE '" + + Key.AGENT_ID.getName() + "' = ?s AND '" + + Key.VM_ID.getName() + "' = ?s SORT '" + + Key.TIMESTAMP.getName() + "' ASC LIMIT 1"; + static final String QUERY_LATEST_THREAD_INFO = "QUERY " + + THREAD_INFO.getName() + " WHERE '" + + Key.AGENT_ID.getName() + "' = ?s AND '" + + Key.VM_ID.getName() + "' = ?s SORT '" + + Key.TIMESTAMP.getName() + "' DSC LIMIT 1"; static final String QUERY_LATEST_DEADLOCK_INFO = "QUERY " + DEADLOCK_INFO.getName() + " WHERE '" + Key.AGENT_ID.getName() + "' = ?s AND '" @@ -181,21 +199,7 @@ return null; } - Cursor<VMThreadCapabilities> cursor; - try { - cursor = stmt.executeQuery(); - } catch (StatementExecutionException e) { - // should not happen, but if it *does* happen, at least log it - logger.log(Level.SEVERE, "Executing query '" + stmt + "' failed!", e); - return null; - } - - VMThreadCapabilities caps = null; - if (cursor.hasNext()) { - caps = cursor.next(); - } - - return caps; + return getFirstResult(stmt); } @Override @@ -243,46 +247,17 @@ return null; } - Cursor<ThreadSummary> cursor; - try { - cursor = stmt.executeQuery(); - } catch (StatementExecutionException e) { - // should not happen, but if it *does* happen, at least log it - logger.log(Level.SEVERE, "Executing query '" + stmt + "' failed!", e); - return null; - } - - ThreadSummary summary = null; - if (cursor.hasNext()) { - summary = cursor.next(); - } - - return summary; + return getFirstResult(stmt); } @Override public List<ThreadSummary> loadSummary(VmRef ref, long since) { - PreparedStatement<ThreadSummary> stmt = prepareQuery(THREAD_SUMMARY, QUERY_SUMMARY_SINCE, ref, since); + PreparedStatement<ThreadSummary> stmt = prepareQuery(THREAD_SUMMARY, QUERY_SUMMARY_SINCE, ref, since, null); if (stmt == null) { return Collections.emptyList(); } - Cursor<ThreadSummary> cursor; - try { - cursor = stmt.executeQuery(); - } catch (StatementExecutionException e) { - // should not happen, but if it *does* happen, at least log it - logger.log(Level.SEVERE, "Executing query '" + stmt + "' failed!", e); - return Collections.emptyList(); - } - - List<ThreadSummary> result = new ArrayList<>(); - while (cursor.hasNext()) { - ThreadSummary summary = cursor.next(); - result.add(summary); - } - - return result; + return getAllResults(stmt); } @Override @@ -311,20 +286,7 @@ return null; } - Cursor<ThreadHarvestingStatus> cursor; - try { - cursor = stmt.executeQuery(); - } catch (StatementExecutionException e) { - // should not happen, but if it *does* happen, at least log it - logger.log(Level.SEVERE, "Executing query '" + stmt + "' failed!", e); - return null; - } - - ThreadHarvestingStatus result = null; - if (cursor.hasNext()) { - result = cursor.next(); - } - return result; + return getFirstResult(stmt); } @Override @@ -353,28 +315,38 @@ } @Override + public Range<Long> getThreadInfoTimeRange(VmRef ref) { + PreparedStatement<ThreadInfoData> stmt; + + stmt = prepareQuery(THREAD_INFO, QUERY_OLDEST_THREAD_INFO, ref); + ThreadInfoData oldestData = getFirstResult(stmt); + long oldestTimeStamp = oldestData.getTimeStamp(); + + stmt = prepareQuery(THREAD_INFO, QUERY_LATEST_THREAD_INFO, ref); + ThreadInfoData latestData = getFirstResult(stmt); + long latestTimeStamp = latestData.getTimeStamp(); + + return new Range<Long>(oldestTimeStamp, latestTimeStamp); + } + + @Override public List<ThreadInfoData> loadThreadInfo(VmRef ref, long since) { - PreparedStatement<ThreadInfoData> stmt = prepareQuery(THREAD_INFO, QUERY_THREAD_INFO, ref, since); + PreparedStatement<ThreadInfoData> stmt = prepareQuery(THREAD_INFO, QUERY_THREAD_INFO_SINCE, ref, since, null); if (stmt == null) { return Collections.emptyList(); } - - Cursor<ThreadInfoData> cursor; - try { - cursor = stmt.executeQuery(); - } catch (StatementExecutionException e) { - // should not happen, but if it *does* happen, at least log it - logger.log(Level.SEVERE, "Executing query '" + stmt + "' failed!", e); + + return getAllResults(stmt); + } + + @Override + public List<ThreadInfoData> loadThreadInfo(VmRef ref, Range<Long> time) { + PreparedStatement<ThreadInfoData> stmt = prepareQuery(THREAD_INFO, QUERY_THREAD_INFO_INTERVAL, ref, time.getMin(), time.getMax()); + if (stmt == null) { return Collections.emptyList(); } - - List<ThreadInfoData> result = new ArrayList<>(); - while (cursor.hasNext()) { - ThreadInfoData info = cursor.next(); - result.add(info); - } - - return result; + + return getAllResults(stmt); } @Override @@ -384,21 +356,7 @@ return null; } - Cursor<VmDeadLockData> cursor; - try { - cursor = stmt.executeQuery(); - } catch (StatementExecutionException e) { - // should not happen, but if it *does* happen, at least log it - logger.log(Level.SEVERE, "Executing query '" + stmt + "' failed!", e); - return null; - } - - VmDeadLockData result = null; - if (cursor.hasNext()) { - result = cursor.next(); - } - - return result; + return getFirstResult(stmt); } @Override @@ -420,29 +378,66 @@ } private <T extends Pojo> PreparedStatement<T> prepareQuery(Category<T> category, String query, VmRef ref) { - return prepareQuery(category, query, ref, null); + return prepareQuery(category, query, ref, null, null); } - private <T extends Pojo> PreparedStatement<T> prepareQuery(Category<T> category, String query, VmRef ref, Long since) { + private <T extends Pojo> PreparedStatement<T> prepareQuery(Category<T> category, String query, VmRef ref, Long since, Long to) { StatementDescriptor<T> desc = new StatementDescriptor<>(category, query); PreparedStatement<T> stmt = null; try { stmt = storage.prepareStatement(desc); stmt.setString(0, ref.getHostRef().getAgentId()); stmt.setString(1, ref.getVmId()); + // assume: the format of the query is such that 2nd and 3rd arguments (if any) are longs if (since != null) { stmt.setLong(2, since); } + if (to != null) { + stmt.setLong(3, to); + } } catch (DescriptorParsingException e) { // should not happen, but if it *does* happen, at least log it logger.log(Level.SEVERE, "Preparing query '" + desc + "' failed!", e); } return stmt; } - - @Override - public Storage getStorage() { - return storage; + + private <T extends Pojo> List<T> getAllResults(PreparedStatement<T> stmt) { + Cursor<T> cursor; + try { + cursor = stmt.executeQuery(); + } catch (StatementExecutionException e) { + // should not happen, but if it *does* happen, at least log it + logger.log(Level.SEVERE, "Executing query '" + stmt + "' failed!", e); + return Collections.emptyList(); + } + + List<T> result = new ArrayList<>(); + while (cursor.hasNext()) { + T info = cursor.next(); + result.add(info); + } + + return result; } + + private <T extends Pojo> T getFirstResult(PreparedStatement<T> stmt) { + Cursor<T> cursor; + try { + cursor = stmt.executeQuery(); + } catch (StatementExecutionException e) { + // should not happen, but if it *does* happen, at least log it + logger.log(Level.SEVERE, "Executing query '" + stmt + "' failed!", e); + return null; + } + + T result = null; + if (cursor.hasNext()) { + result = cursor.next(); + } + + return result; + } + }
--- a/thread/collector/src/main/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoImplStatementDescriptorRegistration.java Fri Oct 04 19:34:29 2013 +0200 +++ b/thread/collector/src/main/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoImplStatementDescriptorRegistration.java Wed Oct 16 12:40:04 2013 -0400 @@ -61,7 +61,10 @@ descs.add(ThreadDaoImpl.QUERY_LATEST_SUMMARY); descs.add(ThreadDaoImpl.QUERY_SUMMARY_SINCE); descs.add(ThreadDaoImpl.QUERY_THREAD_CAPS); - descs.add(ThreadDaoImpl.QUERY_THREAD_INFO); + descs.add(ThreadDaoImpl.QUERY_THREAD_INFO_SINCE); + descs.add(ThreadDaoImpl.QUERY_THREAD_INFO_INTERVAL); + descs.add(ThreadDaoImpl.QUERY_OLDEST_THREAD_INFO); + descs.add(ThreadDaoImpl.QUERY_LATEST_THREAD_INFO); descs.add(ThreadDaoImpl.DESC_ADD_THREAD_DEADLOCK_DATA); descs.add(ThreadDaoImpl.DESC_ADD_THREAD_HARVESTING_STATUS); descs.add(ThreadDaoImpl.DESC_ADD_THREAD_INFO);
--- a/thread/collector/src/test/java/com/redhat/thermostat/thread/dao/impl/ThreadDAOImplStatementDescriptorRegistrationTest.java Fri Oct 04 19:34:29 2013 +0200 +++ b/thread/collector/src/test/java/com/redhat/thermostat/thread/dao/impl/ThreadDAOImplStatementDescriptorRegistrationTest.java Wed Oct 16 12:40:04 2013 -0400 @@ -76,7 +76,7 @@ public void registersAllDescriptors() { ThreadDaoImplStatementDescriptorRegistration reg = new ThreadDaoImplStatementDescriptorRegistration(); Set<String> descriptors = reg.getStatementDescriptors(); - assertEquals(11, descriptors.size()); + assertEquals(14, descriptors.size()); assertFalse("null descriptor not allowed", descriptors.contains(null)); } @@ -104,7 +104,7 @@ // storage-core + this module assertEquals(2, registrations.size()); assertNotNull(threadDaoReg); - assertEquals(11, threadDaoReg.getStatementDescriptors().size()); + assertEquals(14, threadDaoReg.getStatementDescriptors().size()); } private Triple<String, String, PreparedParameter[]> setupForMetaDataTest() { @@ -165,11 +165,38 @@ } @Test - public void canGetMetadataThreadInfoQuery() { + public void canGetMetadataOldestThreadInfo() { Triple<String, String, PreparedParameter[]> triple = setupForMetaDataTest(); - + + StatementDescriptorMetadataFactory factory = new ThreadDaoImplStatementDescriptorRegistration(); + DescriptorMetadata data = factory.getDescriptorMetadata(ThreadDaoImpl.QUERY_OLDEST_THREAD_INFO, triple.third); + assertThreadMetadata(triple, data); + } + + @Test + public void canGetMetadataLatestThreadInfo() { + Triple<String, String, PreparedParameter[]> triple = setupForMetaDataTest(); + StatementDescriptorMetadataFactory factory = new ThreadDaoImplStatementDescriptorRegistration(); - DescriptorMetadata data = factory.getDescriptorMetadata(ThreadDaoImpl.QUERY_THREAD_INFO, triple.third); + DescriptorMetadata data = factory.getDescriptorMetadata(ThreadDaoImpl.QUERY_LATEST_THREAD_INFO, triple.third); + assertThreadMetadata(triple, data); + } + + @Test + public void canGetMetadataThreadInfoQuerySince() { + Triple<String, String, PreparedParameter[]> triple = setupForMetaDataTest(); + + StatementDescriptorMetadataFactory factory = new ThreadDaoImplStatementDescriptorRegistration(); + DescriptorMetadata data = factory.getDescriptorMetadata(ThreadDaoImpl.QUERY_THREAD_INFO_SINCE, triple.third); + assertThreadMetadata(triple, data); + } + + @Test + public void canGetMetadataThreadInfoQueryInterval() { + Triple<String, String, PreparedParameter[]> triple = setupForMetaDataTest(); + + StatementDescriptorMetadataFactory factory = new ThreadDaoImplStatementDescriptorRegistration(); + DescriptorMetadata data = factory.getDescriptorMetadata(ThreadDaoImpl.QUERY_THREAD_INFO_INTERVAL, triple.third); assertThreadMetadata(triple, data); }
--- a/thread/collector/src/test/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoImplTest.java Fri Oct 04 19:34:29 2013 +0200 +++ b/thread/collector/src/test/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoImplTest.java Wed Oct 16 12:40:04 2013 -0400 @@ -40,18 +40,23 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; +import java.util.List; import java.util.NoSuchElementException; +import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; +import com.redhat.thermostat.common.model.Range; import com.redhat.thermostat.storage.core.Cursor; import com.redhat.thermostat.storage.core.DescriptorParsingException; import com.redhat.thermostat.storage.core.HostRef; @@ -64,11 +69,28 @@ import com.redhat.thermostat.storage.model.Pojo; import com.redhat.thermostat.thread.dao.ThreadDao; import com.redhat.thermostat.thread.model.ThreadHarvestingStatus; +import com.redhat.thermostat.thread.model.ThreadInfoData; import com.redhat.thermostat.thread.model.VMThreadCapabilities; import com.redhat.thermostat.thread.model.VmDeadLockData; public class ThreadDaoImplTest { + private static final String AGENT_ID = "0xcafe"; + private static final String VM_ID = "VM42"; + + private VmRef vmRef; + private HostRef hostRef; + + @Before + public void setUp() { + hostRef = mock(HostRef.class); + when(hostRef.getAgentId()).thenReturn(AGENT_ID); + + vmRef = mock(VmRef.class); + when(vmRef.getHostRef()).thenReturn(hostRef); + when(vmRef.getVmId()).thenReturn(VM_ID); + } + @Test public void preparedQueryDescriptorsAreSane() { String expectedQueryThreadCaps = "QUERY vm-thread-capabilities WHERE 'agentId' = ?s AND 'vmId' = ?s LIMIT 1"; @@ -79,8 +101,14 @@ assertEquals(expectedQuerySummarySince, ThreadDaoImpl.QUERY_SUMMARY_SINCE); String expectedQueryLatestHarvestingStatus = "QUERY vm-thread-harvesting WHERE 'agentId' = ?s AND 'vmId' = ?s SORT 'timeStamp' DSC LIMIT 1"; assertEquals(expectedQueryLatestHarvestingStatus, ThreadDaoImpl.QUERY_LATEST_HARVESTING_STATUS); - String expectedQueryThreadInfo = "QUERY vm-thread-info WHERE 'agentId' = ?s AND 'vmId' = ?s AND 'timeStamp' > ?l SORT 'timeStamp' DSC"; - assertEquals(expectedQueryThreadInfo, ThreadDaoImpl.QUERY_THREAD_INFO); + String expectedQueryThreadInfoSince = "QUERY vm-thread-info WHERE 'agentId' = ?s AND 'vmId' = ?s AND 'timeStamp' > ?l SORT 'timeStamp' DSC"; + assertEquals(expectedQueryThreadInfoSince, ThreadDaoImpl.QUERY_THREAD_INFO_SINCE); + String expectedQueryThreadInfoInterval = "QUERY vm-thread-info WHERE 'agentId' = ?s AND 'vmId' = ?s AND 'timeStamp' > ?l AND 'timeStamp' < ?l SORT 'timeStamp' DSC"; + assertEquals(expectedQueryThreadInfoInterval, ThreadDaoImpl.QUERY_THREAD_INFO_INTERVAL); + String expectedQueryLatestThreadInfo = "QUERY vm-thread-info WHERE 'agentId' = ?s AND 'vmId' = ?s SORT 'timeStamp' DSC LIMIT 1"; + assertEquals(expectedQueryLatestThreadInfo, ThreadDaoImpl.QUERY_LATEST_THREAD_INFO); + String expectedQueryOldestThreadInfo = "QUERY vm-thread-info WHERE 'agentId' = ?s AND 'vmId' = ?s SORT 'timeStamp' ASC LIMIT 1"; + assertEquals(expectedQueryOldestThreadInfo, ThreadDaoImpl.QUERY_OLDEST_THREAD_INFO); String expectedQueryThreadLatestDeadlockInfo = "QUERY vm-deadlock-data WHERE 'agentId' = ?s AND 'vmId' = ?s SORT 'timeStamp' DSC LIMIT 1"; assertEquals(expectedQueryThreadLatestDeadlockInfo, ThreadDaoImpl.QUERY_LATEST_DEADLOCK_INFO); String addThreadSummary = "ADD vm-thread-summary SET 'agentId' = ?s , " + @@ -137,16 +165,8 @@ PreparedStatement<VMThreadCapabilities> stmt = (PreparedStatement<VMThreadCapabilities>) mock(PreparedStatement.class); Storage storage = mock(Storage.class); when(storage.prepareStatement(anyDescriptor(VMThreadCapabilities.class))).thenReturn(stmt); - VmRef ref = mock(VmRef.class); - when(ref.getVmId()).thenReturn("VM42"); - - String agentId = "0xcafe"; - HostRef agent = mock(HostRef.class); - when(agent.getAgentId()).thenReturn(agentId); - - when(ref.getHostRef()).thenReturn(agent); - VMThreadCapabilities expected = new VMThreadCapabilities(agentId); + VMThreadCapabilities expected = new VMThreadCapabilities(AGENT_ID); expected.setSupportedFeaturesList(new String[] { ThreadDao.CPU_TIME, ThreadDao.THREAD_ALLOCATED_MEMORY }); @SuppressWarnings("unchecked") Cursor<VMThreadCapabilities> cursor = (Cursor<VMThreadCapabilities>) mock(Cursor.class); @@ -155,11 +175,11 @@ when(stmt.executeQuery()).thenReturn(cursor); ThreadDaoImpl dao = new ThreadDaoImpl(storage); - VMThreadCapabilities caps = dao.loadCapabilities(ref); + VMThreadCapabilities caps = dao.loadCapabilities(vmRef); verify(storage).prepareStatement(anyDescriptor(VMThreadCapabilities.class)); - verify(stmt).setString(0, "0xcafe"); - verify(stmt).setString(1, "VM42"); + verify(stmt).setString(0, AGENT_ID); + verify(stmt).setString(1, VM_ID); verify(stmt).executeQuery(); verifyNoMoreInteractions(stmt); @@ -179,16 +199,8 @@ PreparedStatement<VMThreadCapabilities> stmt = (PreparedStatement<VMThreadCapabilities>) mock(PreparedStatement.class); Storage storage = mock(Storage.class); when(storage.prepareStatement(anyDescriptor(VMThreadCapabilities.class))).thenReturn(stmt); - VmRef ref = mock(VmRef.class); - when(ref.getVmId()).thenReturn("VM42"); - String agentId = "0xcafe"; - HostRef agent = mock(HostRef.class); - when(agent.getAgentId()).thenReturn(agentId); - - when(ref.getHostRef()).thenReturn(agent); - - VMThreadCapabilities expected = new VMThreadCapabilities(agentId); + VMThreadCapabilities expected = new VMThreadCapabilities(AGENT_ID); expected.setSupportedFeaturesList(new String[] { ThreadDao.CPU_TIME, ThreadDao.THREAD_ALLOCATED_MEMORY }); @SuppressWarnings("unchecked") Cursor<VMThreadCapabilities> cursor = (Cursor<VMThreadCapabilities>) mock(Cursor.class); @@ -197,11 +209,11 @@ when(stmt.executeQuery()).thenReturn(cursor); ThreadDaoImpl dao = new ThreadDaoImpl(storage); - VMThreadCapabilities caps = dao.loadCapabilities(ref); + VMThreadCapabilities caps = dao.loadCapabilities(vmRef); verify(storage).prepareStatement(anyDescriptor(VMThreadCapabilities.class)); - verify(stmt).setString(0, "0xcafe"); - verify(stmt).setString(1, "VM42"); + verify(stmt).setString(0, AGENT_ID); + verify(stmt).setString(1, VM_ID); verify(stmt).executeQuery(); verifyNoMoreInteractions(stmt); @@ -211,13 +223,11 @@ @SuppressWarnings("unchecked") @Test public void testSaveVMCapabilities() throws DescriptorParsingException, StatementExecutionException { - String agentId = "fooAgent"; Storage storage = mock(Storage.class); PreparedStatement<AgentInformation> replace = mock(PreparedStatement.class); when(storage.prepareStatement(any(StatementDescriptor.class))).thenReturn(replace); - - String vmId = "VM42"; - VMThreadCapabilities caps = new VMThreadCapabilities(agentId); + + VMThreadCapabilities caps = new VMThreadCapabilities(AGENT_ID); String[] capsFeatures = new String[] { ThreadDao.CONTENTION_MONITOR, ThreadDao.CPU_TIME, @@ -227,7 +237,7 @@ assertTrue(caps.supportContentionMonitor()); assertTrue(caps.supportCPUTime()); assertTrue(caps.supportThreadAllocatedMemory()); - caps.setVmId(vmId); + caps.setVmId(VM_ID); ThreadDaoImpl dao = new ThreadDaoImpl(storage); dao.saveCapabilities(caps); @@ -251,10 +261,10 @@ @Test public void testLoadLatestDeadLockStatus() throws DescriptorParsingException, StatementExecutionException { VmRef vm = mock(VmRef.class); - when(vm.getVmId()).thenReturn("VM42"); + when(vm.getVmId()).thenReturn(VM_ID); HostRef agent = mock(HostRef.class); - when(agent.getAgentId()).thenReturn("0xcafe"); + when(agent.getAgentId()).thenReturn(AGENT_ID); when(vm.getHostRef()).thenReturn(agent); Storage storage = mock(Storage.class); @@ -275,8 +285,8 @@ assertSame(data, result); verify(storage).prepareStatement(anyDescriptor(VmDeadLockData.class)); - verify(stmt).setString(0, "0xcafe"); - verify(stmt).setString(1, "VM42"); + verify(stmt).setString(0, AGENT_ID); + verify(stmt).setString(1, VM_ID); verify(stmt).executeQuery(); verifyNoMoreInteractions(stmt); } @@ -311,13 +321,6 @@ @Test public void testGetLatestHarvestingStatus() throws DescriptorParsingException, StatementExecutionException { - VmRef vm = mock(VmRef.class); - when(vm.getVmId()).thenReturn("VM42"); - - HostRef agent = mock(HostRef.class); - when(agent.getAgentId()).thenReturn("0xcafe"); - when(vm.getHostRef()).thenReturn(agent); - Storage storage = mock(Storage.class); @SuppressWarnings("unchecked") PreparedStatement<ThreadHarvestingStatus> stmt = (PreparedStatement<ThreadHarvestingStatus>) mock(PreparedStatement.class); @@ -331,11 +334,11 @@ when(stmt.executeQuery()).thenReturn(cursor); ThreadDaoImpl dao = new ThreadDaoImpl(storage); - ThreadHarvestingStatus result = dao.getLatestHarvestingStatus(vm); + ThreadHarvestingStatus result = dao.getLatestHarvestingStatus(vmRef); verify(storage).prepareStatement(anyDescriptor(ThreadHarvestingStatus.class)); - verify(stmt).setString(0, "0xcafe"); - verify(stmt).setString(1, "VM42"); + verify(stmt).setString(0, AGENT_ID); + verify(stmt).setString(1, VM_ID); verify(stmt).executeQuery(); verifyNoMoreInteractions(stmt); @@ -368,5 +371,157 @@ verify(add).execute(); verifyNoMoreInteractions(add); } + + @Test + public void testSaveThreadInfo() throws DescriptorParsingException, StatementExecutionException { + final String THREAD_NAME = "name of a thread"; + final long THREAD_ID = 0xcafebabe; + final String THREAD_STATE = Thread.State.RUNNABLE.toString(); + final long ALLOCATED_BYTES = 0xbadbeef; + final long TIMESTAMP = 0xdeadbeef; + final long CPU_TIME = 42; + final long USER_TIME = 24; + final long BLOCKED_COUNT = 22; + final long WAIT_COUNT = 33; + + Storage storage = mock(Storage.class); + PreparedStatement<ThreadInfoData> add = mock(PreparedStatement.class); + when(storage.prepareStatement(any(StatementDescriptor.class))).thenReturn(add); + + // not using mocks because ThreadInfoData is really a data holder (no logic) + ThreadInfoData threadInfo = new ThreadInfoData(); + threadInfo.setAgentId(AGENT_ID); + threadInfo.setVmId(VM_ID); + threadInfo.setThreadName(THREAD_NAME); + threadInfo.setThreadId(THREAD_ID); + threadInfo.setThreadState(THREAD_STATE); + threadInfo.setAllocatedBytes(ALLOCATED_BYTES); + threadInfo.setTimeStamp(TIMESTAMP); + threadInfo.setThreadCpuTime(CPU_TIME); + threadInfo.setThreadUserTime(USER_TIME); + threadInfo.setThreadBlockedCount(BLOCKED_COUNT); + threadInfo.setThreadWaitCount(WAIT_COUNT); + + ThreadDaoImpl dao = new ThreadDaoImpl(storage); + dao.saveThreadInfo(threadInfo); + + verify(add).setString(0, AGENT_ID); + verify(add).setString(1, VM_ID); + verify(add).setString(2, THREAD_NAME); + verify(add).setLong(3, THREAD_ID); + verify(add).setString(4, THREAD_STATE); + verify(add).setLong(5, ALLOCATED_BYTES); + verify(add).setLong(6, TIMESTAMP); + verify(add).setLong(7, CPU_TIME); + verify(add).setLong(8, USER_TIME); + verify(add).setLong(9, BLOCKED_COUNT); + verify(add).setLong(10, WAIT_COUNT); + verify(add).execute(); + verifyNoMoreInteractions(add); + } + + @Test + public void testThreadInfoTimeRange() throws DescriptorParsingException, StatementExecutionException { + final long OLDEST_TIMESTAMP = 0; + final long LATEST_TIMESTAMP = 1999; + + ThreadInfoData oldestData = new ThreadInfoData(); + oldestData.setTimeStamp(OLDEST_TIMESTAMP); + + ThreadInfoData latestData = new ThreadInfoData(); + latestData.setTimeStamp(LATEST_TIMESTAMP); + + StatementDescriptor<ThreadInfoData> oldestThreadQueryDescriptor + = new StatementDescriptor<>(ThreadDaoImpl.THREAD_INFO, ThreadDaoImpl.QUERY_OLDEST_THREAD_INFO); + + StatementDescriptor<ThreadInfoData> latestThreadQueryDescriptor + = new StatementDescriptor<>(ThreadDaoImpl.THREAD_INFO, ThreadDaoImpl.QUERY_LATEST_THREAD_INFO); + + Cursor<ThreadInfoData> oldestThreadQueryCursor = mock(Cursor.class); + when(oldestThreadQueryCursor.hasNext()).thenReturn(true).thenReturn(false); + when(oldestThreadQueryCursor.next()).thenReturn(oldestData).thenThrow(IllegalStateException.class); + + Cursor<ThreadInfoData> latestThreadQueryCursor = mock(Cursor.class); + when(latestThreadQueryCursor.hasNext()).thenReturn(true).thenReturn(false); + when(latestThreadQueryCursor.next()).thenReturn(latestData).thenThrow(IllegalStateException.class); + + PreparedStatement<ThreadInfoData> oldestThreadQueryStatement = mock(PreparedStatement.class); + when(oldestThreadQueryStatement.executeQuery()).thenReturn(oldestThreadQueryCursor); + + PreparedStatement<ThreadInfoData> latestThreadQueryStatement = mock(PreparedStatement.class); + when(latestThreadQueryStatement.executeQuery()).thenReturn(latestThreadQueryCursor); + + Storage storage = mock(Storage.class); + when(storage.prepareStatement(any(StatementDescriptor.class))) + .thenReturn(oldestThreadQueryStatement) + .thenReturn(latestThreadQueryStatement); + + ThreadDaoImpl dao = new ThreadDaoImpl(storage); + + Range<Long> result = dao.getThreadInfoTimeRange(vmRef); + + assertEquals((Long) OLDEST_TIMESTAMP, result.getMin()); + assertEquals((Long) LATEST_TIMESTAMP, result.getMax()); + } + + @Test + public void testLoadThreadInfoSince() throws DescriptorParsingException, StatementExecutionException { + final long SINCE_TIMESTAMP = 100; + + Storage storage = mock(Storage.class); + PreparedStatement<ThreadInfoData> query = mock(PreparedStatement.class); + when(storage.prepareStatement(any(StatementDescriptor.class))).thenReturn(query); + + @SuppressWarnings("unchecked") + Cursor<ThreadInfoData> cursor = (Cursor<ThreadInfoData>) mock(Cursor.class); + ThreadInfoData info = mock(ThreadInfoData.class); + + when(cursor.hasNext()).thenReturn(true).thenReturn(false); + when(cursor.next()).thenReturn(info).thenReturn(null); + when(query.executeQuery()).thenReturn(cursor); + + ThreadDaoImpl dao = new ThreadDaoImpl(storage); + List<ThreadInfoData> result = dao.loadThreadInfo(vmRef, SINCE_TIMESTAMP); + + verify(query).setString(0, AGENT_ID); + verify(query).setString(1, VM_ID); + verify(query).setLong(2, SINCE_TIMESTAMP); + verify(query).executeQuery(); + verifyNoMoreInteractions(query); + + assertEquals(1, result.size()); + assertEquals(info, result.get(0)); + } + + @Test + public void testLoadThreadInfoForRange() throws StatementExecutionException, DescriptorParsingException { + final long SINCE_TIMESTAMP = 100; + final long TO_TIMESTAMP = 10000; + + Storage storage = mock(Storage.class); + PreparedStatement<ThreadInfoData> query = mock(PreparedStatement.class); + when(storage.prepareStatement(any(StatementDescriptor.class))).thenReturn(query); + + @SuppressWarnings("unchecked") + Cursor<ThreadInfoData> cursor = (Cursor<ThreadInfoData>) mock(Cursor.class); + ThreadInfoData info = mock(ThreadInfoData.class); + + when(cursor.hasNext()).thenReturn(true).thenReturn(false); + when(cursor.next()).thenReturn(info).thenReturn(null); + when(query.executeQuery()).thenReturn(cursor); + + ThreadDaoImpl dao = new ThreadDaoImpl(storage); + List<ThreadInfoData> result = dao.loadThreadInfo(vmRef, new Range<Long>(SINCE_TIMESTAMP, TO_TIMESTAMP)); + + verify(query).setString(0, AGENT_ID); + verify(query).setString(1, VM_ID); + verify(query).setLong(2, SINCE_TIMESTAMP); + verify(query).setLong(3, TO_TIMESTAMP); + verify(query).executeQuery(); + verifyNoMoreInteractions(query); + + assertEquals(1, result.size()); + assertEquals(info, result.get(0)); + } }