@ -38,9 +38,9 @@ import java.util.Arrays;
import java.util.Collections ;
import java.util.Collections ;
import java.util.Optional ;
import java.util.Optional ;
import java.util.function.IntPredicate ;
import java.util.function.IntPredicate ;
import java.util.stream.IntStream ;
import java.util.stream.Stream ;
import java.util.stream.Stream ;
import static org.apache.kafka.common.metadata.MetadataRecordType.PARTITION_CHANGE_RECORD ;
import static org.apache.kafka.controller.PartitionChangeBuilder.Election ;
import static org.apache.kafka.controller.PartitionChangeBuilder.Election ;
import static org.apache.kafka.controller.PartitionChangeBuilder.changeRecordIsNoOp ;
import static org.apache.kafka.controller.PartitionChangeBuilder.changeRecordIsNoOp ;
import static org.apache.kafka.metadata.LeaderConstants.NO_LEADER ;
import static org.apache.kafka.metadata.LeaderConstants.NO_LEADER ;
@ -53,13 +53,17 @@ import static org.junit.jupiter.params.provider.Arguments.arguments;
@Timeout ( value = 40 )
@Timeout ( value = 40 )
public class PartitionChangeBuilderTest {
public class PartitionChangeBuilderTest {
private static Stream < Arguments > partitionChangeRecordVersions ( ) {
return IntStream . range ( PartitionChangeRecord . LOWEST_SUPPORTED_VERSION , PartitionChangeRecord . HIGHEST_SUPPORTED_VERSION + 1 ) . mapToObj ( version - > Arguments . of ( ( short ) version ) ) ;
}
@Test
@Test
public void testChangeRecordIsNoOp ( ) {
public void testChangeRecordIsNoOp ( ) {
/ * If the next few checks fail please update them based on the latest schema and make sure
/ * If the next few checks fail please update them based on the latest schema and make sure
* to update changeRecordIsNoOp to take into account the new schema or tagged fields .
* to update changeRecordIsNoOp to take into account the new schema or tagged fields .
* /
* /
// Check that the supported versions haven't changed
// Check that the supported versions haven't changed
assertEquals ( 0 , PartitionChangeRecord . HIGHEST_SUPPORTED_VERSION ) ;
assertEquals ( 1 , PartitionChangeRecord . HIGHEST_SUPPORTED_VERSION ) ;
assertEquals ( 0 , PartitionChangeRecord . LOWEST_SUPPORTED_VERSION ) ;
assertEquals ( 0 , PartitionChangeRecord . LOWEST_SUPPORTED_VERSION ) ;
// For the latest version check that the number of tagged fields hasn't changed
// For the latest version check that the number of tagged fields hasn't changed
TaggedFields taggedFields = ( TaggedFields ) PartitionChangeRecord . SCHEMA_0 . get ( 2 ) . def . type ;
TaggedFields taggedFields = ( TaggedFields ) PartitionChangeRecord . SCHEMA_0 . get ( 2 ) . def . type ;
@ -73,6 +77,10 @@ public class PartitionChangeBuilderTest {
setRemovingReplicas ( Arrays . asList ( 1 ) ) ) ) ;
setRemovingReplicas ( Arrays . asList ( 1 ) ) ) ) ;
assertFalse ( changeRecordIsNoOp ( new PartitionChangeRecord ( ) .
assertFalse ( changeRecordIsNoOp ( new PartitionChangeRecord ( ) .
setAddingReplicas ( Arrays . asList ( 4 ) ) ) ) ;
setAddingReplicas ( Arrays . asList ( 4 ) ) ) ) ;
assertFalse ( changeRecordIsNoOp ( new PartitionChangeRecord ( ) .
setEligibleLeaderReplicas ( Arrays . asList ( 5 ) ) ) ) ;
assertFalse ( changeRecordIsNoOp ( new PartitionChangeRecord ( ) .
setLastKnownELR ( Arrays . asList ( 6 ) ) ) ) ;
assertFalse (
assertFalse (
changeRecordIsNoOp (
changeRecordIsNoOp (
new PartitionChangeRecord ( )
new PartitionChangeRecord ( )
@ -92,12 +100,16 @@ public class PartitionChangeBuilderTest {
private final static Uuid FOO_ID = Uuid . fromString ( "FbrrdcfiR-KC2CPSTHaJrg" ) ;
private final static Uuid FOO_ID = Uuid . fromString ( "FbrrdcfiR-KC2CPSTHaJrg" ) ;
private static PartitionChangeBuilder createFooBuilder ( ) {
private static MetadataVersion metadataVersionForPartitionChangeRecordVersion ( short version ) {
return createFooBuilder ( MetadataVersion . latest ( ) ) ;
return isElrEnabled ( version ) ? MetadataVersion . IBP_3_7_IV1 : MetadataVersion . IBP_3_7_IV0 ;
}
}
private static PartitionChangeBuilder createFooBuilder ( MetadataVersion metadataVersion ) {
private static PartitionChangeBuilder createFooBuilder ( MetadataVersion metadataVersion ) {
return new PartitionChangeBuilder ( FOO , FOO_ID , 0 , r - > r ! = 3 , metadataVersion ) ;
return new PartitionChangeBuilder ( FOO , FOO_ID , 0 , r - > r ! = 3 , metadataVersion , 2 ) ;
}
private static PartitionChangeBuilder createFooBuilder ( short version ) {
return new PartitionChangeBuilder ( FOO , FOO_ID , 0 , r - > r ! = 3 , metadataVersionForPartitionChangeRecordVersion ( version ) , 2 ) . setEligibleLeaderReplicasEnabled ( isElrEnabled ( version ) ) ;
}
}
private static final PartitionRegistration BAR = new PartitionRegistration . Builder ( ) .
private static final PartitionRegistration BAR = new PartitionRegistration . Builder ( ) .
@ -113,8 +125,12 @@ public class PartitionChangeBuilderTest {
private final static Uuid BAR_ID = Uuid . fromString ( "LKfUsCBnQKekvL9O5dY9nw" ) ;
private final static Uuid BAR_ID = Uuid . fromString ( "LKfUsCBnQKekvL9O5dY9nw" ) ;
private static PartitionChangeBuilder createBarBuilder ( ) {
private static boolean isElrEnabled ( short partitionChangeRecordVersion ) {
return new PartitionChangeBuilder ( BAR , BAR_ID , 0 , r - > r ! = 3 , MetadataVersion . latest ( ) ) ;
return partitionChangeRecordVersion > 0 ;
}
private static PartitionChangeBuilder createBarBuilder ( short version ) {
return new PartitionChangeBuilder ( BAR , BAR_ID , 0 , r - > r ! = 3 , metadataVersionForPartitionChangeRecordVersion ( version ) , 2 ) . setEligibleLeaderReplicasEnabled ( isElrEnabled ( version ) ) ;
}
}
private static final PartitionRegistration BAZ = new PartitionRegistration . Builder ( ) .
private static final PartitionRegistration BAZ = new PartitionRegistration . Builder ( ) .
@ -128,8 +144,8 @@ public class PartitionChangeBuilderTest {
private final static Uuid BAZ_ID = Uuid . fromString ( "wQzt5gkSTwuQNXZF5gIw7A" ) ;
private final static Uuid BAZ_ID = Uuid . fromString ( "wQzt5gkSTwuQNXZF5gIw7A" ) ;
private static PartitionChangeBuilder createBazBuilder ( ) {
private static PartitionChangeBuilder createBazBuilder ( short version ) {
return new PartitionChangeBuilder ( BAZ , BAZ_ID , 0 , __ - > true , MetadataVersion . latest ( ) ) ;
return new PartitionChangeBuilder ( BAZ , BAZ_ID , 0 , __ - > true , metadataVersionForPartitionChangeRecordVersion ( version ) , 2 ) . setEligibleLeaderReplicasEnabled ( isElrEnabled ( version ) ) ;
}
}
private static final PartitionRegistration OFFLINE = new PartitionRegistration . Builder ( ) .
private static final PartitionRegistration OFFLINE = new PartitionRegistration . Builder ( ) .
@ -143,8 +159,8 @@ public class PartitionChangeBuilderTest {
private final static Uuid OFFLINE_ID = Uuid . fromString ( "LKfUsCBnQKekvL9O5dY9nw" ) ;
private final static Uuid OFFLINE_ID = Uuid . fromString ( "LKfUsCBnQKekvL9O5dY9nw" ) ;
private static PartitionChangeBuilder createOfflineBuilder ( ) {
private static PartitionChangeBuilder createOfflineBuilder ( short version ) {
return new PartitionChangeBuilder ( OFFLINE , OFFLINE_ID , 0 , r - > r = = 1 , MetadataVersion . latest ( ) ) ;
return new PartitionChangeBuilder ( OFFLINE , OFFLINE_ID , 0 , r - > r = = 1 , metadataVersionForPartitionChangeRecordVersion ( version ) , 2 ) . setEligibleLeaderReplicasEnabled ( isElrEnabled ( version ) ) ;
}
}
private static void assertElectLeaderEquals ( PartitionChangeBuilder builder ,
private static void assertElectLeaderEquals ( PartitionChangeBuilder builder ,
@ -155,29 +171,30 @@ public class PartitionChangeBuilderTest {
assertEquals ( expectedUnclean , electionResult . unclean ) ;
assertEquals ( expectedUnclean , electionResult . unclean ) ;
}
}
@Test
@ParameterizedTest
public void testElectLeader ( ) {
@MethodSource ( "partitionChangeRecordVersions" )
assertElectLeaderEquals ( createFooBuilder ( ) . setElection ( Election . PREFERRED ) , 2 , false ) ;
public void testElectLeader ( short version ) {
assertElectLeaderEquals ( createFooBuilder ( ) , 1 , false ) ;
assertElectLeaderEquals ( createFooBuilder ( version ) . setElection ( Election . PREFERRED ) , 2 , false ) ;
assertElectLeaderEquals ( createFooBuilder ( ) . setElection ( Election . UNCLEAN ) , 1 , false ) ;
assertElectLeaderEquals ( createFooBuilder ( version ) , 1 , false ) ;
assertElectLeaderEquals ( createFooBuilder ( )
assertElectLeaderEquals ( createFooBuilder ( version ) . setElection ( Election . UNCLEAN ) , 1 , false ) ;
assertElectLeaderEquals ( createFooBuilder ( version )
. setTargetIsrWithBrokerStates ( AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( Arrays . asList ( 1 , 3 ) ) ) , 1 , false ) ;
. setTargetIsrWithBrokerStates ( AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( Arrays . asList ( 1 , 3 ) ) ) , 1 , false ) ;
assertElectLeaderEquals ( createFooBuilder ( ) . setElection ( Election . UNCLEAN )
assertElectLeaderEquals ( createFooBuilder ( version ) . setElection ( Election . UNCLEAN )
. setTargetIsrWithBrokerStates ( AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( Arrays . asList ( 1 , 3 ) ) ) , 1 , false ) ;
. setTargetIsrWithBrokerStates ( AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( Arrays . asList ( 1 , 3 ) ) ) , 1 , false ) ;
assertElectLeaderEquals ( createFooBuilder ( )
assertElectLeaderEquals ( createFooBuilder ( version )
. setTargetIsrWithBrokerStates ( AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( Arrays . asList ( 3 ) ) ) , NO_LEADER , false ) ;
. setTargetIsrWithBrokerStates ( AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( Arrays . asList ( 3 ) ) ) , NO_LEADER , false ) ;
assertElectLeaderEquals ( createFooBuilder ( ) . setElection ( Election . UNCLEAN ) .
assertElectLeaderEquals ( createFooBuilder ( version ) . setElection ( Election . UNCLEAN ) .
setTargetIsrWithBrokerStates ( AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( Arrays . asList ( 3 ) ) ) , 2 , true ) ;
setTargetIsrWithBrokerStates ( AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( Arrays . asList ( 3 ) ) ) , 2 , true ) ;
assertElectLeaderEquals (
assertElectLeaderEquals (
createFooBuilder ( ) . setElection ( Election . UNCLEAN )
createFooBuilder ( version ) . setElection ( Election . UNCLEAN )
. setTargetIsrWithBrokerStates ( AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( Arrays . asList ( 4 ) ) ) . setTargetReplicas ( Arrays . asList ( 2 , 1 , 3 , 4 ) ) ,
. setTargetIsrWithBrokerStates ( AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( Arrays . asList ( 4 ) ) ) . setTargetReplicas ( Arrays . asList ( 2 , 1 , 3 , 4 ) ) ,
4 ,
4 ,
false
false
) ;
) ;
assertElectLeaderEquals ( createBazBuilder ( ) . setElection ( Election . PREFERRED ) , 3 , false ) ;
assertElectLeaderEquals ( createBazBuilder ( version ) . setElection ( Election . PREFERRED ) , 3 , false ) ;
assertElectLeaderEquals ( createBazBuilder ( ) , 3 , false ) ;
assertElectLeaderEquals ( createBazBuilder ( version ) , 3 , false ) ;
assertElectLeaderEquals ( createBazBuilder ( ) . setElection ( Election . UNCLEAN ) , 3 , false ) ;
assertElectLeaderEquals ( createBazBuilder ( version ) . setElection ( Election . UNCLEAN ) , 3 , false ) ;
}
}
private static void testTriggerLeaderEpochBumpIfNeededLeader ( PartitionChangeBuilder builder ,
private static void testTriggerLeaderEpochBumpIfNeededLeader ( PartitionChangeBuilder builder ,
@ -187,13 +204,14 @@ public class PartitionChangeBuilderTest {
assertEquals ( expectedLeader , record . leader ( ) ) ;
assertEquals ( expectedLeader , record . leader ( ) ) ;
}
}
@Test
@ParameterizedTest
public void testTriggerLeaderEpochBumpIfNeeded ( ) {
@MethodSource ( "partitionChangeRecordVersions" )
testTriggerLeaderEpochBumpIfNeededLeader ( createFooBuilder ( ) ,
public void testTriggerLeaderEpochBumpIfNeeded ( short version ) {
testTriggerLeaderEpochBumpIfNeededLeader ( createFooBuilder ( version ) ,
new PartitionChangeRecord ( ) , NO_LEADER_CHANGE ) ;
new PartitionChangeRecord ( ) , NO_LEADER_CHANGE ) ;
// Shrinking the ISR doesn't increase the leader epoch
// Shrinking the ISR doesn't increase the leader epoch
testTriggerLeaderEpochBumpIfNeededLeader (
testTriggerLeaderEpochBumpIfNeededLeader (
createFooBuilder ( ) . setTargetIsrWithBrokerStates (
createFooBuilder ( version ) . setTargetIsrWithBrokerStates (
AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( Arrays . asList ( 2 , 1 ) )
AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( Arrays . asList ( 2 , 1 ) )
) ,
) ,
new PartitionChangeRecord ( ) ,
new PartitionChangeRecord ( ) ,
@ -201,7 +219,7 @@ public class PartitionChangeBuilderTest {
) ;
) ;
// Expanding the ISR doesn't increase the leader epoch
// Expanding the ISR doesn't increase the leader epoch
testTriggerLeaderEpochBumpIfNeededLeader (
testTriggerLeaderEpochBumpIfNeededLeader (
createFooBuilder ( ) . setTargetIsrWithBrokerStates (
createFooBuilder ( version ) . setTargetIsrWithBrokerStates (
AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( Arrays . asList ( 2 , 1 , 3 , 4 ) )
AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( Arrays . asList ( 2 , 1 , 3 , 4 ) )
) ,
) ,
new PartitionChangeRecord ( ) ,
new PartitionChangeRecord ( ) ,
@ -209,24 +227,24 @@ public class PartitionChangeBuilderTest {
) ;
) ;
// Expanding the ISR during migration doesn't increase leader epoch
// Expanding the ISR during migration doesn't increase leader epoch
testTriggerLeaderEpochBumpIfNeededLeader (
testTriggerLeaderEpochBumpIfNeededLeader (
createFooBuilder ( )
createFooBuilder ( version )
. setTargetIsrWithBrokerStates (
. setTargetIsrWithBrokerStates (
AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( Arrays . asList ( 2 , 1 , 3 , 4 ) ) )
AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( Arrays . asList ( 2 , 1 , 3 , 4 ) ) )
. setZkMigrationEnabled ( true ) ,
. setZkMigrationEnabled ( true ) ,
new PartitionChangeRecord ( ) ,
new PartitionChangeRecord ( ) ,
NO_LEADER_CHANGE
NO_LEADER_CHANGE
) ;
) ;
testTriggerLeaderEpochBumpIfNeededLeader ( createFooBuilder ( ) .
testTriggerLeaderEpochBumpIfNeededLeader ( createFooBuilder ( version ) .
setTargetReplicas ( Arrays . asList ( 2 , 1 , 3 , 4 ) ) , new PartitionChangeRecord ( ) ,
setTargetReplicas ( Arrays . asList ( 2 , 1 , 3 , 4 ) ) , new PartitionChangeRecord ( ) ,
NO_LEADER_CHANGE ) ;
NO_LEADER_CHANGE ) ;
testTriggerLeaderEpochBumpIfNeededLeader ( createFooBuilder ( ) .
testTriggerLeaderEpochBumpIfNeededLeader ( createFooBuilder ( version ) .
setTargetReplicas ( Arrays . asList ( 2 , 1 , 3 , 4 ) ) ,
setTargetReplicas ( Arrays . asList ( 2 , 1 , 3 , 4 ) ) ,
new PartitionChangeRecord ( ) . setLeader ( 2 ) , 2 ) ;
new PartitionChangeRecord ( ) . setLeader ( 2 ) , 2 ) ;
// Check that the leader epoch is bump if the ISR shrinks and isSkipLeaderEpochBumpSupported is not supported.
// Check that the leader epoch is bump if the ISR shrinks and isSkipLeaderEpochBumpSupported is not supported.
// See KAFKA-15021 for details.
// See KAFKA-15021 for details.
testTriggerLeaderEpochBumpIfNeededLeader (
testTriggerLeaderEpochBumpIfNeededLeader (
new PartitionChangeBuilder ( FOO , FOO_ID , 0 , r - > r ! = 3 , MetadataVersion . IBP_3_5_IV2 )
new PartitionChangeBuilder ( FOO , FOO_ID , 0 , r - > r ! = 3 , MetadataVersion . IBP_3_5_IV2 , 2 )
. setTargetIsrWithBrokerStates (
. setTargetIsrWithBrokerStates (
AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( Arrays . asList ( 2 , 1 ) )
AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( Arrays . asList ( 2 , 1 ) )
) ,
) ,
@ -235,11 +253,12 @@ public class PartitionChangeBuilderTest {
) ;
) ;
}
}
@Test
@ParameterizedTest
public void testLeaderEpochBumpZkMigration ( ) {
@MethodSource ( "partitionChangeRecordVersions" )
public void testLeaderEpochBumpZkMigration ( short version ) {
// KAFKA-15109: Shrinking the ISR while in ZK migration mode requires a leader epoch bump
// KAFKA-15109: Shrinking the ISR while in ZK migration mode requires a leader epoch bump
testTriggerLeaderEpochBumpIfNeededLeader (
testTriggerLeaderEpochBumpIfNeededLeader (
createFooBuilder ( )
createFooBuilder ( version )
. setTargetIsrWithBrokerStates (
. setTargetIsrWithBrokerStates (
AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( Arrays . asList ( 2 , 1 ) ) )
AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( Arrays . asList ( 2 , 1 ) ) )
. setZkMigrationEnabled ( true ) ,
. setZkMigrationEnabled ( true ) ,
@ -248,7 +267,7 @@ public class PartitionChangeBuilderTest {
) ;
) ;
testTriggerLeaderEpochBumpIfNeededLeader (
testTriggerLeaderEpochBumpIfNeededLeader (
createFooBuilder ( )
createFooBuilder ( version )
. setTargetIsrWithBrokerStates (
. setTargetIsrWithBrokerStates (
AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( Arrays . asList ( 2 , 1 ) ) )
AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( Arrays . asList ( 2 , 1 ) ) )
. setZkMigrationEnabled ( false ) ,
. setZkMigrationEnabled ( false ) ,
@ -276,17 +295,19 @@ public class PartitionChangeBuilderTest {
) ;
) ;
}
}
@Test
@ParameterizedTest
public void testNoChange ( ) {
@MethodSource ( "partitionChangeRecordVersions" )
assertEquals ( Optional . empty ( ) , createFooBuilder ( ) . build ( ) ) ;
public void testNoChange ( short version ) {
assertEquals ( Optional . empty ( ) , createFooBuilder ( ) . setElection ( Election . UNCLEAN ) . build ( ) ) ;
assertEquals ( Optional . empty ( ) , createFooBuilder ( version ) . build ( ) ) ;
assertEquals ( Optional . empty ( ) , createBarBuilder ( ) . build ( ) ) ;
assertEquals ( Optional . empty ( ) , createFooBuilder ( version ) . setElection ( Election . UNCLEAN ) . build ( ) ) ;
assertEquals ( Optional . empty ( ) , createBarBuilder ( ) . setElection ( Election . UNCLEAN ) . build ( ) ) ;
assertEquals ( Optional . empty ( ) , createBarBuilder ( version ) . build ( ) ) ;
assertEquals ( Optional . empty ( ) , createBazBuilder ( ) . setElection ( Election . PREFERRED ) . build ( ) ) ;
assertEquals ( Optional . empty ( ) , createBarBuilder ( version ) . setElection ( Election . UNCLEAN ) . build ( ) ) ;
assertEquals ( Optional . empty ( ) , createBazBuilder ( version ) . setElection ( Election . PREFERRED ) . build ( ) ) ;
}
}
@Test
@ParameterizedTest
public void testIsrChangeDoesntBumpLeaderEpoch ( ) {
@MethodSource ( "partitionChangeRecordVersions" )
public void testIsrChangeDoesntBumpLeaderEpoch ( short version ) {
// Changing the ISR should not cause the leader epoch to increase
// Changing the ISR should not cause the leader epoch to increase
assertEquals (
assertEquals (
// Expected
// Expected
@ -296,11 +317,11 @@ public class PartitionChangeBuilderTest {
. setTopicId ( FOO_ID )
. setTopicId ( FOO_ID )
. setPartitionId ( 0 )
. setPartitionId ( 0 )
. setIsr ( Arrays . asList ( 2 , 1 ) ) ,
. setIsr ( Arrays . asList ( 2 , 1 ) ) ,
PARTITION_CHANGE_RECORD . highestSupportedVersion ( )
version
)
)
) ,
) ,
// Actual
// Actual
createFooBuilder ( )
createFooBuilder ( version )
. setTargetIsrWithBrokerStates (
. setTargetIsrWithBrokerStates (
AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( Arrays . asList ( 2 , 1 ) )
AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( Arrays . asList ( 2 , 1 ) )
)
)
@ -308,28 +329,31 @@ public class PartitionChangeBuilderTest {
) ;
) ;
}
}
@Test
@ParameterizedTest
public void testIsrChangeAndLeaderChange ( ) {
@MethodSource ( "partitionChangeRecordVersions" )
public void testIsrChangeAndLeaderChange ( short version ) {
assertEquals ( Optional . of ( new ApiMessageAndVersion ( new PartitionChangeRecord ( ) .
assertEquals ( Optional . of ( new ApiMessageAndVersion ( new PartitionChangeRecord ( ) .
setTopicId ( FOO_ID ) .
setTopicId ( FOO_ID ) .
setPartitionId ( 0 ) .
setPartitionId ( 0 ) .
setIsr ( Arrays . asList ( 2 , 3 ) ) .
setIsr ( Arrays . asList ( 2 , 3 ) ) .
setLeader ( 2 ) , PARTITION_CHANGE_RECORD . highestSupportedVersion ( ) ) ) ,
setLeader ( 2 ) , version ) ) ,
createFooBuilder ( ) . setTargetIsrWithBrokerStates ( AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( Arrays . asList ( 2 , 3 ) ) ) . build ( ) ) ;
createFooBuilder ( version ) . setTargetIsrWithBrokerStates ( AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( Arrays . asList ( 2 , 3 ) ) ) . build ( ) ) ;
}
}
@Test
@ParameterizedTest
public void testReassignmentRearrangesReplicas ( ) {
@MethodSource ( "partitionChangeRecordVersions" )
public void testReassignmentRearrangesReplicas ( short version ) {
assertEquals ( Optional . of ( new ApiMessageAndVersion ( new PartitionChangeRecord ( ) .
assertEquals ( Optional . of ( new ApiMessageAndVersion ( new PartitionChangeRecord ( ) .
setTopicId ( FOO_ID ) .
setTopicId ( FOO_ID ) .
setPartitionId ( 0 ) .
setPartitionId ( 0 ) .
setReplicas ( Arrays . asList ( 3 , 2 , 1 ) ) ,
setReplicas ( Arrays . asList ( 3 , 2 , 1 ) ) ,
PARTITION_CHANGE_RECORD . highestSupportedVersion ( ) ) ) ,
version ) ) ,
createFooBuilder ( ) . setTargetReplicas ( Arrays . asList ( 3 , 2 , 1 ) ) . build ( ) ) ;
createFooBuilder ( version ) . setTargetReplicas ( Arrays . asList ( 3 , 2 , 1 ) ) . build ( ) ) ;
}
}
@Test
@ParameterizedTest
public void testIsrEnlargementCompletesReassignment ( ) {
@MethodSource ( "partitionChangeRecordVersions" )
public void testIsrEnlargementCompletesReassignment ( short version ) {
assertEquals ( Optional . of ( new ApiMessageAndVersion ( new PartitionChangeRecord ( ) .
assertEquals ( Optional . of ( new ApiMessageAndVersion ( new PartitionChangeRecord ( ) .
setTopicId ( BAR_ID ) .
setTopicId ( BAR_ID ) .
setPartitionId ( 0 ) .
setPartitionId ( 0 ) .
@ -338,12 +362,13 @@ public class PartitionChangeBuilderTest {
setLeader ( 2 ) .
setLeader ( 2 ) .
setRemovingReplicas ( Collections . emptyList ( ) ) .
setRemovingReplicas ( Collections . emptyList ( ) ) .
setAddingReplicas ( Collections . emptyList ( ) ) ,
setAddingReplicas ( Collections . emptyList ( ) ) ,
PARTITION_CHANGE_RECORD . highestSupportedVersion ( ) ) ) ,
version ) ) ,
createBarBuilder ( ) . setTargetIsrWithBrokerStates ( AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( Arrays . asList ( 1 , 2 , 3 , 4 ) ) ) . build ( ) ) ;
createBarBuilder ( version ) . setTargetIsrWithBrokerStates ( AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( Arrays . asList ( 1 , 2 , 3 , 4 ) ) ) . build ( ) ) ;
}
}
@Test
@ParameterizedTest
public void testRevertReassignment ( ) {
@MethodSource ( "partitionChangeRecordVersions" )
public void testRevertReassignment ( short version ) {
PartitionReassignmentRevert revert = new PartitionReassignmentRevert ( BAR ) ;
PartitionReassignmentRevert revert = new PartitionReassignmentRevert ( BAR ) ;
assertEquals ( Arrays . asList ( 1 , 2 , 3 ) , revert . replicas ( ) ) ;
assertEquals ( Arrays . asList ( 1 , 2 , 3 ) , revert . replicas ( ) ) ;
assertEquals ( Arrays . asList ( 1 , 2 , 3 ) , revert . isr ( ) ) ;
assertEquals ( Arrays . asList ( 1 , 2 , 3 ) , revert . isr ( ) ) ;
@ -354,8 +379,8 @@ public class PartitionChangeBuilderTest {
setLeader ( 1 ) .
setLeader ( 1 ) .
setRemovingReplicas ( Collections . emptyList ( ) ) .
setRemovingReplicas ( Collections . emptyList ( ) ) .
setAddingReplicas ( Collections . emptyList ( ) ) ,
setAddingReplicas ( Collections . emptyList ( ) ) ,
PARTITION_CHANGE_RECORD . highestSupportedVersion ( ) ) ) ,
version ) ) ,
createBarBuilder ( ) .
createBarBuilder ( version ) .
setTargetReplicas ( revert . replicas ( ) ) .
setTargetReplicas ( revert . replicas ( ) ) .
setTargetIsrWithBrokerStates ( AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( revert . isr ( ) ) ) .
setTargetIsrWithBrokerStates ( AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( revert . isr ( ) ) ) .
setTargetRemoving ( Collections . emptyList ( ) ) .
setTargetRemoving ( Collections . emptyList ( ) ) .
@ -363,8 +388,9 @@ public class PartitionChangeBuilderTest {
build ( ) ) ;
build ( ) ) ;
}
}
@Test
@ParameterizedTest
public void testRemovingReplicaReassignment ( ) {
@MethodSource ( "partitionChangeRecordVersions" )
public void testRemovingReplicaReassignment ( short version ) {
PartitionReassignmentReplicas replicas = new PartitionReassignmentReplicas (
PartitionReassignmentReplicas replicas = new PartitionReassignmentReplicas (
new PartitionAssignment ( Replicas . toList ( FOO . replicas ) ) , new PartitionAssignment ( Arrays . asList ( 1 , 2 ) ) ) ;
new PartitionAssignment ( Replicas . toList ( FOO . replicas ) ) , new PartitionAssignment ( Arrays . asList ( 1 , 2 ) ) ) ;
assertEquals ( Collections . singletonList ( 3 ) , replicas . removing ( ) ) ;
assertEquals ( Collections . singletonList ( 3 ) , replicas . removing ( ) ) ;
@ -376,15 +402,16 @@ public class PartitionChangeBuilderTest {
setReplicas ( Arrays . asList ( 1 , 2 ) ) .
setReplicas ( Arrays . asList ( 1 , 2 ) ) .
setIsr ( Arrays . asList ( 2 , 1 ) ) .
setIsr ( Arrays . asList ( 2 , 1 ) ) .
setLeader ( 1 ) ,
setLeader ( 1 ) ,
PARTITION_CHANGE_RECORD . highestSupportedVersion ( ) ) ) ,
version ) ) ,
createFooBuilder ( ) .
createFooBuilder ( version ) .
setTargetReplicas ( replicas . replicas ( ) ) .
setTargetReplicas ( replicas . replicas ( ) ) .
setTargetRemoving ( replicas . removing ( ) ) .
setTargetRemoving ( replicas . removing ( ) ) .
build ( ) ) ;
build ( ) ) ;
}
}
@Test
@ParameterizedTest
public void testAddingReplicaReassignment ( ) {
@MethodSource ( "partitionChangeRecordVersions" )
public void testAddingReplicaReassignment ( short version ) {
PartitionReassignmentReplicas replicas = new PartitionReassignmentReplicas (
PartitionReassignmentReplicas replicas = new PartitionReassignmentReplicas (
new PartitionAssignment ( Replicas . toList ( FOO . replicas ) ) , new PartitionAssignment ( Arrays . asList ( 1 , 2 , 3 , 4 ) ) ) ;
new PartitionAssignment ( Replicas . toList ( FOO . replicas ) ) , new PartitionAssignment ( Arrays . asList ( 1 , 2 , 3 , 4 ) ) ) ;
assertEquals ( Collections . emptyList ( ) , replicas . removing ( ) ) ;
assertEquals ( Collections . emptyList ( ) , replicas . removing ( ) ) ;
@ -395,15 +422,16 @@ public class PartitionChangeBuilderTest {
setPartitionId ( 0 ) .
setPartitionId ( 0 ) .
setReplicas ( Arrays . asList ( 1 , 2 , 3 , 4 ) ) .
setReplicas ( Arrays . asList ( 1 , 2 , 3 , 4 ) ) .
setAddingReplicas ( Collections . singletonList ( 4 ) ) ,
setAddingReplicas ( Collections . singletonList ( 4 ) ) ,
PARTITION_CHANGE_RECORD . highestSupportedVersion ( ) ) ) ,
version ) ) ,
createFooBuilder ( ) .
createFooBuilder ( version ) .
setTargetReplicas ( replicas . replicas ( ) ) .
setTargetReplicas ( replicas . replicas ( ) ) .
setTargetAdding ( replicas . adding ( ) ) .
setTargetAdding ( replicas . adding ( ) ) .
build ( ) ) ;
build ( ) ) ;
}
}
@Test
@ParameterizedTest
public void testUncleanLeaderElection ( ) {
@MethodSource ( "partitionChangeRecordVersions" )
public void testUncleanLeaderElection ( short version ) {
ApiMessageAndVersion expectedRecord = new ApiMessageAndVersion (
ApiMessageAndVersion expectedRecord = new ApiMessageAndVersion (
new PartitionChangeRecord ( )
new PartitionChangeRecord ( )
. setTopicId ( FOO_ID )
. setTopicId ( FOO_ID )
@ -411,11 +439,11 @@ public class PartitionChangeBuilderTest {
. setIsr ( Arrays . asList ( 2 ) )
. setIsr ( Arrays . asList ( 2 ) )
. setLeader ( 2 )
. setLeader ( 2 )
. setLeaderRecoveryState ( LeaderRecoveryState . RECOVERING . value ( ) ) ,
. setLeaderRecoveryState ( LeaderRecoveryState . RECOVERING . value ( ) ) ,
PARTITION_CHANGE_RECORD . highestSupportedVersion ( )
version
) ;
) ;
assertEquals (
assertEquals (
Optional . of ( expectedRecord ) ,
Optional . of ( expectedRecord ) ,
createFooBuilder ( ) . setElection ( Election . UNCLEAN )
createFooBuilder ( version ) . setElection ( Election . UNCLEAN )
. setTargetIsrWithBrokerStates ( AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( Arrays . asList ( 3 ) ) ) . build ( )
. setTargetIsrWithBrokerStates ( AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( Arrays . asList ( 3 ) ) ) . build ( )
) ;
) ;
@ -426,15 +454,16 @@ public class PartitionChangeBuilderTest {
. setIsr ( Arrays . asList ( 1 ) )
. setIsr ( Arrays . asList ( 1 ) )
. setLeader ( 1 )
. setLeader ( 1 )
. setLeaderRecoveryState ( LeaderRecoveryState . RECOVERING . value ( ) ) ,
. setLeaderRecoveryState ( LeaderRecoveryState . RECOVERING . value ( ) ) ,
PARTITION_CHANGE_RECORD . highestSupportedVersion ( )
version
) ;
) ;
assertEquals (
assertEquals (
Optional . of ( expectedRecord ) ,
Optional . of ( expectedRecord ) ,
createOfflineBuilder ( ) . setElection ( Election . UNCLEAN ) . build ( )
createOfflineBuilder ( version ) . setElection ( Election . UNCLEAN ) . build ( )
) ;
) ;
assertEquals (
assertEquals (
Optional . of ( expectedRecord ) ,
Optional . of ( expectedRecord ) ,
createOfflineBuilder ( ) . setElection ( Election . UNCLEAN )
createOfflineBuilder ( version ) . setElection ( Election . UNCLEAN )
. setTargetIsrWithBrokerStates ( AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( Arrays . asList ( 2 ) ) ) . build ( )
. setTargetIsrWithBrokerStates ( AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( Arrays . asList ( 2 ) ) ) . build ( )
) ;
) ;
}
}
@ -471,7 +500,8 @@ public class PartitionChangeBuilderTest {
FOO_ID ,
FOO_ID ,
0 ,
0 ,
brokerId - > false ,
brokerId - > false ,
metadataVersion
metadataVersion ,
2
) ;
) ;
offlineBuilder . setZkMigrationEnabled ( zkMigrationsEnabled ) ;
offlineBuilder . setZkMigrationEnabled ( zkMigrationsEnabled ) ;
// Set the target ISR to empty to indicate that the last leader is offline
// Set the target ISR to empty to indicate that the last leader is offline
@ -497,7 +527,8 @@ public class PartitionChangeBuilderTest {
FOO_ID ,
FOO_ID ,
0 ,
0 ,
brokerId - > true ,
brokerId - > true ,
metadataVersion
metadataVersion ,
2
) ;
) ;
onlineBuilder . setZkMigrationEnabled ( zkMigrationsEnabled ) ;
onlineBuilder . setZkMigrationEnabled ( zkMigrationsEnabled ) ;
@ -534,7 +565,8 @@ public class PartitionChangeBuilderTest {
FOO_ID ,
FOO_ID ,
0 ,
0 ,
brokerId - > brokerId = = leaderId ,
brokerId - > brokerId = = leaderId ,
metadataVersion
metadataVersion ,
2
) . setElection ( Election . UNCLEAN ) ;
) . setElection ( Election . UNCLEAN ) ;
onlineBuilder . setZkMigrationEnabled ( zkMigrationsEnabled ) ;
onlineBuilder . setZkMigrationEnabled ( zkMigrationsEnabled ) ;
// The partition should stay as recovering
// The partition should stay as recovering
@ -603,7 +635,8 @@ public class PartitionChangeBuilderTest {
topicId ,
topicId ,
0 ,
0 ,
isValidLeader ,
isValidLeader ,
leaderRecoveryMetadataVersion ( false )
leaderRecoveryMetadataVersion ( false ) ,
2
) ;
) ;
// Before we build the new PartitionChangeBuilder, confirm the current leader is 0.
// Before we build the new PartitionChangeBuilder, confirm the current leader is 0.
@ -617,7 +650,7 @@ public class PartitionChangeBuilderTest {
setRemovingReplicas ( Collections . emptyList ( ) ) .
setRemovingReplicas ( Collections . emptyList ( ) ) .
setAddingReplicas ( Collections . emptyList ( ) ) .
setAddingReplicas ( Collections . emptyList ( ) ) .
setLeader ( NO_LEADER ) ,
setLeader ( NO_LEADER ) ,
PARTITION_CHANGE_RECORD . highestSupportedVersion ( ) ) ) ,
( short ) 0 ) ) ,
partitionChangeBuilder . setTargetIsr ( Arrays . asList ( 0 , 1 , 2 , 3 ) ) .
partitionChangeBuilder . setTargetIsr ( Arrays . asList ( 0 , 1 , 2 , 3 ) ) .
build ( ) ) ;
build ( ) ) ;
}
}
@ -629,4 +662,180 @@ public class PartitionChangeBuilderTest {
return MetadataVersion . IBP_3_1_IV0 ;
return MetadataVersion . IBP_3_1_IV0 ;
}
}
}
}
@ParameterizedTest
@MethodSource ( "partitionChangeRecordVersions" )
public void testEligibleLeaderReplicas_IsrShrinkBelowMinISR ( short version ) {
PartitionRegistration partition = new PartitionRegistration . Builder ( )
. setReplicas ( new int [ ] { 1 , 2 , 3 , 4 } )
. setIsr ( new int [ ] { 1 , 2 , 3 , 4 } )
. setLeader ( 1 )
. setLeaderRecoveryState ( LeaderRecoveryState . RECOVERED )
. setLeaderEpoch ( 100 )
. setPartitionEpoch ( 200 )
. build ( ) ;
Uuid topicId = Uuid . fromString ( "FbrrdcfiR-KC2CPSTHaJrg" ) ;
PartitionChangeBuilder builder = new PartitionChangeBuilder ( partition , topicId , 0 , r - > r ! = 3 , metadataVersionForPartitionChangeRecordVersion ( version ) , 3 )
. setElection ( Election . PREFERRED )
. setEligibleLeaderReplicasEnabled ( isElrEnabled ( version ) ) ;
// Update ISR to {1, 2}
builder . setTargetIsrWithBrokerStates ( AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( Arrays . asList ( 1 , 2 ) ) ) ;
PartitionChangeRecord record = new PartitionChangeRecord ( )
. setTopicId ( topicId )
. setPartitionId ( 0 )
. setIsr ( Arrays . asList ( 1 , 2 ) )
. setLeader ( - 2 )
. setLeaderRecoveryState ( LeaderRecoveryState . NO_CHANGE ) ;
if ( version > 0 ) {
record . setEligibleLeaderReplicas ( Arrays . asList ( 3 , 4 ) ) ;
}
ApiMessageAndVersion expectedRecord = new ApiMessageAndVersion (
record ,
version
) ;
assertEquals ( Optional . of ( expectedRecord ) , builder . build ( ) ) ;
partition = partition . merge ( ( PartitionChangeRecord ) builder . build ( ) . get ( ) . message ( ) ) ;
if ( version > 0 ) {
assertTrue ( Arrays . equals ( new int [ ] { 3 , 4 } , partition . elr ) , partition . toString ( ) ) ;
assertTrue ( Arrays . equals ( new int [ ] { } , partition . lastKnownElr ) , partition . toString ( ) ) ;
} else {
assertEquals ( 0 , partition . elr . length ) ;
assertEquals ( 0 , partition . lastKnownElr . length ) ;
}
}
@ParameterizedTest
@MethodSource ( "partitionChangeRecordVersions" )
public void testEligibleLeaderReplicas_IsrExpandAboveMinISR ( short version ) {
PartitionRegistration partition = new PartitionRegistration . Builder ( )
. setReplicas ( new int [ ] { 1 , 2 , 3 , 4 } )
. setIsr ( new int [ ] { 1 , 2 } )
. setElr ( new int [ ] { 3 } )
. setLastKnownElr ( new int [ ] { 4 } )
. setLeader ( 1 )
. setLeaderRecoveryState ( LeaderRecoveryState . RECOVERED )
. setLeaderEpoch ( 100 )
. setPartitionEpoch ( 200 )
. build ( ) ;
Uuid topicId = Uuid . fromString ( "FbrrdcfiR-KC2CPSTHaJrg" ) ;
// Min ISR is 3.
PartitionChangeBuilder builder = new PartitionChangeBuilder ( partition , topicId , 0 , r - > r ! = 3 , metadataVersionForPartitionChangeRecordVersion ( version ) , 3 )
. setElection ( Election . PREFERRED )
. setEligibleLeaderReplicasEnabled ( isElrEnabled ( version ) ) ;
builder . setTargetIsrWithBrokerStates ( AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( Arrays . asList ( 1 , 2 , 3 ) ) ) ;
PartitionChangeRecord record = new PartitionChangeRecord ( )
. setTopicId ( topicId )
. setPartitionId ( 0 )
. setIsr ( Arrays . asList ( 1 , 2 , 3 ) )
. setLeader ( - 2 )
. setLeaderRecoveryState ( LeaderRecoveryState . NO_CHANGE ) ;
// Both versions will set the elr and lastKnownElr as empty list.
record . setEligibleLeaderReplicas ( Collections . emptyList ( ) )
. setLastKnownELR ( Collections . emptyList ( ) ) ;
ApiMessageAndVersion expectedRecord = new ApiMessageAndVersion (
record ,
version
) ;
assertEquals ( Optional . of ( expectedRecord ) , builder . build ( ) ) ;
partition = partition . merge ( ( PartitionChangeRecord ) builder . build ( ) . get ( ) . message ( ) ) ;
assertEquals ( 0 , partition . elr . length ) ;
assertEquals ( 0 , partition . lastKnownElr . length ) ;
}
@ParameterizedTest
@MethodSource ( "partitionChangeRecordVersions" )
public void testEligibleLeaderReplicas_IsrAddNewMemberNotInELR ( short version ) {
PartitionRegistration partition = new PartitionRegistration . Builder ( )
. setReplicas ( new int [ ] { 1 , 2 , 3 , 4 } )
. setIsr ( new int [ ] { 1 } )
. setElr ( new int [ ] { 3 } )
. setLastKnownElr ( new int [ ] { 2 } )
. setLeader ( 1 )
. setLeaderRecoveryState ( LeaderRecoveryState . RECOVERED )
. setLeaderEpoch ( 100 )
. setPartitionEpoch ( 200 )
. build ( ) ;
Uuid topicId = Uuid . fromString ( "FbrrdcfiR-KC2CPSTHaJrg" ) ;
// Min ISR is 3.
PartitionChangeBuilder builder = new PartitionChangeBuilder ( partition , topicId , 0 , r - > r ! = 3 , metadataVersionForPartitionChangeRecordVersion ( version ) , 3 )
. setElection ( Election . PREFERRED )
. setEligibleLeaderReplicasEnabled ( isElrEnabled ( version ) ) ;
builder . setTargetIsrWithBrokerStates ( AlterPartitionRequest . newIsrToSimpleNewIsrWithBrokerEpochs ( Arrays . asList ( 1 , 4 ) ) ) ;
PartitionChangeRecord record = new PartitionChangeRecord ( )
. setTopicId ( topicId )
. setPartitionId ( 0 )
. setIsr ( Arrays . asList ( 1 , 4 ) )
. setLeader ( - 2 )
. setLeaderRecoveryState ( LeaderRecoveryState . NO_CHANGE ) ;
if ( version = = 0 ) {
record . setEligibleLeaderReplicas ( Collections . emptyList ( ) ) ;
record . setLastKnownELR ( Collections . emptyList ( ) ) ;
}
// No change is expected to ELR/LastKnownELR.
ApiMessageAndVersion expectedRecord = new ApiMessageAndVersion (
record ,
version
) ;
assertEquals ( Optional . of ( expectedRecord ) , builder . build ( ) ) ;
partition = partition . merge ( ( PartitionChangeRecord ) builder . build ( ) . get ( ) . message ( ) ) ;
if ( version > 0 ) {
assertTrue ( Arrays . equals ( new int [ ] { 3 } , partition . elr ) , partition . toString ( ) ) ;
assertTrue ( Arrays . equals ( new int [ ] { 2 } , partition . lastKnownElr ) , partition . toString ( ) ) ;
} else {
assertTrue ( Arrays . equals ( new int [ ] { } , partition . elr ) , partition . toString ( ) ) ;
assertTrue ( Arrays . equals ( new int [ ] { } , partition . lastKnownElr ) , partition . toString ( ) ) ;
}
}
@ParameterizedTest
@MethodSource ( "partitionChangeRecordVersions" )
public void testEligibleLeaderReplicas_RemoveUncleanShutdownReplicasFromElr ( short version ) {
PartitionRegistration partition = new PartitionRegistration . Builder ( )
. setReplicas ( new int [ ] { 1 , 2 , 3 , 4 } )
. setIsr ( new int [ ] { 1 } )
. setElr ( new int [ ] { 2 , 3 } )
. setLastKnownElr ( new int [ ] { } )
. setLeader ( 1 )
. setLeaderRecoveryState ( LeaderRecoveryState . RECOVERED )
. setLeaderEpoch ( 100 )
. setPartitionEpoch ( 200 )
. build ( ) ;
Uuid topicId = Uuid . fromString ( "FbrrdcfiR-KC2CPSTHaJrg" ) ;
// Min ISR is 3.
PartitionChangeBuilder builder = new PartitionChangeBuilder ( partition , topicId , 0 , r - > r ! = 3 , metadataVersionForPartitionChangeRecordVersion ( version ) , 3 )
. setElection ( Election . PREFERRED )
. setEligibleLeaderReplicasEnabled ( isElrEnabled ( version ) ) ;
builder . setUncleanShutdownReplicas ( Arrays . asList ( 3 ) ) ;
PartitionChangeRecord record = new PartitionChangeRecord ( )
. setTopicId ( topicId )
. setPartitionId ( 0 )
. setLeader ( - 2 )
. setLeaderRecoveryState ( LeaderRecoveryState . NO_CHANGE ) ;
if ( version > 0 ) {
record . setEligibleLeaderReplicas ( Arrays . asList ( 2 ) )
. setLastKnownELR ( Arrays . asList ( 3 ) ) ;
} else {
record . setEligibleLeaderReplicas ( Collections . emptyList ( ) ) ;
}
ApiMessageAndVersion expectedRecord = new ApiMessageAndVersion (
record ,
version
) ;
assertEquals ( Optional . of ( expectedRecord ) , builder . build ( ) ) ;
partition = partition . merge ( ( PartitionChangeRecord ) builder . build ( ) . get ( ) . message ( ) ) ;
if ( version > 0 ) {
assertTrue ( Arrays . equals ( new int [ ] { 2 } , partition . elr ) , partition . toString ( ) ) ;
assertTrue ( Arrays . equals ( new int [ ] { 3 } , partition . lastKnownElr ) , partition . toString ( ) ) ;
} else {
assertTrue ( Arrays . equals ( new int [ ] { } , partition . elr ) , partition . toString ( ) ) ;
assertTrue ( Arrays . equals ( new int [ ] { } , partition . lastKnownElr ) , partition . toString ( ) ) ;
}
}
}
}