Browse Source

Improve failure message for InternalTestCluster#getInstance (#107398)

Today if `InternalTestCluster#getInstance` fails to find a matching
instance it throws an opaque `AssertionError`. This commit adds a
message describing the problem to make troubleshooting easier.

Relates #107392
David Turner 1 year ago
parent
commit
9626615fc3

+ 39 - 17
test/framework/src/main/java/org/elasticsearch/test/InternalTestCluster.java

@@ -176,13 +176,29 @@ public final class InternalTestCluster extends TestCluster {
 
     private static final Logger logger = LogManager.getLogger(InternalTestCluster.class);
 
-    private static final Predicate<NodeAndClient> DATA_NODE_PREDICATE = nodeAndClient -> DiscoveryNode.canContainData(
-        nodeAndClient.node.settings()
-    );
+    private static final Predicate<NodeAndClient> DATA_NODE_PREDICATE = new Predicate<>() {
+        @Override
+        public boolean test(NodeAndClient nodeAndClient) {
+            return DiscoveryNode.canContainData(nodeAndClient.node.settings());
+        }
+
+        @Override
+        public String toString() {
+            return "any data node";
+        }
+    };
 
-    private static final Predicate<NodeAndClient> MASTER_NODE_PREDICATE = nodeAndClient -> DiscoveryNode.isMasterNode(
-        nodeAndClient.node.settings()
-    );
+    private static final Predicate<NodeAndClient> MASTER_NODE_PREDICATE = new Predicate<>() {
+        @Override
+        public boolean test(NodeAndClient nodeAndClient) {
+            return DiscoveryNode.isMasterNode(nodeAndClient.node.settings());
+        }
+
+        @Override
+        public String toString() {
+            return "any master-eligible node";
+        }
+    };
 
     private static final Predicate<NodeAndClient> NO_DATA_NO_MASTER_PREDICATE = DATA_NODE_PREDICATE.negate()
         .and(MASTER_NODE_PREDICATE.negate());
@@ -1589,15 +1605,25 @@ public final class InternalTestCluster extends TestCluster {
     /**
      * @return the instance of the given class from the node with provided {@code nodeName}
      */
-    public <T> T getInstance(Class<T> clazz, final String nodeName) {
-        return getInstance(clazz, nc -> nodeName == null || nodeName.equals(nc.name));
+    public <T> T getInstance(Class<T> clazz, @Nullable final String nodeName) {
+        return getInstance(clazz, nodeName == null ? Predicates.always() : new NodeNamePredicate(nodeName));
     }
 
     /**
      * @return the instance of the given class from a random node with provided {@code role}
      */
     public <T> T getInstance(Class<T> clazz, DiscoveryNodeRole role) {
-        return getInstance(clazz, nc -> DiscoveryNode.getRolesFromSettings(nc.node.settings()).contains(role));
+        return getInstance(clazz, new Predicate<>() {
+            @Override
+            public boolean test(NodeAndClient nc) {
+                return DiscoveryNode.getRolesFromSettings(nc.node.settings()).contains(role);
+            }
+
+            @Override
+            public String toString() {
+                return "role: " + role;
+            }
+        });
     }
 
     public <T> T getDataNodeInstance(Class<T> clazz) {
@@ -1614,7 +1640,9 @@ public final class InternalTestCluster extends TestCluster {
 
     private synchronized <T> T getInstance(Class<T> clazz, Predicate<NodeAndClient> predicate) {
         NodeAndClient randomNodeAndClient = getRandomNodeAndClient(predicate);
-        assert randomNodeAndClient != null;
+        if (randomNodeAndClient == null) {
+            throw new AssertionError("no node matches [" + predicate + "]");
+        }
         return getInstanceFromNode(clazz, randomNodeAndClient.node);
     }
 
@@ -2296,13 +2324,7 @@ public final class InternalTestCluster extends TestCluster {
         return map.values().stream().filter(predicate).collect(Collectors.toCollection(ArrayList::new));
     }
 
-    private static final class NodeNamePredicate implements Predicate<NodeAndClient> {
-        private final String nodeName;
-
-        NodeNamePredicate(String nodeName) {
-            this.nodeName = nodeName;
-        }
-
+    private record NodeNamePredicate(String nodeName) implements Predicate<NodeAndClient> {
         @Override
         public boolean test(NodeAndClient nodeAndClient) {
             return nodeName.equals(nodeAndClient.getName());