Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

A solution of mocking glibc function with Google Test.

License

NotificationsYou must be signed in to change notification settings

lonnywong/glibcmock

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Build StatusCoverage StatusCoverage StatusCode HealthMIT licensed

Welcome toglibc mock, a solution of mocking glibc function (open, read, write … etc.) withGoogle Test andGoogle Mock!

Mock glibc function by changing GOT value to custom static function address.

As we know, glibc function address is store in GOT (Global Offset Table).
Change the GOT value to a custom static function address, then the glibc call will call the custom static function actually.
In the custom static function, we make it to call a Google Mock method, then we have mocked the glibc function.

Usage

  1. Copygot_hook.h andgot_hook.cc to your C++ test project.
  2. Add#include "got_hook.h" to your test source code.

Sample 1

structMockMalloc {MOCK_METHOD1(Malloc,void *(size_t));};static MockMalloc *g_mock{nullptr};staticvoid *Malloc(size_t size) {return g_mock->Malloc(size);}static std::mutex g_test_mutex;TEST(MallocTest, ReturnNull) {    std::lock_guard<std::mutex>lock(g_test_mutex);// not thread safe    std::unique_ptr<MockMalloc>mock(g_mock =newMockMalloc());    testing::GotHook got_hook;ASSERT_NO_FATAL_FAILURE(got_hook.MockFunction("malloc", (void*)&Malloc));// ... do your test here, for example:EXPECT_CALL(*g_mock,Malloc(testing::_)).WillOnce(testing::Return(nullptr));EXPECT_EQ(nullptr,malloc(1));}

Sample 2

constexprkey_t shm_key =0x123;structTurtle {voidUseSharedMemory() {auto shm_id =shmget(shm_key,0,0);auto buffer =shmat(shm_id,nullptr,0);EXPECT_STREQ("a fake shm buffer", (char*)buffer);// ...shmdt(buffer);    }};structMockTurtle : Turtle {MOCK_METHOD3(shmget,int(key_t,size_t,int));MOCK_METHOD3(shmat,void*(int,constvoid*,int));MOCK_METHOD1(shmdt,int(constvoid*));};static MockTurtle *g_turtle{nullptr};staticintmy_shmget(key_t key,size_t size,int shmflg) {return g_turtle->shmget(key, size, shmflg);}staticvoid *my_shmat(int shmid,constvoid *shmaddr,int shmflg) {return g_turtle->shmat(shmid, shmaddr, shmflg);}staticintmy_shmdt(constvoid *shmaddr) {return g_turtle->shmdt(shmaddr);}static std::mutex g_test_mutex;TEST(TurtleTest, FakeSharedMemory) {    std::lock_guard<std::mutex>lock(g_test_mutex);// not thread safe    std::unique_ptr<MockTurtle>turtle(g_turtle =newMockTurtle());    testing::GotHook got_hook;ASSERT_NO_FATAL_FAILURE({        got_hook.MockFunction("shmget", (void*)&my_shmget);        got_hook.MockFunction("shmat", (void*)&my_shmat);        got_hook.MockFunction("shmdt", (void*)&my_shmdt);    });constexprint shm_id =100;char fake_shm_buffer[2000]{"a fake shm buffer"};// ...EXPECT_CALL(*g_turtle,shmget(shm_key, _, _)).WillOnce(Return(shm_id));EXPECT_CALL(*g_turtle,shmat(shm_id, _, _)).WillOnce(Return(fake_shm_buffer));EXPECT_CALL(*g_turtle,shmdt(fake_shm_buffer)).WillOnce(Return(0));// ...    g_turtle->UseSharedMemory();// ...}

Sample 3

constexprconstchar *prod_file ="/usr/local/xxx";constexprconstchar *test_file ="/tmp/xxx";structPanda {voidOpenFile() {auto fd =open(prod_file, O_RDONLY);// ...close(fd);    }};structMockPanda : Panda {MOCK_METHOD2(Open,int(constchar*,int));};static std::mutex g_test_mutex;static MockPanda *g_panda{nullptr};staticint (*libc_open)(constchar*,int, ...);structPandaTest : testing::Test {    testing::GotHook *got_hook{nullptr};virtualvoidSetUp() {        g_test_mutex.lock();// not thread safe        g_panda =newMockPanda();ASSERT_NO_FATAL_FAILURE({            got_hook =newtesting::GotHook();            got_hook->MockFunction("open", (void*)&Open, (void**)&libc_open);        });ON_CALL(*g_panda,Open(_, _)).WillByDefault(Invoke(libc_open));// ...    }virtualvoidTearDown() {delete got_hook;delete g_panda;        g_test_mutex.unlock();    }staticintOpen(constchar *pathname,int flags, ...) {if (strcmp(prod_file, pathname) ==0) {return g_panda->Open(test_file, flags);        }else {if (flags & O_CREAT) {va_list arg;va_start(arg, flags);mode_t mode =va_arg(arg,mode_t);va_end(arg);returnlibc_open(pathname, flags, mode);            }else {returnlibc_open(pathname, flags);            }        }    }};TEST_F(PandaTest, OpenTestFile) {// ...EXPECT_CALL(*g_panda,Open(test_file, O_RDONLY));// ...    g_panda->OpenFile();// ...}

Requirements

For now support Linux64-bit only. If you need a32-bit version, contact melonnywang@qq.com.

  • C++11 or newer
  • Google Test
  • Google Mock

[8]ページ先頭

©2009-2025 Movatter.jp