mumrah commented on code in PR #17147:
URL: https://github.com/apache/kafka/pull/17147#discussion_r1754786855


##########
metadata/src/test/java/org/apache/kafka/metadata/migration/KRaftMigrationDriverTest.java:
##########
@@ -232,6 +232,32 @@ CompletableFuture<Void> 
enqueueMetadataChangeEventWithFuture(
         return future;
     }
 
+    @Test
+    public void testOnControllerChangeWhenUninitialized() throws 
InterruptedException {
+        CountingMetadataPropagator metadataPropagator = new 
CountingMetadataPropagator();
+        CapturingMigrationClient.newBuilder().build();
+        CapturingMigrationClient migrationClient = 
CapturingMigrationClient.newBuilder().build();
+        MockFaultHandler faultHandler = new 
MockFaultHandler("testBecomeLeaderUninitialized");
+        KRaftMigrationDriver.Builder builder = defaultTestBuilder()
+            .setZkMigrationClient(migrationClient)
+            .setPropagator(metadataPropagator)
+            .setFaultHandler(faultHandler);
+        try (KRaftMigrationDriver driver = builder.build()) {
+            // Fake a complete migration with ZK client
+            migrationClient.setMigrationRecoveryState(
+                    
ZkMigrationLeadershipState.EMPTY.withKRaftMetadataOffsetAndEpoch(100, 1));
+
+            // enqueue a poll event. once run, this will enqueue a recovery 
event
+            driver.start();

Review Comment:
   Good point. Let's consider the possibilities:
   
   Case 1: If the PollEvent runs quickly, we'll see
   * start(), enqueue PollEvent
   * run PollEvent, enqueue RecoverMigrationStateFromZKEvent (from PollEvent)
   * onControllerChange(), enqueue RecoverMigrationStateFromZKEvent and 
KRaftLeaderEvent
   * run RecoverMigrationStateFromZKEvent, state = INACTIVE
   * run RecoverMigrationStateFromZKEvent, no-op
   * run KRaftLeaderEvent, state is INACTIVE ✅ 
   
   Case 2: If the RecoverMigrationStateFromZKEvent from PollEvent runs before 
onControllerChange:
   * start(), enqueue PollEvent
   * run PollEvent, enqueue RecoverMigrationStateFromZKEvent (from PollEvent)
   * run RecoverMigrationStateFromZKEvent, state = INACTIVE
   * onControllerChange(), enqueue KRaftLeaderEvent
   * run KRaftLeaderEvent, state is INACTIVE ✅ 
   
   Only Case 1 tests the race condition and the fix.
   
   If we reverse the operations, we'll have
   
   Case 3:
   * onControllerChange(), enqueue RecoverMigrationStateFromZKEvent and 
KRaftLeaderEvent
   * start(), enqueue PollEvent
   * run RecoverMigrationStateFromZKEvent, state = INACTIVE
   * run KRaftLeaderEvent, state is INACTIVE ✅ 
   * run PollEvent, no-op
   
   So yea, it makes sense to use Case 3 for the test since it always contrives 
the race condition.



-- 
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]

Reply via email to