Handle invalid task roots gracefully

If a root task was previously invalid, it would cause an NPE. Fix
this NPE and output an INVALID task when this happens instead.
Also, Add test case to validate the fix.

Change-Id: Ia3d61315880fd7ac4e50c45c26949c2ba9880de4
diff --git a/src/main/java/com/googlesource/gerrit/plugins/task/TaskAttributeFactory.java b/src/main/java/com/googlesource/gerrit/plugins/task/TaskAttributeFactory.java
index d7e733f..fcf121a 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/task/TaskAttributeFactory.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/task/TaskAttributeFactory.java
@@ -91,7 +91,11 @@
     TaskPluginAttribute a = new TaskPluginAttribute();
     try {
       for (Node node : definitions.getRootNodes(c)) {
-        new AttributeFactory(node).create().ifPresent(t -> a.roots.add(t));
+        if (node == null) {
+          a.roots.add(invalid());
+        } else {
+          new AttributeFactory(node).create().ifPresent(t -> a.roots.add(t));
+        }
       }
     } catch (ConfigInvalidException | IOException e) {
       a.roots.add(invalid());
diff --git a/src/main/resources/Documentation/task_states.md b/src/main/resources/Documentation/task_states.md
index 020a836..8b0c705 100644
--- a/src/main/resources/Documentation/task_states.md
+++ b/src/main/resources/Documentation/task_states.md
@@ -141,6 +141,9 @@
    preload-task = Subtask FAIL
    subtask = Subtask Preload
 
+[root "Root INVALID Preload"]
+  preload-task = missing
+
 [root "INVALIDS"]
   subtasks-file = invalids.config
 
@@ -960,6 +963,10 @@
                ]
             },
             {
+               "name" : "UNKNOWN",
+               "status" : "INVALID"
+            },
+            {
                "hasPass" : false,
                "name" : "INVALIDS",
                "status" : "WAITING",
diff --git a/test/all b/test/all
index 437965f..4832bba 100644
--- a/test/all
+++ b/test/all
@@ -598,6 +598,10 @@
                ]
             },
             {
+               "name" : "UNKNOWN",
+               "status" : "INVALID"
+            },
+            {
                "applicable" : true,
                "hasPass" : false,
                "name" : "INVALIDS",
diff --git a/test/invalid b/test/invalid
index 4e2984e..5b5bc32 100644
--- a/test/invalid
+++ b/test/invalid
@@ -47,6 +47,10 @@
                ]
             },
             {
+               "name" : "UNKNOWN",
+               "status" : "INVALID"
+            },
+            {
                "applicable" : true,
                "hasPass" : false,
                "name" : "INVALIDS",
diff --git a/test/invalid-applicable b/test/invalid-applicable
index 867c177..369ac47 100644
--- a/test/invalid-applicable
+++ b/test/invalid-applicable
@@ -25,6 +25,10 @@
                ]
             },
             {
+               "name" : "UNKNOWN",
+               "status" : "INVALID"
+            },
+            {
                "hasPass" : false,
                "name" : "INVALIDS",
                "status" : "WAITING",