changeset 1006:eec62a0c5457

VM capabilities section is empty Reviewed-by: jerboaa, vanaltj Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2013-February/005845.html
author Omair Majid <omajid@redhat.com>
date Tue, 26 Feb 2013 13:33:52 -0500
parents 8dfbb3b87fcd
children 53ce942c35c1
files common/core/src/main/java/com/redhat/thermostat/common/ActionNotifier.java common/core/src/test/java/com/redhat/thermostat/common/ActionNotifierTest.java thread/client-common/src/main/java/com/redhat/thermostat/thread/client/common/collector/impl/ThreadMXBeanCollector.java thread/collector/src/main/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoImpl.java thread/collector/src/test/java/com/redhat/thermostat/thread/dao/impl/ThreadDaoImplTest.java
diffstat 5 files changed, 81 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- 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<T extends Enum<?>> {
 
+    private static final Logger logger = LoggingUtils.getLogger(ActionNotifier.class);
+
     public ActionNotifier(Object source) {
         this.source = source;
         listeners = new CopyOnWriteArrayList<ActionListener<T>>();
@@ -59,17 +65,20 @@
     }
 
     public void fireAction(T actionId) {
-        ActionEvent<T> action = new ActionEvent<>(source, actionId);
-        for (ActionListener<T> listener : listeners) {
-            listener.actionPerformed(action);
-        }
+        fireAction(actionId, null);
     }
 
     public void fireAction(T actionId, Object payload) {
         ActionEvent<T> action = new ActionEvent<>(source, actionId);
         action.setPayload(payload);
         for (ActionListener<T> 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);
+            }
         }
     }
 }
--- 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<TestId> notifier = new ActionNotifier<TestId>(source);
+        @SuppressWarnings("unchecked")
+        ActionListener<TestId> listener1 = mock(ActionListener.class);
+        @SuppressWarnings("unchecked")
+        ActionListener<TestId> listener2 = mock(ActionListener.class);
+        doThrow(new IllegalArgumentException("ignore")).when(listener2).actionPerformed(isA(ActionEvent.class));
+        @SuppressWarnings("unchecked")
+        ActionListener<TestId> listener3 = mock(ActionListener.class);
+        notifier.addActionListener(listener1);
+        notifier.addActionListener(listener2);
+        notifier.addActionListener(listener3);
+
+        notifier.fireAction(TestId.TEST_ID1);
+
+        verify(listener1).actionPerformed(new ActionEvent<TestId>(source, TestId.TEST_ID1));
+        verify(listener2).actionPerformed(new ActionEvent<TestId>(source, TestId.TEST_ID1));
+        verify(listener3).actionPerformed(new ActionEvent<TestId>(source, TestId.TEST_ID1));
+    }
+
+    @Test
     public void verifyRemoveListener() {
         Object source = new Object();
         ActionNotifier<TestId> viewActionSupport = new ActionNotifier<TestId>(source);
--- 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();
--- 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<VMThreadCapabilities> cursor = query.execute();
+        if (!cursor.hasNext()) {
+            return null;
+        }
+        VMThreadCapabilities caps = cursor.next();
         return caps;
     }
     
--- 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);