This is an automated email from the ASF dual-hosted git repository. cmccabe pushed a commit to branch 3.3 in repository https://gitbox.apache.org/repos/asf/kafka.git
The following commit(s) were added to refs/heads/3.3 by this push: new df30d95a5d2 MINOR: Fix PartitionRegistration.hashCode (#12774) df30d95a5d2 is described below commit df30d95a5d2218f8700d225851e22af784845fee Author: Jason Gustafson <ja...@confluent.io> AuthorDate: Thu Oct 20 14:01:01 2022 -0700 MINOR: Fix PartitionRegistration.hashCode (#12774) `PartitionRegistration.hashCode` passes raw arrays to `Objects.hash` in the `hashCode` implementation. This doesn't work since the `equals` implementation uses `Arrays.equals`. We should use `Arrays.hashCode` instead. Reviewers: David Arthur <mum...@gmail.com> --- .../kafka/metadata/PartitionRegistration.java | 4 +- .../kafka/metadata/PartitionRegistrationTest.java | 45 ++++++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/metadata/src/main/java/org/apache/kafka/metadata/PartitionRegistration.java b/metadata/src/main/java/org/apache/kafka/metadata/PartitionRegistration.java index 1c42bd07c8e..afd03ab2f03 100644 --- a/metadata/src/main/java/org/apache/kafka/metadata/PartitionRegistration.java +++ b/metadata/src/main/java/org/apache/kafka/metadata/PartitionRegistration.java @@ -211,8 +211,8 @@ public class PartitionRegistration { @Override public int hashCode() { - return Objects.hash(replicas, isr, removingReplicas, addingReplicas, leader, leaderRecoveryState, - leaderEpoch, partitionEpoch); + return Objects.hash(Arrays.hashCode(replicas), Arrays.hashCode(isr), Arrays.hashCode(removingReplicas), + Arrays.hashCode(addingReplicas), leader, leaderRecoveryState, leaderEpoch, partitionEpoch); } @Override diff --git a/metadata/src/test/java/org/apache/kafka/metadata/PartitionRegistrationTest.java b/metadata/src/test/java/org/apache/kafka/metadata/PartitionRegistrationTest.java index 66bf3fe0333..fa19149a3f5 100644 --- a/metadata/src/test/java/org/apache/kafka/metadata/PartitionRegistrationTest.java +++ b/metadata/src/test/java/org/apache/kafka/metadata/PartitionRegistrationTest.java @@ -17,6 +17,11 @@ package org.apache.kafka.metadata; +import net.jqwik.api.Arbitraries; +import net.jqwik.api.Arbitrary; +import net.jqwik.api.ForAll; +import net.jqwik.api.Property; +import net.jqwik.api.Provide; import org.apache.kafka.common.TopicPartition; import org.apache.kafka.common.Uuid; import org.apache.kafka.common.message.LeaderAndIsrRequestData.LeaderAndIsrPartitionState; @@ -31,6 +36,7 @@ import java.util.Collections; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -125,4 +131,43 @@ public class PartitionRegistrationTest { new int[] {1, 2, 4}, Replicas.NONE, Replicas.NONE, 1, LeaderRecoveryState.RECOVERED, 100, 202), partition2); assertFalse(partition2.isReassigning()); } + + @Property + public void testConsistentEqualsAndHashCode( + @ForAll("uniqueSamples") PartitionRegistration a, + @ForAll("uniqueSamples") PartitionRegistration b + ) { + if (a.equals(b)) { + assertEquals(a.hashCode(), b.hashCode()); + } + + if (a.hashCode() != b.hashCode()) { + assertNotEquals(a, b); + } + } + + @Provide + Arbitrary<PartitionRegistration> uniqueSamples() { + return Arbitraries.of( + new PartitionRegistration(new int[] {1, 2, 3}, new int[] {1, 2, 3}, Replicas.NONE, Replicas.NONE, + 1, LeaderRecoveryState.RECOVERED, 100, 200), + new PartitionRegistration(new int[] {1, 2, 3}, new int[] {1, 2, 3}, Replicas.NONE, Replicas.NONE, + 1, LeaderRecoveryState.RECOVERED, 101, 200), + new PartitionRegistration(new int[] {1, 2, 3}, new int[] {1, 2, 3}, Replicas.NONE, Replicas.NONE, + 1, LeaderRecoveryState.RECOVERED, 100, 201), + new PartitionRegistration(new int[] {1, 2, 3}, new int[] {1, 2, 3}, Replicas.NONE, Replicas.NONE, + 2, LeaderRecoveryState.RECOVERED, 100, 200), + new PartitionRegistration(new int[] {1, 2, 3}, new int[] {1}, Replicas.NONE, Replicas.NONE, + 1, LeaderRecoveryState.RECOVERING, 100, 200), + new PartitionRegistration(new int[] {1, 2, 3, 4, 5, 6}, new int[] {1, 2, 3}, new int[] {4, 5, 6}, new int[] {1, 2, 3}, + 1, LeaderRecoveryState.RECOVERED, 100, 200), + new PartitionRegistration(new int[] {1, 2, 3, 4, 5, 6}, new int[] {1, 2, 3}, new int[] {1, 2, 3}, new int[] {4, 5, 6}, + 1, LeaderRecoveryState.RECOVERED, 100, 200), + new PartitionRegistration(new int[] {1, 2, 3, 4, 5, 6}, new int[] {1, 2, 3}, new int[] {1, 2, 3}, Replicas.NONE, + 1, LeaderRecoveryState.RECOVERED, 100, 200), + new PartitionRegistration(new int[] {1, 2, 3, 4, 5, 6}, new int[] {1, 2, 3}, Replicas.NONE, new int[] {4, 5, 6}, + 1, LeaderRecoveryState.RECOVERED, 100, 200) + ); + } + }