LogCabin
Client/LeaderRPCMock.cc
Go to the documentation of this file.
00001 /* Copyright (c) 2012 Stanford University
00002  * Copyright (c) 2014 Diego Ongaro
00003  *
00004  * Permission to use, copy, modify, and distribute this software for any
00005  * purpose with or without fee is hereby granted, provided that the above
00006  * copyright notice and this permission notice appear in all copies.
00007  *
00008  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES
00009  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
00010  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR
00011  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00012  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
00013  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
00014  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00015  */
00016 
00017 #include <gtest/gtest.h>
00018 
00019 #include "Core/Debug.h"
00020 #include "Client/LeaderRPCMock.h"
00021 #include "Core/ProtoBuf.h"
00022 
00023 namespace LogCabin {
00024 namespace Client {
00025 
00026 LeaderRPCMock::LeaderRPCMock()
00027     : requestLog()
00028     , responseQueue()
00029 {
00030 }
00031 
00032 LeaderRPCMock::~LeaderRPCMock()
00033 {
00034 }
00035 
00036 void
00037 LeaderRPCMock::expect(OpCode opCode,
00038                       const google::protobuf::Message& response)
00039 {
00040     MessagePtr responseCopy(response.New());
00041     responseCopy->CopyFrom(response);
00042     responseQueue.push({opCode, std::move(responseCopy)});
00043 }
00044 
00045 LeaderRPCMock::MessagePtr
00046 LeaderRPCMock::popRequest()
00047 {
00048     MessagePtr request = std::move(requestLog.at(0).second);
00049     requestLog.pop_front();
00050     return std::move(request);
00051 }
00052 
00053 LeaderRPCMock::Status
00054 LeaderRPCMock::call(OpCode opCode,
00055           const google::protobuf::Message& request,
00056           google::protobuf::Message& response,
00057           TimePoint timeout)
00058 {
00059     if (timeout < Clock::now())
00060         return Status::TIMEOUT;
00061     Call c(*this);
00062     c.start(opCode, request, timeout);
00063     c.wait(response, timeout);
00064     return Status::OK;
00065 }
00066 
00067 LeaderRPCMock::Call::Call(LeaderRPCMock& leaderRPC)
00068     : leaderRPC(leaderRPC)
00069     , canceled(false)
00070 {
00071 }
00072 
00073 void
00074 LeaderRPCMock::Call::start(OpCode opCode,
00075                            const google::protobuf::Message& request,
00076                            TimePoint timeout)
00077 {
00078     MessagePtr requestCopy(request.New());
00079     requestCopy->CopyFrom(request);
00080     leaderRPC.requestLog.push_back({opCode, std::move(requestCopy)});
00081     EXPECT_LT(0U, leaderRPC.responseQueue.size())
00082         << "The client sent an unexpected RPC:\n"
00083         << request.GetTypeName() << ":\n"
00084         << Core::ProtoBuf::dumpString(request);
00085     if (leaderRPC.responseQueue.empty())
00086         throw std::runtime_error("unexpected RPC");
00087     auto& opCodeMsgPair = leaderRPC.responseQueue.front();
00088     EXPECT_EQ(opCode, opCodeMsgPair.first);
00089 }
00090 
00091 void
00092 LeaderRPCMock::Call::cancel()
00093 {
00094     canceled = true;
00095 }
00096 
00097 LeaderRPCMock::Call::Status
00098 LeaderRPCMock::Call::wait(google::protobuf::Message& response,
00099                           TimePoint timeout)
00100 {
00101     if (canceled) {
00102         leaderRPC.responseQueue.pop();
00103         return Status::RETRY;
00104     }
00105     auto& opCodeMsgPair = leaderRPC.responseQueue.front();
00106     response.CopyFrom(*opCodeMsgPair.second);
00107     leaderRPC.responseQueue.pop();
00108     return Status::OK;
00109 }
00110 
00111 std::unique_ptr<LeaderRPCBase::Call>
00112 LeaderRPCMock::makeCall()
00113 {
00114     return std::unique_ptr<LeaderRPCBase::Call>(new Call(*this));
00115 }
00116 
00117 } // namespace LogCabin::Client
00118 } // namespace LogCabin
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines