This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/cassandra.git

commit bcd9e662d219f20fb678161d70f8536d4be22b41
Merge: 5d1830775d feef3fcf51
Author: Caleb Rackliffe <[email protected]>
AuthorDate: Wed Jul 29 15:23:53 2026 -0500

    Merge branch 'cassandra-6.0' into trunk
    
    * cassandra-6.0:
      Fix operationMode reporting DECOMMISSION_FAILED instead of LEAVING when 
resuming a failed decommission

 CHANGES.txt                                        |  1 +
 .../tcm/sequences/SingleNodeSequences.java         |  1 +
 .../distributed/test/DecommissionTest.java         |  4 ++-
 .../distributed/test/ring/DecommissionTest.java    | 41 ++++++++++++++++++++++
 4 files changed, 46 insertions(+), 1 deletion(-)

diff --cc CHANGES.txt
index 587ca0e973,09a7cd544f..c3dfe1b04b
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@@ -1,16 -1,10 +1,17 @@@
 -6.0-alpha2
 +7.0
 + * Don't increment client metrics on messaging service connection unpause 
(CASSANDRA-21491)
 + * Add nodetool getreplicas (CASSANDRA-17665)
 + * Implementation of CEP-49: Hardware-accelerated compression 
(CASSANDRA-20975)
 + * Avoid using ObjectUtils.getFirstNonNull in Schema (CASSANDRA-21394)
 + * Allow nodetool garbagecollect to take a user defined list of SSTables 
(CASSANDRA-16767)
 + * Add a guardrail for misprepared statements (CASSANDRA-21139)
 +Merged from 6.0:
+  * Fix operationMode reporting DECOMMISSION_FAILED instead of LEAVING when 
resuming a failed decommission (CASSANDRA-21493)
   * Avoid megamorphic calls when serializing and deserializing fixed-length 
values (CASSANDRA-21536)
   * Avoid megamorphic calls for 
Cell.timestamp/ttl/path/localDeletionTimeAsUnsignedInt methods (CASSANDRA-21526)
 + * Reduce allocations in DefaultQueryOptions (CASSANDRA-21467)
   * Allow unreserved keywords as user and identity names in USER and IDENTITY 
statements (CASSANDRA-21510)
   * Reduce allocations in DefaultQueryOptions (CASSANDRA-21467)
 - * Coordinator load-shedding returns OverloadedException without setting 
streamId, misrouting query responses (CASSANDRA-21508)
   * Reduce number of scheduledTasks on metric id release in ThreadLocalMetrics 
(CASSANDRA-21475)
   * Cache various Enum.values() used in deserialization to avoid per-read 
array allocation (CASSANDRA-21528)
   * Fix Accord transaction error message when altering a table 
(CASSANDRA-20580)
diff --cc 
test/distributed/org/apache/cassandra/distributed/test/ring/DecommissionTest.java
index 307956828e,69b8e31430..f6ba5c33a1
--- 
a/test/distributed/org/apache/cassandra/distributed/test/ring/DecommissionTest.java
+++ 
b/test/distributed/org/apache/cassandra/distributed/test/ring/DecommissionTest.java
@@@ -84,6 -88,43 +88,43 @@@ public class DecommissionTest extends T
          }
      }
  
+     @Test
+     public void testOperationModeOnDecomResume() throws Exception
+     {
+         // Node 2's first decomission attempt fails mid-stream (injected by 
BB), leaving it in
+         // DECOMISSION_FAILED. On resume, operationMode() must transition 
back to LEAVING before
+         // MID_LEAVE is committed. We pause the CMS just before that commit 
to assert the mode
+         // in the window where streaming has finished but the epoch has not 
yet advanced.
+         try (Cluster cluster = builder().withNodes(3)
+                                         .withConfig(config -> 
config.with(NETWORK, GOSSIP))
+                                         .withInstanceInitializer(BB::install)
+                                         .start())
+         {
+             populate(cluster, 0, 100, 1, 2, ConsistencyLevel.QUORUM);
+ 
+             IInvokableInstance cmsNode = cluster.get(1);
+             IInvokableInstance leavingNode = cluster.get(2);
+ 
+             // --force required: cie_internal keyspace has RF=3, decommission 
would fail replication check otherwise
+             leavingNode.nodetoolResult("decommission", 
"--force").asserts().failure();
+             leavingNode.runOnInstance(() -> 
assertEquals(StorageService.Mode.DECOMMISSION_FAILED, 
StorageService.instance.operationMode()));
+ 
+             Callable<Epoch> midLeavePaused = pauseBeforeCommit(cmsNode, e -> 
e instanceof PrepareLeave.MidLeave);
+ 
+             Thread resumeThread = new Thread(() -> 
leavingNode.nodetoolResult("decommission").asserts().success());
+             resumeThread.start();
+             midLeavePaused.call();
+ 
+             leavingNode.runOnInstance(() ->
 -                                      assertEquals("operationMode during 
resumed decommission streaming should be LEAVING, not DECOMMISSION_FAILED",
 -                                                   
StorageService.Mode.LEAVING,
 -                                                   
StorageService.instance.operationMode()));
++                assertEquals("operationMode during resumed decommission 
streaming should be LEAVING, not DECOMMISSION_FAILED",
++                             StorageService.Mode.LEAVING,
++                             StorageService.instance.operationMode()));
+ 
+             unpauseCommits(cmsNode);
+             resumeThread.join(TimeUnit.MINUTES.toMillis(2));
+         }
+     }
+ 
      @Test
      public void testAddressReuseAfterDecommission() throws IOException, 
ExecutionException, InterruptedException
      {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to