This is an automated email from the ASF dual-hosted git repository.
chia7712 pushed a commit to branch 3.7
in repository https://gitbox.apache.org/repos/asf/kafka.git
The following commit(s) were added to refs/heads/3.7 by this push:
new 3ea2acf60f2 KAFKA-16410 kafka-leader-election / LeaderElectionCommand
doesn't set exit code on error (#15591)
3ea2acf60f2 is described below
commit 3ea2acf60f2eea31d6ebbb667b8542defb1e6332
Author: Kuan-Po (Cooper) Tseng <[email protected]>
AuthorDate: Mon Mar 25 12:31:37 2024 +0800
KAFKA-16410 kafka-leader-election / LeaderElectionCommand doesn't set exit
code on error (#15591)
Reviewers: Chia-Ping Tsai <[email protected]>
---
.../apache/kafka/tools/LeaderElectionCommand.java | 9 +++++-
.../tools/LeaderElectionCommandErrorTest.java | 33 ++++++++++++++--------
.../kafka/tools/LeaderElectionCommandTest.java | 22 +++++++--------
3 files changed, 40 insertions(+), 24 deletions(-)
diff --git
a/tools/src/main/java/org/apache/kafka/tools/LeaderElectionCommand.java
b/tools/src/main/java/org/apache/kafka/tools/LeaderElectionCommand.java
index c704e418750..e1cdeed1e58 100644
--- a/tools/src/main/java/org/apache/kafka/tools/LeaderElectionCommand.java
+++ b/tools/src/main/java/org/apache/kafka/tools/LeaderElectionCommand.java
@@ -28,6 +28,7 @@ import org.apache.kafka.common.TopicPartition;
import org.apache.kafka.common.errors.ClusterAuthorizationException;
import org.apache.kafka.common.errors.ElectionNotNeededException;
import org.apache.kafka.common.errors.TimeoutException;
+import org.apache.kafka.common.utils.Exit;
import org.apache.kafka.common.utils.Utils;
import org.apache.kafka.server.common.AdminCommandFailedException;
import org.apache.kafka.server.common.AdminOperationException;
@@ -62,11 +63,17 @@ public class LeaderElectionCommand {
private static final DecodeJson.DecodeInteger INT = new
DecodeJson.DecodeInteger();
public static void main(String... args) {
+ Exit.exit(mainNoExit(args));
+ }
+
+ static int mainNoExit(String... args) {
try {
run(Duration.ofMillis(30000), args);
- } catch (Exception e) {
+ return 0;
+ } catch (Throwable e) {
System.err.println(e.getMessage());
System.err.println(Utils.stackTrace(e));
+ return 1;
}
}
diff --git
a/tools/src/test/java/org/apache/kafka/tools/LeaderElectionCommandErrorTest.java
b/tools/src/test/java/org/apache/kafka/tools/LeaderElectionCommandErrorTest.java
index fef75bfd104..5c72bb3597c 100644
---
a/tools/src/test/java/org/apache/kafka/tools/LeaderElectionCommandErrorTest.java
+++
b/tools/src/test/java/org/apache/kafka/tools/LeaderElectionCommandErrorTest.java
@@ -22,6 +22,7 @@ import org.junit.jupiter.api.Test;
import java.time.Duration;
+import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -30,46 +31,54 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
* cluster creation and cleanup because the command is expected to fail
immediately.
*/
public class LeaderElectionCommandErrorTest {
+
@Test
public void testTopicWithoutPartition() {
- String out = ToolsTestUtils.captureStandardErr(() ->
LeaderElectionCommand.main(
- "--bootstrap-server", "nohost:9092",
- "--election-type", "unclean",
- "--topic", "some-topic"
- ));
+ String[] args = {
+ "--bootstrap-server", "nohost:9092",
+ "--election-type", "unclean",
+ "--topic", "some-topic"
+ };
+ assertEquals(1, LeaderElectionCommand.mainNoExit(args));
+ String out = ToolsTestUtils.captureStandardErr(() ->
LeaderElectionCommand.mainNoExit(args));
assertTrue(out.startsWith("Missing required option(s)"));
assertTrue(out.contains(" partition"));
}
@Test
public void testPartitionWithoutTopic() {
- String out = ToolsTestUtils.captureStandardErr(() ->
LeaderElectionCommand.main(
+ String[] args = {
"--bootstrap-server", "nohost:9092",
"--election-type", "unclean",
"--all-topic-partitions",
"--partition", "0"
- ));
- String[] rows = out.split("\n");
+ };
+ assertEquals(1, LeaderElectionCommand.mainNoExit(args));
+ String out = ToolsTestUtils.captureStandardErr(() ->
LeaderElectionCommand.mainNoExit(args));
assertTrue(out.startsWith("Option partition is only allowed if topic
is used"));
}
@Test
public void testMissingElectionType() {
- String out = ToolsTestUtils.captureStandardErr(() ->
LeaderElectionCommand.main(
+ String[] args = {
"--bootstrap-server", "nohost:9092",
"--topic", "some-topic",
"--partition", "0"
- ));
+ };
+ assertEquals(1, LeaderElectionCommand.mainNoExit(args));
+ String out = ToolsTestUtils.captureStandardErr(() ->
LeaderElectionCommand.mainNoExit(args));
assertTrue(out.startsWith("Missing required option(s)"));
assertTrue(out.contains(" election-type"));
}
@Test
public void testMissingTopicPartitionSelection() {
- String out = ToolsTestUtils.captureStandardErr(() ->
LeaderElectionCommand.main(
+ String[] args = {
"--bootstrap-server", "nohost:9092",
"--election-type", "preferred"
- ));
+ };
+ assertEquals(1, LeaderElectionCommand.mainNoExit(args));
+ String out = ToolsTestUtils.captureStandardErr(() ->
LeaderElectionCommand.mainNoExit(args));
assertTrue(out.startsWith("One and only one of the following options
is required: "));
assertTrue(out.contains(" all-topic-partitions"));
assertTrue(out.contains(" topic"));
diff --git
a/tools/src/test/java/org/apache/kafka/tools/LeaderElectionCommandTest.java
b/tools/src/test/java/org/apache/kafka/tools/LeaderElectionCommandTest.java
index f68b55ed3fe..677aaa76430 100644
--- a/tools/src/test/java/org/apache/kafka/tools/LeaderElectionCommandTest.java
+++ b/tools/src/test/java/org/apache/kafka/tools/LeaderElectionCommandTest.java
@@ -104,11 +104,11 @@ public class LeaderElectionCommandTest {
cluster.startBroker(broker3);
TestUtils.waitForOnlineBroker(client, broker3);
- LeaderElectionCommand.main(
+ assertEquals(0, LeaderElectionCommand.mainNoExit(
"--bootstrap-server", cluster.bootstrapServers(),
"--election-type", "unclean",
"--all-topic-partitions"
- );
+ ));
TestUtils.assertLeader(client, topicPartition, broker3);
}
@@ -120,11 +120,11 @@ public class LeaderElectionCommandTest {
Path adminConfigPath = tempAdminConfig(defaultApiTimeoutMs,
requestTimeoutMs);
try (final MockedStatic<Admin> mockedAdmin =
Mockito.mockStatic(Admin.class)) {
- LeaderElectionCommand.main(
+ assertEquals(1, LeaderElectionCommand.mainNoExit(
"--bootstrap-server", cluster.bootstrapServers(),
"--election-type", "unclean", "--all-topic-partitions",
"--admin.config", adminConfigPath.toString()
- );
+ ));
ArgumentCaptor<Properties> argumentCaptor =
ArgumentCaptor.forClass(Properties.class);
mockedAdmin.verify(() -> Admin.create(argumentCaptor.capture()));
@@ -160,12 +160,12 @@ public class LeaderElectionCommandTest {
cluster.startBroker(broker3);
TestUtils.waitForOnlineBroker(client, broker3);
- LeaderElectionCommand.main(
+ assertEquals(0, LeaderElectionCommand.mainNoExit(
"--bootstrap-server", cluster.bootstrapServers(),
"--election-type", "unclean",
"--topic", topic,
"--partition", Integer.toString(partition)
- );
+ ));
TestUtils.assertLeader(client, topicPartition, broker3);
}
@@ -199,11 +199,11 @@ public class LeaderElectionCommandTest {
Path topicPartitionPath =
tempTopicPartitionFile(Collections.singletonList(topicPartition));
- LeaderElectionCommand.main(
+ assertEquals(0, LeaderElectionCommand.mainNoExit(
"--bootstrap-server", cluster.bootstrapServers(),
"--election-type", "unclean",
"--path-to-json-file", topicPartitionPath.toString()
- );
+ ));
TestUtils.assertLeader(client, topicPartition, broker3);
}
@@ -232,11 +232,11 @@ public class LeaderElectionCommandTest {
JavaConverters.asScalaBuffer(Collections.singletonList(broker2)).toSet()
);
- LeaderElectionCommand.main(
+ assertEquals(0, LeaderElectionCommand.mainNoExit(
"--bootstrap-server", cluster.bootstrapServers(),
"--election-type", "preferred",
"--all-topic-partitions"
- );
+ ));
TestUtils.assertLeader(client, topicPartition, broker2);
}
@@ -287,7 +287,7 @@ public class LeaderElectionCommandTest {
Path topicPartitionPath =
tempTopicPartitionFile(Arrays.asList(topicPartition0, topicPartition1));
String output = ToolsTestUtils.captureStandardOut(() ->
- LeaderElectionCommand.main(
+ LeaderElectionCommand.mainNoExit(
"--bootstrap-server", cluster.bootstrapServers(),
"--election-type", "preferred",
"--path-to-json-file", topicPartitionPath.toString()