Skip to content

Commit 830c6e3

Browse files
Generalise logging expectations
1 parent ef0905b commit 830c6e3

File tree

1 file changed

+21
-197
lines changed
  • server/src/internalClusterTest/java/org/elasticsearch/cluster/coordination

1 file changed

+21
-197
lines changed

server/src/internalClusterTest/java/org/elasticsearch/cluster/coordination/NodeJoiningIT.java

Lines changed: 21 additions & 197 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ public void testNodeJoinsCluster() {
6262
try {
6363
ensureSufficientMasterEligibleNodes();
6464
String masterNodeName = internalCluster().getMasterName();
65-
DiscoveryNode masterNode = internalCluster().clusterService(masterNodeName).state().nodes().getMasterNode();
6665
int numberOfNodesOriginallyInCluster = internalCluster().clusterService(masterNodeName).state().getNodes().size();
6766
int numberOfMasterNodesOriginallyInCluster = internalCluster().clusterService(masterNodeName)
6867
.state()
@@ -71,30 +70,19 @@ public void testNodeJoinsCluster() {
7170
.size();
7271
List<String> namesOfDataNodesInOriginalCluster = getListOfDataNodeNamesFromCluster(masterNodeName);
7372

74-
// Ensure the logging is as expected
75-
try (var mockLog = MockLog.capture(NodeJoinExecutor.class)) {
76-
assert masterNode != null;
77-
String expectedNewNodeAsString = generateNodeDescriptionForNewDiscoveryNode(numberOfNodesOriginallyInCluster, masterNode);
78-
79-
// We expect to see a node join message from the new node
80-
addNodeJoinExpectation(mockLog, expectedNewNodeAsString);
81-
82-
// Attempt to add new node
83-
String newNodeName = internalCluster().startDataOnlyNode();
84-
85-
mockLog.assertAllExpectationsMatched();
73+
// Attempt to add new node
74+
String newNodeName = internalCluster().startDataOnlyNode();
8675

87-
// Assert the new data node was added
88-
ClusterState state = internalCluster().clusterService(masterNodeName).state();
89-
assertEquals(numberOfNodesOriginallyInCluster + 1, state.nodes().getSize());
90-
assertEquals(namesOfDataNodesInOriginalCluster.size() + 1, state.nodes().getDataNodes().size());
91-
assertEquals(numberOfMasterNodesOriginallyInCluster, state.nodes().getMasterNodes().size());
76+
// Assert the new data node was added
77+
ClusterState state = internalCluster().clusterService(masterNodeName).state();
78+
assertEquals(numberOfNodesOriginallyInCluster + 1, state.nodes().getSize());
79+
assertEquals(namesOfDataNodesInOriginalCluster.size() + 1, state.nodes().getDataNodes().size());
80+
assertEquals(numberOfMasterNodesOriginallyInCluster, state.nodes().getMasterNodes().size());
9281

93-
List<String> namesOfDataNodesInNewCluster = getListOfDataNodeNamesFromCluster(masterNodeName);
94-
assertTrue(namesOfDataNodesInNewCluster.contains(newNodeName));
95-
for (String nodeName : namesOfDataNodesInOriginalCluster) {
96-
assertTrue(namesOfDataNodesInNewCluster.contains(nodeName));
97-
}
82+
List<String> namesOfDataNodesInNewCluster = getListOfDataNodeNamesFromCluster(masterNodeName);
83+
assertTrue(namesOfDataNodesInNewCluster.contains(newNodeName));
84+
for (String nodeName : namesOfDataNodesInOriginalCluster) {
85+
assertTrue(namesOfDataNodesInNewCluster.contains(nodeName));
9886
}
9987
} finally {
10088
Releasables.closeExpectNoException(Releasables.wrap(cleanupTasks));
@@ -119,7 +107,6 @@ public void testNodeTriesToJoinClusterAndThenDifferentMasterIsElected() {
119107
.getMasterNodes()
120108
.size();
121109
List<String> namesOfDataNodesInOriginalCluster = getListOfDataNodeNamesFromCluster(originalMasterNodeName);
122-
DiscoveryNode masterNode = internalCluster().clusterService(originalMasterNodeName).state().getNodes().getMasterNode();
123110

124111
// Sets MockTransportService behaviour
125112
for (final var transportService : internalCluster().getInstances(TransportService.class)) {
@@ -143,14 +130,8 @@ public void testNodeTriesToJoinClusterAndThenDifferentMasterIsElected() {
143130

144131
// Ensure the logging is as expected
145132
try (var mockLog = MockLog.capture(NodeJoinExecutor.class)) {
146-
assert masterNode != null;
147-
String expectedNewNodeAsString = generateNodeDescriptionForNewDiscoveryNode(numberOfNodesOriginallyInCluster, masterNode);
148-
149-
// We expect to see a node join message from the new node
150-
addNodeJoinExpectation(mockLog, expectedNewNodeAsString);
151-
152-
// We do not expect to see the WARN log
153-
addJoiningNodeDisconnectedWarnLogExpectation(mockLog, expectedNewNodeAsString);
133+
// We do not expect to see a WARN log about a node disconnecting (#ES-11449)
134+
addJoiningNodeDisconnectedWarnLogFalseExpectation(mockLog);
154135

155136
// We haven't changed master nodes yet
156137
assertEquals(originalMasterNodeName, internalCluster().getMasterName());
@@ -188,7 +169,7 @@ public void testNodeTriesToJoinClusterAndThenDifferentMasterIsElected() {
188169

189170
/*
190171
In this scenario, node N attempts to join a cluster, there is an election and the original master is re-elected.
191-
Node N should join the cluster, but it should not be disconnected
172+
Node N should join the cluster, but it should not be disconnected (#ES-11449)
192173
*/
193174
@TestLogging(
194175
reason = "test includes assertions about logging",
@@ -207,7 +188,6 @@ public void testNodeTriesToJoinClusterAndThenSameMasterIsElected() {
207188
DiscoveryNode masterNode = internalCluster().clusterService(masterNodeName).state().nodes().getMasterNode();
208189

209190
long originalTerm = internalCluster().clusterService(masterNodeName).state().coordinationMetadata().term();
210-
long originalVersion = internalCluster().clusterService(masterNodeName).state().version();
211191
int numberOfNodesOriginallyInCluster = internalCluster().clusterService(masterNodeName).state().getNodes().size();
212192
int numberOfMasterNodesOriginallyInCluster = internalCluster().clusterService(masterNodeName)
213193
.state()
@@ -255,32 +235,16 @@ public void testNodeTriesToJoinClusterAndThenSameMasterIsElected() {
255235

256236
// Ensure the logging is as expected
257237
try (var mockLog = MockLog.capture(NodeJoinExecutor.class, MasterService.class, ClusterApplierService.class)) {
258-
long firstNodeJoinVersion = originalVersion + 1;
259238
assert masterNode != null;
260-
String expectedNewNodeAsString = generateNodeDescriptionForNewDiscoveryNode(numberOfNodesOriginallyInCluster, masterNode);
261-
262-
/*
263-
We expect to see a node join event as the master tries to process the join,
264-
but cannot commit the cluster state due to a lack of quorum.
265-
This means the join is not successful in this term.
266-
*/
267-
addMasterServiceUpdateTaskNodeJoinExpectation(mockLog, expectedNewNodeAsString, originalTerm, firstNodeJoinVersion);
268239

269-
// The node join fails
270-
addFailedToCommitClusterStateVersionExpectation(mockLog, expectedNewNodeAsString, firstNodeJoinVersion);
240+
// We expect the node join to fail
241+
addFailedToCommitClusterStateExpectation(mockLog);
271242

272243
/*
273244
We expect the cluster to reuse the connection to N and not disconnect it
274245
Therefore, this WARN log should not be thrown
275246
*/
276-
addJoiningNodeDisconnectedWarnLogExpectation(mockLog, expectedNewNodeAsString);
277-
278-
/*
279-
We expect node N to join the cluster.
280-
However, we expect no explicit `node-join: [{node_s5} ...]` log to be emitted by the master in this new term
281-
as the join is processed as part of the new election and cluster state publication, rather than a separate event
282-
*/
283-
addNodeJoinProcessedDuringNewElectionAndClusterStatePublicationExpectation(mockLog, expectedNewNodeAsString);
247+
addJoiningNodeDisconnectedWarnLogFalseExpectation(mockLog);
284248

285249
// Before we add the new node, assert we haven't changed master nodes yet
286250
assertEquals(masterNodeName, internalCluster().getMasterName());
@@ -356,77 +320,7 @@ private boolean nodeExistsWithName(DiscoveryNodes nodes, String nodeName) {
356320
return false;
357321
}
358322

359-
private void addNodeJoinExpectation(MockLog mockLog, String expectedNewNodeAsString) {
360-
// This matches with the node join message from the new node only
361-
mockLog.addExpectation(new MockLog.LoggingExpectation() {
362-
boolean matched = false;
363-
364-
@Override
365-
public void match(LogEvent event) {
366-
if (event.getLevel() != Level.INFO) {
367-
return;
368-
}
369-
if (event.getLoggerName().equals(NodeJoinExecutor.class.getCanonicalName()) == false) {
370-
return;
371-
}
372-
373-
Pattern pattern = Pattern.compile("node-join: \\[" + expectedNewNodeAsString + "] " + "with reason \\[joining]");
374-
Matcher matcher = pattern.matcher(event.getMessage().getFormattedMessage());
375-
376-
if (matcher.find()) {
377-
matched = true;
378-
}
379-
}
380-
381-
@Override
382-
public void assertMatched() {
383-
assertTrue(matched);
384-
}
385-
});
386-
}
387-
388-
private void addMasterServiceUpdateTaskNodeJoinExpectation(MockLog mockLog, String expectedNewNodeAsString, long term, long version) {
389-
mockLog.addExpectation(new MockLog.LoggingExpectation() {
390-
boolean matched = false;
391-
392-
@Override
393-
public void match(LogEvent event) {
394-
if (event.getLevel() != Level.INFO) {
395-
return;
396-
}
397-
if (event.getLoggerName().equals(MasterService.class.getCanonicalName()) == false) {
398-
return;
399-
}
400-
401-
Pattern pattern = Pattern.compile(
402-
"node-join\\["
403-
+ expectedNewNodeAsString
404-
+ " joining],"
405-
+ " term: "
406-
+ term
407-
+ ","
408-
+ " version: "
409-
+ version
410-
+ ","
411-
+ " delta: added \\{"
412-
+ expectedNewNodeAsString
413-
+ "}"
414-
);
415-
Matcher matcher = pattern.matcher(event.getMessage().getFormattedMessage());
416-
417-
if (matcher.find()) {
418-
matched = true;
419-
}
420-
}
421-
422-
@Override
423-
public void assertMatched() {
424-
assertTrue(matched);
425-
}
426-
});
427-
}
428-
429-
private void addFailedToCommitClusterStateVersionExpectation(MockLog mockLog, String expectedNewNodeAsString, long version) {
323+
private void addFailedToCommitClusterStateExpectation(MockLog mockLog) {
430324
mockLog.addExpectation(new MockLog.LoggingExpectation() {
431325
boolean matched = false;
432326

@@ -439,13 +333,7 @@ public void match(LogEvent event) {
439333
return;
440334
}
441335

442-
Pattern pattern = Pattern.compile(
443-
"failing \\[node-join\\["
444-
+ expectedNewNodeAsString
445-
+ " joining]]: failed to commit cluster state version \\["
446-
+ version
447-
+ "]"
448-
);
336+
Pattern pattern = Pattern.compile("failed to commit cluster state");
449337
Matcher matcher = pattern.matcher(event.getMessage().getFormattedMessage());
450338

451339
if (matcher.find()) {
@@ -460,7 +348,7 @@ public void assertMatched() {
460348
});
461349
}
462350

463-
private void addJoiningNodeDisconnectedWarnLogExpectation(MockLog mockLog, String expectedNewNodeAsString) {
351+
private void addJoiningNodeDisconnectedWarnLogFalseExpectation(MockLog mockLog) {
464352
mockLog.addExpectation(new MockLog.LoggingExpectation() {
465353
boolean matched = false;
466354

@@ -476,7 +364,7 @@ public void match(LogEvent event) {
476364
String regexToMatchAnyCharacterExceptClosingBrace = "([^}]+)";
477365
Pattern pattern = Pattern.compile(
478366
"node-join: \\["
479-
+ expectedNewNodeAsString
367+
+ regexToMatchAnyCharacterExceptClosingBrace
480368
+ "] "
481369
+ "with reason \\[joining, removed \\["
482370
+ regexToMatchAnyCharacterExceptClosingBrace
@@ -498,70 +386,6 @@ public void assertMatched() {
498386
});
499387
}
500388

501-
private void addNodeJoinProcessedDuringNewElectionAndClusterStatePublicationExpectation(
502-
MockLog mockLog,
503-
String expectedNewNodeAsString
504-
) {
505-
mockLog.addExpectation(new MockLog.LoggingExpectation() {
506-
boolean matched = false;
507-
508-
@Override
509-
public void match(LogEvent event) {
510-
if (event.getLevel() != Level.INFO) {
511-
return;
512-
}
513-
if (event.getLoggerName().equals(ClusterApplierService.class.getCanonicalName()) == false) {
514-
return;
515-
}
516-
517-
Pattern pattern = Pattern.compile("added \\{" + expectedNewNodeAsString + "}");
518-
Matcher matcher = pattern.matcher(event.getMessage().getFormattedMessage());
519-
520-
if (matcher.find()) {
521-
matched = true;
522-
}
523-
}
524-
525-
@Override
526-
public void assertMatched() {
527-
assertTrue(matched);
528-
}
529-
});
530-
}
531-
532-
private String generateNodeDescriptionForNewDiscoveryNode(int numberOfNodesOriginallyInCluster, DiscoveryNode masterNode) {
533-
// Nodes are named `node_s0`, `node_s1` etc ...
534-
// Therefore, if there are N nodes in the cluster, named `node_s0` ... `node_sN-1`, N+1 will be named `node_sN`
535-
String newNodeName = "node_s" + numberOfNodesOriginallyInCluster;
536-
String regexToMatchAnyCharacterExceptClosingBrace = "([^}]+)";
537-
538-
return "\\{"
539-
+ newNodeName
540-
+ "}"
541-
+ "\\{"
542-
+ regexToMatchAnyCharacterExceptClosingBrace
543-
+ "}"
544-
+ "\\{"
545-
+ regexToMatchAnyCharacterExceptClosingBrace
546-
+ "}"
547-
+ "\\{"
548-
+ newNodeName
549-
+ "}"
550-
+ "\\{"
551-
+ masterNode.getHostAddress()
552-
+ "}"
553-
+ "\\{"
554-
+ masterNode.getHostAddress()
555-
+ ":\\d+}"
556-
+ "\\{d}"
557-
+ "\\{"
558-
+ masterNode.getVersion()
559-
+ "}"
560-
+ "\\{"
561-
+ regexToMatchAnyCharacterExceptClosingBrace
562-
+ "}";
563-
}
564-
565389
/**
566390
* Removes all custom mockTransportService.addSendBehavior so that the original master node can run for election
567391
*

0 commit comments

Comments
 (0)