brpc_memcache_unittest.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  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 <iostream>
  18. #include "butil/time.h"
  19. #include "butil/logging.h"
  20. #include <brpc/memcache.h>
  21. #include <brpc/channel.h>
  22. #include <gtest/gtest.h>
  23. namespace brpc {
  24. DECLARE_int32(idle_timeout_second);
  25. }
  26. int main(int argc, char* argv[]) {
  27. brpc::FLAGS_idle_timeout_second = 0;
  28. testing::InitGoogleTest(&argc, argv);
  29. return RUN_ALL_TESTS();
  30. }
  31. namespace {
  32. static pthread_once_t download_memcached_once = PTHREAD_ONCE_INIT;
  33. static pid_t g_mc_pid = -1;
  34. static void RemoveMemcached() {
  35. puts("[Stopping memcached]");
  36. char cmd[256];
  37. #if defined(BAIDU_INTERNAL)
  38. snprintf(cmd, sizeof(cmd), "kill %d; rm -rf memcached_for_test", g_mc_pid);
  39. #else
  40. snprintf(cmd, sizeof(cmd), "kill %d", g_mc_pid);
  41. #endif
  42. CHECK(0 == system(cmd));
  43. // Wait for mc to stop
  44. usleep(50000);
  45. }
  46. #define MEMCACHED_BIN "memcached"
  47. #define MEMCACHED_PORT "11211"
  48. static void RunMemcached() {
  49. #if defined(BAIDU_INTERNAL)
  50. puts("Downloading memcached...");
  51. if (system("mkdir -p memcached_for_test && cd memcached_for_test && svn co https://svn.baidu.com/third-64/tags/memcached/memcached_1-4-15-100_PD_BL/bin") != 0) {
  52. puts("Fail to get memcached from svn");
  53. return;
  54. }
  55. # undef MEMCACHED_BIN
  56. # define MEMCACHED_BIN "memcached_for_test/bin/memcached";
  57. #else
  58. if (system("which " MEMCACHED_BIN) != 0) {
  59. puts("Fail to find " MEMCACHED_BIN ", following tests will be skipped");
  60. return;
  61. }
  62. #endif
  63. atexit(RemoveMemcached);
  64. g_mc_pid = fork();
  65. if (g_mc_pid < 0) {
  66. puts("Fail to fork");
  67. exit(1);
  68. } else if (g_mc_pid == 0) {
  69. puts("[Starting memcached]");
  70. char* const argv[] = { (char*)MEMCACHED_BIN,
  71. (char*)"-p", (char*)MEMCACHED_PORT,
  72. NULL };
  73. if (execvp(MEMCACHED_BIN, argv) < 0) {
  74. puts("Fail to run " MEMCACHED_BIN);
  75. exit(1);
  76. }
  77. }
  78. // Wait for memcached to start.
  79. usleep(50000);
  80. }
  81. class MemcacheTest : public testing::Test {
  82. protected:
  83. MemcacheTest() {}
  84. void SetUp() {
  85. pthread_once(&download_memcached_once, RunMemcached);
  86. }
  87. void TearDown() {
  88. }
  89. };
  90. TEST_F(MemcacheTest, sanity) {
  91. if (g_mc_pid < 0) {
  92. puts("Skipped due to absence of memcached");
  93. return;
  94. }
  95. brpc::ChannelOptions options;
  96. options.protocol = brpc::PROTOCOL_MEMCACHE;
  97. brpc::Channel channel;
  98. ASSERT_EQ(0, channel.Init("0.0.0.0:" MEMCACHED_PORT, &options));
  99. brpc::MemcacheRequest request;
  100. brpc::MemcacheResponse response;
  101. brpc::Controller cntl;
  102. // Clear all contents in MC which is still holding older data after
  103. // restarting in Ubuntu 18.04 (mc=1.5.6)
  104. request.Flush(0);
  105. channel.CallMethod(NULL, &cntl, &request, &response, NULL);
  106. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText();
  107. ASSERT_TRUE(response.PopFlush());
  108. cntl.Reset();
  109. request.Clear();
  110. request.Get("hello");
  111. channel.CallMethod(NULL, &cntl, &request, &response, NULL);
  112. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText();
  113. std::string value;
  114. uint32_t flags = 0;
  115. uint64_t cas_value = 0;
  116. ASSERT_FALSE(response.PopGet(&value, &flags, &cas_value));
  117. ASSERT_EQ("Not found", response.LastError());
  118. cntl.Reset();
  119. request.Clear();
  120. request.Set("hello", "world", 0xdeadbeef, 10, 0);
  121. channel.CallMethod(NULL, &cntl, &request, &response, NULL);
  122. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText();
  123. ASSERT_TRUE(response.PopSet(&cas_value)) << response.LastError();
  124. ASSERT_EQ("", response.LastError());
  125. cntl.Reset();
  126. request.Clear();
  127. request.Get("hello");
  128. channel.CallMethod(NULL, &cntl, &request, &response, NULL);
  129. ASSERT_FALSE(cntl.Failed());
  130. ASSERT_TRUE(response.PopGet(&value, &flags, &cas_value));
  131. ASSERT_EQ("", response.LastError());
  132. ASSERT_EQ("world", value);
  133. ASSERT_EQ(0xdeadbeef, flags);
  134. std::cout << "cas_value=" << cas_value << std::endl;
  135. cntl.Reset();
  136. request.Clear();
  137. request.Set("hello", "world2", 0xdeadbeef, 10,
  138. cas_value/*intended match*/);
  139. channel.CallMethod(NULL, &cntl, &request, &response, NULL);
  140. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText();
  141. uint64_t cas_value2 = 0;
  142. ASSERT_TRUE(response.PopSet(&cas_value2)) << response.LastError();
  143. cntl.Reset();
  144. request.Clear();
  145. request.Set("hello", "world3", 0xdeadbeef, 10,
  146. cas_value2 + 1/*intended unmatch*/);
  147. channel.CallMethod(NULL, &cntl, &request, &response, NULL);
  148. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText();
  149. uint64_t cas_value3 = ~0;
  150. ASSERT_FALSE(response.PopSet(&cas_value3));
  151. std::cout << response.LastError() << std::endl;
  152. ASSERT_EQ(~0ul, cas_value3);
  153. }
  154. TEST_F(MemcacheTest, incr_and_decr) {
  155. if (g_mc_pid < 0) {
  156. puts("Skipped due to absence of memcached");
  157. return;
  158. }
  159. brpc::ChannelOptions options;
  160. options.protocol = brpc::PROTOCOL_MEMCACHE;
  161. brpc::Channel channel;
  162. ASSERT_EQ(0, channel.Init("0.0.0.0:" MEMCACHED_PORT, &options));
  163. brpc::MemcacheRequest request;
  164. brpc::MemcacheResponse response;
  165. brpc::Controller cntl;
  166. request.Increment("counter1", 2, 10, 10);
  167. request.Decrement("counter1", 1, 10, 10);
  168. request.Increment("counter1", 3, 10, 10);
  169. channel.CallMethod(NULL, &cntl, &request, &response, NULL);
  170. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText();
  171. uint64_t new_value1 = 0;
  172. uint64_t cas_value1 = 0;
  173. ASSERT_TRUE(response.PopIncrement(&new_value1, &cas_value1));
  174. ASSERT_EQ(10ul, new_value1);
  175. uint64_t new_value2 = 0;
  176. uint64_t cas_value2 = 0;
  177. ASSERT_TRUE(response.PopDecrement(&new_value2, &cas_value2));
  178. ASSERT_EQ(9ul, new_value2);
  179. uint64_t new_value3 = 0;
  180. uint64_t cas_value3 = 0;
  181. ASSERT_TRUE(response.PopIncrement(&new_value3, &cas_value3));
  182. ASSERT_EQ(12ul, new_value3);
  183. std::cout << "cas1=" << cas_value1
  184. << " cas2=" << cas_value2
  185. << " cas3=" << cas_value3
  186. << std::endl;
  187. }
  188. TEST_F(MemcacheTest, version) {
  189. if (g_mc_pid < 0) {
  190. puts("Skipped due to absence of memcached");
  191. return;
  192. }
  193. brpc::ChannelOptions options;
  194. options.protocol = brpc::PROTOCOL_MEMCACHE;
  195. brpc::Channel channel;
  196. ASSERT_EQ(0, channel.Init("0.0.0.0:" MEMCACHED_PORT, &options));
  197. brpc::MemcacheRequest request;
  198. brpc::MemcacheResponse response;
  199. brpc::Controller cntl;
  200. request.Version();
  201. channel.CallMethod(NULL, &cntl, &request, &response, NULL);
  202. ASSERT_FALSE(cntl.Failed()) << cntl.ErrorText();
  203. std::string version;
  204. ASSERT_TRUE(response.PopVersion(&version)) << response.LastError();
  205. std::cout << "version=" << version << std::endl;
  206. }
  207. } //namespace