X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=test%2Fjalview%2Fbin%2FCommandsTest.java;fp=test%2Fjalview%2Fbin%2FCommandsTest.java;h=7ca4e555e30d47bbe5bcf1cf2a34894ad005b9c7;hb=ca9a7a8387cb17ea0a4511d1ce3c4c0c45e50db4;hp=7b427371a7a6909c634ae4ae58fc83d9d6668fca;hpb=a2f16af6d565a7535083ff87da9be198b31d95c0;p=jalview.git diff --git a/test/jalview/bin/CommandsTest.java b/test/jalview/bin/CommandsTest.java index 7b42737..7ca4e55 100644 --- a/test/jalview/bin/CommandsTest.java +++ b/test/jalview/bin/CommandsTest.java @@ -20,14 +20,15 @@ */ package jalview.bin; +import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; -import java.lang.reflect.InvocationTargetException; import java.nio.file.Files; import java.util.Date; import java.util.HashSet; import java.util.Set; +import javax.imageio.ImageIO; import javax.swing.SwingUtilities; import org.testng.Assert; @@ -93,7 +94,12 @@ public class CommandsTest public static void callJalviewMain(String[] args) { - if (Jalview.getInstance() != null) + callJalviewMain(args, false); + } + + public static void callJalviewMain(String[] args, boolean newJalview) + { + if (Jalview.getInstance() != null && !newJalview) { Jalview.getInstance().doMain(args); } @@ -116,7 +122,11 @@ public class CommandsTest } */ - @Test(groups = { "Functional", "testTask3" }, dataProvider = "cmdLines", singleThreaded = true) + @Test( + groups = + { "Functional", "testTask3" }, + dataProvider = "cmdLines", + singleThreaded = true) public void commandsOpenTest(String cmdLine, boolean cmdArgs, int numFrames, String[] sequences) @@ -169,40 +179,62 @@ public class CommandsTest @Test( groups = { "Functional", "testTask3" }, - dataProvider = "structureImageOutputFiles", singleThreaded = true) + dataProvider = "structureImageOutputFiles", + singleThreaded = true) public void structureImageOutputTest(String cmdLine, String[] filenames) throws IOException { cleanupFiles(filenames); - String[] args = (cmdLine + " --gui").split("\\s+"); + String[] args = (cmdLine).split("\\s+"); try { - callJalviewMain(args); + callJalviewMain(args, true); Commands cmds = Jalview.getInstance().getCommands(); Assert.assertNotNull(cmds); - File lastFile = null; - for (String filename : filenames) + verifyIncreasingSize(cmdLine, filenames); + } catch (Exception x) + { + Assert.fail("Unexpected exception during structureImageOutputTest", + x); + } finally + { + cleanupFiles(filenames); + tearDown(); + } + } + + /** + * given two command lines, compare the output files produced - they should + * exist and be equal in size + */ + @Test( + groups = + { "Functional", "testTask3" }, + dataProvider = "compareHeadlessAndGUIOps", + singleThreaded = true) + public void headlessOrGuiImageOutputTest(String[] cmdLines, + String[] filenames) throws IOException + { + cleanupFiles(filenames); + try + { + for (String cmdLine : cmdLines) { - File file = new File(filename); - Assert.assertTrue(file.exists(), "File '" + filename - + "' was not created by '" + cmdLine + "'"); - Assert.assertTrue(file.isFile(), "File '" + filename - + "' is not a file from '" + cmdLine + "'"); - Assert.assertTrue(Files.size(file.toPath()) > 0, "File '" + filename - + "' has no content from '" + cmdLine + "'"); - // make sure the successive output files get bigger! - if (lastFile != null) + CommandLineOperations.Worker runner = CommandLineOperations + .getJalviewDesktopRunner(false, cmdLine, 1000); + long timeOut = 10000; + while (runner.isAlive() && timeOut > 0) { - waitForLastWrite(file,25); - - if (Files.size(file.toPath()) > Files - .size(lastFile.toPath())) - Assert.assertTrue(Files.size(file.toPath()) > Files - .size(lastFile.toPath())); + Thread.sleep(25); + timeOut -= 25; } - // remember it for next file - lastFile = file; } + + verifyOrderedFileSet(cmdLines[0] + " vs " + cmdLines[1], filenames, + false); + + verifySimilarEnoughImages(cmdLines[0] + " vs " + cmdLines[1], + filenames, 0f, 0f); } catch (Exception x) { Assert.fail("Unexpected exception during structureImageOutputTest", @@ -214,21 +246,161 @@ public class CommandsTest } } + @DataProvider(name = "compareHeadlessAndGUIOps") + public Object[][] compareHeadlessAndGUIOps() + { + return new Object[][] { + new Object[] + { new String[] { "--open examples/uniref50.fa " + + "--structure [seqid=FER1_SPIOL,tempfac=plddt,showssannotations,structureviewer=jmol]" + + "examples/AlphaFold/AF-P00221-F1-model_v4.pdb " + + "--paematrix examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json --image=" + + testfiles + "/" + + "test-al-pae-ss-gui.png --overwrite --gui --quit", + "--open examples/uniref50.fa " + + "--structure [seqid=FER1_SPIOL,tempfac=plddt,showssannotations,structureviewer=jmol]" + + "examples/AlphaFold/AF-P00221-F1-model_v4.pdb " + + "--paematrix examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json --image=" + + testfiles + "/" + + "test-al-pae-ss-nogui.png --overwrite --nogui" }, + new String[] + { testfiles + "/test-al-pae-ss-gui.png", + testfiles + "/test-al-pae-ss-nogui.png", } } }; + } + + private static void verifyIncreasingSize(String cmdLine, + String[] filenames) throws Exception + { + verifyOrderedFileSet(cmdLine, filenames, true); + } + + private static void verifyOrderedFileSet(String cmdLine, + String[] filenames, boolean increasingSize) throws Exception + { + File lastFile = null; + for (String filename : filenames) + { + File file = new File(filename); + Assert.assertTrue(file.exists(), "File '" + filename + + "' was not created by '" + cmdLine + "'"); + Assert.assertTrue(file.isFile(), "File '" + filename + + "' is not a file from '" + cmdLine + "'"); + Assert.assertTrue(Files.size(file.toPath()) > 0, "File '" + filename + + "' has no content from '" + cmdLine + "'"); + // make sure the successive output files get bigger! + if (lastFile != null) + { + waitForLastWrite(file, 25); + + if (increasingSize) + { + Assert.assertTrue( + Files.size(file.toPath()) > Files.size(lastFile.toPath()), + "Expected " + file.toPath() + " to be larger than " + + lastFile.toPath()); + } + else + { + Assert.assertEquals(Files.size(file.toPath()), + Files.size(lastFile.toPath()), + "New file " + file.toPath() + + " (actual size) not same as last file's size " + + lastFile.toString()); + } + } + // remember it for next file + lastFile = file; + } + + } + + private static void verifySimilarEnoughImages(String cmdLine, + String[] filenames, float w_tolerance_pc, float h_tolerance_pc) + throws Exception + { + int min_w = -1; + int max_w = -1; + int min_h = -1; + int max_h = -1; + for (String filename : filenames) + { + File file = new File(filename); + Assert.assertTrue(file.exists(), "File '" + filename + + "' was not created by '" + cmdLine + "'"); + Assert.assertTrue(file.isFile(), "File '" + filename + + "' is not a file from '" + cmdLine + "'"); + Assert.assertTrue(Files.size(file.toPath()) > 0, "File '" + filename + + "' has no content from '" + cmdLine + "'"); + + BufferedImage img = ImageIO.read(file); + if (img.getWidth() < min_w || min_w == -1) + { + min_w = img.getWidth(); + } + if (img.getWidth() > max_w || max_w == -1) + { + max_w = img.getWidth(); + } + if (img.getHeight() < min_h || min_h == -1) + { + min_h = img.getHeight(); + } + if (img.getHeight() > max_h || max_h == -1) + { + max_h = img.getHeight(); + } + } + Assert.assertTrue(min_w > 0, + "Minimum width is not positive (" + min_w + ")"); + Assert.assertTrue(max_w > 0, + "Maximum width is not positive (" + max_w + ")"); + Assert.assertTrue(min_h > 0, + "Minimum height is not positive (" + min_h + ")"); + Assert.assertTrue(max_h > 0, + "Maximum height is not positive (" + max_h + ")"); + // tolerance + Assert.assertTrue(100 * (max_w - min_w) / min_w <= w_tolerance_pc, + "Width variation (" + (max_w - min_w) + + " not within tolerance (" + w_tolerance_pc + + "%) of minimum width (" + min_w + ")"); + if (max_w != min_w) + { + System.out.println("Widths within tolerance (" + w_tolerance_pc + + "%), min_w=" + min_w + " < max_w=" + max_w); + } + Assert.assertTrue(100 * (max_h - min_h) / min_h <= h_tolerance_pc, + "Height variation (" + (max_h - min_h) + + " not within tolerance (" + h_tolerance_pc + + "%) of minimum height (" + min_h + ")"); + if (max_h != min_h) + { + System.out.println("Heights within tolerance (" + h_tolerance_pc + + "%), min_h=" + min_h + " < max_h=" + max_h); + } + } + private static long waitForLastWrite(File file, int i) throws IOException { - long lastSize,stableSize =Files.size(file.toPath()); + long lastSize, stableSize = Files.size(file.toPath()); // wait around until we are sure the file has been completely written. - do { + do + { lastSize = stableSize; - try { + try + { Thread.sleep(i); - } catch (Exception x) {} - stableSize=Files.size(file.toPath()); - } while (stableSize!=lastSize); + } catch (Exception x) + { + } + stableSize = Files.size(file.toPath()); + } while (stableSize != lastSize); return stableSize; } - @Test(groups = "Functional", dataProvider = "argfileOutputFiles", singleThreaded = true) + @Test( + groups = "Functional", + dataProvider = "argfileOutputFiles", + singleThreaded = true) public void argFilesGlobAndSubstitutionsTest(String cmdLine, String[] filenames) throws IOException @@ -251,10 +423,13 @@ public class CommandsTest Assert.assertTrue(Files.size(file.toPath()) > 0, "File '" + filename + "' has no content from '" + cmdLine + "'"); // make sure the successive output files get bigger! - if (lastFile != null) { + if (lastFile != null) + { Assert.assertTrue(Files.size(file.toPath()) > Files .size(lastFile.toPath())); - System.out.println("this file: "+file+" +"+Files.size(file.toPath()) + " greater than " +Files.size(lastFile.toPath())); + System.out.println("this file: " + file + " +" + + Files.size(file.toPath()) + " greater than " + + Files.size(lastFile.toPath())); } // remember it for next file lastFile = file; @@ -276,49 +451,60 @@ public class CommandsTest { return new Object[][] { // + /* + */ { "--gui --nonews --nosplash --open=./examples/test_fab41.result/sample.a2m " + "--structure=./examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3.pdb " - + "--structureimage=" + testfiles + "/structureimage1.png " + + "--structureimage=" + testfiles + + "/structureimage0-1.png " + "--open=./examples/test_fab41.result/sample.a2m " + "--structure=./examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3.pdb " + "--structureimage=" + testfiles - + "/structureimage2.png --scale=1.5 " + + "/structureimage0-2.png --scale=1.5 " + "--open=./examples/test_fab41.result/sample.a2m " + "--structure=./examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3.pdb " + "--structureimage=" + testfiles - + "/structureimage3.png --scale=2.0 ", + + "/structureimage0-3.png --scale=2.0 ", new String[] - { testfiles + "/structureimage1.png", - testfiles + "/structureimage2.png", - testfiles + "/structureimage3.png" } }, + { testfiles + "/structureimage0-1.png", + testfiles + "/structureimage0-2.png", + testfiles + "/structureimage0-3.png" } }, { "--headless --noquit --open=./examples/test_fab41.result/sample.a2m " + "--structure=./examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3.pdb " - + "--structureimage=" + testfiles + "/structureimage1.png " + + "--structureimage=" + testfiles + + "/structureimage1-1.png " + "--open=./examples/test_fab41.result/sample.a2m " + "--structure=./examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3.pdb " + "--structureimage=" + testfiles - + "/structureimage2.png --scale=1.5 " + + "/structureimage1-2.png --scale=1.5 " + "--open=./examples/test_fab41.result/sample.a2m " + "--structure=./examples/test_fab41.result/test_fab41_unrelaxed_rank_1_model_3.pdb " + "--structureimage=" + testfiles - + "/structureimage3.png --scale=2.0 ", + + "/structureimage1-3.png --scale=2.0 ", new String[] - { testfiles + "/structureimage1.png", - testfiles + "/structureimage2.png", - testfiles + "/structureimage3.png" } }, - { "--gui --nonews --nosplash --open examples/1gaq.txt --append ./examples/3W5V.pdb "+"--structure examples/1gaq.txt --seqid \"1GAQ|A\" "+"--structureimage "+testfiles+"/1gaq.png --structure examples/3W5V.pdb "+"--seqid \"3W5V|A\" --structureimage "+testfiles+"/3w5v.png --overwrite", - - new String[] { - testfiles+"/1gaq.png",testfiles+"/3w5v.png" - } - }, - { "--headless --noquit --open ./examples/1gaq.txt --append ./examples/3W5V.pdb "+"--structure examples/1gaq.txt --seqid \"1GAQ|A\" "+"--structureimage "+testfiles+"/1gaq.png --structure examples/3W5V.pdb "+"--seqid \"3W5V|A\" --structureimage "+testfiles+"/3w5v.png --overwrite", - - new String[] { - testfiles+"/1gaq.png",testfiles+"/3w5v.png" - } - } + { testfiles + "/structureimage1-1.png", + testfiles + "/structureimage1-2.png", + testfiles + "/structureimage1-3.png" } }, + { "--gui --nonews --nosplash --open examples/1gaq.txt --append ./examples/3W5V.pdb " + + "--structure examples/1gaq.txt --seqid \"1GAQ|A\" " + + "--structureimage " + testfiles + + "/structureimage2-1gaq.png --structure examples/3W5V.pdb " + + "--seqid \"3W5V|A\" --structureimage " + testfiles + + "/structureimage2-3w5v.png --overwrite", + new String[] + { testfiles + "/structureimage2-3w5v.png", + testfiles + "/structureimage2-1gaq.png", } }, + { "--headless --noquit --open ./examples/1gaq.txt --append ./examples/3W5V.pdb " + + "--structure examples/1gaq.txt --seqid \"1GAQ|A\" " + + "--structureimage " + testfiles + + "/structureimage3-1gaq.png --structure examples/3W5V.pdb " + + "--seqid \"3W5V|A\" --structureimage " + testfiles + + "/structureimage3-3w5v.png --overwrite", + + new String[] + { testfiles + "/structureimage3-3w5v.png", + testfiles + "/structureimage3-1gaq.png", } } /* */ // @@ -674,4 +860,105 @@ public class CommandsTest }; } + @Test( + groups = + { "Functional", "testTask3" }, + dataProvider = "structureImageAnnotationsOutputFiles", + singleThreaded = true) + public void structureImageAnnotationsOutputTest(String cmdLine, + String filename, int height) throws IOException + { + cleanupFiles(new String[] { filename }); + String[] args = (cmdLine).split("\\s+"); + callJalviewMain(args, true); // Create new instance of Jalview each time for + // linkedIds + BufferedImage img = ImageIO.read(new File(filename)); + Assert.assertEquals(height, img.getHeight(), "Output image '" + filename + + "' is not in the expected height range, possibly because of the wrong number of annotations"); + + cleanupFiles(new String[] { filename }); + tearDown(); + } + + @DataProvider(name = "structureImageAnnotationsOutputFiles") + public Object[][] structureImageAnnotationsOutputFiles() + { + String filename = "test/jalview/bin/argparser/testfiles/test_annotations.png"; + return new Object[][] { + // MUST use --noquit with --headless to avoid a System.exit() + { "--noquit --headless --nonews --nosplash --open=./examples/uniref50.fa " + + "--structure=examples/AlphaFold/AF-P00221-F1-model_v4.pdb " + + "--seqid=FER1_SPIOL --structureviewer=jmol " + + "--paematrix examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json " + + "--image=" + filename + " " + "--tempfac=plddt " + + "--overwrite " // + + "--noshowssannotations " + "--noshowannotations", // + filename, // + 252 }, // + { "--noquit --headless --nonews --nosplash --open=./examples/uniref50.fa " + + "--structure=examples/AlphaFold/AF-P00221-F1-model_v4.pdb " + + "--seqid=FER1_SPIOL --structureviewer=jmol " + + "--paematrix examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json " + + "--image=" + filename + " " + "--tempfac=plddt " + + "--overwrite " // + + "--showssannotations " + "--noshowannotations", // + filename, // + 368 }, // + { "--noquit --headless --nonews --nosplash --open=./examples/uniref50.fa " + + "--structure=examples/AlphaFold/AF-P00221-F1-model_v4.pdb " + + "--seqid=FER1_SPIOL --structureviewer=jmol " + + "--paematrix examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json " + + "--image=" + filename + " " + "--tempfac=plddt " + + "--overwrite " // + + "--noshowssannotations " + "--showannotations", // + filename, // + 524 }, // + { "--noquit --headless --nonews --nosplash --open=./examples/uniref50.fa " + + "--structure=examples/AlphaFold/AF-P00221-F1-model_v4.pdb " + + "--seqid=FER1_SPIOL --structureviewer=jmol " + + "--paematrix examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json " + + "--image=" + filename + " " + "--tempfac=plddt " + + "--overwrite " // + + "--showssannotations " + "--showannotations", // + filename, // + 660 }, // + { "--gui --nonews --nosplash --open=./examples/uniref50.fa " + + "--structure=examples/AlphaFold/AF-P00221-F1-model_v4.pdb " + + "--seqid=FER1_SPIOL --structureviewer=jmol " + + "--paematrix examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json " + + "--image=" + filename + " " + "--tempfac=plddt " + + "--overwrite " // + + "--noshowssannotations " + "--noshowannotations", // + filename, // + 252 }, // + { "--gui --nonews --nosplash --open=./examples/uniref50.fa " + + "--structure=examples/AlphaFold/AF-P00221-F1-model_v4.pdb " + + "--seqid=FER1_SPIOL --structureviewer=jmol " + + "--paematrix examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json " + + "--image=" + filename + " " + "--tempfac=plddt " + + "--overwrite " // + + "--showssannotations " + "--noshowannotations", // + filename, // + 368 }, // + { "--gui --nonews --nosplash --open=./examples/uniref50.fa " + + "--structure=examples/AlphaFold/AF-P00221-F1-model_v4.pdb " + + "--seqid=FER1_SPIOL --structureviewer=jmol " + + "--paematrix examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json " + + "--image=" + filename + " " + "--tempfac=plddt " + + "--overwrite " // + + "--noshowssannotations " + "--showannotations", // + filename, // + 524 }, // + { "--gui --nonews --nosplash --open=./examples/uniref50.fa " + + "--structure=examples/AlphaFold/AF-P00221-F1-model_v4.pdb " + + "--seqid=FER1_SPIOL --structureviewer=jmol " + + "--paematrix examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json " + + "--image=" + filename + " " + "--tempfac=plddt " + + "--overwrite " // + + "--showssannotations " + "--showannotations", // + filename, // + 660 }, // + }; + } + }