Skip to content

Commit

Permalink
Merge branch 'master' into 5.2.0
Browse files Browse the repository at this point in the history
sazzad16 authored Mar 10, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
2 parents b897094 + a2386fe commit dc35d45
Showing 11 changed files with 1,069 additions and 348 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
@@ -67,7 +67,7 @@
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20240205</version>
<version>20240303</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
2 changes: 1 addition & 1 deletion src/main/java/redis/clients/jedis/Protocol.java
Original file line number Diff line number Diff line change
@@ -312,7 +312,7 @@ public static enum Keyword implements Rawable {
DELETE, LIBRARYNAME, WITHCODE, DESCRIPTION, GETKEYS, GETKEYSANDFLAGS, DOCS, FILTERBY, DUMP,
MODULE, ACLCAT, PATTERN, DOCTOR, LATEST, HISTORY, USAGE, SAMPLES, PURGE, STATS, LOADEX, CONFIG, ARGS, RANK,
NOW, VERSION, ADDR, SKIPME, USER, LADDR,
CHANNELS, NUMPAT, NUMSUB, SHARDCHANNELS, SHARDNUMSUB, NOVALUES;
CHANNELS, NUMPAT, NUMSUB, SHARDCHANNELS, SHARDNUMSUB, NOVALUES, MAXAGE;

private final byte[] raw;

Original file line number Diff line number Diff line change
@@ -30,10 +30,10 @@ public interface ClientCommands {
String clientKill(String ip, int port);

/**
* Close a given client connection.
* Close client connections based on certain selection parameters.
*
* @param params Connection info will be closed
* @return Close success return OK
* @param params Parameters defining what client connections to close.
* @return The number of client connections that were closed.
*/
long clientKill(ClientKillParams params);

10 changes: 10 additions & 0 deletions src/main/java/redis/clients/jedis/params/ClientKillParams.java
Original file line number Diff line number Diff line change
@@ -67,6 +67,16 @@ public ClientKillParams laddr(String ip, int port) {
return addParam(Keyword.LADDR, ip + ':' + port);
}

/**
* Kill clients older than {@code maxAge} seconds.
*
* @param maxAge Clients older than this number of seconds will be killed.
* @return The {@code ClientKillParams} instance, for call chaining.
*/
public ClientKillParams maxAge(long maxAge) {
return addParam(Keyword.MAXAGE, maxAge);
}

@Override
public void addParams(CommandArguments args) {
params.forEach(kv -> args.add(kv.getKey()).add(kv.getValue()));
398 changes: 398 additions & 0 deletions src/test/java/redis/clients/jedis/MigratePipeliningTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,398 @@
package redis.clients.jedis;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.both;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.hasToString;
import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import redis.clients.jedis.commands.jedis.JedisCommandsTestBase;
import redis.clients.jedis.exceptions.JedisDataException;
import redis.clients.jedis.params.MigrateParams;

public class MigratePipeliningTest extends JedisCommandsTestBase {

private static final byte[] bfoo = { 0x01, 0x02, 0x03 };
private static final byte[] bbar = { 0x04, 0x05, 0x06 };
private static final byte[] bfoo1 = { 0x07, 0x08, 0x01 };
private static final byte[] bbar1 = { 0x09, 0x00, 0x01 };
private static final byte[] bfoo2 = { 0x07, 0x08, 0x02 };
private static final byte[] bbar2 = { 0x09, 0x00, 0x02 };
private static final byte[] bfoo3 = { 0x07, 0x08, 0x03 };
private static final byte[] bbar3 = { 0x09, 0x00, 0x03 };

private static final String host = hnp.getHost();
private static final int port = 6386;
private static final int portAuth = hnp.getPort() + 1;
private static final int db = 2;
private static final int dbAuth = 3;
private static final int timeout = Protocol.DEFAULT_TIMEOUT;

private Jedis dest;
private Jedis destAuth;

@Before
@Override
public void setUp() throws Exception {
super.setUp();

dest = new Jedis(host, port, 500);
dest.flushAll();
dest.select(db);

destAuth = new Jedis(host, portAuth, 500);
destAuth.auth("foobared");
destAuth.flushAll();
destAuth.select(dbAuth);
}

@After
@Override
public void tearDown() throws Exception {
dest.close();
destAuth.close();
super.tearDown();
}

@Test
public void noKey() {
Pipeline p = jedis.pipelined();

p.migrate(host, port, "foo", db, timeout);
p.migrate(host, port, bfoo, db, timeout);
p.migrate(host, port, db, timeout, new MigrateParams(), "foo1", "foo2", "foo3");
p.migrate(host, port, db, timeout, new MigrateParams(), bfoo1, bfoo2, bfoo3);

assertThat(p.syncAndReturnAll(),
hasItems("NOKEY", "NOKEY", "NOKEY", "NOKEY"));
}

@Test
public void migrate() {
assertNull(dest.get("foo"));

Pipeline p = jedis.pipelined();

p.set("foo", "bar");
p.migrate(host, port, "foo", db, timeout);
p.get("foo");

assertThat(p.syncAndReturnAll(),
hasItems("OK", "OK", null));

assertEquals("bar", dest.get("foo"));
}

@Test
public void migrateBinary() {
assertNull(dest.get(bfoo));

Pipeline p = jedis.pipelined();

p.set(bfoo, bbar);
p.migrate(host, port, bfoo, db, timeout);
p.get(bfoo);

assertThat(p.syncAndReturnAll(),
hasItems("OK", "OK", null));

assertArrayEquals(bbar, dest.get(bfoo));
}

@Test
public void migrateEmptyParams() {
assertNull(dest.get("foo"));

Pipeline p = jedis.pipelined();

p.set("foo", "bar");
p.migrate(host, port, db, timeout, new MigrateParams(), "foo");
p.get("foo");

assertThat(p.syncAndReturnAll(),
hasItems("OK", "OK", null));

assertEquals("bar", dest.get("foo"));
}

@Test
public void migrateEmptyParamsBinary() {
assertNull(dest.get(bfoo));

Pipeline p = jedis.pipelined();

p.set(bfoo, bbar);
p.migrate(host, port, db, timeout, new MigrateParams(), bfoo);
p.get(bfoo);

assertThat(p.syncAndReturnAll(),
hasItems("OK", "OK", null));

assertArrayEquals(bbar, dest.get(bfoo));
}

@Test
public void migrateCopy() {
assertNull(dest.get("foo"));

Pipeline p = jedis.pipelined();

p.set("foo", "bar");
p.migrate(host, port, db, timeout, new MigrateParams().copy(), "foo");
p.get("foo");

assertThat(p.syncAndReturnAll(),
hasItems("OK", "OK", "bar"));

assertEquals("bar", dest.get("foo"));
}

@Test
public void migrateCopyBinary() {
assertNull(dest.get(bfoo));

Pipeline p = jedis.pipelined();

p.set(bfoo, bbar);
p.migrate(host, port, db, timeout, new MigrateParams().copy(), bfoo);
p.get(bfoo);

assertThat(p.syncAndReturnAll(),
hasItems("OK", "OK", bbar));

assertArrayEquals(bbar, dest.get(bfoo));
}

@Test
public void migrateReplace() {
dest.set("foo", "bar2");

assertEquals("bar2", dest.get("foo"));

Pipeline p = jedis.pipelined();

p.set("foo", "bar1");
p.migrate(host, port, db, timeout, new MigrateParams().replace(), "foo");
p.get("foo");

assertThat(p.syncAndReturnAll(),
hasItems("OK", "OK", null));

assertEquals("bar1", dest.get("foo"));
}

@Test
public void migrateReplaceBinary() {
dest.set(bfoo, bbar2);

assertArrayEquals(bbar2, dest.get(bfoo));

Pipeline p = jedis.pipelined();

p.set(bfoo, bbar1);
p.migrate(host, port, db, timeout, new MigrateParams().replace(), bfoo);
p.get(bfoo);

assertThat(p.syncAndReturnAll(),
hasItems("OK", "OK", null));

assertArrayEquals(bbar1, dest.get(bfoo));
}

@Test
public void migrateCopyReplace() {
dest.set("foo", "bar2");

assertEquals("bar2", dest.get("foo"));

Pipeline p = jedis.pipelined();

p.set("foo", "bar1");
p.migrate(host, port, db, timeout, new MigrateParams().copy().replace(), "foo");
p.get("foo");

assertThat(p.syncAndReturnAll(),
hasItems("OK", "OK", "bar1"));

assertEquals("bar1", dest.get("foo"));
}

@Test
public void migrateCopyReplaceBinary() {
dest.set(bfoo, bbar2);

assertArrayEquals(bbar2, dest.get(bfoo));

Pipeline p = jedis.pipelined();

p.set(bfoo, bbar1);
p.migrate(host, port, db, timeout, new MigrateParams().copy().replace(), bfoo);
p.get(bfoo);

assertThat(p.syncAndReturnAll(),
hasItems("OK", "OK", bbar1));

assertArrayEquals(bbar1, dest.get(bfoo));
}

@Test
public void migrateAuth() {
assertNull(dest.get("foo"));

Pipeline p = jedis.pipelined();

p.set("foo", "bar");
p.migrate(host, portAuth, dbAuth, timeout, new MigrateParams().auth("foobared"), "foo");
p.get("foo");

assertThat(p.syncAndReturnAll(),
hasItems("OK", "OK", null));

assertEquals("bar", destAuth.get("foo"));
}

@Test
public void migrateAuthBinary() {
assertNull(dest.get(bfoo));

Pipeline p = jedis.pipelined();

p.set(bfoo, bbar);
p.migrate(host, portAuth, dbAuth, timeout, new MigrateParams().auth("foobared"), bfoo);
p.get(bfoo);

assertThat(p.syncAndReturnAll(),
hasItems("OK", "OK", null));

assertArrayEquals(bbar, destAuth.get(bfoo));
}

@Test
public void migrateAuth2() {
assertNull(jedis.get("foo"));

Pipeline p = destAuth.pipelined();

p.set("foo", "bar");
p.migrate(host, hnp.getPort(), 0, timeout,
new MigrateParams().auth2("acljedis", "fizzbuzz"), "foo");
p.get("foo");

assertThat(p.syncAndReturnAll(),
hasItems("OK", "OK", null));

assertEquals("bar", jedis.get("foo"));
}

@Test
public void migrateAuth2Binary() {
assertNull(jedis.get(bfoo));

Pipeline p = dest.pipelined();

p.set(bfoo, bbar);
p.migrate(host, hnp.getPort(), 0, timeout,
new MigrateParams().auth2("acljedis", "fizzbuzz"), bfoo);
p.get(bfoo);

assertThat(p.syncAndReturnAll(),
hasItems("OK", "OK", null));

assertArrayEquals(bbar, jedis.get(bfoo));
}

@Test
public void migrateMulti() {
assertNull(dest.get("foo1"));
assertNull(dest.get("foo2"));
assertNull(dest.get("foo3"));

Pipeline p = jedis.pipelined();

p.mset("foo1", "bar1", "foo2", "bar2", "foo3", "bar3");
p.migrate(host, port, db, timeout, new MigrateParams(), "foo1", "foo2", "foo3");

assertThat(p.syncAndReturnAll(),
hasItems("OK", "OK"));

assertEquals("bar1", dest.get("foo1"));
assertEquals("bar2", dest.get("foo2"));
assertEquals("bar3", dest.get("foo3"));
}

@Test
public void migrateMultiBinary() {
assertNull(dest.get(bfoo1));
assertNull(dest.get(bfoo2));
assertNull(dest.get(bfoo3));

Pipeline p = jedis.pipelined();

p.mset(bfoo1, bbar1, bfoo2, bbar2, bfoo3, bbar3);
p.migrate(host, port, db, timeout, new MigrateParams(), bfoo1, bfoo2, bfoo3);

assertThat(p.syncAndReturnAll(),
hasItems("OK", "OK"));

assertArrayEquals(bbar1, dest.get(bfoo1));
assertArrayEquals(bbar2, dest.get(bfoo2));
assertArrayEquals(bbar3, dest.get(bfoo3));
}

@Test
public void migrateConflict() {
dest.set("foo2", "bar");

assertNull(dest.get("foo1"));
assertEquals("bar", dest.get("foo2"));
assertNull(dest.get("foo3"));

Pipeline p = jedis.pipelined();

p.mset("foo1", "bar1", "foo2", "bar2", "foo3", "bar3");
p.migrate(host, port, db, timeout, new MigrateParams(), "foo1", "foo2", "foo3");

assertThat(p.syncAndReturnAll(),
hasItems(
equalTo("OK"),
both(instanceOf(JedisDataException.class)).and(hasToString(containsString("BUSYKEY")))
));

assertEquals("bar1", dest.get("foo1"));
assertEquals("bar", dest.get("foo2"));
assertEquals("bar3", dest.get("foo3"));
}

@Test
public void migrateConflictBinary() {
dest.set(bfoo2, bbar);

assertNull(dest.get(bfoo1));
assertArrayEquals(bbar, dest.get(bfoo2));
assertNull(dest.get(bfoo3));

Pipeline p = jedis.pipelined();

p.mset(bfoo1, bbar1, bfoo2, bbar2, bfoo3, bbar3);
p.migrate(host, port, db, timeout, new MigrateParams(), bfoo1, bfoo2, bfoo3);

assertThat(p.syncAndReturnAll(),
hasItems(
equalTo("OK"),
both(instanceOf(JedisDataException.class)).and(hasToString(containsString("BUSYKEY")))
));

assertArrayEquals(bbar1, dest.get(bfoo1));
assertArrayEquals(bbar, dest.get(bfoo2));
assertArrayEquals(bbar3, dest.get(bfoo3));
}

}
499 changes: 162 additions & 337 deletions src/test/java/redis/clients/jedis/PipeliningTest.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -222,17 +222,38 @@ public void killAddrIpPort() {

@Test
public void killUser() {
Jedis client2 = new Jedis(hnp.getHost(), hnp.getPort(), 500);
client.aclSetUser("test_kill", "on", "+acl", ">password1");
try {
try (Jedis client2 = new Jedis(hnp.getHost(), hnp.getPort(), 500)) {
client2.auth("test_kill", "password1");

assertEquals(1, jedis.clientKill(new ClientKillParams().user("test_kill")));
assertDisconnected(client2);
} finally {
jedis.aclDelUser("test_kill");
}
}

@Test
public void killMaxAge() throws InterruptedException {
long maxAge = 2;

// sleep twice the maxAge, to be sure
Thread.sleep(maxAge * 2 * 1000);

try (Jedis client2 = new Jedis(hnp.getHost(), hnp.getPort(), 500)) {
client2.auth("foobared");

long killedClients = jedis.clientKill(new ClientKillParams().maxAge(maxAge));

// The reality is that some tests leak clients, so we can't assert
// on the exact number of killed clients.
assertTrue(killedClients > 0);

assertDisconnected(client);
assertConnected(client2);
}
}

@Test
public void clientInfo() {
String info = client.clientInfo();
@@ -267,6 +288,10 @@ private void assertDisconnected(Jedis j) {
}
}

private void assertConnected(Jedis j) {
assertEquals("PONG", j.ping());
}

private String findInClientList() {
for (String clientInfo : jedis.clientList().split("\n")) {
if (pattern.matcher(clientInfo).find()) {
Original file line number Diff line number Diff line change
@@ -0,0 +1,391 @@
package redis.clients.jedis.commands.unified.pipeline;

import static redis.clients.jedis.util.AssertUtil.assertPipelineSyncAll;

import java.util.*;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

import redis.clients.jedis.commands.unified.pooled.PooledCommandsTestHelper;

public class HashesPipelineCommandsTest extends PipelineCommandsTestBase {

@BeforeClass
public static void prepare() throws InterruptedException {
jedis = PooledCommandsTestHelper.getPooled();
}

@AfterClass
public static void cleanUp() {
jedis.close();
}
//
// @Before
// public void setUp() {
// PooledCommandsTestHelper.clearData();
// }
//
// @After
// public void tearDown() {
// PooledCommandsTestHelper.clearData();
// }

final byte[] bfoo = { 0x01, 0x02, 0x03, 0x04 };
final byte[] bbar = { 0x05, 0x06, 0x07, 0x08 };
final byte[] bcar = { 0x09, 0x0A, 0x0B, 0x0C };

final byte[] bbar1 = { 0x05, 0x06, 0x07, 0x08, 0x0A };
final byte[] bbar2 = { 0x05, 0x06, 0x07, 0x08, 0x0B };
final byte[] bbar3 = { 0x05, 0x06, 0x07, 0x08, 0x0C };
final byte[] bbarstar = { 0x05, 0x06, 0x07, 0x08, '*' };

@Test
public void hset() {
pipe.hset("foo", "bar", "car");
pipe.hset("foo", "bar", "foo");

// Binary
pipe.hset(bfoo, bbar, bcar);
pipe.hset(bfoo, bbar, bfoo);

assertPipelineSyncAll(
Arrays.<Object>asList(1L, 0L, 1L, 0L),
pipe.syncAndReturnAll());
}

@Test
public void hget() {
pipe.hset("foo", "bar", "car");
pipe.hget("bar", "foo");
pipe.hget("foo", "car");
pipe.hget("foo", "bar");

// Binary
pipe.hset(bfoo, bbar, bcar);
pipe.hget(bbar, bfoo);
pipe.hget(bfoo, bcar);
pipe.hget(bfoo, bbar);

assertPipelineSyncAll(
Arrays.<Object>asList(
1L, null, null, "car",
1L, null, null, bcar),
pipe.syncAndReturnAll());
}

@Test
public void hsetnx() {
pipe.hsetnx("foo", "bar", "car");
pipe.hget("foo", "bar");

pipe.hsetnx("foo", "bar", "foo");
pipe.hget("foo", "bar");

pipe.hsetnx("foo", "car", "bar");
pipe.hget("foo", "car");

// Binary
pipe.hsetnx(bfoo, bbar, bcar);
pipe.hget(bfoo, bbar);

pipe.hsetnx(bfoo, bbar, bfoo);
pipe.hget(bfoo, bbar);

pipe.hsetnx(bfoo, bcar, bbar);
pipe.hget(bfoo, bcar);

assertPipelineSyncAll(
Arrays.<Object>asList(
1L, "car", 0L, "car", 1L, "bar",
1L, bcar, 0L, bcar, 1L, bbar),
pipe.syncAndReturnAll());
}

@Test
public void hmset() {
Map<String, String> hash = new HashMap<>();
hash.put("bar", "car");
hash.put("car", "bar");
pipe.hmset("foo", hash);
pipe.hget("foo", "bar");
pipe.hget("foo", "car");

// Binary
Map<byte[], byte[]> bhash = new HashMap<>();
bhash.put(bbar, bcar);
bhash.put(bcar, bbar);
pipe.hmset(bfoo, bhash);
pipe.hget(bfoo, bbar);
pipe.hget(bfoo, bcar);

assertPipelineSyncAll(
Arrays.<Object>asList("OK", "car", "bar", "OK", bcar, bbar),
pipe.syncAndReturnAll());
}

@Test
public void hsetVariadic() {
Map<String, String> hash = new HashMap<>();
hash.put("bar", "car");
hash.put("car", "bar");
pipe.hset("foo", hash);
pipe.hget("foo", "bar");
pipe.hget("foo", "car");

// Binary
Map<byte[], byte[]> bhash = new HashMap<>();
bhash.put(bbar, bcar);
bhash.put(bcar, bbar);
pipe.hset(bfoo, bhash);
pipe.hget(bfoo, bbar);
pipe.hget(bfoo, bcar);

assertPipelineSyncAll(
Arrays.<Object>asList(2L, "car", "bar", 2L, bcar, bbar),
pipe.syncAndReturnAll());
}

@Test
public void hmget() {
Map<String, String> hash = new HashMap<>();
hash.put("bar", "car");
hash.put("car", "bar");
pipe.hmset("foo", hash);

pipe.hmget("foo", "bar", "car", "foo");
List<String> expected = new ArrayList<>();
expected.add("car");
expected.add("bar");
expected.add(null);

// Binary
Map<byte[], byte[]> bhash = new HashMap<>();
bhash.put(bbar, bcar);
bhash.put(bcar, bbar);
pipe.hmset(bfoo, bhash);

pipe.hmget(bfoo, bbar, bcar, bfoo);
List<byte[]> bexpected = new ArrayList<>();
bexpected.add(bcar);
bexpected.add(bbar);
bexpected.add(null);

assertPipelineSyncAll(
Arrays.<Object>asList(
"OK", Arrays.asList("car", "bar", null),
"OK", Arrays.asList(bcar, bbar, null)),
pipe.syncAndReturnAll());
}

@Test
public void hincrBy() {
pipe.hincrBy("foo", "bar", 1);
pipe.hincrBy("foo", "bar", -1);
pipe.hincrBy("foo", "bar", -10);

// Binary
pipe.hincrBy(bfoo, bbar, 1);
pipe.hincrBy(bfoo, bbar, -1);
pipe.hincrBy(bfoo, bbar, -10);

assertPipelineSyncAll(
Arrays.<Object>asList(1L, 0L, -10L, 1L, 0L, -10L),
pipe.syncAndReturnAll());
}

@Test
public void hincrByFloat() {
pipe.hincrByFloat("foo", "bar", 1.5d);
pipe.hincrByFloat("foo", "bar", -1.5d);
pipe.hincrByFloat("foo", "bar", -10.7d);

// Binary
pipe.hincrByFloat(bfoo, bbar, 1.5d);
pipe.hincrByFloat(bfoo, bbar, -1.5d);
pipe.hincrByFloat(bfoo, bbar, -10.7d);

assertPipelineSyncAll(
Arrays.<Object>asList(1.5, 0d, -10.7, 1.5, 0d, -10.7),
pipe.syncAndReturnAll());
}

@Test
public void hexists() {
Map<String, String> hash = new HashMap<>();
hash.put("bar", "car");
hash.put("car", "bar");
pipe.hset("foo", hash);

pipe.hexists("bar", "foo");
pipe.hexists("foo", "foo");
pipe.hexists("foo", "bar");

// Binary
Map<byte[], byte[]> bhash = new HashMap<>();
bhash.put(bbar, bcar);
bhash.put(bcar, bbar);
pipe.hset(bfoo, bhash);

pipe.hexists(bbar, bfoo);
pipe.hexists(bfoo, bfoo);
pipe.hexists(bfoo, bbar);

assertPipelineSyncAll(
Arrays.<Object>asList(
2L, false, false, true,
2L, false, false, true),
pipe.syncAndReturnAll());
}

@Test
public void hdel() {
Map<String, String> hash = new HashMap<>();
hash.put("bar", "car");
hash.put("car", "bar");
pipe.hset("foo", hash);

pipe.hdel("bar", "foo");
pipe.hdel("foo", "foo");
pipe.hdel("foo", "bar");
pipe.hget("foo", "bar");

// Binary
Map<byte[], byte[]> bhash = new HashMap<>();
bhash.put(bbar, bcar);
bhash.put(bcar, bbar);
pipe.hset(bfoo, bhash);

pipe.hdel(bbar, bfoo);
pipe.hdel(bfoo, bfoo);
pipe.hdel(bfoo, bbar);
pipe.hget(bfoo, bbar);

assertPipelineSyncAll(
Arrays.<Object>asList(
2L, 0L, 0L, 1L, null,
2L, 0L, 0L, 1L, null),
pipe.syncAndReturnAll());
}

@Test
public void hlen() {
Map<String, String> hash = new HashMap<>();
hash.put("bar", "car");
hash.put("car", "bar");
pipe.hset("foo", hash);

pipe.hlen("bar");
pipe.hlen("foo");

// Binary
Map<byte[], byte[]> bhash = new HashMap<>();
bhash.put(bbar, bcar);
bhash.put(bcar, bbar);
pipe.hset(bfoo, bhash);

pipe.hlen(bbar);
pipe.hlen(bfoo);

assertPipelineSyncAll(
Arrays.<Object>asList(2L, 0L, 2L, 2L, 0L, 2L),
pipe.syncAndReturnAll());
}

@Test
public void hkeys() {
Map<String, String> hash = new LinkedHashMap<>();
hash.put("bar", "car");
hash.put("car", "bar");
pipe.hset("foo", hash);

pipe.hkeys("foo");
Set<String> expected = new LinkedHashSet<>();
expected.add("bar");
expected.add("car");

// Binary
Map<byte[], byte[]> bhash = new LinkedHashMap<>();
bhash.put(bbar, bcar);
bhash.put(bcar, bbar);
pipe.hset(bfoo, bhash);

pipe.hkeys(bfoo);
Set<byte[]> bexpected = new LinkedHashSet<>();
bexpected.add(bbar);
bexpected.add(bcar);

assertPipelineSyncAll(
Arrays.<Object>asList(
2L, new HashSet<>(Arrays.asList("bar", "car")),
2L, new HashSet<>(Arrays.asList(bbar, bcar))),
pipe.syncAndReturnAll());
}

@Test
public void hvals() {
Map<String, String> hash = new LinkedHashMap<>();
hash.put("bar", "car");
//hash.put("car", "bar");
pipe.hset("foo", hash);

pipe.hvals("foo");

// Binary
Map<byte[], byte[]> bhash = new LinkedHashMap<>();
bhash.put(bbar, bcar);
//bhash.put(bcar, bbar);
pipe.hset(bfoo, bhash);

pipe.hvals(bfoo);

assertPipelineSyncAll(
Arrays.<Object>asList(
//2L, Arrays.asList("bar", "car"),
//2L, Arrays.asList(bbar, bcar)),
1L, Arrays.asList("car"),
1L, Arrays.asList(bcar)),
pipe.syncAndReturnAll());
}

@Test
public void hgetAll() {
Map<String, String> hash = new HashMap<>();
hash.put("bar", "car");
//hash.put("car", "bar");
pipe.hset("foo", hash);

pipe.hgetAll("foo");

// Binary
Map<byte[], byte[]> bhash = new HashMap<>();
bhash.put(bbar, bcar);
//bhash.put(bcar, bbar);
pipe.hset(bfoo, bhash);

pipe.hgetAll(bfoo);

// assertPipelineSyncAll(
// Arrays.<Object>asList(
// 1L, hash,
// 1L, bhash),
// pipe.syncAndReturnAll());
pipe.syncAndReturnAll();
}

@Test
public void hstrlen() {
pipe.hstrlen("foo", "key");
pipe.hset("foo", "key", "value");
pipe.hstrlen("foo", "key");

pipe.hstrlen(bfoo, bbar);
pipe.hset(bfoo, bbar, bcar);
pipe.hstrlen(bfoo, bbar);

assertPipelineSyncAll(
Arrays.<Object>asList(0L, 1L, 5L, 0L, 1L, 4L),
pipe.syncAndReturnAll());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package redis.clients.jedis.commands.unified.pipeline;

import org.junit.After;
import org.junit.Before;

import redis.clients.jedis.JedisPooled;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.commands.unified.pooled.PooledCommandsTestHelper;

public abstract class PipelineCommandsTestBase {

protected static JedisPooled jedis;
protected Pipeline pipe;

public PipelineCommandsTestBase() {
}

@Before
public void setUp() {
PooledCommandsTestHelper.clearData();
pipe = jedis.pipelined();
}

@After
public void tearDown() {
pipe.close();
}
}
Original file line number Diff line number Diff line change
@@ -13,18 +13,18 @@ public class PooledCommandsTestHelper {

private static Jedis node;

static JedisPooled getPooled() throws InterruptedException {
public static JedisPooled getPooled() throws InterruptedException {

node = new Jedis(nodeInfo);
node.auth("foobared");
node.flushAll();
//node.flushAll();

//return new JedisPooled(nodeInfo.getHost(), nodeInfo.getPort(), null, "foobared");
return new JedisPooled(nodeInfo, DefaultJedisClientConfig.builder()
.protocol(RedisProtocolUtil.getRedisProtocol()).password("foobared").build());
}

static void clearData() {
node.flushDB();
public static void clearData() {
node.flushAll();
}
}
44 changes: 44 additions & 0 deletions src/test/java/redis/clients/jedis/util/AssertUtil.java
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

@@ -105,4 +106,47 @@ public static void assertByteArrayCollectionContainsAll(Collection<byte[]> all,
}
}

public static void assertPipelineSyncAll(List<Object> expected, List<Object> actual) {
assertEquals(expected.size(), actual.size());
for (int n = 0; n < expected.size(); n++) {
Object expObj = expected.get(n);
Object actObj = actual.get(n);
if (expObj instanceof List) {
if (!(actObj instanceof List)) {
throw new ComparisonFailure(n + "'th element is not a list",
expObj.getClass().toString(), actObj.getClass().toString());
}
assertPipelineSyncAll((List) expObj, (List) actObj);
} else if (expObj instanceof List) {
if (!(actObj instanceof List)) {
throw new ComparisonFailure(n + "'th element is not a list",
expObj.getClass().toString(), actObj.getClass().toString());
}
assertPipelineSyncAll((List) expObj, (List) actObj);
} else if (expObj instanceof Set) {
if (!(actObj instanceof Set)) {
throw new ComparisonFailure(n + "'th element is not a set",
expObj.getClass().toString(), actObj.getClass().toString());
}
assertPipelineSyncAllSet((Set) expObj, (Set) actObj);
} else if (expObj instanceof byte[]) {
if (!(actObj instanceof byte[])) {
throw new ComparisonFailure(n + "'th element is not byte array",
expObj.getClass().toString(), actObj.getClass().toString());
}
assertArrayEquals((byte[]) expObj, (byte[]) actObj);
} else {
assertEquals(n + "'th element mismatched", expObj, actObj);
}
}
}

private static void assertPipelineSyncAllSet(Set<?> expected, Set<?> actual) {
assertEquals(expected.size(), actual.size());
if (expected.iterator().next() instanceof byte[]) {
assertByteArraySetEquals((Set<byte[]>) expected, (Set<byte[]>) actual);
} else {
assertEquals(expected, actual);
}
}
}

0 comments on commit dc35d45

Please sign in to comment.