brpc_grpc_protocol_unittest.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. // Licensed to the Apache Software Foundation (ASF) under one
  2. // or more contributor license agreements. See the NOTICE file
  3. // distributed with this work for additional information
  4. // regarding copyright ownership. The ASF licenses this file
  5. // to you under the Apache License, Version 2.0 (the
  6. // "License"); you may not use this file except in compliance
  7. // with the License. You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing,
  12. // software distributed under the License is distributed on an
  13. // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  14. // KIND, either express or implied. See the License for the
  15. // specific language governing permissions and limitations
  16. // under the License.
  17. #include <gtest/gtest.h>
  18. #include <gflags/gflags.h>
  19. #include "brpc/controller.h"
  20. #include "brpc/server.h"
  21. #include "brpc/channel.h"
  22. #include "brpc/grpc.h"
  23. #include "butil/time.h"
  24. #include "grpc.pb.h"
  25. int main(int argc, char* argv[]) {
  26. testing::InitGoogleTest(&argc, argv);
  27. GFLAGS_NS::ParseCommandLineFlags(&argc, &argv, true);
  28. if (GFLAGS_NS::SetCommandLineOption("http_body_compress_threshold", "0").empty()) {
  29. std::cerr << "Fail to set -crash_on_fatal_log" << std::endl;
  30. return -1;
  31. }
  32. if (GFLAGS_NS::SetCommandLineOption("crash_on_fatal_log", "true").empty()) {
  33. std::cerr << "Fail to set -crash_on_fatal_log" << std::endl;
  34. return -1;
  35. }
  36. return RUN_ALL_TESTS();
  37. }
  38. namespace {
  39. const std::string g_server_addr = "127.0.0.1:8011";
  40. const std::string g_prefix = "Hello, ";
  41. const std::string g_req = "wyt";
  42. const int64_t g_timeout_ms = 1000;
  43. const std::string g_protocol = "h2:grpc";
  44. class MyGrpcService : public ::test::GrpcService {
  45. public:
  46. void Method(::google::protobuf::RpcController* cntl_base,
  47. const ::test::GrpcRequest* req,
  48. ::test::GrpcResponse* res,
  49. ::google::protobuf::Closure* done) {
  50. brpc::Controller* cntl =
  51. static_cast<brpc::Controller*>(cntl_base);
  52. brpc::ClosureGuard done_guard(done);
  53. EXPECT_EQ(g_req, req->message());
  54. if (req->gzip()) {
  55. cntl->set_response_compress_type(brpc::COMPRESS_TYPE_GZIP);
  56. }
  57. res->set_message(g_prefix + req->message());
  58. if (req->return_error()) {
  59. cntl->SetFailed(brpc::EINTERNAL, "%s", g_prefix.c_str());
  60. return;
  61. }
  62. if (req->has_timeout_us()) {
  63. if (req->timeout_us() < 0) {
  64. EXPECT_EQ(-1, cntl->deadline_us());
  65. } else {
  66. EXPECT_NEAR(cntl->deadline_us(),
  67. butil::gettimeofday_us() + req->timeout_us(), 5000);
  68. }
  69. }
  70. }
  71. void MethodTimeOut(::google::protobuf::RpcController* cntl_base,
  72. const ::test::GrpcRequest* req,
  73. ::test::GrpcResponse* res,
  74. ::google::protobuf::Closure* done) {
  75. brpc::ClosureGuard done_guard(done);
  76. bthread_usleep(2000000 /*2s*/);
  77. res->set_message(g_prefix + req->message());
  78. return;
  79. }
  80. };
  81. class GrpcTest : public ::testing::Test {
  82. protected:
  83. GrpcTest() {
  84. EXPECT_EQ(0, _server.AddService(&_svc, brpc::SERVER_DOESNT_OWN_SERVICE));
  85. EXPECT_EQ(0, _server.Start(g_server_addr.c_str(), NULL));
  86. brpc::ChannelOptions options;
  87. options.protocol = g_protocol;
  88. options.timeout_ms = g_timeout_ms;
  89. EXPECT_EQ(0, _channel.Init(g_server_addr.c_str(), "", &options));
  90. }
  91. virtual ~GrpcTest() {};
  92. virtual void SetUp() {};
  93. virtual void TearDown() {};
  94. void CallMethod(bool req_gzip, bool res_gzip) {
  95. test::GrpcRequest req;
  96. test::GrpcResponse res;
  97. brpc::Controller cntl;
  98. if (req_gzip) {
  99. cntl.set_request_compress_type(brpc::COMPRESS_TYPE_GZIP);
  100. }
  101. req.set_message(g_req);
  102. req.set_gzip(res_gzip);
  103. req.set_return_error(false);
  104. test::GrpcService_Stub stub(&_channel);
  105. stub.Method(&cntl, &req, &res, NULL);
  106. EXPECT_FALSE(cntl.Failed()) << cntl.ErrorCode() << ": " << cntl.ErrorText();
  107. EXPECT_EQ(res.message(), g_prefix + g_req);
  108. }
  109. brpc::Server _server;
  110. MyGrpcService _svc;
  111. brpc::Channel _channel;
  112. };
  113. TEST_F(GrpcTest, percent_encode) {
  114. std::string out;
  115. std::string s1("abcdefg !@#$^&*()/");
  116. std::string s1_out("abcdefg%20%21%40%23%24%5e%26%2a%28%29%2f");
  117. brpc::PercentEncode(s1, &out);
  118. EXPECT_TRUE(out == s1_out) << s1_out << " vs " << out;
  119. char s2_buf[] = "\0\0%\33\35 brpc";
  120. std::string s2(s2_buf, sizeof(s2_buf) - 1);
  121. std::string s2_expected_out("%00%00%25%1b%1d%20brpc");
  122. brpc::PercentEncode(s2, &out);
  123. EXPECT_TRUE(out == s2_expected_out) << s2_expected_out << " vs " << out;
  124. }
  125. TEST_F(GrpcTest, percent_decode) {
  126. std::string out;
  127. std::string s1("abcdefg%20%21%40%23%24%5e%26%2a%28%29%2f");
  128. std::string s1_out("abcdefg !@#$^&*()/");
  129. brpc::PercentDecode(s1, &out);
  130. EXPECT_TRUE(out == s1_out) << s1_out << " vs " << out;
  131. std::string s2("%00%00%1b%1d%20brpc");
  132. char s2_expected_out_buf[] = "\0\0\33\35 brpc";
  133. std::string s2_expected_out(s2_expected_out_buf, sizeof(s2_expected_out_buf) - 1);
  134. brpc::PercentDecode(s2, &out);
  135. EXPECT_TRUE(out == s2_expected_out) << s2_expected_out << " vs " << out;
  136. }
  137. TEST_F(GrpcTest, sanity) {
  138. for (int i = 0; i < 2; ++i) { // if req use gzip or not
  139. for (int j = 0; j < 2; ++j) { // if res use gzip or not
  140. CallMethod(i, j);
  141. }
  142. }
  143. }
  144. TEST_F(GrpcTest, return_error) {
  145. test::GrpcRequest req;
  146. test::GrpcResponse res;
  147. brpc::Controller cntl;
  148. req.set_message(g_req);
  149. req.set_gzip(false);
  150. req.set_return_error(true);
  151. test::GrpcService_Stub stub(&_channel);
  152. stub.Method(&cntl, &req, &res, NULL);
  153. EXPECT_TRUE(cntl.Failed());
  154. EXPECT_EQ(cntl.ErrorCode(), brpc::EINTERNAL);
  155. EXPECT_TRUE(butil::StringPiece(cntl.ErrorText()).ends_with(butil::string_printf("%s", g_prefix.c_str())));
  156. }
  157. TEST_F(GrpcTest, RpcTimedOut) {
  158. brpc::Channel channel;
  159. brpc::ChannelOptions options;
  160. options.protocol = g_protocol;
  161. options.timeout_ms = g_timeout_ms;
  162. EXPECT_EQ(0, channel.Init(g_server_addr.c_str(), "", &options));
  163. test::GrpcRequest req;
  164. test::GrpcResponse res;
  165. brpc::Controller cntl;
  166. req.set_message(g_req);
  167. req.set_gzip(false);
  168. req.set_return_error(false);
  169. test::GrpcService_Stub stub(&_channel);
  170. stub.MethodTimeOut(&cntl, &req, &res, NULL);
  171. EXPECT_TRUE(cntl.Failed());
  172. EXPECT_EQ(cntl.ErrorCode(), brpc::ERPCTIMEDOUT);
  173. }
  174. TEST_F(GrpcTest, MethodNotExist) {
  175. test::GrpcRequest req;
  176. test::GrpcResponse res;
  177. brpc::Controller cntl;
  178. req.set_message(g_req);
  179. req.set_gzip(false);
  180. req.set_return_error(false);
  181. test::GrpcService_Stub stub(&_channel);
  182. stub.MethodNotExist(&cntl, &req, &res, NULL);
  183. EXPECT_TRUE(cntl.Failed());
  184. EXPECT_EQ(cntl.ErrorCode(), brpc::EINTERNAL);
  185. ASSERT_TRUE(butil::StringPiece(cntl.ErrorText()).ends_with("Method MethodNotExist() not implemented."));
  186. }
  187. TEST_F(GrpcTest, GrpcTimeOut) {
  188. const char* timeouts[] = {
  189. // valid case
  190. "2H", "7200000000",
  191. "3M", "180000000",
  192. "+1S", "1000000",
  193. "4m", "4000",
  194. "5u", "5",
  195. "6n", "1",
  196. // invalid case
  197. "30A", "-1",
  198. "123ASH", "-1",
  199. "HHHH", "-1",
  200. "112", "-1",
  201. "H999m", "-1",
  202. "", "-1"
  203. };
  204. // test all timeout format
  205. for (size_t i = 0; i < arraysize(timeouts); i = i + 2) {
  206. test::GrpcRequest req;
  207. test::GrpcResponse res;
  208. brpc::Controller cntl;
  209. req.set_message(g_req);
  210. req.set_gzip(false);
  211. req.set_return_error(false);
  212. req.set_timeout_us((int64_t)(strtol(timeouts[i+1], NULL, 10)));
  213. cntl.set_timeout_ms(-1);
  214. cntl.http_request().SetHeader("grpc-timeout", timeouts[i]);
  215. test::GrpcService_Stub stub(&_channel);
  216. stub.Method(&cntl, &req, &res, NULL);
  217. EXPECT_FALSE(cntl.Failed());
  218. }
  219. // test timeout by using timeout_ms in cntl
  220. {
  221. test::GrpcRequest req;
  222. test::GrpcResponse res;
  223. brpc::Controller cntl;
  224. req.set_message(g_req);
  225. req.set_gzip(false);
  226. req.set_return_error(false);
  227. req.set_timeout_us(9876000);
  228. cntl.set_timeout_ms(9876);
  229. test::GrpcService_Stub stub(&_channel);
  230. stub.Method(&cntl, &req, &res, NULL);
  231. EXPECT_FALSE(cntl.Failed());
  232. }
  233. // test timeout by using timeout_ms in channel
  234. {
  235. test::GrpcRequest req;
  236. test::GrpcResponse res;
  237. brpc::Controller cntl;
  238. req.set_message(g_req);
  239. req.set_gzip(false);
  240. req.set_return_error(false);
  241. req.set_timeout_us(g_timeout_ms * 1000);
  242. test::GrpcService_Stub stub(&_channel);
  243. stub.Method(&cntl, &req, &res, NULL);
  244. EXPECT_FALSE(cntl.Failed());
  245. }
  246. }
  247. } // namespace