From dee8020d92e6bff562cef723dcacdea714b89982 Mon Sep 17 00:00:00 2001 From: "sojung.kim" Date: Fri, 12 Jul 2024 19:59:35 +0900 Subject: [PATCH] [#2341] Initialize slots with empty BitSet in RedisClusterNode's constructors (#2852) * fix(#2341): Initialize slots with empty BitSet in RedisClusterNode's constructors * test(#2341): Add test cases for slot initialization in RedisClusterNode constructors * fix(redis#2341): Initialize RedisClusterNode slots with SlotHash.SLOT_COUNT * chore(redis#2341): Adjust the formatting * test(redis#2341):Add test cases for hasSameSlotsAs() * fix(#2341): Clone node2 from node1 using the RedisClusterNode constructor and compare the two clusters with hasSameSlotsAs() --- .../models/partitions/RedisClusterNode.java | 12 ++- .../partitions/RedisClusterNodeUnitTests.java | 85 +++++++++++++++++++ 2 files changed, 93 insertions(+), 4 deletions(-) diff --git a/src/main/java/io/lettuce/core/cluster/models/partitions/RedisClusterNode.java b/src/main/java/io/lettuce/core/cluster/models/partitions/RedisClusterNode.java index e1cef2fdce..7645281c24 100644 --- a/src/main/java/io/lettuce/core/cluster/models/partitions/RedisClusterNode.java +++ b/src/main/java/io/lettuce/core/cluster/models/partitions/RedisClusterNode.java @@ -103,8 +103,11 @@ public RedisClusterNode(RedisURI uri, String nodeId, boolean connected, String s this.configEpoch = configEpoch; this.replOffset = -1; - this.slots = new BitSet(slots.length()); - this.slots.or(slots); + this.slots = new BitSet(SlotHash.SLOT_COUNT); + + if (slots != null) { + this.slots.or(slots); + } setFlags(flags); } @@ -123,8 +126,9 @@ public RedisClusterNode(RedisClusterNode redisClusterNode) { this.replOffset = redisClusterNode.replOffset; this.aliases.addAll(redisClusterNode.aliases); - if (redisClusterNode.slots != null && !redisClusterNode.slots.isEmpty()) { - this.slots = new BitSet(SlotHash.SLOT_COUNT); + this.slots = new BitSet(SlotHash.SLOT_COUNT); + + if (redisClusterNode.slots != null) { this.slots.or(redisClusterNode.slots); } diff --git a/src/test/java/io/lettuce/core/cluster/models/partitions/RedisClusterNodeUnitTests.java b/src/test/java/io/lettuce/core/cluster/models/partitions/RedisClusterNodeUnitTests.java index 4c0d02fc53..8c9ed71688 100644 --- a/src/test/java/io/lettuce/core/cluster/models/partitions/RedisClusterNodeUnitTests.java +++ b/src/test/java/io/lettuce/core/cluster/models/partitions/RedisClusterNodeUnitTests.java @@ -3,6 +3,9 @@ import static org.assertj.core.api.Assertions.*; import java.util.Arrays; +import java.util.BitSet; +import java.util.Collections; +import java.util.HashSet; import org.junit.jupiter.api.Test; @@ -16,6 +19,88 @@ */ class RedisClusterNodeUnitTests { + @Test + void shouldCreateNodeWithEmptySlots() { + + BitSet slots = new BitSet(); + RedisClusterNode node = new RedisClusterNode(RedisURI.create("localhost", 6379), "1", true, null, 0, 0, 0, slots, + Collections.emptySet()); + + assertThat(node.getSlots()).isEmpty(); + assertThat(node.getSlots()).isNotNull(); + } + + @Test + void shouldCreateNodeWithNonEmptySlots() { + + BitSet slots = new BitSet(); + slots.set(1); + slots.set(2); + RedisClusterNode node = new RedisClusterNode(RedisURI.create("localhost", 6379), "1", true, null, 0, 0, 0, slots, + Collections.emptySet()); + + assertThat(node.getSlots()).containsExactly(1, 2); + } + + @Test + void shouldCopyNodeWithEmptySlots() { + + BitSet slots = new BitSet(); + RedisClusterNode originalNode = new RedisClusterNode(RedisURI.create("localhost", 6379), "1", true, null, 0, 0, 0, + slots, Collections.emptySet()); + + RedisClusterNode copiedNode = new RedisClusterNode(originalNode); + + assertThat(copiedNode.getSlots()).isEmpty(); + assertThat(copiedNode.getSlots()).isNotNull(); + } + + @Test + void shouldCopyNodeWithNonEmptySlots() { + + BitSet slots = new BitSet(); + slots.set(1); + slots.set(2); + RedisClusterNode originalNode = new RedisClusterNode(RedisURI.create("localhost", 6379), "1", true, null, 0, 0, 0, + slots, Collections.emptySet()); + + RedisClusterNode copiedNode = new RedisClusterNode(originalNode); + + assertThat(copiedNode.getSlots()).containsExactly(1, 2); + } + + @Test + public void testHasSameSlotsAs() { + + BitSet emptySlots = new BitSet(SlotHash.SLOT_COUNT); + emptySlots.set(1); + emptySlots.set(2); + + RedisClusterNode node1 = new RedisClusterNode(RedisURI.create("localhost", 6379), "nodeId1", true, "slaveOf", 0L, 0L, + 0L, emptySlots, new HashSet<>()); + + RedisClusterNode node2 = new RedisClusterNode(node1); + + assertThat(node1.hasSameSlotsAs(node2)).isTrue(); + } + + @Test + public void testHasDifferentSlotsAs() { + + BitSet slots1 = new BitSet(SlotHash.SLOT_COUNT); + slots1.set(1); + + BitSet slots2 = new BitSet(SlotHash.SLOT_COUNT); + slots2.set(2); + + RedisClusterNode node1 = new RedisClusterNode(RedisURI.create("localhost", 6379), "nodeId1", true, "slaveOf", 0L, 0L, + 0L, slots1, new HashSet<>()); + RedisClusterNode node2 = new RedisClusterNode(RedisURI.create("localhost", 6379), "nodeId2", true, "slaveOf", 0L, 0L, + 0L, slots2, new HashSet<>()); + + assertThat(node1.hasSameSlotsAs(node2)).isFalse(); + } + @Test void shouldCopyNode() {