LibCMocks.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  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. #ifndef LIBCMOCKS_H_
  17. #define LIBCMOCKS_H_
  18. #include <string>
  19. #include <vector>
  20. #include <deque>
  21. #include <errno.h>
  22. #include "MocksBase.h"
  23. #include "LibCSymTable.h"
  24. #include "ThreadingUtil.h"
  25. // *****************************************************************************
  26. // gethostbyname
  27. class Mock_gethostbyname: public Mock
  28. {
  29. public:
  30. struct HostEntry: public hostent {
  31. HostEntry(const char* hostName,short addrtype);
  32. ~HostEntry();
  33. HostEntry& addAlias(const char* alias);
  34. HostEntry& addAddress(const char* addr4);
  35. };
  36. Mock_gethostbyname():current(0){mock_=this;}
  37. virtual ~Mock_gethostbyname();
  38. HostEntry& addHostEntry(const char* hostName,short addrtype=AF_INET);
  39. virtual hostent* call(const char* name);
  40. typedef std::vector<HostEntry*> HostEntryCollection;
  41. HostEntryCollection gethostbynameReturns;
  42. int current;
  43. static Mock_gethostbyname* mock_;
  44. };
  45. class MockFailed_gethostbyname: public Mock_gethostbyname
  46. {
  47. public:
  48. MockFailed_gethostbyname():h_errnoReturn(HOST_NOT_FOUND) {}
  49. int h_errnoReturn;
  50. virtual hostent* call(const char* name) {
  51. h_errno=h_errnoReturn;
  52. return 0;
  53. }
  54. };
  55. // *****************************************************************************
  56. // calloc
  57. class Mock_calloc: public Mock
  58. {
  59. public:
  60. Mock_calloc():errnoOnFailure(ENOMEM),callsBeforeFailure(-1),counter(0) {
  61. mock_=this;
  62. }
  63. virtual ~Mock_calloc() {mock_=0;}
  64. int errnoOnFailure;
  65. int callsBeforeFailure;
  66. int counter;
  67. virtual void* call(size_t p1, size_t p2);
  68. static Mock_calloc* mock_;
  69. };
  70. // *****************************************************************************
  71. // realloc
  72. class Mock_realloc: public Mock
  73. {
  74. public:
  75. Mock_realloc():errnoOnFailure(ENOMEM),callsBeforeFailure(-1),counter(0) {
  76. mock_=this;
  77. }
  78. virtual ~Mock_realloc() {mock_=0;}
  79. int errnoOnFailure;
  80. int callsBeforeFailure;
  81. int counter;
  82. virtual void* call(void* p, size_t s);
  83. static Mock_realloc* mock_;
  84. };
  85. // *****************************************************************************
  86. // random
  87. class Mock_random: public Mock
  88. {
  89. public:
  90. Mock_random():currentIdx(0) {mock_=this;}
  91. virtual ~Mock_random() {mock_=0;}
  92. int currentIdx;
  93. std::vector<int> randomReturns;
  94. virtual int call();
  95. void setSeed(unsigned long){currentIdx=0;}
  96. static Mock_random* mock_;
  97. };
  98. // *****************************************************************************
  99. // no-op free; keeps track of all deallocation requests
  100. class Mock_free_noop: public Mock
  101. {
  102. Mutex mx;
  103. std::vector<void*> requested;
  104. public:
  105. Mock_free_noop():nested(0),callCounter(0){mock_=this;}
  106. virtual ~Mock_free_noop(){
  107. mock_=0;
  108. freeRequested();
  109. }
  110. int nested;
  111. int callCounter;
  112. virtual void call(void* p);
  113. void freeRequested();
  114. void disable(){mock_=0;}
  115. // returns number of times the pointer was freed
  116. int getFreeCount(void*);
  117. bool isFreed(void*);
  118. static Mock_free_noop* mock_;
  119. };
  120. // *****************************************************************************
  121. // socket and related system calls
  122. class Mock_socket: public Mock
  123. {
  124. public:
  125. static const int FD=63;
  126. Mock_socket():socketReturns(FD),closeReturns(0),getsocketoptReturns(0),
  127. optvalSO_ERROR(0),
  128. setsockoptReturns(0),connectReturns(0),connectErrno(0),
  129. sendErrno(0),recvErrno(0)
  130. {
  131. mock_=this;
  132. }
  133. virtual ~Mock_socket(){mock_=0;}
  134. int socketReturns;
  135. virtual int callSocket(int domain, int type, int protocol){
  136. return socketReturns;
  137. }
  138. int closeReturns;
  139. virtual int callClose(int fd){
  140. return closeReturns;
  141. }
  142. int getsocketoptReturns;
  143. int optvalSO_ERROR;
  144. virtual int callGet(int s,int level,int optname,void *optval,socklen_t *len){
  145. if(level==SOL_SOCKET && optname==SO_ERROR){
  146. setSO_ERROR(optval,*len);
  147. }
  148. return getsocketoptReturns;
  149. }
  150. virtual void setSO_ERROR(void *optval,socklen_t len){
  151. memcpy(optval,&optvalSO_ERROR,len);
  152. }
  153. int setsockoptReturns;
  154. virtual int callSet(int s,int level,int optname,const void *optval,socklen_t len){
  155. return setsockoptReturns;
  156. }
  157. int connectReturns;
  158. int connectErrno;
  159. virtual int callConnect(int s,const struct sockaddr *addr,socklen_t len){
  160. errno=connectErrno;
  161. return connectReturns;
  162. }
  163. virtual void notifyBufferSent(const std::string& buffer){}
  164. int sendErrno;
  165. std::string sendBuffer;
  166. virtual ssize_t callSend(int s,const void *buf,size_t len,int flags){
  167. if(sendErrno!=0){
  168. errno=sendErrno;
  169. return -1;
  170. }
  171. // first call to send() is always the length of the buffer to follow
  172. bool sendingLength=sendBuffer.size()==0;
  173. // overwrite the length bytes
  174. sendBuffer.assign((const char*)buf,len);
  175. if(!sendingLength){
  176. notifyBufferSent(sendBuffer);
  177. sendBuffer.erase();
  178. }
  179. return len;
  180. }
  181. int recvErrno;
  182. std::string recvReturnBuffer;
  183. virtual ssize_t callRecv(int s,void *buf,size_t len,int flags){
  184. if(recvErrno!=0){
  185. errno=recvErrno;
  186. return -1;
  187. }
  188. int k=std::min(len,recvReturnBuffer.length());
  189. if(k==0)
  190. return 0;
  191. memcpy(buf,recvReturnBuffer.data(),k);
  192. recvReturnBuffer.erase(0,k);
  193. return k;
  194. }
  195. virtual bool hasMoreRecv() const{
  196. return recvReturnBuffer.size()!=0;
  197. }
  198. static Mock_socket* mock_;
  199. };
  200. // *****************************************************************************
  201. // fcntl
  202. class Mock_fcntl: public Mock
  203. {
  204. public:
  205. Mock_fcntl():callReturns(0),trapFD(-1){mock_=this;}
  206. ~Mock_fcntl(){mock_=0;}
  207. int callReturns;
  208. int trapFD;
  209. virtual int call(int fd, int cmd, void* arg){
  210. if(trapFD==-1)
  211. return LIBC_SYMBOLS.fcntl(fd,cmd,arg);
  212. return callReturns;
  213. }
  214. static Mock_fcntl* mock_;
  215. };
  216. // *****************************************************************************
  217. // select
  218. class Mock_select: public Mock
  219. {
  220. public:
  221. Mock_select(Mock_socket* s,int fd):sock(s),
  222. callReturns(0),myFD(fd),timeout(50)
  223. {
  224. mock_=this;
  225. }
  226. ~Mock_select(){mock_=0;}
  227. Mock_socket* sock;
  228. int callReturns;
  229. int myFD;
  230. int timeout; //in millis
  231. virtual int call(int nfds,fd_set *rfds,fd_set *wfds,fd_set *efds,struct timeval *tv){
  232. bool isWritableRequested=(wfds && FD_ISSET(myFD,wfds));
  233. if(rfds) FD_CLR(myFD,rfds);
  234. if(wfds) FD_CLR(myFD,wfds);
  235. // this timeout is only to prevent a tight loop
  236. timeval myTimeout={0,0};
  237. if(!isWritableRequested && !isFDReadable()){
  238. myTimeout.tv_sec=timeout/1000;
  239. myTimeout.tv_usec=(timeout%1000)*1000;
  240. }
  241. LIBC_SYMBOLS.select(nfds,rfds,wfds,efds,&myTimeout);
  242. // myFD is always writable
  243. if(isWritableRequested) FD_SET(myFD,wfds);
  244. // myFD is only readable if the socket has anything to read
  245. if(isFDReadable() && rfds) FD_SET(myFD,rfds);
  246. return callReturns;
  247. }
  248. virtual bool isFDReadable() const {
  249. return sock->hasMoreRecv();
  250. }
  251. static Mock_select* mock_;
  252. };
  253. // *****************************************************************************
  254. // poll
  255. // the last element of the pollfd array is expected to be test FD
  256. class Mock_poll: public Mock
  257. {
  258. public:
  259. Mock_poll(Mock_socket* s,int fd):sock(s),
  260. callReturns(1),myFD(fd),timeout(50)
  261. {
  262. mock_=this;
  263. }
  264. ~Mock_poll(){mock_=0;}
  265. Mock_socket* sock;
  266. int callReturns;
  267. int myFD;
  268. int timeout; //in millis
  269. virtual int call(struct pollfd *fds, POLL_NFDS_TYPE nfds, int to) {
  270. pollfd* myPoll=0;
  271. if(fds[nfds-1].fd==myFD)
  272. myPoll=&fds[nfds-1];
  273. bool isWritableRequested=false;
  274. if(myPoll!=0){
  275. isWritableRequested=myPoll->events&POLLOUT;
  276. nfds--;
  277. }
  278. LIBC_SYMBOLS.poll(fds,nfds,(!isWritableRequested&&!isFDReadable())?timeout:0);
  279. if(myPoll!=0){
  280. // myFD is always writable if requested
  281. myPoll->revents=isWritableRequested?POLLOUT:0;
  282. // myFD is only readable if the socket has anything to read
  283. myPoll->revents|=isFDReadable()?POLLIN:0;
  284. }
  285. return callReturns;
  286. }
  287. virtual bool isFDReadable() const {
  288. return sock->hasMoreRecv();
  289. }
  290. static Mock_poll* mock_;
  291. };
  292. // *****************************************************************************
  293. // gettimeofday
  294. class Mock_gettimeofday: public Mock
  295. {
  296. public:
  297. Mock_gettimeofday(){
  298. LIBC_SYMBOLS.gettimeofday(&tv,0);
  299. mock_=this;
  300. }
  301. Mock_gettimeofday(const Mock_gettimeofday& other):tv(other.tv){}
  302. Mock_gettimeofday(int32_t sec,int32_t usec){
  303. tv.tv_sec=sec;
  304. tv.tv_usec=usec;
  305. }
  306. ~Mock_gettimeofday(){mock_=0;}
  307. timeval tv;
  308. virtual int call(struct timeval *tp, GETTIMEOFDAY_ARG2_TYPE tzp){
  309. *tp=tv;
  310. return 0;
  311. }
  312. operator timeval() const{
  313. return tv;
  314. }
  315. // advance secs
  316. virtual void tick(int howmuch=1){tv.tv_sec+=howmuch;}
  317. // advance milliseconds
  318. // can move the clock forward as well as backward by providing a negative
  319. // number
  320. virtual void millitick(int howmuch=1){
  321. int ms=tv.tv_usec/1000+howmuch;
  322. tv.tv_sec+=ms/1000;
  323. // going backward?
  324. if(ms<0){
  325. ms=1000-(-ms%1000); //wrap millis around
  326. }
  327. tv.tv_usec=(ms%1000)*1000;
  328. }
  329. virtual void tick(const timeval& howmuch){
  330. // add milliseconds (discarding microsecond portion)
  331. long ms=tv.tv_usec/1000+howmuch.tv_usec/1000;
  332. tv.tv_sec+=howmuch.tv_sec+ms/1000;
  333. tv.tv_usec=(ms%1000)*1000;
  334. }
  335. static Mock_gettimeofday* mock_;
  336. };
  337. // discard microseconds!
  338. inline bool operator==(const timeval& lhs, const timeval& rhs){
  339. return rhs.tv_sec==lhs.tv_sec && rhs.tv_usec/1000==lhs.tv_usec/1000;
  340. }
  341. // simplistic implementation: no normalization, assume lhs >= rhs,
  342. // discarding microseconds
  343. inline timeval operator-(const timeval& lhs, const timeval& rhs){
  344. timeval res;
  345. res.tv_sec=lhs.tv_sec-rhs.tv_sec;
  346. res.tv_usec=(lhs.tv_usec/1000-rhs.tv_usec/1000)*1000;
  347. if(res.tv_usec<0){
  348. res.tv_sec--;
  349. res.tv_usec=1000000+res.tv_usec%1000000; // wrap the millis around
  350. }
  351. return res;
  352. }
  353. inline int32_t toMilliseconds(const timeval& tv){
  354. return tv.tv_sec*1000+tv.tv_usec/1000;
  355. }
  356. #endif /*LIBCMOCKS_H_*/