changeset 1950:8ea5f5f57cd9

Don't throw NPE when there is no VM class stats data. PR3032 Reviewed-by: neugens Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2016-June/019900.html
author Jie Kang <jkang@redhat.com>
date Mon, 27 Jun 2016 14:59:37 -0400
parents 311aeb2c95aa
children 569595f0f2bb
files vm-classstat/client-core/src/main/java/com/redhat/thermostat/vm/classstat/client/core/internal/VmClassStatController.java vm-classstat/client-core/src/test/java/com/redhat/thermostat/vm/classstat/client/core/internal/VmClassStatControllerTest.java
diffstat 2 files changed, 44 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/vm-classstat/client-core/src/main/java/com/redhat/thermostat/vm/classstat/client/core/internal/VmClassStatController.java	Fri Jun 24 15:04:08 2016 -0400
+++ b/vm-classstat/client-core/src/main/java/com/redhat/thermostat/vm/classstat/client/core/internal/VmClassStatController.java	Mon Jun 27 14:59:37 2016 -0400
@@ -76,6 +76,10 @@
         public void run() {
             VmClassStat oldest = dao.getOldest(ref);
             VmClassStat newest = dao.getNewest(ref);
+            // Do nothing when there is no data
+            if (oldest == null || newest == null) {
+                return;
+            }
 
             final List<DiscreteTimeData<? extends Number>> loadedClasses = new LinkedList<>();
             final List<DiscreteTimeData<? extends Number>> loadedBytes = new LinkedList<>();
--- a/vm-classstat/client-core/src/test/java/com/redhat/thermostat/vm/classstat/client/core/internal/VmClassStatControllerTest.java	Fri Jun 24 15:04:08 2016 -0400
+++ b/vm-classstat/client-core/src/test/java/com/redhat/thermostat/vm/classstat/client/core/internal/VmClassStatControllerTest.java	Mon Jun 27 14:59:37 2016 -0400
@@ -48,6 +48,7 @@
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 
+import org.junit.Before;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 
@@ -65,10 +66,20 @@
 
 public class VmClassStatControllerTest {
 
-    @SuppressWarnings({ "unchecked", "rawtypes" }) // any(List.class)
+    private ActionListener<VmClassStatView.Action> listener;
+    private Timer timer;
+    private VmClassStatView view;
+    private VmRef ref;
+    private Runnable timerAction;
+
+    @Before
+    public void setup() {
+        ref = mock(VmRef.class);
+    }
+
+    @SuppressWarnings({ "unchecked" })
     @Test
     public void testChartUpdate() {
-
         final long SOME_TIMESTAMP = 12345;
         final int SOME_VALUE = 1234;
 
@@ -79,13 +90,33 @@
 
         VmClassStatDAO vmClassStatDAO = mock(VmClassStatDAO.class);
 
-        VmRef ref = mock(VmRef.class);
-
         when(vmClassStatDAO.getLatestClassStats(any(VmRef.class), any(Long.class))).thenThrow(new AssertionError("Unbounded queries are bad!"));
         when(vmClassStatDAO.getOldest(ref)).thenReturn(stat1);
         when(vmClassStatDAO.getNewest(ref)).thenReturn(stat1);
 
-        Timer timer = mock(Timer.class);
+        setupWithVmClassStatDAO(vmClassStatDAO);
+
+        listener.actionPerformed(new ActionEvent<>(view, VmClassStatView.Action.VISIBLE));
+
+        verify(timer).start();
+        timerAction.run();
+        verify(view, times(4)).addClassData(isA(String.class), isA(List.class));
+
+        listener.actionPerformed(new ActionEvent<>(view, VmClassStatView.Action.HIDDEN));
+
+        verify(timer).stop();
+    }
+
+    @Test
+    public void verifyNoClassStatDataDoesNotNPE() {
+        setupWithVmClassStatDAO(mock(VmClassStatDAO.class));
+        timerAction.run();
+    }
+
+    @SuppressWarnings("unchecked")
+    private void setupWithVmClassStatDAO(VmClassStatDAO vmClassStatDAO) {
+
+        timer = mock(Timer.class);
         ArgumentCaptor<Runnable> timerActionCaptor = ArgumentCaptor.forClass(Runnable.class);
         doNothing().when(timer).setAction(timerActionCaptor.capture());
 
@@ -94,7 +125,8 @@
         ApplicationService appSvc = mock(ApplicationService.class);
         when(appSvc.getTimerFactory()).thenReturn(timerFactory);
 
-        VmClassStatView view = mock(VmClassStatView.class);
+        view = mock(VmClassStatView.class);
+        @SuppressWarnings("rawtypes")
         ArgumentCaptor<ActionListener> viewArgumentCaptor = ArgumentCaptor.forClass(ActionListener.class);
         doNothing().when(view).addActionListener(viewArgumentCaptor.capture());
 
@@ -106,17 +138,8 @@
         @SuppressWarnings("unused")
         VmClassStatController controller = new VmClassStatController(appSvc, vmClassStatDAO, ref, viewProvider);
 
-        ActionListener<VmClassStatView.Action> l = viewArgumentCaptor.getValue();
-
-        l.actionPerformed(new ActionEvent<>(view, VmClassStatView.Action.VISIBLE));
-
-        verify(timer).start();
-        timerActionCaptor.getValue().run();
-        verify(view, times(4)).addClassData(isA(String.class), isA(List.class));
-
-        l.actionPerformed(new ActionEvent<>(view, VmClassStatView.Action.HIDDEN));
-
-        verify(timer).stop();
+        listener = viewArgumentCaptor.getValue();
+        timerAction = timerActionCaptor.getValue();
     }
 
 }