1 | #include <Common/typeid_cast.h> |
2 | #include <Common/ZooKeeper/ZooKeeper.h> |
3 | #include <Common/ZooKeeper/KeeperException.h> |
4 | #include <Common/StringUtils/StringUtils.h> |
5 | #include <iostream> |
6 | #include <chrono> |
7 | |
8 | #include <gtest/gtest.h> |
9 | |
10 | #include <Common/ShellCommand.h> |
11 | |
12 | |
13 | using namespace DB; |
14 | |
15 | TEST(zkutil, zookeeper_connected) |
16 | { |
17 | try |
18 | { |
19 | auto zookeeper = std::make_unique<zkutil::ZooKeeper>("localhost:2181" ); |
20 | zookeeper->exists("/" ); |
21 | } |
22 | catch (...) |
23 | { |
24 | std::cerr << "No zookeeper. skip tests." << std::endl; |
25 | exit(0); |
26 | } |
27 | } |
28 | |
29 | TEST(zkutil, multi_nice_exception_msg) |
30 | { |
31 | auto zookeeper = std::make_unique<zkutil::ZooKeeper>("localhost:2181" ); |
32 | |
33 | Coordination::Requests ops; |
34 | |
35 | ASSERT_NO_THROW( |
36 | zookeeper->tryRemoveRecursive("/clickhouse_test/zkutil_multi" ); |
37 | |
38 | ops.emplace_back(zkutil::makeCreateRequest("/clickhouse_test/zkutil_multi" , "_" , zkutil::CreateMode::Persistent)); |
39 | ops.emplace_back(zkutil::makeCreateRequest("/clickhouse_test/zkutil_multi/a" , "_" , zkutil::CreateMode::Persistent)); |
40 | zookeeper->multi(ops); |
41 | ); |
42 | |
43 | try |
44 | { |
45 | ops.clear(); |
46 | ops.emplace_back(zkutil::makeCreateRequest("/clickhouse_test/zkutil_multi/c" , "_" , zkutil::CreateMode::Persistent)); |
47 | ops.emplace_back(zkutil::makeRemoveRequest("/clickhouse_test/zkutil_multi/c" , -1)); |
48 | ops.emplace_back(zkutil::makeCreateRequest("/clickhouse_test/zkutil_multi/a" , "BadBoy" , zkutil::CreateMode::Persistent)); |
49 | ops.emplace_back(zkutil::makeCreateRequest("/clickhouse_test/zkutil_multi/b" , "_" , zkutil::CreateMode::Persistent)); |
50 | ops.emplace_back(zkutil::makeCreateRequest("/clickhouse_test/zkutil_multi/a" , "_" , zkutil::CreateMode::Persistent)); |
51 | |
52 | zookeeper->multi(ops); |
53 | FAIL(); |
54 | } |
55 | catch (...) |
56 | { |
57 | zookeeper->tryRemoveRecursive("/clickhouse_test/zkutil_multi" ); |
58 | |
59 | String msg = getCurrentExceptionMessage(false); |
60 | |
61 | bool msg_has_reqired_patterns = msg.find("#2" ) != std::string::npos; |
62 | EXPECT_TRUE(msg_has_reqired_patterns) << msg; |
63 | } |
64 | } |
65 | |
66 | |
67 | TEST(zkutil, multi_async) |
68 | { |
69 | auto zookeeper = std::make_unique<zkutil::ZooKeeper>("localhost:2181" ); |
70 | Coordination::Requests ops; |
71 | |
72 | zookeeper->tryRemoveRecursive("/clickhouse_test/zkutil_multi" ); |
73 | |
74 | { |
75 | ops.clear(); |
76 | auto fut = zookeeper->asyncMulti(ops); |
77 | } |
78 | |
79 | { |
80 | ops.clear(); |
81 | ops.emplace_back(zkutil::makeCreateRequest("/clickhouse_test/zkutil_multi" , "" , zkutil::CreateMode::Persistent)); |
82 | ops.emplace_back(zkutil::makeCreateRequest("/clickhouse_test/zkutil_multi/a" , "" , zkutil::CreateMode::Persistent)); |
83 | |
84 | auto fut = zookeeper->tryAsyncMulti(ops); |
85 | ops.clear(); |
86 | |
87 | auto res = fut.get(); |
88 | ASSERT_TRUE(res.error == Coordination::ZOK); |
89 | ASSERT_EQ(res.responses.size(), 2); |
90 | } |
91 | |
92 | EXPECT_ANY_THROW |
93 | ( |
94 | std::vector<std::future<Coordination::MultiResponse>> futures; |
95 | |
96 | for (size_t i = 0; i < 10000; ++i) |
97 | { |
98 | ops.clear(); |
99 | ops.emplace_back(zkutil::makeRemoveRequest("/clickhouse_test/zkutil_multi" , -1)); |
100 | ops.emplace_back(zkutil::makeCreateRequest("/clickhouse_test/zkutil_multi" , "_" , zkutil::CreateMode::Persistent)); |
101 | ops.emplace_back(zkutil::makeCheckRequest("/clickhouse_test/zkutil_multi" , -1)); |
102 | ops.emplace_back(zkutil::makeSetRequest("/clickhouse_test/zkutil_multi" , "xxx" , 42)); |
103 | ops.emplace_back(zkutil::makeCreateRequest("/clickhouse_test/zkutil_multi/a" , "_" , zkutil::CreateMode::Persistent)); |
104 | |
105 | futures.emplace_back(zookeeper->asyncMulti(ops)); |
106 | } |
107 | |
108 | futures[0].get(); |
109 | ); |
110 | |
111 | /// Check there are no segfaults for remaining 999 futures |
112 | using namespace std::chrono_literals; |
113 | std::this_thread::sleep_for(1s); |
114 | |
115 | { |
116 | ops.clear(); |
117 | ops.emplace_back(zkutil::makeCreateRequest("/clickhouse_test/zkutil_multi" , "_" , zkutil::CreateMode::Persistent)); |
118 | ops.emplace_back(zkutil::makeCreateRequest("/clickhouse_test/zkutil_multi/a" , "_" , zkutil::CreateMode::Persistent)); |
119 | |
120 | auto fut = zookeeper->tryAsyncMulti(ops); |
121 | ops.clear(); |
122 | |
123 | auto res = fut.get(); |
124 | ASSERT_TRUE(res.error == Coordination::ZNODEEXISTS); |
125 | ASSERT_EQ(res.responses.size(), 2); |
126 | } |
127 | } |
128 | |
129 | TEST(zkutil, watch_get_children_with_chroot) |
130 | { |
131 | try |
132 | { |
133 | const String zk_server = "localhost:2181" ; |
134 | const String prefix = "/clickhouse_test/zkutil/watch_get_children_with_chroot" ; |
135 | |
136 | /// Create chroot node firstly |
137 | auto zookeeper = std::make_unique<zkutil::ZooKeeper>(zk_server); |
138 | zookeeper->createAncestors(prefix + "/" ); |
139 | zookeeper = std::make_unique<zkutil::ZooKeeper>(zk_server, "" , |
140 | zkutil::DEFAULT_SESSION_TIMEOUT, |
141 | zkutil::DEFAULT_OPERATION_TIMEOUT, |
142 | prefix); |
143 | |
144 | String queue_path = "/queue" ; |
145 | zookeeper->tryRemoveRecursive(queue_path); |
146 | zookeeper->createAncestors(queue_path + "/" ); |
147 | |
148 | zkutil::EventPtr event = std::make_shared<Poco::Event>(); |
149 | zookeeper->getChildren(queue_path, nullptr, event); |
150 | { |
151 | auto zookeeper2 = std::make_unique<zkutil::ZooKeeper>(zk_server, "" , |
152 | zkutil::DEFAULT_SESSION_TIMEOUT, |
153 | zkutil::DEFAULT_OPERATION_TIMEOUT, |
154 | prefix); |
155 | zookeeper2->create(queue_path + "/children-" , "" , zkutil::CreateMode::PersistentSequential); |
156 | } |
157 | event->wait(); |
158 | } |
159 | catch (...) |
160 | { |
161 | std::cerr << getCurrentExceptionMessage(true); |
162 | throw; |
163 | } |
164 | } |
165 | |
166 | TEST(zkutil, multi_create_sequential) |
167 | { |
168 | try |
169 | { |
170 | const String zk_server = "localhost:2181" ; |
171 | const String prefix = "/clickhouse_test/zkutil" ; |
172 | |
173 | /// Create chroot node firstly |
174 | auto zookeeper = std::make_unique<zkutil::ZooKeeper>(zk_server); |
175 | zookeeper->createAncestors(prefix + "/" ); |
176 | zookeeper = std::make_unique<zkutil::ZooKeeper>(zk_server, "" , |
177 | zkutil::DEFAULT_SESSION_TIMEOUT, |
178 | zkutil::DEFAULT_OPERATION_TIMEOUT, |
179 | "/clickhouse_test" ); |
180 | |
181 | String base_path = "/multi_create_sequential" ; |
182 | zookeeper->tryRemoveRecursive(base_path); |
183 | zookeeper->createAncestors(base_path + "/" ); |
184 | |
185 | Coordination::Requests ops; |
186 | String sequential_node_prefix = base_path + "/queue-" ; |
187 | ops.emplace_back(zkutil::makeCreateRequest(sequential_node_prefix, "" , zkutil::CreateMode::EphemeralSequential)); |
188 | auto results = zookeeper->multi(ops); |
189 | const auto & sequential_node_result_op = dynamic_cast<const Coordination::CreateResponse &>(*results.at(0)); |
190 | |
191 | EXPECT_FALSE(sequential_node_result_op.path_created.empty()); |
192 | EXPECT_GT(sequential_node_result_op.path_created.length(), sequential_node_prefix.length()); |
193 | EXPECT_EQ(sequential_node_result_op.path_created.substr(0, sequential_node_prefix.length()), sequential_node_prefix); |
194 | } |
195 | catch (...) |
196 | { |
197 | std::cerr << getCurrentExceptionMessage(false); |
198 | throw; |
199 | } |
200 | } |
201 | |
202 | |
203 | |
204 | |