bcaf231f7de3921efe6814afe820e1ba4b1e1be0
chmalee
  Wed Feb 19 11:55:53 2020 -0800
Adding a test for missing hub description or genome description pages, refs #13428

diff --git src/hg/utils/hubCheck/hubCheck.c src/hg/utils/hubCheck/hubCheck.c
index 73070d2..b148162 100644
--- src/hg/utils/hubCheck/hubCheck.c
+++ src/hg/utils/hubCheck/hubCheck.c
@@ -500,47 +500,52 @@
     strippedMessage = cloneString(message);
 stripChar(strippedMessage, '\n');
 safef(id, sizeof(id), "%s%d", sl, count);
 
 // make the error message
 dyStringPrintf(errors, "trackData['%s'] = [%s];\n", sl,
     makeChildObjectString(id, "Hub Error", sl, sl, "#550073", sl, strippedMessage, sl));
 
 // display it by default
 dyStringPrintf(errors, "trackData['#'] = [%s];\n",
     makeFolderObjectString(sl, "Error getting hub or genomes configuration", "#", "Click to open node", TRUE, TRUE));
 count++;
 }
 
 void genomeErr(struct dyString *errors, char *message, struct trackHub *hub,
-    struct trackHubGenome *genome)
+    struct trackHubGenome *genome, boolean doHtml)
 /* Construct the right javascript for the jstree for a top-level genomes.txt error or
  * error opening a trackDb.txt file */
 {
+if (!doHtml)
+    dyStringPrintf(errors, "%s", message);
+else
+    {
     static int count = 0; // forces unique ID's which the jstree object needs
     char id[512];
     char *strippedMessage = NULL;
     char *genomeName = trackHubSkipHubName(genome->name);
     if (message)
         strippedMessage = cloneString(message);
     stripChar(strippedMessage, '\n');
     safef(id, sizeof(id), "%s%d", genomeName, count);
 
-dyStringPrintf(errors, "trackData['%s'] = [%s", genomeName,
-    makeChildObjectString(id, "Error Getting TrackDb", genomeName, genomeName, "#550073", genomeName, strippedMessage, genomeName));
+    dyStringPrintf(errors, "trackData['%s'] = [%s,", genomeName,
+        makeChildObjectString(id, "Genome Error", genomeName, genomeName, "#550073", genomeName, strippedMessage, genomeName));
     count++;
     }
+}
 
 void trackDbErr(struct dyString *errors, char *message, struct trackHubGenome *genome, struct trackDb *tdb, boolean doHtml)
 /* Adds the right object for a jstree object of trackDb configuration errors.  */
 {
 if (!doHtml)
     {
     dyStringPrintf(errors, "%s", message);
     }
 else
     {
     char *strippedMessage = NULL;
     char *splitMessages[16]; // SUBGROUP_MAX=9 but add a few extra just in case
     char parentOrTrackString[512];
     char id[512];
     static int count = 0; // forces unique ID's which the jstree object needs
@@ -819,56 +824,54 @@
 return retVal;
 }
 
 
 int hubCheckGenome(struct trackHub *hub, struct trackHubGenome *genome,
                 struct trackHubCheckOptions *options, struct dyString *errors)
 /* Check out genome within hub. */
 {
 struct errCatch *errCatch = errCatchNew();
 struct trackDb *tdbList = NULL;
 int genomeErrorCount = 0;
 boolean openedGenome = FALSE;
 
 if (errCatchStart(errCatch))
     {
+    if (genome->twoBitPath != NULL)
+        {
+        char *htmlPath = hashFindVal(genome->settingsHash, "htmlPath");
+        if (htmlPath == NULL)
+            warn("warning: missing htmlPath setting for assembly hub '%s'", genome->name);
+        else if (!udcExists(htmlPath))
+            warn("warning: htmlPath file does not exist: '%s'", htmlPath);
+        }
     tdbList = trackHubTracksForGenome(hub, genome);
     tdbList = trackDbLinkUpGenerations(tdbList);
     tdbList = trackDbPolishAfterLinkup(tdbList, genome->name);
     trackHubPolishTrackNames(hub, tdbList);
     }
 errCatchEnd(errCatch);
 if (errCatch->gotError)
     {
     openedGenome = TRUE;
     genomeErrorCount += 1;
-    if (options->htmlOut)
-        {
-        genomeErr(errors, errCatch->message->string, hub, genome);
+    genomeErr(errors, errCatch->message->string, hub, genome, options->htmlOut);
     }
-    else
-        dyStringPrintf(errors, "%s", errCatch->message->string);
-    }
-if (errCatch->gotWarning && !errCatch->gotError)
+if (errCatch->gotWarning)
     {
     openedGenome = TRUE;
-    if (options->htmlOut)
-        {
-        genomeErr(errors, errCatch->message->string, hub, genome);
-        }
-    else
-        dyStringPrintf(errors, "%s", errCatch->message->string);
+    genomeErr(errors, errCatch->message->string, hub, genome, options->htmlOut);
     }
 errCatchFree(&errCatch);
 
 verbose(2, "%d tracks in %s\n", slCount(tdbList), genome->name);
 struct trackDb *tdb;
 int tdbCheckVal;
 static struct dyString *tdbDyString = NULL;
 if (!tdbDyString)
     tdbDyString = dyStringNew(0);
 
 // build up the track results list, keep track of number of errors, then
 // open up genomes folder
 char *genomeName = trackHubSkipHubName(genome->name);
 for (tdb = tdbList; tdb != NULL; tdb = tdb->next)
     {
@@ -905,33 +908,37 @@
 
 
 int trackHubCheck(char *hubUrl, struct trackHubCheckOptions *options, struct dyString *errors)
 /* Check a track data hub for integrity. Put errors in dyString.
  *      return 0 if hub has no errors, 1 otherwise
  *      if options->checkTracks is TRUE, check remote files of individual tracks
  */
 {
 struct errCatch *errCatch = errCatchNew();
 struct trackHub *hub = NULL;
 int retVal = 0;
 
 if (errCatchStart(errCatch))
     {
     hub = trackHubOpen(hubUrl, "");
+    if (hub->descriptionUrl == NULL)
+        warn("warning: missing hub overview descripton page (descriptionUrl setting)");
+    else if (!udcExists(hub->descriptionUrl))
+        warn("warning: %s descriptionUrl setting does not exist", hub->descriptionUrl);
     }
 errCatchEnd(errCatch);
-if (errCatch->gotError)
+if (errCatch->gotError || errCatch->gotWarning)
     {
     retVal = 1;
     if (options->htmlOut)
         {
         hubErr(errors, errCatch->message->string, hub);
         }
     else
         dyStringPrintf(errors, "%s\n", errCatch->message->string);
     }
 if (errCatch->gotWarning && !errCatch->gotError)
     dyStringPrintf(errors, "%s", errCatch->message->string);
 errCatchFree(&errCatch);
 
 if (hub == NULL)
     return 1;