blob: cec6e891be7e9b8e80f5a3122c3f95f77e9f7eb3 [file] [log] [blame]
Hongwei Wang8e04d412015-07-31 15:12:51 -07001/*
2 *
murgatroid99ace28d32016-01-14 10:12:10 -08003 * Copyright 2015-2016, Google Inc.
Hongwei Wang8e04d412015-07-31 15:12:51 -07004 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
yang-g8c2be9f2015-08-19 16:28:09 -070034#include <grpc++/channel.h>
Hongwei Wang8e04d412015-07-31 15:12:51 -070035#include <grpc++/client_context.h>
36#include <grpc++/create_channel.h>
Hongwei Wang8e04d412015-07-31 15:12:51 -070037#include <grpc++/server.h>
38#include <grpc++/server_builder.h>
39#include <grpc++/server_context.h>
Hongwei Wang8e04d412015-07-31 15:12:51 -070040#include <grpc/grpc.h>
41#include <grpc/grpc_zookeeper.h>
Sree Kuchibhotla5a05f512016-01-13 22:43:20 -080042#include <gtest/gtest.h>
Hongwei Wang8e04d412015-07-31 15:12:51 -070043#include <zookeeper/zookeeper.h>
44
yang-g9e2f90c2015-08-21 15:35:03 -070045#include "src/core/support/env.h"
Sree Kuchibhotla5a05f512016-01-13 22:43:20 -080046#include "src/proto/grpc/testing/echo.grpc.pb.h"
47#include "test/core/util/port.h"
48#include "test/core/util/test_config.h"
yang-g9e2f90c2015-08-21 15:35:03 -070049
Craig Tiller1b4e3302015-12-17 16:35:00 -080050using grpc::testing::EchoRequest;
51using grpc::testing::EchoResponse;
Hongwei Wang8e04d412015-07-31 15:12:51 -070052
53namespace grpc {
54namespace testing {
55
Sree Kuchibhotla5a05f512016-01-13 22:43:20 -080056class ZookeeperTestServiceImpl
57 : public ::grpc::testing::EchoTestService::Service {
Hongwei Wang8e04d412015-07-31 15:12:51 -070058 public:
59 Status Echo(ServerContext* context, const EchoRequest* request,
60 EchoResponse* response) GRPC_OVERRIDE {
61 response->set_message(request->message());
62 return Status::OK;
63 }
64};
65
66class ZookeeperTest : public ::testing::Test {
67 protected:
68 ZookeeperTest() {}
69
70 void SetUp() GRPC_OVERRIDE {
Hongwei Wangb0453fb2015-08-10 17:04:36 -070071 SetUpZookeeper();
Hongwei Wang8e04d412015-07-31 15:12:51 -070072
Hongwei Wangc3f48c82015-08-13 17:22:58 -070073 // Sets up two servers
Hongwei Wangb0453fb2015-08-10 17:04:36 -070074 int port1 = grpc_pick_unused_port_or_die();
Hongwei Wangb0453fb2015-08-10 17:04:36 -070075 server1_ = SetUpServer(port1);
Hongwei Wangff6097a2015-08-12 17:48:56 -070076
77 int port2 = grpc_pick_unused_port_or_die();
Hongwei Wangb0453fb2015-08-10 17:04:36 -070078 server2_ = SetUpServer(port2);
Hongwei Wangd7c5aa82015-08-10 20:30:39 -070079
Hongwei Wangc3f48c82015-08-13 17:22:58 -070080 // Registers service /test in zookeeper
Hongwei Wangb0453fb2015-08-10 17:04:36 -070081 RegisterService("/test", "test");
82
Hongwei Wangc3f48c82015-08-13 17:22:58 -070083 // Registers service instance /test/1 in zookeeper
Hongwei Wangd7c5aa82015-08-10 20:30:39 -070084 string value =
Hongwei Wang85ad6852015-08-13 16:13:10 -070085 "{\"host\":\"localhost\",\"port\":\"" + to_string(port1) + "\"}";
Hongwei Wangb0453fb2015-08-10 17:04:36 -070086 RegisterService("/test/1", value);
87
Hongwei Wangc3f48c82015-08-13 17:22:58 -070088 // Registers service instance /test/2 in zookeeper
Craig Tillerd6c98df2015-08-18 09:33:44 -070089 value = "{\"host\":\"localhost\",\"port\":\"" + to_string(port2) + "\"}";
Hongwei Wangb0453fb2015-08-10 17:04:36 -070090 RegisterService("/test/2", value);
91 }
92
Hongwei Wangc3f48c82015-08-13 17:22:58 -070093 // Requires zookeeper server running
Hongwei Wangb0453fb2015-08-10 17:04:36 -070094 void SetUpZookeeper() {
Hongwei Wangc3f48c82015-08-13 17:22:58 -070095 // Finds zookeeper server address in environment
Hongwei Wangb0453fb2015-08-10 17:04:36 -070096 // Default is localhost:2181
Hongwei Wang497d26a2015-08-07 16:39:24 -070097 zookeeper_address_ = "localhost:2181";
Hongwei Wang6d445962015-08-07 10:53:22 -070098 char* addr = gpr_getenv("GRPC_ZOOKEEPER_SERVER_TEST");
99 if (addr != NULL) {
100 string addr_str(addr);
Hongwei Wang497d26a2015-08-07 16:39:24 -0700101 zookeeper_address_ = addr_str;
Hongwei Wang6d445962015-08-07 10:53:22 -0700102 gpr_free(addr);
Hongwei Wang2ad07d72015-08-07 11:30:36 -0700103 }
Hongwei Wang6bbcd042015-08-07 19:09:36 -0700104 gpr_log(GPR_DEBUG, zookeeper_address_.c_str());
Hongwei Wang8e04d412015-07-31 15:12:51 -0700105
Hongwei Wangc3f48c82015-08-13 17:22:58 -0700106 // Connects to zookeeper server
Hongwei Wang8e04d412015-07-31 15:12:51 -0700107 zoo_set_debug_level(ZOO_LOG_LEVEL_WARN);
Hongwei Wangd7c5aa82015-08-10 20:30:39 -0700108 zookeeper_handle_ =
109 zookeeper_init(zookeeper_address_.c_str(), NULL, 15000, 0, 0, 0);
Hongwei Wangeace1902015-08-03 12:22:32 -0700110 GPR_ASSERT(zookeeper_handle_ != NULL);
Hongwei Wang8e04d412015-07-31 15:12:51 -0700111
Hongwei Wangc3f48c82015-08-13 17:22:58 -0700112 // Registers zookeeper name resolver in grpc
Hongwei Wang8e04d412015-07-31 15:12:51 -0700113 grpc_zookeeper_register();
Hongwei Wangff6097a2015-08-12 17:48:56 -0700114 }
115
Hongwei Wang85ad6852015-08-13 16:13:10 -0700116 std::unique_ptr<Server> SetUpServer(const int port) {
117 string server_address = "localhost:" + to_string(port);
Hongwei Wangff6097a2015-08-12 17:48:56 -0700118
119 ServerBuilder builder;
120 builder.AddListeningPort(server_address, InsecureServerCredentials());
121 builder.RegisterService(&service_);
122 std::unique_ptr<Server> server = builder.BuildAndStart();
123 return server;
Hongwei Wang8e04d412015-07-31 15:12:51 -0700124 }
125
Hongwei Wang85ad6852015-08-13 16:13:10 -0700126 void RegisterService(const string& name, const string& value) {
Hongwei Wangd7c5aa82015-08-10 20:30:39 -0700127 char* path = (char*)gpr_malloc(name.size());
Hongwei Wangeace1902015-08-03 12:22:32 -0700128
Hongwei Wangb0453fb2015-08-10 17:04:36 -0700129 int status = zoo_exists(zookeeper_handle_, name.c_str(), 0, NULL);
Hongwei Wangeace1902015-08-03 12:22:32 -0700130 if (status == ZNONODE) {
Hongwei Wangd7c5aa82015-08-10 20:30:39 -0700131 status =
132 zoo_create(zookeeper_handle_, name.c_str(), value.c_str(),
133 value.size(), &ZOO_OPEN_ACL_UNSAFE, 0, path, name.size());
Hongwei Wangeace1902015-08-03 12:22:32 -0700134 } else {
Hongwei Wangd7c5aa82015-08-10 20:30:39 -0700135 status = zoo_set(zookeeper_handle_, name.c_str(), value.c_str(),
136 value.size(), -1);
Hongwei Wangeace1902015-08-03 12:22:32 -0700137 }
Hongwei Wangb0453fb2015-08-10 17:04:36 -0700138 gpr_free(path);
139 GPR_ASSERT(status == 0);
140 }
141
Hongwei Wang85ad6852015-08-13 16:13:10 -0700142 void DeleteService(const string& name) {
Hongwei Wangb0453fb2015-08-10 17:04:36 -0700143 int status = zoo_delete(zookeeper_handle_, name.c_str(), -1);
144 GPR_ASSERT(status == 0);
Hongwei Wangeace1902015-08-03 12:22:32 -0700145 }
146
Hongwei Wang85ad6852015-08-13 16:13:10 -0700147 void ChangeZookeeperState() {
148 server1_->Shutdown();
149 DeleteService("/test/1");
150 }
151
Hongwei Wang8e04d412015-07-31 15:12:51 -0700152 void TearDown() GRPC_OVERRIDE {
Hongwei Wangb0453fb2015-08-10 17:04:36 -0700153 server1_->Shutdown();
154 server2_->Shutdown();
Hongwei Wangeace1902015-08-03 12:22:32 -0700155 zookeeper_close(zookeeper_handle_);
Hongwei Wang8e04d412015-07-31 15:12:51 -0700156 }
157
158 void ResetStub() {
Hongwei Wang497d26a2015-08-07 16:39:24 -0700159 string target = "zookeeper://" + zookeeper_address_ + "/test";
Julien Boeuf18a12c42015-10-12 15:05:59 -0700160 channel_ = CreateChannel(target, InsecureChannelCredentials());
Sree Kuchibhotla5a05f512016-01-13 22:43:20 -0800161 stub_ = grpc::testing::EchoTestService::NewStub(channel_);
Hongwei Wang8e04d412015-07-31 15:12:51 -0700162 }
163
Hongwei Wang85ad6852015-08-13 16:13:10 -0700164 string to_string(const int number) {
165 std::stringstream strs;
166 strs << number;
167 return strs.str();
168 }
169
yang-g8c2be9f2015-08-19 16:28:09 -0700170 std::shared_ptr<Channel> channel_;
Sree Kuchibhotla5a05f512016-01-13 22:43:20 -0800171 std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_;
Hongwei Wangb0453fb2015-08-10 17:04:36 -0700172 std::unique_ptr<Server> server1_;
173 std::unique_ptr<Server> server2_;
Hongwei Wang8e04d412015-07-31 15:12:51 -0700174 ZookeeperTestServiceImpl service_;
Hongwei Wangeace1902015-08-03 12:22:32 -0700175 zhandle_t* zookeeper_handle_;
Hongwei Wang497d26a2015-08-07 16:39:24 -0700176 string zookeeper_address_;
Hongwei Wang8e04d412015-07-31 15:12:51 -0700177};
178
Hongwei Wangc3f48c82015-08-13 17:22:58 -0700179// Tests zookeeper state change between two RPCs
Hongwei Wang85ad6852015-08-13 16:13:10 -0700180// TODO(ctiller): leaked objects in this test
Hongwei Wangeace1902015-08-03 12:22:32 -0700181TEST_F(ZookeeperTest, ZookeeperStateChangeTwoRpc) {
Hongwei Wang8e04d412015-07-31 15:12:51 -0700182 ResetStub();
Hongwei Wang8e04d412015-07-31 15:12:51 -0700183
Hongwei Wangeace1902015-08-03 12:22:32 -0700184 // First RPC
185 EchoRequest request1;
186 EchoResponse response1;
187 ClientContext context1;
Hongwei Wang443a7502015-08-05 16:27:54 -0700188 context1.set_authority("test");
Hongwei Wangeace1902015-08-03 12:22:32 -0700189 request1.set_message("Hello");
190 Status s1 = stub_->Echo(&context1, request1, &response1);
191 EXPECT_EQ(response1.message(), request1.message());
192 EXPECT_TRUE(s1.ok());
193
Hongwei Wangc3f48c82015-08-13 17:22:58 -0700194 // Zookeeper state changes
Craig Tillerd6c98df2015-08-18 09:33:44 -0700195 gpr_log(GPR_DEBUG, "Zookeeper state change");
Hongwei Wang85ad6852015-08-13 16:13:10 -0700196 ChangeZookeeperState();
Hongwei Wangc3f48c82015-08-13 17:22:58 -0700197 // Waits for re-resolving addresses
Hongwei Wang85ad6852015-08-13 16:13:10 -0700198 // TODO(ctiller): RPC will probably fail if not waiting
Hongwei Wangd7c5aa82015-08-10 20:30:39 -0700199 sleep(1);
Hongwei Wangeace1902015-08-03 12:22:32 -0700200
201 // Second RPC
202 EchoRequest request2;
203 EchoResponse response2;
204 ClientContext context2;
Hongwei Wang443a7502015-08-05 16:27:54 -0700205 context2.set_authority("test");
Hongwei Wangb0453fb2015-08-10 17:04:36 -0700206 request2.set_message("World");
Hongwei Wangeace1902015-08-03 12:22:32 -0700207 Status s2 = stub_->Echo(&context2, request2, &response2);
208 EXPECT_EQ(response2.message(), request2.message());
209 EXPECT_TRUE(s2.ok());
Hongwei Wang8e04d412015-07-31 15:12:51 -0700210}
211
212} // namespace testing
213} // namespace grpc
214
215int main(int argc, char** argv) {
216 grpc_test_init(argc, argv);
217 ::testing::InitGoogleTest(&argc, argv);
218 return RUN_ALL_TESTS();
murgatroid99ace28d32016-01-14 10:12:10 -0800219}