Mercurial > hg > release > thermostat-1.6
changeset 1986:38e39491d46a
Fix heap dump details tab pane
PR3059, PR3022
Reviewed-by: jkang
Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2016-June/019844.html
Original-thread: http://icedtea.classpath.org/pipermail/thermostat/2015-October/016799.html
line wrap: on
line diff
--- a/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/HeapDumpDetailsView.java Wed Jun 29 12:23:09 2016 -0400 +++ b/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/HeapDumpDetailsView.java Wed Jun 29 12:23:10 2016 -0400 @@ -46,5 +46,8 @@ public abstract void addSubView(LocalizedString title, ObjectDetailsView child); public abstract void addSubView(LocalizedString title, HeapTreeMapView child); public abstract void removeSubView(LocalizedString title); + public abstract void updateView(final HeapHistogramView histogramView, + final ObjectDetailsView detailsView, + final HeapTreeMapView treeMapView); }
--- a/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumpController.java Wed Jun 29 12:23:09 2016 -0400 +++ b/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumpController.java Wed Jun 29 12:23:10 2016 -0400 @@ -107,6 +107,7 @@ private ObjectDetailsViewProvider objectDetailsViewProvider; private ObjectRootsViewProvider objectRootsViewProvider; private HeapDumpListViewProvider heapDumpListViewProvider; + private HeapDumpDetailsController heapDumpDetailsController; private ProgressNotifier notifier; @@ -155,6 +156,14 @@ this.vmDao = vmMemoryStatDao; this.heapDAO = heapDao; this.heapDumpListViewProvider = heapDumpListViewProvider; + + this.heapDumpDetailsController = new HeapDumpDetailsController( + appService, + detailsViewProvider, + histogramViewProvider, + treeMapViewProvider, + objectDetailsViewProvider, + objectRootsViewProvider); model = new OverviewChart( null, @@ -372,15 +381,9 @@ } private void showHeapDumpDetails(HeapDump dump) { - HeapDumpDetailsController controller = - new HeapDumpDetailsController(appService, detailsViewProvider, - histogramViewProvider, - treeMapViewProvider, - objectDetailsViewProvider, - objectRootsViewProvider); - controller.setDump(dump); + heapDumpDetailsController.setDump(dump); view.setActiveDump(dump); - view.setChildView(controller.getView()); + view.setChildView(heapDumpDetailsController.getView()); view.openDumpView(); }
--- a/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumpDetailsController.java Wed Jun 29 12:23:09 2016 -0400 +++ b/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumpDetailsController.java Wed Jun 29 12:23:10 2016 -0400 @@ -38,6 +38,7 @@ import java.io.IOException; import java.util.Collection; +import java.util.Objects; import java.util.logging.Level; import java.util.logging.Logger; @@ -47,8 +48,6 @@ import com.redhat.thermostat.common.ApplicationService; import com.redhat.thermostat.common.NotImplementedException; import com.redhat.thermostat.common.utils.LoggingUtils; -import com.redhat.thermostat.shared.locale.LocalizedString; -import com.redhat.thermostat.shared.locale.Translate; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpDetailsView; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpDetailsViewProvider; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapHistogramView; @@ -59,23 +58,20 @@ import com.redhat.thermostat.vm.heap.analysis.client.core.ObjectDetailsView; import com.redhat.thermostat.vm.heap.analysis.client.core.ObjectDetailsViewProvider; import com.redhat.thermostat.vm.heap.analysis.client.core.ObjectRootsViewProvider; -import com.redhat.thermostat.vm.heap.analysis.client.locale.LocaleResources; import com.redhat.thermostat.vm.heap.analysis.common.HeapDump; import com.redhat.thermostat.vm.heap.analysis.common.ObjectHistogram; import com.sun.tools.hat.internal.model.JavaHeapObject; public class HeapDumpDetailsController { - private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer(); - private static final Logger log = LoggingUtils.getLogger(HeapDumpDetailsController.class); private final ApplicationService appService; private HeapDumpDetailsView view; private HeapDump heapDump; + private HeapTreeMapView heapTreeMapView; private HeapHistogramViewProvider histogramViewProvider; - private HeapTreeMapViewProvider treeMapViewProvider; private ObjectDetailsViewProvider objectDetailsViewProvider; private ObjectRootsViewProvider objectRootsViewProvider; private HeapHistogramView heapHistogramView; @@ -83,48 +79,50 @@ public HeapDumpDetailsController(ApplicationService appService, HeapDumpDetailsViewProvider viewProvider, HeapHistogramViewProvider histogramProvider, HeapTreeMapViewProvider treeMapProvider, ObjectDetailsViewProvider objectDetailsProvider, ObjectRootsViewProvider objectRootsProvider) { this.appService = appService; this.histogramViewProvider = histogramProvider; - this.treeMapViewProvider = treeMapProvider; this.objectDetailsViewProvider = objectDetailsProvider; this.objectRootsViewProvider = objectRootsProvider; view = viewProvider.createView(); + heapTreeMapView = treeMapProvider.createView(); } public void setDump(HeapDump dump) { this.heapDump = dump; + ObjectHistogram histogram = null; + try { - ObjectHistogram histogram = heapDump.getHistogram(); - heapHistogramView = histogramViewProvider.createView(); - heapHistogramView.setHistogram(histogram); - heapHistogramView.addHistogramActionListener(new ActionListener<HistogramAction>() { - @Override - public void actionPerformed(ActionEvent<HistogramAction> actionEvent) { - switch (actionEvent.getActionId()) { - case SEARCH: - searchForObject((String) actionEvent.getPayload()); - break; - default: - throw new NotImplementedException("unknown action fired by " + actionEvent.getSource()); - } - } - }); - - LocalizedString title = translator.localize(LocaleResources.HEAP_DUMP_SECTION_HISTOGRAM); - view.addSubView(title, heapHistogramView); - - HeapTreeMapView heapTreeMapView = treeMapViewProvider.createView(); - heapTreeMapView.display(heapDump.getHistogram()); - LocalizedString titleTreeMap = translator.localize(LocaleResources.HEAP_DUMP_SECTION_TREEMAP); - view.addSubView(titleTreeMap, heapTreeMapView); + histogram = dump.getHistogram(); } catch (IOException e) { log.log(Level.SEVERE, "unexpected error while reading heap dump", e); } - ObjectDetailsController controller = new ObjectDetailsController(appService, dump, objectDetailsViewProvider, objectRootsViewProvider); + Objects.requireNonNull(histogram); + + heapHistogramView = histogramViewProvider.createView(); + heapHistogramView.setHistogram(histogram); + heapHistogramView.addHistogramActionListener(new ActionListener<HistogramAction>() { + @Override + public void actionPerformed(ActionEvent<HistogramAction> actionEvent) { + switch (actionEvent.getActionId()) { + case SEARCH: + searchForObject((String) actionEvent.getPayload()); + break; + default: + throw new NotImplementedException( + "unknown action fired by " + actionEvent.getSource()); + } + } + }); + + heapTreeMapView.display(histogram); + + ObjectDetailsController controller = new ObjectDetailsController(appService, dump, + objectDetailsViewProvider, objectRootsViewProvider); ObjectDetailsView detailsView = controller.getView(); - view.addSubView(translator.localize(LocaleResources.HEAP_DUMP_SECTION_OBJECT_BROWSER), detailsView); + + view.updateView(heapHistogramView, detailsView, heapTreeMapView); // do a dummy search right now to prep the index - heapDump.searchObjects("A_RANDOM_PATTERN", 1); + dump.searchObjects("A_RANDOM_PATTERN", 1); } private void searchForObject(final String searchText) {
--- a/vm-heap-analysis/client-core/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumpControllerTest.java Wed Jun 29 12:23:09 2016 -0400 +++ b/vm-heap-analysis/client-core/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumpControllerTest.java Wed Jun 29 12:23:10 2016 -0400 @@ -49,6 +49,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -96,6 +97,7 @@ import com.redhat.thermostat.vm.heap.analysis.common.DumpFile; import com.redhat.thermostat.vm.heap.analysis.common.HeapDAO; import com.redhat.thermostat.vm.heap.analysis.common.HeapDump; +import com.redhat.thermostat.vm.heap.analysis.common.ObjectHistogram; import com.redhat.thermostat.vm.heap.analysis.common.model.HeapInfo; import com.redhat.thermostat.vm.memory.common.VmMemoryStatDAO; import com.redhat.thermostat.vm.memory.common.model.VmMemoryStat; @@ -286,10 +288,13 @@ } @Test - public void testOpenDumpCalledWhenPreviousDump() { + public void testOpenDumpCalledWhenPreviousDump() throws IOException { setUpTimers(); HeapDump dump = mock(HeapDump.class); + + ObjectHistogram histogram = mock(ObjectHistogram.class); + when(dump.getHistogram()).thenReturn(histogram); HeapInfo info1 = mock(HeapInfo.class); when(dump.getInfo()).thenReturn(info1);
--- a/vm-heap-analysis/client-core/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumpDetailsControllerTest.java Wed Jun 29 12:23:09 2016 -0400 +++ b/vm-heap-analysis/client-core/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/core/internal/HeapDumpDetailsControllerTest.java Wed Jun 29 12:23:10 2016 -0400 @@ -36,6 +36,9 @@ package com.redhat.thermostat.vm.heap.analysis.client.core.internal; +import junit.framework.Assert; + +import static junit.framework.Assert.assertTrue; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.isA; import static org.mockito.Mockito.mock; @@ -49,7 +52,6 @@ import org.junit.Test; import com.redhat.thermostat.common.ApplicationService; -import com.redhat.thermostat.shared.locale.LocalizedString; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpDetailsView; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpDetailsViewProvider; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapHistogramView; @@ -104,24 +106,45 @@ } @Test - public void verifyInitialize() throws IOException { - ApplicationService appService = mock(ApplicationService.class); + public void testSetDumpFailsWithEmptyDump() throws IOException { + HeapDumpDetailsController controller = setupController(); + + HeapDump emptyDump = mock(HeapDump.class); + when(emptyDump.getHistogram()).thenReturn(null); - ObjectHistogram histogram = mock(ObjectHistogram.class); + boolean caught = false; + try { + controller.setDump(emptyDump); + } catch (NullPointerException e) { + caught = true; + } + assertTrue("Null pointer exception expected", caught); + } + + @Test + public void testSetDumpWorksWithValidDump() throws IOException { + HeapDumpDetailsController controller = setupController(); HeapDump dump = mock(HeapDump.class); + ObjectHistogram histogram = mock(ObjectHistogram.class); when(dump.getHistogram()).thenReturn(histogram); - HeapDumpDetailsController controller = new HeapDumpDetailsController( + try { + controller.setDump(dump); + } catch (NullPointerException e) { + Assert.fail("Did not expect null pointer exception"); + } + + verify(dump).searchObjects(isA(String.class), anyInt()); + verify(view).updateView(isA(HeapHistogramView.class), isA(ObjectDetailsView.class), + isA(HeapTreeMapView.class)); + } + + private HeapDumpDetailsController setupController() { + ApplicationService appService = mock(ApplicationService.class); + return new HeapDumpDetailsController( appService, viewProvider, histogramProvider, treeMapProvider, objectDetailsProvider, objectRootsProvider); - controller.setDump(dump); - - verify(dump).searchObjects(isA(String.class), anyInt()); - verify(view) - .addSubView(isA(LocalizedString.class), isA(HeapHistogramView.class)); - verify(view) - .addSubView(isA(LocalizedString.class), isA(ObjectDetailsView.class)); } }
--- a/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HeapDetailsSwing.java Wed Jun 29 12:23:09 2016 -0400 +++ b/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HeapDetailsSwing.java Wed Jun 29 12:23:10 2016 -0400 @@ -45,13 +45,17 @@ import com.redhat.thermostat.client.swing.SwingComponent; import com.redhat.thermostat.client.swing.components.ThermostatTabbedPane; import com.redhat.thermostat.shared.locale.LocalizedString; +import com.redhat.thermostat.shared.locale.Translate; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpDetailsView; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapHistogramView; import com.redhat.thermostat.vm.heap.analysis.client.core.HeapTreeMapView; import com.redhat.thermostat.vm.heap.analysis.client.core.ObjectDetailsView; +import com.redhat.thermostat.vm.heap.analysis.client.locale.LocaleResources; public class HeapDetailsSwing extends HeapDumpDetailsView implements SwingComponent { + private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer(); + /** For TESTING only! */ static final String TAB_NAME = "tabs"; @@ -65,8 +69,17 @@ visiblePane.add(tabPane, BorderLayout.CENTER); tabPane.setName(TAB_NAME); + tabPane.addTab( + translator.localize(LocaleResources.HEAP_DUMP_SECTION_TREEMAP).getContents(), null); + tabPane.addTab( + translator.localize(LocaleResources.HEAP_DUMP_SECTION_OBJECT_BROWSER).getContents(), null); + tabPane.addTab( + translator.localize(LocaleResources.HEAP_DUMP_SECTION_HISTOGRAM).getContents(), null); + tabPane.setSelectedIndex(0); } + + @Override public void addSubView(final LocalizedString title, final HeapHistogramView view) { verifyIsSwingComponent(view); @@ -128,4 +141,25 @@ }); } + @Override + public void updateView(final HeapHistogramView histogramView, + final ObjectDetailsView detailsView, + final HeapTreeMapView treeMapView) { + + verifyIsSwingComponent(histogramView); + verifyIsSwingComponent(detailsView); + verifyIsSwingComponent(treeMapView); + + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + tabPane.setComponentAt(0, ((SwingComponent) treeMapView).getUiComponent()); + tabPane.setComponentAt(1, ((SwingComponent) detailsView).getUiComponent()); + tabPane.setComponentAt(2, ((SwingComponent) histogramView).getUiComponent()); + tabPane.revalidate(); + tabPane.repaint(); + } + }); + } + }
--- a/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/SwingHeapTreeMapView.java Wed Jun 29 12:23:09 2016 -0400 +++ b/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/SwingHeapTreeMapView.java Wed Jun 29 12:23:10 2016 -0400 @@ -40,6 +40,7 @@ import java.awt.Component; import javax.swing.JPanel; +import javax.swing.SwingUtilities; import com.redhat.thermostat.client.swing.SwingComponent; import com.redhat.thermostat.client.swing.components.experimental.TreeMapComponent; @@ -52,8 +53,8 @@ public class SwingHeapTreeMapView extends HeapTreeMapView implements SwingComponent { private TreeMapComponent treeMap; - private final JPanel panel; - + private JPanel panel; + public SwingHeapTreeMapView() { treeMap = new TreeMapComponent(); treeMap.setToolTipRenderer(new WeightAsSizeRenderer()); @@ -63,11 +64,19 @@ } @Override - public void display(ObjectHistogram histogram) { - TreeMapNode model = HistogramConverter.convertToTreeMap(histogram); - treeMap.setModel(model); - panel.add(treeMap, BorderLayout.CENTER); - panel.add(new TreeMapToolbar(treeMap), BorderLayout.NORTH); + public void display(final ObjectHistogram histogram) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + TreeMapNode model = HistogramConverter.convertToTreeMap(histogram); + treeMap.setModel(model); + panel.removeAll(); + panel.add(treeMap, BorderLayout.CENTER); + panel.add(new TreeMapToolbar(treeMap), BorderLayout.NORTH); + panel.revalidate(); + panel.repaint(); + } + }); } @Override
--- a/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HeapDetailsSwingTest.java Wed Jun 29 12:23:09 2016 -0400 +++ b/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HeapDetailsSwingTest.java Wed Jun 29 12:23:10 2016 -0400 @@ -36,17 +36,23 @@ package com.redhat.thermostat.vm.heap.analysis.client.swing.internal; +import junit.framework.Assert; +import net.java.openjdk.cacio.ctc.junit.CacioFESTRunner; + +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Arrays; import java.util.concurrent.Callable; import javax.swing.JFrame; import javax.swing.JPanel; - -import net.java.openjdk.cacio.ctc.junit.CacioFESTRunner; +import javax.swing.SwingUtilities; import org.fest.swing.annotation.GUITest; import org.fest.swing.edt.FailOnThreadViolationRepaintManager; @@ -54,6 +60,7 @@ import org.fest.swing.edt.GuiTask; import org.fest.swing.fixture.FrameFixture; import org.fest.swing.fixture.JTabbedPaneFixture; +import org.fest.swing.util.Triple; import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; @@ -64,13 +71,21 @@ import com.redhat.thermostat.annotations.internal.CacioTest; import com.redhat.thermostat.client.swing.EdtHelper; import com.redhat.thermostat.shared.locale.LocalizedString; +import com.redhat.thermostat.shared.locale.Translate; +import com.redhat.thermostat.vm.heap.analysis.client.core.HeapHistogramView; +import com.redhat.thermostat.vm.heap.analysis.client.core.HeapTreeMapView; +import com.redhat.thermostat.vm.heap.analysis.client.core.ObjectDetailsView; +import com.redhat.thermostat.vm.heap.analysis.client.locale.LocaleResources; @Category(CacioTest.class) @RunWith(CacioFESTRunner.class) public class HeapDetailsSwingTest { + private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer(); + private JFrame frame; private FrameFixture frameFixture; + private JTabbedPaneFixture tabPane; private HeapDetailsSwing view; @BeforeClass @@ -100,57 +115,192 @@ @GUITest @Test - public void verifyTabsAdded() throws InvocationTargetException, InterruptedException { + public void testTabSetup() throws InvocationTargetException, InterruptedException { + frameFixture.show(); + + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + tabPane = frameFixture.tabbedPane("tabs"); + assertNotNull(tabPane); + + ArrayList<String> tabTitles = new ArrayList<>(); + tabTitles.addAll(Arrays.asList(tabPane.tabTitles())); + + assertEquals(0, tabPane.component().getSelectedIndex()); + assertEquals(3, tabTitles.size()); + assertTrue(tabTitles.contains( + translator.localize(LocaleResources.HEAP_DUMP_SECTION_TREEMAP).getContents())); + assertTrue(tabTitles.contains( + translator.localize(LocaleResources.HEAP_DUMP_SECTION_OBJECT_BROWSER).getContents())); + assertTrue(tabTitles.contains( + translator.localize(LocaleResources.HEAP_DUMP_SECTION_HISTOGRAM).getContents())); + } + }); + } + + @GUITest + @Test + public void testUpdateView() throws InvocationTargetException, InterruptedException { frameFixture.show(); - JTabbedPaneFixture tabPane = frameFixture.tabbedPane("tabs"); - assertNotNull(tabPane); + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + tabPane = frameFixture.tabbedPane("tabs"); + assertNotNull(tabPane); + assertEquals(0, tabPane.component().getComponents().length); + } + }); + + Triple<HistogramPanel, ObjectDetailsPanel, SwingHeapTreeMapView> setup = setupViews(); + + String exceptionMessage = ""; + try { + view.updateView(null, setup.ii, setup.iii); + } catch (IllegalArgumentException e) { + exceptionMessage = e.getMessage(); + } + assertEquals("component is not swing", exceptionMessage); + + exceptionMessage = ""; + try { + view.updateView(setup.i, null, setup.iii); + } catch (IllegalArgumentException e) { + exceptionMessage = e.getMessage(); + } + assertEquals("component is not swing", exceptionMessage); - HistogramPanel histogramView = mock(HistogramPanel.class); - when(histogramView.getUiComponent()).thenReturn(new EdtHelper().callAndWait(new Callable<JPanel>() { + exceptionMessage = ""; + try { + view.updateView(setup.i, setup.ii, null); + } catch (IllegalArgumentException e) { + exceptionMessage = e.getMessage(); + } + assertEquals("component is not swing", exceptionMessage); + + try { + view.updateView(setup.i, setup.ii, setup.iii); + } catch (IllegalArgumentException e) { + Assert.fail("no illegal argument exception expected"); + } + + SwingUtilities.invokeAndWait(new Runnable() { @Override - public JPanel call() throws Exception { - return new JPanel(); + public void run() { + assertEquals(3, tabPane.component().getComponents().length); } - })); + }); + } + + @GUITest + @Test + public void testAddRemove() throws InvocationTargetException, InterruptedException { + frameFixture.show(); - ObjectDetailsPanel objectDetailsView = mock(ObjectDetailsPanel.class); - when(objectDetailsView.getUiComponent()).thenReturn(new EdtHelper().callAndWait(new Callable<JPanel>() { + final ArrayList<String> tabNames = new ArrayList<>(); + SwingUtilities.invokeAndWait(new Runnable() { @Override - public JPanel call() throws Exception { - return new JPanel(); + public void run() { + tabPane = frameFixture.tabbedPane("tabs"); + assertNotNull(tabPane); + tabNames.addAll(Arrays.asList(tabPane.tabTitles())); + } + }); + + for (String tabName : tabNames) { + view.removeSubView(new LocalizedString(tabName)); + } + + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + assertEquals(0, tabPane.tabTitles().length); } - })); - view.addSubView(new LocalizedString("test1"), histogramView); - view.addSubView(new LocalizedString("test2"), objectDetailsView); + }); + + String exceptionMessage = ""; + try { + view.addSubView(new LocalizedString("test1"), (HeapHistogramView) null); + } catch (IllegalArgumentException e) { + exceptionMessage = e.getMessage(); + } + assertEquals("component is not swing", exceptionMessage); + + exceptionMessage = ""; + try { + view.addSubView(new LocalizedString("test2"), (ObjectDetailsView) null); + } catch (IllegalArgumentException e) { + exceptionMessage = e.getMessage(); + } + assertEquals("component is not swing", exceptionMessage); - tabPane.requireTabTitles("test1", "test2"); + exceptionMessage = ""; + try { + view.addSubView(new LocalizedString("test3"), (HeapTreeMapView) null); + } catch (IllegalArgumentException e) { + exceptionMessage = e.getMessage(); + } + assertEquals("component is not swing", exceptionMessage); + + Triple<HistogramPanel, ObjectDetailsPanel, SwingHeapTreeMapView> setup = setupViews(); + try { + view.addSubView(new LocalizedString("test1"), setup.i); + view.addSubView(new LocalizedString("test2"), setup.ii); + view.addSubView(new LocalizedString("test3"), setup.iii); + } catch (IllegalArgumentException e) { + Assert.fail("no illegal argument exception expected"); + } + + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + ArrayList<String> tabTitles = new ArrayList<>(); + tabTitles.addAll(Arrays.asList(tabPane.tabTitles())); + + assertEquals(3, tabTitles.size()); + assertTrue(tabTitles.contains("test1")); + assertTrue(tabTitles.contains("test2")); + assertTrue(tabTitles.contains("test3")); + } + }); } - @GUITest - @Test - public void verifyAddRemove() throws InvocationTargetException, InterruptedException { - frameFixture.show(); - - JTabbedPaneFixture tabPane = frameFixture.tabbedPane("tabs"); - assertNotNull(tabPane); - + private Triple<HistogramPanel, ObjectDetailsPanel, SwingHeapTreeMapView> setupViews() { HistogramPanel histogramView = mock(HistogramPanel.class); - when(histogramView.getUiComponent()).thenReturn(new EdtHelper().callAndWait(new Callable<JPanel>() { - @Override - public JPanel call() throws Exception { - return new JPanel(); - } - })); + ObjectDetailsPanel objectDetailsView = mock(ObjectDetailsPanel.class); + SwingHeapTreeMapView treeMapView = mock(SwingHeapTreeMapView.class); + + try { + when(histogramView.getUiComponent()).thenReturn(new EdtHelper().callAndWait(new Callable<JPanel>() { + @Override + public JPanel call() throws Exception { + return new JPanel(); + } + })); + - view.addSubView(new LocalizedString("test1"), histogramView); + when(objectDetailsView.getUiComponent()).thenReturn(new EdtHelper().callAndWait(new Callable<JPanel>() { + @Override + public JPanel call() throws Exception { + return new JPanel(); + } + })); - tabPane.requireTabTitles("test1"); - view.removeSubView(new LocalizedString("test1")); + when(treeMapView.getUiComponent()).thenReturn(new EdtHelper().callAndWait(new Callable<JPanel>() { + @Override + public JPanel call() throws Exception { + return new JPanel(); + } + })); + } catch (InvocationTargetException | InterruptedException e) { + Assert.fail("Did not expect exception"); + } - tabPane.requireTabTitles(); + return new Triple<>(histogramView, objectDetailsView, treeMapView); } + }
--- a/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/SwingHeapTreeMapViewTest.java Wed Jun 29 12:23:09 2016 -0400 +++ b/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/SwingHeapTreeMapViewTest.java Wed Jun 29 12:23:10 2016 -0400 @@ -38,7 +38,9 @@ import static org.junit.Assert.assertEquals; +import org.fest.swing.edt.FailOnThreadViolationRepaintManager; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; import com.redhat.thermostat.client.swing.components.experimental.TreeMapNode; @@ -51,6 +53,11 @@ private SwingHeapTreeMapView.WeightAsSizeRenderer renderer; private TreeMapNode root; + @BeforeClass + public static void setUpOnce() { + FailOnThreadViolationRepaintManager.install(); + } + @Before public void setUp() { root = new TreeMapNode(SOME_ROOT, WEIGHT);