在linux上搭建bhook
技術標籤:軟體測試
上一節介紹了gtest的測試,這一節我們將進一步介紹bhook的安裝和使用,
BHOOK是Linux平臺上C/C++程式的一種Hook框架,是百度推出的開源hook框架,主要基於Hook鉤子的原理,它可以在執行時動態地替換原來的函式來改變程式邏輯,支援如下功能:
1)支援替換任何函式(打破gmock需要繼承業務程式碼的類,且只能mock虛擬函式的限制),包括共享庫函式(如系統函式)、靜態庫函式和程式函式。
2)提供系統功能的預設掛鉤庫(比如模擬磁碟滿)。
3)它可以用於除錯(比如聯調下游未完備的情況)、模擬、測試(比如單測)等。
首先介紹下安裝步驟
1)原始碼包可以從我的微雲上獲取:
https://share.weiyun.com/UCSHHV1G-g
2)這裡使用的是bhook-1.0.0,解壓後進入bhook-1.0.0資料夾:
cd bhook-1.0.0/
3)呼叫configure配置編譯生成檔案的路徑,這裡必須要設定為絕對路徑
./configure --prefix=/root/gtest/bhook
這裡我們設定的路徑為/root/gtest/bhook,依次執行編譯和安裝
make
make install
此時可以看到/root/gtest/bhook資料夾下:
我們在上一篇介紹gtest的測試的文章基礎上繼續寫一個簡單的測試程式,編寫測試檔案funcTest.cpp:
#include "gtest/gtest.h" #include "bhook.h" #include <iostream> using namespace std; class testObj { public: int test() { cout<<"Origin test func"<<endl; return 0; } }; int mytest() { cout<<"Alternate test func"<<endl; return 0; } TEST(testObj,testbHook){ testObj tObj; int ret=tObj.test(); ASSERT_TRUE(ret>=0); attach_func_lib("testObj::test", (void *)mytest); ret=tObj.test(); ASSERT_TRUE(ret>=0); attach_func_lib("testObj::test", (void *)mytest); } int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }
makefile的編寫如下:
CXX=g++ LDFLAGS = -g -L../gtest-1.7.0/lib/ -L../bhook/lib/ LIBS = -lgtest -lgtest_main -lpthread -lbhook -lbfd -liberty -lopcodes -ldl CXXFLAGS = -I../gtest-1.7.0/include -I../bhook/include funcTest: funcTest.o $(CXX) -o funcTest funcTest.o $(LIBS) funcTest.o: funcTest.cpp $(CXX) $(LDFLAGS) $(CXXFLAGS) -c funcTest.cpp clean: rm -rf *.o funcTest
同樣這裡要注意bhook的include和lib資料夾位置,應該只想之前編譯的資料夾位置。編譯生成後,執行程式結果如下:
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from testObj
[ RUN ] testObj.testbHook
Origin test func
Alternate test func
[ OK ] testObj.testbHook (10 ms)
[----------] 1 test from testObj (10 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (10 ms total)
[ PASSED ] 1 test.
這裡可以看到bhook的作用,呼叫attach_func_lib可以用自定義函式替換指定的函式,在呼叫attach_func_lib之前,該函式將一直被代替,對於一些需要網路連結或者都資料庫的操作,如果測試環境不滿足條件,就可以通過這種方式替代那些都資料庫和都網路的函式,自己寫函式“假裝”讀取網路或資料庫,來實現測試的功能,需要指出的一點是,這種替換隻能針對類的共有函式,私有函式是無法替換的,不知道目前有什麼好的解決辦法。