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, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 #include <cppunit/extensions/HelperMacros.h>
20 #include "CppAssertHelper.h"
21
22 #include <signal.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <sys/select.h>
26
27 #include "CollectionUtil.h"
28 #include "ThreadingUtil.h"
29
30 using namespace Util;
31
32 #include "Vector.h"
33 using namespace std;
34
35 #include <cstring>
36 #include <list>
37
38 #include <zookeeper.h>
39 #include <errno.h>
40 #include <recordio.h>
41 #include "Util.h"
42 #include "ZKMocks.h"
43
44 struct buff_struct_2 {
45 int32_t len;
46 int32_t off;
47 char *buffer;
48 };
49
50 // TODO(br33d): the vast majority of this test is not usable with single threaded.
51 // it needs a overhaul to work properly with both threaded and single
52 // threaded (ZOOKEEPER-2640)
53 #ifdef THREADED
54 // For testing LogMessage Callback functionality
55 list<string> logMessages;
logMessageHandler(const char * message)56 void logMessageHandler(const char* message) {
57 cout << "Log Message Received: [" << message << "]" << endl;
58 logMessages.push_back(message);
59 }
60
Stat_eq(struct Stat * a,struct Stat * b)61 static int Stat_eq(struct Stat* a, struct Stat* b)
62 {
63 if (a->czxid != b->czxid) return 0;
64 if (a->mzxid != b->mzxid) return 0;
65 if (a->ctime != b->ctime) return 0;
66 if (a->mtime != b->mtime) return 0;
67 if (a->version != b->version) return 0;
68 if (a->cversion != b->cversion) return 0;
69 if (a->aversion != b->aversion) return 0;
70 if (a->ephemeralOwner != b->ephemeralOwner) return 0;
71 if (a->dataLength != b->dataLength) return 0;
72 if (a->numChildren != b->numChildren) return 0;
73 if (a->pzxid != b->pzxid) return 0;
74 return 1;
75 }
76 #ifdef THREADED
yield(zhandle_t * zh,int i)77 static void yield(zhandle_t *zh, int i)
78 {
79 sleep(i);
80 }
81 #else
yield(zhandle_t * zh,int seconds)82 static void yield(zhandle_t *zh, int seconds)
83 {
84 int fd;
85 int interest;
86 int events;
87 struct timeval tv;
88 int rc;
89 time_t expires = time(0) + seconds;
90 time_t timeLeft = seconds;
91 fd_set rfds, wfds, efds;
92 FD_ZERO(&rfds);
93 FD_ZERO(&wfds);
94 FD_ZERO(&efds);
95
96 while(timeLeft >= 0) {
97 zookeeper_interest(zh, &fd, &interest, &tv);
98 if (fd != -1) {
99 if (interest&ZOOKEEPER_READ) {
100 FD_SET(fd, &rfds);
101 } else {
102 FD_CLR(fd, &rfds);
103 }
104 if (interest&ZOOKEEPER_WRITE) {
105 FD_SET(fd, &wfds);
106 } else {
107 FD_CLR(fd, &wfds);
108 }
109 } else {
110 fd = 0;
111 }
112 FD_SET(0, &rfds);
113 if (tv.tv_sec > timeLeft) {
114 tv.tv_sec = timeLeft;
115 }
116 rc = select(fd+1, &rfds, &wfds, &efds, &tv);
117 timeLeft = expires - time(0);
118 events = 0;
119 if (FD_ISSET(fd, &rfds)) {
120 events |= ZOOKEEPER_READ;
121 }
122 if (FD_ISSET(fd, &wfds)) {
123 events |= ZOOKEEPER_WRITE;
124 }
125 zookeeper_process(zh, events);
126 }
127 }
128 #endif
129
130 typedef struct evt {
131 string path;
132 int type;
133 } evt_t;
134
135 typedef struct watchCtx {
136 private:
137 list<evt_t> events;
138 watchCtx(const watchCtx&);
139 watchCtx& operator=(const watchCtx&);
140 public:
141 bool connected;
142 zhandle_t *zh;
143 Mutex mutex;
144
watchCtxwatchCtx145 watchCtx() {
146 connected = false;
147 zh = 0;
148 }
~watchCtxwatchCtx149 ~watchCtx() {
150 if (zh) {
151 zookeeper_close(zh);
152 zh = 0;
153 }
154 }
155
getEventwatchCtx156 evt_t getEvent() {
157 evt_t evt;
158 mutex.acquire();
159 CPPUNIT_ASSERT( events.size() > 0);
160 evt = events.front();
161 events.pop_front();
162 mutex.release();
163 return evt;
164 }
165
countEventswatchCtx166 int countEvents() {
167 int count;
168 mutex.acquire();
169 count = events.size();
170 mutex.release();
171 return count;
172 }
173
putEventwatchCtx174 void putEvent(evt_t evt) {
175 mutex.acquire();
176 events.push_back(evt);
177 mutex.release();
178 }
179
waitForConnectedwatchCtx180 bool waitForConnected(zhandle_t *zh) {
181 time_t expires = time(0) + 10;
182 while(!connected && time(0) < expires) {
183 yield(zh, 1);
184 }
185 return connected;
186 }
187
waitForDisconnectedwatchCtx188 bool waitForDisconnected(zhandle_t *zh) {
189 time_t expires = time(0) + 15;
190 while(connected && time(0) < expires) {
191 yield(zh, 1);
192 }
193 return !connected;
194 }
195
196 } watchctx_t;
197
198 class Zookeeper_simpleSystem : public CPPUNIT_NS::TestFixture
199 {
200 CPPUNIT_TEST_SUITE(Zookeeper_simpleSystem);
201 CPPUNIT_TEST(testLogCallbackSet);
202 CPPUNIT_TEST(testLogCallbackInit);
203 CPPUNIT_TEST(testLogCallbackClear);
204 CPPUNIT_TEST(testAsyncWatcherAutoReset);
205 CPPUNIT_TEST(testDeserializeString);
206 CPPUNIT_TEST(testFirstServerDown);
207 CPPUNIT_TEST(testNonexistentHost);
208 #ifdef THREADED
209 CPPUNIT_TEST(testNullData);
210 #ifdef ZOO_IPV6_ENABLED
211 CPPUNIT_TEST(testIPV6);
212 #endif
213 #ifdef HAVE_OPENSSL_H
214 CPPUNIT_TEST(testSSL);
215 #endif
216 CPPUNIT_TEST(testCreate);
217 CPPUNIT_TEST(testCreateContainer);
218 CPPUNIT_TEST(testCreateTtl);
219 CPPUNIT_TEST(testPath);
220 CPPUNIT_TEST(testPathValidation);
221 CPPUNIT_TEST(testPing);
222 CPPUNIT_TEST(testAcl);
223 CPPUNIT_TEST(testChroot);
224 CPPUNIT_TEST(testAuth);
225 CPPUNIT_TEST(testHangingClient);
226 CPPUNIT_TEST(testWatcherAutoResetWithGlobal);
227 CPPUNIT_TEST(testWatcherAutoResetWithLocal);
228 CPPUNIT_TEST(testGetChildren2);
229 CPPUNIT_TEST(testLastZxid);
230 CPPUNIT_TEST(testServersResolutionDelay);
231 CPPUNIT_TEST(testRemoveWatchers);
232 #endif
233 CPPUNIT_TEST_SUITE_END();
234
watcher(zhandle_t *,int type,int state,const char * path,void * v)235 static void watcher(zhandle_t *, int type, int state, const char *path,void*v){
236 watchctx_t *ctx = (watchctx_t*)v;
237
238 if (state == ZOO_CONNECTED_STATE) {
239 ctx->connected = true;
240 } else {
241 ctx->connected = false;
242 }
243 if (type != ZOO_SESSION_EVENT) {
244 evt_t evt;
245 evt.path = path;
246 evt.type = type;
247 ctx->putEvent(evt);
248 }
249 }
250
251 static const char hostPorts[];
252
getHostPorts()253 const char *getHostPorts() {
254 return hostPorts;
255 }
256
createClient(watchctx_t * ctx)257 zhandle_t *createClient(watchctx_t *ctx) {
258 return createClient(hostPorts, ctx);
259 }
260
createClient(watchctx_t * ctx,log_callback_fn logCallback)261 zhandle_t *createClient(watchctx_t *ctx, log_callback_fn logCallback) {
262 zhandle_t *zk = zookeeper_init2(hostPorts, watcher, 10000, 0, ctx, 0, logCallback);
263 ctx->zh = zk;
264 sleep(1);
265 return zk;
266 }
267
createClient(const char * hp,watchctx_t * ctx)268 zhandle_t *createClient(const char *hp, watchctx_t *ctx) {
269 zhandle_t *zk = zookeeper_init(hp, watcher, 10000, 0, ctx, 0);
270 ctx->zh = zk;
271 sleep(1);
272 return zk;
273 }
274
275 #ifdef HAVE_OPENSSL_H
createSSLClient(const char * hp,const char * cert,watchctx_t * ctx)276 zhandle_t *createSSLClient(const char *hp, const char *cert, watchctx_t *ctx) {
277 zhandle_t *zk = zookeeper_init_ssl(hp, cert, watcher, 30000, 0, ctx, 0);
278 ctx->zh = zk;
279 sleep(1);
280 return zk;
281 }
282 #endif
283
createchClient(watchctx_t * ctx,const char * chroot)284 zhandle_t *createchClient(watchctx_t *ctx, const char* chroot) {
285 zhandle_t *zk = zookeeper_init(chroot, watcher, 10000, 0, ctx, 0);
286 ctx->zh = zk;
287 sleep(1);
288 return zk;
289 }
290
291 FILE *logfile;
292 public:
293
Zookeeper_simpleSystem()294 Zookeeper_simpleSystem() {
295 logfile = openlogfile("Zookeeper_simpleSystem");
296 }
297
~Zookeeper_simpleSystem()298 ~Zookeeper_simpleSystem() {
299 if (logfile) {
300 fflush(logfile);
301 fclose(logfile);
302 logfile = 0;
303 }
304 }
305
setUp()306 void setUp()
307 {
308 zoo_set_log_stream(logfile);
309 }
310
startServer()311 void startServer() {
312 char cmd[1024];
313 sprintf(cmd, "%s start %s", ZKSERVER_CMD, getHostPorts());
314 CPPUNIT_ASSERT(system(cmd) == 0);
315 }
316
stopServer()317 void stopServer() {
318 char cmd[1024];
319 sprintf(cmd, "%s stop %s", ZKSERVER_CMD, getHostPorts());
320 CPPUNIT_ASSERT(system(cmd) == 0);
321 }
322
tearDown()323 void tearDown()
324 {
325 }
326
327 /** have a callback in the default watcher **/
default_zoo_watcher(zhandle_t * zzh,int type,int state,const char * path,void * context)328 static void default_zoo_watcher(zhandle_t *zzh, int type, int state, const char *path, void *context){
329 int zrc;
330 struct String_vector str_vec = {0, NULL};
331 zrc = zoo_wget_children(zzh, "/mytest", default_zoo_watcher, NULL, &str_vec);
332 CPPUNIT_ASSERT(zrc == ZOK || zrc == ZCLOSING);
333 }
334
335 /** ZOOKEEPER-1057 This checks that the client connects to the second server when the first is not reachable **/
testFirstServerDown()336 void testFirstServerDown() {
337 watchctx_t ctx;
338
339 zoo_deterministic_conn_order(true);
340
341 zhandle_t* zk = createClient("127.0.0.1:22182,127.0.0.1:22181", &ctx);
342 CPPUNIT_ASSERT(zk != 0);
343 CPPUNIT_ASSERT(ctx.waitForConnected(zk));
344 }
345
346 /* Checks that a non-existent host will not block the connection*/
testNonexistentHost()347 void testNonexistentHost() {
348 char hosts[] = "jimmy:5555,127.0.0.1:22181";
349 watchctx_t ctx;
350 zoo_deterministic_conn_order(true /* disable permute */);
351 zhandle_t *zh = createClient(hosts, &ctx);
352 CPPUNIT_ASSERT(ctx.waitForConnected(zh));
353 zoo_deterministic_conn_order(false /* enable permute */);
354 }
355
356 /** this checks for a deadlock in calling zookeeper_close and calls from a default watcher that might get triggered just when zookeeper_close() is in progress **/
testHangingClient()357 void testHangingClient() {
358 int zrc;
359 char buff[10] = "testall";
360 char path[512];
361 watchctx_t *ctx = NULL;
362 struct String_vector str_vec = {0, NULL};
363 zhandle_t *zh = zookeeper_init(hostPorts, NULL, 10000, 0, ctx, 0);
364 sleep(1);
365 zrc = zoo_create(zh, "/mytest", buff, 10, &ZOO_OPEN_ACL_UNSAFE, 0, path, 512);
366 CPPUNIT_ASSERT_EQUAL((int)ZOK, zrc);
367 zrc = zoo_wget_children(zh, "/mytest", default_zoo_watcher, NULL, &str_vec);
368 CPPUNIT_ASSERT_EQUAL((int)ZOK, zrc);
369 zrc = zoo_create(zh, "/mytest/test1", buff, 10, &ZOO_OPEN_ACL_UNSAFE, 0, path, 512);
370 CPPUNIT_ASSERT_EQUAL((int)ZOK, zrc);
371 zrc = zoo_wget_children(zh, "/mytest", default_zoo_watcher, NULL, &str_vec);
372 CPPUNIT_ASSERT_EQUAL((int)ZOK, zrc);
373 zrc = zoo_delete(zh, "/mytest/test1", -1);
374 CPPUNIT_ASSERT_EQUAL((int)ZOK, zrc);
375 zookeeper_close(zh);
376 }
377
testBadDescriptor()378 void testBadDescriptor() {
379 watchctx_t *ctx = NULL;
380 zhandle_t *zh = zookeeper_init(hostPorts, NULL, 10000, 0, ctx, 0);
381 sleep(1);
382 zh->io_count = 0;
383 //close socket
384 close_zsock(zh->fd);
385 sleep(1);
386 //Check that doIo isn't spinning
387 CPPUNIT_ASSERT(zh->io_count < 2);
388 zookeeper_close(zh);
389 }
390
391 /* Checks the zoo_set_servers_resolution_delay default and operation */
testServersResolutionDelay()392 void testServersResolutionDelay() {
393 watchctx_t ctx;
394 zhandle_t *zk = createClient(&ctx);
395 int rc;
396 struct timeval tv;
397 struct Stat stat;
398
399 CPPUNIT_ASSERT(zk);
400 CPPUNIT_ASSERT(zk->resolve_delay_ms == 0);
401
402 // a) Default/0 case: resolve at each request.
403
404 tv = zk->last_resolve;
405 usleep(10000); // 10ms
406
407 rc = zoo_exists(zk, "/", 0, &stat);
408 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
409
410 // Must have changed because of the request.
411 CPPUNIT_ASSERT(zk->last_resolve.tv_sec != tv.tv_sec ||
412 zk->last_resolve.tv_usec != tv.tv_usec);
413
414 // b) Disabled/-1 case: never perform "routine" resolutions.
415
416 rc = zoo_set_servers_resolution_delay(zk, -1); // Disabled
417 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
418
419 tv = zk->last_resolve;
420 usleep(10000); // 10ms
421
422 rc = zoo_exists(zk, "/", 0, &stat);
423 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
424
425 // Must not have changed as auto-resolution is disabled.
426 CPPUNIT_ASSERT(zk->last_resolve.tv_sec == tv.tv_sec &&
427 zk->last_resolve.tv_usec == tv.tv_usec);
428
429 // c) Invalid delay is rejected.
430
431 rc = zoo_set_servers_resolution_delay(zk, -1000); // Bad
432 CPPUNIT_ASSERT_EQUAL((int)ZBADARGUMENTS, rc);
433
434 // d) Valid delay, no resolution within window.
435
436 rc = zoo_set_servers_resolution_delay(zk, 500); // 0.5s
437 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
438
439 tv = zk->last_resolve;
440 usleep(10000); // 10ms
441
442 rc = zoo_exists(zk, "/", 0, &stat);
443 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
444
445 // Must not have changed because the request (hopefully!)
446 // executed in less than 0.5s.
447 CPPUNIT_ASSERT(zk->last_resolve.tv_sec == tv.tv_sec &&
448 zk->last_resolve.tv_usec == tv.tv_usec);
449
450 // e) Valid delay, at least one resolution after delay.
451
452 usleep(500 * 1000); // 0.5s
453
454 rc = zoo_exists(zk, "/", 0, &stat);
455 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
456
457 // Must have changed because we waited 0.5s between the
458 // capture and the last request.
459 CPPUNIT_ASSERT(zk->last_resolve.tv_sec != tv.tv_sec ||
460 zk->last_resolve.tv_usec != tv.tv_usec);
461 }
462
testPing()463 void testPing()
464 {
465 watchctx_t ctxIdle;
466 watchctx_t ctxWC;
467 zhandle_t *zkIdle = createClient(&ctxIdle);
468 zhandle_t *zkWatchCreator = createClient(&ctxWC);
469
470 CPPUNIT_ASSERT(zkIdle);
471 CPPUNIT_ASSERT(zkWatchCreator);
472
473 char path[80];
474 sprintf(path, "/testping");
475 int rc = zoo_create(zkWatchCreator, path, "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
476 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
477
478 for(int i = 0; i < 30; i++) {
479 sprintf(path, "/testping/%i", i);
480 rc = zoo_create(zkWatchCreator, path, "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
481 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
482 }
483
484 for(int i = 0; i < 30; i++) {
485 sprintf(path, "/testping/%i", i);
486 struct Stat stat;
487 rc = zoo_exists(zkIdle, path, 1, &stat);
488 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
489 }
490
491 for(int i = 0; i < 30; i++) {
492 sprintf(path, "/testping/%i", i);
493 usleep(500000);
494 rc = zoo_delete(zkWatchCreator, path, -1);
495 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
496 }
497 struct Stat stat;
498 CPPUNIT_ASSERT_EQUAL((int)ZNONODE, zoo_exists(zkIdle, "/testping/0", 0, &stat));
499 }
500
waitForEvent(zhandle_t * zh,watchctx_t * ctx,int seconds)501 bool waitForEvent(zhandle_t *zh, watchctx_t *ctx, int seconds) {
502 time_t expires = time(0) + seconds;
503 while(ctx->countEvents() == 0 && time(0) < expires) {
504 yield(zh, 1);
505 }
506 return ctx->countEvents() > 0;
507 }
508
509 #define COUNT 100
510
511 static zhandle_t *async_zk;
512 static volatile int count;
513 static const char* hp_chroot;
514
statCompletion(int rc,const struct Stat * stat,const void * data)515 static void statCompletion(int rc, const struct Stat *stat, const void *data) {
516 int tmp = (int) (long) data;
517 CPPUNIT_ASSERT_EQUAL(tmp, rc);
518 }
519
stringCompletion(int rc,const char * value,const void * data)520 static void stringCompletion(int rc, const char *value, const void *data) {
521 char *path = (char*)data;
522
523 if (rc == ZCONNECTIONLOSS && path) {
524 // Try again
525 rc = zoo_acreate(async_zk, path, "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, stringCompletion, 0);
526 } else if (rc != ZOK) {
527 // fprintf(stderr, "rc = %d with path = %s\n", rc, (path ? path : "null"));
528 }
529 if (path) {
530 free(path);
531 }
532 }
533
stringStatCompletion(int rc,const char * value,const struct Stat * stat,const void * data)534 static void stringStatCompletion(int rc, const char *value, const struct Stat *stat,
535 const void *data) {
536 stringCompletion(rc, value, data);
537 CPPUNIT_ASSERT(stat != 0);
538 }
539
create_completion_fn(int rc,const char * value,const void * data)540 static void create_completion_fn(int rc, const char* value, const void *data) {
541 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
542 if (data) {
543 const char *expected_value = (const char *)data;
544 CPPUNIT_ASSERT_EQUAL(string(expected_value), string(value));
545 }
546 count++;
547 }
548
waitForCreateCompletion(int seconds)549 static void waitForCreateCompletion(int seconds) {
550 time_t expires = time(0) + seconds;
551 while(count == 0 && time(0) < expires) {
552 sleep(1);
553 }
554 count--;
555 }
556
watcher_chroot_fn(zhandle_t * zh,int type,int state,const char * path,void * watcherCtx)557 static void watcher_chroot_fn(zhandle_t *zh, int type,
558 int state, const char *path,void *watcherCtx) {
559 // check for path
560 char *client_path = (char *) watcherCtx;
561 CPPUNIT_ASSERT(strcmp(client_path, path) == 0);
562 count ++;
563 }
564
waitForChrootWatch(int seconds)565 static void waitForChrootWatch(int seconds) {
566 time_t expires = time(0) + seconds;
567 while (count == 0 && time(0) < expires) {
568 sleep(1);
569 }
570 count--;
571 }
572
waitForVoidCompletion(int seconds)573 static void waitForVoidCompletion(int seconds) {
574 time_t expires = time(0) + seconds;
575 while(count == 0 && time(0) < expires) {
576 sleep(1);
577 }
578 count--;
579 }
580
voidCompletion(int rc,const void * data)581 static void voidCompletion(int rc, const void *data) {
582 int tmp = (int) (long) data;
583 CPPUNIT_ASSERT_EQUAL(tmp, rc);
584 count++;
585 }
586
verifyCreateFails(const char * path,zhandle_t * zk)587 static void verifyCreateFails(const char *path, zhandle_t *zk) {
588 CPPUNIT_ASSERT_EQUAL((int)ZBADARGUMENTS, zoo_create(zk,
589 path, "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0));
590 }
591
verifyCreateOk(const char * path,zhandle_t * zk)592 static void verifyCreateOk(const char *path, zhandle_t *zk) {
593 CPPUNIT_ASSERT_EQUAL((int)ZOK, zoo_create(zk,
594 path, "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0));
595 }
596
verifyCreateFailsSeq(const char * path,zhandle_t * zk)597 static void verifyCreateFailsSeq(const char *path, zhandle_t *zk) {
598 CPPUNIT_ASSERT_EQUAL((int)ZBADARGUMENTS, zoo_create(zk,
599 path, "", 0, &ZOO_OPEN_ACL_UNSAFE, ZOO_SEQUENCE, 0, 0));
600 }
601
verifyCreateOkSeq(const char * path,zhandle_t * zk)602 static void verifyCreateOkSeq(const char *path, zhandle_t *zk) {
603 CPPUNIT_ASSERT_EQUAL((int)ZOK, zoo_create(zk,
604 path, "", 0, &ZOO_OPEN_ACL_UNSAFE, ZOO_SEQUENCE, 0, 0));
605 }
606
607
608 /**
609 returns false if the vectors dont match
610 **/
compareAcl(struct ACL_vector acl1,struct ACL_vector acl2)611 bool compareAcl(struct ACL_vector acl1, struct ACL_vector acl2) {
612 if (acl1.count != acl2.count) {
613 return false;
614 }
615 struct ACL *aclval1 = acl1.data;
616 struct ACL *aclval2 = acl2.data;
617 if (aclval1->perms != aclval2->perms) {
618 return false;
619 }
620 struct Id id1 = aclval1->id;
621 struct Id id2 = aclval2->id;
622 if (strcmp(id1.scheme, id2.scheme) != 0) {
623 return false;
624 }
625 if (strcmp(id1.id, id2.id) != 0) {
626 return false;
627 }
628 return true;
629 }
630
testDeserializeString()631 void testDeserializeString() {
632 char *val_str;
633 int rc = 0;
634 int val = -1;
635 struct iarchive *ia;
636 struct buff_struct_2 *b;
637 struct oarchive *oa = create_buffer_oarchive();
638 oa->serialize_Int(oa, "int", &val);
639 b = (struct buff_struct_2 *) oa->priv;
640 ia = create_buffer_iarchive(b->buffer, b->len);
641 rc = ia->deserialize_String(ia, "string", &val_str);
642 CPPUNIT_ASSERT_EQUAL(-EINVAL, rc);
643 }
644
testAcl()645 void testAcl() {
646 int rc;
647 struct ACL_vector aclvec;
648 struct Stat stat;
649 watchctx_t ctx;
650 zhandle_t *zk = createClient(&ctx);
651 rc = zoo_create(zk, "/acl", "", 0,
652 &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
653 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
654 rc = zoo_get_acl(zk, "/acl", &aclvec, &stat );
655 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
656 bool cmp = compareAcl(ZOO_OPEN_ACL_UNSAFE, aclvec);
657 CPPUNIT_ASSERT_EQUAL(true, cmp);
658 rc = zoo_set_acl(zk, "/acl", -1, &ZOO_READ_ACL_UNSAFE);
659 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
660 rc = zoo_get_acl(zk, "/acl", &aclvec, &stat);
661 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
662 cmp = compareAcl(ZOO_READ_ACL_UNSAFE, aclvec);
663 CPPUNIT_ASSERT_EQUAL(true, cmp);
664 }
665
666
testAuth()667 void testAuth() {
668 int rc;
669 count = 0;
670 watchctx_t ctx1, ctx2, ctx3, ctx4, ctx5;
671 zhandle_t *zk = createClient(&ctx1);
672 struct ACL_vector nodeAcl;
673 struct ACL acl_val;
674 rc = zoo_add_auth(0, "", 0, 0, voidCompletion, (void*)-1);
675 CPPUNIT_ASSERT_EQUAL((int) ZBADARGUMENTS, rc);
676
677 rc = zoo_add_auth(zk, 0, 0, 0, voidCompletion, (void*)-1);
678 CPPUNIT_ASSERT_EQUAL((int) ZBADARGUMENTS, rc);
679
680 // auth as pat, create /tauth1, close session
681 rc = zoo_add_auth(zk, "digest", "pat:passwd", 10, voidCompletion,
682 (void*)ZOK);
683 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
684 waitForVoidCompletion(3);
685 CPPUNIT_ASSERT(count == 0);
686
687 rc = zoo_create(zk, "/tauth1", "", 0, &ZOO_CREATOR_ALL_ACL, 0, 0, 0);
688 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
689
690 {
691 //create a new client
692 zk = createClient(&ctx4);
693 rc = zoo_add_auth(zk, "digest", "", 0, voidCompletion, (void*)ZOK);
694 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
695 waitForVoidCompletion(3);
696 CPPUNIT_ASSERT(count == 0);
697
698 rc = zoo_add_auth(zk, "digest", "", 0, voidCompletion, (void*)ZOK);
699 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
700 waitForVoidCompletion(3);
701 CPPUNIT_ASSERT(count == 0);
702 }
703
704 //create a new client
705 zk = createClient(&ctx2);
706
707 rc = zoo_add_auth(zk, "digest", "pat:passwd2", 11, voidCompletion,
708 (void*)ZOK);
709 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
710 waitForVoidCompletion(3);
711 CPPUNIT_ASSERT(count == 0);
712
713 char buf[1024];
714 int blen = sizeof(buf);
715 struct Stat stat;
716 rc = zoo_get(zk, "/tauth1", 0, buf, &blen, &stat);
717 CPPUNIT_ASSERT_EQUAL((int)ZNOAUTH, rc);
718 // add auth pat w/correct pass verify success
719 rc = zoo_add_auth(zk, "digest", "pat:passwd", 10, voidCompletion,
720 (void*)ZOK);
721
722 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
723 rc = zoo_get(zk, "/tauth1", 0, buf, &blen, &stat);
724 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
725 waitForVoidCompletion(3);
726 CPPUNIT_ASSERT(count == 0);
727 //create a new client
728 zk = createClient(&ctx3);
729 rc = zoo_add_auth(zk, "digest", "pat:passwd", 10, voidCompletion, (void*) ZOK);
730 waitForVoidCompletion(3);
731 CPPUNIT_ASSERT(count == 0);
732 rc = zoo_add_auth(zk, "ip", "none", 4, voidCompletion, (void*)ZOK);
733 //make the server forget the auths
734 waitForVoidCompletion(3);
735 CPPUNIT_ASSERT(count == 0);
736
737 stopServer();
738 CPPUNIT_ASSERT(ctx3.waitForDisconnected(zk));
739 startServer();
740 CPPUNIT_ASSERT(ctx3.waitForConnected(zk));
741 // now try getting the data
742 rc = zoo_get(zk, "/tauth1", 0, buf, &blen, &stat);
743 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
744 // also check for get
745 rc = zoo_get_acl(zk, "/", &nodeAcl, &stat);
746 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
747 // check if the acl has all the perms
748 CPPUNIT_ASSERT_EQUAL((int)1, (int)nodeAcl.count);
749 acl_val = *(nodeAcl.data);
750 CPPUNIT_ASSERT_EQUAL((int) acl_val.perms, ZOO_PERM_ALL);
751 // verify on root node
752 rc = zoo_set_acl(zk, "/", -1, &ZOO_CREATOR_ALL_ACL);
753 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
754
755 rc = zoo_set_acl(zk, "/", -1, &ZOO_OPEN_ACL_UNSAFE);
756 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
757
758 //[ZOOKEEPER-1108], test that auth info is sent to server, if client is not
759 //connected to server when zoo_add_auth was called.
760 zhandle_t *zk_auth = zookeeper_init(hostPorts, NULL, 10000, 0, NULL, 0);
761 rc = zoo_add_auth(zk_auth, "digest", "pat:passwd", 10, voidCompletion, (void*)ZOK);
762 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
763 sleep(2);
764 CPPUNIT_ASSERT(count == 1);
765 count = 0;
766 CPPUNIT_ASSERT_EQUAL((int) ZOK, zookeeper_close(zk_auth));
767
768 struct sockaddr addr;
769 socklen_t addr_len = sizeof(addr);
770 zk = createClient(&ctx5);
771 stopServer();
772 CPPUNIT_ASSERT(ctx5.waitForDisconnected(zk));
773 CPPUNIT_ASSERT(zookeeper_get_connected_host(zk, &addr, &addr_len) == NULL);
774 addr_len = sizeof(addr);
775 startServer();
776 CPPUNIT_ASSERT(ctx5.waitForConnected(zk));
777 CPPUNIT_ASSERT(zookeeper_get_connected_host(zk, &addr, &addr_len) != NULL);
778 }
779
testCreate()780 void testCreate() {
781 watchctx_t ctx;
782 int rc = 0;
783 zhandle_t *zk = createClient(&ctx);
784 CPPUNIT_ASSERT(zk);
785 char pathbuf[80];
786
787 struct Stat stat_a = {0};
788 struct Stat stat_b = {0};
789 rc = zoo_create2(zk, "/testcreateA", "", 0,
790 &ZOO_OPEN_ACL_UNSAFE, 0, pathbuf, sizeof(pathbuf), &stat_a);
791 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
792 CPPUNIT_ASSERT(strcmp(pathbuf, "/testcreateA") == 0);
793 CPPUNIT_ASSERT(stat_a.czxid > 0);
794 CPPUNIT_ASSERT(stat_a.mtime > 0);
795
796 rc = zoo_create2(zk, "/testcreateB", "", 0,
797 &ZOO_OPEN_ACL_UNSAFE, 0, pathbuf, sizeof(pathbuf), &stat_b);
798 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
799 CPPUNIT_ASSERT(strcmp(pathbuf, "/testcreateB") == 0);
800 CPPUNIT_ASSERT(stat_b.czxid > 0);
801 CPPUNIT_ASSERT(stat_b.mtime > 0);
802
803 // Should get different Stats back from different creates
804 CPPUNIT_ASSERT(Stat_eq(&stat_a, &stat_b) != 1);
805 }
806
testCreateContainer()807 void testCreateContainer() {
808 watchctx_t ctx;
809 int rc = 0;
810 zhandle_t *zk = createClient(&ctx);
811 CPPUNIT_ASSERT(zk);
812 char pathbuf[80];
813 struct Stat stat = {0};
814
815 rc = zoo_create2(zk, "/testContainer", "", 0, &ZOO_OPEN_ACL_UNSAFE,
816 ZOO_CONTAINER, pathbuf, sizeof(pathbuf), &stat);
817 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
818 }
819
testCreateTtl()820 void testCreateTtl() {
821 watchctx_t ctx;
822 int rc = 0;
823 zhandle_t *zk = createClient(&ctx);
824 CPPUNIT_ASSERT(zk);
825 char pathbuf[80];
826 struct Stat stat = {0};
827
828 rc = zoo_create2_ttl(zk, "/testTtl", "", 0, &ZOO_OPEN_ACL_UNSAFE,
829 ZOO_PERSISTENT_WITH_TTL, 1, pathbuf, sizeof(pathbuf), &stat);
830 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
831
832 sleep(1);
833
834 rc = zoo_exists(zk, "/testTtl", 1, &stat);
835 CPPUNIT_ASSERT_EQUAL((int) ZNONODE, rc);
836 }
837
testGetChildren2()838 void testGetChildren2() {
839 int rc;
840 watchctx_t ctx;
841 zhandle_t *zk = createClient(&ctx);
842
843 rc = zoo_create(zk, "/parent", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
844 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
845
846 rc = zoo_create(zk, "/parent/child_a", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
847 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
848
849 rc = zoo_create(zk, "/parent/child_b", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
850 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
851
852 rc = zoo_create(zk, "/parent/child_c", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
853 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
854
855 rc = zoo_create(zk, "/parent/child_d", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
856 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
857
858 struct String_vector strings;
859 struct Stat stat_a, stat_b;
860
861 rc = zoo_get_children2(zk, "/parent", 0, &strings, &stat_a);
862 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
863
864 rc = zoo_exists(zk, "/parent", 0, &stat_b);
865 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
866
867 CPPUNIT_ASSERT(Stat_eq(&stat_a, &stat_b));
868 CPPUNIT_ASSERT(stat_a.numChildren == 4);
869 }
870
testIPV6()871 void testIPV6() {
872 watchctx_t ctx;
873 zhandle_t *zk = createClient("::1:22181", &ctx);
874 CPPUNIT_ASSERT(zk);
875 int rc = 0;
876 rc = zoo_create(zk, "/ipv6", NULL, -1,
877 &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
878 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
879 }
880
881 #ifdef HAVE_OPENSSL_H
testSSL()882 void testSSL() {
883 watchctx_t ctx;
884 zoo_set_debug_level(ZOO_LOG_LEVEL_DEBUG);
885 zhandle_t *zk = createSSLClient("127.0.0.1:22281", "/tmp/certs/server.crt,/tmp/certs/client.crt,/tmp/certs/clientkey.pem,password", &ctx);
886 CPPUNIT_ASSERT(zk);
887 int rc = 0;
888 rc = zoo_create(zk, "/ssl", NULL, -1,
889 &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
890 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
891 }
892 #endif
893
testNullData()894 void testNullData() {
895 watchctx_t ctx;
896 zhandle_t *zk = createClient(&ctx);
897 CPPUNIT_ASSERT(zk);
898 int rc = 0;
899 rc = zoo_create(zk, "/mahadev", NULL, -1,
900 &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
901 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
902 char buffer[512];
903 struct Stat stat;
904 int len = 512;
905 rc = zoo_wget(zk, "/mahadev", NULL, NULL, buffer, &len, &stat);
906 CPPUNIT_ASSERT_EQUAL( -1, len);
907 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
908 rc = zoo_set(zk, "/mahadev", NULL, -1, -1);
909 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
910 rc = zoo_wget(zk, "/mahadev", NULL, NULL, buffer, &len, &stat);
911 CPPUNIT_ASSERT_EQUAL( -1, len);
912 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
913 }
914
testPath()915 void testPath() {
916 watchctx_t ctx;
917 char pathbuf[20];
918 zhandle_t *zk = createClient(&ctx);
919 CPPUNIT_ASSERT(zk);
920 int rc = 0;
921
922 memset(pathbuf, 'X', 20);
923 rc = zoo_create(zk, "/testpathpath0", "", 0,
924 &ZOO_OPEN_ACL_UNSAFE, 0, pathbuf, 0);
925 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
926 CPPUNIT_ASSERT_EQUAL('X', pathbuf[0]);
927
928 rc = zoo_create(zk, "/testpathpath1", "", 0,
929 &ZOO_OPEN_ACL_UNSAFE, 0, pathbuf, 1);
930 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
931 CPPUNIT_ASSERT(strlen(pathbuf) == 0);
932
933 rc = zoo_create(zk, "/testpathpath2", "", 0,
934 &ZOO_OPEN_ACL_UNSAFE, 0, pathbuf, 2);
935 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
936 CPPUNIT_ASSERT(strcmp(pathbuf, "/") == 0);
937
938 rc = zoo_create(zk, "/testpathpath3", "", 0,
939 &ZOO_OPEN_ACL_UNSAFE, 0, pathbuf, 3);
940 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
941 CPPUNIT_ASSERT(strcmp(pathbuf, "/t") == 0);
942
943 rc = zoo_create(zk, "/testpathpath7", "", 0,
944 &ZOO_OPEN_ACL_UNSAFE, 0, pathbuf, 15);
945 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
946 CPPUNIT_ASSERT(strcmp(pathbuf, "/testpathpath7") == 0);
947
948 rc = zoo_create(zk, "/testpathpath8", "", 0,
949 &ZOO_OPEN_ACL_UNSAFE, 0, pathbuf, 16);
950 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
951 CPPUNIT_ASSERT(strcmp(pathbuf, "/testpathpath8") == 0);
952 }
953
testPathValidation()954 void testPathValidation() {
955 watchctx_t ctx;
956 zhandle_t *zk = createClient(&ctx);
957 CPPUNIT_ASSERT(zk);
958
959 verifyCreateFails(0, zk);
960 verifyCreateFails("", zk);
961 verifyCreateFails("//", zk);
962 verifyCreateFails("///", zk);
963 verifyCreateFails("////", zk);
964 verifyCreateFails("/.", zk);
965 verifyCreateFails("/..", zk);
966 verifyCreateFails("/./", zk);
967 verifyCreateFails("/../", zk);
968 verifyCreateFails("/foo/./", zk);
969 verifyCreateFails("/foo/../", zk);
970 verifyCreateFails("/foo/.", zk);
971 verifyCreateFails("/foo/..", zk);
972 verifyCreateFails("/./.", zk);
973 verifyCreateFails("/../..", zk);
974 verifyCreateFails("/foo/bar/", zk);
975 verifyCreateFails("/foo//bar", zk);
976 verifyCreateFails("/foo/bar//", zk);
977
978 verifyCreateFails("foo", zk);
979 verifyCreateFails("a", zk);
980
981 // verify that trailing fails, except for seq which adds suffix
982 verifyCreateOk("/createseq", zk);
983 verifyCreateFails("/createseq/", zk);
984 verifyCreateOkSeq("/createseq/", zk);
985 verifyCreateOkSeq("/createseq/.", zk);
986 verifyCreateOkSeq("/createseq/..", zk);
987 verifyCreateFailsSeq("/createseq//", zk);
988 verifyCreateFailsSeq("/createseq/./", zk);
989 verifyCreateFailsSeq("/createseq/../", zk);
990
991 verifyCreateOk("/.foo", zk);
992 verifyCreateOk("/.f.", zk);
993 verifyCreateOk("/..f", zk);
994 verifyCreateOk("/..f..", zk);
995 verifyCreateOk("/f.c", zk);
996 verifyCreateOk("/f", zk);
997 verifyCreateOk("/f/.f", zk);
998 verifyCreateOk("/f/f.", zk);
999 verifyCreateOk("/f/..f", zk);
1000 verifyCreateOk("/f/f..", zk);
1001 verifyCreateOk("/f/.f/f", zk);
1002 verifyCreateOk("/f/f./f", zk);
1003 }
1004
testChroot()1005 void testChroot() {
1006 // the c client async callbacks do
1007 // not callback with the path, so
1008 // we dont need to test taht for now
1009 // we should fix that though soon!
1010 watchctx_t ctx, ctx_ch;
1011 zhandle_t *zk, *zk_ch;
1012 char buf[60];
1013 int rc, len;
1014 struct Stat stat;
1015 const char* data = "garbage";
1016 const char* retStr = "/chroot";
1017 const char* root= "/";
1018 zk_ch = createchClient(&ctx_ch, "127.0.0.1:22181/testch1/mahadev");
1019 CPPUNIT_ASSERT(zk_ch != NULL);
1020 zk = createClient(&ctx);
1021 // first test with a NULL zk handle, make sure client library does not
1022 // dereference a null pointer, but instead returns ZBADARGUMENTS
1023 rc = zoo_create(NULL, "/testch1", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
1024 CPPUNIT_ASSERT_EQUAL((int) ZBADARGUMENTS, rc);
1025 rc = zoo_create(zk, "/testch1", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
1026 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
1027 rc = zoo_create(zk, "/testch1/mahadev", data, 7, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
1028 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
1029 // try an exists with /
1030 len = 60;
1031 rc = zoo_get(zk_ch, "/", 0, buf, &len, &stat);
1032 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1033 //check if the data is the same
1034 CPPUNIT_ASSERT(strncmp(buf, data, 7) == 0);
1035 //check for watches
1036 rc = zoo_wexists(zk_ch, "/chroot", watcher_chroot_fn, (void *) retStr, &stat);
1037 //now check if we can do create/delete/get/sets/acls/getChildren and others
1038 //check create
1039 rc = zoo_create(zk_ch, "/chroot", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0,0);
1040 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
1041 waitForChrootWatch(3);
1042 CPPUNIT_ASSERT(count == 0);
1043 rc = zoo_create(zk_ch, "/chroot/child", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
1044 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
1045 rc = zoo_exists(zk, "/testch1/mahadev/chroot/child", 0, &stat);
1046 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
1047
1048 rc = zoo_delete(zk_ch, "/chroot/child", -1);
1049 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
1050 rc = zoo_exists(zk, "/testch1/mahadev/chroot/child", 0, &stat);
1051 CPPUNIT_ASSERT_EQUAL((int) ZNONODE, rc);
1052 rc = zoo_wget(zk_ch, "/chroot", watcher_chroot_fn, (char*) retStr,
1053 buf, &len, &stat);
1054 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
1055 rc = zoo_set(zk_ch, "/chroot",buf, 3, -1);
1056 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
1057 waitForChrootWatch(3);
1058 CPPUNIT_ASSERT(count == 0);
1059 // check for getchildren
1060 struct String_vector children;
1061 rc = zoo_get_children(zk_ch, "/", 0, &children);
1062 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1063 CPPUNIT_ASSERT_EQUAL((int)1, (int)children.count);
1064 //check if te child if chroot
1065 CPPUNIT_ASSERT(strcmp((retStr+1), children.data[0]) == 0);
1066 // check for get/set acl
1067 struct ACL_vector acl;
1068 rc = zoo_get_acl(zk_ch, "/", &acl, &stat);
1069 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1070 CPPUNIT_ASSERT_EQUAL((int)1, (int)acl.count);
1071 CPPUNIT_ASSERT_EQUAL((int)ZOO_PERM_ALL, (int)acl.data->perms);
1072 // set acl
1073 rc = zoo_set_acl(zk_ch, "/chroot", -1, &ZOO_READ_ACL_UNSAFE);
1074 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
1075 // see if you add children
1076 rc = zoo_create(zk_ch, "/chroot/child1", "",0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
1077 CPPUNIT_ASSERT_EQUAL((int)ZNOAUTH, rc);
1078 //add wget children test
1079 rc = zoo_wget_children(zk_ch, "/", watcher_chroot_fn, (char*) root, &children);
1080 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1081
1082 //now create a node
1083 rc = zoo_create(zk_ch, "/child2", "",0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
1084 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
1085 waitForChrootWatch(3);
1086 CPPUNIT_ASSERT(count == 0);
1087 //check for one async call just to make sure
1088 rc = zoo_acreate(zk_ch, "/child3", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0,
1089 create_completion_fn, 0);
1090 waitForCreateCompletion(3);
1091 CPPUNIT_ASSERT(count == 0);
1092
1093 //ZOOKEEPER-1027 correctly return path_buffer without prefixed chroot
1094 const char* path = "/zookeeper1027";
1095 char path_buffer[1024];
1096 int path_buffer_len=sizeof(path_buffer);
1097 rc = zoo_create(zk_ch, path, "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, path_buffer, path_buffer_len);
1098 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
1099 CPPUNIT_ASSERT_EQUAL(string(path), string(path_buffer));
1100
1101 const char* path2282 = "/zookeeper2282";
1102 rc = zoo_acreate(zk_ch, path2282, "", 0, &ZOO_OPEN_ACL_UNSAFE, 0,
1103 create_completion_fn, path2282);
1104 waitForCreateCompletion(3);
1105 CPPUNIT_ASSERT(count == 0);
1106 }
1107
1108 // Test creating normal handle via zookeeper_init then explicitly setting callback
testLogCallbackSet()1109 void testLogCallbackSet()
1110 {
1111 watchctx_t ctx;
1112 CPPUNIT_ASSERT(logMessages.empty());
1113 zhandle_t *zk = createClient(&ctx);
1114
1115 zoo_set_log_callback(zk, &logMessageHandler);
1116 CPPUNIT_ASSERT_EQUAL(zoo_get_log_callback(zk), &logMessageHandler);
1117
1118 // Log 10 messages and ensure all go to callback
1119 const std::size_t expected = 10;
1120 for (std::size_t i = 0; i < expected; i++)
1121 {
1122 LOG_INFO(LOGCALLBACK(zk), "%s #%d", __FUNCTION__, i);
1123 }
1124 CPPUNIT_ASSERT(expected == logMessages.size());
1125 }
1126
1127 // Test creating handle via zookeeper_init2 to ensure all connection messages go to callback
testLogCallbackInit()1128 void testLogCallbackInit()
1129 {
1130 logMessages.clear();
1131 watchctx_t ctx;
1132 zhandle_t *zk = createClient(&ctx, &logMessageHandler);
1133 CPPUNIT_ASSERT_EQUAL(zoo_get_log_callback(zk), &logMessageHandler);
1134
1135 // All the connection messages should have gone to the callback -- don't
1136 // want this to be a maintenance issue so we're not asserting exact count
1137 std::size_t numBefore = logMessages.size();
1138 CPPUNIT_ASSERT(numBefore != 0);
1139
1140 // Log 10 messages and ensure all go to callback
1141 const std::size_t expected = 10;
1142 for (std::size_t i = 0; i < expected; i++)
1143 {
1144 LOG_INFO(LOGCALLBACK(zk), "%s #%d", __FUNCTION__, i);
1145 }
1146 CPPUNIT_ASSERT(logMessages.size() == numBefore + expected);
1147 }
1148
1149 // Test clearing log callback -- logging should resume going to logstream
testLogCallbackClear()1150 void testLogCallbackClear()
1151 {
1152 logMessages.clear();
1153 watchctx_t ctx;
1154 zhandle_t *zk = createClient(&ctx, &logMessageHandler);
1155 CPPUNIT_ASSERT_EQUAL(zoo_get_log_callback(zk), &logMessageHandler);
1156
1157 // All the connection messages should have gone to the callback -- again, we don't
1158 // want this to be a maintenance issue so we're not asserting exact count
1159 int numBefore = logMessages.size();
1160 CPPUNIT_ASSERT(numBefore > 0);
1161
1162 // Clear log_callback
1163 zoo_set_log_callback(zk, NULL);
1164
1165 // Future log messages should go to logstream not callback
1166 LOG_INFO(LOGCALLBACK(zk), __FUNCTION__);
1167 int numAfter = logMessages.size();
1168 CPPUNIT_ASSERT_EQUAL(numBefore, numAfter);
1169 }
1170
testAsyncWatcherAutoReset()1171 void testAsyncWatcherAutoReset()
1172 {
1173 watchctx_t ctx;
1174 zhandle_t *zk = createClient(&ctx);
1175 watchctx_t lctx[COUNT];
1176 int i;
1177 char path[80];
1178 int rc;
1179 evt_t evt;
1180
1181 async_zk = zk;
1182 for(i = 0; i < COUNT; i++) {
1183 sprintf(path, "/awar%d", i);
1184 rc = zoo_awexists(zk, path, watcher, &lctx[i], statCompletion, (void*)ZNONODE);
1185 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1186 }
1187
1188 yield(zk, 0);
1189
1190 for(i = 0; i < COUNT/4; i++) {
1191 sprintf(path, "/awar%d", i);
1192 rc = zoo_acreate(zk, path, "", 0, &ZOO_OPEN_ACL_UNSAFE, 0,
1193 stringCompletion, strdup(path));
1194 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1195 }
1196
1197 for(i = COUNT/4; i < COUNT/2; i++) {
1198 sprintf(path, "/awar%d", i);
1199 rc = zoo_acreate2(zk, path, "", 0, &ZOO_OPEN_ACL_UNSAFE, 0,
1200 stringStatCompletion, strdup(path));
1201 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1202 }
1203
1204 yield(zk, 3);
1205 for(i = 0; i < COUNT/2; i++) {
1206 sprintf(path, "/awar%d", i);
1207 CPPUNIT_ASSERT_MESSAGE(path, waitForEvent(zk, &lctx[i], 5));
1208 evt = lctx[i].getEvent();
1209 CPPUNIT_ASSERT_EQUAL_MESSAGE(evt.path.c_str(), ZOO_CREATED_EVENT, evt.type);
1210 CPPUNIT_ASSERT_EQUAL(string(path), evt.path);
1211 }
1212
1213 for(i = COUNT/2 + 1; i < COUNT*10; i++) {
1214 sprintf(path, "/awar%d", i);
1215 rc = zoo_acreate(zk, path, "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, stringCompletion, strdup(path));
1216 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1217 }
1218
1219 yield(zk, 1);
1220 stopServer();
1221 CPPUNIT_ASSERT(ctx.waitForDisconnected(zk));
1222 startServer();
1223 CPPUNIT_ASSERT(ctx.waitForConnected(zk));
1224 yield(zk, 3);
1225 for(i = COUNT/2+1; i < COUNT; i++) {
1226 sprintf(path, "/awar%d", i);
1227 CPPUNIT_ASSERT_MESSAGE(path, waitForEvent(zk, &lctx[i], 5));
1228 evt = lctx[i].getEvent();
1229 CPPUNIT_ASSERT_EQUAL_MESSAGE(evt.path, ZOO_CREATED_EVENT, evt.type);
1230 CPPUNIT_ASSERT_EQUAL(string(path), evt.path);
1231 }
1232 }
1233
testWatcherAutoReset(zhandle_t * zk,watchctx_t * ctxGlobal,watchctx_t * ctxLocal)1234 void testWatcherAutoReset(zhandle_t *zk, watchctx_t *ctxGlobal,
1235 watchctx_t *ctxLocal)
1236 {
1237 bool isGlobal = (ctxGlobal == ctxLocal);
1238 int rc;
1239 struct Stat stat;
1240 char buf[1024];
1241 int blen;
1242 struct String_vector strings;
1243 const char *testName;
1244
1245 rc = zoo_create(zk, "/watchtest", "", 0,
1246 &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
1247 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1248 rc = zoo_create(zk, "/watchtest/child", "", 0,
1249 &ZOO_OPEN_ACL_UNSAFE, ZOO_EPHEMERAL, 0, 0);
1250 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1251
1252 if (isGlobal) {
1253 testName = "GlobalTest";
1254 rc = zoo_get_children(zk, "/watchtest", 1, &strings);
1255 deallocate_String_vector(&strings);
1256 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1257 blen = sizeof(buf);
1258 rc = zoo_get(zk, "/watchtest/child", 1, buf, &blen, &stat);
1259 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1260 rc = zoo_exists(zk, "/watchtest/child2", 1, &stat);
1261 CPPUNIT_ASSERT_EQUAL((int)ZNONODE, rc);
1262 } else {
1263 testName = "LocalTest";
1264 rc = zoo_wget_children(zk, "/watchtest", watcher, ctxLocal,
1265 &strings);
1266 deallocate_String_vector(&strings);
1267 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1268 blen = sizeof(buf);
1269 rc = zoo_wget(zk, "/watchtest/child", watcher, ctxLocal,
1270 buf, &blen, &stat);
1271 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1272 rc = zoo_wexists(zk, "/watchtest/child2", watcher, ctxLocal,
1273 &stat);
1274 CPPUNIT_ASSERT_EQUAL((int)ZNONODE, rc);
1275 }
1276
1277 CPPUNIT_ASSERT(ctxLocal->countEvents() == 0);
1278
1279 stopServer();
1280 CPPUNIT_ASSERT_MESSAGE(testName, ctxGlobal->waitForDisconnected(zk));
1281 startServer();
1282 CPPUNIT_ASSERT_MESSAGE(testName, ctxLocal->waitForConnected(zk));
1283
1284 CPPUNIT_ASSERT(ctxLocal->countEvents() == 0);
1285
1286 rc = zoo_set(zk, "/watchtest/child", "1", 1, -1);
1287 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1288 struct Stat stat1, stat2;
1289 rc = zoo_set2(zk, "/watchtest/child", "1", 1, -1, &stat1);
1290 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1291 CPPUNIT_ASSERT(stat1.version >= 0);
1292 rc = zoo_set2(zk, "/watchtest/child", "1", 1, stat1.version, &stat2);
1293 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1294 rc = zoo_set(zk, "/watchtest/child", "1", 1, stat2.version);
1295 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1296 rc = zoo_create(zk, "/watchtest/child2", "", 0,
1297 &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
1298 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1299
1300 CPPUNIT_ASSERT_MESSAGE(testName, waitForEvent(zk, ctxLocal, 5));
1301
1302 evt_t evt = ctxLocal->getEvent();
1303 CPPUNIT_ASSERT_EQUAL_MESSAGE(evt.path, ZOO_CHANGED_EVENT, evt.type);
1304 CPPUNIT_ASSERT_EQUAL(string("/watchtest/child"), evt.path);
1305
1306 CPPUNIT_ASSERT_MESSAGE(testName, waitForEvent(zk, ctxLocal, 5));
1307 // The create will trigget the get children and the
1308 // exists watches
1309 evt = ctxLocal->getEvent();
1310 CPPUNIT_ASSERT_EQUAL_MESSAGE(evt.path, ZOO_CREATED_EVENT, evt.type);
1311 CPPUNIT_ASSERT_EQUAL(string("/watchtest/child2"), evt.path);
1312 CPPUNIT_ASSERT_MESSAGE(testName, waitForEvent(zk, ctxLocal, 5));
1313 evt = ctxLocal->getEvent();
1314 CPPUNIT_ASSERT_EQUAL_MESSAGE(evt.path, ZOO_CHILD_EVENT, evt.type);
1315 CPPUNIT_ASSERT_EQUAL(string("/watchtest"), evt.path);
1316
1317 // Make sure Pings are giving us problems
1318 sleep(5);
1319
1320 CPPUNIT_ASSERT(ctxLocal->countEvents() == 0);
1321
1322 stopServer();
1323 CPPUNIT_ASSERT_MESSAGE(testName, ctxGlobal->waitForDisconnected(zk));
1324 startServer();
1325 CPPUNIT_ASSERT_MESSAGE(testName, ctxGlobal->waitForConnected(zk));
1326
1327 if (isGlobal) {
1328 testName = "GlobalTest";
1329 rc = zoo_get_children(zk, "/watchtest", 1, &strings);
1330 deallocate_String_vector(&strings);
1331 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1332 blen = sizeof(buf);
1333 rc = zoo_get(zk, "/watchtest/child", 1, buf, &blen, &stat);
1334 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1335 rc = zoo_exists(zk, "/watchtest/child2", 1, &stat);
1336 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1337 } else {
1338 testName = "LocalTest";
1339 rc = zoo_wget_children(zk, "/watchtest", watcher, ctxLocal,
1340 &strings);
1341 deallocate_String_vector(&strings);
1342 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1343 blen = sizeof(buf);
1344 rc = zoo_wget(zk, "/watchtest/child", watcher, ctxLocal,
1345 buf, &blen, &stat);
1346 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1347 rc = zoo_wexists(zk, "/watchtest/child2", watcher, ctxLocal,
1348 &stat);
1349 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1350 }
1351
1352 zoo_delete(zk, "/watchtest/child2", -1);
1353
1354 CPPUNIT_ASSERT_MESSAGE(testName, waitForEvent(zk, ctxLocal, 5));
1355
1356 evt = ctxLocal->getEvent();
1357 CPPUNIT_ASSERT_EQUAL_MESSAGE(evt.path, ZOO_DELETED_EVENT, evt.type);
1358 CPPUNIT_ASSERT_EQUAL(string("/watchtest/child2"), evt.path);
1359
1360 CPPUNIT_ASSERT_MESSAGE(testName, waitForEvent(zk, ctxLocal, 5));
1361 evt = ctxLocal->getEvent();
1362 CPPUNIT_ASSERT_EQUAL_MESSAGE(evt.path, ZOO_CHILD_EVENT, evt.type);
1363 CPPUNIT_ASSERT_EQUAL(string("/watchtest"), evt.path);
1364
1365 stopServer();
1366 CPPUNIT_ASSERT_MESSAGE(testName, ctxGlobal->waitForDisconnected(zk));
1367 startServer();
1368 CPPUNIT_ASSERT_MESSAGE(testName, ctxLocal->waitForConnected(zk));
1369
1370 zoo_delete(zk, "/watchtest/child", -1);
1371 zoo_delete(zk, "/watchtest", -1);
1372
1373 CPPUNIT_ASSERT_MESSAGE(testName, waitForEvent(zk, ctxLocal, 5));
1374
1375 evt = ctxLocal->getEvent();
1376 CPPUNIT_ASSERT_EQUAL_MESSAGE(evt.path, ZOO_DELETED_EVENT, evt.type);
1377 CPPUNIT_ASSERT_EQUAL(string("/watchtest/child"), evt.path);
1378
1379 // Make sure nothing is straggling
1380 sleep(1);
1381 CPPUNIT_ASSERT(ctxLocal->countEvents() == 0);
1382 }
1383
testWatcherAutoResetWithGlobal()1384 void testWatcherAutoResetWithGlobal()
1385 {
1386 {
1387 watchctx_t ctx;
1388 zhandle_t *zk = createClient(&ctx);
1389 int rc = zoo_create(zk, "/testarwg", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
1390 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
1391 rc = zoo_create(zk, "/testarwg/arwg", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
1392 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
1393 }
1394
1395 {
1396 watchctx_t ctx;
1397 zhandle_t *zk = createchClient(&ctx, "127.0.0.1:22181/testarwg/arwg");
1398
1399 testWatcherAutoReset(zk, &ctx, &ctx);
1400 }
1401 }
1402
testWatcherAutoResetWithLocal()1403 void testWatcherAutoResetWithLocal()
1404 {
1405 {
1406 watchctx_t ctx;
1407 zhandle_t *zk = createClient(&ctx);
1408 int rc = zoo_create(zk, "/testarwl", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
1409 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
1410 rc = zoo_create(zk, "/testarwl/arwl", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
1411 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
1412 }
1413
1414 {
1415 watchctx_t ctx;
1416 watchctx_t lctx;
1417 zhandle_t *zk = createchClient(&ctx, "127.0.0.1:22181/testarwl/arwl");
1418 testWatcherAutoReset(zk, &ctx, &lctx);
1419 }
1420 }
1421
testLastZxid()1422 void testLastZxid() {
1423 // ZOOKEEPER-1417: Test that c-client only update last zxid upon
1424 // receiving request response only.
1425 const int timeout = 5000;
1426 int rc;
1427 watchctx_t ctx1, ctx2;
1428 zhandle_t *zk1 = createClient(&ctx1);
1429 zhandle_t *zk2 = createClient(&ctx2);
1430 CPPUNIT_ASSERT(zk1);
1431 CPPUNIT_ASSERT(zk2);
1432
1433 int64_t original = zk2->last_zxid;
1434
1435 // Create txn to increase system zxid
1436 rc = zoo_create(zk1, "/lastzxid", "", 0,
1437 &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
1438 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1439
1440 // This should be enough time for zk2 to receive ping request
1441 usleep(timeout/2 * 1000);
1442
1443 // check that zk1's last zxid is updated
1444 struct Stat stat;
1445 rc = zoo_exists(zk1, "/lastzxid", 0, &stat);
1446 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
1447 CPPUNIT_ASSERT_EQUAL((int64_t) zk1->last_zxid, stat.czxid);
1448 // zk2's last zxid should remain the same
1449 CPPUNIT_ASSERT_EQUAL(original, (int64_t) zk2->last_zxid);
1450
1451 // Perform read and also register a watch
1452 rc = zoo_wexists(zk2, "/lastzxid", watcher, &ctx2, &stat);
1453 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
1454 int64_t updated = zk2->last_zxid;
1455 // check that zk2's last zxid is updated
1456 CPPUNIT_ASSERT_EQUAL(updated, stat.czxid);
1457
1458 // Increment system zxid again
1459 rc = zoo_set(zk1, "/lastzxid", NULL, -1, -1);
1460 CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
1461
1462 // Wait for zk2 to get watch event
1463 CPPUNIT_ASSERT(waitForEvent(zk2, &ctx2, 5));
1464 // zk2's last zxid should remain the same
1465 CPPUNIT_ASSERT_EQUAL(updated, (int64_t) zk2->last_zxid);
1466 }
1467
watcher_rw(zhandle_t * zh,int type,int state,const char * path,void * ctx)1468 static void watcher_rw(zhandle_t *zh,
1469 int type,
1470 int state,
1471 const char *path,
1472 void *ctx) {
1473 count++;
1474 }
1475
watcher_rw2(zhandle_t * zh,int type,int state,const char * path,void * ctx)1476 static void watcher_rw2(zhandle_t *zh,
1477 int type,
1478 int state,
1479 const char *path,
1480 void *ctx) {
1481 count++;
1482 }
1483
testRemoveWatchers()1484 void testRemoveWatchers() {
1485 const char *path = "/something";
1486 char buf[1024];
1487 int blen = sizeof(buf);
1488 int rc;
1489 watchctx_t ctx;
1490 zhandle_t *zk;
1491
1492 /* setup path */
1493 zk = createClient(&ctx);
1494 CPPUNIT_ASSERT(zk);
1495
1496 rc = zoo_create(zk, path, "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
1497 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1498
1499 rc = zoo_create(zk, "/something2", "", 0,
1500 &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
1501 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1502
1503 /* remove all watchers */
1504 count = 0;
1505 rc = zoo_wget(zk, path, watcher_rw, NULL, buf, &blen, NULL);
1506 rc = zoo_wget(zk, path, watcher_rw2, NULL, buf, &blen, NULL);
1507 rc = zoo_remove_all_watches(zk, path, ZWATCHTYPE_ANY, 0);
1508 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1509 rc = zoo_set(zk, path, "nowatch", 7, -1);
1510 CPPUNIT_ASSERT(count == 0);
1511
1512 /* remove a specific watcher before it's added (should fail) */
1513 rc = zoo_remove_watches(zk, path, ZWATCHTYPE_DATA,
1514 watcher_rw, NULL, 0);
1515 CPPUNIT_ASSERT_EQUAL((int)ZNOWATCHER, rc);
1516
1517 /* now add a specific watcher and then remove it */
1518 rc = zoo_wget(zk, path, watcher_rw, NULL,
1519 buf, &blen, NULL);
1520 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1521 rc = zoo_remove_watches(zk, path, ZWATCHTYPE_DATA,
1522 watcher_rw, NULL, 0);
1523 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1524
1525 /* ditto for children watcher */
1526 rc = zoo_remove_watches(zk, path, ZWATCHTYPE_CHILD,
1527 watcher_rw, NULL, 0);
1528 CPPUNIT_ASSERT_EQUAL((int)ZNOWATCHER, rc);
1529
1530 struct String_vector str_vec = {0, NULL};
1531 rc = zoo_wget_children(zk, path, watcher_rw, NULL,
1532 &str_vec);
1533 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1534 rc = zoo_remove_watches(zk, path, ZWATCHTYPE_CHILD,
1535 watcher_rw, NULL, 0);
1536 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1537
1538 /* add a watch, stop the server, and have remove fail */
1539 rc = zoo_wget(zk, path, watcher_rw, NULL,
1540 buf, &blen, NULL);
1541 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1542 stopServer();
1543 ctx.waitForDisconnected(zk);
1544 rc = zoo_remove_watches(zk, path, ZWATCHTYPE_DATA,
1545 watcher_rw, NULL, 0);
1546 CPPUNIT_ASSERT_EQUAL((int)ZCONNECTIONLOSS, rc);
1547
1548 zookeeper_close(zk);
1549
1550 /* bring the server back */
1551 startServer();
1552 zk = createClient(&ctx);
1553
1554 /* add a watch, stop the server, and remove it locally */
1555 void* ctx1=(void*)0x1;
1556 void* ctx2=(void*)0x2;
1557
1558 rc = zoo_wget(zk, path, watcher_rw, ctx1,
1559 buf, &blen, NULL);
1560 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1561
1562 rc = zoo_wget(zk, "/something2", watcher_rw, ctx2,
1563 buf, &blen, NULL);
1564 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1565
1566 stopServer();
1567 rc = zoo_remove_watches(zk, path, ZWATCHTYPE_DATA,
1568 watcher_rw, ctx1, 1);
1569 CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
1570
1571 rc = zoo_remove_watches(zk, path, ZWATCHTYPE_DATA,
1572 watcher_rw, ctx1, 1);
1573 CPPUNIT_ASSERT_EQUAL((int)ZNOWATCHER, rc);
1574
1575 rc = zoo_remove_watches(zk, "/something2", ZWATCHTYPE_DATA,
1576 watcher_rw, ctx2, 1);
1577 CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
1578 }
1579 };
1580
1581 volatile int Zookeeper_simpleSystem::count;
1582 zhandle_t *Zookeeper_simpleSystem::async_zk;
1583 const char Zookeeper_simpleSystem::hostPorts[] = "127.0.0.1:22181";
1584 CPPUNIT_TEST_SUITE_REGISTRATION(Zookeeper_simpleSystem);
1585 #endif
1586