DonalEvans commented on a change in pull request #7278:
URL: https://github.com/apache/geode/pull/7278#discussion_r796013240
##########
File path:
geode-for-redis/src/integrationTest/java/org/apache/geode/redis/internal/commands/executor/set/AbstractSScanIntegrationTest.java
##########
@@ -54,295 +72,394 @@ public void tearDown() {
}
@Test
- public void givenNoKeyArgument_returnsWrongNumberOfArgumentsError() {
- assertThatThrownBy(() -> jedis.sendCommand("key", Protocol.Command.SSCAN))
- .hasMessageContaining("ERR wrong number of arguments for 'sscan'
command");
+ public void givenLessThanTwoArguments_returnsWrongNumberOfArgumentsError() {
+ assertAtLeastNArgs(jedis, Protocol.Command.SSCAN, 2);
}
@Test
- public void givenNoCursorArgument_returnsWrongNumberOfArgumentsError() {
- assertThatThrownBy(() -> jedis.sendCommand("key", Protocol.Command.SSCAN,
"key"))
- .hasMessageContaining("ERR wrong number of arguments for 'sscan'
command");
+ public void givenNonexistentKey_returnsEmptyArray() {
+ ScanResult<String> result = jedis.sscan("nonexistentKey", ZERO_CURSOR);
+ assertThat(result.isCompleteIteration()).isTrue();
+ assertThat(result.getResult()).isEmpty();
}
@Test
- public void givenArgumentsAreNotOddAndKeyExists_returnsSyntaxError() {
- jedis.sadd("a", "1");
- assertThatThrownBy(() -> jedis.sendCommand("a", Protocol.Command.SSCAN,
"a", "0", "a*"))
- .hasMessageContaining(ERROR_SYNTAX);
+ public void
givenNonexistentKeyAndIncorrectOptionalArguments_returnsEmptyArray() {
+ ScanResult<byte[]> result =
+ sendCustomSscanCommand("nonexistentKey", "nonexistentKey",
ZERO_CURSOR, "ANY");
+ assertThat(result.getResult()).isEmpty();
}
@Test
- @SuppressWarnings("unchecked")
- public void givenArgumentsAreNotOddAndKeyDoesNotExist_returnsEmptyArray() {
- List<Object> result =
- (List<Object>) jedis.sendCommand("key!", Protocol.Command.SSCAN,
"key!", "0", "a*");
+ public void givenIncorrectOptionalArgumentsAndKeyExists_returnsSyntaxError()
{
+ jedis.sadd(KEY, MEMBER_ONE);
+ assertThatThrownBy(
+ () -> jedis.sendCommand(KEY, Protocol.Command.SSCAN, KEY, ZERO_CURSOR,
"a*"))
+ .hasMessageContaining(ERROR_SYNTAX);
+ }
- assertThat((byte[]) result.get(0)).isEqualTo("0".getBytes());
- assertThat((List<Object>) result.get(1)).isEmpty();
+ @Test
+ public void
givenMatchArgumentWithoutPatternOnExistingKey_returnsSyntaxError() {
+ jedis.sadd(KEY, MEMBER_ONE);
+ assertThatThrownBy(
+ () -> jedis.sendCommand(KEY, Protocol.Command.SSCAN, KEY, ZERO_CURSOR,
"MATCH"))
+ .hasMessageContaining(ERROR_SYNTAX);
}
@Test
- public void givenMatchOrCountKeywordNotSpecified_returnsSyntaxError() {
- jedis.sadd("a", "1");
- assertThatThrownBy(() -> jedis.sendCommand("a", Protocol.Command.SSCAN,
"a", "0", "a*", "1"))
- .hasMessageContaining(ERROR_SYNTAX);
+ public void
givenCountArgumentWithoutNumberOnExistingKey_returnsSyntaxError() {
+ jedis.sadd(KEY, MEMBER_ONE);
+ assertThatThrownBy(
+ () -> jedis.sendCommand(KEY, Protocol.Command.SSCAN, KEY, ZERO_CURSOR,
"COUNT"))
+ .hasMessageContaining(ERROR_SYNTAX);
+ }
+
+ @Test
+ public void
givenAdditionalArgumentNotEqualToMatchOrCount_returnsSyntaxError() {
+ jedis.sadd(KEY, MEMBER_ONE);
+ assertThatThrownBy(
+ () -> jedis.sendCommand(KEY, Protocol.Command.SSCAN, KEY, ZERO_CURSOR,
"a*", "1"))
+ .hasMessageContaining(ERROR_SYNTAX);
}
@Test
public void
givenCount_whenCountParameterIsNotAnInteger_returnsNotIntegerError() {
- jedis.sadd("a", "1");
+ jedis.sadd(KEY, MEMBER_ONE);
assertThatThrownBy(
- () -> jedis.sendCommand("a", Protocol.Command.SSCAN, "a", "0",
"COUNT", "MATCH"))
- .hasMessageContaining(ERROR_NOT_INTEGER);
+ () -> jedis.sendCommand(KEY, Protocol.Command.SSCAN, KEY, ZERO_CURSOR,
"COUNT",
+ "notAnInteger"))
+ .hasMessageContaining(ERROR_NOT_INTEGER);
}
@Test
public void
givenMultipleCounts_whenAnyCountParameterIsNotAnInteger_returnsNotIntegerError()
{
- jedis.sadd("a", "1");
- assertThatThrownBy(() -> jedis.sendCommand("a", Protocol.Command.SSCAN,
"a", "0", "COUNT", "2",
- "COUNT", "sjlfs", "COUNT", "1"))
- .hasMessageContaining(ERROR_NOT_INTEGER);
+ jedis.sadd(KEY, MEMBER_ONE);
+ assertThatThrownBy(
+ () -> jedis.sendCommand(KEY, Protocol.Command.SSCAN, KEY, ZERO_CURSOR,
"COUNT", "12",
+ "COUNT", "notAnInteger", "COUNT", "1"))
+ .hasMessageContaining(ERROR_NOT_INTEGER);
}
@Test
public void
givenMultipleCounts_whenAnyCountParameterIsLessThanOne_returnsSyntaxError() {
- jedis.sadd("a", "1");
- assertThatThrownBy(() -> jedis.sendCommand("a", Protocol.Command.SSCAN,
"a", "0", "COUNT", "2",
- "COUNT", "0", "COUNT", "1"))
- .hasMessageContaining(ERROR_SYNTAX);
+ jedis.sadd(KEY, MEMBER_ONE);
+ assertThatThrownBy(
+ () -> jedis.sendCommand(KEY, Protocol.Command.SSCAN, KEY, ZERO_CURSOR,
"COUNT", "12",
+ "COUNT", "0", "COUNT", "1"))
+ .hasMessageContaining(ERROR_SYNTAX);
}
@Test
public void givenCount_whenCountParameterIsZero_returnsSyntaxError() {
- jedis.sadd("a", "1");
-
- assertThatThrownBy(() -> jedis.sendCommand("a", Protocol.Command.SSCAN,
"a", "0", "COUNT", "0"))
- .hasMessageContaining(ERROR_SYNTAX);
+ jedis.sadd(KEY, MEMBER_ONE);
+ assertThatThrownBy(
+ () -> jedis.sscan(KEY_BYTES, ZERO_CURSOR_BYTES, new
ScanParams().count(0)))
+ .hasMessageContaining(ERROR_SYNTAX);
}
@Test
public void givenCount_whenCountParameterIsNegative_returnsSyntaxError() {
- jedis.sadd("a", "1");
-
+ jedis.sadd(KEY, MEMBER_ONE);
assertThatThrownBy(
- () -> jedis.sendCommand("a", Protocol.Command.SSCAN, "a", "0",
"COUNT", "-37"))
+ () -> jedis.sscan(KEY_BYTES, ZERO_CURSOR_BYTES, new
ScanParams().count(-37)))
.hasMessageContaining(ERROR_SYNTAX);
}
@Test
public void givenKeyIsNotASet_returnsWrongTypeError() {
- jedis.hset("a", "b", "1");
-
+ jedis.hset(KEY, "b", MEMBER_ONE);
assertThatThrownBy(
- () -> jedis.sendCommand("a", Protocol.Command.SSCAN, "a", "0",
"COUNT", "-37"))
+ () -> jedis.sscan(KEY, ZERO_CURSOR))
.hasMessageContaining(ERROR_WRONG_TYPE);
}
@Test
public void
givenKeyIsNotASet_andCursorIsNotAnInteger_returnsInvalidCursorError() {
- jedis.hset("a", "b", "1");
-
- assertThatThrownBy(() -> jedis.sendCommand("a", Protocol.Command.SSCAN,
"a", "sjfls"))
- .hasMessageContaining(ERROR_CURSOR);
+ jedis.hset(KEY, "b", MEMBER_ONE);
+ assertThatThrownBy(
+ () -> jedis.sscan(KEY, "notAnInteger"))
+ .hasMessageContaining(ERROR_CURSOR);
}
@Test
public void
givenNonexistentKey_andCursorIsNotInteger_returnsInvalidCursorError() {
assertThatThrownBy(
- () -> jedis.sendCommand("notReal", Protocol.Command.SSCAN, "notReal",
"notReal", "sjfls"))
+ () -> jedis.sscan("nonexistentKey", "notAnInteger"))
.hasMessageContaining(ERROR_CURSOR);
}
@Test
public void
givenExistentSetKey_andCursorIsNotAnInteger_returnsInvalidCursorError() {
- jedis.set("a", "b");
-
- assertThatThrownBy(() -> jedis.sendCommand("a", Protocol.Command.SSCAN,
"a", "sjfls"))
- .hasMessageContaining(ERROR_CURSOR);
+ jedis.set(KEY, "b");
+ assertThatThrownBy(
+ () -> jedis.sscan(KEY, "notAnInteger"))
+ .hasMessageContaining(ERROR_CURSOR);
}
@Test
- public void givenNonexistentKey_returnsEmptyArray() {
- ScanResult<String> result = jedis.sscan("nonexistent", "0");
-
- assertThat(result.isCompleteIteration()).isTrue();
- assertThat(result.getResult()).isEmpty();
+ public void givenNegativeCursor_doesNotError() {
+ initializeThousandMemberSet();
+ assertThatNoException().isThrownBy(() -> jedis.sscan(KEY, "-1"));
}
@Test
public void givenSetWithOneMember_returnsMember() {
- jedis.sadd("a", "1");
- ScanResult<String> result = jedis.sscan("a", "0");
+ jedis.sadd(KEY, MEMBER_ONE);
+
+ ScanResult<String> result = jedis.sscan(KEY, ZERO_CURSOR);
assertThat(result.isCompleteIteration()).isTrue();
- assertThat(result.getResult()).containsExactly("1");
+ assertThat(result.getResult()).containsOnly(MEMBER_ONE);
}
@Test
- public void givenSetWithMultipleMembers_returnsAllMembers() {
- jedis.sadd("a", "1", "2", "3");
- ScanResult<String> result = jedis.sscan("a", "0");
+ public void givenSetWithMultipleMembers_returnsSubsetOfMembers() {
+ Set<String> initialMemberData = initializeThousandMemberSet();
- assertThat(result.isCompleteIteration()).isTrue();
- assertThat(result.getResult()).containsExactlyInAnyOrder("1", "2", "3");
+ ScanResult<String> result = jedis.sscan(KEY, ZERO_CURSOR);
+
+ assertThat(result.getResult()).isSubsetOf(initialMemberData);
}
@Test
public void givenCount_returnsAllMembersWithoutDuplicates() {
- jedis.sadd("a", "1", "2", "3");
+ Set<byte[]> initialTotalSet = initializeThousandMemberByteSet();
+ int count = 99;
- ScanParams scanParams = new ScanParams();
- scanParams.count(1);
- String cursor = "0";
- ScanResult<byte[]> result;
- List<byte[]> allMembersFromScan = new ArrayList<>();
+ ScanResult<byte[]> result =
+ jedis.sscan(KEY_BYTES, ZERO_CURSOR_BYTES, new
ScanParams().count(count));
- do {
- result = jedis.sscan("a".getBytes(), cursor.getBytes(), scanParams);
- allMembersFromScan.addAll(result.getResult());
- cursor = result.getCursor();
- } while (!result.isCompleteIteration());
+ assertThat(result.getResult().size()).isGreaterThanOrEqualTo(count);
+ assertThat(result.getResult()).isSubsetOf(initialTotalSet);
+ }
- assertThat(allMembersFromScan).containsExactlyInAnyOrder("1".getBytes(),
- "2".getBytes(),
- "3".getBytes());
+ @Test
+ public void givenMultipleCounts_usesLastCountSpecified() {
+ Set<byte[]> initialMemberData = initializeThousandMemberByteSet();
+ // Choose two COUNT arguments with a large difference, so that it's
extremely unlikely that if
+ // the first COUNT is used, a number of members greater than or equal to
the second COUNT will
+ // be returned.
+ int firstCount = 1;
+ int secondCount = 500;
+ ScanParams scanParams = new
ScanParams().count(firstCount).count(secondCount);
Review comment:
It's not possible to test the server's behaviour with multiple MATCH or
COUNT parameters used if you try to specify them using `ScanParameters`,
because internally, `ScanParameters` uses a map to store the values, meaning
the multiple calls to `match()` or `count()` just overwrite previous calls. In
order to test the behaviour we're interested in, you need to use the
sendCustomSscanCommand helper method:
```
result = sendCustomSscanCommand(KEY, KEY, ZERO_CURSOR,
"COUNT", String.valueOf(firstCount),
"COUNT", String.valueOf(secondCount));
```
##########
File path:
geode-for-redis/src/integrationTest/java/org/apache/geode/redis/internal/commands/executor/set/AbstractSScanIntegrationTest.java
##########
@@ -54,295 +72,394 @@ public void tearDown() {
}
@Test
- public void givenNoKeyArgument_returnsWrongNumberOfArgumentsError() {
- assertThatThrownBy(() -> jedis.sendCommand("key", Protocol.Command.SSCAN))
- .hasMessageContaining("ERR wrong number of arguments for 'sscan'
command");
+ public void givenLessThanTwoArguments_returnsWrongNumberOfArgumentsError() {
+ assertAtLeastNArgs(jedis, Protocol.Command.SSCAN, 2);
}
@Test
- public void givenNoCursorArgument_returnsWrongNumberOfArgumentsError() {
- assertThatThrownBy(() -> jedis.sendCommand("key", Protocol.Command.SSCAN,
"key"))
- .hasMessageContaining("ERR wrong number of arguments for 'sscan'
command");
+ public void givenNonexistentKey_returnsEmptyArray() {
+ ScanResult<String> result = jedis.sscan("nonexistentKey", ZERO_CURSOR);
+ assertThat(result.isCompleteIteration()).isTrue();
+ assertThat(result.getResult()).isEmpty();
}
@Test
- public void givenArgumentsAreNotOddAndKeyExists_returnsSyntaxError() {
- jedis.sadd("a", "1");
- assertThatThrownBy(() -> jedis.sendCommand("a", Protocol.Command.SSCAN,
"a", "0", "a*"))
- .hasMessageContaining(ERROR_SYNTAX);
+ public void
givenNonexistentKeyAndIncorrectOptionalArguments_returnsEmptyArray() {
+ ScanResult<byte[]> result =
+ sendCustomSscanCommand("nonexistentKey", "nonexistentKey",
ZERO_CURSOR, "ANY");
+ assertThat(result.getResult()).isEmpty();
}
@Test
- @SuppressWarnings("unchecked")
- public void givenArgumentsAreNotOddAndKeyDoesNotExist_returnsEmptyArray() {
- List<Object> result =
- (List<Object>) jedis.sendCommand("key!", Protocol.Command.SSCAN,
"key!", "0", "a*");
+ public void givenIncorrectOptionalArgumentsAndKeyExists_returnsSyntaxError()
{
+ jedis.sadd(KEY, MEMBER_ONE);
+ assertThatThrownBy(
+ () -> jedis.sendCommand(KEY, Protocol.Command.SSCAN, KEY, ZERO_CURSOR,
"a*"))
+ .hasMessageContaining(ERROR_SYNTAX);
+ }
- assertThat((byte[]) result.get(0)).isEqualTo("0".getBytes());
- assertThat((List<Object>) result.get(1)).isEmpty();
+ @Test
+ public void
givenMatchArgumentWithoutPatternOnExistingKey_returnsSyntaxError() {
+ jedis.sadd(KEY, MEMBER_ONE);
+ assertThatThrownBy(
+ () -> jedis.sendCommand(KEY, Protocol.Command.SSCAN, KEY, ZERO_CURSOR,
"MATCH"))
+ .hasMessageContaining(ERROR_SYNTAX);
}
@Test
- public void givenMatchOrCountKeywordNotSpecified_returnsSyntaxError() {
- jedis.sadd("a", "1");
- assertThatThrownBy(() -> jedis.sendCommand("a", Protocol.Command.SSCAN,
"a", "0", "a*", "1"))
- .hasMessageContaining(ERROR_SYNTAX);
+ public void
givenCountArgumentWithoutNumberOnExistingKey_returnsSyntaxError() {
+ jedis.sadd(KEY, MEMBER_ONE);
+ assertThatThrownBy(
+ () -> jedis.sendCommand(KEY, Protocol.Command.SSCAN, KEY, ZERO_CURSOR,
"COUNT"))
+ .hasMessageContaining(ERROR_SYNTAX);
+ }
+
+ @Test
+ public void
givenAdditionalArgumentNotEqualToMatchOrCount_returnsSyntaxError() {
+ jedis.sadd(KEY, MEMBER_ONE);
+ assertThatThrownBy(
+ () -> jedis.sendCommand(KEY, Protocol.Command.SSCAN, KEY, ZERO_CURSOR,
"a*", "1"))
+ .hasMessageContaining(ERROR_SYNTAX);
}
@Test
public void
givenCount_whenCountParameterIsNotAnInteger_returnsNotIntegerError() {
- jedis.sadd("a", "1");
+ jedis.sadd(KEY, MEMBER_ONE);
assertThatThrownBy(
- () -> jedis.sendCommand("a", Protocol.Command.SSCAN, "a", "0",
"COUNT", "MATCH"))
- .hasMessageContaining(ERROR_NOT_INTEGER);
+ () -> jedis.sendCommand(KEY, Protocol.Command.SSCAN, KEY, ZERO_CURSOR,
"COUNT",
+ "notAnInteger"))
+ .hasMessageContaining(ERROR_NOT_INTEGER);
}
@Test
public void
givenMultipleCounts_whenAnyCountParameterIsNotAnInteger_returnsNotIntegerError()
{
- jedis.sadd("a", "1");
- assertThatThrownBy(() -> jedis.sendCommand("a", Protocol.Command.SSCAN,
"a", "0", "COUNT", "2",
- "COUNT", "sjlfs", "COUNT", "1"))
- .hasMessageContaining(ERROR_NOT_INTEGER);
+ jedis.sadd(KEY, MEMBER_ONE);
+ assertThatThrownBy(
+ () -> jedis.sendCommand(KEY, Protocol.Command.SSCAN, KEY, ZERO_CURSOR,
"COUNT", "12",
+ "COUNT", "notAnInteger", "COUNT", "1"))
+ .hasMessageContaining(ERROR_NOT_INTEGER);
}
@Test
public void
givenMultipleCounts_whenAnyCountParameterIsLessThanOne_returnsSyntaxError() {
- jedis.sadd("a", "1");
- assertThatThrownBy(() -> jedis.sendCommand("a", Protocol.Command.SSCAN,
"a", "0", "COUNT", "2",
- "COUNT", "0", "COUNT", "1"))
- .hasMessageContaining(ERROR_SYNTAX);
+ jedis.sadd(KEY, MEMBER_ONE);
+ assertThatThrownBy(
+ () -> jedis.sendCommand(KEY, Protocol.Command.SSCAN, KEY, ZERO_CURSOR,
"COUNT", "12",
+ "COUNT", "0", "COUNT", "1"))
+ .hasMessageContaining(ERROR_SYNTAX);
}
@Test
public void givenCount_whenCountParameterIsZero_returnsSyntaxError() {
- jedis.sadd("a", "1");
-
- assertThatThrownBy(() -> jedis.sendCommand("a", Protocol.Command.SSCAN,
"a", "0", "COUNT", "0"))
- .hasMessageContaining(ERROR_SYNTAX);
+ jedis.sadd(KEY, MEMBER_ONE);
+ assertThatThrownBy(
+ () -> jedis.sscan(KEY_BYTES, ZERO_CURSOR_BYTES, new
ScanParams().count(0)))
+ .hasMessageContaining(ERROR_SYNTAX);
}
@Test
public void givenCount_whenCountParameterIsNegative_returnsSyntaxError() {
- jedis.sadd("a", "1");
-
+ jedis.sadd(KEY, MEMBER_ONE);
assertThatThrownBy(
- () -> jedis.sendCommand("a", Protocol.Command.SSCAN, "a", "0",
"COUNT", "-37"))
+ () -> jedis.sscan(KEY_BYTES, ZERO_CURSOR_BYTES, new
ScanParams().count(-37)))
.hasMessageContaining(ERROR_SYNTAX);
}
@Test
public void givenKeyIsNotASet_returnsWrongTypeError() {
- jedis.hset("a", "b", "1");
-
+ jedis.hset(KEY, "b", MEMBER_ONE);
assertThatThrownBy(
- () -> jedis.sendCommand("a", Protocol.Command.SSCAN, "a", "0",
"COUNT", "-37"))
+ () -> jedis.sscan(KEY, ZERO_CURSOR))
.hasMessageContaining(ERROR_WRONG_TYPE);
}
@Test
public void
givenKeyIsNotASet_andCursorIsNotAnInteger_returnsInvalidCursorError() {
- jedis.hset("a", "b", "1");
-
- assertThatThrownBy(() -> jedis.sendCommand("a", Protocol.Command.SSCAN,
"a", "sjfls"))
- .hasMessageContaining(ERROR_CURSOR);
+ jedis.hset(KEY, "b", MEMBER_ONE);
+ assertThatThrownBy(
+ () -> jedis.sscan(KEY, "notAnInteger"))
+ .hasMessageContaining(ERROR_CURSOR);
}
@Test
public void
givenNonexistentKey_andCursorIsNotInteger_returnsInvalidCursorError() {
assertThatThrownBy(
- () -> jedis.sendCommand("notReal", Protocol.Command.SSCAN, "notReal",
"notReal", "sjfls"))
+ () -> jedis.sscan("nonexistentKey", "notAnInteger"))
.hasMessageContaining(ERROR_CURSOR);
}
@Test
public void
givenExistentSetKey_andCursorIsNotAnInteger_returnsInvalidCursorError() {
- jedis.set("a", "b");
-
- assertThatThrownBy(() -> jedis.sendCommand("a", Protocol.Command.SSCAN,
"a", "sjfls"))
- .hasMessageContaining(ERROR_CURSOR);
+ jedis.set(KEY, "b");
+ assertThatThrownBy(
+ () -> jedis.sscan(KEY, "notAnInteger"))
+ .hasMessageContaining(ERROR_CURSOR);
}
@Test
- public void givenNonexistentKey_returnsEmptyArray() {
- ScanResult<String> result = jedis.sscan("nonexistent", "0");
-
- assertThat(result.isCompleteIteration()).isTrue();
- assertThat(result.getResult()).isEmpty();
+ public void givenNegativeCursor_doesNotError() {
+ initializeThousandMemberSet();
+ assertThatNoException().isThrownBy(() -> jedis.sscan(KEY, "-1"));
}
@Test
public void givenSetWithOneMember_returnsMember() {
- jedis.sadd("a", "1");
- ScanResult<String> result = jedis.sscan("a", "0");
+ jedis.sadd(KEY, MEMBER_ONE);
+
+ ScanResult<String> result = jedis.sscan(KEY, ZERO_CURSOR);
assertThat(result.isCompleteIteration()).isTrue();
- assertThat(result.getResult()).containsExactly("1");
+ assertThat(result.getResult()).containsOnly(MEMBER_ONE);
}
@Test
- public void givenSetWithMultipleMembers_returnsAllMembers() {
- jedis.sadd("a", "1", "2", "3");
- ScanResult<String> result = jedis.sscan("a", "0");
+ public void givenSetWithMultipleMembers_returnsSubsetOfMembers() {
+ Set<String> initialMemberData = initializeThousandMemberSet();
- assertThat(result.isCompleteIteration()).isTrue();
- assertThat(result.getResult()).containsExactlyInAnyOrder("1", "2", "3");
+ ScanResult<String> result = jedis.sscan(KEY, ZERO_CURSOR);
+
+ assertThat(result.getResult()).isSubsetOf(initialMemberData);
}
@Test
public void givenCount_returnsAllMembersWithoutDuplicates() {
- jedis.sadd("a", "1", "2", "3");
+ Set<byte[]> initialTotalSet = initializeThousandMemberByteSet();
+ int count = 99;
- ScanParams scanParams = new ScanParams();
- scanParams.count(1);
- String cursor = "0";
- ScanResult<byte[]> result;
- List<byte[]> allMembersFromScan = new ArrayList<>();
+ ScanResult<byte[]> result =
+ jedis.sscan(KEY_BYTES, ZERO_CURSOR_BYTES, new
ScanParams().count(count));
- do {
- result = jedis.sscan("a".getBytes(), cursor.getBytes(), scanParams);
- allMembersFromScan.addAll(result.getResult());
- cursor = result.getCursor();
- } while (!result.isCompleteIteration());
+ assertThat(result.getResult().size()).isGreaterThanOrEqualTo(count);
+ assertThat(result.getResult()).isSubsetOf(initialTotalSet);
+ }
- assertThat(allMembersFromScan).containsExactlyInAnyOrder("1".getBytes(),
- "2".getBytes(),
- "3".getBytes());
+ @Test
+ public void givenMultipleCounts_usesLastCountSpecified() {
+ Set<byte[]> initialMemberData = initializeThousandMemberByteSet();
+ // Choose two COUNT arguments with a large difference, so that it's
extremely unlikely that if
+ // the first COUNT is used, a number of members greater than or equal to
the second COUNT will
+ // be returned.
+ int firstCount = 1;
+ int secondCount = 500;
+ ScanParams scanParams = new
ScanParams().count(firstCount).count(secondCount);
+
+ ScanResult<byte[]> result = jedis.sscan(KEY_BYTES, ZERO_CURSOR_BYTES,
scanParams);
+
+ List<byte[]> returnedMembers = result.getResult();
+ assertThat(returnedMembers.size()).isGreaterThanOrEqualTo(secondCount);
+ assertThat(returnedMembers).isSubsetOf(initialMemberData);
}
@Test
- @SuppressWarnings("unchecked")
- public void givenMultipleCounts_returnsAllEntriesWithoutDuplicates() {
- jedis.sadd("a", "1", "12", "3");
+ public void givenSetWithThreeEntriesAndMatch_returnsOnlyMatchingElements() {
+ jedis.sadd(KEY, MEMBER_ONE, MEMBER_TWELVE, MEMBER_THREE);
+ ScanParams scanParams = new ScanParams().match("1*");
- List<Object> result;
+ ScanResult<byte[]> result = jedis.sscan(KEY_BYTES, ZERO_CURSOR_BYTES,
scanParams);
- List<byte[]> allEntries = new ArrayList<>();
- String cursor = "0";
+ assertThat(result.isCompleteIteration()).isTrue();
+ assertThat(result.getResult()).containsOnly(MEMBER_ONE.getBytes(),
+ MEMBER_TWELVE.getBytes());
+ }
- do {
- result =
- (List<Object>) jedis.sendCommand("a", Protocol.Command.SSCAN, "a",
cursor, "COUNT", "2",
- "COUNT", "1");
- allEntries.addAll((List<byte[]>) result.get(1));
- cursor = new String((byte[]) result.get(0));
- } while (!Arrays.equals((byte[]) result.get(0), "0".getBytes()));
+ @Test
+ public void
givenSetWithThreeEntriesAndMultipleMatchArguments_returnsOnlyElementsMatchingLastMatchArgument()
{
+ jedis.sadd(KEY, MEMBER_ONE, MEMBER_TWELVE, MEMBER_THREE);
+ ScanParams scanParams = new ScanParams().match("3*").match("1*");
+
+ ScanResult<byte[]> result = jedis.sscan(KEY_BYTES, ZERO_CURSOR_BYTES,
scanParams);
- assertThat((byte[]) result.get(0)).isEqualTo("0".getBytes());
- assertThat(allEntries).containsExactlyInAnyOrder("1".getBytes(),
- "12".getBytes(),
- "3".getBytes());
+ assertThat(result.getCursor()).isEqualTo(ZERO_CURSOR);
+ assertThat(result.getResult()).containsOnly(MEMBER_ONE.getBytes(),
+ MEMBER_TWELVE.getBytes());
}
@Test
- public void givenMatch_returnsAllMatchingMembersWithoutDuplicates() {
- jedis.sadd("a", "1", "12", "3");
-
+ public void givenLargeCountAndMatch_returnsOnlyMatchingMembers() {
+ Set<byte[]> initialMemberData = initializeThousandMemberByteSet();
ScanParams scanParams = new ScanParams();
- scanParams.match("1*");
+ // There are 111 matching members in the set 0..999
+ scanParams.match("9*");
+ // Choose a large COUNT to ensure that some matching members are returned
+ scanParams.count(950);
+
+ ScanResult<byte[]> result = jedis.sscan(KEY_BYTES, ZERO_CURSOR_BYTES,
scanParams);
+
+ List<byte[]> returnedMembers = result.getResult();
+ // We know that we must have found at least 61 matching members, given the
size of COUNT and the
+ // number of matching members in the set
+ assertThat(returnedMembers.size()).isGreaterThanOrEqualTo(61);
+ assertThat(returnedMembers).isSubsetOf(initialMemberData);
+ assertThat(returnedMembers).allSatisfy(bytes -> assertThat(new
String(bytes)).startsWith("9"));
+ }
- ScanResult<byte[]> result =
- jedis.sscan("a".getBytes(), "0".getBytes(), scanParams);
+ @Test
+ public void givenMultipleCountAndMatch_usesLastSpecified() {
+ Set<byte[]> initialMemberData = initializeThousandMemberByteSet();
+ // Choose a large COUNT to ensure that some matching members are returned
+ // There are 111 matching members in the set 0..999
+ ScanParams scanParams = new
ScanParams().count(20).match("1*").count(950).match("9*");
Review comment:
See the comment above about using `sendCustomSscanCommand()` instead of
multiple calls to `ScanParams` methods here.
##########
File path:
geode-for-redis/src/integrationTest/java/org/apache/geode/redis/internal/commands/executor/set/AbstractSScanIntegrationTest.java
##########
@@ -54,295 +72,394 @@ public void tearDown() {
}
@Test
- public void givenNoKeyArgument_returnsWrongNumberOfArgumentsError() {
- assertThatThrownBy(() -> jedis.sendCommand("key", Protocol.Command.SSCAN))
- .hasMessageContaining("ERR wrong number of arguments for 'sscan'
command");
+ public void givenLessThanTwoArguments_returnsWrongNumberOfArgumentsError() {
+ assertAtLeastNArgs(jedis, Protocol.Command.SSCAN, 2);
}
@Test
- public void givenNoCursorArgument_returnsWrongNumberOfArgumentsError() {
- assertThatThrownBy(() -> jedis.sendCommand("key", Protocol.Command.SSCAN,
"key"))
- .hasMessageContaining("ERR wrong number of arguments for 'sscan'
command");
+ public void givenNonexistentKey_returnsEmptyArray() {
+ ScanResult<String> result = jedis.sscan("nonexistentKey", ZERO_CURSOR);
+ assertThat(result.isCompleteIteration()).isTrue();
+ assertThat(result.getResult()).isEmpty();
}
@Test
- public void givenArgumentsAreNotOddAndKeyExists_returnsSyntaxError() {
- jedis.sadd("a", "1");
- assertThatThrownBy(() -> jedis.sendCommand("a", Protocol.Command.SSCAN,
"a", "0", "a*"))
- .hasMessageContaining(ERROR_SYNTAX);
+ public void
givenNonexistentKeyAndIncorrectOptionalArguments_returnsEmptyArray() {
+ ScanResult<byte[]> result =
+ sendCustomSscanCommand("nonexistentKey", "nonexistentKey",
ZERO_CURSOR, "ANY");
+ assertThat(result.getResult()).isEmpty();
}
@Test
- @SuppressWarnings("unchecked")
- public void givenArgumentsAreNotOddAndKeyDoesNotExist_returnsEmptyArray() {
- List<Object> result =
- (List<Object>) jedis.sendCommand("key!", Protocol.Command.SSCAN,
"key!", "0", "a*");
+ public void givenIncorrectOptionalArgumentsAndKeyExists_returnsSyntaxError()
{
+ jedis.sadd(KEY, MEMBER_ONE);
+ assertThatThrownBy(
+ () -> jedis.sendCommand(KEY, Protocol.Command.SSCAN, KEY, ZERO_CURSOR,
"a*"))
+ .hasMessageContaining(ERROR_SYNTAX);
+ }
- assertThat((byte[]) result.get(0)).isEqualTo("0".getBytes());
- assertThat((List<Object>) result.get(1)).isEmpty();
+ @Test
+ public void
givenMatchArgumentWithoutPatternOnExistingKey_returnsSyntaxError() {
+ jedis.sadd(KEY, MEMBER_ONE);
+ assertThatThrownBy(
+ () -> jedis.sendCommand(KEY, Protocol.Command.SSCAN, KEY, ZERO_CURSOR,
"MATCH"))
+ .hasMessageContaining(ERROR_SYNTAX);
}
@Test
- public void givenMatchOrCountKeywordNotSpecified_returnsSyntaxError() {
- jedis.sadd("a", "1");
- assertThatThrownBy(() -> jedis.sendCommand("a", Protocol.Command.SSCAN,
"a", "0", "a*", "1"))
- .hasMessageContaining(ERROR_SYNTAX);
+ public void
givenCountArgumentWithoutNumberOnExistingKey_returnsSyntaxError() {
+ jedis.sadd(KEY, MEMBER_ONE);
+ assertThatThrownBy(
+ () -> jedis.sendCommand(KEY, Protocol.Command.SSCAN, KEY, ZERO_CURSOR,
"COUNT"))
+ .hasMessageContaining(ERROR_SYNTAX);
+ }
+
+ @Test
+ public void
givenAdditionalArgumentNotEqualToMatchOrCount_returnsSyntaxError() {
+ jedis.sadd(KEY, MEMBER_ONE);
+ assertThatThrownBy(
+ () -> jedis.sendCommand(KEY, Protocol.Command.SSCAN, KEY, ZERO_CURSOR,
"a*", "1"))
+ .hasMessageContaining(ERROR_SYNTAX);
}
@Test
public void
givenCount_whenCountParameterIsNotAnInteger_returnsNotIntegerError() {
- jedis.sadd("a", "1");
+ jedis.sadd(KEY, MEMBER_ONE);
assertThatThrownBy(
- () -> jedis.sendCommand("a", Protocol.Command.SSCAN, "a", "0",
"COUNT", "MATCH"))
- .hasMessageContaining(ERROR_NOT_INTEGER);
+ () -> jedis.sendCommand(KEY, Protocol.Command.SSCAN, KEY, ZERO_CURSOR,
"COUNT",
+ "notAnInteger"))
+ .hasMessageContaining(ERROR_NOT_INTEGER);
}
@Test
public void
givenMultipleCounts_whenAnyCountParameterIsNotAnInteger_returnsNotIntegerError()
{
- jedis.sadd("a", "1");
- assertThatThrownBy(() -> jedis.sendCommand("a", Protocol.Command.SSCAN,
"a", "0", "COUNT", "2",
- "COUNT", "sjlfs", "COUNT", "1"))
- .hasMessageContaining(ERROR_NOT_INTEGER);
+ jedis.sadd(KEY, MEMBER_ONE);
+ assertThatThrownBy(
+ () -> jedis.sendCommand(KEY, Protocol.Command.SSCAN, KEY, ZERO_CURSOR,
"COUNT", "12",
+ "COUNT", "notAnInteger", "COUNT", "1"))
+ .hasMessageContaining(ERROR_NOT_INTEGER);
}
@Test
public void
givenMultipleCounts_whenAnyCountParameterIsLessThanOne_returnsSyntaxError() {
- jedis.sadd("a", "1");
- assertThatThrownBy(() -> jedis.sendCommand("a", Protocol.Command.SSCAN,
"a", "0", "COUNT", "2",
- "COUNT", "0", "COUNT", "1"))
- .hasMessageContaining(ERROR_SYNTAX);
+ jedis.sadd(KEY, MEMBER_ONE);
+ assertThatThrownBy(
+ () -> jedis.sendCommand(KEY, Protocol.Command.SSCAN, KEY, ZERO_CURSOR,
"COUNT", "12",
+ "COUNT", "0", "COUNT", "1"))
+ .hasMessageContaining(ERROR_SYNTAX);
}
@Test
public void givenCount_whenCountParameterIsZero_returnsSyntaxError() {
- jedis.sadd("a", "1");
-
- assertThatThrownBy(() -> jedis.sendCommand("a", Protocol.Command.SSCAN,
"a", "0", "COUNT", "0"))
- .hasMessageContaining(ERROR_SYNTAX);
+ jedis.sadd(KEY, MEMBER_ONE);
+ assertThatThrownBy(
+ () -> jedis.sscan(KEY_BYTES, ZERO_CURSOR_BYTES, new
ScanParams().count(0)))
+ .hasMessageContaining(ERROR_SYNTAX);
}
@Test
public void givenCount_whenCountParameterIsNegative_returnsSyntaxError() {
- jedis.sadd("a", "1");
-
+ jedis.sadd(KEY, MEMBER_ONE);
assertThatThrownBy(
- () -> jedis.sendCommand("a", Protocol.Command.SSCAN, "a", "0",
"COUNT", "-37"))
+ () -> jedis.sscan(KEY_BYTES, ZERO_CURSOR_BYTES, new
ScanParams().count(-37)))
.hasMessageContaining(ERROR_SYNTAX);
}
@Test
public void givenKeyIsNotASet_returnsWrongTypeError() {
- jedis.hset("a", "b", "1");
-
+ jedis.hset(KEY, "b", MEMBER_ONE);
assertThatThrownBy(
- () -> jedis.sendCommand("a", Protocol.Command.SSCAN, "a", "0",
"COUNT", "-37"))
+ () -> jedis.sscan(KEY, ZERO_CURSOR))
.hasMessageContaining(ERROR_WRONG_TYPE);
}
@Test
public void
givenKeyIsNotASet_andCursorIsNotAnInteger_returnsInvalidCursorError() {
- jedis.hset("a", "b", "1");
-
- assertThatThrownBy(() -> jedis.sendCommand("a", Protocol.Command.SSCAN,
"a", "sjfls"))
- .hasMessageContaining(ERROR_CURSOR);
+ jedis.hset(KEY, "b", MEMBER_ONE);
+ assertThatThrownBy(
+ () -> jedis.sscan(KEY, "notAnInteger"))
+ .hasMessageContaining(ERROR_CURSOR);
}
@Test
public void
givenNonexistentKey_andCursorIsNotInteger_returnsInvalidCursorError() {
assertThatThrownBy(
- () -> jedis.sendCommand("notReal", Protocol.Command.SSCAN, "notReal",
"notReal", "sjfls"))
+ () -> jedis.sscan("nonexistentKey", "notAnInteger"))
.hasMessageContaining(ERROR_CURSOR);
}
@Test
public void
givenExistentSetKey_andCursorIsNotAnInteger_returnsInvalidCursorError() {
- jedis.set("a", "b");
-
- assertThatThrownBy(() -> jedis.sendCommand("a", Protocol.Command.SSCAN,
"a", "sjfls"))
- .hasMessageContaining(ERROR_CURSOR);
+ jedis.set(KEY, "b");
+ assertThatThrownBy(
+ () -> jedis.sscan(KEY, "notAnInteger"))
+ .hasMessageContaining(ERROR_CURSOR);
}
@Test
- public void givenNonexistentKey_returnsEmptyArray() {
- ScanResult<String> result = jedis.sscan("nonexistent", "0");
-
- assertThat(result.isCompleteIteration()).isTrue();
- assertThat(result.getResult()).isEmpty();
+ public void givenNegativeCursor_doesNotError() {
+ initializeThousandMemberSet();
+ assertThatNoException().isThrownBy(() -> jedis.sscan(KEY, "-1"));
}
@Test
public void givenSetWithOneMember_returnsMember() {
- jedis.sadd("a", "1");
- ScanResult<String> result = jedis.sscan("a", "0");
+ jedis.sadd(KEY, MEMBER_ONE);
+
+ ScanResult<String> result = jedis.sscan(KEY, ZERO_CURSOR);
assertThat(result.isCompleteIteration()).isTrue();
- assertThat(result.getResult()).containsExactly("1");
+ assertThat(result.getResult()).containsOnly(MEMBER_ONE);
}
@Test
- public void givenSetWithMultipleMembers_returnsAllMembers() {
- jedis.sadd("a", "1", "2", "3");
- ScanResult<String> result = jedis.sscan("a", "0");
+ public void givenSetWithMultipleMembers_returnsSubsetOfMembers() {
+ Set<String> initialMemberData = initializeThousandMemberSet();
- assertThat(result.isCompleteIteration()).isTrue();
- assertThat(result.getResult()).containsExactlyInAnyOrder("1", "2", "3");
+ ScanResult<String> result = jedis.sscan(KEY, ZERO_CURSOR);
+
+ assertThat(result.getResult()).isSubsetOf(initialMemberData);
}
@Test
public void givenCount_returnsAllMembersWithoutDuplicates() {
- jedis.sadd("a", "1", "2", "3");
+ Set<byte[]> initialTotalSet = initializeThousandMemberByteSet();
+ int count = 99;
- ScanParams scanParams = new ScanParams();
- scanParams.count(1);
- String cursor = "0";
- ScanResult<byte[]> result;
- List<byte[]> allMembersFromScan = new ArrayList<>();
+ ScanResult<byte[]> result =
+ jedis.sscan(KEY_BYTES, ZERO_CURSOR_BYTES, new
ScanParams().count(count));
- do {
- result = jedis.sscan("a".getBytes(), cursor.getBytes(), scanParams);
- allMembersFromScan.addAll(result.getResult());
- cursor = result.getCursor();
- } while (!result.isCompleteIteration());
+ assertThat(result.getResult().size()).isGreaterThanOrEqualTo(count);
+ assertThat(result.getResult()).isSubsetOf(initialTotalSet);
+ }
- assertThat(allMembersFromScan).containsExactlyInAnyOrder("1".getBytes(),
- "2".getBytes(),
- "3".getBytes());
+ @Test
+ public void givenMultipleCounts_usesLastCountSpecified() {
+ Set<byte[]> initialMemberData = initializeThousandMemberByteSet();
+ // Choose two COUNT arguments with a large difference, so that it's
extremely unlikely that if
+ // the first COUNT is used, a number of members greater than or equal to
the second COUNT will
+ // be returned.
+ int firstCount = 1;
+ int secondCount = 500;
+ ScanParams scanParams = new
ScanParams().count(firstCount).count(secondCount);
+
+ ScanResult<byte[]> result = jedis.sscan(KEY_BYTES, ZERO_CURSOR_BYTES,
scanParams);
+
+ List<byte[]> returnedMembers = result.getResult();
+ assertThat(returnedMembers.size()).isGreaterThanOrEqualTo(secondCount);
+ assertThat(returnedMembers).isSubsetOf(initialMemberData);
}
@Test
- @SuppressWarnings("unchecked")
- public void givenMultipleCounts_returnsAllEntriesWithoutDuplicates() {
- jedis.sadd("a", "1", "12", "3");
+ public void givenSetWithThreeEntriesAndMatch_returnsOnlyMatchingElements() {
+ jedis.sadd(KEY, MEMBER_ONE, MEMBER_TWELVE, MEMBER_THREE);
+ ScanParams scanParams = new ScanParams().match("1*");
- List<Object> result;
+ ScanResult<byte[]> result = jedis.sscan(KEY_BYTES, ZERO_CURSOR_BYTES,
scanParams);
- List<byte[]> allEntries = new ArrayList<>();
- String cursor = "0";
+ assertThat(result.isCompleteIteration()).isTrue();
+ assertThat(result.getResult()).containsOnly(MEMBER_ONE.getBytes(),
+ MEMBER_TWELVE.getBytes());
+ }
- do {
- result =
- (List<Object>) jedis.sendCommand("a", Protocol.Command.SSCAN, "a",
cursor, "COUNT", "2",
- "COUNT", "1");
- allEntries.addAll((List<byte[]>) result.get(1));
- cursor = new String((byte[]) result.get(0));
- } while (!Arrays.equals((byte[]) result.get(0), "0".getBytes()));
+ @Test
+ public void
givenSetWithThreeEntriesAndMultipleMatchArguments_returnsOnlyElementsMatchingLastMatchArgument()
{
+ jedis.sadd(KEY, MEMBER_ONE, MEMBER_TWELVE, MEMBER_THREE);
+ ScanParams scanParams = new ScanParams().match("3*").match("1*");
Review comment:
See the comment above about using `sendCustomSscanCommand()` instead of
multiple calls to `ScanParams` methods here.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]