# HG changeset patch # User Omair Majid # Date 1361903632 18000 # Node ID eec62a0c5457bd83733a9ad88a387217f6596a19 # Parent 8dfbb3b87fcd94296fb9d21bf5c842b2ba75cc34 VM capabilities section is empty Reviewed-by: jerboaa, vanaltj Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2013-February/005845.html diff -r 8dfbb3b87fcd -r eec62a0c5457 common/core/src/main/java/com/redhat/thermostat/common/ActionNotifier.java --- a/common/core/src/main/java/com/redhat/thermostat/common/ActionNotifier.java Tue Feb 26 13:23:34 2013 -0500 +++ b/common/core/src/main/java/com/redhat/thermostat/common/ActionNotifier.java Tue Feb 26 13:33:52 2013 -0500 @@ -38,9 +38,15 @@ import java.util.Collection; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.redhat.thermostat.common.utils.LoggingUtils; public class ActionNotifier> { + private static final Logger logger = LoggingUtils.getLogger(ActionNotifier.class); + public ActionNotifier(Object source) { this.source = source; listeners = new CopyOnWriteArrayList>(); @@ -59,17 +65,20 @@ } public void fireAction(T actionId) { - ActionEvent action = new ActionEvent<>(source, actionId); - for (ActionListener listener : listeners) { - listener.actionPerformed(action); - } + fireAction(actionId, null); } public void fireAction(T actionId, Object payload) { ActionEvent action = new ActionEvent<>(source, actionId); action.setPayload(payload); for (ActionListener listener : listeners) { - listener.actionPerformed(action); + try { + listener.actionPerformed(action); + } catch (Exception e) { + // a listener throwing exception is BAD + // unfortunately, all we can do is make sure other listeners continue working + logger.log(Level.WARNING, "a listener threw an unexpected exception", e); + } } } } diff -r 8dfbb3b87fcd -r eec62a0c5457 common/core/src/test/java/com/redhat/thermostat/common/ActionNotifierTest.java --- a/common/core/src/test/java/com/redhat/thermostat/common/ActionNotifierTest.java Tue Feb 26 13:23:34 2013 -0500 +++ b/common/core/src/test/java/com/redhat/thermostat/common/ActionNotifierTest.java Tue Feb 26 13:33:52 2013 -0500 @@ -38,9 +38,13 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.isA; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import org.junit.Test; @@ -88,6 +92,28 @@ } @Test + public void verifyListenersInvokedInPresenseOfExceptions() { + Object source = new Object(); + ActionNotifier notifier = new ActionNotifier(source); + @SuppressWarnings("unchecked") + ActionListener listener1 = mock(ActionListener.class); + @SuppressWarnings("unchecked") + ActionListener listener2 = mock(ActionListener.class); + doThrow(new IllegalArgumentException("ignore")).when(listener2).actionPerformed(isA(ActionEvent.class)); + @SuppressWarnings("unchecked") + ActionListener listener3 = mock(ActionListener.class); + notifier.addActionListener(listener1); + notifier.addActionListener(listener2); + notifier.addActionListener(listener3); + + notifier.fireAction(TestId.TEST_ID1); + + verify(listener1).actionPerformed(new ActionEvent(source, TestId.TEST_ID1)); + verify(listener2).actionPerformed(new ActionEvent(source, TestId.TEST_ID1)); + verify(listener3).actionPerformed(new ActionEvent(source, TestId.TEST_ID1)); + } + + @Test public void verifyRemoveListener() { Object source = new Object(); ActionNotifier viewActionSupport = new ActionNotifier(source); diff -r 8dfbb3b87fcd -r eec62a0c5457 thread/client-common/src/main/java/com/redhat/thermostat/thread/client/common/collector/impl/ThreadMXBeanCollector.java --- a/thread/client-common/src/main/java/com/redhat/thermostat/thread/client/common/collector/impl/ThreadMXBeanCollector.java Tue Feb 26 13:23:34 2013 -0500 +++ b/thread/client-common/src/main/java/com/redhat/thermostat/thread/client/common/collector/impl/ThreadMXBeanCollector.java Tue Feb 26 13:33:52 2013 -0500 @@ -240,6 +240,7 @@ try { latch.await(); + // FIXME there is no guarantee that data is now present in storage caps = threadDao.loadCapabilities(ref); } catch (InterruptedException ignore) { caps = new VMThreadCapabilities(); diff -r 8dfbb3b87fcd -r eec62a0c5457 thread/collector/src/main/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoImpl.java --- a/thread/collector/src/main/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoImpl.java Tue Feb 26 13:23:34 2013 -0500 +++ b/thread/collector/src/main/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoImpl.java Tue Feb 26 13:33:52 2013 -0500 @@ -69,7 +69,11 @@ query.where(Key.VM_ID, Query.Criteria.EQUALS, vm.getId()); query.where(Key.AGENT_ID, Query.Criteria.EQUALS, vm.getAgent().getAgentId()); query.limit(1); - VMThreadCapabilities caps = query.execute().next(); + Cursor cursor = query.execute(); + if (!cursor.hasNext()) { + return null; + } + VMThreadCapabilities caps = cursor.next(); return caps; } diff -r 8dfbb3b87fcd -r eec62a0c5457 thread/collector/src/test/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoImplTest.java --- a/thread/collector/src/test/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoImplTest.java Tue Feb 26 13:23:34 2013 -0500 +++ b/thread/collector/src/test/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoImplTest.java Tue Feb 26 13:33:52 2013 -0500 @@ -36,6 +36,7 @@ package com.redhat.thermostat.thread.dao.impl; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; @@ -44,6 +45,8 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; +import java.util.NoSuchElementException; + import org.junit.Test; import com.redhat.thermostat.storage.core.Category; @@ -108,6 +111,38 @@ } @Test + public void testLoadVMCapabilitiesWithoutAnyDataInStorage() { + Query query = mock(Query.class); + Storage storage = mock(Storage.class); + when(storage.createQuery(any(Category.class))).thenReturn(query); + VmRef ref = mock(VmRef.class); + when(ref.getId()).thenReturn(42); + + HostRef agent = mock(HostRef.class); + when(agent.getAgentId()).thenReturn("0xcafe"); + + when(ref.getAgent()).thenReturn(agent); + + VMThreadCapabilities expected = new VMThreadCapabilities(); + expected.setSupportedFeaturesList(new String[] { ThreadDao.CPU_TIME, ThreadDao.THREAD_ALLOCATED_MEMORY }); + Cursor cursor = mock(Cursor.class); + when(cursor.hasNext()).thenReturn(false); + when(cursor.next()).thenThrow(new NoSuchElementException()); + when(query.execute()).thenReturn(cursor); + + ThreadDaoImpl dao = new ThreadDaoImpl(storage); + VMThreadCapabilities caps = dao.loadCapabilities(ref); + + verify(query).where(Key.VM_ID, Criteria.EQUALS, 42); + verify(query).where(Key.AGENT_ID, Criteria.EQUALS, "0xcafe"); + verify(query).limit(1); + verify(query).execute(); + verifyNoMoreInteractions(query); + + assertEquals(null, caps); + } + + @Test public void testSaveVMCapabilities() { Storage storage = mock(Storage.class); Replace replace = mock(Replace.class);