TestZookeeperClose.cc 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  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. #include <cppunit/extensions/HelperMacros.h>
  19. #include "ZKMocks.h"
  20. #ifdef THREADED
  21. #include "PthreadMocks.h"
  22. #endif
  23. using namespace std;
  24. class Zookeeper_close : public CPPUNIT_NS::TestFixture
  25. {
  26. CPPUNIT_TEST_SUITE(Zookeeper_close);
  27. #ifdef THREADED
  28. CPPUNIT_TEST(testIOThreadStoppedOnExpire);
  29. #endif
  30. CPPUNIT_TEST(testCloseUnconnected);
  31. CPPUNIT_TEST(testCloseUnconnected1);
  32. CPPUNIT_TEST(testCloseConnected1);
  33. CPPUNIT_TEST(testCloseFromWatcher1);
  34. CPPUNIT_TEST_SUITE_END();
  35. zhandle_t *zh;
  36. static void watcher(zhandle_t *, int, int, const char *,void*){}
  37. FILE *logfile;
  38. public:
  39. Zookeeper_close() {
  40. logfile = openlogfile("Zookeeper_close");
  41. }
  42. ~Zookeeper_close() {
  43. if (logfile) {
  44. fflush(logfile);
  45. fclose(logfile);
  46. logfile = 0;
  47. }
  48. }
  49. void setUp()
  50. {
  51. zoo_set_log_stream(logfile);
  52. zoo_deterministic_conn_order(0);
  53. zh=0;
  54. }
  55. void tearDown()
  56. {
  57. zookeeper_close(zh);
  58. }
  59. class CloseOnSessionExpired: public WatcherAction{
  60. public:
  61. CloseOnSessionExpired(bool callClose=true):
  62. callClose_(callClose),rc(ZOK){}
  63. virtual void onSessionExpired(zhandle_t* zh){
  64. memcpy(&lzh,zh,sizeof(lzh));
  65. if(callClose_)
  66. rc=zookeeper_close(zh);
  67. }
  68. zhandle_t lzh;
  69. bool callClose_;
  70. int rc;
  71. };
  72. #ifndef THREADED
  73. void testCloseUnconnected()
  74. {
  75. zh=zookeeper_init("localhost:2121",watcher,10000,0,0,0);
  76. CPPUNIT_ASSERT(zh!=0);
  77. // do not actually free the memory while in zookeeper_close()
  78. Mock_free_noop freeMock;
  79. // make a copy of zhandle before close() overwrites some of
  80. // it members with NULLs
  81. zhandle_t lzh;
  82. memcpy(&lzh,zh,sizeof(lzh));
  83. int rc=zookeeper_close(zh);
  84. zhandle_t* savezh=zh; zh=0;
  85. freeMock.disable(); // disable mock's fake free()- use libc's free() instead
  86. // verify that zookeeper_close has done its job
  87. CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
  88. // memory
  89. CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(savezh));
  90. CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(lzh.hostname));
  91. CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(lzh.addrs.data));
  92. // This cannot be maintained properly CPPUNIT_ASSERT_EQUAL(9,freeMock.callCounter);
  93. }
  94. void testCloseUnconnected1()
  95. {
  96. zh=zookeeper_init("localhost:2121",watcher,10000,0,0,0);
  97. CPPUNIT_ASSERT(zh!=0);
  98. // simulate connected state
  99. zh->fd->sock=ZookeeperServer::FD;
  100. zh->state=ZOO_CONNECTED_STATE;
  101. Mock_flush_send_queue zkMock;
  102. // do not actually free the memory while in zookeeper_close()
  103. Mock_free_noop freeMock;
  104. // make a copy of zhandle before close() overwrites some of
  105. // it members with NULLs
  106. zhandle_t lzh;
  107. memcpy(&lzh,zh,sizeof(lzh));
  108. int rc=zookeeper_close(zh);
  109. zhandle_t* savezh=zh; zh=0;
  110. freeMock.disable(); // disable mock's fake free()- use libc's free() instead
  111. // verify that zookeeper_close has done its job
  112. CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
  113. // memory
  114. CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(savezh));
  115. CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(lzh.hostname));
  116. CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(lzh.addrs.data));
  117. // the close request sent?
  118. CPPUNIT_ASSERT_EQUAL(1,zkMock.counter);
  119. }
  120. void testCloseConnected1()
  121. {
  122. ZookeeperServer zkServer;
  123. // poll() will called from zookeeper_close()
  124. Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
  125. zh=zookeeper_init("localhost:2121",watcher,10000,TEST_CLIENT_ID,0,0);
  126. CPPUNIT_ASSERT(zh!=0);
  127. CPPUNIT_ASSERT_EQUAL(ZOO_NOTCONNECTED_STATE, zoo_state(zh));
  128. Mock_gettimeofday timeMock;
  129. int fd=0;
  130. int interest=0;
  131. timeval tv;
  132. int rc=zookeeper_interest(zh,&fd,&interest,&tv);
  133. CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
  134. CPPUNIT_ASSERT_EQUAL(ZOO_CONNECTING_STATE,zoo_state(zh));
  135. CPPUNIT_ASSERT_EQUAL(ZOOKEEPER_READ|ZOOKEEPER_WRITE,interest);
  136. rc=zookeeper_process(zh,interest);
  137. CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
  138. CPPUNIT_ASSERT_EQUAL(ZOO_ASSOCIATING_STATE,zoo_state(zh));
  139. rc=zookeeper_interest(zh,&fd,&interest,&tv);
  140. CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
  141. rc=zookeeper_process(zh,interest);
  142. CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
  143. CPPUNIT_ASSERT_EQUAL(ZOO_CONNECTED_STATE,zoo_state(zh));
  144. // do not actually free the memory while in zookeeper_close()
  145. Mock_free_noop freeMock;
  146. // make a copy of zhandle before close() overwrites some of
  147. // it members with NULLs
  148. zhandle_t lzh;
  149. memcpy(&lzh,zh,sizeof(lzh));
  150. zookeeper_close(zh);
  151. zhandle_t* savezh=zh; zh=0;
  152. freeMock.disable(); // disable mock's fake free()- use libc's free() instead
  153. // memory
  154. CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(savezh));
  155. CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(lzh.hostname));
  156. CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(lzh.addrs.data));
  157. // the close request sent?
  158. CPPUNIT_ASSERT_EQUAL(1,(int)zkServer.closeSent);
  159. }
  160. void testCloseFromWatcher1()
  161. {
  162. Mock_gettimeofday timeMock;
  163. ZookeeperServer zkServer;
  164. // make the server return a non-matching session id
  165. zkServer.returnSessionExpired();
  166. // poll() will called from zookeeper_close()
  167. Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
  168. CloseOnSessionExpired closeAction;
  169. zh=zookeeper_init("localhost:2121",activeWatcher,10000,
  170. TEST_CLIENT_ID,&closeAction,0);
  171. CPPUNIT_ASSERT(zh!=0);
  172. int fd=0;
  173. int interest=0;
  174. timeval tv;
  175. // initiate connection
  176. int rc=zookeeper_interest(zh,&fd,&interest,&tv);
  177. CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
  178. CPPUNIT_ASSERT_EQUAL(ZOO_CONNECTING_STATE,zoo_state(zh));
  179. CPPUNIT_ASSERT_EQUAL(ZOOKEEPER_READ|ZOOKEEPER_WRITE,interest);
  180. rc=zookeeper_process(zh,interest);
  181. // make sure the handshake in progress
  182. CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
  183. CPPUNIT_ASSERT_EQUAL(ZOO_ASSOCIATING_STATE,zoo_state(zh));
  184. rc=zookeeper_interest(zh,&fd,&interest,&tv);
  185. CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
  186. // do not actually free the memory while in zookeeper_close()
  187. Mock_free_noop freeMock;
  188. // should call the watcher with ZOO_EXPIRED_SESSION_STATE state
  189. rc=zookeeper_process(zh,interest);
  190. zhandle_t* savezh=zh; zh=0;
  191. freeMock.disable(); // disable mock's fake free()- use libc's free() instead
  192. CPPUNIT_ASSERT_EQUAL(ZOO_EXPIRED_SESSION_STATE,zoo_state(savezh));
  193. // memory
  194. CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(savezh));
  195. CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(closeAction.lzh.hostname));
  196. CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(closeAction.lzh.addrs.data));
  197. // make sure the close request NOT sent
  198. CPPUNIT_ASSERT_EQUAL(0,(int)zkServer.closeSent);
  199. }
  200. #else
  201. void testCloseUnconnected()
  202. {
  203. // disable threading
  204. MockPthreadZKNull pthreadMock;
  205. zh=zookeeper_init("localhost:2121",watcher,10000,0,0,0);
  206. CPPUNIT_ASSERT(zh!=0);
  207. adaptor_threads* adaptor=(adaptor_threads*)zh->adaptor_priv;
  208. CPPUNIT_ASSERT(adaptor!=0);
  209. // do not actually free the memory while in zookeeper_close()
  210. Mock_free_noop freeMock;
  211. // make a copy of zhandle before close() overwrites some of
  212. // it members with NULLs
  213. zhandle_t lzh;
  214. memcpy(&lzh,zh,sizeof(lzh));
  215. int rc=zookeeper_close(zh);
  216. zhandle_t* savezh=zh; zh=0;
  217. // we're done, disable mock's fake free(), use libc's free() instead
  218. freeMock.disable();
  219. // verify that zookeeper_close has done its job
  220. CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
  221. // memory
  222. CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(savezh));
  223. CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(lzh.hostname));
  224. CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(lzh.addrs.data));
  225. CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(adaptor));
  226. // Cannot be maintained accurately: CPPUNIT_ASSERT_EQUAL(10,freeMock.callCounter);
  227. // threads
  228. CPPUNIT_ASSERT_EQUAL(1,MockPthreadsNull::getDestroyCounter(adaptor->io));
  229. CPPUNIT_ASSERT_EQUAL(1,MockPthreadsNull::getDestroyCounter(adaptor->completion));
  230. // mutexes
  231. CPPUNIT_ASSERT_EQUAL(1,MockPthreadsNull::getDestroyCounter(&savezh->to_process.lock));
  232. CPPUNIT_ASSERT_EQUAL(0,MockPthreadsNull::getInvalidAccessCounter(&savezh->to_process.lock));
  233. CPPUNIT_ASSERT_EQUAL(1,MockPthreadsNull::getDestroyCounter(&savezh->to_send.lock));
  234. CPPUNIT_ASSERT_EQUAL(0,MockPthreadsNull::getInvalidAccessCounter(&savezh->to_send.lock));
  235. CPPUNIT_ASSERT_EQUAL(1,MockPthreadsNull::getDestroyCounter(&savezh->sent_requests.lock));
  236. CPPUNIT_ASSERT_EQUAL(0,MockPthreadsNull::getInvalidAccessCounter(&savezh->sent_requests.lock));
  237. CPPUNIT_ASSERT_EQUAL(1,MockPthreadsNull::getDestroyCounter(&savezh->completions_to_process.lock));
  238. CPPUNIT_ASSERT_EQUAL(0,MockPthreadsNull::getInvalidAccessCounter(&savezh->completions_to_process.lock));
  239. // conditionals
  240. CPPUNIT_ASSERT_EQUAL(1,MockPthreadsNull::getDestroyCounter(&savezh->sent_requests.cond));
  241. CPPUNIT_ASSERT_EQUAL(0,MockPthreadsNull::getInvalidAccessCounter(&savezh->sent_requests.cond));
  242. CPPUNIT_ASSERT_EQUAL(1,MockPthreadsNull::getDestroyCounter(&savezh->completions_to_process.cond));
  243. CPPUNIT_ASSERT_EQUAL(0,MockPthreadsNull::getInvalidAccessCounter(&savezh->completions_to_process.cond));
  244. }
  245. void testCloseUnconnected1()
  246. {
  247. for(int i=0; i<100;i++){
  248. zh=zookeeper_init("localhost:2121",watcher,10000,0,0,0);
  249. CPPUNIT_ASSERT(zh!=0);
  250. adaptor_threads* adaptor=(adaptor_threads*)zh->adaptor_priv;
  251. CPPUNIT_ASSERT(adaptor!=0);
  252. int rc=zookeeper_close(zh);
  253. zh=0;
  254. CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
  255. }
  256. }
  257. void testCloseConnected1()
  258. {
  259. // frozen time -- no timeouts and no pings
  260. Mock_gettimeofday timeMock;
  261. for(int i=0;i<100;i++){
  262. ZookeeperServer zkServer;
  263. Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
  264. // use a checked version of pthread calls
  265. CheckedPthread threadMock;
  266. // do not actually free the memory while in zookeeper_close()
  267. Mock_free_noop freeMock;
  268. zh=zookeeper_init("localhost:2121",watcher,10000,TEST_CLIENT_ID,0,0);
  269. CPPUNIT_ASSERT(zh!=0);
  270. // make sure the client has connected
  271. CPPUNIT_ASSERT(ensureCondition(ClientConnected(zh),1000)<1000);
  272. // make a copy of zhandle before close() overwrites some of
  273. // its members with NULLs
  274. zhandle_t lzh;
  275. memcpy(&lzh,zh,sizeof(lzh));
  276. int rc=zookeeper_close(zh);
  277. zhandle_t* savezh=zh; zh=0;
  278. // we're done, disable mock's fake free(), use libc's free() instead
  279. freeMock.disable();
  280. CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
  281. adaptor_threads* adaptor=(adaptor_threads*)lzh.adaptor_priv;
  282. // memory
  283. CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(savezh));
  284. CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(lzh.hostname));
  285. CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(lzh.addrs.data));
  286. CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(adaptor));
  287. // threads
  288. CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(adaptor->io));
  289. CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(adaptor->completion));
  290. // mutexes
  291. CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&savezh->to_process.lock));
  292. CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&savezh->to_process.lock));
  293. CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&savezh->to_send.lock));
  294. CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&savezh->to_send.lock));
  295. CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&savezh->sent_requests.lock));
  296. CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&savezh->sent_requests.lock));
  297. CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&savezh->completions_to_process.lock));
  298. CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&savezh->completions_to_process.lock));
  299. // conditionals
  300. CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&savezh->sent_requests.cond));
  301. CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&savezh->sent_requests.cond));
  302. CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&savezh->completions_to_process.cond));
  303. CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&savezh->completions_to_process.cond));
  304. }
  305. }
  306. struct PointerFreed{
  307. PointerFreed(Mock_free_noop& freeMock,void* ptr):
  308. freeMock_(freeMock),ptr_(ptr){}
  309. bool operator()() const{return freeMock_.isFreed(ptr_); }
  310. Mock_free_noop& freeMock_;
  311. void* ptr_;
  312. };
  313. // test if zookeeper_close may be called from a watcher callback on
  314. // SESSION_EXPIRED event
  315. void testCloseFromWatcher1()
  316. {
  317. // frozen time -- no timeouts and no pings
  318. Mock_gettimeofday timeMock;
  319. for(int i=0;i<100;i++){
  320. ZookeeperServer zkServer;
  321. // make the server return a non-matching session id
  322. zkServer.returnSessionExpired();
  323. Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
  324. // use a checked version of pthread calls
  325. CheckedPthread threadMock;
  326. // do not actually free the memory while in zookeeper_close()
  327. Mock_free_noop freeMock;
  328. CloseOnSessionExpired closeAction;
  329. zh=zookeeper_init("localhost:2121",activeWatcher,10000,
  330. TEST_CLIENT_ID,&closeAction,0);
  331. CPPUNIT_ASSERT(zh!=0);
  332. // we rely on the fact that zh is freed the last right before
  333. // zookeeper_close() returns...
  334. CPPUNIT_ASSERT(ensureCondition(PointerFreed(freeMock,zh),1000)<1000);
  335. zhandle_t* lzh=zh;
  336. zh=0;
  337. // we're done, disable mock's fake free(), use libc's free() instead
  338. freeMock.disable();
  339. CPPUNIT_ASSERT_EQUAL((int)ZOK,closeAction.rc);
  340. adaptor_threads* adaptor=(adaptor_threads*)closeAction.lzh.adaptor_priv;
  341. // memory
  342. CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(lzh));
  343. CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(closeAction.lzh.hostname));
  344. CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(closeAction.lzh.addrs.data));
  345. CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(adaptor));
  346. // threads
  347. CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(adaptor->io));
  348. CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(adaptor->completion));
  349. // mutexes
  350. CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&lzh->to_process.lock));
  351. CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&lzh->to_process.lock));
  352. CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&lzh->to_send.lock));
  353. CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&lzh->to_send.lock));
  354. CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&lzh->sent_requests.lock));
  355. CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&lzh->sent_requests.lock));
  356. CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&lzh->completions_to_process.lock));
  357. CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&lzh->completions_to_process.lock));
  358. // conditionals
  359. CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&lzh->sent_requests.cond));
  360. CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&lzh->sent_requests.cond));
  361. CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&lzh->completions_to_process.cond));
  362. CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&lzh->completions_to_process.cond));
  363. }
  364. }
  365. void testIOThreadStoppedOnExpire()
  366. {
  367. // frozen time -- no timeouts and no pings
  368. Mock_gettimeofday timeMock;
  369. for(int i=0;i<100;i++){
  370. ZookeeperServer zkServer;
  371. // make the server return a non-matching session id
  372. zkServer.returnSessionExpired();
  373. Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
  374. // use a checked version of pthread calls
  375. CheckedPthread threadMock;
  376. // do not call zookeeper_close() from the watcher
  377. CloseOnSessionExpired closeAction(false);
  378. zh=zookeeper_init("localhost:2121",activeWatcher,10000,
  379. &testClientId,&closeAction,0);
  380. // this is to ensure that if any assert fires, zookeeper_close()
  381. // will still be called while all the mocks are in the scope!
  382. CloseFinally guard(&zh);
  383. CPPUNIT_ASSERT(zh!=0);
  384. CPPUNIT_ASSERT(ensureCondition(SessionExpired(zh),1000)<1000);
  385. CPPUNIT_ASSERT(ensureCondition(IOThreadStopped(zh),1000)<1000);
  386. // make sure the watcher has been processed
  387. CPPUNIT_ASSERT(ensureCondition(closeAction.isWatcherTriggered(),1000)<1000);
  388. // make sure the threads have not been destroyed yet
  389. adaptor_threads* adaptor=(adaptor_threads*)zh->adaptor_priv;
  390. CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getDestroyCounter(adaptor->io));
  391. CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getDestroyCounter(adaptor->completion));
  392. // about to call zookeeper_close() -- no longer need the guard
  393. guard.disarm();
  394. // do not actually free the memory while in zookeeper_close()
  395. Mock_free_noop freeMock;
  396. zookeeper_close(zh);
  397. zhandle_t* lzh=zh; zh=0;
  398. // we're done, disable mock's fake free(), use libc's free() instead
  399. freeMock.disable();
  400. // memory
  401. CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(lzh));
  402. CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(closeAction.lzh.hostname));
  403. CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(closeAction.lzh.addrs.data));
  404. CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(adaptor));
  405. // threads
  406. CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(adaptor->io));
  407. CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(adaptor->completion));
  408. // mutexes
  409. CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&lzh->to_process.lock));
  410. CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&lzh->to_process.lock));
  411. CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&lzh->to_send.lock));
  412. CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&lzh->to_send.lock));
  413. CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&lzh->sent_requests.lock));
  414. CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&lzh->sent_requests.lock));
  415. CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&lzh->completions_to_process.lock));
  416. CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&lzh->completions_to_process.lock));
  417. // conditionals
  418. CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&lzh->sent_requests.cond));
  419. CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&lzh->sent_requests.cond));
  420. CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&lzh->completions_to_process.cond));
  421. CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&lzh->completions_to_process.cond));
  422. }
  423. }
  424. #endif
  425. };
  426. CPPUNIT_TEST_SUITE_REGISTRATION(Zookeeper_close);