// ---------------------------------------------------------------------- // File: dispatcher.cc // Author: Georgios Bitzes - CERN // ---------------------------------------------------------------------- /************************************************************************ * quarkdb - a redis-like highly available key-value store * * Copyright (C) 2016 CERN/Switzerland * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see .* ************************************************************************/ #include "Dispatcher.hh" #include "BufferedReader.hh" #include "StateMachine.hh" #include "pubsub/Publisher.hh" #include using namespace quarkdb; #define ASSERT_OK(msg) ASSERT_TRUE(msg.ok()) #define ASSERT_NOTFOUND(msg) ASSERT_TRUE(msg.IsNotFound()) class Dispatcher_ : public ::testing::Test { protected: Dispatcher_() : store("/tmp/rocksdb-testdb"), conn(&link), reader(&link), dispatcher(store, publisher) { store.flushall(); conn.setResponseBuffering(false); } void assert_reply(RedisRequest &&request, const std::string &reply) { EXPECT_EQ(dispatcher.dispatch(&conn, request), (int) reply.size()); std::string tmp; ASSERT_EQ(reader.consume(reply.size(), tmp), (int) reply.size()); ASSERT_EQ(tmp, reply); } StateMachine store; Link link; Connection conn; BufferedReader reader; Publisher publisher; RedisDispatcher dispatcher; std::string buffer; }; TEST_F(Dispatcher_, T1) { assert_reply( {"wrOng CoMmand"}, "-ERR unknown command 'wrOng CoMmand'\r\n"); assert_reply( {"PINGGG"}, "-ERR unknown command 'PINGGG'\r\n"); assert_reply( {"PIN"}, "-ERR unknown command 'PIN'\r\n"); assert_reply( {"ping"}, "+PONG\r\n" ); assert_reply( {"Ping"}, "+PONG\r\n" ); assert_reply( {"PiNg"}, "+PONG\r\n" ); assert_reply( {"PING"}, "+PONG\r\n" ); assert_reply( {"flushall"}, "+OK\r\n" ); assert_reply( {"Fflushall"}, "-ERR unknown command 'Fflushall'\r\n" ); assert_reply( {"set", "abc", "12345"}, "+OK\r\n"); ASSERT_OK(store.get("abc", buffer)); ASSERT_EQ(buffer, "12345"); assert_reply( {"set", "qqq", "ppp"}, "+OK\r\n"); ASSERT_OK(store.get("qqq", buffer)); ASSERT_EQ(buffer, "ppp"); assert_reply( {"get", "abc"}, "$5\r\n12345\r\n"); assert_reply( {"get", "notexists"}, "$-1\r\n"); assert_reply( {"exists", "notexists"}, ":0\r\n"); assert_reply( {"exists", "notexists", "abc"}, ":1\r\n"); assert_reply( {"exists", "abc"}, ":1\r\n"); assert_reply( {"exists", "abc", "qqq"}, ":2\r\n"); assert_reply( {"exists", "abc", "notexists", "qqq"}, ":2\r\n"); assert_reply( {"del", "notexists"}, ":0\r\n"); assert_reply( {"del", "abc", "qqq"}, ":2\r\n"); assert_reply( {"exists", "abc", "qqq"}, ":0\r\n"); assert_reply( {"keys", "*" }, "*0\r\n"); assert_reply( {"set", "abc", "12345"}, "+OK\r\n"); assert_reply( {"set", "qqq", "ppp"}, "+OK\r\n"); assert_reply( {"keys", "*" }, "*2\r\n$3\r\nabc\r\n$3\r\nqqq\r\n"); assert_reply( {"keys", "a*" }, "*1\r\n$3\r\nabc\r\n"); assert_reply( {"keys", "q*" }, "*1\r\n$3\r\nqqq\r\n"); assert_reply( {"hset", "myhash", "abc", "123"}, ":1\r\n"); assert_reply( {"hset", "myhash", "abc", "12345"}, ":0\r\n"); assert_reply( {"hget", "myhash", "abc" }, "$5\r\n12345\r\n"); assert_reply( {"keys", "myh*" }, "*1\r\n$6\r\nmyhash\r\n"); assert_reply( {"hget", "myhash", "abc", "cde"}, "-ERR wrong number of arguments for 'hget' command\r\n"); assert_reply( {"hexists", "myhash", "abc" }, ":1\r\n"); assert_reply( {"hexists", "myhash", "notexist" }, ":0\r\n"); assert_reply( {"hset", "myhash", "key2", "54321"}, ":1\r\n"); assert_reply( {"hkeys", "myhash" }, "*2\r\n$3\r\nabc\r\n$4\r\nkey2\r\n"); assert_reply( {"hkeys", "notexists" }, "*0\r\n"); assert_reply( {"hgetall", "myhash"}, "*4\r\n$3\r\nabc\r\n$5\r\n12345\r\n$4\r\nkey2\r\n$5\r\n54321\r\n"); assert_reply( {"hvals", "myhash"}, "*2\r\n$5\r\n12345\r\n$5\r\n54321\r\n"); assert_reply( {"hscan", "myhash", "0"}, "*2\r\n$1\r\n0\r\n" "*4\r\n$3\r\nabc\r\n$5\r\n12345\r\n$4\r\nkey2\r\n$5\r\n54321\r\n"); assert_reply( {"hincrby", "myhash", "counter", "1"}, ":1\r\n"); assert_reply( {"hincrby", "myhash", "counter", "2"}, ":3\r\n"); assert_reply( {"hincrby", "myhash", "counter", "-3"}, ":0\r\n"); assert_reply( {"hlen", "myhash"}, ":3\r\n"); assert_reply( {"hdel", "myhash", "counter", "key2"}, ":2\r\n"); assert_reply( {"hvals", "myhash"}, "*1\r\n$5\r\n12345\r\n"); assert_reply( {"hlen", "myhash"}, ":1\r\n"); assert_reply( {"hdel", "myhash", "counter", "key2", "abc"}, ":1\r\n"); assert_reply( {"hlen", "myhash"}, ":0\r\n"); assert_reply( {"hscan", "myhash", "0"}, "*2\r\n$1\r\n0\r\n*0\r\n"); assert_reply( {"sadd", "myset", "a", "b", "c", "d" }, ":4\r\n"); assert_reply( {"sadd", "myset", "a", "b", "c", "d" }, ":0\r\n"); assert_reply( {"sadd", "myset", "b", "c", "d", "e", "f" }, ":2\r\n"); assert_reply( {"sismember", "myset", "a"}, ":1\r\n"); assert_reply( {"sismember", "myset", "e"}, ":1\r\n"); assert_reply( {"sismember", "myset", "g"}, ":0\r\n"); assert_reply( {"smembers", "myset"}, "*6\r\n$1\r\na\r\n$1\r\nb\r\n$1\r\nc\r\n$1\r\nd\r\n$1\r\ne\r\n$1\r\nf\r\n"); assert_reply( {"sscan", "myset", "0"}, "*2\r\n$1\r\n0\r\n*6\r\n$1\r\na\r\n$1\r\nb\r\n$1\r\nc\r\n$1\r\nd\r\n$1\r\ne\r\n$1\r\nf\r\n"); assert_reply( {"scard", "myset"}, ":6\r\n"); assert_reply( {"scard", "asdf"}, ":0\r\n"); assert_reply( {"srem", "myset", "a", "b"}, ":2\r\n"); assert_reply( {"smembers", "myset"}, "*4\r\n$1\r\nc\r\n$1\r\nd\r\n$1\r\ne\r\n$1\r\nf\r\n"); assert_reply( {"srem", "myset", "a", "b"}, ":0\r\n"); assert_reply( {"srem", "myset", "a", "b", "c"}, ":1\r\n"); assert_reply( {"sismember", "myset", "a"}, ":0\r\n"); assert_reply( {"smembers", "myset"}, "*3\r\n$1\r\nd\r\n$1\r\ne\r\n$1\r\nf\r\n"); assert_reply( {"sscan", "myset", "0"}, "*2\r\n$1\r\n0\r\n*3\r\n$1\r\nd\r\n$1\r\ne\r\n$1\r\nf\r\n"); assert_reply( {"smembers", "asdf"}, "*0\r\n"); assert_reply( {"scard", "myset"}, ":3\r\n"); assert_reply( {"sscan", "asdf", "0"}, "*2\r\n$1\r\n0\r\n*0\r\n"); }