X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=test%2Fjalview%2Fgui%2FFreeUpMemoryTest.java;h=9b212749bca07fda9d9c8704a9234be18ab4faa8;hb=3c8a25936a2d805e7e3d7ab82f83b13135406d18;hp=9fc0678fdb20ee8af214292447d505351a1c5b01;hpb=8b21c13f49da87d7f13ec5efa3d7b4054aa3fd5f;p=jalview.git diff --git a/test/jalview/gui/FreeUpMemoryTest.java b/test/jalview/gui/FreeUpMemoryTest.java index 9fc0678..9b21274 100644 --- a/test/jalview/gui/FreeUpMemoryTest.java +++ b/test/jalview/gui/FreeUpMemoryTest.java @@ -1,13 +1,18 @@ package jalview.gui; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertTrue; import jalview.analysis.AlignmentGenerator; import jalview.bin.Cache; import jalview.bin.Jalview; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.SequenceGroup; import jalview.io.DataSourceType; import jalview.io.FileLoader; +import java.awt.event.MouseEvent; import java.io.File; import java.io.IOException; import java.io.PrintStream; @@ -15,6 +20,8 @@ import java.io.PrintStream; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; +import junit.extensions.PA; + public class FreeUpMemoryTest { private static final int ONE_MB = 1000 * 1000; @@ -27,16 +34,12 @@ public class FreeUpMemoryTest { Jalview.main(new String[] { "-nonews", "-props", "test/jalview/testProps.jvprops" }); - Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS", - Boolean.TRUE.toString()); - Cache.applicationProperties.setProperty("SHOW_QUALITY", - Boolean.TRUE.toString()); - Cache.applicationProperties.setProperty("SHOW_CONSERVATION", - Boolean.TRUE.toString()); - Cache.applicationProperties.setProperty("SHOW_OCCUPANCY", - Boolean.TRUE.toString()); - Cache.applicationProperties.setProperty("SHOW_IDENTITY", - Boolean.TRUE.toString()); + String True = Boolean.TRUE.toString(); + Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS", True); + Cache.applicationProperties.setProperty("SHOW_QUALITY", True); + Cache.applicationProperties.setProperty("SHOW_CONSERVATION", True); + Cache.applicationProperties.setProperty("SHOW_OCCUPANCY", True); + Cache.applicationProperties.setProperty("SHOW_IDENTITY", True); } /** @@ -50,12 +53,12 @@ public class FreeUpMemoryTest * * * If the test fails, this suggests that a reference to some large object - * (perhaps the alignment data, or consensus profile) has failed to be garbage - * collected. If this is the case, the heap will need to be inspected manually - * (suggest using jvisualvm) in order to track down where large objects are - * still referenced. The code (for example AlignmentViewport.dispose()) should - * then be updated to ensure references to large objects are set to null when - * they are no longer required. + * (perhaps the alignment data, or some annotation / Tree / PCA data) has + * failed to be garbage collected. If this is the case, the heap will need to + * be inspected manually (suggest using jvisualvm) in order to track down + * where large objects are still referenced. The code (for example + * AlignmentViewport.dispose()) should then be updated to ensure references to + * large objects are set to null when they are no longer required. * * @throws IOException */ @@ -65,35 +68,35 @@ public class FreeUpMemoryTest File f = generateAlignment(); f.deleteOnExit(); - /* - * load alignment, wait for consensus and other threads to complete - */ - AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(f.getPath(), - DataSourceType.FILE); - waitForThreads(af.getViewport()); + doStuffInJalview(f); + + Desktop.instance.closeAll_actionPerformed(null); - af.closeMenuItem_actionPerformed(true); + checkUsedMemory(35L); + } + /** + * Requests garbage collection and then checks whether remaining memory in use + * is less than the expected value (in Megabytes) + * + * @param expectedMax + */ + protected void checkUsedMemory(long expectedMax) + { /* - * request garbage collection and wait briefly for it to run; + * request garbage collection and wait for it to run; * NB there is no guarantee when, or whether, it will do so + * wait time depends on JRE/processor, generous allowance here */ System.gc(); - synchronized (this) - { - try - { - wait(10); - } catch (InterruptedException e) - { - } - } + waitFor(1500); /* * a second gc() call should not be necessary - but it is! * the test passes with it, and fails without it */ System.gc(); + waitFor(1500); /* * check used memory is 'reasonably low' @@ -101,8 +104,12 @@ public class FreeUpMemoryTest long availableMemory = Runtime.getRuntime().totalMemory() / ONE_MB; long freeMemory = Runtime.getRuntime().freeMemory() / ONE_MB; long usedMemory = availableMemory - freeMemory; - System.out.println("Memory in use after close all windows: " - + usedMemory + "MB"); + + /* + * sanity check - fails if any frame was added after + * closeAll_actionPerformed + */ + assertEquals(Desktop.instance.getAllFrames().length, 0); /* * if this assertion fails @@ -111,27 +118,93 @@ public class FreeUpMemoryTest * - identify large objects in the heap and their referers * - fix code as necessary to null the references on close */ - long expectedMax = 30L; // typically reports around 25 + System.out.println("Used memory after gc = " + usedMemory + "MB"); assertTrue(usedMemory < expectedMax, String.format( - "Used memory %d should be less than %d", usedMemory, + "Used memory %d should be less than %d (Recommend running test manually to verify)", + usedMemory, expectedMax)); } /** - * wait for consensus etc thread to complete + * Loads an alignment from file and exercises various operations in Jalview * - * @param av + * @param f */ - protected void waitForThreads(AlignViewport av) + protected void doStuffInJalview(File f) { - while (av.isCalcInProgress()) + /* + * load alignment, wait for consensus and other threads to complete + */ + AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(f.getPath(), + DataSourceType.FILE); + while (af.getViewport().isCalcInProgress()) + { + waitFor(200); + } + + /* + * open an Overview window + */ + af.overviewMenuItem_actionPerformed(null); + assertNotNull(af.alignPanel.overviewPanel); + + /* + * exercise the pop-up menu in the Overview Panel (JAL-2864) + */ + Object[] args = new Object[] { + new MouseEvent(af, 0, 0, 0, 0, 0, 1, true) }; + PA.invokeMethod(af.alignPanel.overviewPanel, + "showPopupMenu(java.awt.event.MouseEvent)", args); + + /* + * set a selection group - potential memory leak if it retains + * a reference to the alignment + */ + SequenceGroup sg = new SequenceGroup(); + sg.setStartRes(0); + sg.setEndRes(100); + AlignmentI al = af.viewport.getAlignment(); + for (int i = 0; i < al.getHeight(); i++) + { + sg.addSequence(al.getSequenceAt(i), false); + } + af.viewport.setSelectionGroup(sg); + + /* + * compute Tree and PCA (on all sequences, 100 columns) + */ + af.openTreePcaDialog(); + CalculationChooser dialog = af.alignPanel.getCalculationDialog(); + dialog.openPcaPanel("BLOSUM62", dialog.getSimilarityParameters(true)); + dialog.openTreePanel("BLOSUM62", dialog.getSimilarityParameters(false)); + + /* + * wait until Tree and PCA have been computed + */ + while (af.viewport.getCurrentTree() == null + && dialog.getPcaPanel().isWorking()) + { + waitFor(10); + } + + /* + * give Swing time to add the PCA panel (?!?) + */ + waitFor(100); + } + + /** + * Wait for waitMs miliseconds + * + * @param waitMs + */ + protected void waitFor(int waitMs) + { + try + { + Thread.sleep(waitMs); + } catch (InterruptedException e) { - try - { - Thread.sleep(200); - } catch (Exception x) - { - } } }