| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more contributor license |
| * agreements. See the NOTICE file distributed with this work for additional information regarding |
| * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance with the License. You may obtain a |
| * copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software distributed under the License |
| * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
| * or implied. See the License for the specific language governing permissions and limitations under |
| * the License. |
| */ |
| |
| package org.apache.geode.redis.internal.executor.key; |
| |
| import static org.assertj.core.api.Assertions.assertThat; |
| import static org.assertj.core.api.Assertions.assertThatThrownBy; |
| |
| import java.io.UnsupportedEncodingException; |
| import java.nio.ByteBuffer; |
| |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Test; |
| import redis.clients.jedis.Jedis; |
| import redis.clients.jedis.Protocol; |
| |
| import org.apache.geode.test.awaitility.GeodeAwaitility; |
| import org.apache.geode.test.dunit.rules.RedisPortSupplier; |
| |
| public abstract class AbstractKeysIntegrationTest implements RedisPortSupplier { |
| |
| private Jedis jedis; |
| private static final int REDIS_CLIENT_TIMEOUT = |
| Math.toIntExact(GeodeAwaitility.getTimeout().toMillis()); |
| |
| @Before |
| public void setUp() { |
| jedis = new Jedis("localhost", getPort(), REDIS_CLIENT_TIMEOUT); |
| } |
| |
| @After |
| public void tearDown() { |
| jedis.flushAll(); |
| jedis.close(); |
| } |
| |
| @Test |
| public void givenPatternNotProvided_returnsWrongNumberOfArgumentsError() { |
| assertThatThrownBy(() -> jedis.sendCommand(Protocol.Command.KEYS)) |
| .hasMessageContaining("ERR wrong number of arguments for 'keys' command"); |
| } |
| |
| @Test |
| public void givenMoreThanTwoArguments_returnsWrongNumberOfArgumentsError() { |
| assertThatThrownBy(() -> jedis.sendCommand(Protocol.Command.KEYS, "*", "extraArg")) |
| .hasMessageContaining("ERR wrong number of arguments for 'keys' command"); |
| } |
| |
| @Test |
| public void givenSplat_withASCIIdata_returnsExpectedMatches() { |
| jedis.set("string1", "v1"); |
| jedis.sadd("set1", "member1"); |
| jedis.hset("hash1", "key1", "field1"); |
| assertThat(jedis.keys("*")).containsExactlyInAnyOrder("string1", "set1", "hash1"); |
| assertThat(jedis.keys("s*")).containsExactlyInAnyOrder("string1", "set1"); |
| assertThat(jedis.keys("h*")).containsExactlyInAnyOrder("hash1"); |
| assertThat(jedis.keys("foo*")).isEmpty(); |
| } |
| |
| @Test |
| public void givenSplat_withBinaryData_returnsExpectedMatches() { |
| byte[] stringKey = |
| new byte[] {(byte) 0xac, (byte) 0xed, 0, 4, 0, 5, 's', 't', 'r', 'i', 'n', 'g', '1'}; |
| byte[] value = new byte[] {'v', '1'}; |
| jedis.set(stringKey, value); |
| byte[] setKey = new byte[] {(byte) 0xac, (byte) 0xed, 0, 4, 0, 5, 's', 'e', 't', '1'}; |
| byte[] member = new byte[] {'m', '1'}; |
| jedis.sadd(setKey, member); |
| byte[] hashKey = new byte[] {(byte) 0xac, (byte) 0xed, 0, 4, 0, 5, 'h', 'a', 's', 'h', '1'}; |
| byte[] key = new byte[] {'k', 'e', 'y', '1'}; |
| jedis.hset(hashKey, key, value); |
| assertThat(jedis.exists(stringKey)); |
| assertThat(jedis.exists(setKey)); |
| assertThat(jedis.exists(hashKey)); |
| assertThat(jedis.keys(new byte[] {'*'})).containsExactlyInAnyOrder(stringKey, setKey, hashKey); |
| assertThat(jedis.keys(new byte[] {(byte) 0xac, (byte) 0xed, 0, 4, 0, 5, 's', '*'})) |
| .containsExactlyInAnyOrder(stringKey, setKey); |
| assertThat(jedis.keys(new byte[] {(byte) 0xac, (byte) 0xed, 0, 4, 0, 5, 'h', '*'})) |
| .containsExactlyInAnyOrder(hashKey); |
| assertThat(jedis.keys(new byte[] {'f', '*'})).isEmpty(); |
| } |
| |
| @Test |
| public void givenBinaryValue_withExactMatch_preservesBinaryData() |
| throws UnsupportedEncodingException { |
| String chinese_utf16 = "子"; |
| byte[] utf16encodedBytes = chinese_utf16.getBytes("UTF-16"); |
| byte[] stringKey = |
| new byte[] {(byte) 0xac, (byte) 0xed, 0, 4, 0, 5, 's', 't', 'r', 'i', 'n', 'g', '1'}; |
| byte[] allByteArray = new byte[utf16encodedBytes.length + stringKey.length]; |
| |
| ByteBuffer buff = ByteBuffer.wrap(allByteArray); |
| buff.put(utf16encodedBytes); |
| buff.put(stringKey); |
| byte[] combined = buff.array(); |
| |
| jedis.set(combined, combined); |
| assertThat(jedis.keys("*".getBytes())).containsExactlyInAnyOrder(combined); |
| } |
| |
| @Test |
| public void givenSplat_withCarriageReturnLineFeedAndTab_returnsExpectedMatches() { |
| jedis.set(" foo bar ", "123"); |
| jedis.set(" foo\r\nbar\r\n ", "456"); |
| jedis.set(" \r\n\t\\x07\\x13 ", "789"); |
| |
| assertThat(jedis.keys("*")).containsExactlyInAnyOrder(" \r\n\t\\x07\\x13 ", " foo\r\nbar\r\n ", |
| " foo bar "); |
| } |
| |
| @Test |
| public void givenMalformedGlobPattern_returnsEmptySet() { |
| assertThat(jedis.keys("[][]")).isEmpty(); |
| } |
| } |