mod_validityVertifier.cpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. #include "stdafx.h"
  2. #include "SpBase.h"
  3. #include "SpTest.h"
  4. /*Integrated test deamon*/
  5. #define OP_START 1
  6. #define OP_TEST 2
  7. struct TestModeInfo {
  8. TestModeInfo() :isTestMode(false), nLevel(0) {
  9. }
  10. bool isTestMode;
  11. int nLevel;
  12. };
  13. class CTestDeamon
  14. : public CEntityBase
  15. , public IEntityLifeListener
  16. , public IEntityStateListener
  17. , public ILogListener
  18. , public ICallbackListener
  19. , public ITerminalStateChangedListener
  20. {
  21. public:
  22. CTestDeamon() : _dwStartedTestEntities(0) { _arrTestEntities.Clear(); }
  23. virtual ~CTestDeamon() {
  24. GetFunction()->UnsubscribeLog(m_subUUID);
  25. GetFunction()->GetPrivilegeFunction()->UnregistLiftEvent();
  26. GetFunction()->GetPrivilegeFunction()->UnregistEntityStateEvent(NULL);
  27. }
  28. virtual const char *GetEntityName() const { return "TestDeamon"; }
  29. virtual void OnPreStart(CAutoArray<CSimpleStringA> strArgs, CSmartPointer<ITransactionContext> pTransactionContext)
  30. {
  31. LOG_FUNCTION();
  32. for (int i = 0; i < strArgs.GetCount(); ++i) {
  33. auto& strParam = strArgs[i];
  34. if (strParam.IsStartWith("TestMode", true)) {
  35. if (strParam.IsEndWith("=ON", true)) {
  36. _testInfo.isTestMode = true;
  37. }
  38. }
  39. }
  40. auto privilegeFunc = GetFunction()->GetPrivilegeFunction();
  41. privilegeFunc->RegistEntityLifeEvent(this);
  42. /*register all entity state*/
  43. privilegeFunc->RegistEntityStateEvent(NULL, this);
  44. Dbg("to subscribe Error_Failed type log.");
  45. auto res = GetFunction()->SubscribeLog(m_subUUID, this, Log_Error, Severity_None, Error_Failed, -2, NULL, false);
  46. if (IS_FAILURED(res)) {
  47. LogError(Severity_High, res, 0, "subscribe Error_Failed type log failed!");
  48. }
  49. pTransactionContext->SendAnswer(Error_Succeed);
  50. }
  51. BOOL IsExcludeEntity(const CSimpleStringA& name)
  52. {
  53. if (name.Compare(GetEntityName()) == 0)
  54. return TRUE;
  55. for (int i = 0; i < _arrTestEntities.GetCount(); ++i) {
  56. if (name.Compare(_arrTestEntities[i]) == 0)
  57. return TRUE;
  58. }
  59. return FALSE;
  60. }
  61. void TestAllRegistedEntity()
  62. {
  63. CAutoArray<CSimpleStringA> arrStartEntities;
  64. CAutoArray< DWORD> arrEntitityID;
  65. IFFAILBREAK(GetFunction()->GetAllStartedEntity(arrStartEntities, arrEntitityID));
  66. for (int i = 0; i < arrStartEntities.GetCount(); ++i) {
  67. if(!IsExcludeEntity(arrStartEntities[i]))
  68. TestEntity(arrStartEntities[i]);
  69. }
  70. }
  71. ErrorCodeEnum StartTestEntity()
  72. {
  73. CSmartPointer<IConfigInfo> spConfig;
  74. IFFAILRET(GetFunction()->OpenConfig(Config_Software, spConfig));
  75. auto privilegeFunc = GetFunction()->GetPrivilegeFunction();
  76. REQUIRE(privilegeFunc != NULL);
  77. int entityCount = 0;
  78. IFFAILRET(spConfig->ReadConfigValueInt("Entity", "Number", entityCount));
  79. _arrTestEntities.Init(entityCount);
  80. for (int i = 1; i <= entityCount; ++i) {
  81. char szNumber[4];
  82. sprintf(szNumber, "%d", i);
  83. CSimpleStringA strCurEntityName;
  84. IFFAILRET(spConfig->ReadConfigValue("Entity", szNumber, strCurEntityName));
  85. REQUIRE_FALSE(strCurEntityName.IsNullOrEmpty());
  86. Dbg("Try to start entity: %s", (LPCTSTR)strCurEntityName);
  87. CSmartPointer<IAsynWaitSp> spWait;
  88. IFFAILRET(privilegeFunc->StartEntity(strCurEntityName, NULL, spWait));
  89. REQUIRE(spWait != NULL);
  90. SetOPCallback(spWait, strCurEntityName, OP_START);
  91. //_arrTestEntities[i - 1] = strCurEntityName;
  92. }
  93. return Error_Succeed;
  94. }
  95. virtual void OnStarted()
  96. {
  97. LOG_FUNCTION();
  98. IFFAILBREAK(GetFunction()->RegistTerminalStateChangeEvent(this));
  99. if (_testInfo.isTestMode) {
  100. if (IS_SUCCEED(StartTestEntity())) {
  101. //TestAllRegistedEntity();
  102. }
  103. }
  104. }
  105. virtual void OnPreClose(EntityCloseCauseEnum eCloseCause,CSmartPointer<ITransactionContext> pTransactionContext)
  106. {
  107. LOG_FUNCTION();
  108. pTransactionContext->SendAnswer(Error_Succeed);
  109. }
  110. //IEntityLifeListener
  111. void OnCreated(const char* pszEntityName, ErrorCodeEnum eOnStartErrorCode, const char* pszCallerEntity)
  112. {
  113. LOG_TRACE("%s created by %s turns out %s",pszEntityName, pszCallerEntity, SpStrError(eOnStartErrorCode));
  114. }
  115. void OnClosed(const char* pszEntityName,
  116. EntityCloseCauseEnum eCloseCause,
  117. ErrorCodeEnum eOnCloseErrorCode,
  118. const char* pszCallerEntity)
  119. {
  120. LOG_TRACE("%s closed by %s because reason: %s turns out: %s",pszEntityName, pszCallerEntity, SpStrCloseCause(eCloseCause), SpStrError(eOnCloseErrorCode));
  121. }
  122. void OnException(const char* pszEntityName, const char* pszFunctionName, EntityStateEnum eState, EntityStateEnum eLastState, ErrorCodeEnum eErrorCode)
  123. {
  124. THROW_FATAL("OnException: %s::%s, changed state from %s to %s: ec:%s",
  125. pszEntityName, pszFunctionName, SpStrEntityState(eLastState), SpStrEntityState(eState), SpStrError(eErrorCode));
  126. if (eState == EntityState_Failed || eState == EntityState_Lost) {
  127. RequireTerminalExit();
  128. }
  129. }
  130. //IEntityStateListener
  131. void OnEntityStateHook(const char* pszEntityName,
  132. const char* pszTriggerEntity,
  133. EntityStateEnum eState,
  134. EntityStateEnum eLastState)
  135. {
  136. LOG_TRACE(">>>%s's entity state refreshed from %s to %s by %s",
  137. pszEntityName, SpStrEntityState(eLastState), SpStrEntityState(eState), pszTriggerEntity);
  138. if (eState == EntityState_Failed || eState == EntityState_Lost) {
  139. RequireTerminalExit();
  140. }
  141. else if (eLastState == EntityState_Starting && eState == EntityState_Idle) {
  142. /** if meet multi-entities at one mod, do test maybe failed beacause mod is busy at starting other brother entity.*/
  143. //TestEntity(pszEntityName);
  144. }
  145. }
  146. void OnUserStateHook(const char* pszEntityName, DWORD dwState, DWORD dwLastState)
  147. {
  148. LOG_TRACE(">>>%s'user state refreshed to %d from %d", pszEntityName, dwState, dwLastState);
  149. }
  150. void OnCeateConnection(const char* pszCallerEntity, const char* pszServiceEntity)
  151. {
  152. LOG_TRACE(">>>OnCeateConnection: caller: %s, service: %s", pszCallerEntity, pszServiceEntity);
  153. }
  154. void OnCloseConnection(const char* pszCallerEntity, const char* pszServiceEntity)
  155. {
  156. LOG_TRACE(">>>OnCloseConnection: caller: %s, service: %s", pszCallerEntity, pszServiceEntity);
  157. }
  158. //ILogListener
  159. void OnLog(const CAutoArray<CUUID>& SubIDs
  160. , const CUUID nLogID
  161. , const LogTypeEnum eLogType
  162. , const SeverityLevelEnum eLevel
  163. , const DWORD dwSysError, const DWORD dwUserCode
  164. , const DWORD dwEntityInstanceID, const WORD wEntityDevelID
  165. , const CAutoArray<DWORD>& Param
  166. , const char* pszEntityName, const char* pszModuleName, const char* pszMessage)
  167. {
  168. LogEvent(eLevel, 0,
  169. CSimpleStringA::Format("Catched Test Failed Message: [%s][0x%03X][%s] - %s",
  170. pszModuleName, wEntityDevelID, pszEntityName, pszMessage));
  171. switch (eLevel) {
  172. case Severity_High:
  173. RequireTerminalExit();
  174. break;
  175. case Severity_Middle:
  176. break;
  177. default:
  178. break;
  179. }
  180. }
  181. void OnStateChanged(FrameworkStateEnum oldState, FrameworkStateEnum curState, const char* triggerEntity)
  182. {
  183. Dbg("OnStateChanged: from %s to %s trigged by %s",
  184. SpStrFrameworkState(oldState), SpStrFrameworkState(curState), triggerEntity);
  185. if (curState == FrameworkState_Running && _testInfo.isTestMode) {
  186. TestAllRegistedEntity();
  187. }
  188. }
  189. struct TestCallbackResult : public IReleasable
  190. {
  191. TestCallbackResult() :strEntityName(true), op(0) {}
  192. virtual ~TestCallbackResult() {}
  193. CSimpleStringA strEntityName;
  194. int op;
  195. };
  196. /*ICallbackListener*/
  197. void OnAnswer(CSmartPointer<IAsynWaitSp> pAsynWaitSp)
  198. {
  199. CSmartPointer<ICallbackListener> listener;
  200. CSmartPointer<IReleasable> context;
  201. CHECK(pAsynWaitSp->GetCallback(listener, context));
  202. TestCallbackResult* result = static_cast<TestCallbackResult*>(context.GetRawPointer());
  203. CHECK(result != NULL);
  204. const auto ec = pAsynWaitSp->AsyncGetAnswer();
  205. if (result->op == OP_START) {
  206. if (IS_FAILURED(ec)) {
  207. THROW_ERROR("Start %s failed return %s!", result->strEntityName.GetData(), SpStrError(ec));
  208. }
  209. else {
  210. Dbg("Start entity %s succ.", result->strEntityName.GetData());
  211. _arrTestEntities[_dwStartedTestEntities++] = result->strEntityName;
  212. }
  213. }
  214. else if(result->op == OP_TEST) {
  215. if (IS_FAILURED(ec)) {
  216. THROW_ERROR("Test for %s failed return %s!", result->strEntityName.GetData(), SpStrError(ec));
  217. }
  218. Dbg("Test %s succ.", result->strEntityName.GetData());
  219. }
  220. }
  221. private:
  222. void RequireTerminalExit()
  223. {
  224. if (_testInfo.isTestMode) {
  225. Dbg("Test Failed! shutdown the terminal program...");
  226. auto pPriviFunc = GetFunction()->GetPrivilegeFunction();
  227. pPriviFunc->Reboot(RebootTrigger_DeadForever, RebootWay_Framework);
  228. }
  229. }
  230. void SetOPCallback(CSmartPointer<IAsynWaitSp>& spWait, const char* pcszName, int op)
  231. {
  232. TestCallbackResult* result = new TestCallbackResult();
  233. result->strEntityName = pcszName;
  234. result->op = op;
  235. spWait->SetCallback(this, result);
  236. }
  237. ErrorCodeEnum TestEntity(const char* lcpszEntityName)
  238. {
  239. LogEvent(Severity_High, 0, CSimpleStringA::Format("Test specified entity: %s", lcpszEntityName));
  240. auto pPriviFunc = GetFunction()->GetPrivilegeFunction();
  241. CSmartPointer<IAsynWaitSp> waitSp;
  242. auto ec = pPriviFunc->TestEntity(lcpszEntityName, Test_Examine, waitSp);
  243. if (IS_FAILURED(ec)) {
  244. THROW_ERROR("Try to test for %s failed return %s!", lcpszEntityName, SpStrError(ec));
  245. return Error_Failed;
  246. }
  247. SetOPCallback(waitSp, lcpszEntityName, OP_TEST);
  248. return Error_Succeed;
  249. }
  250. private:
  251. TestModeInfo _testInfo;
  252. CUUID m_subUUID;
  253. CAutoArray<CSimpleStringA> _arrTestEntities;
  254. DWORD _dwStartedTestEntities;
  255. };
  256. SP_BEGIN_ENTITY_MAP()
  257. SP_ENTITY(CTestDeamon)
  258. SP_END_ENTITY_MAP()