LibCMocks.h 11 KB

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