123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408 |
- /**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #ifndef LIBCMOCKS_H_
- #define LIBCMOCKS_H_
- #include <string>
- #include <vector>
- #include <deque>
- #include <errno.h>
- #include <string.h>
- #include "MocksBase.h"
- #include "LibCSymTable.h"
- #include "ThreadingUtil.h"
- // *****************************************************************************
- // gethostbyname
- class Mock_gethostbyname: public Mock
- {
- public:
- struct HostEntry: public hostent {
- HostEntry(const char* hostName,short addrtype);
- ~HostEntry();
- HostEntry& addAlias(const char* alias);
- HostEntry& addAddress(const char* addr4);
- };
- Mock_gethostbyname():current(0){mock_=this;}
- virtual ~Mock_gethostbyname();
- HostEntry& addHostEntry(const char* hostName,short addrtype=AF_INET);
- virtual hostent* call(const char* name);
- typedef std::vector<HostEntry*> HostEntryCollection;
- HostEntryCollection gethostbynameReturns;
- int current;
- static Mock_gethostbyname* mock_;
- };
- class MockFailed_gethostbyname: public Mock_gethostbyname
- {
- public:
- MockFailed_gethostbyname():h_errnoReturn(HOST_NOT_FOUND) {}
- int h_errnoReturn;
- virtual hostent* call(const char* name) {
- h_errno=h_errnoReturn;
- return 0;
- }
- };
- // *****************************************************************************
- // calloc
- class Mock_calloc: public Mock
- {
- public:
- Mock_calloc():errnoOnFailure(ENOMEM),callsBeforeFailure(-1),counter(0) {
- mock_=this;
- }
- virtual ~Mock_calloc() {mock_=0;}
- int errnoOnFailure;
- int callsBeforeFailure;
- int counter;
- virtual void* call(size_t p1, size_t p2);
- static Mock_calloc* mock_;
- };
- // *****************************************************************************
- // realloc
- class Mock_realloc: public Mock
- {
- public:
- Mock_realloc():errnoOnFailure(ENOMEM),callsBeforeFailure(-1),counter(0) {
- mock_=this;
- }
- virtual ~Mock_realloc() {mock_=0;}
- int errnoOnFailure;
- int callsBeforeFailure;
- int counter;
- virtual void* call(void* p, size_t s);
- static Mock_realloc* mock_;
- };
- // *****************************************************************************
- // random
- class Mock_random: public Mock
- {
- public:
- Mock_random():currentIdx(0) {mock_=this;}
- virtual ~Mock_random() {mock_=0;}
- int currentIdx;
- std::vector<int> randomReturns;
- virtual int call();
- void setSeed(unsigned long){currentIdx=0;}
- static Mock_random* mock_;
- };
- // *****************************************************************************
- // no-op free; keeps track of all deallocation requests
- class Mock_free_noop: public Mock
- {
- Mutex mx;
- std::vector<void*> requested;
- public:
- Mock_free_noop():nested(0),callCounter(0){mock_=this;}
- virtual ~Mock_free_noop(){
- mock_=0;
- freeRequested();
- }
-
- int nested;
- int callCounter;
- virtual void call(void* p);
- void freeRequested();
- void disable(){mock_=0;}
- // returns number of times the pointer was freed
- int getFreeCount(void*);
- bool isFreed(void*);
-
- static Mock_free_noop* mock_;
- };
- // *****************************************************************************
- // socket and related system calls
- class Mock_socket: public Mock
- {
- public:
- static const int FD=63;
- Mock_socket():socketReturns(FD),closeReturns(0),getsocketoptReturns(0),
- optvalSO_ERROR(0),
- setsockoptReturns(0),connectReturns(0),connectErrno(0),
- sendErrno(0),recvErrno(0)
- {
- mock_=this;
- }
- virtual ~Mock_socket(){mock_=0;}
- int socketReturns;
- virtual int callSocket(int domain, int type, int protocol){
- return socketReturns;
- }
- int closeReturns;
- virtual int callClose(int fd){
- return closeReturns;
- }
- int getsocketoptReturns;
- int optvalSO_ERROR;
- virtual int callGet(int s,int level,int optname,void *optval,socklen_t *len){
- if(level==SOL_SOCKET && optname==SO_ERROR){
- setSO_ERROR(optval,*len);
- }
- return getsocketoptReturns;
- }
- virtual void setSO_ERROR(void *optval,socklen_t len){
- memcpy(optval,&optvalSO_ERROR,len);
- }
-
- int setsockoptReturns;
- virtual int callSet(int s,int level,int optname,const void *optval,socklen_t len){
- return setsockoptReturns;
- }
- int connectReturns;
- int connectErrno;
- virtual int callConnect(int s,const struct sockaddr *addr,socklen_t len){
- errno=connectErrno;
- return connectReturns;
- }
-
- virtual void notifyBufferSent(const std::string& buffer){}
-
- int sendErrno;
- std::string sendBuffer;
- virtual ssize_t callSend(int s,const void *buf,size_t len,int flags){
- if(sendErrno!=0){
- errno=sendErrno;
- return -1;
- }
- // first call to send() is always the length of the buffer to follow
- bool sendingLength=sendBuffer.size()==0;
- // overwrite the length bytes
- sendBuffer.assign((const char*)buf,len);
- if(!sendingLength){
- notifyBufferSent(sendBuffer);
- sendBuffer.erase();
- }
- return len;
- }
- int recvErrno;
- std::string recvReturnBuffer;
- virtual ssize_t callRecv(int s,void *buf,size_t len,int flags){
- if(recvErrno!=0){
- errno=recvErrno;
- return -1;
- }
- int k=std::min(len,recvReturnBuffer.length());
- if(k==0)
- return 0;
- memcpy(buf,recvReturnBuffer.data(),k);
- recvReturnBuffer.erase(0,k);
- return k;
- }
- virtual bool hasMoreRecv() const{
- return recvReturnBuffer.size()!=0;
- }
- static Mock_socket* mock_;
- };
- // *****************************************************************************
- // fcntl
- class Mock_fcntl: public Mock
- {
- public:
- Mock_fcntl():callReturns(0),trapFD(-1){mock_=this;}
- ~Mock_fcntl(){mock_=0;}
-
- int callReturns;
- int trapFD;
- virtual int call(int fd, int cmd, void* arg){
- if(trapFD==-1)
- return LIBC_SYMBOLS.fcntl(fd,cmd,arg);
- return callReturns;
- }
- static Mock_fcntl* mock_;
- };
- // *****************************************************************************
- // select
- class Mock_select: public Mock
- {
- public:
- Mock_select(Mock_socket* s,int fd):sock(s),
- callReturns(0),myFD(fd),timeout(50)
- {
- mock_=this;
- }
- ~Mock_select(){mock_=0;}
-
- Mock_socket* sock;
- int callReturns;
- int myFD;
- int timeout; //in millis
- virtual int call(int nfds,fd_set *rfds,fd_set *wfds,fd_set *efds,struct timeval *tv){
- bool isWritableRequested=(wfds && FD_ISSET(myFD,wfds));
- if(rfds) FD_CLR(myFD,rfds);
- if(wfds) FD_CLR(myFD,wfds);
- // this timeout is only to prevent a tight loop
- timeval myTimeout={0,0};
- if(!isWritableRequested && !isFDReadable()){
- myTimeout.tv_sec=timeout/1000;
- myTimeout.tv_usec=(timeout%1000)*1000;
- }
- LIBC_SYMBOLS.select(nfds,rfds,wfds,efds,&myTimeout);
- // myFD is always writable
- if(isWritableRequested) FD_SET(myFD,wfds);
- // myFD is only readable if the socket has anything to read
- if(isFDReadable() && rfds) FD_SET(myFD,rfds);
- return callReturns;
- }
- virtual bool isFDReadable() const {
- return sock->hasMoreRecv();
- }
-
- static Mock_select* mock_;
- };
- // *****************************************************************************
- // poll
- // the last element of the pollfd array is expected to be test FD
- class Mock_poll: public Mock
- {
- public:
- Mock_poll(Mock_socket* s,int fd):sock(s),
- callReturns(1),myFD(fd),timeout(50)
- {
- mock_=this;
- }
- ~Mock_poll(){mock_=0;}
-
- Mock_socket* sock;
- int callReturns;
- int myFD;
- int timeout; //in millis
- virtual int call(struct pollfd *fds, POLL_NFDS_TYPE nfds, int to) {
- pollfd* myPoll=0;
- if(fds[nfds-1].fd==myFD)
- myPoll=&fds[nfds-1];
- bool isWritableRequested=false;
- if(myPoll!=0){
- isWritableRequested=myPoll->events&POLLOUT;
- nfds--;
- }
- LIBC_SYMBOLS.poll(fds,nfds,(!isWritableRequested&&!isFDReadable())?timeout:0);
- if(myPoll!=0){
- // myFD is always writable if requested
- myPoll->revents=isWritableRequested?POLLOUT:0;
- // myFD is only readable if the socket has anything to read
- myPoll->revents|=isFDReadable()?POLLIN:0;
- }
- return callReturns;
- }
- virtual bool isFDReadable() const {
- return sock->hasMoreRecv();
- }
-
- static Mock_poll* mock_;
- };
- // *****************************************************************************
- // gettimeofday
- class Mock_gettimeofday: public Mock
- {
- public:
- Mock_gettimeofday(){
- LIBC_SYMBOLS.gettimeofday(&tv,0);
- mock_=this;
- }
- Mock_gettimeofday(const Mock_gettimeofday& other):tv(other.tv){}
- Mock_gettimeofday(int32_t sec,int32_t usec){
- tv.tv_sec=sec;
- tv.tv_usec=usec;
- }
- ~Mock_gettimeofday(){mock_=0;}
-
- timeval tv;
- virtual int call(struct timeval *tp, GETTIMEOFDAY_ARG2_TYPE tzp){
- *tp=tv;
- return 0;
- }
- operator timeval() const{
- return tv;
- }
- // advance secs
- virtual void tick(int howmuch=1){tv.tv_sec+=howmuch;}
- // advance milliseconds
- // can move the clock forward as well as backward by providing a negative
- // number
- virtual void millitick(int howmuch=1){
- int ms=tv.tv_usec/1000+howmuch;
- tv.tv_sec+=ms/1000;
- // going backward?
- if(ms<0){
- ms=1000-(-ms%1000); //wrap millis around
- }
- tv.tv_usec=(ms%1000)*1000;
- }
- virtual void tick(const timeval& howmuch){
- // add milliseconds (discarding microsecond portion)
- long ms=tv.tv_usec/1000+howmuch.tv_usec/1000;
- tv.tv_sec+=howmuch.tv_sec+ms/1000;
- tv.tv_usec=(ms%1000)*1000;
- }
- static Mock_gettimeofday* mock_;
- };
- // discard microseconds!
- inline bool operator==(const timeval& lhs, const timeval& rhs){
- return rhs.tv_sec==lhs.tv_sec && rhs.tv_usec/1000==lhs.tv_usec/1000;
- }
- // simplistic implementation: no normalization, assume lhs >= rhs,
- // discarding microseconds
- inline timeval operator-(const timeval& lhs, const timeval& rhs){
- timeval res;
- res.tv_sec=lhs.tv_sec-rhs.tv_sec;
- res.tv_usec=(lhs.tv_usec/1000-rhs.tv_usec/1000)*1000;
- if(res.tv_usec<0){
- res.tv_sec--;
- res.tv_usec=1000000+res.tv_usec%1000000; // wrap the millis around
- }
- return res;
- }
- inline int32_t toMilliseconds(const timeval& tv){
- return tv.tv_sec*1000+tv.tv_usec/1000;
- }
- #endif /*LIBCMOCKS_H_*/
|