// Copyright (C) 2011 - Will Glozer. All rights reserved.
package com.lambdaworks.redis.commands;
import static com.lambdaworks.redis.ScriptOutputType.*;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.List;
import org.junit.After;
import org.junit.FixMethodOrder;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runners.MethodSorters;
import com.lambdaworks.Wait;
import com.lambdaworks.redis.AbstractRedisClientTest;
import com.lambdaworks.redis.RedisAsyncConnection;
import com.lambdaworks.redis.RedisException;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class ScriptingCommandTest extends AbstractRedisClientTest {
@Rule
public ExpectedException exception = ExpectedException.none();
@After
public void tearDown() throws Exception {
Wait.untilNoException(() -> {
try {
redis.scriptKill();
} catch (RedisException e) {
// ignore
}
redis.ping();
}).waitOrTimeout();
}
@Test
public void eval() throws Exception {
assertThat((Boolean) redis.eval("return 1 + 1 == 4", BOOLEAN)).isEqualTo(false);
assertThat((Number) redis.eval("return 1 + 1", INTEGER)).isEqualTo(2L);
assertThat((String) redis.eval("return {ok='status'}", STATUS)).isEqualTo("status");
assertThat((String) redis.eval("return 'one'", VALUE)).isEqualTo("one");
assertThat((List<?>) redis.eval("return {1, 'one', {2}}", MULTI)).isEqualTo(list(1L, "one", list(2L)));
exception.expectMessage("Oops!");
redis.eval("return {err='Oops!'}", STATUS);
}
@Test
public void evalWithKeys() throws Exception {
assertThat((List<?>) redis.eval("return {KEYS[1], KEYS[2]}", MULTI, "one", "two")).isEqualTo(list("one", "two"));
}
@Test
public void evalWithArgs() throws Exception {
String[] keys = new String[0];
assertThat((List<?>) redis.eval("return {ARGV[1], ARGV[2]}", MULTI, keys, "a", "b")).isEqualTo(list("a", "b"));
}
@Test
public void evalsha() throws Exception {
redis.scriptFlush();
String script = "return 1 + 1";
String digest = redis.digest(script);
assertThat((Number) redis.eval(script, INTEGER)).isEqualTo(2L);
assertThat((Number) redis.evalsha(digest, INTEGER)).isEqualTo(2L);
exception.expectMessage("NOSCRIPT No matching script. Please use EVAL.");
redis.evalsha(redis.digest("return 1 + 1 == 4"), INTEGER);
}
@Test
public void evalshaWithMulti() throws Exception {
redis.scriptFlush();
String digest = redis.digest("return {1234, 5678}");
exception.expectMessage("NOSCRIPT No matching script. Please use EVAL.");
redis.evalsha(digest, MULTI);
}
@Test
public void evalshaWithKeys() throws Exception {
redis.scriptFlush();
String digest = redis.scriptLoad("return {KEYS[1], KEYS[2]}");
assertThat((Object) redis.evalsha(digest, MULTI, "one", "two")).isEqualTo(list("one", "two"));
}
@Test
public void evalshaWithArgs() throws Exception {
redis.scriptFlush();
String digest = redis.scriptLoad("return {ARGV[1], ARGV[2]}");
String[] keys = new String[0];
assertThat((Object) redis.evalsha(digest, MULTI, keys, "a", "b")).isEqualTo(list("a", "b"));
}
@Test
public void script() throws Exception {
assertThat(redis.scriptFlush()).isEqualTo("OK");
String script1 = "return 1 + 1";
String digest1 = redis.digest(script1);
String script2 = "return 1 + 1 == 4";
String digest2 = redis.digest(script2);
assertThat(redis.scriptExists(digest1, digest2)).isEqualTo(list(false, false));
assertThat(redis.scriptLoad(script1)).isEqualTo(digest1);
assertThat((Object) redis.evalsha(digest1, INTEGER)).isEqualTo(2L);
assertThat(redis.scriptExists(digest1, digest2)).isEqualTo(list(true, false));
assertThat(redis.scriptFlush()).isEqualTo("OK");
assertThat(redis.scriptExists(digest1, digest2)).isEqualTo(list(false, false));
redis.configSet("lua-time-limit", "10");
RedisAsyncConnection<String, String> async = client.connectAsync();
try {
async.eval("while true do end", STATUS, new String[0]);
Thread.sleep(100);
assertThat(redis.scriptKill()).isEqualTo("OK");
} finally {
async.close();
}
}
}