From 9affcf169f08faf696f285c28a098daf9bb97b79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szymon=20Mi=C4=99=C5=BCa=C5=82?= Date: Thu, 9 Nov 2023 14:02:41 +0100 Subject: [PATCH] Fix nodetool repair_admin summarize-pending command to not throw exception Fixed a bug causing the `OpenDataException` being thrown when executing the `repair_admin summarize-pending` command. This patch addresses the problem by including a missing composite in `PendingStats.toComposite`, ensuring proper data conversion. patch by Szymon Miezal; reviewed by Stefan Miklosovic and Brandon Williams for CASSANDRA-19014 --- CHANGES.txt | 1 + .../repair/consistent/admin/PendingStats.java | 7 +++--- .../distributed/test/IncRepairAdminTest.java | 22 +++++++++++++++++++ 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 6286c86cf5..d33268f863 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 4.0.12 + * Fix nodetool repair_admin summarize-pending command to not throw exception (CASSANDRA-19014) * Fix cassandra-stress in simplenative mode with prepared statements (CASSANDRA-18744) * Fix filtering system ks sstables for relocation on startup (CASSANDRA-18963) * Remove completed coordinator sessions (CASSANDRA-18903) diff --git a/src/java/org/apache/cassandra/repair/consistent/admin/PendingStats.java b/src/java/org/apache/cassandra/repair/consistent/admin/PendingStats.java index f1b515e666..fa7d5b5dd8 100644 --- a/src/java/org/apache/cassandra/repair/consistent/admin/PendingStats.java +++ b/src/java/org/apache/cassandra/repair/consistent/admin/PendingStats.java @@ -78,9 +78,10 @@ public class PendingStats Map values = new HashMap<>(); values.put(COMPOSITE_NAMES[0], keyspace); values.put(COMPOSITE_NAMES[1], table); - values.put(COMPOSITE_NAMES[2], pending.toComposite()); - values.put(COMPOSITE_NAMES[3], finalized.toComposite()); - values.put(COMPOSITE_NAMES[4], failed.toComposite()); + values.put(COMPOSITE_NAMES[2], total.toComposite()); + values.put(COMPOSITE_NAMES[3], pending.toComposite()); + values.put(COMPOSITE_NAMES[4], finalized.toComposite()); + values.put(COMPOSITE_NAMES[5], failed.toComposite()); try { return new CompositeDataSupport(COMPOSITE_TYPE, values); diff --git a/test/distributed/org/apache/cassandra/distributed/test/IncRepairAdminTest.java b/test/distributed/org/apache/cassandra/distributed/test/IncRepairAdminTest.java index 236c8193b0..d55448e7ee 100644 --- a/test/distributed/org/apache/cassandra/distributed/test/IncRepairAdminTest.java +++ b/test/distributed/org/apache/cassandra/distributed/test/IncRepairAdminTest.java @@ -43,6 +43,7 @@ import org.apache.cassandra.service.ActiveRepairService; import org.apache.cassandra.streaming.PreviewKind; import org.apache.cassandra.utils.UUIDGen; +import static java.util.Arrays.stream; import static org.apache.cassandra.distributed.api.Feature.GOSSIP; import static org.apache.cassandra.distributed.api.Feature.NETWORK; import static org.apache.cassandra.repair.consistent.ConsistentSession.State.REPAIRING; @@ -50,6 +51,27 @@ import static org.junit.Assert.assertTrue; public class IncRepairAdminTest extends TestBaseImpl { + @Test + public void testRepairAdminSummarizePending() throws IOException + { + try (Cluster cluster = init(Cluster.build(1) + .withConfig(config -> config.with(GOSSIP).with(NETWORK)) + .start())) + { + // given a cluster with a table + cluster.schemaChange("CREATE TABLE " + KEYSPACE + ".tbl (k INT PRIMARY KEY, v INT)"); + // when running repair_admin summarize-pending + NodeToolResult res = cluster.get(1).nodetoolResult("repair_admin", "summarize-pending"); + // then the table info should be present in the output + res.asserts().success(); + String outputLine = stream(res.getStdout().split("\n")) + .filter(l -> l.contains(KEYSPACE) && l.contains("tbl")) + .findFirst() + .orElseThrow(() -> new AssertionError("should find tbl table in output of repair_admin summarize-pending")); + assertTrue("should contain information about zero pending bytes", outputLine.contains("0 bytes (0 sstables / 0 sessions)")); + } + } + @Test public void testManualSessionFail() throws IOException {