Mercurial > hg > release > thermostat-0.15
changeset 263:9a1a69250ee2
Merge
author | Roman Kennke <rkennke@redhat.com> |
---|---|
date | Tue, 24 Apr 2012 14:15:34 +0200 |
parents | 8bd725ac3bdf (current diff) 0ad7fdcad47e (diff) |
children | 4d82fc25b016 |
files | |
diffstat | 17 files changed, 582 insertions(+), 111 deletions(-) [+] |
line wrap: on
line diff
--- a/client/src/main/java/com/redhat/thermostat/client/MainWindowControllerImpl.java Tue Apr 24 14:14:13 2012 +0200 +++ b/client/src/main/java/com/redhat/thermostat/client/MainWindowControllerImpl.java Tue Apr 24 14:15:34 2012 +0200 @@ -182,6 +182,7 @@ case SHUTDOWN: view.hideMainWindow(); stop(); + ApplicationContext.getInstance().getTimerFactory().shutdown(); break; default: throw new IllegalStateException("unhandled action");
--- a/client/src/main/java/com/redhat/thermostat/client/locale/LocaleResources.java Tue Apr 24 14:14:13 2012 +0200 +++ b/client/src/main/java/com/redhat/thermostat/client/locale/LocaleResources.java Tue Apr 24 14:15:34 2012 +0200 @@ -61,7 +61,7 @@ MENU_EDIT_ENABLE_HISTORY_MODE, MENU_HELP, MENU_HELP_ABOUT, - + GARBAGE_COLLECTION, YOUNG_GEN, EDEN_GEN, @@ -164,11 +164,10 @@ VM_CPU_CHART_LOAD_LABEL, VM_CPU_CHART_TIME_LABEL, - VM_CURRENT_MEMORY_CHART_USED, - VM_CURRENT_MEMORY_CHART_CAPACITY, - VM_CURRENT_MEMORY_CHART_MAX_CAPACITY, - VM_CURRENT_MEMORY_CHART_SPACE, - VM_CURRENT_MEMORY_CHART_SIZE, + VM_MEMORY_SPACE_TITLE, + VM_MEMORY_SPACE_USED, + VM_MEMORY_SPACE_FREE, + VM_MEMORY_SPACE_ADDITIONAL, VM_GC_COLLECTOR_OVER_GENERATION, VM_GC_COLLECTOR_CHART_REAL_TIME_LABEL,
--- a/client/src/main/java/com/redhat/thermostat/client/ui/IconResource.java Tue Apr 24 14:14:13 2012 +0200 +++ b/client/src/main/java/com/redhat/thermostat/client/ui/IconResource.java Tue Apr 24 14:15:34 2012 +0200 @@ -58,6 +58,8 @@ public static final IconResource NETWORK_SERVER = new IconResource(ICON_PREFIX + "48x48/places/network-server.png"); public static final IconResource NETWORK_GROUP = new IconResource(ICON_PREFIX + "48x48/places/network-workgroup.png"); + public static final IconResource ARROW_RIGHT = new IconResource(ICON_PREFIX + "48x48/actions/go-next.png"); + public static final IconResource SEARCH = new IconResource(ICON_PREFIX + "16x16/actions/search.png"); private final String path;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/src/main/java/com/redhat/thermostat/client/ui/MemorySpacePanel.java Tue Apr 24 14:15:34 2012 +0200 @@ -0,0 +1,109 @@ +/* + * Copyright 2012 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.client.ui; + +import javax.swing.GroupLayout; +import javax.swing.GroupLayout.Alignment; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JProgressBar; +import javax.swing.LayoutStyle.ComponentPlacement; + +public class MemorySpacePanel extends JPanel { + + private final JProgressBar percentagePanel; + private final JLabel additionalDetailsIcon; + private final JLabel lblUsed; + private final JLabel lblAvailable; + + public MemorySpacePanel(String regionName) { + JLabel lblRegionName = new JLabel(regionName); + + percentagePanel = new JProgressBar(0, 100); + + additionalDetailsIcon = new JLabel(IconResource.ARROW_RIGHT.getIcon()); + + lblUsed = new JLabel("${USED}"); + lblAvailable = new JLabel("${AVAILABLE}"); + + GroupLayout groupLayout = new GroupLayout(this); + groupLayout.setHorizontalGroup( + groupLayout.createParallelGroup(Alignment.LEADING) + .addGroup(groupLayout.createSequentialGroup() + .addContainerGap() + .addGroup(groupLayout.createParallelGroup(Alignment.LEADING) + .addComponent(lblRegionName) + .addGroup(groupLayout.createSequentialGroup() + .addGap(12) + .addGroup(groupLayout.createParallelGroup(Alignment.LEADING) + .addComponent(percentagePanel, GroupLayout.DEFAULT_SIZE, 574, Short.MAX_VALUE) + .addGroup(groupLayout.createSequentialGroup() + .addComponent(lblUsed) + .addPreferredGap(ComponentPlacement.RELATED, 441, Short.MAX_VALUE) + .addComponent(lblAvailable))))) + .addPreferredGap(ComponentPlacement.RELATED) + .addComponent(additionalDetailsIcon) + .addContainerGap()) + ); + groupLayout.setVerticalGroup( + groupLayout.createParallelGroup(Alignment.LEADING) + .addGroup(groupLayout.createSequentialGroup() + .addContainerGap() + .addComponent(lblRegionName) + .addPreferredGap(ComponentPlacement.RELATED) + .addGroup(groupLayout.createParallelGroup(Alignment.LEADING) + .addComponent(additionalDetailsIcon, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(percentagePanel, GroupLayout.DEFAULT_SIZE, 44, Short.MAX_VALUE)) + .addPreferredGap(ComponentPlacement.RELATED) + .addGroup(groupLayout.createParallelGroup(Alignment.BASELINE) + .addComponent(lblUsed) + .addComponent(lblAvailable)) + .addGap(5)) + ); + setLayout(groupLayout); + } + + + public void updateRegionData(int percentageUsed, String currentlyUsed, String currentlyAvailable, String allocatable) { + percentagePanel.setValue(percentageUsed); + + lblUsed.setText(currentlyUsed); + lblAvailable.setText(currentlyAvailable); + additionalDetailsIcon.setToolTipText(allocatable); + } + +}
--- a/client/src/main/java/com/redhat/thermostat/client/ui/VmMemoryController.java Tue Apr 24 14:14:13 2012 +0200 +++ b/client/src/main/java/com/redhat/thermostat/client/ui/VmMemoryController.java Tue Apr 24 14:15:34 2012 +0200 @@ -36,13 +36,17 @@ package com.redhat.thermostat.client.ui; +import static com.redhat.thermostat.client.locale.Translate.localize; + import java.awt.Component; +import java.util.ArrayList; import java.util.List; -import java.util.Timer; -import java.util.TimerTask; import java.util.concurrent.TimeUnit; import com.redhat.thermostat.client.AsyncUiFacade; +import com.redhat.thermostat.client.locale.LocaleResources; +import com.redhat.thermostat.common.Timer; +import com.redhat.thermostat.common.Timer.SchedulingType; import com.redhat.thermostat.common.appctx.ApplicationContext; import com.redhat.thermostat.common.dao.VmMemoryStatDAO; import com.redhat.thermostat.common.dao.VmRef; @@ -52,21 +56,19 @@ class VmMemoryController implements AsyncUiFacade { - private final VmRef ref; private final VmMemoryView view; private final VmMemoryStatDAO dao; - private final Timer timer = new Timer(); + private final Timer timer; + + private final List<String> spacesInView = new ArrayList<>(); - public VmMemoryController(VmRef ref) { - this.ref = ref; + public VmMemoryController(final VmRef ref) { dao = ApplicationContext.getInstance().getDAOFactory().getVmMemoryStatDAO(); + timer = ApplicationContext.getInstance().getTimerFactory().createTimer(); view = ApplicationContext.getInstance().getViewFactory().getView(VmMemoryView.class); - } - @Override - public void start() { - timer.scheduleAtFixedRate(new TimerTask() { + timer.setAction(new Runnable() { @Override public void run() { VmMemoryStat info = dao.getLatestMemoryStat(ref); @@ -74,18 +76,37 @@ for (Generation generation: generations) { List<Space> spaces = generation.spaces; for (Space space: spaces) { - view.setMemoryRegionSize(space.name, space.used, space.capacity, space.maxCapacity); + + if (!spacesInView.contains(space.name)) { + view.addRegion(space.name); + spacesInView.add(space.name); + } + + int percentageUsed = (int) (100.0 * space.used/space.capacity); + String currentlyUsed = localize(LocaleResources.VM_MEMORY_SPACE_USED, String.valueOf(space.used)); + String currentlyUnused = localize(LocaleResources.VM_MEMORY_SPACE_FREE, String.valueOf(space.capacity - space.used)); + String allocatable = localize(LocaleResources.VM_MEMORY_SPACE_ADDITIONAL, String.valueOf(space.maxCapacity-space.capacity)); + String name = space.name; // FIXME + view.updateRegionSize(name, percentageUsed, currentlyUsed, currentlyUnused, allocatable); + } } + } + }); + timer.setInitialDelay(0); + timer.setDelay(10); + timer.setTimeUnit(TimeUnit.MILLISECONDS); + timer.setSchedulingType(SchedulingType.FIXED_RATE); + } - } - - }, 0, TimeUnit.SECONDS.toMillis(5)); + @Override + public void start() { + timer.start(); } @Override public void stop() { - timer.cancel(); + timer.stop(); } public Component getComponent() {
--- a/client/src/main/java/com/redhat/thermostat/client/ui/VmMemoryPanel.java Tue Apr 24 14:14:13 2012 +0200 +++ b/client/src/main/java/com/redhat/thermostat/client/ui/VmMemoryPanel.java Tue Apr 24 14:15:34 2012 +0200 @@ -37,18 +37,17 @@ package com.redhat.thermostat.client.ui; import static com.redhat.thermostat.client.locale.Translate.localize; +import java.awt.Component; +import java.util.HashMap; +import java.util.Map; -import java.awt.Component; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; - +import javax.swing.GroupLayout; +import javax.swing.GroupLayout.Alignment; +import javax.swing.JLabel; import javax.swing.JPanel; - -import org.jfree.chart.ChartFactory; -import org.jfree.chart.ChartPanel; -import org.jfree.chart.JFreeChart; -import org.jfree.chart.plot.PlotOrientation; -import org.jfree.data.category.DefaultCategoryDataset; +import javax.swing.LayoutStyle.ComponentPlacement; +import javax.swing.BoxLayout; +import javax.swing.SwingUtilities; import com.redhat.thermostat.client.locale.LocaleResources; @@ -56,58 +55,77 @@ private static final long serialVersionUID = -2882890932814218436L; - private final DefaultCategoryDataset dataset = new DefaultCategoryDataset(); + private final Map<String, MemorySpacePanel> regions = new HashMap<>(); + + private final JPanel currentRegionSizePanel; public VmMemoryPanel() { - initializePanel(); + JLabel lblMem = new JLabel(localize(LocaleResources.VM_MEMORY_SPACE_TITLE)); + + currentRegionSizePanel = new JPanel(); + + GroupLayout groupLayout = new GroupLayout(this); + groupLayout.setHorizontalGroup( + groupLayout.createParallelGroup(Alignment.TRAILING) + .addGroup(groupLayout.createSequentialGroup() + .addContainerGap() + .addGroup(groupLayout.createParallelGroup(Alignment.LEADING) + .addGroup(groupLayout.createSequentialGroup() + .addComponent(currentRegionSizePanel, GroupLayout.DEFAULT_SIZE, 630, Short.MAX_VALUE) + .addContainerGap()) + .addGroup(Alignment.TRAILING, groupLayout.createSequentialGroup() + .addComponent(lblMem) + .addGap(491)))) + ); + groupLayout.setVerticalGroup( + groupLayout.createParallelGroup(Alignment.LEADING) + .addGroup(groupLayout.createSequentialGroup() + .addContainerGap() + .addComponent(lblMem) + .addPreferredGap(ComponentPlacement.RELATED) + .addComponent(currentRegionSizePanel, GroupLayout.DEFAULT_SIZE, 483, Short.MAX_VALUE) + .addContainerGap()) + ); + currentRegionSizePanel.setLayout(new BoxLayout(currentRegionSizePanel, BoxLayout.PAGE_AXIS)); + setLayout(groupLayout); + } @Override - public void setMemoryRegionSize(String name, long used, long allocated, long max) { - dataset.addValue(used, localize(LocaleResources.VM_CURRENT_MEMORY_CHART_USED), name); - dataset.addValue(allocated - used, - localize(LocaleResources.VM_CURRENT_MEMORY_CHART_CAPACITY), name); - dataset.addValue(max - allocated, - localize(LocaleResources.VM_CURRENT_MEMORY_CHART_MAX_CAPACITY), name); - } - - private void initializePanel() { - JPanel panel = this; - panel.setLayout(new GridBagLayout()); - GridBagConstraints c = new GridBagConstraints(); - c.gridx = 0; - c.gridy = 0; - c.fill = GridBagConstraints.BOTH; - c.weightx = 1; - c.weighty = 1; - panel.add(createCurrentMemoryDisplay(), c); - c.gridy++; - panel.add(createMemoryHistoryPanel(), c); + public void addRegion(final String humanReadableName) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + MemorySpacePanel regionInfo = new MemorySpacePanel(humanReadableName); + regions.put(humanReadableName, regionInfo); + currentRegionSizePanel.add(regionInfo); + currentRegionSizePanel.revalidate(); + } + }); } - private Component createCurrentMemoryDisplay() { - JFreeChart chart = ChartFactory.createStackedBarChart( - null, - localize(LocaleResources.VM_CURRENT_MEMORY_CHART_SPACE), - localize(LocaleResources.VM_CURRENT_MEMORY_CHART_SIZE), - dataset, - PlotOrientation.HORIZONTAL, true, false, false); - - ChartPanel chartPanel = new ChartPanel(chart); - // make this chart non-interactive - chartPanel.setDisplayToolTips(true); - chartPanel.setDoubleBuffered(true); - chartPanel.setMouseZoomable(false); - chartPanel.setPopupMenu(null); - - return chartPanel; + @Override + public void removeAllRegions() { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + regions.clear(); + currentRegionSizePanel.removeAll(); + currentRegionSizePanel.revalidate(); + } + }); } - private Component createMemoryHistoryPanel() { - JPanel historyPanel = new JPanel(); - // TODO implement this - return historyPanel; + @Override + public void updateRegionSize(final String name, final int percentageUsed, final String currentlyUsed, final String currentlyAvailable, final String allocatable) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + regions.get(name).updateRegionData(percentageUsed, currentlyUsed, currentlyAvailable, allocatable); + } + }); + } @Override
--- a/client/src/main/java/com/redhat/thermostat/client/ui/VmMemoryView.java Tue Apr 24 14:14:13 2012 +0200 +++ b/client/src/main/java/com/redhat/thermostat/client/ui/VmMemoryView.java Tue Apr 24 14:15:34 2012 +0200 @@ -42,7 +42,11 @@ public interface VmMemoryView extends View { - void setMemoryRegionSize(String name, long used, long allocated, long max); + void addRegion(String humanReadableName); + + void removeAllRegions(); + + void updateRegionSize(String name, int percentageUsed, String currentlyUsed, String currentlyAvailable, String allocatable); Component getUiComponent();
--- a/client/src/main/resources/com/redhat/thermostat/client/locale/strings.properties Tue Apr 24 14:14:13 2012 +0200 +++ b/client/src/main/resources/com/redhat/thermostat/client/locale/strings.properties Tue Apr 24 14:15:34 2012 +0200 @@ -125,11 +125,10 @@ VM_CPU_CHART_LOAD_LABEL = % CPU VM_CPU_CHART_TIME_LABEL = Time -VM_CURRENT_MEMORY_CHART_USED = Used -VM_CURRENT_MEMORY_CHART_CAPACITY = Capacity -VM_CURRENT_MEMORY_CHART_MAX_CAPACITY = Max Capacity -VM_CURRENT_MEMORY_CHART_SPACE = Memory Region -VM_CURRENT_MEMORY_CHART_SIZE = Size +VM_MEMORY_SPACE_TITLE = Memory Region Sizes +VM_MEMORY_SPACE_USED = {0} bytes used +VM_MEMORY_SPACE_FREE = {0} bytes unused +VM_MEMORY_SPACE_ADDITIONAL = An additional {0} bytes can be allocated VM_GC_COLLECTOR_OVER_GENERATION = Collector {0} running on {1} VM_GC_COLLECTOR_CHART_REAL_TIME_LABEL = Time
--- a/client/src/test/java/com/redhat/thermostat/client/MainWindowControllerImplTest.java Tue Apr 24 14:14:13 2012 +0200 +++ b/client/src/test/java/com/redhat/thermostat/client/MainWindowControllerImplTest.java Tue Apr 24 14:15:34 2012 +0200 @@ -68,6 +68,7 @@ import com.redhat.thermostat.common.dao.HostRef; import com.redhat.thermostat.common.dao.VmInfoDAO; import com.redhat.thermostat.common.dao.VmRef; +import com.redhat.thermostat.test.Bug; public class MainWindowControllerImplTest { @@ -237,10 +238,11 @@ } @Test - public void bug954() { + @Bug(id="954", + summary="Thermostat GUI client should remember my last panel selected", + url="http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=954") + public void verifyOpenSameHostVMTab() { - // see http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=954 - VmRef vmRef = mock(VmRef.class); when(view.getSelectedHostOrVm()).thenReturn(vmRef);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/src/test/java/com/redhat/thermostat/client/ui/VmMemoryControllerTest.java Tue Apr 24 14:15:34 2012 +0200 @@ -0,0 +1,161 @@ +/* + * Copyright 2012 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.client.ui; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.contains; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mockito; + +import com.redhat.thermostat.common.Timer; +import com.redhat.thermostat.common.Timer.SchedulingType; +import com.redhat.thermostat.common.TimerFactory; +import com.redhat.thermostat.common.ViewFactory; +import com.redhat.thermostat.common.appctx.ApplicationContext; +import com.redhat.thermostat.common.appctx.ApplicationContextUtil; +import com.redhat.thermostat.common.dao.DAOFactory; +import com.redhat.thermostat.common.dao.VmMemoryStatDAO; +import com.redhat.thermostat.common.dao.VmRef; +import com.redhat.thermostat.common.model.VmMemoryStat; +import com.redhat.thermostat.common.model.VmMemoryStat.Generation; +import com.redhat.thermostat.common.model.VmMemoryStat.Space; + +public class VmMemoryControllerTest { + + private final long TIMESTAMP = 1; + private final int VM_ID = 99; + + private List<Generation> generations = new ArrayList<>(); + + private Timer timer; + private Space space; + private Generation gen; + private VmMemoryController controller; + private VmMemoryView view; + private Runnable timerAction; + + + @Before() + public void setUp() { + ApplicationContextUtil.resetApplicationContext(); + + // Setup timer. + timer = mock(Timer.class); + ArgumentCaptor<Runnable> actionCaptor = ArgumentCaptor.forClass(Runnable.class); + doNothing().when(timer).setAction(actionCaptor.capture()); + + TimerFactory timerFactory = mock(TimerFactory.class); + when(timerFactory.createTimer()).thenReturn(timer); + ApplicationContext.getInstance().setTimerFactory(timerFactory); + + space = new Space(); + space.name = "space"; + space.index = 0; + space.used = 10; + space.capacity = 100; + space.maxCapacity = 1000; + + gen = new Generation(); + gen.spaces = new ArrayList<>(); + gen.spaces.add(space); + + generations.add(gen); + + // Setup dao + VmMemoryStat vmMemory = new VmMemoryStat(TIMESTAMP, VM_ID, generations); + VmMemoryStatDAO memoryStatDao = mock(VmMemoryStatDAO.class); + when(memoryStatDao.getLatestMemoryStat(any(VmRef.class))).thenReturn(vmMemory); + + DAOFactory daoFactory = mock(DAOFactory.class); + when(daoFactory.getVmMemoryStatDAO()).thenReturn(memoryStatDao); + + ApplicationContext.getInstance().setDAOFactory(daoFactory); + + // Setup view + view = mock(VmMemoryView.class); + ViewFactory viewFactory = mock(ViewFactory.class); + when(viewFactory.getView(eq(VmMemoryView.class))).thenReturn(view); + ApplicationContext.getInstance().setViewFactory(viewFactory); + + + VmRef ref = mock(VmRef.class); + + controller = new VmMemoryController(ref); + timerAction = actionCaptor.getValue(); + + } + + @After + public void tearDown() { + ApplicationContextUtil.resetApplicationContext(); + } + + @Test + public void testTimer() { + + controller.start(); + + verify(timer).start(); + verify(timer).setSchedulingType(SchedulingType.FIXED_RATE); + + controller.stop(); + + verify(timer).stop(); + } + + + @Test + public void testControllerUpdatesView() { + + timerAction.run(); + + verify(view).addRegion(eq("space")); + verify(view).updateRegionSize(eq("space"), eq(10), contains("10"), contains("90"), contains("900")); + } +}
--- a/common/src/main/java/com/redhat/thermostat/common/ThreadPoolTimerFactory.java Tue Apr 24 14:14:13 2012 +0200 +++ b/common/src/main/java/com/redhat/thermostat/common/ThreadPoolTimerFactory.java Tue Apr 24 14:15:34 2012 +0200 @@ -39,12 +39,23 @@ import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; public class ThreadPoolTimerFactory implements TimerFactory { public ThreadPoolTimerFactory(int poolSize) { - timerThreadPool = Executors.newScheduledThreadPool(poolSize); + this(poolSize, Thread.currentThread().getThreadGroup()); + } + + ThreadPoolTimerFactory(int poolSize, final ThreadGroup group) { + timerThreadPool = Executors.newScheduledThreadPool(poolSize, new ThreadFactory() { + + @Override + public Thread newThread(Runnable r) { + return new Thread(group, r); + } + }); } private class ThreadPoolTimer implements Timer { @@ -126,4 +137,9 @@ return new ThreadPoolTimer(); } + @Override + public void shutdown() { + timerThreadPool.shutdown(); + } + }
--- a/common/src/main/java/com/redhat/thermostat/common/TimerFactory.java Tue Apr 24 14:14:13 2012 +0200 +++ b/common/src/main/java/com/redhat/thermostat/common/TimerFactory.java Tue Apr 24 14:15:34 2012 +0200 @@ -39,4 +39,6 @@ public interface TimerFactory { Timer createTimer(); + + void shutdown(); }
--- a/common/src/main/java/com/redhat/thermostat/common/dao/VmMemoryStatConverter.java Tue Apr 24 14:14:13 2012 +0200 +++ b/common/src/main/java/com/redhat/thermostat/common/dao/VmMemoryStatConverter.java Tue Apr 24 14:15:34 2012 +0200 @@ -115,7 +115,7 @@ newGen.collector = chunk.get(VmMemoryStatDAO.edenCollectorKey); space = new Space(); - space.name = chunk.get(VmMemoryStatDAO.edenGenKey); + space.name = VmMemoryStatDAO.edenKey.getName(); space.capacity = chunk.get(VmMemoryStatDAO.edenCapacityKey); space.maxCapacity = chunk.get(VmMemoryStatDAO.edenMaxCapacityKey); space.used = chunk.get(VmMemoryStatDAO.edenUsedKey); @@ -124,7 +124,7 @@ newGen.maxCapacity += space.maxCapacity; space = new Space(); - space.name = chunk.get(VmMemoryStatDAO.s0GenKey); + space.name = VmMemoryStatDAO.s0Key.getName(); space.capacity = chunk.get(VmMemoryStatDAO.s0CapacityKey); space.maxCapacity = chunk.get(VmMemoryStatDAO.s0MaxCapacityKey); space.used = chunk.get(VmMemoryStatDAO.s0UsedKey); @@ -133,7 +133,7 @@ newGen.maxCapacity += space.maxCapacity; space = new Space(); - space.name = chunk.get(VmMemoryStatDAO.s1GenKey); + space.name = VmMemoryStatDAO.s1Key.getName(); space.capacity = chunk.get(VmMemoryStatDAO.s1CapacityKey); space.maxCapacity = chunk.get(VmMemoryStatDAO.s1MaxCapacityKey); space.used = chunk.get(VmMemoryStatDAO.s1UsedKey); @@ -150,7 +150,7 @@ oldGen.collector = chunk.get(VmMemoryStatDAO.oldCollectorKey); space = new Space(); - space.name = chunk.get(VmMemoryStatDAO.oldGenKey); + space.name = VmMemoryStatDAO.oldKey.getName(); space.capacity = chunk.get(VmMemoryStatDAO.oldCapacityKey); space.maxCapacity = chunk.get(VmMemoryStatDAO.oldMaxCapacityKey); space.used = chunk.get(VmMemoryStatDAO.oldUsedKey); @@ -167,7 +167,7 @@ permGen.collector = chunk.get(VmMemoryStatDAO.permCollectorKey); space = new Space(); - space.name = chunk.get(VmMemoryStatDAO.permGenKey); + space.name = VmMemoryStatDAO.permKey.getName(); space.capacity = chunk.get(VmMemoryStatDAO.permCapacityKey); space.maxCapacity = chunk.get(VmMemoryStatDAO.permMaxCapacityKey); space.used = chunk.get(VmMemoryStatDAO.permUsedKey);
--- a/common/src/main/java/com/redhat/thermostat/common/dao/VmMemoryStatDAO.java Tue Apr 24 14:14:13 2012 +0200 +++ b/common/src/main/java/com/redhat/thermostat/common/dao/VmMemoryStatDAO.java Tue Apr 24 14:15:34 2012 +0200 @@ -42,30 +42,35 @@ public interface VmMemoryStatDAO { + static final Key<String> edenKey = new Key<>("eden", false); static final Key<String> edenGenKey = new Key<>("eden.gen", false); static final Key<String> edenCollectorKey = new Key<>("eden.collector", false); static final Key<Long> edenCapacityKey = new Key<>("eden.capacity", false); static final Key<Long> edenMaxCapacityKey = new Key<>("eden.max-capacity", false); static final Key<Long> edenUsedKey = new Key<>("eden.used", false); + static final Key<String> s0Key = new Key<>("s0", false); static final Key<String> s0GenKey = new Key<>("s0.gen", false); static final Key<String> s0CollectorKey = new Key<>("s0.collector", false); static final Key<Long> s0CapacityKey = new Key<>("s0.capacity", false); static final Key<Long> s0MaxCapacityKey = new Key<>("s0.max-capacity", false); static final Key<Long> s0UsedKey = new Key<>("s0.used", false); + static final Key<String> s1Key = new Key<>("s1", false); static final Key<String> s1GenKey = new Key<>("s1.gen", false); static final Key<String> s1CollectorKey = new Key<>("s1.collector", false); static final Key<Long> s1CapacityKey = new Key<>("s1.capacity", false); static final Key<Long> s1MaxCapacityKey = new Key<>("s1.max-capacity", false); static final Key<Long> s1UsedKey = new Key<>("s1.used", false); + static final Key<String> oldKey = new Key<>("old", false); static final Key<String> oldGenKey = new Key<>("old.gen", false); static final Key<String> oldCollectorKey = new Key<>("old.collector", false); static final Key<Long> oldCapacityKey = new Key<>("old.capacity", false); static final Key<Long> oldMaxCapacityKey = new Key<>("old.max-capacity", false); static final Key<Long> oldUsedKey = new Key<>("old.used", false); + static final Key<String> permKey = new Key<>("perm", false); static final Key<String> permGenKey = new Key<>("perm.gen", false); static final Key<String> permCollectorKey = new Key<>("perm.collector", false); static final Key<Long> permCapacityKey = new Key<>("perm.capacity", false);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/src/main/java/com/redhat/thermostat/test/Bug.java Tue Apr 24 14:15:34 2012 +0200 @@ -0,0 +1,44 @@ +/* + * Copyright 2012 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.test; + +public @interface Bug { + + String id(); + String url(); + String summary(); +}
--- a/common/src/test/java/com/redhat/thermostat/common/ThreadPoolTimerFactoryTest.java Tue Apr 24 14:14:13 2012 +0200 +++ b/common/src/test/java/com/redhat/thermostat/common/ThreadPoolTimerFactoryTest.java Tue Apr 24 14:15:34 2012 +0200 @@ -36,6 +36,8 @@ package com.redhat.thermostat.common; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; @@ -51,6 +53,7 @@ import org.mockito.stubbing.Answer; import com.redhat.thermostat.common.Timer.SchedulingType; +import com.redhat.thermostat.test.Bug; public class ThreadPoolTimerFactoryTest { @@ -58,15 +61,24 @@ private Timer timer; + private ThreadGroup threadGroup; + + private TimerFactory timerFactory; + @Before public void setUp() { - ThreadPoolTimerFactory timerFactory = new ThreadPoolTimerFactory(1); + threadGroup = new ThreadGroup("test"); + timerFactory = new ThreadPoolTimerFactory(1, threadGroup); timer = timerFactory.createTimer(); } @After public void tearDown() { + timer = null; + timerFactory.shutdown(); + timerFactory = null; + threadGroup = null; } @Test @@ -187,4 +199,24 @@ Thread.sleep(DELAY); verify(action, times(2)).run(); } + + @Bug(id="957", + summary="Thermostat GUI doesn't exit when closed, needs killing", + url="http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=957") + @Test + public void verifyShutdownKillsThreads() throws InterruptedException { + + Runnable action = mock(Runnable.class); + timer.setAction(action); + timer.setInitialDelay(DELAY / 2); + timer.start(); + + assertTrue(threadGroup.activeCount() > 0); + + timerFactory.shutdown(); + + Thread.sleep(DELAY); + + assertEquals(0, threadGroup.activeCount()); + } }
--- a/common/src/test/java/com/redhat/thermostat/common/dao/VmMemoryStatConverterTest.java Tue Apr 24 14:14:13 2012 +0200 +++ b/common/src/test/java/com/redhat/thermostat/common/dao/VmMemoryStatConverterTest.java Tue Apr 24 14:15:34 2012 +0200 @@ -122,6 +122,26 @@ final long TIMESTAMP = 1234l; final int VM_ID = 4567; + final long EDEN_USED = 1; + final long EDEN_CAPACITY = 2; + final long EDEN_MAX_CAPACITY = 3; + + final long S0_USED = 4; + final long S0_CAPACITY = 5; + final long S0_MAX_CAPACITY = 6; + + final long S1_USED = 7; + final long S1_CAPACITY = 8; + final long S1_MAX_CAPACITY = 9; + + final long OLD_USED = 10; + final long OLD_CAPACITY = 11; + final long OLD_MAX_CAPACITY = 12; + + final long PERM_USED = 13; + final long PERM_CAPACITY = 14; + final long PERM_MAX_CAPACITY = 15; + Chunk chunk = new Chunk(VmMemoryStatDAO.vmMemoryStatsCategory, false); chunk.put(Key.TIMESTAMP, TIMESTAMP); @@ -129,33 +149,33 @@ chunk.put(VmMemoryStatDAO.edenGenKey, "new"); chunk.put(VmMemoryStatDAO.edenCollectorKey, "new-collector"); - chunk.put(VmMemoryStatDAO.edenUsedKey, 1l); - chunk.put(VmMemoryStatDAO.edenCapacityKey, 2l); - chunk.put(VmMemoryStatDAO.edenMaxCapacityKey, 3l); + chunk.put(VmMemoryStatDAO.edenUsedKey, EDEN_USED); + chunk.put(VmMemoryStatDAO.edenCapacityKey, EDEN_CAPACITY); + chunk.put(VmMemoryStatDAO.edenMaxCapacityKey, EDEN_MAX_CAPACITY); chunk.put(VmMemoryStatDAO.s0GenKey, "new"); chunk.put(VmMemoryStatDAO.s0CollectorKey, "new-collector"); - chunk.put(VmMemoryStatDAO.s0UsedKey, 4l); - chunk.put(VmMemoryStatDAO.s0CapacityKey, 5l); - chunk.put(VmMemoryStatDAO.s0MaxCapacityKey, 6l); + chunk.put(VmMemoryStatDAO.s0UsedKey, S0_USED); + chunk.put(VmMemoryStatDAO.s0CapacityKey, S0_CAPACITY); + chunk.put(VmMemoryStatDAO.s0MaxCapacityKey, S0_MAX_CAPACITY); chunk.put(VmMemoryStatDAO.s1GenKey, "new"); chunk.put(VmMemoryStatDAO.s1CollectorKey, "new-collector"); - chunk.put(VmMemoryStatDAO.s1UsedKey, 7l); - chunk.put(VmMemoryStatDAO.s1CapacityKey, 8l); - chunk.put(VmMemoryStatDAO.s1MaxCapacityKey, 9l); + chunk.put(VmMemoryStatDAO.s1UsedKey, S1_USED); + chunk.put(VmMemoryStatDAO.s1CapacityKey, S1_CAPACITY); + chunk.put(VmMemoryStatDAO.s1MaxCapacityKey, S1_MAX_CAPACITY); chunk.put(VmMemoryStatDAO.oldGenKey, "old"); chunk.put(VmMemoryStatDAO.oldCollectorKey, "old-collector"); - chunk.put(VmMemoryStatDAO.oldUsedKey, 10l); - chunk.put(VmMemoryStatDAO.oldCapacityKey, 11l); - chunk.put(VmMemoryStatDAO.oldMaxCapacityKey, 12l); + chunk.put(VmMemoryStatDAO.oldUsedKey, OLD_USED); + chunk.put(VmMemoryStatDAO.oldCapacityKey, OLD_CAPACITY); + chunk.put(VmMemoryStatDAO.oldMaxCapacityKey, OLD_MAX_CAPACITY); chunk.put(VmMemoryStatDAO.permGenKey, "perm"); chunk.put(VmMemoryStatDAO.permCollectorKey, "perm-collector"); - chunk.put(VmMemoryStatDAO.permUsedKey, 13l); - chunk.put(VmMemoryStatDAO.permCapacityKey, 14l); - chunk.put(VmMemoryStatDAO.permMaxCapacityKey, 15l); + chunk.put(VmMemoryStatDAO.permUsedKey, PERM_USED); + chunk.put(VmMemoryStatDAO.permCapacityKey, PERM_CAPACITY); + chunk.put(VmMemoryStatDAO.permMaxCapacityKey, PERM_MAX_CAPACITY); VmMemoryStat stat = new VmMemoryStatConverter().fromChunk(chunk); @@ -165,13 +185,49 @@ assertEquals(3, stat.getGenerations().size()); - assertEquals(3, stat.getGeneration("new").spaces.size()); - assertEquals("new-collector", stat.getGeneration("new").collector); + Generation newGen = stat.getGeneration("new"); + assertNotNull(newGen); + assertEquals(3, newGen.spaces.size()); + assertEquals("new-collector", newGen.collector); + + Space eden = newGen.getSpace("eden"); + assertNotNull(eden); + assertEquals(EDEN_USED, eden.used); + assertEquals(EDEN_CAPACITY, eden.capacity); + assertEquals(EDEN_MAX_CAPACITY, eden.maxCapacity); + + Space s0 = newGen.getSpace("s0"); + assertNotNull(s0); + assertEquals(S0_USED, s0.used); + assertEquals(S0_CAPACITY, s0.capacity); + assertEquals(S0_MAX_CAPACITY, s0.maxCapacity); + + Space s1 = newGen.getSpace("s1"); + assertNotNull(s1); + assertEquals(S1_USED, s1.used); + assertEquals(S1_CAPACITY, s1.capacity); + assertEquals(S1_MAX_CAPACITY, s1.maxCapacity); + + Generation oldGen = stat.getGeneration("old"); + assertNotNull(oldGen); + assertEquals(1, oldGen.spaces.size()); + assertEquals("old-collector", oldGen.collector); - assertEquals(1, stat.getGeneration("old").spaces.size()); - assertEquals("old-collector", stat.getGeneration("old").collector); - - assertEquals(1, stat.getGeneration("perm").spaces.size()); - assertEquals("perm-collector", stat.getGeneration("perm").collector); + Space old = oldGen.getSpace("old"); + assertNotNull(old); + assertEquals(OLD_USED, old.used); + assertEquals(OLD_CAPACITY, old.capacity); + assertEquals(OLD_MAX_CAPACITY, old.maxCapacity); + + Generation permGen = stat.getGeneration("perm"); + assertNotNull(permGen); + assertEquals(1, permGen.spaces.size()); + assertEquals("perm-collector", permGen.collector); + + Space permSpace = permGen.getSpace("perm"); + assertNotNull(permSpace); + assertEquals(PERM_USED, permSpace.used); + assertEquals(PERM_CAPACITY, permSpace.capacity); + assertEquals(PERM_MAX_CAPACITY, permSpace.maxCapacity); } }