Loading...
Searching...
No Matches
resdb_test.cpp
Go to the documentation of this file.
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20#include <glog/logging.h>
21#include <gmock/gmock.h>
22#include <gtest/gtest.h>
23
24#include <thread>
25
31#include "platform/test/proto/resdb_test.pb.h"
32
33namespace resdb {
34
35using ::testing::ElementsAreArray;
36using ::testing::Test;
37
38const std::string test_dir = std::string(getenv("TEST_SRCDIR")) + "/" +
39 std::string(getenv("TEST_WORKSPACE")) +
40 "/platform/test/";
41
43 public:
45
46 int Set(int seq) {
47 TestRequest request;
48 request.set_seq(seq);
49 TestResponse response;
50 return SendRequest(request, &response);
51 }
52};
53
55 public:
56 ResDBTestManager(const ResDBConfig& config) : config_(config) {}
57 std::vector<int> GetSeqs() { return seqs_; }
58
59 protected:
60 std::unique_ptr<std::string> ExecuteData(const std::string& request) {
61 TestRequest test_request;
62 // TestResponse test_response;
63 if (!test_request.ParseFromString(request)) {
64 LOG(ERROR) << "parse data fail";
65 return nullptr;
66 }
67 seqs_.push_back(test_request.seq());
68 return nullptr;
69 }
70
72 std::vector<int> seqs_;
73};
74
75class ResDBTest : public Test {
76 public:
77 void StartServer() {}
78
79 void StartOneServer(int server_id) {
80 ResDBConfig config = GetConfig(server_id);
81 config.SetTestMode(true);
82 auto executor = std::make_unique<ResDBTestManager>(config);
83 executors_.push_back(executor.get());
84 server_.push_back(std::make_unique<ServiceNetwork>(
85 config,
86 std::make_unique<ConsensusManagerPBFT>(config, std::move(executor))));
87 server_thread_.push_back(std::thread(
88 [&](ServiceNetwork* server) { server->Run(); }, server_.back().get()));
89 }
90
92 for (auto& server : server_) {
93 while (true) {
94 std::unique_lock<std::mutex> lk(mutex_);
95 cv_.wait_for(lk, std::chrono::microseconds(1000),
96 [&] { return server->ServiceIsReady(); });
97 if (server->ServiceIsReady()) {
98 break;
99 }
100 }
101 }
102 }
103
104 void WaitExecutorDone(int received_num) {
105 for (auto executor : executors_) {
106 while (static_cast<int>(executor->GetSeqs().size()) < received_num) {
107 usleep(10000);
108 }
109 }
110 }
111
112 void Stop() {
113 for (auto& server : server_) {
114 server->Stop();
115 }
116 for (auto& th : server_thread_) {
117 th.join();
118 }
119 server_.clear();
120 }
121
122 std::string GetPrivateKey(int id) {
123 return test_dir + std::string("test_data/node") + std::to_string(id) +
124 ".key.pri";
125 }
126
127 std::string GetCertFile(int id) {
128 return test_dir + std::string("test_data/cert_") + std::to_string(id) +
129 ".cert";
130 }
131
132 std::string GetConfiFile() { return test_dir + "test_data/server.config"; }
133
135 int id, std::optional<ReplicaInfo> replica_info = std::nullopt) {
137 GetCertFile(id), replica_info);
138 }
139
140 protected:
141 std::mutex mutex_;
142 std::condition_variable cv_;
143 std::vector<ResDBTestManager*> executors_;
144 std::vector<std::unique_ptr<ServiceNetwork>> server_;
145 std::vector<std::thread> server_thread_;
146};
147
148TEST_F(ResDBTest, TestPBFTService) {
149 for (int i = 1; i <= 4; ++i) {
150 StartOneServer(i);
151 }
152 WaitAllServerStarted();
153 int client_id = 5;
154 ReplicaInfo client_info = GenerateReplicaInfo(client_id, "127.0.0.1", 80000);
155 auto config = GetConfig(client_id, client_info);
156 ResDBTestClient client(config);
157 EXPECT_EQ(client.Set(1), 0);
158
159 WaitExecutorDone(1);
160
161 for (auto executor : executors_) {
162 EXPECT_THAT(executor->GetSeqs(), ElementsAreArray({1}));
163 }
164
165 Stop();
166}
167
168} // namespace resdb
ResDBTestClient(const ResDBConfig &config)
ResDBTestManager(const ResDBConfig &config)
std::vector< int > GetSeqs()
std::unique_ptr< std::string > ExecuteData(const std::string &request)
std::vector< int > seqs_
void WaitAllServerStarted()
std::vector< ResDBTestManager * > executors_
std::vector< std::thread > server_thread_
std::condition_variable cv_
std::string GetCertFile(int id)
std::string GetConfiFile()
void StartOneServer(int server_id)
std::string GetPrivateKey(int id)
std::vector< std::unique_ptr< ServiceNetwork > > server_
std::mutex mutex_
void WaitExecutorDone(int received_num)
ResDBConfig GetConfig(int id, std::optional< ReplicaInfo > replica_info=std::nullopt)
int SendRequest(const google::protobuf::Message &message, Request::Type type=Request::TYPE_CLIENT_REQUEST)
const std::string test_dir
ReplicaInfo GenerateReplicaInfo(int id, const std::string &ip, int port)
std::unique_ptr< ResDBConfig > GenerateResDBConfig(const std::string &config_file, const std::string &private_key_file, const std::string &cert_file, std::optional< ReplicaInfo > self_info, std::optional< ConfigGenFunc > gen_func)
TEST_F(ResDBTest, TestPBFTService)