From 3c82560621f08d4f7c4378c2ef32ccece4f1a3e4 Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Thu, 5 May 2005 14:00:08 +0000 Subject: [PATCH] Added test4.cpp for plugin managment system testing, added -v parameter for verbose output on test fail --HG-- extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/trunk%4061 --- sourcehook/test/Makefile | 7 +- sourcehook/test/main.cpp | 3 +- sourcehook/test/test4.cpp | 422 +++++++++++++++++++++++++++++++++++ sourcehook/test/testevents.h | 27 ++- 4 files changed, 455 insertions(+), 4 deletions(-) create mode 100644 sourcehook/test/test4.cpp diff --git a/sourcehook/test/Makefile b/sourcehook/test/Makefile index d5837ba..03ad491 100644 --- a/sourcehook/test/Makefile +++ b/sourcehook/test/Makefile @@ -1,8 +1,8 @@ CC=gcc CCFLAGS=-c -g -I.. -DSH_DEBUG -test.bin: bin bin/main.o bin/test1.o bin/test2.o bin/test3.o bin/sourcehook.o - $(CC) bin/main.o bin/test1.o bin/test2.o bin/test3.o bin/sourcehook.o -lstdc++ -o test.bin +test.bin: bin bin/main.o bin/test1.o bin/test2.o bin/test3.o bin/test4.o bin/sourcehook.o + $(CC) bin/main.o bin/test1.o bin/test2.o bin/test3.o bin/test4.o bin/sourcehook.o -lstdc++ -o test.bin bin: mkdir bin @@ -19,6 +19,9 @@ bin/test2.o: test2.cpp ../sourcehook.h bin/test3.o: test3.cpp ../sourcehook.h $(CC) $(CCFLAGS) -o bin/test3.o test3.cpp +bin/test4.o: test4.cpp ../sourcehook.h + $(CC) $(CCFLAGS) -o bin/test4.o test4.cpp + bin/sourcehook.o: ../sourcehook.cpp ../sourcehook.h $(CC) $(CCFLAGS) -o bin/sourcehook.o ../sourcehook.cpp diff --git a/sourcehook/test/main.cpp b/sourcehook/test/main.cpp index c3ce672..b4a791f 100644 --- a/sourcehook/test/main.cpp +++ b/sourcehook/test/main.cpp @@ -62,13 +62,14 @@ std::list Test::ms_Tests; DO_TEST(Basic); DO_TEST(VafmtAndOverload); DO_TEST(ThisPtrOffs); +DO_TEST(PlugSys); int main(int argc, char *argv[]) { std::string error; int passed=0, failed=0; - g_Verbose = false; + g_Verbose = argc > 1 && strcmp(argv[1], "-v") == 0; Test::DoTests(); diff --git a/sourcehook/test/test4.cpp b/sourcehook/test/test4.cpp new file mode 100644 index 0000000..004d5d0 --- /dev/null +++ b/sourcehook/test/test4.cpp @@ -0,0 +1,422 @@ +#include +#include "sourcehook_impl.h" +#include "testevents.h" + +// TEST4 +// Tests of plugin management system + +namespace +{ + StateList g_States; + SourceHook::ISourceHook *g_SHPtr; + SourceHook::Plugin g_PLID; + + MAKE_STATE(State_Func1_Called); + MAKE_STATE(State_Func2_Called); + MAKE_STATE(State_Func3_Called); + + MAKE_STATE(State_Func1H_Called); + MAKE_STATE(State_Func2H_Called); + MAKE_STATE(State_Func3H_Called); + + MAKE_STATE_2(State_PluginInUse, int, bool); + + class Test + { + public: + virtual void Func1() + { + ADD_STATE(State_Func1_Called); + } + + virtual void Func2() + { + ADD_STATE(State_Func2_Called); + } + + virtual void Func3() + { + ADD_STATE(State_Func3_Called); + } + }; + + SH_DECL_HOOK0_void(Test, Func1, SH_NOATTRIB, 0); + SH_DECL_HOOK0_void(Test, Func2, SH_NOATTRIB, 0); + SH_DECL_HOOK0_void(Test, Func3, SH_NOATTRIB, 0); + + void Handler_Func1() + { + ADD_STATE(State_Func1H_Called); + } + void Handler_Func2() + { + ADD_STATE(State_Func2H_Called); + } + void Handler_Func3() + { + ADD_STATE(State_Func3H_Called); + } +} + +bool TestPlugSys(std::string &error) +{ + SourceHook::CSourceHookImpl g_SHImpl; + g_SHPtr = &g_SHImpl; + g_PLID = 1; + + Test inst; + Test *pInst = &inst; + + // 1) + // Add hooks, then issue a complete shutdown + SH_ADD_HOOK_STATICFUNC(Test, Func1, pInst, Handler_Func1, false); + SH_ADD_HOOK_STATICFUNC(Test, Func2, pInst, Handler_Func2, true); + SH_ADD_HOOK_STATICFUNC(Test, Func3, pInst, Handler_Func3, false); + + pInst->Func1(); + pInst->Func2(); + pInst->Func3(); + + CHECK_STATES((&g_States, + new State_Func1H_Called, + new State_Func1_Called, + new State_Func2_Called, + new State_Func2H_Called, + new State_Func3H_Called, + new State_Func3_Called, + NULL), "Part 1.1"); + + g_SHImpl.CompleteShutdown(); + + pInst->Func1(); + pInst->Func2(); + pInst->Func3(); + + CHECK_STATES((&g_States, + new State_Func1_Called, + new State_Func2_Called, + new State_Func3_Called, + NULL), "Part 1.2"); + + // 2) + // Add hooks from "different plugins", then shutdown the plugins + + g_PLID = 1; + SH_ADD_HOOK_STATICFUNC(Test, Func1, pInst, Handler_Func1, false); + g_PLID = 2; + SH_ADD_HOOK_STATICFUNC(Test, Func2, pInst, Handler_Func2, true); + g_PLID = 3; + SH_ADD_HOOK_STATICFUNC(Test, Func3, pInst, Handler_Func3, false); + + g_PLID = 1; + SH_ADD_HOOK_STATICFUNC(Test, Func2, pInst, Handler_Func2, true); + SH_ADD_HOOK_STATICFUNC(Test, Func3, pInst, Handler_Func3, false); + + g_PLID = 2; + SH_ADD_HOOK_STATICFUNC(Test, Func1, pInst, Handler_Func1, false); + SH_ADD_HOOK_STATICFUNC(Test, Func3, pInst, Handler_Func3, false); + + g_PLID = 3; + SH_ADD_HOOK_STATICFUNC(Test, Func1, pInst, Handler_Func1, false); + SH_ADD_HOOK_STATICFUNC(Test, Func2, pInst, Handler_Func2, true); + + pInst->Func1(); + pInst->Func2(); + pInst->Func3(); + + CHECK_STATES((&g_States, + new State_Func1H_Called, + new State_Func1H_Called, + new State_Func1H_Called, + new State_Func1_Called, + new State_Func2_Called, + new State_Func2H_Called, + new State_Func2H_Called, + new State_Func2H_Called, + new State_Func3H_Called, + new State_Func3H_Called, + new State_Func3H_Called, + new State_Func3_Called, + NULL), "Part 2.1"); + + ADD_STATE(State_PluginInUse(1, g_SHImpl.IsPluginInUse(1))); + ADD_STATE(State_PluginInUse(2, g_SHImpl.IsPluginInUse(2))); + ADD_STATE(State_PluginInUse(3, g_SHImpl.IsPluginInUse(3))); + ADD_STATE(State_PluginInUse(4, g_SHImpl.IsPluginInUse(4))); + + CHECK_STATES((&g_States, + new State_PluginInUse(1, true), + new State_PluginInUse(2, true), + new State_PluginInUse(3, true), + new State_PluginInUse(4, false), + NULL), "Part 2.2"); + + // Unload plugins one by one + g_SHImpl.UnloadPlugin(3); + + pInst->Func1(); + pInst->Func2(); + pInst->Func3(); + + CHECK_STATES((&g_States, + new State_Func1H_Called, + new State_Func1H_Called, + new State_Func1_Called, + new State_Func2_Called, + new State_Func2H_Called, + new State_Func2H_Called, + new State_Func3H_Called, + new State_Func3H_Called, + new State_Func3_Called, + NULL), "Part 2.3.1"); + + ADD_STATE(State_PluginInUse(1, g_SHImpl.IsPluginInUse(1))); + ADD_STATE(State_PluginInUse(2, g_SHImpl.IsPluginInUse(2))); + ADD_STATE(State_PluginInUse(3, g_SHImpl.IsPluginInUse(3))); + ADD_STATE(State_PluginInUse(4, g_SHImpl.IsPluginInUse(4))); + + CHECK_STATES((&g_States, + new State_PluginInUse(1, true), + new State_PluginInUse(2, true), + new State_PluginInUse(3, false), + new State_PluginInUse(4, false), + NULL), "Part 2.3.2"); + + g_SHImpl.UnloadPlugin(2); + + pInst->Func1(); + pInst->Func2(); + pInst->Func3(); + + CHECK_STATES((&g_States, + new State_Func1H_Called, + new State_Func1_Called, + new State_Func2_Called, + new State_Func2H_Called, + new State_Func3H_Called, + new State_Func3_Called, + NULL), "Part 2.4.1"); + + ADD_STATE(State_PluginInUse(1, g_SHImpl.IsPluginInUse(1))); + ADD_STATE(State_PluginInUse(2, g_SHImpl.IsPluginInUse(2))); + ADD_STATE(State_PluginInUse(3, g_SHImpl.IsPluginInUse(3))); + ADD_STATE(State_PluginInUse(4, g_SHImpl.IsPluginInUse(4))); + + CHECK_STATES((&g_States, + new State_PluginInUse(1, true), + new State_PluginInUse(2, false), + new State_PluginInUse(3, false), + new State_PluginInUse(4, false), + NULL), "Part 2.4.2"); + + g_SHImpl.UnloadPlugin(1); + + pInst->Func1(); + pInst->Func2(); + pInst->Func3(); + + CHECK_STATES((&g_States, + new State_Func1_Called, + new State_Func2_Called, + new State_Func3_Called, + NULL), "Part 2.5.1"); + + ADD_STATE(State_PluginInUse(1, g_SHImpl.IsPluginInUse(1))); + ADD_STATE(State_PluginInUse(2, g_SHImpl.IsPluginInUse(2))); + ADD_STATE(State_PluginInUse(3, g_SHImpl.IsPluginInUse(3))); + ADD_STATE(State_PluginInUse(4, g_SHImpl.IsPluginInUse(4))); + + CHECK_STATES((&g_States, + new State_PluginInUse(1, false), + new State_PluginInUse(2, false), + new State_PluginInUse(3, false), + new State_PluginInUse(4, false), + NULL), "Part 2.5.2"); + + + // 3) + // Add hooks from "different plugins", then pause the plugins + + g_PLID = 1; + SH_ADD_HOOK_STATICFUNC(Test, Func1, pInst, Handler_Func1, false); + g_PLID = 2; + SH_ADD_HOOK_STATICFUNC(Test, Func2, pInst, Handler_Func2, true); + g_PLID = 3; + SH_ADD_HOOK_STATICFUNC(Test, Func3, pInst, Handler_Func3, false); + + g_PLID = 1; + SH_ADD_HOOK_STATICFUNC(Test, Func2, pInst, Handler_Func2, true); + SH_ADD_HOOK_STATICFUNC(Test, Func3, pInst, Handler_Func3, false); + + g_PLID = 2; + SH_ADD_HOOK_STATICFUNC(Test, Func1, pInst, Handler_Func1, false); + SH_ADD_HOOK_STATICFUNC(Test, Func3, pInst, Handler_Func3, false); + + g_PLID = 3; + SH_ADD_HOOK_STATICFUNC(Test, Func1, pInst, Handler_Func1, false); + SH_ADD_HOOK_STATICFUNC(Test, Func2, pInst, Handler_Func2, true); + + pInst->Func1(); + pInst->Func2(); + pInst->Func3(); + + CHECK_STATES((&g_States, + new State_Func1H_Called, + new State_Func1H_Called, + new State_Func1H_Called, + new State_Func1_Called, + new State_Func2_Called, + new State_Func2H_Called, + new State_Func2H_Called, + new State_Func2H_Called, + new State_Func3H_Called, + new State_Func3H_Called, + new State_Func3H_Called, + new State_Func3_Called, + NULL), "Part 3.1"); + + ADD_STATE(State_PluginInUse(1, g_SHImpl.IsPluginInUse(1))); + ADD_STATE(State_PluginInUse(2, g_SHImpl.IsPluginInUse(2))); + ADD_STATE(State_PluginInUse(3, g_SHImpl.IsPluginInUse(3))); + ADD_STATE(State_PluginInUse(4, g_SHImpl.IsPluginInUse(4))); + + CHECK_STATES((&g_States, + new State_PluginInUse(1, true), + new State_PluginInUse(2, true), + new State_PluginInUse(3, true), + new State_PluginInUse(4, false), + NULL), "Part 3.2"); + + // Unload plugins one by one + g_SHImpl.PausePlugin(3); + + pInst->Func1(); + pInst->Func2(); + pInst->Func3(); + + CHECK_STATES((&g_States, + new State_Func1H_Called, + new State_Func1H_Called, + new State_Func1_Called, + new State_Func2_Called, + new State_Func2H_Called, + new State_Func2H_Called, + new State_Func3H_Called, + new State_Func3H_Called, + new State_Func3_Called, + NULL), "Part 3.3.1"); + + ADD_STATE(State_PluginInUse(1, g_SHImpl.IsPluginInUse(1))); + ADD_STATE(State_PluginInUse(2, g_SHImpl.IsPluginInUse(2))); + ADD_STATE(State_PluginInUse(3, g_SHImpl.IsPluginInUse(3))); + ADD_STATE(State_PluginInUse(4, g_SHImpl.IsPluginInUse(4))); + + CHECK_STATES((&g_States, + new State_PluginInUse(1, true), + new State_PluginInUse(2, true), + new State_PluginInUse(3, true), + new State_PluginInUse(4, false), + NULL), "Part 3.3.2"); + + g_SHImpl.PausePlugin(2); + + pInst->Func1(); + pInst->Func2(); + pInst->Func3(); + + CHECK_STATES((&g_States, + new State_Func1H_Called, + new State_Func1_Called, + new State_Func2_Called, + new State_Func2H_Called, + new State_Func3H_Called, + new State_Func3_Called, + NULL), "Part 3.4.1"); + + ADD_STATE(State_PluginInUse(1, g_SHImpl.IsPluginInUse(1))); + ADD_STATE(State_PluginInUse(2, g_SHImpl.IsPluginInUse(2))); + ADD_STATE(State_PluginInUse(3, g_SHImpl.IsPluginInUse(3))); + ADD_STATE(State_PluginInUse(4, g_SHImpl.IsPluginInUse(4))); + + CHECK_STATES((&g_States, + new State_PluginInUse(1, true), + new State_PluginInUse(2, true), + new State_PluginInUse(3, true), + new State_PluginInUse(4, false), + NULL), "Part 3.4.2"); + + g_SHImpl.PausePlugin(1); + + pInst->Func1(); + pInst->Func2(); + pInst->Func3(); + + CHECK_STATES((&g_States, + new State_Func1_Called, + new State_Func2_Called, + new State_Func3_Called, + NULL), "Part 3.5.1"); + + ADD_STATE(State_PluginInUse(1, g_SHImpl.IsPluginInUse(1))); + ADD_STATE(State_PluginInUse(2, g_SHImpl.IsPluginInUse(2))); + ADD_STATE(State_PluginInUse(3, g_SHImpl.IsPluginInUse(3))); + ADD_STATE(State_PluginInUse(4, g_SHImpl.IsPluginInUse(4))); + + CHECK_STATES((&g_States, + new State_PluginInUse(1, true), + new State_PluginInUse(2, true), + new State_PluginInUse(3, true), + new State_PluginInUse(4, false), + NULL), "Part 3.5.2"); + + g_SHImpl.UnpausePlugin(1); + g_SHImpl.UnpausePlugin(2); + g_SHImpl.UnpausePlugin(3); + + ADD_STATE(State_PluginInUse(1, g_SHImpl.IsPluginInUse(1))); + ADD_STATE(State_PluginInUse(2, g_SHImpl.IsPluginInUse(2))); + ADD_STATE(State_PluginInUse(3, g_SHImpl.IsPluginInUse(3))); + ADD_STATE(State_PluginInUse(4, g_SHImpl.IsPluginInUse(4))); + + CHECK_STATES((&g_States, + new State_PluginInUse(1, true), + new State_PluginInUse(2, true), + new State_PluginInUse(3, true), + new State_PluginInUse(4, false), + NULL), "Part 3.6"); + + pInst->Func1(); + pInst->Func2(); + pInst->Func3(); + + CHECK_STATES((&g_States, + new State_Func1H_Called, + new State_Func1H_Called, + new State_Func1H_Called, + new State_Func1_Called, + new State_Func2_Called, + new State_Func2H_Called, + new State_Func2H_Called, + new State_Func2H_Called, + new State_Func3H_Called, + new State_Func3H_Called, + new State_Func3H_Called, + new State_Func3_Called, + NULL), "Part 3.7"); + + // 4) Shutdown :) + g_SHImpl.CompleteShutdown(); + + pInst->Func1(); + pInst->Func2(); + pInst->Func3(); + + CHECK_STATES((&g_States, + new State_Func1_Called, + new State_Func2_Called, + new State_Func3_Called, + NULL), "Part 4"); + + return true; +} + diff --git a/sourcehook/test/testevents.h b/sourcehook/test/testevents.h index 11e6f52..622b181 100644 --- a/sourcehook/test/testevents.h +++ b/sourcehook/test/testevents.h @@ -14,6 +14,7 @@ #include #include #include +#include extern bool g_Verbose; @@ -31,6 +32,8 @@ namespace { return (typeid(other) == typeid(this)) ? true : false; } + + virtual void Dump() = 0; }; typedef std::list StateList; @@ -38,6 +41,12 @@ namespace #define ADD_STATE(name) g_States.push_back(new name) + void DumpStates(StateList *sl) + { + for (StateList::iterator iter = sl->begin(); iter != sl->end(); ++iter) + (*iter)->Dump(); + } + bool StatesOk(StateList *sl, ...) { StateList requiredstates; @@ -54,6 +63,14 @@ namespace if (requiredstates.size() != sl->size()) { + if (g_Verbose) + { + std::cout << std::endl << "FAIL: Should be:" << std::endl; + DumpStates(&requiredstates); + std::cout << std::endl << "FAIL: Is:" << std::endl; + DumpStates(sl); + } + for (StateList::iterator iter = requiredstates.begin(); iter != requiredstates.end(); ++iter) delete *iter; for (StateList::iterator iter = sl->begin(); iter != sl->end(); ++iter) @@ -86,7 +103,11 @@ namespace //#define CHECK_STATES(mwah, myerr) if (!StatesOk mwah) { error=myerr; return false; } else if (g_Verbose) { std::cout << "No error: " << myerr << std::endl; } #define CHECK_STATES(mwah, myerr) if (!StatesOk mwah) { error=myerr; return false; } -#define MAKE_STATE(name) struct name : State {}; +#define MAKE_STATE(name) struct name : State { \ + virtual void Dump() { \ + std::cout << " " << #name << std::endl; } \ + }; + #define MAKE_STATE_1(name, p1_type) struct name : State { \ p1_type m_Param1; \ name(p1_type param1) : m_Param1(param1) {} \ @@ -96,6 +117,8 @@ namespace return false; \ return other2->m_Param1 == m_Param1;\ } \ + virtual void Dump() { \ + std::cout << " " << #name << "; Param1=" << m_Param1 << std::endl; } \ } #define MAKE_STATE_2(name, p1_type, p2_type) struct name : State { \ @@ -108,6 +131,8 @@ namespace return false; \ return other2->m_Param1 == m_Param1 && other2->m_Param2 == m_Param2;\ } \ + virtual void Dump() { \ + std::cout << " " << #name << "; Param1=" << m_Param1 << "; Param2=" << m_Param2 << std::endl; } \ } #endif