// ----------------------------------------------------------------------
// File: raft-talker.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 "utils/IntToBinaryString.hh"
#include "raft/RaftTalker.hh"
#include "raft/RaftContactDetails.hh"
#include "Common.hh"
#include "Version.hh"
#include "test-utils.hh"
#include "RedisParser.hh"
#include
using namespace quarkdb;
TEST(RaftTalker, T1) {
std::string clusterID = "b50da34e-ac15-4c02-b5a7-296454e5f779";
RaftTimeouts timeouts(std::chrono::milliseconds(1), std::chrono::milliseconds(2),
std::chrono::milliseconds(3));
RaftServer node = {"localhost", 12344};
RaftServer myself = {"its_me_ur_leader", 1337};
RaftContactDetails cd(clusterID, timeouts, "");
RaftTalker talker(node, cd, "some-client-name");
SocketListener listener(12344);
int s2 = listener.accept();
ASSERT_GT(s2, 0);
Link link(s2);
RedisParser parser(&link);
RedisRequest req;
int rc;
while( (rc = parser.fetch(req, true)) == 0) ;
ASSERT_EQ(rc, 1);
RedisRequest tmp = {"RAFT_HANDSHAKE", VERSION_FULL_STRING, clusterID, timeouts.toString()};
ASSERT_EQ(req, tmp);
link.Send("+OK\r\n");
// send an append entries message over the talker
std::vector entries;
entries.emplace_back(RaftEntry(3, "SET", "abc", "asdf").serialize());
entries.emplace_back(RaftEntry(12, "SET", "abcd", "1234").serialize());
entries.emplace_back(RaftEntry(12, "HSET", "myhash", "key", "value").serialize());
// valid request
talker.appendEntries(
12, myself, // my state
7, 11, // previous entry
3, // commit index
entries // payload
);
while( (rc = parser.fetch(req, true)) == 0) ;
ASSERT_EQ(rc, 1);
tmp = {"CLIENT", "SETNAME", "some-client-name"};
ASSERT_EQ(req, tmp);
link.Send("+OK\r\n");
while( (rc = parser.fetch(req, true)) == 0) ;
ASSERT_EQ(rc, 1);
tmp = {"QUARKDB_VERSION"};
ASSERT_EQ(req, tmp);
link.Send("$6\r\n1.33.7\r\n");
while( talker.getNodeVersion() != "1.33.7" ) ;
while( (rc = parser.fetch(req, true)) == 0) ;
ASSERT_EQ(rc, 1);
tmp = {"RAFT_APPEND_ENTRIES", "its_me_ur_leader:1337",
intToBinaryString(12) + intToBinaryString(7) + intToBinaryString(11) +
intToBinaryString(3) + intToBinaryString(3),
entries[0],
entries[1],
entries[2]
};
ASSERT_EQ(req, tmp);
}