Mercurial > hg > release > thermostat-0.7
changeset 741:e9531651f79d
Eclipse Host CPU chart
This commit adds a new view in Eclipse for monitoring a host's CPU,
similar to the host's Processor tab in the Swing GUI.
Reviewed-by: jerboaa
Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2012-September/003349.html
author | Elliott Baron <ebaron@redhat.com> |
---|---|
date | Thu, 25 Oct 2012 13:34:48 -0400 |
parents | 2f1cedb72af5 |
children | 061618d8bcba |
files | eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/HostCpuViewPart.java eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/SWTHostCpuView.java eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/SWTHostCpuViewProvider.java eclipse/com.redhat.thermostat.eclipse.test.ui/src/com/redhat/thermostat/eclipse/test/ui/SWTHostCpuViewTest.java eclipse/com.redhat.thermostat.eclipse.test/src/com/redhat/thermostat/eclipse/test/views/HostCpuViewPartTest.java |
diffstat | 5 files changed, 904 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/HostCpuViewPart.java Thu Oct 25 13:34:48 2012 -0400 @@ -0,0 +1,70 @@ +/* + * 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.eclipse.chart.common; + +import com.redhat.thermostat.client.core.views.HostCpuViewProvider; +import com.redhat.thermostat.client.ui.HostCpuController; +import com.redhat.thermostat.common.dao.CpuStatDAO; +import com.redhat.thermostat.common.dao.HostInfoDAO; +import com.redhat.thermostat.common.dao.HostRef; +import com.redhat.thermostat.common.utils.OSGIUtils; +import com.redhat.thermostat.eclipse.views.SWTComponent; + +public class HostCpuViewPart extends HostRefViewPart { + + private HostCpuController cpuController; + + @Override + protected void createControllerView(HostRef ref) { + HostInfoDAO hostInfoDao = OSGIUtils.getInstance().getService( + HostInfoDAO.class); + CpuStatDAO cpuStatDao = OSGIUtils.getInstance().getService( + CpuStatDAO.class); + HostCpuViewProvider viewProvider = OSGIUtils.getInstance().getService( + HostCpuViewProvider.class); + cpuController = createController(hostInfoDao, cpuStatDao, ref, + viewProvider); + SWTComponent view = (SWTComponent) cpuController.getView(); + view.createControl(top); + } + + public HostCpuController createController(HostInfoDAO hostInfoDao, + CpuStatDAO cpuStatDao, HostRef ref, HostCpuViewProvider viewProvider) { + return new HostCpuController(hostInfoDao, cpuStatDao, ref, viewProvider); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/SWTHostCpuView.java Thu Oct 25 13:34:48 2012 -0400 @@ -0,0 +1,314 @@ +/* + * 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.eclipse.chart.common; + +import java.awt.Color; +import java.awt.EventQueue; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CountDownLatch; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.PlatformUI; +import org.jfree.chart.ChartFactory; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.renderer.xy.XYItemRenderer; +import org.jfree.data.time.FixedMillisecond; +import org.jfree.data.time.RegularTimePeriod; +import org.jfree.data.time.TimeSeries; +import org.jfree.data.time.TimeSeriesCollection; + +import com.redhat.thermostat.client.core.views.HostCpuView; +import com.redhat.thermostat.client.locale.LocaleResources; +import com.redhat.thermostat.client.ui.ChartColors; +import com.redhat.thermostat.common.locale.Translate; +import com.redhat.thermostat.common.model.DiscreteTimeData; +import com.redhat.thermostat.eclipse.ThermostatConstants; +import com.redhat.thermostat.eclipse.views.SWTComponent; + +public class SWTHostCpuView extends HostCpuView implements SWTComponent { + public static final String TEST_ID_CPU_MODEL = "SWTHostCpuView.cpuModel"; + public static final String TEST_ID_CPU_COUNT = "SWTHostCpuView.cpuCount"; + public static final String TEST_ID_LEGEND_ITEM = "SWTHostCpuView.legendItem"; + + private static final String LEGEND_COLOUR_BLOCK = "\u2588"; + private static final int H_INDENT = 20; + private static final int SPACER_WIDTH = 10; + private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer(); + + private JFreeChart chart; + private TimeSeriesCollection datasetCollection; + private Label cpuModel; + private Label cpuCount; + + private final Map<Integer, TimeSeries> datasets; + private final Map<String, Color> colors; + private Composite chartTop; + private Composite legendTop; + private Composite parent; + private ViewVisibilityWatcher watcher; + private CountDownLatch latch; + + public SWTHostCpuView() { + datasetCollection = new TimeSeriesCollection(); + datasets = new HashMap<Integer, TimeSeries>(); + colors = new HashMap<String, Color>(); + watcher = new ViewVisibilityWatcher(notifier); + chart = createCpuChart(); + latch = new CountDownLatch(1); + } + + public void createControl(Composite parent) { + this.parent = parent; + + Label summaryLabel = new Label(parent, SWT.LEAD); + Font stdFont = summaryLabel.getFont(); + Font boldFont = new Font(stdFont.getDevice(), + stdFont.getFontData()[0].getName(), + stdFont.getFontData()[0].getHeight(), SWT.BOLD); + + summaryLabel.setText(translator.localize(LocaleResources.HOST_CPU_SECTION_OVERVIEW)); + summaryLabel.setFont(boldFont); + + Composite detailsTop = new Composite(parent, SWT.NONE); + detailsTop.setLayout(new GridLayout(3, false)); + + Label cpuModelLabel = new Label(detailsTop, SWT.TRAIL); + cpuModelLabel.setText(translator.localize(LocaleResources.HOST_INFO_CPU_MODEL)); + GridData hIndentLayoutData = new GridData(); + hIndentLayoutData.horizontalIndent = H_INDENT; + cpuModelLabel.setLayoutData(hIndentLayoutData); + + Label cpuModelSpacer = new Label(detailsTop, SWT.NONE); + cpuModelSpacer.setLayoutData(new GridData(SPACER_WIDTH, SWT.DEFAULT)); + + cpuModel = new Label(detailsTop, SWT.LEAD); + cpuModel.setData(ThermostatConstants.TEST_TAG, TEST_ID_CPU_MODEL); + cpuModel.setText("Unknown"); + + Label cpuCountLabel = new Label(detailsTop, SWT.TRAIL); + cpuCountLabel.setText(translator.localize(LocaleResources.HOST_INFO_CPU_COUNT)); + cpuCountLabel.setLayoutData(hIndentLayoutData); + + Label cpuCountSpacer = new Label(detailsTop, SWT.NONE); + cpuCountSpacer.setLayoutData(new GridData(SPACER_WIDTH, SWT.DEFAULT)); + + cpuCount = new Label(detailsTop, SWT.LEAD); + cpuCount.setData(ThermostatConstants.TEST_TAG, TEST_ID_CPU_COUNT); + cpuCount.setText("Unknown"); + + chartTop = new RecentTimeSeriesChartComposite(parent, SWT.NONE, chart); + chartTop.setLayout(new GridLayout()); + chartTop.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + legendTop = new Composite(parent, SWT.NONE); + RowLayout legendLayout = new RowLayout(SWT.HORIZONTAL); + legendLayout.center = true; + legendLayout.wrap = false; + legendLayout.marginHeight = 0; + legendTop.setLayout(legendLayout); + + // Notify threads that controls are created + latch.countDown(); + + // Don't start giving updates until controls are created + watcher.watch(parent, ThermostatConstants.VIEW_ID_HOST_CPU); + } + + private JFreeChart createCpuChart() { + JFreeChart chart = ChartFactory.createTimeSeriesChart(null, + translator.localize(LocaleResources.HOST_CPU_USAGE_CHART_TIME_LABEL), + translator.localize(LocaleResources.HOST_CPU_USAGE_CHART_VALUE_LABEL), + datasetCollection, false, false, false); + + chart.getPlot().setBackgroundPaint(new Color(255, 255, 255, 0)); + chart.getPlot().setBackgroundImageAlpha(0.0f); + chart.getPlot().setOutlinePaint(new Color(0, 0, 0, 0)); + + return chart; + } + + public void setCpuCount(final String count) { + PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + if (!cpuCount.isDisposed()) { + cpuCount.setText(count); + } + } + }); + } + + public void setCpuModel(final String model) { + PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + if (!cpuModel.isDisposed()) { + cpuModel.setText(model); + } + } + }); + } + + @Override + public void addCpuUsageChart(final int cpuIndex, final String humanReadableName) { + EventQueue.invokeLater(new Runnable() { + + @Override + public void run() { + TimeSeries series = new TimeSeries(humanReadableName); + Color color = ChartColors.getColor(colors.size()); + colors.put(humanReadableName, color); + + datasets.put(cpuIndex, series); + datasetCollection.addSeries(series); + + updateColors(); + + addLegendItem(humanReadableName, color); + } + }); + } + + @Override + public void addCpuUsageData(final int cpuIndex, List<DiscreteTimeData<Double>> data) { + final ArrayList<DiscreteTimeData<Double>> copy = new ArrayList<>(data); + EventQueue.invokeLater(new Runnable() { + @Override + public void run() { + TimeSeries dataset = datasets.get(cpuIndex); + for (DiscreteTimeData<Double> timeData: copy) { + RegularTimePeriod period = new FixedMillisecond(timeData.getTimeInMillis()); + if (dataset.getDataItem(period) == null) { + dataset.add(period, timeData.getData(), false); + } + } + dataset.fireSeriesChanged(); + } + }); + } + + @Override + public void clearCpuUsageData() { + EventQueue.invokeLater(new Runnable() { + @Override + public void run() { + for (Iterator<Map.Entry<Integer, TimeSeries>> iter = datasets.entrySet().iterator(); iter.hasNext();) { + Map.Entry<Integer, TimeSeries> entry = iter.next(); + datasetCollection.removeSeries(entry.getValue()); + entry.getValue().clear(); + + iter.remove(); + + } + updateColors(); + } + }); + } + + /** + * Adding or removing series to the series collection may change the order + * of existing items. Plus the paint for the index is now out-of-date. So + * let's walk through all the series and set the right paint for those. + */ + private void updateColors() { + XYItemRenderer itemRenderer = chart.getXYPlot().getRenderer(); + for (int i = 0; i < datasetCollection.getSeriesCount(); i++) { + String tag = (String) datasetCollection.getSeriesKey(i); + Color color = colors.get(tag); + itemRenderer.setSeriesPaint(i, color); + } + } + + + private Composite createLabelWithLegend(Composite parent, String text, Color color) { + Composite top = new Composite(parent, SWT.NONE); + GridLayout topLayout = new GridLayout(2, false); + topLayout.marginHeight = 0; + top.setLayout(topLayout); + + Label colourBlock = new Label(top, SWT.NONE); + colourBlock.setText(LEGEND_COLOUR_BLOCK); + + // Convert to SWT colour + final org.eclipse.swt.graphics.Color swtColour = new org.eclipse.swt.graphics.Color( + PlatformUI.getWorkbench().getDisplay(), color.getRed(), + color.getGreen(), color.getBlue()); + colourBlock.addDisposeListener(new DisposeListener() { + + @Override + public void widgetDisposed(DisposeEvent e) { + swtColour.dispose(); + } + }); + colourBlock.setForeground(swtColour); + + Label colourText = new Label(top, SWT.NONE); + colourText.setData(ThermostatConstants.TEST_TAG, TEST_ID_LEGEND_ITEM); + colourText.setText(text); + return top; + } + + private void addLegendItem(final String humanReadableName, final Color color) { + // We need to wait for the controls to be fully constructed + // before modifying the legend + ChartUtils.runAfterCreated(latch, new Runnable() { + @Override + public void run() { + createLabelWithLegend(legendTop, humanReadableName, + color); + parent.layout(); + } + }); + } + + public JFreeChart getChart() { + return chart; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/SWTHostCpuViewProvider.java Thu Oct 25 13:34:48 2012 -0400 @@ -0,0 +1,49 @@ +/* + * 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.eclipse.chart.common; + +import com.redhat.thermostat.client.core.views.HostCpuView; +import com.redhat.thermostat.client.core.views.HostCpuViewProvider; + +public class SWTHostCpuViewProvider implements HostCpuViewProvider { + + @Override + public HostCpuView createView() { + return new SWTHostCpuView(); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eclipse/com.redhat.thermostat.eclipse.test.ui/src/com/redhat/thermostat/eclipse/test/ui/SWTHostCpuViewTest.java Thu Oct 25 13:34:48 2012 -0400 @@ -0,0 +1,335 @@ +/* + * 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.eclipse.test.ui; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot; +import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner; +import org.eclipse.swtbot.swt.finder.waits.DefaultCondition; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotLabel; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.plot.XYPlot; +import org.jfree.data.time.TimeSeriesCollection; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import com.redhat.thermostat.common.model.DiscreteTimeData; +import com.redhat.thermostat.eclipse.ThermostatConstants; +import com.redhat.thermostat.eclipse.chart.common.SWTHostCpuView; + +@RunWith(SWTBotJunit4ClassRunner.class) +public class SWTHostCpuViewTest { + private SWTWorkbenchBot bot; + private SWTHostCpuView view; + private Shell shell; + + @Before + public void beforeTest() throws Exception { + bot = new SWTWorkbenchBot(); + + Display.getDefault().syncExec(new Runnable() { + + @Override + public void run() { + shell = new Shell(Display.getCurrent()); + Composite parent = new Composite(shell, SWT.NONE); + parent.setLayout(new GridLayout()); + parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, + true)); + view = new SWTHostCpuView(); + view.createControl(parent); + shell.open(); + } + }); + } + + @After + public void afterTest() throws Exception { + Display.getDefault().syncExec(new Runnable() { + + @Override + public void run() { + if (shell != null) { + shell.close(); + view = null; + } + } + }); + } + + @Test + public void testSetCpuModel() throws Exception { + String model = "Test CPU"; + + view.setCpuModel(model); + + bot.waitUntil(new DefaultCondition() { + + @Override + public boolean test() throws Exception { + SWTBotLabel label = bot.labelWithId( + ThermostatConstants.TEST_TAG, + SWTHostCpuView.TEST_ID_CPU_MODEL); + return !label.getText().equals("Unknown"); // TODO Externalize + } + + @Override + public String getFailureMessage() { + return "CPU Model label unchanged after set"; + } + + }); + } + + @Test + public void testSetCpuCount() throws Exception { + String count = "8"; + + view.setCpuCount(count); + + bot.waitUntil(new DefaultCondition() { + + @Override + public boolean test() throws Exception { + SWTBotLabel label = bot.labelWithId( + ThermostatConstants.TEST_TAG, + SWTHostCpuView.TEST_ID_CPU_COUNT); + return !label.getText().equals("Unknown"); // TODO Externalize + } + + @Override + public String getFailureMessage() { + return "CPU Model label unchanged after set"; + } + + }); + } + + @Test + public void testAddCpuUsageChart() throws Exception { + String humanReadableName = "Test"; + + // Test series added + addSeries(0, humanReadableName, 1); + + // Verify legend added + SWTBotLabel label = bot.labelWithId(ThermostatConstants.TEST_TAG, + SWTHostCpuView.TEST_ID_LEGEND_ITEM); + assertEquals(humanReadableName, label.getText()); + } + + private void addSeries(int seriesIndex, String humanReadableName, + final int numSeries) { + view.addCpuUsageChart(seriesIndex, humanReadableName); + + bot.waitUntil(new DefaultCondition() { + + @Override + public boolean test() throws Exception { + JFreeChart chart = view.getChart(); + XYPlot plot = (XYPlot) chart.getPlot(); + int count = plot.getSeriesCount(); + return count == numSeries; + } + + @Override + public String getFailureMessage() { + return "Data series never added"; + } + }); + + // Wait until legend added + bot.labelWithId(ThermostatConstants.TEST_TAG, + SWTHostCpuView.TEST_ID_LEGEND_ITEM); + } + + @Test + public void testAddCpuUsageChartMultiple() throws Exception { + String humanReadableName1 = "Test 1"; + String humanReadableName2 = "Test 2"; + + addSeries(0, humanReadableName1, 1); + addSeries(1, humanReadableName2, 2); + + // Verify legend added + SWTBotLabel label = bot.labelWithId(ThermostatConstants.TEST_TAG, + SWTHostCpuView.TEST_ID_LEGEND_ITEM, 0); + assertEquals(humanReadableName1, label.getText()); + label = bot.labelWithId(ThermostatConstants.TEST_TAG, + SWTHostCpuView.TEST_ID_LEGEND_ITEM, 1); + assertEquals(humanReadableName2, label.getText()); + } + + @Test + public void testAddCpuUsageData() throws Exception { + List<DiscreteTimeData<Double>> data = new ArrayList<DiscreteTimeData<Double>>(); + + data.add(new DiscreteTimeData<Double>(1000L, 50D)); + data.add(new DiscreteTimeData<Double>(2000L, 75D)); + data.add(new DiscreteTimeData<Double>(3000L, 25D)); + + addSeries(0, "Test", 1); + + addData(0, data); + + JFreeChart chart = view.getChart(); + TimeSeriesCollection dataset = (TimeSeriesCollection) chart.getXYPlot() + .getDataset(); + + assertEquals(1000L, dataset.getX(0, 0)); + assertEquals(2000L, dataset.getX(0, 1)); + assertEquals(3000L, dataset.getX(0, 2)); + + assertEquals(50D, dataset.getY(0, 0)); + assertEquals(75D, dataset.getY(0, 1)); + assertEquals(25D, dataset.getY(0, 2)); + } + + private void addData(final int seriesIndex, + final List<DiscreteTimeData<Double>> data) { + view.addCpuUsageData(seriesIndex, data); + + bot.waitUntil(new DefaultCondition() { + + @Override + public boolean test() throws Exception { + JFreeChart chart = view.getChart(); + TimeSeriesCollection dataset = (TimeSeriesCollection) chart + .getXYPlot().getDataset(); + return dataset.getItemCount(seriesIndex) == data.size(); + } + + @Override + public String getFailureMessage() { + return "Data not added"; + } + }); + } + + @Test + public void testAddCpuUsageDataMultiple() throws Exception { + List<DiscreteTimeData<Double>> data1 = new ArrayList<DiscreteTimeData<Double>>(); + + data1.add(new DiscreteTimeData<Double>(1000L, 50D)); + data1.add(new DiscreteTimeData<Double>(2000L, 75D)); + data1.add(new DiscreteTimeData<Double>(3000L, 25D)); + + List<DiscreteTimeData<Double>> data2 = new ArrayList<DiscreteTimeData<Double>>(); + + data2.add(new DiscreteTimeData<Double>(1500L, 30D)); + data2.add(new DiscreteTimeData<Double>(2500L, 60D)); + data2.add(new DiscreteTimeData<Double>(3500L, 90D)); + + addSeries(0, "Test 1", 1); + addSeries(1, "Test 2", 2); + + addData(0, data1); + addData(1, data2); + + JFreeChart chart = view.getChart(); + TimeSeriesCollection dataset = (TimeSeriesCollection) chart.getXYPlot() + .getDataset(); + + assertEquals(1000L, dataset.getX(0, 0)); + assertEquals(2000L, dataset.getX(0, 1)); + assertEquals(3000L, dataset.getX(0, 2)); + + assertEquals(50D, dataset.getY(0, 0)); + assertEquals(75D, dataset.getY(0, 1)); + assertEquals(25D, dataset.getY(0, 2)); + + assertEquals(1500L, dataset.getX(1, 0)); + assertEquals(2500L, dataset.getX(1, 1)); + assertEquals(3500L, dataset.getX(1, 2)); + + assertEquals(30D, dataset.getY(1, 0)); + assertEquals(60D, dataset.getY(1, 1)); + assertEquals(90D, dataset.getY(1, 2)); + } + + @Test + public void testClearCpuUsageData() { + List<DiscreteTimeData<Double>> data1 = new ArrayList<DiscreteTimeData<Double>>(); + + data1.add(new DiscreteTimeData<Double>(1000L, 50D)); + data1.add(new DiscreteTimeData<Double>(2000L, 75D)); + data1.add(new DiscreteTimeData<Double>(3000L, 25D)); + + List<DiscreteTimeData<Double>> data2 = new ArrayList<DiscreteTimeData<Double>>(); + + data2.add(new DiscreteTimeData<Double>(1500L, 30D)); + data2.add(new DiscreteTimeData<Double>(2500L, 60D)); + data2.add(new DiscreteTimeData<Double>(3500L, 90D)); + + addSeries(0, "Test 1", 1); + addSeries(1, "Test 2", 2); + + addData(0, data1); + addData(1, data2); + + view.clearCpuUsageData(); + + // Wait until data cleared + bot.waitUntil(new DefaultCondition() { + + @Override + public boolean test() throws Exception { + JFreeChart chart = view.getChart(); + int count = chart.getXYPlot().getSeriesCount(); + return count == 0; + } + + @Override + public String getFailureMessage() { + return "Data not cleared"; + } + }); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eclipse/com.redhat.thermostat.eclipse.test/src/com/redhat/thermostat/eclipse/test/views/HostCpuViewPartTest.java Thu Oct 25 13:34:48 2012 -0400 @@ -0,0 +1,136 @@ +/* + * 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.eclipse.test.views; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.same; +import static org.mockito.Mockito.doReturn; +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.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.widgets.Composite; +import org.junit.Test; + +import com.redhat.thermostat.client.core.views.BasicView; +import com.redhat.thermostat.client.core.views.HostCpuViewProvider; +import com.redhat.thermostat.client.ui.HostCpuController; +import com.redhat.thermostat.common.dao.CpuStatDAO; +import com.redhat.thermostat.common.dao.HostInfoDAO; +import com.redhat.thermostat.common.dao.HostRef; +import com.redhat.thermostat.common.dao.VmRef; +import com.redhat.thermostat.eclipse.chart.common.HostCpuViewPart; +import com.redhat.thermostat.eclipse.chart.common.RefViewPart; +import com.redhat.thermostat.eclipse.chart.common.SWTHostCpuView; + +public class HostCpuViewPartTest extends AbstractRefViewPartTest<HostRef> { + + @Test + public void testSetFocus() throws Exception { + view.createPartControl(parent); + view.setFocus(); + + verify(parent).setFocus(); + } + + @Test + public void testNoSelection() throws Exception { + view.createPartControl(parent); + verify(view).createNoSelectionLabel(); + } + + @Test + public void testSelectionBefore() throws Exception { + HostRef hostRef = new HostRef("TEST", "Test"); + mockSelection(hostRef); + view.createPartControl(parent); + + verify(view, never()).createNoSelectionLabel(); + + verify(thermoView).createControl(any(Composite.class)); + } + + @Test + public void testSelectionAfter() throws Exception { + view.createPartControl(parent); + + HostRef hostRef = new HostRef("TEST", "Test"); + IStructuredSelection selection = mockSelection(hostRef); + view.selectionChanged(hostVMView, selection); + + verify(thermoView).createControl(any(Composite.class)); + } + + @Test + public void testSelectionVmRef() throws Exception { + view.createPartControl(parent); + + HostRef hostRef = new HostRef("TEST", "Test"); + VmRef vmRef = new VmRef(hostRef, 0, "Test"); + IStructuredSelection selection = mockSelection(vmRef); + view.selectionChanged(hostVMView, selection); + + verify(thermoView).createControl(any(Composite.class)); + } + + @Override + protected RefViewPart<HostRef> createViewPart() { + return new HostCpuViewPart(); + } + + @Override + protected void mockController() { + HostCpuController controller = mock(HostCpuController.class); + thermoView = mock(SWTHostCpuView.class); + + HostInfoDAO hostInfoDao = mock(HostInfoDAO.class); + CpuStatDAO cpuStatDao = mock(CpuStatDAO.class); + HostCpuViewProvider viewProvider = mock(HostCpuViewProvider.class); + when(osgi.getService(HostInfoDAO.class)).thenReturn(hostInfoDao); + when(osgi.getService(CpuStatDAO.class)).thenReturn(cpuStatDao); + when(osgi.getService(HostCpuViewProvider.class)).thenReturn( + viewProvider); + + doReturn(controller).when(((HostCpuViewPart) view)).createController( + same(hostInfoDao), same(cpuStatDao), any(HostRef.class), + same(viewProvider)); + when(controller.getView()).thenReturn((BasicView) thermoView); + } + +}