LogCabin
|
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 <deque> 00018 #include <queue> 00019 #include <memory> 00020 #include <utility> 00021 00022 #include "Core/ProtoBuf.h" 00023 #include "Client/LeaderRPC.h" 00024 00025 #ifndef LOGCABIN_CLIENT_LEADERRPCMOCK_H 00026 #define LOGCABIN_CLIENT_LEADERRPCMOCK_H 00027 00028 namespace LogCabin { 00029 namespace Client { 00030 00031 /** 00032 * This class is used in unit testing to interpose when clients send RPCs to 00033 * the leader of the LogCabin cluster. 00034 */ 00035 class LeaderRPCMock : public LeaderRPCBase { 00036 public: 00037 typedef std::unique_ptr<google::protobuf::Message> MessagePtr; 00038 /// Constructor. 00039 LeaderRPCMock(); 00040 /// Destructor. 00041 ~LeaderRPCMock(); 00042 /** 00043 * Expect the next request operation to have type opCode, and return it 00044 * the given response. 00045 */ 00046 void expect(OpCode opCode, 00047 const google::protobuf::Message& response); 00048 /** 00049 * Pop the first request from the queue. 00050 */ 00051 MessagePtr popRequest(); 00052 00053 /** 00054 * Mocks out an RPC call. 00055 * You should have called expect prior to this to prime a response. 00056 * The request will be logged so you can pop it. 00057 */ 00058 Status call(OpCode opCode, 00059 const google::protobuf::Message& request, 00060 google::protobuf::Message& response, 00061 TimePoint timeout); 00062 00063 /// See LeaderRPCBase::makeCall. 00064 std::unique_ptr<LeaderRPCBase::Call> makeCall(); 00065 00066 private: 00067 /// See LeaderRPCBase::Call. 00068 class Call : public LeaderRPCBase::Call { 00069 public: 00070 explicit Call(LeaderRPCMock& leaderRPC); 00071 void start(OpCode opCode, 00072 const google::protobuf::Message& request, 00073 TimePoint timeout); 00074 void cancel(); 00075 Status wait(google::protobuf::Message& response, 00076 TimePoint timeout); 00077 LeaderRPCMock& leaderRPC; 00078 bool canceled; 00079 }; 00080 00081 /** 00082 * A queue of requests that have come in from call(). 00083 */ 00084 std::deque<std::pair<OpCode, MessagePtr>> requestLog; 00085 /** 00086 * A queue of responses that have been primed from expect(). 00087 */ 00088 std::queue<std::pair<OpCode, MessagePtr>> responseQueue; 00089 }; 00090 00091 } // namespace Client 00092 } // namespace LogCabin 00093 00094 #endif /* LOGCABIN_CLIENT_LEADERRPC_H */