@@ -812,3 +812,92 @@ pub(crate) mod test_support {
812812 . expect ( "validate should succeed for the test fixture" )
813813 }
814814}
815+
816+ #[ cfg( test) ]
817+ mod tests {
818+ use std:: collections:: BTreeSet ;
819+
820+ use super :: {
821+ PodDescriptorsError ,
822+ test_support:: { minimal_kafka, validated_cluster} ,
823+ } ;
824+ use crate :: crd:: role:: KafkaRole ;
825+
826+ /// Two broker role groups whose names hash to the same node-id offset must be
827+ /// rejected: a collision would hand two pods the same Kafka `node.id`. `rg865`
828+ /// and `rg1400` are a known colliding pair for the `broker` role (see
829+ /// [`node_id_hash32_offset`](super::node_id_hasher::node_id_hash32_offset)).
830+ #[ test]
831+ fn pod_descriptors_rejects_node_id_hash_collision ( ) {
832+ let kafka = minimal_kafka (
833+ r#"
834+ apiVersion: kafka.stackable.tech/v1alpha1
835+ kind: KafkaCluster
836+ metadata:
837+ name: simple-kafka
838+ namespace: default
839+ uid: 12345678-1234-1234-1234-123456789012
840+ spec:
841+ image:
842+ productVersion: 3.9.2
843+ clusterConfig:
844+ zookeeperConfigMapName: xyz
845+ brokers:
846+ roleGroups:
847+ rg865:
848+ replicas: 1
849+ rg1400:
850+ replicas: 1
851+ "# ,
852+ ) ;
853+ let validated = validated_cluster ( & kafka) ;
854+
855+ match validated. pod_descriptors ( None ) {
856+ Err ( PodDescriptorsError :: KafkaNodeIdHashCollision {
857+ role,
858+ colliding_role,
859+ ..
860+ } ) => {
861+ assert_eq ! ( role, KafkaRole :: Broker ) ;
862+ assert_eq ! ( colliding_role, KafkaRole :: Broker ) ;
863+ }
864+ other => panic ! ( "expected a node-id hash collision error, got {other:?}" ) ,
865+ }
866+ }
867+
868+ /// Non-colliding role groups expand to one descriptor per replica, each with a
869+ /// unique `node_id`.
870+ #[ test]
871+ fn pod_descriptors_assigns_unique_node_ids ( ) {
872+ let kafka = minimal_kafka (
873+ r#"
874+ apiVersion: kafka.stackable.tech/v1alpha1
875+ kind: KafkaCluster
876+ metadata:
877+ name: simple-kafka
878+ namespace: default
879+ uid: 12345678-1234-1234-1234-123456789012
880+ spec:
881+ image:
882+ productVersion: 3.9.2
883+ clusterConfig:
884+ zookeeperConfigMapName: xyz
885+ brokers:
886+ roleGroups:
887+ default:
888+ replicas: 2
889+ other:
890+ replicas: 1
891+ "# ,
892+ ) ;
893+ let validated = validated_cluster ( & kafka) ;
894+
895+ let descriptors = validated
896+ . pod_descriptors ( None )
897+ . expect ( "non-colliding role groups must not error" ) ;
898+
899+ assert_eq ! ( descriptors. len( ) , 3 ) ;
900+ let node_ids: BTreeSet < u32 > = descriptors. iter ( ) . map ( |d| d. node_id ) . collect ( ) ;
901+ assert_eq ! ( node_ids. len( ) , 3 , "node ids must be unique: {node_ids:?}" ) ;
902+ }
903+ }
0 commit comments