TestZookeeperInit.cc 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. /*
  2. * Copyright 2008, Yahoo! Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include <cppunit/extensions/HelperMacros.h>
  17. #include <sys/types.h>
  18. #include <netinet/in.h>
  19. #include <errno.h>
  20. #include "Util.h"
  21. #include "LibCMocks.h"
  22. #include "ZKMocks.h"
  23. #ifdef THREADED
  24. #include "PthreadMocks.h"
  25. #else
  26. class MockPthreadsNull;
  27. #endif
  28. using namespace std;
  29. class Zookeeper_init : public CPPUNIT_NS::TestFixture
  30. {
  31. CPPUNIT_TEST_SUITE(Zookeeper_init);
  32. CPPUNIT_TEST(testBasic);
  33. CPPUNIT_TEST(testAddressResolution);
  34. CPPUNIT_TEST(testMultipleAddressResolution);
  35. CPPUNIT_TEST(testInvalidAddressString1);
  36. CPPUNIT_TEST(testInvalidAddressString2);
  37. CPPUNIT_TEST(testNonexistentHost);
  38. CPPUNIT_TEST(testOutOfMemory_init);
  39. CPPUNIT_TEST(testOutOfMemory_getaddrs1);
  40. CPPUNIT_TEST(testOutOfMemory_getaddrs2);
  41. CPPUNIT_TEST(testPermuteAddrsList);
  42. CPPUNIT_TEST_SUITE_END();
  43. zhandle_t *zh;
  44. MockPthreadsNull* pthreadMock;
  45. static void watcher(zhandle_t *, int , int , const char *){}
  46. public:
  47. Zookeeper_init():zh(0),pthreadMock(0){}
  48. void setUp()
  49. {
  50. zoo_set_debug_level((ZooLogLevel)0); // disable logging
  51. zoo_deterministic_conn_order(0);
  52. #ifdef THREADED
  53. // disable threading
  54. pthreadMock=new MockPthreadZKNull;
  55. #endif
  56. zh=0;
  57. }
  58. void tearDown()
  59. {
  60. zookeeper_close(zh);
  61. #ifdef THREADED
  62. delete pthreadMock;
  63. #endif
  64. }
  65. void testBasic()
  66. {
  67. const string EXPECTED_HOST("localhost:2121");
  68. const int EXPECTED_ADDRS_COUNT =1;
  69. const int EXPECTED_RECV_TIMEOUT=10000;
  70. clientid_t cid;
  71. memset(&cid,0xFE,sizeof(cid));
  72. zh=zookeeper_init(EXPECTED_HOST.c_str(),watcher,EXPECTED_RECV_TIMEOUT,
  73. &cid,(void*)1,0);
  74. CPPUNIT_ASSERT(zh!=0);
  75. CPPUNIT_ASSERT(zh->fd == -1);
  76. CPPUNIT_ASSERT(zh->hostname!=0);
  77. CPPUNIT_ASSERT_EQUAL(EXPECTED_ADDRS_COUNT,zh->addrs_count);
  78. CPPUNIT_ASSERT_EQUAL(EXPECTED_HOST,string(zh->hostname));
  79. CPPUNIT_ASSERT(zh->state == 0);
  80. CPPUNIT_ASSERT(zh->context == (void*)1);
  81. CPPUNIT_ASSERT_EQUAL(EXPECTED_RECV_TIMEOUT,zh->recv_timeout);
  82. CPPUNIT_ASSERT(zh->watcher == watcher);
  83. CPPUNIT_ASSERT(zh->connect_index==0);
  84. CPPUNIT_ASSERT(zh->primer_buffer.buffer==zh->primer_storage_buffer);
  85. CPPUNIT_ASSERT(zh->primer_buffer.curr_offset ==0);
  86. CPPUNIT_ASSERT(zh->primer_buffer.len == sizeof(zh->primer_storage_buffer));
  87. CPPUNIT_ASSERT(zh->primer_buffer.next == 0);
  88. CPPUNIT_ASSERT(zh->last_zxid ==0);
  89. CPPUNIT_ASSERT(memcmp(&zh->client_id,&cid,sizeof(cid))==0);
  90. #ifdef THREADED
  91. // thread specific checks
  92. adaptor_threads* adaptor=(adaptor_threads*)zh->adaptor_priv;
  93. CPPUNIT_ASSERT(adaptor!=0);
  94. CPPUNIT_ASSERT(pthreadMock->pthread_createCounter==2);
  95. CPPUNIT_ASSERT(MockPthreadsNull::isInitialized(adaptor->io));
  96. CPPUNIT_ASSERT(MockPthreadsNull::isInitialized(adaptor->completion));
  97. CPPUNIT_ASSERT(MockPthreadsNull::isInitialized(&zh->to_process.lock));
  98. CPPUNIT_ASSERT(MockPthreadsNull::isInitialized(&zh->to_send.lock));
  99. CPPUNIT_ASSERT(MockPthreadsNull::isInitialized(&zh->sent_requests.lock));
  100. CPPUNIT_ASSERT(MockPthreadsNull::isInitialized(&zh->completions_to_process.lock));
  101. CPPUNIT_ASSERT(MockPthreadsNull::isInitialized(&zh->sent_requests.cond));
  102. CPPUNIT_ASSERT(MockPthreadsNull::isInitialized(&zh->completions_to_process.cond));
  103. #endif
  104. }
  105. void testAddressResolution()
  106. {
  107. const char EXPECTED_IPS[][4]={{127,0,0,1},{127,0,0,2},{127,0,0,3}};
  108. const int EXPECTED_ADDRS_COUNT =COUNTOF(EXPECTED_IPS);
  109. Mock_gethostbyname mock;
  110. mock.addHostEntry("somehostname").addAddress(EXPECTED_IPS[0]).
  111. addAddress(EXPECTED_IPS[1]).addAddress(EXPECTED_IPS[2]);
  112. zoo_deterministic_conn_order(1);
  113. zh=zookeeper_init("host:2121",0,10000,0,0,0);
  114. CPPUNIT_ASSERT(zh!=0);
  115. CPPUNIT_ASSERT_EQUAL(EXPECTED_ADDRS_COUNT,zh->addrs_count);
  116. for(int i=0;i<zh->addrs_count;i++){
  117. sockaddr_in* addr=(struct sockaddr_in*)&zh->addrs[i];
  118. CPPUNIT_ASSERT(memcmp(EXPECTED_IPS[i],&addr->sin_addr,sizeof(addr->sin_addr))==0);
  119. CPPUNIT_ASSERT_EQUAL(2121,(int)ntohs(addr->sin_port));
  120. }
  121. }
  122. void testMultipleAddressResolution()
  123. {
  124. const string EXPECTED_HOST("host1:2121,host2:3434");
  125. const char EXPECTED_IPS[][4]={{127,0,0,1},{127,0,0,2},{127,0,0,3},
  126. {126,1,1,1},{126,2,2,2}};
  127. const int EXPECTED_ADDRS_COUNT =COUNTOF(EXPECTED_IPS);
  128. Mock_gethostbyname mock;
  129. mock.addHostEntry("somehost1").addAddress(EXPECTED_IPS[0]).
  130. addAddress(EXPECTED_IPS[1]).addAddress(EXPECTED_IPS[2]);
  131. mock.addHostEntry("somehost2").addAddress(EXPECTED_IPS[3]).
  132. addAddress(EXPECTED_IPS[4]);
  133. zoo_deterministic_conn_order(1);
  134. zh=zookeeper_init(EXPECTED_HOST.c_str(),0,1000,0,0,0);
  135. CPPUNIT_ASSERT(zh!=0);
  136. CPPUNIT_ASSERT_EQUAL(EXPECTED_ADDRS_COUNT,zh->addrs_count);
  137. for(int i=0;i<zh->addrs_count;i++){
  138. sockaddr_in* addr=(struct sockaddr_in*)&zh->addrs[i];
  139. CPPUNIT_ASSERT(memcmp(EXPECTED_IPS[i],&addr->sin_addr,sizeof(addr->sin_addr))==0);
  140. if(i<3)
  141. CPPUNIT_ASSERT_EQUAL(2121,(int)ntohs(addr->sin_port));
  142. else
  143. CPPUNIT_ASSERT_EQUAL(3434,(int)ntohs(addr->sin_port));
  144. }
  145. }
  146. void testInvalidAddressString1()
  147. {
  148. const string INVALID_HOST("host1");
  149. zh=zookeeper_init(INVALID_HOST.c_str(),0,0,0,0,0);
  150. CPPUNIT_ASSERT(zh==0);
  151. CPPUNIT_ASSERT_EQUAL(EINVAL,errno);
  152. }
  153. void testInvalidAddressString2()
  154. {
  155. const string INVALID_HOST("host1:1111+host:123");
  156. zh=zookeeper_init(INVALID_HOST.c_str(),0,0,0,0,0);
  157. CPPUNIT_ASSERT(zh==0);
  158. CPPUNIT_ASSERT_EQUAL(EINVAL,errno);
  159. }
  160. void testNonexistentHost()
  161. {
  162. const string EXPECTED_HOST("host1:1111");
  163. MockFailed_gethostbyname mock;
  164. zh=zookeeper_init(EXPECTED_HOST.c_str(),0,0,0,0,0);
  165. CPPUNIT_ASSERT(zh==0);
  166. CPPUNIT_ASSERT_EQUAL(EINVAL,errno);
  167. CPPUNIT_ASSERT_EQUAL(HOST_NOT_FOUND,h_errno);
  168. }
  169. void testOutOfMemory_init()
  170. {
  171. Mock_calloc mock;
  172. mock.callsBeforeFailure=0; // fail first calloc in init()
  173. zh=zookeeper_init("ahost:123",watcher,10000,0,0,0);
  174. CPPUNIT_ASSERT(zh==0);
  175. CPPUNIT_ASSERT_EQUAL(ENOMEM,errno);
  176. }
  177. void testOutOfMemory_getaddrs1()
  178. {
  179. Mock_realloc reallocMock;
  180. reallocMock.callsBeforeFailure=0; // fail on first call to realloc
  181. Mock_gethostbyname gethostbynameMock;
  182. gethostbynameMock.addHostEntry("ahost").addAddress("\1\1\1\1");
  183. zh=zookeeper_init("ahost:123",0,0,0,0,0);
  184. CPPUNIT_ASSERT(zh==0);
  185. CPPUNIT_ASSERT_EQUAL(ENOMEM,errno);
  186. }
  187. void testOutOfMemory_getaddrs2()
  188. {
  189. const char ADDR[]="\1\1\1\1";
  190. Mock_realloc reallocMock;
  191. reallocMock.callsBeforeFailure=1; // fail on the second call to realloc
  192. Mock_gethostbyname gethostbynameMock;
  193. // need >16 IPs to get realloc called the second time
  194. gethostbynameMock.addHostEntry("ahost").
  195. addAddress(ADDR).addAddress(ADDR).addAddress(ADDR).addAddress(ADDR).
  196. addAddress(ADDR).addAddress(ADDR).addAddress(ADDR).addAddress(ADDR).
  197. addAddress(ADDR).addAddress(ADDR).addAddress(ADDR).addAddress(ADDR).
  198. addAddress(ADDR).addAddress(ADDR).addAddress(ADDR).addAddress(ADDR).
  199. addAddress(ADDR);
  200. zh=zookeeper_init("ahost:123",0,0,0,0,0);
  201. CPPUNIT_ASSERT(zh==0);
  202. CPPUNIT_ASSERT_EQUAL(ENOMEM,errno);
  203. }
  204. void testPermuteAddrsList()
  205. {
  206. const char EXPECTED[][5]={"\0\0\0\0","\1\1\1\1","\2\2\2\2","\3\3\3\3"};
  207. const int EXPECTED_ADDR_COUNT=COUNTOF(EXPECTED);
  208. Mock_gethostbyname gethostbynameMock;
  209. gethostbynameMock.addHostEntry("ahost").
  210. addAddress(EXPECTED[0]).addAddress(EXPECTED[1]).
  211. addAddress(EXPECTED[2]).addAddress(EXPECTED[3]);
  212. const int RAND_SEQ[]={0,1,2,3,1,3,2,0,-1};
  213. const int RAND_SIZE=COUNTOF(RAND_SEQ);
  214. Mock_random randomMock;
  215. randomMock.randomReturns.assign(RAND_SEQ,RAND_SEQ+RAND_SIZE-1);
  216. zh=zookeeper_init("ahost:123",0,1000,0,0,0);
  217. CPPUNIT_ASSERT(zh!=0);
  218. CPPUNIT_ASSERT_EQUAL(EXPECTED_ADDR_COUNT,zh->addrs_count);
  219. const string EXPECTED_SEQ("3210");
  220. char ACTUAL_SEQ[EXPECTED_ADDR_COUNT+1]; ACTUAL_SEQ[EXPECTED_ADDR_COUNT]=0;
  221. for(int i=0;i<zh->addrs_count;i++){
  222. sockaddr_in* addr=(struct sockaddr_in*)&zh->addrs[i];
  223. // match the first byte of the EXPECTED and of the actual address
  224. ACTUAL_SEQ[i]=((char*)&addr->sin_addr)[0]+'0';
  225. }
  226. CPPUNIT_ASSERT_EQUAL(EXPECTED_SEQ,string(ACTUAL_SEQ));
  227. }
  228. };
  229. CPPUNIT_TEST_SUITE_REGISTRATION(Zookeeper_init);