ソースを参照

Z991239-678 #comment feature: 将 TestDeamon 移到 实体开发中

gifur 5 年 前
コミット
e66539c86d

+ 15 - 0
Module/mod_validityVertifier/CMakeLists.txt

@@ -0,0 +1,15 @@
+# 定义实体名称
+define_moudle("validityVertifier")
+
+set(${MODULE_PREFIX}_SRCS
+	mod_validityVertifier.cpp)
+
+set(MOD_VERSION_STRING "1.0.0-dev1")
+add_module_libraries(${MODULE_PREFIX} ${MODULE_NAME} ${MOD_VERSION_STRING})
+
+
+# 添加实体需要依赖的其他共享库(包括系统库)
+set(${MODULE_PREFIX}_LIBS ${MODULE_BASE_LIBS})
+target_link_libraries(${MODULE_NAME}  ${${MODULE_PREFIX}_LIBS})
+
+deploy_module(${MODULE_PREFIX} ${MODULE_NAME})

+ 0 - 0
Module/mod_validityVertifier/ChangeLog


+ 314 - 0
Module/mod_validityVertifier/mod_validityVertifier.cpp

@@ -0,0 +1,314 @@
+#include "stdafx.h"
+#include "SpBase.h"
+#include "SpTest.h"
+#include "modVer.h"
+
+/*Integrated test deamon*/
+
+#define OP_START  1
+#define OP_TEST     2
+#define OP_CHECK  3
+
+struct TestModeInfo {
+	TestModeInfo() :isTestMode(false), nLevel(0) {
+	}
+	bool isTestMode;
+	int nLevel;
+};
+
+class CTestDeamon
+	: public CEntityBase
+	, public IEntityLifeListener
+	, public IEntityStateListener
+	, public ILogListener
+	, public ICallbackListener
+	, public ITerminalStateChangedListener
+	, public ITimerListener
+{
+public:
+	CTestDeamon() : _dwStartedTestEntities(0) { _arrTestEntities.Clear(); }
+	virtual ~CTestDeamon() {
+		GetFunction()->UnsubscribeLog(m_subUUID);
+		GetFunction()->GetPrivilegeFunction()->UnregistLiftEvent();
+		GetFunction()->GetPrivilegeFunction()->UnregistEntityStateEvent(NULL);
+	}
+	virtual const char *GetEntityName() const { return "TestDeamon"; }
+	const char* GetEntityVersion() const { return MODULE_VERSION_FULL; }
+
+	virtual void OnPreStart(CAutoArray<CSimpleStringA> strArgs, CSmartPointer<ITransactionContext> pTransactionContext)
+	{
+		LOG_FUNCTION();
+		for (int i = 0; i < strArgs.GetCount(); ++i) {
+			auto& strParam = strArgs[i];
+			if (strParam.IsStartWith("TestMode", true)) {
+				if (strParam.IsEndWith("=ON", true)) {
+					_testInfo.isTestMode = true;
+				}
+			}
+		}
+
+		IFFAILBREAK(GetFunction()->GetSystemRunInfo(_runInfo));
+
+		auto privilegeFunc = GetFunction()->GetPrivilegeFunction();
+		privilegeFunc->RegistEntityLifeEvent(this);
+		/*register all entity state*/
+		privilegeFunc->RegistEntityStateEvent(NULL, this);
+		Dbg("to subscribe Error_Failed type log.");
+		auto res = GetFunction()->SubscribeLog(m_subUUID, this, Log_Error, Severity_None, Error_Failed, -2, NULL, false);
+		if (IS_FAILURED(res)) {
+			LogError(Severity_High, res, 0, "subscribe Error_Failed type log failed!");
+		}
+		pTransactionContext->SendAnswer(Error_Succeed);
+	}
+
+	BOOL IsExcludeEntity(const CSimpleStringA& name)
+	{
+		if (name.Compare(GetEntityName()) == 0)
+			return TRUE;
+
+		for (int i = 0; i < _arrTestEntities.GetCount(); ++i) {
+			if (name.Compare(_arrTestEntities[i]) == 0)
+				return TRUE;
+		}
+		
+		return FALSE;
+	}
+
+	void TestAllRegistedEntity()
+	{
+		CAutoArray<CSimpleStringA> arrStartEntities;
+		CAutoArray< DWORD> arrEntitityID;
+		IFFAILBREAK(GetFunction()->GetAllStartedEntity(arrStartEntities, arrEntitityID));
+		for (int i = 0; i < arrStartEntities.GetCount(); ++i) {
+			if(!IsExcludeEntity(arrStartEntities[i]))
+				TestEntity(arrStartEntities[i]);
+		}
+	}
+
+	virtual void OnStarted()
+	{
+		LOG_FUNCTION();
+		IFFAILBREAK(GetFunction()->RegistTerminalStateChangeEvent(this));
+		IFFAILBREAK(GetFunction()->SetTimer(1, this, 60 * 1000));
+	}
+
+	virtual void OnPreClose(EntityCloseCauseEnum eCloseCause,CSmartPointer<ITransactionContext> pTransactionContext) 
+	{ 
+		LOG_FUNCTION();
+		pTransactionContext->SendAnswer(Error_Succeed); 
+	}
+
+	//IEntityLifeListener
+	void OnCreated(const char* pszEntityName, ErrorCodeEnum eOnStartErrorCode, const char* pszCallerEntity)
+	{
+		LOG_TRACE("%s created by %s turns out %s",pszEntityName, pszCallerEntity, SpStrError(eOnStartErrorCode));
+	}
+
+	void OnClosed(const char* pszEntityName,
+		EntityCloseCauseEnum eCloseCause,
+		ErrorCodeEnum eOnCloseErrorCode,
+		const char* pszCallerEntity)
+	{
+		LOG_TRACE("%s closed by %s because reason: %s turns out: %s",pszEntityName, pszCallerEntity, SpStrCloseCause(eCloseCause), SpStrError(eOnCloseErrorCode));
+	}
+	void OnException(const char* pszEntityName, const char* pszFunctionName, EntityStateEnum eState, EntityStateEnum eLastState, ErrorCodeEnum eErrorCode)
+	{
+		THROW_FATAL("OnException: %s::%s, changed state from %s to %s: ec:%s", 
+			pszEntityName, pszFunctionName, SpStrEntityState(eLastState), SpStrEntityState(eState), SpStrError(eErrorCode));
+		if (eState == EntityState_Failed || eState == EntityState_Lost) {
+			RequireTerminalExit();
+		}
+	}
+
+	//IEntityStateListener
+	void OnEntityStateHook(const char* pszEntityName,
+		const char* pszTriggerEntity,
+		EntityStateEnum eState,
+		EntityStateEnum eLastState)
+	{
+		LOG_TRACE(">>>%s's entity state refreshed from %s to %s by %s",
+			pszEntityName, SpStrEntityState(eLastState), SpStrEntityState(eState), pszTriggerEntity);
+		if (eState == EntityState_Failed || eState == EntityState_Lost) {
+			RequireTerminalExit();
+		}
+		else if (eLastState == EntityState_Starting && eState == EntityState_Idle) {
+			/** if meet multi-entities at one mod, do test maybe failed beacause mod is busy at starting other brother entity.*/
+			//TestEntity(pszEntityName);
+		}
+	}
+
+	void OnUserStateHook(const char* pszEntityName, DWORD dwState, DWORD dwLastState)
+	{
+		LOG_TRACE(">>>%s'user state refreshed to %d from %d", pszEntityName, dwState, dwLastState);
+	}
+
+	void OnCeateConnection(const char* pszCallerEntity, const char* pszServiceEntity)
+	{
+		LOG_TRACE(">>>OnCeateConnection: caller: %s, service: %s", pszCallerEntity, pszServiceEntity);
+	}
+
+	void OnCloseConnection(const char* pszCallerEntity, const char* pszServiceEntity)
+	{
+		LOG_TRACE(">>>OnCloseConnection: caller: %s, service: %s", pszCallerEntity, pszServiceEntity);
+	}
+
+	//ILogListener
+	void OnLog(const CAutoArray<CUUID>& SubIDs
+		, const CUUID nLogID
+		, const LogTypeEnum eLogType
+		, const SeverityLevelEnum eLevel
+		, const DWORD dwSysError, const DWORD dwUserCode
+		, const DWORD dwEntityInstanceID, const WORD wEntityDevelID
+		, const CAutoArray<DWORD>& Param
+		, const char* pszEntityName, const char* pszModuleName, const char* pszMessage)
+	{
+		LogEvent(eLevel, 0,
+			CSimpleStringA::Format("Catched Test Failed Message: [%s][0x%03X][%s] - %s", 
+				pszModuleName, wEntityDevelID, pszEntityName, pszMessage));
+		switch (eLevel) {
+		case Severity_High:
+			RequireTerminalExit();
+			break;
+		case Severity_Middle:
+			/** do nothings*/
+			break;
+		default:
+			break;
+		}
+	}
+
+	void OnStateChanged(FrameworkStateEnum oldState, FrameworkStateEnum curState, const char* triggerEntity)
+	{
+
+		Dbg("OnStateChanged:  from %s to %s trigged by %s",
+			SpStrFrameworkState(oldState), SpStrFrameworkState(curState), triggerEntity);
+
+		if (curState == FrameworkState_Running && _testInfo.isTestMode
+			// && !(_runInfo.dwBootOption & BootOption_Benchmark) /** when under benchmark, still need to test entity??*/
+			) 
+		{
+			TestAllRegistedEntity();
+		}
+	}
+
+	void OnTimeout(DWORD dwTimerID)
+	{
+		Dbg("timer out: %d, to shake hand", dwTimerID);
+		CAutoArray<CSimpleStringA> arrStartEntities;
+		CAutoArray< DWORD> arrEntitityID;
+		IFFAILBREAK(GetFunction()->GetAllStartedEntity(arrStartEntities, arrEntitityID));
+		for (int i = 0; i < arrStartEntities.GetCount(); ++i)
+		{
+			if (arrStartEntities[i].Compare(GetEntityName()) != 0) 
+			{
+				TestEntity(arrStartEntities[i], TRUE);
+			}
+		}
+	}
+
+	struct TestCallbackResult : public IReleasable
+	{
+		TestCallbackResult() :strEntityName(true), op(0) {}
+		virtual ~TestCallbackResult() {}
+		CSimpleStringA strEntityName;
+		int op;
+	};
+
+	/*ICallbackListener*/
+	void OnAnswer(CSmartPointer<IAsynWaitSp> pAsynWaitSp)
+	{
+		CSmartPointer<ICallbackListener> listener;
+		CSmartPointer<IReleasable> context;
+		CHECK(pAsynWaitSp->GetCallback(listener, context));
+		TestCallbackResult* result = static_cast<TestCallbackResult*>(context.GetRawPointer());
+		CHECK(result != NULL);
+		DWORD dwUserCode = 0;
+		const auto ec = pAsynWaitSp->AsyncGetAnswer(dwUserCode);
+		if (result->op == OP_START) 
+		{
+			if (IS_FAILURED(ec)) 
+			{
+				THROW_ERROR("Start %s failed return %s!", result->strEntityName.GetData(), SpStrError(ec));
+			}
+			else 
+			{
+				Dbg("Start entity %s succ.", result->strEntityName.GetData());
+				_arrTestEntities[_dwStartedTestEntities++] = result->strEntityName;
+			}
+		}
+		else if(result->op == OP_TEST) 
+		{ /** OnExam returned.*/
+			if (Error_IgnoreAll == ec || Error_NotImpl == ec) 
+			{
+				LogWarn(Severity_Middle, Error_NotImpl, 0, CSimpleStringA::Format(
+					"Test for entity [%s] is not OK: Detect no any TestCase!!", result->strEntityName.GetData()));
+			}
+			else if (Error_Accept == ec || Error_Succeed == ec)
+			{
+				LogEvent(Severity_High, 0, CSimpleStringA::Format("Test for entity[%s] succ.", result->strEntityName.GetData()));
+			}
+			else
+			{
+				TestCaseStatistics statistic;
+				statistic.ConvertFormUserCode(dwUserCode);
+				THROW_ERROR("Test for entity[%s] failed return %s: %.2lf percent tests passed, %u test failed out of %u cases",
+					result->strEntityName.GetData(), SpStrError(ec), statistic.FailureRate(), statistic.Failures(), statistic.Total());
+			}
+			Dbg("return usercode: 0x%08X", dwUserCode);
+		}
+		else if (result->op == OP_CHECK) 
+		{
+			if (IS_FAILURED(ec))
+			{
+				THROW_ERROR("Check %s failed return %s!", result->strEntityName.GetData(), SpStrError(ec));
+			}
+		}
+	}
+
+private:
+
+	void RequireTerminalExit()
+	{
+		if (_testInfo.isTestMode) 
+		{
+			Dbg("Test Failed! shutdown the terminal program...");
+			auto pPriviFunc = GetFunction()->GetPrivilegeFunction();
+			pPriviFunc->Reboot(RebootTrigger_DeadForever, RebootWay_Framework);
+		}
+	}
+
+	void SetOPCallback(CSmartPointer<IAsynWaitSp>& spWait, const char* pcszName, int op)
+	{
+		TestCallbackResult* result = new TestCallbackResult();
+		result->strEntityName = pcszName;
+		result->op = op;
+		spWait->SetCallback(this, result);
+	}
+
+	ErrorCodeEnum TestEntity(const char* lcpszEntityName, bool bShake = false)
+	{
+		if(!bShake)
+			LogEvent(Severity_High, 0, CSimpleStringA::Format("Test specified entity: %s", lcpszEntityName));
+		auto pPriviFunc = GetFunction()->GetPrivilegeFunction();
+		CSmartPointer<IAsynWaitSp> waitSp;
+		auto ec = pPriviFunc->TestEntity(lcpszEntityName, bShake ? Test_ShakeHand : Test_Examine, waitSp);
+		if (IS_FAILURED(ec)) 
+		{
+			THROW_ERROR("Try to %s for %s failed return %s!", bShake ? "check" : "test", lcpszEntityName, SpStrError(ec));
+			return Error_Failed;
+		}
+		SetOPCallback(waitSp, lcpszEntityName,  bShake ? OP_CHECK : OP_TEST);
+		return Error_Succeed;
+	}
+
+private:
+	TestModeInfo _testInfo;
+	CUUID m_subUUID;
+	CAutoArray<CSimpleStringA> _arrTestEntities;
+	DWORD _dwStartedTestEntities;
+	CSystemRunInfo _runInfo;
+};
+
+SP_BEGIN_ENTITY_MAP()
+	SP_ENTITY(CTestDeamon)
+SP_END_ENTITY_MAP()

+ 0 - 7
addin/cfg/TestDeamon.ini

@@ -1,7 +0,0 @@
-[Entity]
-Number=5
-1=HighVoltage
-2=HighVoltageSecond
-3=HighVoltageThird
-4=HighVoltageFour
-5=HighVoltageFifth

+ 1 - 28
addin/cfg/shell.ini.in

@@ -90,22 +90,6 @@ Initializer=0,@LIB_PREFIX@mod_Initializer@LIB_SUFFIX@,0x509
 
 ;ʵÌå²âÊÔ
 TestDeamon=1,@LIB_PREFIX@mod_validityVertifier@LIB_SUFFIX@,0xF00
-HelloService=0,@LIB_PREFIX@mod_helloservice@LIB_SUFFIX@,0xF01
-HelloClient=0,@LIB_PREFIX@mod_helloclient@LIB_SUFFIX@,0xF02
-SampleEntity=0,@LIB_PREFIX@mod_SampleEntity@LIB_SUFFIX@,0xF03
-TestSubscribe=0,@LIB_PREFIX@mod_testSubscribe@LIB_SUFFIX@,0xF04
-BlackSheep=0,@LIB_PREFIX@mod_blackSheep@LIB_SUFFIX@,0xF05
-TestPrivilegeEntity=1,@LIB_PREFIX@mod_testPrivilegeEntity@LIB_SUFFIX@,0xF06
-TestNormalEntity=0,@LIB_PREFIX@mod_testNormalEntity@LIB_SUFFIX@,0xF07
-TestPassiveEntity=0,@LIB_PREFIX@mod_testPassiveEntity@LIB_SUFFIX@,0xF08
-TestPassiveSecondEntity=0,@LIB_PREFIX@mod_testPassiveEntity@LIB_SUFFIX@,0xF09
-TestPassiveThirdEntity=0,@LIB_PREFIX@mod_testPassiveEntity@LIB_SUFFIX@,0xF0A
-TestLogSender=0,@LIB_PREFIX@mod_testSendLog@LIB_SUFFIX@,0xF0B
-HighVoltage=0,@LIB_PREFIX@mod_highVoltage@LIB_SUFFIX@,0xF0C
-HighVoltageSecond=0,@LIB_PREFIX@mod_highVoltageSecond@LIB_SUFFIX@,0xF0D
-HighVoltageThird=0,@LIB_PREFIX@mod_highVoltageThird@LIB_SUFFIX@,0xF0E
-HighVoltageFour=0,@LIB_PREFIX@mod_highVoltageFour@LIB_SUFFIX@,0xF0F
-HighVoltageFifth=0,@LIB_PREFIX@mod_highVoltageFifth@LIB_SUFFIX@,0xF10
 
 [Startup]
 Number=2
@@ -116,21 +100,10 @@ Number=2
 
 
 [Test]
-Number=6
+Number=1
 1=TestDeamon TestMode=ON Level=3 Entity=BlackSheep -D
-2=TestSubscribe
-3=SampleEntity
-4=TestLogSender
-5=TestNormalEntity
-6=TestPrivilegeEntity
-;illegal name
-7=BlackSheep
 
 [SysEvent]
-SampleState=SampleEntity;TestDeamon;HelloClient HelloService,"0"
-PrivilegeState=TestPrivilegeEntity	TestNormalEntity,"the max length of this system value cannot exceed to 260 include end char"
-AlwaysUpdate=HighVoltage;HighVoltageSecond;HighVoltageThird;HighVoltageFour;HighVoltageFifth,"0"
-
 ;HelloState=HelloService,"0"
 ;CallState=CounterConnector,"O"
 ;BackInitiative=InitiativeTransfer,"O"

+ 0 - 1
module/CMakeLists.txt

@@ -15,7 +15,6 @@ else()
     set(TOOLKIT_LIB libtoolkit)
 endif(RVC_DEBUG_MODE)
 
-
 set(MODULE_BASE_LIBS ${SPBASE_LIB} ${TOOLKIT_LIB})
 set(MODULE_BASE_ALL_LIBS ${MODULE_BASE_LIBS} ${RVCCOMM_LIB}) 
 if(NOT MSVC)