kevin-wu24 commented on code in PR #19982:
URL: https://github.com/apache/kafka/pull/19982#discussion_r2153376114


##########
raft/src/test/java/org/apache/kafka/raft/KafkaRaftClientReconfigTest.java:
##########
@@ -374,26 +428,104 @@ public void testAddVoter() throws Exception {
             apiVersionRequest.destination(),
             apiVersionsResponse(Errors.NONE)
         );
+    }
 
-        // Handle the API_VERSIONS response
-        context.client.poll();
-        // Append new VotersRecord to log
-        context.client.poll();
+    private void commitAddVoter(
+        RaftClientTestContext context,
+        ReplicaKey leader,
+        ReplicaKey follower,
+        ReplicaKey newVoter,
+        int epoch
+    ) throws Exception {
         // The new voter is now a voter after writing the VotersRecord to the 
log
         assertTrue(context.client.quorum().isVoter(newVoter));
         checkLeaderMetricValues(3, 0, 1, context);
 
         // Send a FETCH to increase the HWM and commit the new voter set
         context.deliverRequest(
-            context.fetchRequest(epoch, follower, 
context.log.endOffset().offset(), epoch, 0)
+            context.fetchRequest(
+                epoch,
+                follower,
+                context.log.endOffset().offset(),
+                epoch,
+                0
+            )
         );
         context.pollUntilResponse();
-        context.assertSentFetchPartitionResponse(Errors.NONE, epoch, 
OptionalInt.of(local.id()));
+        context.assertSentFetchPartitionResponse(Errors.NONE, epoch, 
OptionalInt.of(leader.id()));
         checkLeaderMetricValues(3, 0, 0, context);
+    }
 
-        // Expect reply for AddVoter request
+    @ParameterizedTest
+    @EnumSource(value = RaftProtocol.class, names = {
+        "KIP_853_PROTOCOL",
+        "KIP_996_PROTOCOL"
+    })
+    void testAddVoterCompatibility(RaftProtocol protocol) throws Exception {
+        ReplicaKey local = replicaKey(randomReplicaId(), true);
+        ReplicaKey follower = replicaKey(local.id() + 1, true);
+
+        VoterSet voters = VoterSetTest.voterSet(Stream.of(local, follower));
+
+        RaftClientTestContext context = new 
RaftClientTestContext.Builder(local.id(), local.directoryId().get())
+            .withRaftProtocol(protocol)
+            .withBootstrapSnapshot(Optional.of(voters))
+            .withUnknownLeader(3)
+            .build();
+
+        context.unattachedToLeader();
+        int epoch = context.currentEpoch();
+
+        ReplicaKey newVoter = replicaKey(local.id() + 2, true);
+        InetSocketAddress newAddress = InetSocketAddress.createUnresolved(
+            "localhost",
+            9990 + newVoter.id()
+        );
+        Endpoints newListeners = Endpoints.fromInetSocketAddresses(
+            Map.of(context.channel.listenerName(), newAddress)
+        );
+
+        prepareToSendAddVoter(context, epoch, local, follower, newVoter);
+
+        // Attempt to add new voter to the quorum
+        assertThrows(
+            UnsupportedVersionException.class,
+            () -> context.deliverRequest(
+                context.addVoterRequest(
+                    Integer.MAX_VALUE,
+                    newVoter,
+                    newListeners
+                ).setAckWhenCommitted(false)
+            )
+        );
+    }
+
+    // This method sets up the context so a test can send an AddVoter request 
after
+    // exiting this method
+    private void prepareToSendAddVoter(

Review Comment:
   > could we perhaps rename to "prepareLeaderToReceiveAddVoter"
   
   Yeah, this is more accurate.
   
   > I wonder if it might be more clear to have this written out explicitly in 
the tests
   
   I would prefer to have this code in a helper method, which applies to the 
other comment too. In my opinion, it's clearer to me when all of these tests do 
have the exact same assertions so long as they apply, because it means our new 
`AckWhenCommitted` field (or any other feature) is not changing the behavior 
around the existing assertions. For example, the metric values check prevented 
me from writing an incorrect implementation!
   
   Another way to think about it is that in these `AddVoter` unit tests, we're 
testing the same state of KRaft essentially (i.e. how the local leader handles 
AddVoter RPC), but each test is changing one thing, which is the 
`ackWhenCommitted` value (true, false, or NOT_SUPPORTED). Because we want 
coverage, I think duplication is a natural side-effect. 
   
   Maybe I can just document the helpers/rename them as specific to these 
`AddVoter` tests?
   



-- 
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: jira-unsubscr...@kafka.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to