JAL-2154 report any db fetch failures as a fail at end
[jalview.git] / test / jalview / io / CrossRef2xmlTests.java
index d8cf9eb..838aa7a 100644 (file)
@@ -20,8 +20,6 @@
  */
 package jalview.io;
 
-import static org.testng.AssertJUnit.assertTrue;
-
 import jalview.analysis.CrossRef;
 import jalview.api.AlignmentViewPanel;
 import jalview.datamodel.AlignedCodonFrame;
@@ -37,7 +35,6 @@ import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.IdentityHashMap;
 import java.util.List;
 
 import org.testng.Assert;
@@ -55,6 +52,11 @@ public class CrossRef2xmlTests extends Jalview2xmlBase
   @Test(groups = { "Operational" }, enabled = true)
   public void testRetrieveAndShowCrossref() throws Exception
   {
+
+    List<String> failedDBRetr = new ArrayList<String>();
+    List<String> failedXrefMenuItems = new ArrayList<String>();
+    List<String> failedProjectRecoveries = new ArrayList<String>();
+
     // for every set of db queries
     // retrieve db query
     // verify presence of expected xrefs
@@ -88,22 +90,34 @@ public class CrossRef2xmlTests extends Jalview2xmlBase
       {
         String first = did[0] + " " + did[1];
         AlignFrame af = null;
+        boolean dna;
+        AlignmentI retral;
+        AlignmentI dataset;
+        SequenceI[] seqs;
+        List<String> ptypes = null;
         if (pass1 == 0)
         {
           // retrieve dbref
 
+          List<AlignFrame> afs = jalview.gui.SequenceFetcher.fetchAndShow(
+                  did[0], did[1]);
+          if (afs.size() == 0)
+          {
+            failedDBRetr.add("Didn't retrieve " + first);
+            break;
+          }
           keyseq.add(first);
-
-          af = jalview.gui.SequenceFetcher.fetchAndShow(did[0], did[1])
-                  .get(0);
-          assertTrue("Didn't retrieve " + first, af != null);
+          af = afs.get(0);
 
           // verify references for retrieved data
-          AlignmentTest.verifyAlignmentDatasetRefs(af.getViewport()
-                  .getAlignment(), true);
+          AlignmentTest.assertAlignmentDatasetRefs(af.getViewport()
+                  .getAlignment(), "Pass (" + pass1 + "," + pass2 + ","
+                  + pass3 + "): Fetch " + first + ":");
+          dna = af.getViewport().getAlignment().isNucleotide();
+          retral = af.getViewport().getAlignment();
+          dataset = retral.getDataset();
+          seqs = retral.getSequencesArray();
 
-          // store project to recover on next pass
-          stringify(dbtoviewBit, savedProjects, first, af.alignPanel);
         }
         else
         {
@@ -111,59 +125,79 @@ public class CrossRef2xmlTests extends Jalview2xmlBase
           // recover stored project
           af = new FileLoader(false).LoadFileWaitTillLoaded(savedProjects
                   .get(first).toString(), FormatAdapter.FILE);
+          System.out.println("Recovered view for '" + first + "' from '"
+                  + savedProjects.get(first).toString() + "'");
+          dna = af.getViewport().getAlignment().isNucleotide();
+          retral = af.getViewport().getAlignment();
+          dataset = retral.getDataset();
+          seqs = retral.getSequencesArray();
 
           // verify references for recovered data
-          AlignmentTest.verifyAlignmentDatasetRefs(af.getViewport()
-                  .getAlignment(), true);
+          AlignmentTest.assertAlignmentDatasetRefs(af.getViewport()
+                  .getAlignment(), "Pass (" + pass1 + "," + pass2 + ","
+                  + pass3 + "): Recover " + first + ":");
 
         }
 
-        boolean dna = af.getViewport().getAlignment().isNucleotide();
-        AlignmentI retral = af.getViewport().getAlignment();
-        AlignmentI dataset = retral.getDataset();
-        SequenceI[] seqs = retral.getSequencesArray();
-        List<String> ptypes = (seqs == null || seqs.length == 0) ? null
-                : new CrossRef(seqs, dataset)
-                        .findXrefSourcesForSequences(dna);
-
-        /*
-         * map between a view, and views generated after retrieving xrefs
-         */
-        IdentityHashMap<AlignmentViewPanel, List<AlignmentViewPanel>> viewxrefview = new IdentityHashMap<AlignmentViewPanel, List<AlignmentViewPanel>>();
-        /*
-         * map between a particular view and it's originating dbref path
-         */
-        IdentityHashMap<AlignmentViewPanel, String> viewsourcedb = new IdentityHashMap<AlignmentViewPanel, String>();
-
-        viewsourcedb.put(af.alignPanel, first);
-        for (String db : ptypes)
+        // store project on first pass, compare next pass
+        stringify(dbtoviewBit, savedProjects, first, af.alignPanel);
+
+        ptypes = (seqs == null || seqs.length == 0) ? null : new CrossRef(
+                seqs, dataset).findXrefSourcesForSequences(dna);
+
+        // start of pass2: retrieve each cross-ref for fetched or restored
+        // project.
+        do // first cross ref and recover crossref loop
         {
-          pass2 = 0;
-          do // second cross ref and recover crossref loop
+
+          for (String db : ptypes)
           {
             // counter for splitframe views retrieved via crossref
-            int p = 0;
+            int firstcr_ap = 0;
             // build next key so we an retrieve all views
-            String nextxref = first + " -> " + db + "{" + p + "}";
+            String nextxref = first + " -> " + db + "{" + firstcr_ap + "}";
             // perform crossref action, or retrieve stored project
             List<AlignmentViewPanel> cra_views = new ArrayList<AlignmentViewPanel>();
             CrossRefAction cra = null;
+            
             if (pass2 == 0)
             { // retrieve and show cross-refs in this thread
               cra = new CrossRefAction(af, seqs, dna, db);
               cra.run();
-              Assert.assertTrue(cra.getXrefViews().size() > 0,
-                      "No crossrefs retrieved for " + db);
+              if (cra.getXrefViews().size() == 0)
+              {
+                failedXrefMenuItems.add("No crossrefs retrieved for "
+                        + first + " -> " + db);
+                continue;
+              }
               cra_views = cra.getXrefViews();
-              viewxrefview.put(af.alignPanel, cra.getXrefViews());
+              assertNucleotide(cra_views.get(0),
+                      "Nucleotide panel included proteins for " + first
+                              + " -> " + db);
+              assertProtein(cra_views.get(1),
+                      "Protein panel included nucleotides for " + first
+                              + " -> " + db);
             }
             else
             {
               Desktop.instance.closeAll_actionPerformed(null);
+              pass3 = 0;
+              // recover stored project
+              File storedProject = savedProjects.get(nextxref);
+              if (storedProject == null)
+              {
+                failedProjectRecoveries.add("Failed to store a view for '"
+                        + nextxref + "'");
+                continue;
+              }
+
               // recover stored project
               AlignFrame af2 = new FileLoader(false)
-                      .LoadFileWaitTillLoaded(savedProjects.get(first)
+                      .LoadFileWaitTillLoaded(savedProjects.get(nextxref)
                               .toString(), FormatAdapter.FILE);
+              System.out.println("Recovered view for '" + nextxref
+                      + "' from '" + savedProjects.get(nextxref).toString()
+                      + "'");
               // gymnastics to recover the alignPanel/Complementary alignPanel
               if (af2.getViewport().isNucleotide())
               {
@@ -184,55 +218,94 @@ public class CrossRef2xmlTests extends Jalview2xmlBase
 
               }
             }
+            HashMap<String, List<String>> xrptypes = new HashMap<String, List<String>>();
+            // first save/verify views.
             for (AlignmentViewPanel avp : cra_views)
             {
+              nextxref = first + " -> " + db + "{" + firstcr_ap++ + "}";
               // verify references for this panel
-              AlignmentTest.verifyAlignmentDatasetRefs(avp.getAlignment(),
-                      true);
+              AlignmentTest.assertAlignmentDatasetRefs(avp.getAlignment(),
+                      "Pass (" + pass1 + "," + pass2 + "," + pass3
+                              + "): before start of pass3: " + nextxref
+                              + ":");
 
               SequenceI[] xrseqs = avp.getAlignment().getSequencesArray();
-              nextxref = first + " -> " + db + "{" + p++ + "}";
 
-              viewsourcedb.put(avp, nextxref);
-              stringify(dbtoviewBit, savedProjects, nextxref, avp);
-              keyseq.add(nextxref);
-
-              List<String> xrptypes = (seqs == null || seqs.length == 0) ? null
+              List<String> _xrptypes = (seqs == null || seqs.length == 0) ? null
                       : new CrossRef(xrseqs, dataset)
                               .findXrefSourcesForSequences(avp
                                       .getAlignViewport().isNucleotide());
-              for (String xrefdb : xrptypes)
+              
+              stringify(dbtoviewBit, savedProjects, nextxref, avp);
+              xrptypes.put(nextxref, _xrptypes);
+
+            }
+
+            // now do the second xref pass starting from either saved or just
+            // recovered split pane, in sequence
+            do // retrieve second set of cross refs or recover and verify
+            {
+              firstcr_ap = 0;
+              for (AlignmentViewPanel avp : cra_views)
               {
-                pass3 = 0;
-                do // 3rd cross ref and recover crossref loop
+                nextxref = first + " -> " + db + "{" + firstcr_ap++ + "}";
+                for (String xrefdb : xrptypes.get(nextxref))
                 {
                   List<AlignmentViewPanel> cra_views2 = new ArrayList<AlignmentViewPanel>();
                   int q = 0;
-                  String nextnextxref = "{" + p + "}" + nextxref + " -> "
-                          + xrefdb + "{" + q + "}";
+                  String nextnextxref = nextxref
+                          + " -> " + xrefdb + "{" + q + "}";
 
-                  AlignFrame nextaf = Desktop.getAlignFrameFor(avp
-                          .getAlignViewport());
                   if (pass3 == 0)
                   {
 
+                    SequenceI[] xrseqs = avp.getAlignment()
+                            .getSequencesArray();
+                    AlignFrame nextaf = Desktop.getAlignFrameFor(avp
+                            .getAlignViewport());
+
                     cra = new CrossRefAction(nextaf, xrseqs, avp
                             .getAlignViewport().isNucleotide(), xrefdb);
                     cra.run();
-                    Assert.assertTrue(cra.getXrefViews().size() > 0,
-                            "No crossrefs found for '" + nextxref + "' to "
-                                    + xrefdb + " via '" + nextaf.getTitle()
-                                    + "'");
+                    if (cra.getXrefViews().size() == 0)
+                    {
+                      failedXrefMenuItems
+                              .add("No crossrefs retrieved for '"
+                              + nextxref + "' to " + xrefdb + " via '"
+                              + nextaf.getTitle() + "'");
+                      continue;
+                    }
                     cra_views2 = cra.getXrefViews();
+                    assertNucleotide(cra_views2.get(0),
+                            "Nucleotide panel included proteins for '"
+                                    + nextxref + "' to " + xrefdb
+                                    + " via '" + nextaf.getTitle() + "'");
+                    assertProtein(cra_views2.get(1),
+                            "Protein panel included nucleotides for '"
+                                    + nextxref + "' to " + xrefdb
+                                    + " via '" + nextaf.getTitle() + "'");
+
                   }
                   else
                   {
                     Desktop.instance.closeAll_actionPerformed(null);
                     // recover stored project
+                    File storedProject = savedProjects.get(nextnextxref);
+                    if (storedProject == null)
+                    {
+                      failedProjectRecoveries
+                              .add("Failed to store a view for '"
+                                      + nextnextxref + "'");
+                      continue;
+                    }
                     AlignFrame af2 = new FileLoader(false)
                             .LoadFileWaitTillLoaded(
                                     savedProjects.get(nextnextxref)
                                             .toString(), FormatAdapter.FILE);
+                    System.out.println("Recovered view for '"
+                            + nextnextxref + "' from '"
+                            + savedProjects.get(nextnextxref).toString()
+                            + "'");
                     // gymnastics to recover the alignPanel/Complementary
                     // alignPanel
                     if (af2.getViewport().isNucleotide())
@@ -259,24 +332,121 @@ public class CrossRef2xmlTests extends Jalview2xmlBase
 
                   for (AlignmentViewPanel nextavp : cra_views2)
                   {
-                    nextnextxref = "{" + p + "}" + nextxref + " -> "
-                            + xrefdb + "{" + q++ + "}";
+                    nextnextxref = nextxref
+                            + " -> " + xrefdb + "{" + q++ + "}";
 
                     // verify references for this panel
-                    AlignmentTest.verifyAlignmentDatasetRefs(
-                            nextavp.getAlignment(), true);
+                    AlignmentTest.assertAlignmentDatasetRefs(
+                            nextavp.getAlignment(), "" + "Pass (" + pass1
+                                    + "," + pass2 + "): For "
+                                    + nextnextxref + ":");
 
-                    viewsourcedb.put(nextavp, nextnextxref);
                     stringify(dbtoviewBit, savedProjects, nextnextxref,
                             nextavp);
                     keyseq.add(nextnextxref);
                   }
-                } while (pass3++ < 2 && pass2 < 1);
-              }
-            }
-          } while (pass2++ < 2 && pass1 < 1);
+                } // end of loop around showing all xrefdb for crossrf2
+
+              } // end of loop around all viewpanels from crossrf1
+            } while (pass2 == 2 && pass3++ < 2);
+            // fetchdb->crossref1->crossref-2->verify for xrefs we
+            // either loop twice when pass2=0, or just once when pass2=1
+            // (recovered project from previous crossref)
+
+          } // end of loop over db-xrefs for crossref-2
+
+          // fetchdb-->crossref1
+          // for each xref we try to retrieve xref, store and verify when
+          // pass1=0, or just retrieve and verify when pass1=1
+        } while (pass1 == 1 && pass2++ < 2);
+        // fetchdb
+        // for each ref we
+        // loop twice: first, do the retrieve, second recover from saved project
+
+        // increment pass counters, so we repeat traversal starting from the
+        // oldest saved project first.
+        if (pass1 == 0)
+        {
+          // verify stored projects for first set of cross references
+          pass1 = 1;
+          // and verify cross-references retrieved from stored projects
+          pass2 = 0;
+          pass3 = 0;
         }
-      } while (++pass1 < 2);
+        else
+        {
+          pass1++;
+          if (pass1 < 2)
+          {
+            // verify stored projects for second set of cross references
+            pass2 = 1;
+          // and verify cross-references retrievable from those stored projects.
+            pass3 = 0;
+          }
+        }
+      } while (pass3 < 2);
+    }
+    if (failedXrefMenuItems.size() > 0)
+    {
+      for (String s : failedXrefMenuItems)
+      {
+        System.err.println(s);
+      }
+      Assert.fail("Faulty xref menu (" + failedXrefMenuItems.size()
+              + " counts)");
+    }
+    if (failedProjectRecoveries.size() > 0)
+    {
+
+      for (String s : failedProjectRecoveries)
+      {
+        System.err.println(s);
+      }
+      Assert.fail("Didn't recover projects for some retrievals (did they retrieve ?) ("
+              + failedProjectRecoveries.size() + " counts)");
+    }
+    if (failedDBRetr.size() > 0)
+    {
+      for (String s : failedProjectRecoveries)
+      {
+        System.err.println(s);
+      }
+      Assert.fail("Didn't retrieve some db refs for checking cross-refs ("
+              + failedDBRetr.size() + " counts)");
+    }
+  }
+
+  private void assertProtein(AlignmentViewPanel alignmentViewPanel,
+          String message)
+  {
+    assertType(true, alignmentViewPanel, message);
+  }
+
+  private void assertNucleotide(AlignmentViewPanel alignmentViewPanel,
+          String message)
+  {
+    assertType(false, alignmentViewPanel, message);
+  }
+
+  private void assertType(boolean expectProtein,
+          AlignmentViewPanel alignmentViewPanel, String message)
+  {
+    List<SequenceI> nonType = new ArrayList<SequenceI>();
+    for (SequenceI sq : alignmentViewPanel.getAlignViewport()
+            .getAlignment()
+            .getSequences())
+    {
+      if (sq.isProtein() != expectProtein)
+      {
+        nonType.add(sq);
+      }
+    }
+    if (nonType.size() > 0)
+    {
+      Assert.fail(message + " [ "
+              + (expectProtein ? "nucleotides were " : "proteins were ")
+              + nonType.toString()
+              + " ]");
     }
   }
 
@@ -307,22 +477,22 @@ public class CrossRef2xmlTests extends Jalview2xmlBase
     if (savedProjects != null)
     {
       if (savedProjects.get(xrefpath) == null)
-    {
-      // write a project file for this view. On the second pass, this will be
-      // recovered and cross-references verified
-      try
-      {
-        File prfile = File.createTempFile("crossRefTest", ".jvp");
-        AlignFrame af = Desktop.getAlignFrameFor(avp.getAlignViewport());
-        new Jalview2XML(false).saveAlignment(af, prfile.toString(),
-                af.getTitle());
-        System.out.println("Written view from '" + xrefpath + "' as '"
-                + prfile.getAbsolutePath() + "'");
-        savedProjects.put(xrefpath, prfile);
-      } catch (IOException q)
       {
-        Assert.fail("Unexpected IO Exception", q);
-      }
+        // write a project file for this view. On the second pass, this will be
+        // recovered and cross-references verified
+        try
+        {
+          File prfile = File.createTempFile("crossRefTest", ".jvp");
+          AlignFrame af = Desktop.getAlignFrameFor(avp.getAlignViewport());
+          new Jalview2XML(false).saveAlignment(af, prfile.toString(),
+                  af.getTitle());
+          System.out.println("Written view from '" + xrefpath + "' as '"
+                  + prfile.getAbsolutePath() + "'");
+          savedProjects.put(xrefpath, prfile);
+        } catch (IOException q)
+        {
+          Assert.fail("Unexpected IO Exception", q);
+        }
       }
       else
       {