function) {
+
+ if (keys.length == 0) {
+ throw new IllegalArgumentException("Keys array must contain at least one element");
+ }
+
+ T firstKey = keys[0];
+ T[] otherKeys = Arrays.copyOfRange(keys, 1, keys.length);
+ return function.apply(firstKey, otherKeys);
+ }
+
+ /**
+ * Represents a function that accepts two arguments of the same base type and produces a result while the second
+ * argument is an array of {@code T}. This is similar to a {@link java.util.function.BiFunction} but restricts both
+ * arguments to be of the same type. Typically used in arrangements where a composite collection of keys is split into
+ * the first key and the remaining keys.
+ *
+ * This is a functional interface whose functional method is
+ * {@link #apply(Object, Object)}.
+ *
+ * @param the type of the first argument to the function.
+ * @param the type of the result of the function.
+ */
+ public interface SourceKeysFunction {
+
+ /**
+ * Applies this function to the given arguments.
+ *
+ * @param firstKey the first key argument.
+ * @param otherKeys the other keys function argument.
+ * @return the function result.
+ */
+ R apply(T firstKey, T[] otherKeys);
+
+ }
+
+ // utility constructor
+ private KeyUtils() {
+
+ }
+
+}
diff --git a/src/test/java/org/springframework/data/redis/connection/AbstractConnectionIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/AbstractConnectionIntegrationTests.java
index d09bb78ddf..5493467b40 100644
--- a/src/test/java/org/springframework/data/redis/connection/AbstractConnectionIntegrationTests.java
+++ b/src/test/java/org/springframework/data/redis/connection/AbstractConnectionIntegrationTests.java
@@ -117,6 +117,7 @@
* @author Roman Osadchuk
* @author Tihomir Mateev
* @author Jeonggyu Choi
+ * @author Viktoriya Kutsarova
*/
public abstract class AbstractConnectionIntegrationTests {
@@ -571,6 +572,42 @@ void testBitOpNotMultipleSources() {
.isThrownBy(() -> connection.bitOp(BitOperation.NOT, "key3", "key1", "key2"));
}
+ @Test // GH-3250
+ void testBitOpDiff() {
+
+ actual.add(connection.set("key1", "foobar"));
+ actual.add(connection.set("key2", "abcdef"));
+ actual.add(connection.bitOp(BitOperation.DIFF, "key3", "key1", "key2"));
+ verifyResults(Arrays.asList(Boolean.TRUE, Boolean.TRUE, 6L));
+ }
+
+ @Test // GH-3250
+ void testBitOpDiff1() {
+
+ actual.add(connection.set("key1", "foobar"));
+ actual.add(connection.set("key2", "abcdef"));
+ actual.add(connection.bitOp(BitOperation.DIFF1, "key3", "key1", "key2"));
+ verifyResults(Arrays.asList(Boolean.TRUE, Boolean.TRUE, 6L));
+ }
+
+ @Test // GH-3250
+ void testBitOpAndor() {
+
+ actual.add(connection.set("key1", "foo"));
+ actual.add(connection.set("key2", "bar"));
+ actual.add(connection.bitOp(BitOperation.ANDOR, "key3", "key1", "key2"));
+ verifyResults(Arrays.asList(Boolean.TRUE, Boolean.TRUE, 3L));
+ }
+
+ @Test // GH-3250
+ void testBitOpOne() {
+
+ actual.add(connection.set("key1", "foo"));
+ actual.add(connection.set("key2", "bar"));
+ actual.add(connection.bitOp(BitOperation.ONE, "key3", "key1", "key2"));
+ verifyResults(Arrays.asList(Boolean.TRUE, Boolean.TRUE, 3L));
+ }
+
@Test
@EnabledOnCommand("COPY")
void testCopy() {
diff --git a/src/test/java/org/springframework/data/redis/connection/DefaultStringRedisConnectionPipelineTests.java b/src/test/java/org/springframework/data/redis/connection/DefaultStringRedisConnectionPipelineTests.java
index 0d977e00fa..bf3e962eb7 100644
--- a/src/test/java/org/springframework/data/redis/connection/DefaultStringRedisConnectionPipelineTests.java
+++ b/src/test/java/org/springframework/data/redis/connection/DefaultStringRedisConnectionPipelineTests.java
@@ -38,6 +38,7 @@
* @author Ninad Divadkar
* @author Mark Paluch
* @author dengliming
+ * @author Viktoriya Kutsarova
*/
public class DefaultStringRedisConnectionPipelineTests extends DefaultStringRedisConnectionTests {
@@ -1010,6 +1011,90 @@ public void testBitOp() {
super.testBitOp();
}
+ @Test // GH-3250
+ public void testBitOpOrBytes() {
+ doReturn(Collections.singletonList(5L)).when(nativeConnection).closePipeline();
+ super.testBitOpOrBytes();
+ }
+
+ @Test // GH-3250
+ public void testBitOpOr() {
+ doReturn(Collections.singletonList(5L)).when(nativeConnection).closePipeline();
+ super.testBitOpOr();
+ }
+
+ @Test // GH-3250
+ public void testBitOpXorBytes() {
+ doReturn(Collections.singletonList(5L)).when(nativeConnection).closePipeline();
+ super.testBitOpXorBytes();
+ }
+
+ @Test // GH-3250
+ public void testBitOpXor() {
+ doReturn(Collections.singletonList(5L)).when(nativeConnection).closePipeline();
+ super.testBitOpXor();
+ }
+
+ @Test // GH-3250
+ public void testBitOpNotBytes() {
+ doReturn(Collections.singletonList(5L)).when(nativeConnection).closePipeline();
+ super.testBitOpNotBytes();
+ }
+
+ @Test // GH-3250
+ public void testBitOpNot() {
+ doReturn(Collections.singletonList(5L)).when(nativeConnection).closePipeline();
+ super.testBitOpNot();
+ }
+
+ @Test // GH-3250
+ public void testBitOpDiffBytes() {
+ doReturn(Collections.singletonList(5L)).when(nativeConnection).closePipeline();
+ super.testBitOpDiffBytes();
+ }
+
+ @Test // GH-3250
+ public void testBitOpDiff() {
+ doReturn(Collections.singletonList(5L)).when(nativeConnection).closePipeline();
+ super.testBitOpDiff();
+ }
+
+ @Test // GH-3250
+ public void testBitOpDiff1Bytes() {
+ doReturn(Collections.singletonList(5L)).when(nativeConnection).closePipeline();
+ super.testBitOpDiff1Bytes();
+ }
+
+ @Test // GH-3250
+ public void testBitOpDiff1() {
+ doReturn(Collections.singletonList(5L)).when(nativeConnection).closePipeline();
+ super.testBitOpDiff1();
+ }
+
+ @Test // GH-3250
+ public void testBitOpAndorBytes() {
+ doReturn(Collections.singletonList(5L)).when(nativeConnection).closePipeline();
+ super.testBitOpAndorBytes();
+ }
+
+ @Test // GH-3250
+ public void testBitOpAndor() {
+ doReturn(Collections.singletonList(5L)).when(nativeConnection).closePipeline();
+ super.testBitOpAndor();
+ }
+
+ @Test // GH-3250
+ public void testBitOpOneBytes() {
+ doReturn(Collections.singletonList(5L)).when(nativeConnection).closePipeline();
+ super.testBitOpOneBytes();
+ }
+
+ @Test // GH-3250
+ public void testBitOpOne() {
+ doReturn(Collections.singletonList(5L)).when(nativeConnection).closePipeline();
+ super.testBitOpOne();
+ }
+
@Test
public void testSUnionBytes() {
doReturn(Collections.singletonList(bytesSet)).when(nativeConnection).closePipeline();
diff --git a/src/test/java/org/springframework/data/redis/connection/DefaultStringRedisConnectionPipelineTxTests.java b/src/test/java/org/springframework/data/redis/connection/DefaultStringRedisConnectionPipelineTxTests.java
index 6ad92f531b..a0fb3f2faf 100644
--- a/src/test/java/org/springframework/data/redis/connection/DefaultStringRedisConnectionPipelineTxTests.java
+++ b/src/test/java/org/springframework/data/redis/connection/DefaultStringRedisConnectionPipelineTxTests.java
@@ -37,6 +37,7 @@
* @author Ninad Divadkar
* @author Mark Paluch
* @author dengliming
+ * @author Viktoriya Kutsarova
*/
public class DefaultStringRedisConnectionPipelineTxTests extends DefaultStringRedisConnectionTxTests {
@@ -1025,6 +1026,90 @@ public void testBitOp() {
super.testBitOp();
}
+ @Test // GH-3250
+ public void testBitOpOrBytes() {
+ doReturn(Collections.singletonList(Collections.singletonList(5L))).when(nativeConnection).closePipeline();
+ super.testBitOpOrBytes();
+ }
+
+ @Test // GH-3250
+ public void testBitOpOr() {
+ doReturn(Collections.singletonList(Collections.singletonList(5L))).when(nativeConnection).closePipeline();
+ super.testBitOpOr();
+ }
+
+ @Test // GH-3250
+ public void testBitOpXorBytes() {
+ doReturn(Collections.singletonList(Collections.singletonList(5L))).when(nativeConnection).closePipeline();
+ super.testBitOpXorBytes();
+ }
+
+ @Test // GH-3250
+ public void testBitOpXor() {
+ doReturn(Collections.singletonList(Collections.singletonList(5L))).when(nativeConnection).closePipeline();
+ super.testBitOpXor();
+ }
+
+ @Test // GH-3250
+ public void testBitOpNotBytes() {
+ doReturn(Collections.singletonList(Collections.singletonList(5L))).when(nativeConnection).closePipeline();
+ super.testBitOpNotBytes();
+ }
+
+ @Test // GH-3250
+ public void testBitOpNot() {
+ doReturn(Collections.singletonList(Collections.singletonList(5L))).when(nativeConnection).closePipeline();
+ super.testBitOpNot();
+ }
+
+ @Test // GH-3250
+ public void testBitOpDiffBytes() {
+ doReturn(Collections.singletonList(Collections.singletonList(5L))).when(nativeConnection).closePipeline();
+ super.testBitOpDiffBytes();
+ }
+
+ @Test // GH-3250
+ public void testBitOpDiff() {
+ doReturn(Collections.singletonList(Collections.singletonList(5L))).when(nativeConnection).closePipeline();
+ super.testBitOpDiff();
+ }
+
+ @Test // GH-3250
+ public void testBitOpDiff1Bytes() {
+ doReturn(Collections.singletonList(Collections.singletonList(5L))).when(nativeConnection).closePipeline();
+ super.testBitOpDiff1Bytes();
+ }
+
+ @Test // GH-3250
+ public void testBitOpDiff1() {
+ doReturn(Collections.singletonList(Collections.singletonList(5L))).when(nativeConnection).closePipeline();
+ super.testBitOpDiff1();
+ }
+
+ @Test // GH-3250
+ public void testBitOpAndorBytes() {
+ doReturn(Collections.singletonList(Collections.singletonList(5L))).when(nativeConnection).closePipeline();
+ super.testBitOpAndorBytes();
+ }
+
+ @Test // GH-3250
+ public void testBitOpAndor() {
+ doReturn(Collections.singletonList(Collections.singletonList(5L))).when(nativeConnection).closePipeline();
+ super.testBitOpAndor();
+ }
+
+ @Test // GH-3250
+ public void testBitOpOneBytes() {
+ doReturn(Collections.singletonList(Collections.singletonList(5L))).when(nativeConnection).closePipeline();
+ super.testBitOpOneBytes();
+ }
+
+ @Test // GH-3250
+ public void testBitOpOne() {
+ doReturn(Collections.singletonList(Collections.singletonList(5L))).when(nativeConnection).closePipeline();
+ super.testBitOpOne();
+ }
+
@Test
public void testSUnionBytes() {
doReturn(Collections.singletonList(Collections.singletonList(bytesSet))).when(nativeConnection).closePipeline();
diff --git a/src/test/java/org/springframework/data/redis/connection/DefaultStringRedisConnectionTests.java b/src/test/java/org/springframework/data/redis/connection/DefaultStringRedisConnectionTests.java
index e57589012a..20947d6c63 100644
--- a/src/test/java/org/springframework/data/redis/connection/DefaultStringRedisConnectionTests.java
+++ b/src/test/java/org/springframework/data/redis/connection/DefaultStringRedisConnectionTests.java
@@ -78,6 +78,7 @@
* @author Mark Paluch
* @author dengliming
* @author ihaohong
+ * @author Viktoriya Kutsarova
*/
@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
@@ -1266,6 +1267,104 @@ public void testBitOp() {
verifyResults(Collections.singletonList(5L));
}
+ @Test
+ public void testBitOpOrBytes() {
+ doReturn(5L).when(nativeConnection).bitOp(BitOperation.OR, fooBytes, barBytes);
+ actual.add(connection.bitOp(BitOperation.OR, fooBytes, barBytes));
+ verifyResults(Collections.singletonList(5L));
+ }
+
+ @Test
+ public void testBitOpOr() {
+ doReturn(5L).when(nativeConnection).bitOp(BitOperation.OR, fooBytes, barBytes);
+ actual.add(connection.bitOp(BitOperation.OR, foo, bar));
+ verifyResults(Collections.singletonList(5L));
+ }
+
+ @Test
+ public void testBitOpXorBytes() {
+ doReturn(5L).when(nativeConnection).bitOp(BitOperation.XOR, fooBytes, barBytes);
+ actual.add(connection.bitOp(BitOperation.XOR, fooBytes, barBytes));
+ verifyResults(Collections.singletonList(5L));
+ }
+
+ @Test
+ public void testBitOpXor() {
+ doReturn(5L).when(nativeConnection).bitOp(BitOperation.XOR, fooBytes, barBytes);
+ actual.add(connection.bitOp(BitOperation.XOR, foo, bar));
+ verifyResults(Collections.singletonList(5L));
+ }
+
+ @Test
+ public void testBitOpNotBytes() {
+ doReturn(5L).when(nativeConnection).bitOp(BitOperation.NOT, fooBytes, barBytes);
+ actual.add(connection.bitOp(BitOperation.NOT, fooBytes, barBytes));
+ verifyResults(Collections.singletonList(5L));
+ }
+
+ @Test
+ public void testBitOpNot() {
+ doReturn(5L).when(nativeConnection).bitOp(BitOperation.NOT, fooBytes, barBytes);
+ actual.add(connection.bitOp(BitOperation.NOT, foo, bar));
+ verifyResults(Collections.singletonList(5L));
+ }
+
+ @Test // GH-3250
+ public void testBitOpDiffBytes() {
+ doReturn(5L).when(nativeConnection).bitOp(BitOperation.DIFF, fooBytes, barBytes);
+ actual.add(connection.bitOp(BitOperation.DIFF, fooBytes, barBytes));
+ verifyResults(Collections.singletonList(5L));
+ }
+
+ @Test // GH-3250
+ public void testBitOpDiff() {
+ doReturn(5L).when(nativeConnection).bitOp(BitOperation.DIFF, fooBytes, barBytes);
+ actual.add(connection.bitOp(BitOperation.DIFF, foo, bar));
+ verifyResults(Collections.singletonList(5L));
+ }
+
+ @Test // GH-3250
+ public void testBitOpDiff1Bytes() {
+ doReturn(5L).when(nativeConnection).bitOp(BitOperation.DIFF1, fooBytes, barBytes);
+ actual.add(connection.bitOp(BitOperation.DIFF1, fooBytes, barBytes));
+ verifyResults(Collections.singletonList(5L));
+ }
+
+ @Test // GH-3250
+ public void testBitOpDiff1() {
+ doReturn(5L).when(nativeConnection).bitOp(BitOperation.DIFF1, fooBytes, barBytes);
+ actual.add(connection.bitOp(BitOperation.DIFF1, foo, bar));
+ verifyResults(Collections.singletonList(5L));
+ }
+
+ @Test // GH-3250
+ public void testBitOpAndorBytes() {
+ doReturn(5L).when(nativeConnection).bitOp(BitOperation.ANDOR, fooBytes, barBytes);
+ actual.add(connection.bitOp(BitOperation.ANDOR, fooBytes, barBytes));
+ verifyResults(Collections.singletonList(5L));
+ }
+
+ @Test // GH-3250
+ public void testBitOpAndor() {
+ doReturn(5L).when(nativeConnection).bitOp(BitOperation.ANDOR, fooBytes, barBytes);
+ actual.add(connection.bitOp(BitOperation.ANDOR, foo, bar));
+ verifyResults(Collections.singletonList(5L));
+ }
+
+ @Test // GH-3250
+ public void testBitOpOneBytes() {
+ doReturn(5L).when(nativeConnection).bitOp(BitOperation.ONE, fooBytes, barBytes);
+ actual.add(connection.bitOp(BitOperation.ONE, fooBytes, barBytes));
+ verifyResults(Collections.singletonList(5L));
+ }
+
+ @Test // GH-3250
+ public void testBitOpOne() {
+ doReturn(5L).when(nativeConnection).bitOp(BitOperation.ONE, fooBytes, barBytes);
+ actual.add(connection.bitOp(BitOperation.ONE, foo, bar));
+ verifyResults(Collections.singletonList(5L));
+ }
+
@Test
public void testSUnionBytes() {
doReturn(bytesSet).when(nativeConnection).sUnion(fooBytes, barBytes);
diff --git a/src/test/java/org/springframework/data/redis/connection/DefaultStringRedisConnectionTxTests.java b/src/test/java/org/springframework/data/redis/connection/DefaultStringRedisConnectionTxTests.java
index 0e8fa6c1fb..051d391478 100644
--- a/src/test/java/org/springframework/data/redis/connection/DefaultStringRedisConnectionTxTests.java
+++ b/src/test/java/org/springframework/data/redis/connection/DefaultStringRedisConnectionTxTests.java
@@ -34,6 +34,7 @@
* @author Jennifer Hickey
* @author Christoph Strobl
* @author Ninad Divadkar
+ * @author Viktoriya Kutsarova
*/
public class DefaultStringRedisConnectionTxTests extends DefaultStringRedisConnectionTests {
@@ -995,6 +996,90 @@ public void testBitOp() {
super.testBitOp();
}
+ @Test // GH-3250
+ public void testBitOpOrBytes() {
+ doReturn(Collections.singletonList(5L)).when(nativeConnection).exec();
+ super.testBitOpOrBytes();
+ }
+
+ @Test // GH-3250
+ public void testBitOpOr() {
+ doReturn(Collections.singletonList(5L)).when(nativeConnection).exec();
+ super.testBitOpOr();
+ }
+
+ @Test // GH-3250
+ public void testBitOpXorBytes() {
+ doReturn(Collections.singletonList(5L)).when(nativeConnection).exec();
+ super.testBitOpXorBytes();
+ }
+
+ @Test // GH-3250
+ public void testBitOpXor() {
+ doReturn(Collections.singletonList(5L)).when(nativeConnection).exec();
+ super.testBitOpXor();
+ }
+
+ @Test // GH-3250
+ public void testBitOpNotBytes() {
+ doReturn(Collections.singletonList(5L)).when(nativeConnection).exec();
+ super.testBitOpNotBytes();
+ }
+
+ @Test // GH-3250
+ public void testBitOpNot() {
+ doReturn(Collections.singletonList(5L)).when(nativeConnection).exec();
+ super.testBitOpNot();
+ }
+
+ @Test // GH-3250
+ public void testBitOpDiffBytes() {
+ doReturn(Collections.singletonList(5L)).when(nativeConnection).exec();
+ super.testBitOpDiffBytes();
+ }
+
+ @Test // GH-3250
+ public void testBitOpDiff() {
+ doReturn(Collections.singletonList(5L)).when(nativeConnection).exec();
+ super.testBitOpDiff();
+ }
+
+ @Test // GH-3250
+ public void testBitOpDiff1Bytes() {
+ doReturn(Collections.singletonList(5L)).when(nativeConnection).exec();
+ super.testBitOpDiff1Bytes();
+ }
+
+ @Test // GH-3250
+ public void testBitOpDiff1() {
+ doReturn(Collections.singletonList(5L)).when(nativeConnection).exec();
+ super.testBitOpDiff1();
+ }
+
+ @Test // GH-3250
+ public void testBitOpAndorBytes() {
+ doReturn(Collections.singletonList(5L)).when(nativeConnection).exec();
+ super.testBitOpAndorBytes();
+ }
+
+ @Test // GH-3250
+ public void testBitOpAndor() {
+ doReturn(Collections.singletonList(5L)).when(nativeConnection).exec();
+ super.testBitOpAndor();
+ }
+
+ @Test // GH-3250
+ public void testBitOpOneBytes() {
+ doReturn(Collections.singletonList(5L)).when(nativeConnection).exec();
+ super.testBitOpOneBytes();
+ }
+
+ @Test // GH-3250
+ public void testBitOpOne() {
+ doReturn(Collections.singletonList(5L)).when(nativeConnection).exec();
+ super.testBitOpOne();
+ }
+
@Test
public void testSUnionBytes() {
doReturn(Collections.singletonList(bytesSet)).when(nativeConnection).exec();
diff --git a/src/test/java/org/springframework/data/redis/connection/jedis/JedisClusterConnectionTests.java b/src/test/java/org/springframework/data/redis/connection/jedis/JedisClusterConnectionTests.java
index 08ee13c910..72beaa1321 100644
--- a/src/test/java/org/springframework/data/redis/connection/jedis/JedisClusterConnectionTests.java
+++ b/src/test/java/org/springframework/data/redis/connection/jedis/JedisClusterConnectionTests.java
@@ -78,6 +78,7 @@
* @author Pavel Khokhlov
* @author Dennis Neufeld
* @author Tihomir Mateev
+ * @author Viktoriya Kutsarova
*/
@EnabledOnRedisClusterAvailable
@ExtendWith(JedisExtension.class)
@@ -191,6 +192,82 @@ void bitOpShouldWorkCorrectly() {
assertThat(nativeConnection.get(SAME_SLOT_KEY_3)).isEqualTo("bab");
}
+ @Test // GH-3250
+ void bitOpOrShouldWorkCorrectly() {
+
+ nativeConnection.set(SAME_SLOT_KEY_1, "foo");
+ nativeConnection.set(SAME_SLOT_KEY_2, "ugh");
+
+ clusterConnection.bitOp(BitOperation.OR, SAME_SLOT_KEY_3_BYTES, SAME_SLOT_KEY_1_BYTES, SAME_SLOT_KEY_2_BYTES);
+
+ assertThat(nativeConnection.get(SAME_SLOT_KEY_3)).isEqualTo("woo");
+ }
+
+ @Test // GH-3250
+ void bitOpXorShouldWorkCorrectly() {
+
+ nativeConnection.set(SAME_SLOT_KEY_1, "aaa");
+ nativeConnection.set(SAME_SLOT_KEY_2, "___");
+
+ clusterConnection.bitOp(BitOperation.XOR, SAME_SLOT_KEY_3_BYTES, SAME_SLOT_KEY_1_BYTES, SAME_SLOT_KEY_2_BYTES);
+
+ assertThat(nativeConnection.get(SAME_SLOT_KEY_3)).isEqualTo(">>>");
+ }
+
+ @Test // GH-3250
+ void bitOpNotShouldWorkCorrectly() {
+
+ nativeConnection.set(SAME_SLOT_KEY_1, "foo");
+
+ clusterConnection.bitOp(BitOperation.NOT, SAME_SLOT_KEY_3_BYTES, SAME_SLOT_KEY_1_BYTES);
+
+ assertThat(nativeConnection.get(SAME_SLOT_KEY_3)).isNotNull();
+ }
+
+ @Test // GH-3250
+ void bitOpDiffShouldWorkCorrectly() {
+
+ nativeConnection.set(SAME_SLOT_KEY_1, "foobar");
+ nativeConnection.set(SAME_SLOT_KEY_2, "abcdef");
+
+ clusterConnection.bitOp(BitOperation.DIFF, SAME_SLOT_KEY_3_BYTES, SAME_SLOT_KEY_1_BYTES, SAME_SLOT_KEY_2_BYTES);
+
+ assertThat(nativeConnection.get(SAME_SLOT_KEY_3)).isNotNull();
+ }
+
+ @Test // GH-3250
+ void bitOpDiff1ShouldWorkCorrectly() {
+
+ nativeConnection.set(SAME_SLOT_KEY_1, "foobar");
+ nativeConnection.set(SAME_SLOT_KEY_2, "abcdef");
+
+ clusterConnection.bitOp(BitOperation.DIFF1, SAME_SLOT_KEY_3_BYTES, SAME_SLOT_KEY_1_BYTES, SAME_SLOT_KEY_2_BYTES);
+
+ assertThat(nativeConnection.get(SAME_SLOT_KEY_3)).isNotNull();
+ }
+
+ @Test // GH-3250
+ void bitOpAndorShouldWorkCorrectly() {
+
+ nativeConnection.set(SAME_SLOT_KEY_1, "foo");
+ nativeConnection.set(SAME_SLOT_KEY_2, "bar");
+
+ clusterConnection.bitOp(BitOperation.ANDOR, SAME_SLOT_KEY_3_BYTES, SAME_SLOT_KEY_1_BYTES, SAME_SLOT_KEY_2_BYTES);
+
+ assertThat(nativeConnection.get(SAME_SLOT_KEY_3)).isNotNull();
+ }
+
+ @Test // GH-3250
+ void bitOpOneShouldWorkCorrectly() {
+
+ nativeConnection.set(SAME_SLOT_KEY_1, "foo");
+ nativeConnection.set(SAME_SLOT_KEY_2, "bar");
+
+ clusterConnection.bitOp(BitOperation.ONE, SAME_SLOT_KEY_3_BYTES, SAME_SLOT_KEY_1_BYTES, SAME_SLOT_KEY_2_BYTES);
+
+ assertThat(nativeConnection.get(SAME_SLOT_KEY_3)).isNotNull();
+ }
+
@Test // DATAREDIS-315
public void blPopShouldPopElementCorrectly() {
diff --git a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceClusterConnectionTests.java b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceClusterConnectionTests.java
index af6285dad9..80d7e4db23 100644
--- a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceClusterConnectionTests.java
+++ b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceClusterConnectionTests.java
@@ -76,6 +76,7 @@
* @author Mark Paluch
* @author Dennis Neufeld
* @author Tihomir Mateev
+ * @author Viktoriya Kutsarova
*/
@SuppressWarnings("deprecation")
@EnabledOnRedisClusterAvailable
@@ -279,6 +280,82 @@ void bitOpShouldWorkCorrectly() {
assertThat(nativeConnection.get(SAME_SLOT_KEY_3)).isEqualTo("bab");
}
+ @Test // GH-3250
+ void bitOpOrShouldWorkCorrectly() {
+
+ nativeConnection.set(SAME_SLOT_KEY_1, "foo");
+ nativeConnection.set(SAME_SLOT_KEY_2, "ugh");
+
+ clusterConnection.bitOp(BitOperation.OR, SAME_SLOT_KEY_3_BYTES, SAME_SLOT_KEY_1_BYTES, SAME_SLOT_KEY_2_BYTES);
+
+ assertThat(nativeConnection.get(SAME_SLOT_KEY_3)).isEqualTo("woo");
+ }
+
+ @Test // GH-3250
+ void bitOpXorShouldWorkCorrectly() {
+
+ nativeConnection.set(SAME_SLOT_KEY_1, "aaa");
+ nativeConnection.set(SAME_SLOT_KEY_2, "___");
+
+ clusterConnection.bitOp(BitOperation.XOR, SAME_SLOT_KEY_3_BYTES, SAME_SLOT_KEY_1_BYTES, SAME_SLOT_KEY_2_BYTES);
+
+ assertThat(nativeConnection.get(SAME_SLOT_KEY_3)).isEqualTo(">>>");
+ }
+
+ @Test // GH-3250
+ void bitOpNotShouldWorkCorrectly() {
+
+ nativeConnection.set(SAME_SLOT_KEY_1, "foo");
+
+ clusterConnection.bitOp(BitOperation.NOT, SAME_SLOT_KEY_3_BYTES, SAME_SLOT_KEY_1_BYTES);
+
+ assertThat(nativeConnection.get(SAME_SLOT_KEY_3)).isNotNull();
+ }
+
+ @Test // GH-3250
+ void bitOpDiffShouldWorkCorrectly() {
+
+ nativeConnection.set(SAME_SLOT_KEY_1, "foobar");
+ nativeConnection.set(SAME_SLOT_KEY_2, "abcdef");
+
+ clusterConnection.bitOp(BitOperation.DIFF, SAME_SLOT_KEY_3_BYTES, SAME_SLOT_KEY_1_BYTES, SAME_SLOT_KEY_2_BYTES);
+
+ assertThat(nativeConnection.get(SAME_SLOT_KEY_3)).isNotNull();
+ }
+
+ @Test // GH-3250
+ void bitOpDiff1ShouldWorkCorrectly() {
+
+ nativeConnection.set(SAME_SLOT_KEY_1, "foobar");
+ nativeConnection.set(SAME_SLOT_KEY_2, "abcdef");
+
+ clusterConnection.bitOp(BitOperation.DIFF1, SAME_SLOT_KEY_3_BYTES, SAME_SLOT_KEY_1_BYTES, SAME_SLOT_KEY_2_BYTES);
+
+ assertThat(nativeConnection.get(SAME_SLOT_KEY_3)).isNotNull();
+ }
+
+ @Test // GH-3250
+ void bitOpAndorShouldWorkCorrectly() {
+
+ nativeConnection.set(SAME_SLOT_KEY_1, "foo");
+ nativeConnection.set(SAME_SLOT_KEY_2, "bar");
+
+ clusterConnection.bitOp(BitOperation.ANDOR, SAME_SLOT_KEY_3_BYTES, SAME_SLOT_KEY_1_BYTES, SAME_SLOT_KEY_2_BYTES);
+
+ assertThat(nativeConnection.get(SAME_SLOT_KEY_3)).isNotNull();
+ }
+
+ @Test // GH-3250
+ void bitOpOneShouldWorkCorrectly() {
+
+ nativeConnection.set(SAME_SLOT_KEY_1, "foo");
+ nativeConnection.set(SAME_SLOT_KEY_2, "bar");
+
+ clusterConnection.bitOp(BitOperation.ONE, SAME_SLOT_KEY_3_BYTES, SAME_SLOT_KEY_1_BYTES, SAME_SLOT_KEY_2_BYTES);
+
+ assertThat(nativeConnection.get(SAME_SLOT_KEY_3)).isNotNull();
+ }
+
@Test // DATAREDIS-315
public void blPopShouldPopElementCorrectly() {
diff --git a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveClusterStringCommandsIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveClusterStringCommandsIntegrationTests.java
index 1f56137cf2..8078a58513 100644
--- a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveClusterStringCommandsIntegrationTests.java
+++ b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveClusterStringCommandsIntegrationTests.java
@@ -29,6 +29,7 @@
/**
* @author Christoph Strobl
+ * @author Viktoriya Kutsarova
* @since 2.0
*/
class LettuceReactiveClusterStringCommandsIntegrationTests extends LettuceReactiveClusterTestSupport {
@@ -83,6 +84,27 @@ void bitOpOrShouldWorkAsExpectedWhenKeysMapToSameSlot() {
assertThat(nativeCommands.get(SAME_SLOT_KEY_3)).isEqualTo(VALUE_3);
}
+ @Test // GH-3250
+ void bitOpXorShouldWorkAsExpectedWhenKeysMapToSameSlot() {
+
+ nativeCommands.set(SAME_SLOT_KEY_1, VALUE_1);
+ nativeCommands.set(SAME_SLOT_KEY_2, VALUE_2);
+
+ assertThat(connection.stringCommands().bitOp(Arrays.asList(SAME_SLOT_KEY_1_BBUFFER, SAME_SLOT_KEY_2_BBUFFER),
+ RedisStringCommands.BitOperation.XOR, SAME_SLOT_KEY_3_BBUFFER).block()).isEqualTo(7L);
+ assertThat(nativeCommands.get(SAME_SLOT_KEY_3)).isNotNull();
+ }
+
+ @Test // GH-3250
+ void bitOpNotShouldWorkAsExpectedWhenKeysMapToSameSlot() {
+
+ nativeCommands.set(SAME_SLOT_KEY_1, VALUE_1);
+
+ assertThat(connection.stringCommands().bitOp(Arrays.asList(SAME_SLOT_KEY_1_BBUFFER),
+ RedisStringCommands.BitOperation.NOT, SAME_SLOT_KEY_3_BBUFFER).block()).isEqualTo(7L);
+ assertThat(nativeCommands.get(SAME_SLOT_KEY_3)).isNotNull();
+ }
+
@Test // DATAREDIS-525
void bitNotShouldThrowExceptionWhenMoreThanOnSourceKeyAndKeysMapToSameSlot() {
assertThatIllegalArgumentException().isThrownBy(
@@ -90,4 +112,48 @@ void bitNotShouldThrowExceptionWhenMoreThanOnSourceKeyAndKeysMapToSameSlot() {
RedisStringCommands.BitOperation.NOT, SAME_SLOT_KEY_3_BBUFFER).block());
}
+ @Test // GH-3250
+ void bitOpDiffShouldWorkAsExpectedWhenKeysMapToSameSlot() {
+
+ nativeCommands.set(SAME_SLOT_KEY_1, "foobar");
+ nativeCommands.set(SAME_SLOT_KEY_2, "abcdef");
+
+ assertThat(connection.stringCommands().bitOp(Arrays.asList(SAME_SLOT_KEY_1_BBUFFER, SAME_SLOT_KEY_2_BBUFFER),
+ RedisStringCommands.BitOperation.DIFF, SAME_SLOT_KEY_3_BBUFFER).block()).isEqualTo(6L);
+ assertThat(nativeCommands.get(SAME_SLOT_KEY_3)).isNotNull();
+ }
+
+ @Test // GH-3250
+ void bitOpDiff1ShouldWorkAsExpectedWhenKeysMapToSameSlot() {
+
+ nativeCommands.set(SAME_SLOT_KEY_1, "foobar");
+ nativeCommands.set(SAME_SLOT_KEY_2, "abcdef");
+
+ assertThat(connection.stringCommands().bitOp(Arrays.asList(SAME_SLOT_KEY_1_BBUFFER, SAME_SLOT_KEY_2_BBUFFER),
+ RedisStringCommands.BitOperation.DIFF1, SAME_SLOT_KEY_3_BBUFFER).block()).isEqualTo(6L);
+ assertThat(nativeCommands.get(SAME_SLOT_KEY_3)).isNotNull();
+ }
+
+ @Test // GH-3250
+ void bitOpAndorShouldWorkAsExpectedWhenKeysMapToSameSlot() {
+
+ nativeCommands.set(SAME_SLOT_KEY_1, VALUE_1);
+ nativeCommands.set(SAME_SLOT_KEY_2, VALUE_2);
+
+ assertThat(connection.stringCommands().bitOp(Arrays.asList(SAME_SLOT_KEY_1_BBUFFER, SAME_SLOT_KEY_2_BBUFFER),
+ RedisStringCommands.BitOperation.ANDOR, SAME_SLOT_KEY_3_BBUFFER).block()).isEqualTo(7L);
+ assertThat(nativeCommands.get(SAME_SLOT_KEY_3)).isNotNull();
+ }
+
+ @Test // GH-3250
+ void bitOpOneShouldWorkAsExpectedWhenKeysMapToSameSlot() {
+
+ nativeCommands.set(SAME_SLOT_KEY_1, VALUE_1);
+ nativeCommands.set(SAME_SLOT_KEY_2, VALUE_2);
+
+ assertThat(connection.stringCommands().bitOp(Arrays.asList(SAME_SLOT_KEY_1_BBUFFER, SAME_SLOT_KEY_2_BBUFFER),
+ RedisStringCommands.BitOperation.ONE, SAME_SLOT_KEY_3_BBUFFER).block()).isEqualTo(7L);
+ assertThat(nativeCommands.get(SAME_SLOT_KEY_3)).isNotNull();
+ }
+
}
diff --git a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveStringCommandsIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveStringCommandsIntegrationTests.java
index 5f233cd40c..b0ab1bb84f 100644
--- a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveStringCommandsIntegrationTests.java
+++ b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveStringCommandsIntegrationTests.java
@@ -61,6 +61,7 @@
* @author Christoph Strobl
* @author Mark Paluch
* @author Michele Mancioppi
+ * @author Viktoriya Kutsarova
*/
@ParameterizedClass
public class LettuceReactiveStringCommandsIntegrationTests extends LettuceReactiveCommandsTestSupport {
@@ -508,6 +509,70 @@ void bitNotShouldThrowExceptionWhenMoreThanOnSourceKey() {
.verify();
}
+ @Test // GH-3250
+ void bitOpDiffShouldWorkAsExpected() {
+
+ assumeTrue(connectionProvider instanceof StandaloneConnectionProvider);
+
+ nativeCommands.set(KEY_1, "foobar");
+ nativeCommands.set(KEY_2, "abcdef");
+
+ connection.stringCommands().bitOp(Arrays.asList(KEY_1_BBUFFER, KEY_2_BBUFFER), BitOperation.DIFF, KEY_3_BBUFFER)
+ .as(StepVerifier::create) //
+ .expectNext(6L) //
+ .verifyComplete();
+
+ assertThat(nativeCommands.get(KEY_3)).isNotNull();
+ }
+
+ @Test // GH-3250
+ void bitOpDiff1ShouldWorkAsExpected() {
+
+ assumeTrue(connectionProvider instanceof StandaloneConnectionProvider);
+
+ nativeCommands.set(KEY_1, "foobar");
+ nativeCommands.set(KEY_2, "abcdef");
+
+ connection.stringCommands().bitOp(Arrays.asList(KEY_1_BBUFFER, KEY_2_BBUFFER), BitOperation.DIFF1, KEY_3_BBUFFER)
+ .as(StepVerifier::create) //
+ .expectNext(6L) //
+ .verifyComplete();
+
+ assertThat(nativeCommands.get(KEY_3)).isNotNull();
+ }
+
+ @Test // GH-3250
+ void bitOpAndorShouldWorkAsExpected() {
+
+ assumeTrue(connectionProvider instanceof StandaloneConnectionProvider);
+
+ nativeCommands.set(KEY_1, "foo");
+ nativeCommands.set(KEY_2, "bar");
+
+ connection.stringCommands().bitOp(Arrays.asList(KEY_1_BBUFFER, KEY_2_BBUFFER), BitOperation.ANDOR, KEY_3_BBUFFER)
+ .as(StepVerifier::create) //
+ .expectNext(3L) //
+ .verifyComplete();
+
+ assertThat(nativeCommands.get(KEY_3)).isNotNull();
+ }
+
+ @Test // GH-3250
+ void bitOpOneShouldWorkAsExpected() {
+
+ assumeTrue(connectionProvider instanceof StandaloneConnectionProvider);
+
+ nativeCommands.set(KEY_1, VALUE_1);
+ nativeCommands.set(KEY_2, VALUE_2);
+
+ connection.stringCommands().bitOp(Arrays.asList(KEY_1_BBUFFER, KEY_2_BBUFFER), BitOperation.ONE, KEY_3_BBUFFER)
+ .as(StepVerifier::create) //
+ .expectNext(7L) //
+ .verifyComplete();
+
+ assertThat(nativeCommands.get(KEY_3)).isNotNull();
+ }
+
@Test // DATAREDIS-525
void strLenShouldReturnValueCorrectly() {