changeset 1934:8942de6227a9

Don't throw NPE when there is no VM CPU data Backport of cb454e33ddcf from HEAD. PR3032 Reviewed-by: jkang Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2016-June/019688.html
author Alex Macdonald <almacdon@redhat.com>
date Thu, 23 Jun 2016 10:17:51 -0400
parents c5dc33321342
children 5935a4e822ba
files vm-cpu/client-core/src/main/java/com/redhat/thermostat/vm/cpu/client/core/internal/VmCpuController.java vm-cpu/client-core/src/test/java/com/redhat/thermostat/vm/cpu/client/core/internal/VmCpuControllerTest.java
diffstat 2 files changed, 50 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/vm-cpu/client-core/src/main/java/com/redhat/thermostat/vm/cpu/client/core/internal/VmCpuController.java	Thu Jun 23 09:21:02 2016 -0400
+++ b/vm-cpu/client-core/src/main/java/com/redhat/thermostat/vm/cpu/client/core/internal/VmCpuController.java	Thu Jun 23 10:17:51 2016 -0400
@@ -137,10 +137,15 @@
     }
 
     private void updateData() {
+        VmCpuStat oldest = dao.getOldest(ref);
+        VmCpuStat newest = dao.getNewest(ref);
+        // Do nothing when there is no data
+        if (oldest == null || newest == null) {
+            return;
+        }
+        
         final List<DiscreteTimeData<? extends Number>> data = new ArrayList<>();
 
-        VmCpuStat oldest = dao.getOldest(ref);
-        VmCpuStat newest = dao.getNewest(ref);
 
         Range<Long> newAvailableRange = new Range<>(oldest.getTimeStamp(), newest.getTimeStamp());
 
--- a/vm-cpu/client-core/src/test/java/com/redhat/thermostat/vm/cpu/client/core/internal/VmCpuControllerTest.java	Thu Jun 23 09:21:02 2016 -0400
+++ b/vm-cpu/client-core/src/test/java/com/redhat/thermostat/vm/cpu/client/core/internal/VmCpuControllerTest.java	Thu Jun 23 10:17:51 2016 -0400
@@ -46,6 +46,7 @@
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 
+import org.junit.Before;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 
@@ -62,12 +63,21 @@
 import com.redhat.thermostat.vm.cpu.common.model.VmCpuStat;
 
 public class VmCpuControllerTest {
+    
+    private ActionListener<VmCpuView.Action> listener;
+    private Timer timer;
+    private Runnable timerAction;
+    private VmCpuView view;
+    private VmRef ref;
+    
+    @Before
+    public void setup() {
+        ref = mock(VmRef.class);
+    }
 
-    @SuppressWarnings({ "unchecked", "rawtypes" }) // any(List.class)
+    @SuppressWarnings({ "unchecked"}) // any(List.class)
     @Test
     public void testChartUpdate() {
-        VmRef ref = mock(VmRef.class);
-
         VmCpuStat stat1 = new VmCpuStat("foo-agent", 123, "vmId", 50.5);
         List<VmCpuStat> stats = new ArrayList<VmCpuStat>();
         stats.add(stat1);
@@ -76,8 +86,32 @@
         when(vmCpuStatDAO.getLatestVmCpuStats(any(VmRef.class), any(Long.class))).thenThrow(new AssertionError("Unbounded queries are bad!"));
         when(vmCpuStatDAO.getOldest(ref)).thenReturn(stat1);
         when(vmCpuStatDAO.getNewest(ref)).thenReturn(stat1);
+        
+        setupWithVmCPUStatDAO(vmCpuStatDAO);
 
-        Timer timer = mock(Timer.class);
+        listener.actionPerformed(new ActionEvent<>(view, VmCpuView.Action.VISIBLE));
+
+        verify(timer).start();
+
+        timerAction.run();
+
+        listener.actionPerformed(new ActionEvent<>(view, VmCpuView.Action.HIDDEN));
+
+        verify(timer).stop();
+
+        verify(view).addData(any(List.class));
+        // We don't verify atMost() since we might increase the update rate in the future.
+    }
+    
+    @Test
+    public void verifyNoNPEWhenNoCpuData() {
+        setupWithVmCPUStatDAO(mock(VmCpuStatDAO.class));
+        timerAction.run();
+    }
+
+    @SuppressWarnings("unchecked")
+    private void setupWithVmCPUStatDAO(VmCpuStatDAO dao) {
+        timer = mock(Timer.class);
         ArgumentCaptor<Runnable> timerActionCaptor = ArgumentCaptor.forClass(Runnable.class);
         doNothing().when(timer).setAction(timerActionCaptor.capture());
 
@@ -86,7 +120,8 @@
         ApplicationService appSvc = mock(ApplicationService.class);
         when(appSvc.getTimerFactory()).thenReturn(timerFactory);
 
-        final VmCpuView view = mock(VmCpuView.class);
+        view = mock(VmCpuView.class);
+        @SuppressWarnings("rawtypes")
         ArgumentCaptor<ActionListener> viewArgumentCaptor = ArgumentCaptor.forClass(ActionListener.class);
         doNothing().when(view).addActionListener(viewArgumentCaptor.capture());
 
@@ -96,22 +131,9 @@
         when(viewProvider.createView()).thenReturn(view);
 
         @SuppressWarnings("unused")
-        VmCpuController controller = new VmCpuController(appSvc, vmCpuStatDAO, ref, viewProvider);
-
-        ActionListener<VmCpuView.Action> l = viewArgumentCaptor.getValue();
-
-        l.actionPerformed(new ActionEvent<>(view, VmCpuView.Action.VISIBLE));
-
-        verify(timer).start();
-
-        timerActionCaptor.getValue().run();
-
-        l.actionPerformed(new ActionEvent<>(view, VmCpuView.Action.HIDDEN));
-
-        verify(timer).stop();
-
-        verify(view).addData(any(List.class));
-        // We don't verify atMost() since we might increase the update rate in the future.
+        VmCpuController controller = new VmCpuController(appSvc, dao, ref, viewProvider);
+        listener = viewArgumentCaptor.getValue();
+        timerAction = timerActionCaptor.getValue();
     }
 }