blambov commented on code in PR #3532:
URL: https://github.com/apache/cassandra/pull/3532#discussion_r1761170255


##########
test/unit/org/apache/cassandra/db/compaction/CompactionStrategyManagerPendingRepairTest.java:
##########
@@ -306,6 +311,96 @@ public void cleanupCompactionFailed()
         Assert.assertEquals(ActiveRepairService.UNREPAIRED_SSTABLE, 
sstable.getSSTableMetadata().repairedAt);
     }
 
+    /**
+     * Tests that finalized repairs racing with compactions on the same set of 
sstables don't leave unrepaired sstables behind
+     *
+     * This test checks that when a repair has been finalized but there are 
still pending sstables a finalize repair
+     * compaction task is issued for that repair session.
+     */
+    @Test
+    public void testFinalizedAndCompactionRace() throws IOException
+    {
+        UUID repairID = registerSession(cfs, true, true);
+        LocalSessionAccessor.prepareUnsafe(repairID, COORDINATOR, 
PARTICIPANTS);
+
+        int numberOfSStables = 4;
+        List<SSTableReader> sstables = new ArrayList<>(numberOfSStables);
+        for (int i = 0; i < numberOfSStables; i++)
+        {
+            SSTableReader sstable = makeSSTable(true);
+            sstables.add(sstable);
+            Assert.assertFalse(sstable.isRepaired());
+            Assert.assertFalse(sstable.isPendingRepair());
+        }
+
+        // change to pending repair
+        mutateRepaired(sstables, repairID, false);
+        csm.handleNotification(new SSTableAddedNotification(sstables, null), 
cfs.getTracker());
+        for (SSTableReader sstable : sstables)
+        {
+            Assert.assertFalse(sstable.isRepaired());
+            Assert.assertTrue(sstable.isPendingRepair());
+            Assert.assertEquals(repairID, sstable.getPendingRepair());
+        }
+
+        // Get a compaction taks based on the sstables marked as pending repair
+        cfs.getCompactionStrategyManager().enable();
+        for (SSTableReader sstable : sstables)
+            pendingContains(sstable);
+        AbstractCompactionTask compactionTask = 
csm.getNextBackgroundTask(FBUtilities.nowInSeconds());
+        Assert.assertNotNull(compactionTask);
+
+        // Finalize the repair session
+        LocalSessionAccessor.finalizeUnsafe(repairID);
+        LocalSession session = ARS.consistent.local.getSession(repairID);
+        ARS.consistent.local.sessionCompleted(session);
+        Assert.assertTrue(hasPendingStrategiesFor(repairID));
+
+        // run the compaction
+        compactionTask.execute(ActiveCompactionsTracker.NOOP);
+
+        // The repair session is finalized but there is an sstable left behind 
pending repair!
+        SSTableReader compactedSSTable = 
cfs.getLiveSSTables().iterator().next();
+        Assert.assertEquals(repairID, compactedSSTable.getPendingRepair());

Review Comment:
   Nit: Ideally the test wouldn't be checking that the transient invalid state 
exists, only that everything is in correct state after the necessary actions 
are taken.
   
   I.e. it should also be acceptable for `compactedSSTable` to already be 
marked as repaired, and in that case `getNextBackgroundTasks` below to return 
nothing. I would thus wrap lines 364 to 381 inside an `if 
(!compactedSSTable.isRepaired())`. This may also fix potential flakiness if the 
thread is preempted before line 363 and something manages to run compaction 
during the pause.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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

Reply via email to