SATExecutor.cpp 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773
  1. #include "StdAfx.h"
  2. #include "SATExecutor.h"
  3. #include "PythonExecutor.h"
  4. #include "CharEncoding.h"
  5. #include "SynSerial.h"
  6. #include "IRControl.h"
  7. namespace SATEXE{
  8. std::string GetPythonCommandLine(STPyCmd &pycmd)
  9. {
  10. std::string strPyCmd;
  11. cJSON *pRoot = cJSON_CreateObject();
  12. if ( pRoot == NULL ) {
  13. return strPyCmd;
  14. }
  15. //cJSON_AddNumberToObject(pRoot, "Round", pycmd.nRound);
  16. cJSON_AddStringToObject(pRoot, "Round", pycmd.strRound.c_str());
  17. //cJSON_AddStringToObject(pRoot, "TaskId", pycmd.strTaskId.c_str());
  18. cJSON_AddNumberToObject(pRoot, "TaskId", pycmd.nTaskId);
  19. char *pText = cJSON_Print(pRoot);
  20. if ( pText)
  21. strPyCmd = pText;
  22. // 释放堆内存;
  23. if (pText)
  24. delete pText;
  25. pText = NULL;
  26. if ( pRoot )
  27. cJSON_Delete(pRoot);
  28. pRoot = NULL;
  29. return GLOBAL::Replace(strPyCmd, "'", "\"");
  30. }
  31. };
  32. CSATExecutor::CSATExecutor(void)
  33. {
  34. m_bLogin = FALSE;
  35. m_bStopWathTV = FALSE;
  36. m_hEventHearbeat = NULL;
  37. m_hThreadHearbeat = NULL;
  38. m_hEventExcuteScript = NULL;
  39. m_hThreadExcuteScript = NULL;
  40. m_dwSomkingThreadId = 0;
  41. }
  42. CSATExecutor::~CSATExecutor(void)
  43. {
  44. m_bStopWathTV = FALSE;
  45. EndofWork();
  46. }
  47. bool CSATExecutor::IsTaskExist(SATHTTP::STTask &task)
  48. {
  49. // 若是冒烟任务;
  50. #ifdef _DBG_SOMKING_
  51. task.taskInfo.strInstanceType = "4";
  52. #endif
  53. if ( task.taskInfo.strInstanceType == "4" ) {
  54. AutoThreadSection ats(&m_csSomkingTask);
  55. // 如果任务存在,删除原来的;
  56. std::vector<SATHTTP::STTask>::iterator it = m_vtSmokingTask.begin();
  57. for ( ; it != m_vtSmokingTask.end(); it++ ) {
  58. // 不要使用nTaskId,这个值没啥用;//不要使用Id这个值,如果任务被停止会变更;
  59. if ( it->taskInfo.nInstanceId == task.taskInfo.nInstanceId ) {
  60. m_vtSmokingTask.erase(it);
  61. break;
  62. }
  63. }
  64. // 再将任务添加入队列;
  65. if ( _tcsicmp(task.taskInfo.strTaskType.c_str(), "3") != 0 ) {
  66. bool bExsit = false;
  67. AutoThreadSection ats(&m_csTask);
  68. for ( std::vector<SATHTTP::STTask>::iterator it = m_vtTask.begin(); it != m_vtTask.end(); it++ ) {
  69. if ( it->taskInfo.nInstanceId == task.taskInfo.nInstanceId && it->taskInfo._nExecutionState != SATHTTP::EXECUTED )
  70. bExsit = true;
  71. }
  72. // 被中止的任务不入队;
  73. if ( !bExsit )
  74. m_vtSmokingTask.push_back(task);
  75. }
  76. else
  77. {
  78. AutoThreadSection ats(&m_csTask);
  79. std::vector<SATHTTP::STTask>::iterator it = m_vtTask.begin();
  80. for ( ; it != m_vtTask.end(); it++ ) {
  81. // 不要使用nTaskId,这个值没啥用;//不要使用Id这个值,如果任务被停止会变更;
  82. if ( it->taskInfo.nInstanceId == task.taskInfo.nInstanceId ) {
  83. it->taskInfo._nExecutionState = SATHTTP::EXECUTED;
  84. it->taskInfo._nExecutionResult = SATHTTP::FAIL;
  85. break;
  86. }
  87. }
  88. }
  89. return true;
  90. }
  91. // 实时任务;
  92. bool found = false;
  93. AutoThreadSection ats(&m_csTask);
  94. std::vector<SATHTTP::STTask>::iterator it = m_vtTask.begin();
  95. for ( ; it != m_vtTask.end(); it++ ) {
  96. // 不要使用nTaskId,这个值没啥用;//不要使用Id这个值,如果任务被停止会变更;
  97. if ( it->taskInfo.nInstanceId == task.taskInfo.nInstanceId ) {
  98. // 如果被中止,并变更状态为已执行;
  99. if ( _tcsicmp(task.taskInfo.strTaskType.c_str(), "3") == 0 ) {
  100. it->taskInfo._nExecutionState = SATHTTP::EXECUTED;
  101. it->taskInfo._nExecutionResult = SATHTTP::FAIL;
  102. }
  103. found = true;
  104. break;
  105. }
  106. }
  107. return found;
  108. }
  109. void CSATExecutor::DownloadTask(SATHTTP::STTask &task)
  110. {
  111. // 将任务压入队列中;
  112. AutoThreadSection ats(&m_csTask);
  113. // 同时下载任务;
  114. GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, _T("【任务脚本下载】:%s"), task.Job.strUniqueId.c_str());
  115. std::string host = GLOBAL::g_stSATConfig.szCaseServer;
  116. std::string url = host + "/ajaxInteractiveManage!getCaseFileListUrl.action";
  117. std::vector<SATHTTP::STCase>::iterator _case = task.vtCases.begin();
  118. for ( int i = 1; _case != task.vtCases.end(); _case++) {
  119. // 下载脚本;
  120. _case->_nCaseStep = i++;
  121. SATHTTP::STScriptUrlResp stScriptUrlResp;
  122. // 脚本保存路径;
  123. std::string strScriptSaveDir = GLOBAL::g_stSATConfig.szScriptDir;
  124. strScriptSaveDir.append(task.Job.strProjectName+"\\");
  125. strScriptSaveDir.append(task.Job.strUniqueId+"\\");
  126. // 把冒号改成下划线;
  127. strScriptSaveDir.append(GLOBAL::Replace(task.Job.strDeviceId, "_", ":")+"\\");
  128. if ( DownloadScript(url, _case->strId, strScriptSaveDir, stScriptUrlResp) ) {
  129. _case->_strFileDir = stScriptUrlResp._strFileDir;
  130. _case->_strFileName = stScriptUrlResp._strFileName;
  131. _case->_strScriptPath = stScriptUrlResp._strScripFile;
  132. } else {
  133. // 脚本下载失败时,需要标记脚本为已运行且异常;
  134. _case->_nExecutionState = SATHTTP::EXECUTED;
  135. _case->_nExecutionResult = SATHTTP::ABNORMAL;
  136. GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, _T("【下载脚本失败】:%s"), _case->strCaseName.c_str());
  137. }
  138. }
  139. TaskRoundSetting(&task);
  140. m_vtTask.push_back(task);
  141. }
  142. SATHTTP::STTask* CSATExecutor::IsThereATaskInProcess()
  143. {
  144. AutoThreadSection ats(&m_csTask);
  145. std::vector<SATHTTP::STTask>::iterator it = m_vtTask.begin();
  146. for ( ; it != m_vtTask.end(); it++ ) {
  147. // 执行中的任务;
  148. if ( it->taskInfo._nExecutionState == SATHTTP::INEXECUTED ) {
  149. return &(*it);
  150. }
  151. }
  152. return NULL;
  153. }
  154. SATHTTP::STTask* CSATExecutor::GetFreeTask()
  155. {
  156. AutoThreadSection ats(&m_csTask);
  157. std::vector<SATHTTP::STTask>::iterator it = m_vtTask.begin();
  158. for ( ; it != m_vtTask.end(); it++ ) {
  159. // 未执行的任务;
  160. if ( it->taskInfo._nExecutionState == SATHTTP::UNEXECUTED ) {
  161. return &(*it);
  162. }
  163. }
  164. return NULL;
  165. }
  166. void CSATExecutor::DelFinishedTask()
  167. {
  168. AutoThreadSection ats(&m_csTask);
  169. std::vector<SATHTTP::STTask>::iterator it = m_vtTask.begin();
  170. for ( ; it != m_vtTask.end(); it++ ) {
  171. // 状态为2的完成任务;
  172. if ( it->taskInfo._nExecutionState == SATHTTP::EXECUTED ) {
  173. // 删除所有执行器对象;
  174. CPythonExecutor *pExecutor = NULL;
  175. for (std::vector<SATHTTP::STCase>::iterator _case = it->vtCases.begin(); _case != it->vtCases.end(); _case++ ) {
  176. // 一般被停止的任务,才会触发下面的操作;
  177. pExecutor = (CPythonExecutor *)_case->_pExcutor;
  178. if ( pExecutor ) {
  179. // 释放内存;
  180. delete pExecutor;
  181. _case->_pExcutor = pExecutor = NULL;
  182. #ifdef _DEBUG
  183. TRACE2(_T("删除任务成功:%s,%s\n"), it->Job.strTaskId.c_str(), _case->strCaseName.c_str());
  184. #endif
  185. }
  186. }
  187. // 删除任务前,变更设备状态为空闲;
  188. SetDeviceStatus(it->Job.strDeviceId, SATDEV::Idle);
  189. GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, "\n<===============================================>\n"
  190. "end.删除已完成任务:%s\n<===============================================>\n", it->Job.strUniqueId.c_str());
  191. // 删除任务;
  192. if ( m_vtTask.size() > 1 )
  193. m_vtTask.erase(it);
  194. break;
  195. }
  196. }
  197. }
  198. // 返回正在执行的用例对象, 如果没有正在执行的任务返回NULL;
  199. SATHTTP::STCase* CSATExecutor::IsCaseScriptProcess(std::vector<SATHTTP::STCase> &vtCases)
  200. {
  201. std::vector<SATHTTP::STCase>::iterator it = vtCases.begin();
  202. for ( ; it != vtCases.end(); it++) {
  203. // 执行中的脚本;
  204. if ( it->_nExecutionState == SATHTTP::INEXECUTED ) {
  205. return &(*it);
  206. }
  207. }
  208. return NULL;
  209. }
  210. SATHTTP::STCase* CSATExecutor::GetFreeCaseScript(SATHTTP::STTask* pTask)
  211. {
  212. #if 0 // 原获取方式;
  213. std::vector<SATHTTP::STCase>::iterator it = pTask->vtCases.begin();
  214. for ( ; it != vtCases.end(); it++) {
  215. // 未执行的脚本;
  216. if ( it->_nExecutionState == SATHTTP::UNEXECUTED ) {
  217. return &(*it);
  218. }
  219. }
  220. return NULL;
  221. #else
  222. int nCaseIndex = 0;
  223. int nCaseRound = 0;
  224. SATHTTP::STCase *pCase = NULL;
  225. std::vector<SATHTTP::STCase>::iterator it = pTask->vtCases.begin();
  226. for ( ; it != pTask->vtCases.end(); it++) {
  227. // 获取用例索引;
  228. nCaseIndex = _tstol(it->strIndex.c_str());
  229. nCaseRound = _tstol(it->_strRoundNum.c_str());
  230. if ( nCaseRound == pTask->_curRound ) {
  231. if ( nCaseIndex == pTask->_curCaseIndex ) {
  232. // 正常:未执行的脚本;
  233. if ( it->_nExecutionState == SATHTTP::UNEXECUTED ) {
  234. // 是否转到下一轮;
  235. if ( nCaseIndex == pTask->_roundSize ) {
  236. pTask->_curRound++; // 下一轮;
  237. pTask->_curCaseIndex = 1; // 重置为1;
  238. } else
  239. pTask->_curCaseIndex++;
  240. // 返回结果;
  241. pCase = &*it;
  242. // 退出;
  243. break;
  244. }
  245. GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, _T("用例轮空:round=%d, caseIndex=%d"), pTask->_curRound, pTask->_curCaseIndex);
  246. // 是否转到下一轮;
  247. if ( nCaseIndex == pTask->_roundSize ) {
  248. pTask->_curRound++; // 下一轮;
  249. pTask->_curCaseIndex = 1; // 重置为0;
  250. } else
  251. pTask->_curCaseIndex++;
  252. }
  253. }
  254. }
  255. // 容错处理;
  256. if ( pCase == NULL ) {
  257. GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, _T("获取可用用例失败"));
  258. }
  259. return pCase;
  260. #endif
  261. }
  262. SATHTTP::STCase* CSATExecutor::ExecuteFreeCaseScript(SATHTTP::STTask* pTask)
  263. {
  264. // 获取未执行的脚本;
  265. SATHTTP::STCase* pCase = GetFreeCaseScript(pTask);
  266. if (pCase) {
  267. std::string xmlpath = pCase->_strFileDir;
  268. xmlpath.append("detail\\");
  269. xmlpath.append(pCase->_strFileName);
  270. xmlpath.append("_result.xml");
  271. // 删除前面留的文件;
  272. DeleteFile(xmlpath.c_str());
  273. // 命令行:{"Round": %d}
  274. SATEXE::STPyCmd pycmd;
  275. pycmd.strRound = pCase->_strRoundNum;
  276. pycmd.nTaskId = pTask->taskInfo.nInstanceId;
  277. std::string strPyCmd = SATEXE::GetPythonCommandLine(pycmd);
  278. //TCHAR szCommandLine[MAX_PATH] = { 0 };
  279. //_stprintf_s(szCommandLine, _T("{'Round': %s}"), pCase->_strRoundNum.c_str());
  280. if ( !pCase->_pExcutor ) {
  281. CPythonExecutor *pExcutor = new CPythonExecutor();
  282. if ( pExcutor ) {
  283. pCase->_pExcutor = pExcutor;
  284. // 用例的日志文件路径;
  285. pCase->_strCaseLog = pCase->_strFileDir + pCase->_strFileName + _T("_") + pCase->_strRoundNum + ".txt";
  286. if ( pExcutor->InitScript(pCase->_strScriptPath, pCase->_strCaseLog, strPyCmd.c_str()) ) {
  287. // 设置用例对象;
  288. pExcutor->SetCaseObje(pCase);
  289. pExcutor->StartScript();
  290. }
  291. // 标记用例执行中;
  292. pCase->_nExecutionState = SATHTTP::INEXECUTED;
  293. // 标记任务为执行中;
  294. pTask->taskInfo._nExecutionState = SATHTTP::INEXECUTED;
  295. // 记录开始时间;
  296. pCase->_ulStartTickCount = GetTickCount64();
  297. pCase->_strStartTime = CTime::GetCurrentTime().Format(_T("%Y-%m-%d %H:%M:%S"));
  298. GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, "启动脚本(%s)", pCase->strCaseName.c_str());
  299. }
  300. }
  301. else {
  302. GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, "重新初始化脚本(%s)", pCase->strCaseName.c_str());
  303. // 重新初始化脚本;
  304. CPythonExecutor *pExcutor = (CPythonExecutor *)pCase->_pExcutor;
  305. if ( pExcutor->InitScript(pCase->_strScriptPath, pCase->_strCaseLog, strPyCmd.c_str()) ) {
  306. // 设置用例对象;
  307. pExcutor->SetCaseObje(pCase);
  308. pExcutor->StartScript();
  309. // 标记用例执行中;
  310. pCase->_nExecutionState = SATHTTP::INEXECUTED;
  311. }
  312. else { // 如果再次初始化失败,标记脚本失败;
  313. pCase->_nExecutionResult = SATHTTP::FAIL;
  314. }
  315. }
  316. }
  317. return pCase;
  318. }
  319. void CSATExecutor::TaskRoundSetting(SATHTTP::STTask* pTask)
  320. {
  321. if ( pTask == NULL )
  322. return;
  323. // 1轮有多少用例数量;
  324. pTask->_roundSize = pTask->vtCases.size();
  325. // 获取执行轮数;
  326. pTask->_roundCount = _tstol(pTask->Job.strRound.c_str());
  327. if ( pTask->_roundCount > 1 ) {
  328. TCHAR szValue[8] = { 0 };
  329. // 复制一份出来,修改round值,再添加给任务;
  330. std::vector<SATHTTP::STCase> vtOrgCase = pTask->vtCases;
  331. for ( int i = 2; i <= pTask->_roundCount; i++ ) {
  332. _itoa_s(i, szValue, 10);
  333. std::vector<SATHTTP::STCase> vtCase = vtOrgCase;
  334. for ( std::vector<SATHTTP::STCase>::iterator it = vtCase.begin(); it != vtCase.end(); it++ ) {
  335. it->_strRoundNum = szValue;
  336. pTask->vtCases.push_back(*it);
  337. }
  338. }
  339. }
  340. }
  341. void CSATExecutor::AddDevices(const SATDEV::STDevice &stDevice)
  342. {
  343. if ( IsDeviceExist(stDevice.strName) )
  344. return;
  345. SATHTTP::STDevice http_dev;
  346. // 设备使用状态;
  347. if ( stDevice.nUsageState == SATDEV::Idle )
  348. http_dev.strStatus = "0";
  349. else if ( stDevice.nUsageState == SATDEV::InUse )
  350. http_dev.strStatus = "2"; // 注意避坑:0表示连接,即设备空闲;1表示设备断开;2表示设备繁忙
  351. // 设备序列号;
  352. http_dev.strDeviceSerial = stDevice.strName;
  353. // 余下变量固定值;
  354. http_dev.strComments = "";
  355. http_dev.strCPU = "";
  356. http_dev.strDeviceMac = "";
  357. http_dev.strElectric = "";
  358. http_dev.strHardwareVersion = "SAT-HV";
  359. http_dev.strLastJob = "";
  360. http_dev.strLastJobFinishTime = "";
  361. http_dev.strLastJobStartTime = "";
  362. http_dev.strLastTimeBreak = "";
  363. http_dev.strLastTimeConnected = "";
  364. http_dev.strManu = "";
  365. http_dev.strMemory = "";
  366. http_dev.strModel = "SATModel";
  367. http_dev.strPhoneNumber = "";
  368. http_dev.strSoftwareVersion = "0123456789";
  369. m_vtDevice.push_back(http_dev);
  370. }
  371. void CSATExecutor::DelDevices(const SATDEV::STDevice &stDevice)
  372. {
  373. std::vector<SATHTTP::STDevice>::iterator it = m_vtDevice.begin();
  374. for ( ; it != m_vtDevice.end(); it++ ) {
  375. if ( _tcsicmp(it->strDeviceSerial.c_str(), stDevice.strName.c_str()) == 0 ) {
  376. m_vtDevice.erase(it);
  377. break;
  378. }
  379. }
  380. }
  381. void CSATExecutor::SetDeviceStatus(std::string strDevName, SATDEV::DEVICE_USAGE_STATUS status)
  382. {
  383. std::vector<SATHTTP::STDevice>::iterator it = m_vtDevice.begin();
  384. for ( ; it != m_vtDevice.end(); it++ ) {
  385. if ( _tcsicmp(it->strDeviceSerial.c_str(), strDevName.c_str()) == 0 ) {
  386. if ( status == SATDEV::Idle )
  387. it->strStatus = "0";
  388. else if ( status == SATDEV::InUse )
  389. it->strStatus = "2"; // 注意避坑:0表示连接,即设备空闲;1表示设备断开;2表示设备繁忙
  390. break;
  391. }
  392. }
  393. // 同时,同步SATDevices的设备状态;
  394. CSATDevices::SetDeviceUsageStatus(strDevName, status);
  395. }
  396. bool CSATExecutor::IsDeviceExist(std::string strDevName)
  397. {
  398. bool bExist = false;
  399. std::vector<SATHTTP::STDevice>::iterator it = m_vtDevice.begin();
  400. for ( ; it != m_vtDevice.end(); it++ ) {
  401. if ( _tcsicmp(it->strDeviceSerial.c_str(), strDevName.c_str()) == 0 ) {
  402. bExist = true;
  403. break;
  404. }
  405. }
  406. return bExist;
  407. }
  408. bool CSATExecutor::Login(bool bLogin /* = true */)
  409. {
  410. std::string url = GLOBAL::g_stSATConfig.szExecuteServer;
  411. url.append("/ajaxInteractiveManage!executeLogin.action");
  412. // 填充数据;
  413. m_stLoginReq.strStatus = bLogin ? "0" : "1"; // 0表示登录;
  414. m_stLoginReq.strDeleteStatus = "";
  415. m_stLoginReq.strIP = GLOBAL::GetLocalAddress();// GLOBAL::g_strIPAddress;
  416. m_stLoginReq.strStorage = "";
  417. if ( bLogin ) {
  418. m_stLoginReq.strDisconnectTime = "";
  419. m_stLoginReq.strConnectTime = CTime::GetCurrentTime().Format(_T("%Y-%m-%d %H:%M:%S"));
  420. } else {
  421. m_stLoginReq.strConnectTime = "";
  422. m_stLoginReq.strDisconnectTime = CTime::GetCurrentTime().Format(_T("%Y-%m-%d %H:%M:%S"));
  423. }
  424. // 执行器PC物理地址;
  425. m_stLoginReq.strMAC = GLOBAL::g_strMacs;
  426. m_stLoginReq.strCPU = "";
  427. if ( ::Login(url, m_stLoginReq, m_stLoginResp) ) {
  428. GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, "登录成功");
  429. m_bLogin = TRUE;
  430. return true;
  431. }
  432. GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, "登录失败");
  433. return false;
  434. }
  435. bool CSATExecutor::Login(std::string user, std::string password, std::string actuator, bool bLogin /*= true*/)
  436. {
  437. // 填充数据;
  438. m_stLoginReq.strUserName = user;
  439. m_stLoginReq.strPassword = password;
  440. // 执行器名称;
  441. m_stLoginReq.strExecuteName = m_strActuatorName = actuator;
  442. return Login(bLogin);
  443. }
  444. bool CSATExecutor::Logout(std::string user, std::string password)
  445. {
  446. return Login(user, password, m_strActuatorName, false);
  447. }
  448. bool CSATExecutor::UpdateDevice()
  449. {
  450. SATHTTP::STUpdateDeviceReq stUpdateDeviceReq;
  451. SATHTTP::STUpdateDeviceResp stUpdateDeviceResp;
  452. std::string url = GLOBAL::g_stSATConfig.szExecuteServer;
  453. url.append("/ajaxInteractiveManage!updateDeviceMessage.action");
  454. // 这个状态值要怎么设置?// 此处统一为0;
  455. stUpdateDeviceReq.strStatus = "0";
  456. stUpdateDeviceReq.strUserName = m_stLoginReq.strUserName;
  457. stUpdateDeviceReq.strIP = GLOBAL::g_strIPAddress;
  458. stUpdateDeviceReq.strStorage = "";
  459. stUpdateDeviceReq.strRunnerName = m_strActuatorName;
  460. // 这里使用PC物理地址;
  461. stUpdateDeviceReq.strMAC = GLOBAL::g_strMacs;
  462. // 这个reportType具体意义不明;
  463. stUpdateDeviceReq.strReportType = "1";
  464. stUpdateDeviceReq.strStartTime = CTime::GetCurrentTime().Format(_T("%Y-%m-%d %H:%M:%S"));
  465. stUpdateDeviceReq.strMemory = "";
  466. stUpdateDeviceReq.strEndTime = "";
  467. stUpdateDeviceReq.strCPU = "";
  468. stUpdateDeviceReq.devicelist.assign(m_vtDevice.begin(), m_vtDevice.end());
  469. if ( !::UpdateDeviceMessage(url, stUpdateDeviceReq, stUpdateDeviceResp) ) {
  470. GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, "更新设备信息失败");
  471. return false;
  472. }
  473. return true;
  474. }
  475. bool CSATExecutor::NotifyTaskStart(SATHTTP::STTask* pTask)
  476. {
  477. if ( !pTask )
  478. return false;
  479. SATHTTP::STNotifyJobStartReq stNotifyJobStartReq;
  480. SATHTTP::STNotifyJobStartResp stNotifyJobStartResp;
  481. std::string url = GLOBAL::g_stSATConfig.szExecuteServer;
  482. url.append("/ajaxInteractiveManage!setResult.action");
  483. TCHAR szValue[36] = {0};
  484. _itoa_s(pTask->taskInfo.nDeviceId, szValue, 10);
  485. stNotifyJobStartReq.strDeviceId = szValue;
  486. _itoa_s(pTask->taskInfo.nExecuteId, szValue, 10);
  487. stNotifyJobStartReq.strExecuteId = szValue;
  488. // _itoa_s(stTask.taskInfo.nInstanceId, szValue, 10); // 误导:应该使用id而不是nInstanceId
  489. _itoa_s(pTask->taskInfo.Id, szValue, 10);
  490. stNotifyJobStartReq.strInstanceId = szValue;
  491. //_itoa_s(pTask->nTaskId, szValue, 10);
  492. if ( pTask->taskInfo.strInstanceType == "4" ) {
  493. _itoa_s(pTask->taskInfo.nInstanceId, szValue, 10);
  494. stNotifyJobStartReq.strTaskId = szValue;
  495. }
  496. else
  497. stNotifyJobStartReq.strTaskId = pTask->Job.strTaskId;
  498. stNotifyJobStartReq.strTaskType = pTask->taskInfo.strInstanceType;
  499. // 这个映像路径有何用?
  500. stNotifyJobStartReq.strSignalImageUrl = GLOBAL::g_stSATConfig.szScriptDir;
  501. stNotifyJobStartReq.strSignalImageUrl.append(pTask->taskInfo.strTaskName+"\\\\");
  502. stNotifyJobStartReq.strSignalImageUrl.append(pTask->Job.strUniqueId+"\\\\");
  503. stNotifyJobStartReq.strSignalImageUrl.append(pTask->Job.strDeviceId);
  504. stNotifyJobStartReq.strSignalImageUrl = CharEncoding::ASCII2UTF8(stNotifyJobStartReq.strSignalImageUrl.c_str());
  505. if ( SetResult(url, stNotifyJobStartReq, stNotifyJobStartResp) ) {
  506. GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, "更新任务状态成功:%s", pTask->Job.strUniqueId.c_str());
  507. return true;
  508. }
  509. GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, "更新任务状态失败:%s", pTask->Job.strUniqueId.c_str());
  510. return false;
  511. }
  512. bool CSATExecutor::UploadCaseImg(SATHTTP::STTask* pTask, SATHTTP::STCase *pCase, std::string img)
  513. {
  514. TCHAR szValue[MAX_PATH] = {0};
  515. std::string url = GLOBAL::g_stSATConfig.szExecuteServer;
  516. url.append("/ajaxInteractiveManage!saveResultImg.action");
  517. SATHTTP::STSaveImgReq stSaveImgReq;
  518. SATHTTP::STSaveImgResp stSaveImgResp;
  519. stSaveImgReq.strCaseId = pCase->strId;
  520. stSaveImgReq.strCaseRepeat = "0";
  521. _itoa_s(pCase->_nCaseStep, szValue, 10);
  522. stSaveImgReq.strCaseStep = szValue;
  523. // 实例Id;
  524. _itoa_s(pTask->taskInfo.nDeviceId, szValue, 10);
  525. stSaveImgReq.strDeviceId = szValue;//pTask->Job.strDeviceId;
  526. // 就是Task中的ExecuteId
  527. _itoa_s(pTask->taskInfo.nExecuteId, szValue, 10);
  528. stSaveImgReq.strExecuteId = szValue;
  529. // 实例Id;
  530. _itoa_s(pTask->taskInfo.nInstanceId, szValue, 10);
  531. stSaveImgReq.strInstanceId = szValue;
  532. stSaveImgReq.strJobRepeat = "0";
  533. // 注意避坑:roundnum必须赋值0或1;
  534. stSaveImgReq.strRoundNum = pCase->_strRoundNum;
  535. stSaveImgReq.strImgType = "";
  536. stSaveImgReq.strUploads = img;
  537. // 上传用例图片;
  538. if ( SaveResultImg(url, stSaveImgReq, stSaveImgResp) ) {
  539. GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, "上传图片成功:任务=%s, 用例=%s, 图片=%s", pTask->Job.strUniqueId.c_str(), pCase->strCaseName.c_str(), img.c_str());
  540. return true;
  541. }
  542. GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, "上传图片失败:任务=%s, 用例=%s, 图片=%s", pTask->Job.strUniqueId.c_str(), pCase->strCaseName.c_str(), img.c_str());
  543. return false;
  544. }
  545. bool CSATExecutor::UploadCaseLog(SATHTTP::STTask* pTask, SATHTTP::STCase *pCase)
  546. {
  547. TCHAR szValue[MAX_PATH] = {0};
  548. std::string url = GLOBAL::g_stSATConfig.szExecuteServer;
  549. url.append("/ajaxInteractiveManage!saveCaseOrTaskLog.action");
  550. SATHTTP::STSaveLogReq stSaveLogReq;
  551. SATHTTP::STSaveLogResp stSaveLogResp;
  552. stSaveLogReq.strCaseId = pCase->strId;
  553. // 执行ID;
  554. _itoa_s(pTask->taskInfo.nExecuteId, szValue, 10);
  555. stSaveLogReq.strExecuteId = szValue;
  556. stSaveLogReq.strFileType = "caseLogFile";
  557. // 任务Id;
  558. //_itoa_s(pTask->nTaskId, szValue, 10);
  559. stSaveLogReq.strTaskId = pTask->Job.strTaskInstanceId;
  560. stSaveLogReq.strUserId = pTask->Job.strUserId;
  561. // 第几轮日志;
  562. stSaveLogReq.strRoundNum = pCase->_strRoundNum;
  563. // 要上传的日志文件;
  564. stSaveLogReq.strUploads = pCase->_strCaseLog;
  565. if ( SaveCaseOrTaskLog(url, stSaveLogReq, stSaveLogResp) ) {
  566. GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, "上传日志成功:任务=%s, 用例=%s, 日志=%s", pTask->Job.strUniqueId.c_str(), pCase->strCaseName.c_str(), pCase->_strCaseLog.c_str());
  567. return true;
  568. }
  569. GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, "上传日志失败:任务=%s, 用例=%s, 日志=%s", pTask->Job.strUniqueId.c_str(), pCase->strCaseName.c_str(), pCase->_strCaseLog.c_str());
  570. return false;
  571. }
  572. bool CSATExecutor::ReportCaseItemFinish(SATHTTP::STTask* pTask, SATHTTP::STCase *pCase, STCaseItem &caseItem)
  573. {
  574. TCHAR szValue[MAX_PATH] = {0};
  575. std::string url = GLOBAL::g_stSATConfig.szExecuteServer;
  576. url.append("/ajaxInteractiveManage!setResultList.action");
  577. SATHTTP::STJobProcessReq stJobProcessReq;
  578. SATHTTP::STJobProcessResp stJobProcessResp;
  579. // 0 表示测试项Pass, 1 表示测试项Fail;
  580. stJobProcessReq.strResultState = caseItem.result ? "0" : "1";
  581. // 如果测试项失败,标记用例和任务失败;
  582. if ( !caseItem.result ) {
  583. pCase->_nExecutionResult = SATHTTP::FAIL;
  584. pTask->taskInfo._nExecutionResult = SATHTTP::FAIL;
  585. }
  586. stJobProcessReq.strCaseScene = "";
  587. // 索引;
  588. _itoa_s(pCase->_nCaseStep, szValue, 10);
  589. stJobProcessReq.strCaseStep = szValue;
  590. stJobProcessReq.strApkMD5 = "";
  591. stJobProcessReq.strCrashTime = "";
  592. // 就是Task中的ExecuteId
  593. _itoa_s(pTask->taskInfo.nExecuteId, szValue, 10);
  594. stJobProcessReq.strRunnerId = szValue;
  595. stJobProcessReq.strCPUInfo = "0";
  596. stJobProcessReq.strRunnedActionNameList = "";
  597. stJobProcessReq.strArtificialResult = "";
  598. stJobProcessReq.strArtificialModify = "";
  599. stJobProcessReq.strRunnerName = "";
  600. stJobProcessReq.strTaskType = "FUNCTIONALITY";
  601. stJobProcessReq.strCaseRepeat = "0";
  602. stJobProcessReq.strApplicationGroup = "";
  603. // 实例Id;
  604. _itoa_s(pTask->taskInfo.Id, szValue, 10);
  605. stJobProcessReq.strInstanceId = szValue;
  606. stJobProcessReq.strCaseId = pCase->strId;
  607. // 进度;
  608. _itoa_s(100*(atoi(pCase->strIndex.c_str()))/pTask->vtCases.size(), szValue, 10);
  609. stJobProcessReq.strProgress = szValue;
  610. // 需要将utf-8转gbk;
  611. stJobProcessReq.strReusltMessage = caseItem.name;//CharEncoding::UTF82ASCII(caseItem.name.c_str());
  612. stJobProcessReq.strJobRepeat = "0";
  613. stJobProcessReq.strScreenShot = "";
  614. stJobProcessReq.strStartTime = pCase->_strStartTime;
  615. stJobProcessReq.strCrashNumber = "";
  616. stJobProcessReq.strCaseName = pCase->strCaseName;
  617. //stJobProcessReq.strFailedReason = CharEncoding::UTF82ASCII(caseItem.remark.c_str());
  618. //stJobProcessReq.strFailedReason = (char*)CharEncoding::UTF82UNICODE(caseItem.remark.c_str());
  619. stJobProcessReq.strFailedReason = caseItem.remark;
  620. for (std::vector<std::string>::iterator it = caseItem.imgs.begin(); it != caseItem.imgs.end(); it++ ) {
  621. int npos = it->find_last_of('/');
  622. if ( std::string::npos != npos ) {
  623. stJobProcessReq.strImgName.append(it->substr(npos+1));
  624. stJobProcessReq.strImgName.append("&");
  625. }
  626. }
  627. if ( stJobProcessReq.strImgName.size() && stJobProcessReq.strImgName.at(stJobProcessReq.strImgName.size()-1) == '&')
  628. stJobProcessReq.strImgName.erase(stJobProcessReq.strImgName.size()-1);
  629. stJobProcessReq.strCaseIndex = pCase->strIndex;
  630. // 实例Id;
  631. _itoa_s(pTask->taskInfo.nDeviceId, szValue, 10);
  632. stJobProcessReq.strDeviceId = szValue;
  633. stJobProcessReq.strSceneIndex = "0";
  634. // 实例Id;
  635. //_itoa_s(pTask->nTaskId, szValue, 10);
  636. if ( pTask->taskInfo.strInstanceType == "4") {
  637. _itoa_s(pTask->taskInfo.nInstanceId, szValue, 10);
  638. stJobProcessReq.strTaskId = szValue;
  639. }
  640. else
  641. stJobProcessReq.strTaskId = pTask->Job.strTaskId;
  642. stJobProcessReq.strInstanceType = pTask->taskInfo.strInstanceType;
  643. //stJobProcessReq.strAnalysis = CharEncoding::UTF82ASCII(caseItem.data.c_str());
  644. stJobProcessReq.strAnalysis = caseItem.data.c_str();
  645. // 设备名称:即DeviceSerial;
  646. stJobProcessReq.strDevnceName = pTask->Job.strDeviceId; // 命名及其不范围,一会deviceid是deviceserial,一会是id;
  647. // 固定为:TOTAL
  648. stJobProcessReq.strInfoType = "";
  649. // 如果是Android设备,需要通过adb获取;
  650. //stJobProcessReq.strMemoryInfo = stDevice.strMemory;
  651. stJobProcessReq.strEndTime = CTime::GetCurrentTime().Format(_T("%Y-%m-%d %H:%M:%S"));//"2019-12-16 10:18:20";
  652. stJobProcessReq.strRoundNumber = pCase->_strRoundNum;
  653. stJobProcessReq.strResultType = "4"; // reportActionFinish;
  654. stJobProcessReq.strOperationStep = "";
  655. if ( SetResultList(url, stJobProcessReq, stJobProcessResp) ) {
  656. GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, "上传【用例测试项】结果完成【成功】:任务=%s, 用例=%s", pTask->Job.strUniqueId.c_str(), pCase->strCaseName.c_str());
  657. // 再上传图片;
  658. std::string img;
  659. for (std::vector<std::string>::iterator it = caseItem.imgs.begin(); it != caseItem.imgs.end(); it++ ) {
  660. // 使用脚本路径;
  661. img = pCase->_strFileDir;
  662. img.append(it->substr(3));
  663. img = GLOBAL::Replace(img, "/", "\\");
  664. GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, "图片路径=%s", img.c_str());
  665. UploadCaseImg(pTask, pCase, img);
  666. }
  667. return true;
  668. }
  669. GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, "上传【用例测试项】结果完成【失败】:任务=%s, 用例=%s", pTask->Job.strUniqueId.c_str(), pCase->strCaseName.c_str());
  670. return false;
  671. }
  672. bool CSATExecutor::ReportCaseFinish(SATHTTP::STTask* pTask, SATHTTP::STCase *pCase, std::string strRunnedActionNameList)
  673. {
  674. TCHAR szValue[MAX_PATH] = {0};
  675. std::string url = GLOBAL::g_stSATConfig.szExecuteServer;
  676. url.append("/ajaxInteractiveManage!setResultList.action");
  677. SATHTTP::STJobProcessReq stJobProcessReq;
  678. SATHTTP::STJobProcessResp stJobProcessResp;
  679. // 上报用例结果:0表示脚本成功执行, 1表示脚本出错或超时;
  680. if ( pCase->_nExecutionState == SATHTTP::EXECUTED ) {
  681. if ( pCase->_nExecutionResult == SATHTTP::SUCCESS ) {
  682. stJobProcessReq.strResultState = "0";
  683. stJobProcessReq.strFailedReason = CharEncoding::ASCII2UTF8("脚本执行成功");
  684. }
  685. else {
  686. if ( pCase->_nExecutionResult == SATHTTP::ABNORMAL )
  687. stJobProcessReq.strFailedReason = CharEncoding::ASCII2UTF8("脚本执行异常");
  688. else
  689. stJobProcessReq.strFailedReason = CharEncoding::ASCII2UTF8("脚本执行失败");
  690. stJobProcessReq.strResultState = "1";
  691. // 同时标记任务失败;
  692. pTask->taskInfo._nExecutionResult = SATHTTP::FAIL;
  693. }
  694. }
  695. else {
  696. stJobProcessReq.strResultState = "1"; // 脚本执行未完成,认为fail;
  697. // 同时标记任务失败;
  698. pTask->taskInfo._nExecutionResult = SATHTTP::FAIL;
  699. stJobProcessReq.strFailedReason = CharEncoding::ASCII2UTF8("脚本未执行");
  700. }
  701. stJobProcessReq.strCaseScene = "";
  702. // 索引;
  703. _itoa_s(pCase->_nCaseStep, szValue, 10);
  704. stJobProcessReq.strCaseStep = szValue;
  705. stJobProcessReq.strApkMD5 = "";
  706. stJobProcessReq.strCrashTime = "";
  707. // 就是Task中的ExecuteId
  708. _itoa_s(pTask->taskInfo.nExecuteId, szValue, 10);
  709. stJobProcessReq.strRunnerId = szValue;
  710. stJobProcessReq.strCPUInfo = "0";
  711. stJobProcessReq.strRunnedActionNameList = strRunnedActionNameList;
  712. stJobProcessReq.strArtificialResult = "";
  713. stJobProcessReq.strArtificialModify = "";
  714. stJobProcessReq.strRunnerName = "";
  715. stJobProcessReq.strTaskType = "FUNCTIONALITY";
  716. stJobProcessReq.strCaseRepeat = "";
  717. stJobProcessReq.strApplicationGroup = "";
  718. // 实例Id;注意避坑;
  719. _itoa_s(pTask->taskInfo.Id, szValue, 10);
  720. stJobProcessReq.strInstanceId = szValue;
  721. stJobProcessReq.strCaseId = pCase->strId;
  722. // 进度(###需要修改此处###);
  723. _itoa_s(100*(atoi(pCase->strIndex.c_str()))/pTask->vtCases.size(), szValue, 10);
  724. stJobProcessReq.strProgress = szValue;
  725. // 需要将utf-8转gbk;
  726. stJobProcessReq.strReusltMessage = CharEncoding::ASCII2UTF8("测试用例结果:");
  727. stJobProcessReq.strJobRepeat = "";
  728. stJobProcessReq.strScreenShot = "";
  729. stJobProcessReq.strStartTime = pCase->_strStartTime;
  730. stJobProcessReq.strCrashNumber = "";
  731. stJobProcessReq.strCaseName = pCase->strCaseName;
  732. stJobProcessReq.strImgName = "";
  733. stJobProcessReq.strCaseIndex = pCase->strIndex;
  734. // 实例Id;
  735. _itoa_s(pTask->taskInfo.nDeviceId, szValue, 10);
  736. stJobProcessReq.strDeviceId = szValue;
  737. stJobProcessReq.strSceneIndex = "0";
  738. // 实例Id;
  739. //_itoa_s(pTask->nTaskId, szValue, 10);
  740. if ( pTask->taskInfo.strInstanceType == "4") {
  741. _itoa_s(pTask->taskInfo.nInstanceId, szValue, 10);
  742. stJobProcessReq.strTaskId = szValue;
  743. }
  744. else
  745. stJobProcessReq.strTaskId = pTask->Job.strTaskId;
  746. stJobProcessReq.strInstanceType = pTask->taskInfo.strInstanceType;
  747. stJobProcessReq.strAnalysis = "";
  748. // 设备名称:即DeviceSerial;
  749. stJobProcessReq.strDevnceName = pTask->Job.strDeviceId; // 命名极其不范围,一会deviceid是deviceserial,一会是id;
  750. // 固定为:TOTAL
  751. stJobProcessReq.strInfoType = "TOTAL";
  752. // 如果是Android设备,需要通过adb获取;
  753. //stJobProcessReq.strMemoryInfo = stDevice.strMemory;
  754. stJobProcessReq.strEndTime = pCase->_strEndTime;//CTime::GetCurrentTime().Format(_T("%Y-%m-%d %H:%M:%S"));//"2019-12-16 10:18:20";
  755. stJobProcessReq.strRoundNumber = pCase->_strRoundNum;
  756. stJobProcessReq.strResultType = "5"; // reportCaseFinish;
  757. stJobProcessReq.strOperationStep = "";
  758. if ( SetResultList(url, stJobProcessReq, stJobProcessResp) ) {
  759. GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, "上传用例结果完成【成功】:任务=%s, 用例=%s", pTask->Job.strUniqueId.c_str(), pCase->strCaseName.c_str());
  760. return true;
  761. }
  762. GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, "上传用例结果完成【失败】:任务=%s, 用例=%s", pTask->Job.strUniqueId.c_str(), pCase->strCaseName.c_str());
  763. return false;
  764. }
  765. bool CSATExecutor::ReportCaseResult(SATHTTP::STTask* pTask, SATHTTP::STCase *pCase)
  766. {
  767. // 获取xml文件内容;
  768. std::string xmlpath = pCase->_strFileDir;
  769. xmlpath.append("detail\\");
  770. xmlpath.append(pCase->_strFileName + _T("_"));
  771. xmlpath.append(pCase->_strRoundNum);
  772. #if 0
  773. // 文件名加下PID做为后缀;
  774. if ( pCase->__dwPythonPID > 0)
  775. {
  776. TCHAR szPID[16] = "_";
  777. _ltoa_s(pCase->__dwPythonPID, &szPID[1], 15, 10);
  778. xmlpath.append(szPID);
  779. }
  780. #endif
  781. xmlpath.append("_result.xml");
  782. std::vector<STCaseItem> vtCaseItem;
  783. if ( GetCaseXMLResult(xmlpath, vtCaseItem) )
  784. pCase->_nExecutionResult = SATHTTP::SUCCESS;
  785. // 如果测试项空,任务失败;
  786. if ( vtCaseItem.size() == 0 ) {
  787. // 将默认成功值改为异常;
  788. if ( pCase->_nExecutionResult == SATHTTP::SUCCESS )
  789. pCase->_nExecutionResult = SATHTTP::ABNORMAL;
  790. // 同时标记任务失败;
  791. pTask->taskInfo._nExecutionResult = SATHTTP::FAIL;
  792. GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, _T("测试项空,用例名:%s"), pCase->strCaseName.c_str());
  793. }
  794. // 遍历所有用例测试项;
  795. std::string strRunnedActionNameList;
  796. std::vector<STCaseItem>::iterator it = vtCaseItem.begin();
  797. for (; it != vtCaseItem.end();) {
  798. // 上报测试项结果(包含相片);
  799. ReportCaseItemFinish(pTask, pCase, *it);
  800. strRunnedActionNameList.append(it->name);
  801. if ( ++it != vtCaseItem.end() )
  802. strRunnedActionNameList.append("&");
  803. }
  804. // 上报用例完成;
  805. ReportCaseFinish(pTask, pCase, strRunnedActionNameList);
  806. // 上传用例日志;
  807. UploadCaseLog(pTask, pCase);
  808. // 删除执行对象;
  809. if ( pCase->_pExcutor )
  810. delete pCase->_pExcutor;
  811. pCase->_pExcutor = NULL;
  812. GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, _T("用例已完成,执行器对象删除成功,脚本用例名为=%s"), pCase->strCaseName.c_str());
  813. return true;
  814. }
  815. bool CSATExecutor::UploadTaskLog(SATHTTP::STTask* pTask)
  816. {
  817. TCHAR szValue[MAX_PATH] = {0};
  818. std::string url = GLOBAL::g_stSATConfig.szExecuteServer;
  819. url.append("/ajaxInteractiveManage!saveCaseOrTaskLog.action");
  820. SATHTTP::STSaveLogReq stSaveLogReq;
  821. SATHTTP::STSaveLogResp stSaveLogResp;
  822. stSaveLogReq.strCaseId = "";
  823. // 执行ID;
  824. _itoa_s(pTask->taskInfo.nExecuteId, szValue, 10);
  825. stSaveLogReq.strExecuteId = szValue;
  826. stSaveLogReq.strFileType = "taskLogFile";
  827. // 任务Id;
  828. //_itoa_s(pTask->nTaskId, szValue, 10);
  829. stSaveLogReq.strTaskId = pTask->Job.strTaskInstanceId;
  830. stSaveLogReq.strUserId = pTask->Job.strUserId;
  831. // 要上传的日志文件;
  832. stSaveLogReq.strUploads = "D:\\sat\\log.txt";//pTask->_strTaskLog;
  833. if ( SaveCaseOrTaskLog(url, stSaveLogReq, stSaveLogResp) ) {
  834. GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, _T("任务已完成,上传任务日志【成功】,任务编号为=%s"), pTask->Job.strUniqueId.c_str());
  835. return true;
  836. }
  837. GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, _T("任务已完成,上传任务日志【失败】,任务编号为=%s"), pTask->Job.strUniqueId.c_str());
  838. return false;
  839. }
  840. bool CSATExecutor::ReportTaskStart(SATHTTP::STTask* pTask)
  841. {
  842. TCHAR szValue[MAX_PATH] = {0};
  843. std::string url = GLOBAL::g_stSATConfig.szExecuteServer;
  844. url.append("/ajaxInteractiveManage!setResultList.action");
  845. SATHTTP::STJobProcessReq stJobProcessReq;
  846. SATHTTP::STJobProcessResp stJobProcessResp;
  847. // 需要处理###
  848. stJobProcessReq.strResultState = ""; // 脚本执行中,认为fail;
  849. stJobProcessReq.strCaseScene = "";
  850. // 索引;
  851. stJobProcessReq.strCaseStep = "0";
  852. stJobProcessReq.strApkMD5 = "";
  853. stJobProcessReq.strCrashTime = "";
  854. // 就是Task中的ExecuteId
  855. _itoa_s(pTask->taskInfo.nExecuteId, szValue, 10);
  856. stJobProcessReq.strRunnerId = szValue;
  857. stJobProcessReq.strCPUInfo = "0";
  858. stJobProcessReq.strRunnedActionNameList = "";
  859. stJobProcessReq.strArtificialResult = "";
  860. stJobProcessReq.strArtificialModify = "";
  861. stJobProcessReq.strRunnerName = "";
  862. stJobProcessReq.strTaskType = "FUNCTIONALITY";
  863. stJobProcessReq.strCaseRepeat = "";
  864. stJobProcessReq.strApplicationGroup = "";
  865. // 实例Id;注意避坑;
  866. _itoa_s(pTask->taskInfo.Id, szValue, 10);
  867. stJobProcessReq.strInstanceId = szValue;
  868. stJobProcessReq.strCaseId = "";
  869. // 进度(###需要修改此处###);
  870. stJobProcessReq.strProgress = "0";
  871. // 需要将utf-8转gbk;
  872. stJobProcessReq.strReusltMessage = CharEncoding::ASCII2UTF8("任务开始");
  873. stJobProcessReq.strJobRepeat = "";
  874. stJobProcessReq.strScreenShot = "";
  875. stJobProcessReq.strStartTime = pTask->taskInfo.strStartTime;
  876. stJobProcessReq.strCrashNumber = "";
  877. stJobProcessReq.strCaseName = "";
  878. stJobProcessReq.strFailedReason = "";
  879. stJobProcessReq.strImgName = "";
  880. stJobProcessReq.strCaseIndex = "";
  881. // 实例Id;
  882. _itoa_s(pTask->taskInfo.nDeviceId, szValue, 10);
  883. stJobProcessReq.strDeviceId = szValue;
  884. stJobProcessReq.strSceneIndex = "";
  885. // 实例Id;
  886. //_itoa_s(pTask->nTaskId, szValue, 10);
  887. if ( pTask->taskInfo.strInstanceType == "4") {
  888. _itoa_s(pTask->taskInfo.nInstanceId, szValue, 10);
  889. stJobProcessReq.strTaskId = szValue;
  890. }
  891. else
  892. stJobProcessReq.strTaskId = pTask->Job.strTaskId;
  893. stJobProcessReq.strInstanceType = pTask->taskInfo.strInstanceType;
  894. stJobProcessReq.strAnalysis = "";
  895. // 设备名称:即DeviceSerial;
  896. stJobProcessReq.strDevnceName = pTask->Job.strDeviceId; // 命名及其不范围,一会deviceid是deviceserial,一会是id;
  897. // 固定为:TOTAL
  898. stJobProcessReq.strInfoType = "TOTAL";
  899. // 如果是Android设备,需要通过adb获取;
  900. //stJobProcessReq.strMemoryInfo = stDevice.strMemory;
  901. stJobProcessReq.strEndTime = "";// CTime::GetCurrentTime().Format(_T("%Y-%m-%d %H:%M:%S"));//"2019-12-16 10:18:20";
  902. stJobProcessReq.strRoundNumber = "1";
  903. stJobProcessReq.strResultType = "0"; // reportJobStart;
  904. stJobProcessReq.strOperationStep = "";
  905. if ( SetResultList(url, stJobProcessReq, stJobProcessResp) ) {
  906. GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, _T("上报任务开始【成功】,任务编号为=%s"), pTask->Job.strUniqueId.c_str());
  907. return true;
  908. }
  909. GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, _T("上报任务开始【失败】,任务编号为=%s"), pTask->Job.strUniqueId.c_str());
  910. return false;
  911. }
  912. bool CSATExecutor::ReportTaskFinish(SATHTTP::STTask* pTask)
  913. {
  914. TCHAR szValue[MAX_PATH] = {0};
  915. std::string url = GLOBAL::g_stSATConfig.szExecuteServer;
  916. url.append("/ajaxInteractiveManage!setResultList.action");
  917. SATHTTP::STJobProcessReq stJobProcessReq;
  918. SATHTTP::STJobProcessResp stJobProcessResp;
  919. // 需要处理(只要有用例失败,任务就失败)
  920. if ( pTask->taskInfo._nExecutionState == SATHTTP::EXECUTED ) {
  921. if ( pTask->taskInfo._nExecutionResult == SATHTTP::SUCCESS )
  922. stJobProcessReq.strResultState = "0"; // 脚本成功;
  923. else
  924. stJobProcessReq.strResultState = "1"; // 脚本失败;
  925. }
  926. else
  927. stJobProcessReq.strResultState = "1"; // 脚本失败;
  928. stJobProcessReq.strCaseScene = "";
  929. // 索引;
  930. stJobProcessReq.strCaseStep = "0";
  931. stJobProcessReq.strApkMD5 = "";
  932. stJobProcessReq.strCrashTime = "";
  933. // 就是Task中的ExecuteId
  934. _itoa_s(pTask->taskInfo.nExecuteId, szValue, 10);
  935. stJobProcessReq.strRunnerId = szValue;
  936. stJobProcessReq.strCPUInfo = "0";
  937. stJobProcessReq.strRunnedActionNameList = "";
  938. stJobProcessReq.strArtificialResult = "";
  939. stJobProcessReq.strArtificialModify = "";
  940. stJobProcessReq.strRunnerName = "";
  941. stJobProcessReq.strTaskType = "FUNCTIONALITY";
  942. stJobProcessReq.strCaseRepeat = "0";
  943. stJobProcessReq.strApplicationGroup = "";
  944. // 实例Id;注意避坑;
  945. _itoa_s(pTask->taskInfo.Id, szValue, 10);
  946. stJobProcessReq.strInstanceId = szValue;
  947. stJobProcessReq.strCaseId = "";
  948. // 进度(###需要修改此处###);
  949. stJobProcessReq.strProgress = "100";
  950. // 需要将utf-8转gbk;
  951. stJobProcessReq.strReusltMessage = CharEncoding::ASCII2UTF8("任务结束");
  952. stJobProcessReq.strJobRepeat = "0";
  953. stJobProcessReq.strScreenShot = "";
  954. // 注意避坑:实际结束时间也要放在该字段中;
  955. stJobProcessReq.strStartTime = CTime::GetCurrentTime().Format(_T("%Y-%m-%d %H:%M:%S"));
  956. stJobProcessReq.strCrashNumber = "";
  957. stJobProcessReq.strCaseName = "";
  958. stJobProcessReq.strFailedReason = "";
  959. stJobProcessReq.strImgName = "";
  960. stJobProcessReq.strCaseIndex = "";
  961. // 实例Id;
  962. _itoa_s(pTask->taskInfo.nDeviceId, szValue, 10);
  963. stJobProcessReq.strDeviceId = szValue;
  964. stJobProcessReq.strSceneIndex = "0";
  965. // 实例Id;
  966. //_itoa_s(pTask->nTaskId, szValue, 10);
  967. if ( pTask->taskInfo.strInstanceType == "4") {
  968. _itoa_s(pTask->taskInfo.nInstanceId, szValue, 10);
  969. stJobProcessReq.strTaskId = szValue;
  970. }
  971. else
  972. stJobProcessReq.strTaskId = pTask->Job.strTaskId;
  973. stJobProcessReq.strInstanceType = pTask->taskInfo.strInstanceType;
  974. stJobProcessReq.strAnalysis = "";
  975. // 设备名称:即DeviceSerial;
  976. stJobProcessReq.strDevnceName = pTask->Job.strDeviceId; // 命名及其不范围,一会deviceid是deviceserial,一会是id;
  977. // 固定为:TOTAL
  978. stJobProcessReq.strInfoType = "";
  979. // 如果是Android设备,需要通过adb获取;
  980. //stJobProcessReq.strMemoryInfo = stDevice.strMemory;
  981. stJobProcessReq.strEndTime = CTime::GetCurrentTime().Format(_T("%Y-%m-%d %H:%M:%S"));//"2019-12-16 10:18:20";
  982. stJobProcessReq.strRoundNumber = pTask->Job.strRound;
  983. stJobProcessReq.strResultType = "1"; // reportJobFinish;
  984. stJobProcessReq.strOperationStep = "";
  985. if ( SetResultList(url, stJobProcessReq, stJobProcessResp) ) {
  986. GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, _T("上报任务结束【成功】,任务编号为=%s"), pTask->Job.strUniqueId.c_str());
  987. return true;
  988. }
  989. GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, _T("上报任务结束【失败】,任务编号为=%s"), pTask->Job.strUniqueId.c_str());
  990. return false;
  991. }
  992. bool CSATExecutor::GetCaseXMLResult(std::string xmlpath, std::vector<STCaseItem> &vtCaseItem)
  993. {
  994. // 解析xml;
  995. tinyxml2::XMLDocument doc;
  996. if (tinyxml2::XML_SUCCESS != doc.LoadFile(xmlpath.c_str()) ) {
  997. GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, "没有测试项对应的xml文件:%s", xmlpath.c_str());
  998. return false;
  999. }
  1000. tinyxml2::XMLElement *pXmlRoot = NULL;
  1001. if ((pXmlRoot = doc.RootElement()) == NULL)
  1002. return false;
  1003. if (_tcsicmp(pXmlRoot->Value(), "results") != 0)
  1004. return false;
  1005. // 获取属性;
  1006. bool bFinishStatus = false;
  1007. const tinyxml2::XMLAttribute *pAttr = pXmlRoot->FirstAttribute();
  1008. while (pAttr) {
  1009. if (_tcsicmp(pAttr->Name(), "caseFinish") == 0) {
  1010. // 整个测试项ok;
  1011. if ( _tcsicmp(pAttr->Value(), _T("1")) == 0 )
  1012. bFinishStatus = true;
  1013. break;
  1014. }
  1015. pAttr = pAttr->Next();
  1016. }
  1017. GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, "开始获取测试项内容:%s", xmlpath.c_str());
  1018. tinyxml2::XMLElement *pXmlElent = pXmlRoot->FirstChildElement();
  1019. while (pXmlElent) {
  1020. if (_tcsicmp(pXmlElent->Value(), _T("item")) == 0) {
  1021. STCaseItem cItem;
  1022. tinyxml2::XMLElement *pItem = pXmlElent->FirstChildElement();
  1023. while (pItem) {
  1024. if (_tcsicmp(pItem->Value(), _T("name")) == 0) {
  1025. cItem.name = pItem->GetText();
  1026. }
  1027. else if (_tcsicmp(pItem->Value(), _T("result")) == 0) {
  1028. if ( _tcsicmp(pItem->GetText(), _T("Pass")) == 0 )
  1029. cItem.result = true;
  1030. else
  1031. cItem.result = false;
  1032. }
  1033. else if (_tcsicmp(pItem->Value(), _T("data")) == 0) {
  1034. cItem.data = pItem->GetText();
  1035. }
  1036. else if (_tcsicmp(pItem->Value(), _T("log")) == 0) {
  1037. cItem.log = pItem->GetText();
  1038. }
  1039. else if (_tcsicmp(pItem->Value(), _T("remark")) == 0) {
  1040. cItem.remark = pItem->GetText();
  1041. }
  1042. else if (_tcsicmp(pItem->Value(), _T("screen")) == 0) {
  1043. cItem.imgs.push_back(pItem->GetText());
  1044. }
  1045. pItem = pItem->NextSiblingElement();
  1046. }
  1047. // 压入容器;
  1048. if ( cItem.name.size() )
  1049. vtCaseItem.push_back(cItem);
  1050. }
  1051. pXmlElent = pXmlElent->NextSiblingElement();
  1052. }
  1053. return bFinishStatus;
  1054. }
  1055. int CSATExecutor::AttachTaskInfo2Buffer(SATPROTO::TaskInfo (&pbuff)[SATPROTO::MAX_TASKS])
  1056. {
  1057. int count = 0;
  1058. if ( pbuff ) {
  1059. AutoThreadSection ats(&m_csTask);
  1060. std::vector<SATHTTP::STTask>::iterator it = m_vtTask.begin();
  1061. for ( ;it != m_vtTask.end(); it++ ) {
  1062. // 任务状态;
  1063. //pbuff[count].nStatus = it->_nExecutionState;
  1064. // 任务id;
  1065. pbuff[count].nTaskId = it->taskInfo.Id;
  1066. // 任务编号;
  1067. memcpy_s(pbuff[count].szTaskNo, SATPROTO::MAX_NAME, it->Job.strUniqueId.c_str(), it->Job.strUniqueId.size());
  1068. // 任务名称;
  1069. memcpy_s(pbuff[count].szTaskName, SATPROTO::MAX_NAME, it->taskInfo.strTaskName.c_str(), it->taskInfo.strTaskName.size());
  1070. // 任务状态;
  1071. if ( it->taskInfo._nExecutionState == SATHTTP::UNEXECUTED ) {
  1072. _stprintf_s(pbuff[count].szStatus, SATPROTO::MAX_STATUS, _T("未执行"));
  1073. }
  1074. else if (it->taskInfo._nExecutionState == SATHTTP::INEXECUTED) {
  1075. _stprintf_s(pbuff[count].szStatus, SATPROTO::MAX_STATUS, _T("执行中"));
  1076. }
  1077. else if (it->taskInfo._nExecutionState == SATHTTP::EXECUTED) {
  1078. _stprintf_s(pbuff[count].szStatus, SATPROTO::MAX_STATUS, _T("已执行"));
  1079. }
  1080. int nIndex = 0;
  1081. // 用例数量;
  1082. pbuff[count].nCaseSize = it->vtCases.size();
  1083. for (std::vector<SATHTTP::STCase>::iterator _case = it->vtCases.begin(); _case != it->vtCases.end(); _case++) {
  1084. // 用例状态;
  1085. // pbuff[count].ssCases[nIndex].nStatus = _case->_nExecutionState;
  1086. //pbuff[count].ssCases[nIndex].nCaseId = _case->_nCaseStep;
  1087. // 用例名称;
  1088. memcpy_s(pbuff[count].ssCases[nIndex].szCaseName, SATPROTO::MAX_NAME, _case->strCaseName.c_str(), _case->strCaseName.size());
  1089. // 用例日志路径;
  1090. memcpy_s(pbuff[count].ssCases[nIndex].szCaseLogPath, MAX_PATH, _case->_strCaseLog.c_str(), _case->_strCaseLog.size());
  1091. // 用例执行状态;
  1092. if (_case->_nExecutionState == SATHTTP::UNEXECUTED) {
  1093. _stprintf_s(pbuff[count].ssCases[nIndex].szExecStatus, SATPROTO::MAX_STATUS, _T("未执行"));
  1094. }
  1095. else if (_case->_nExecutionState == SATHTTP::INEXECUTED) {
  1096. _stprintf_s(pbuff[count].ssCases[nIndex].szExecStatus, SATPROTO::MAX_STATUS, _T("执行中"));
  1097. }
  1098. else if (_case->_nExecutionState == SATHTTP::EXECUTED) {
  1099. _stprintf_s(pbuff[count].ssCases[nIndex].szExecStatus, SATPROTO::MAX_STATUS, _T("已执行"));
  1100. }
  1101. // 用例执行结果;
  1102. if ( _case->_nExecutionResult == SATHTTP::NONE ) {
  1103. _stprintf_s(pbuff[count].ssCases[nIndex].szResultStatus, SATPROTO::MAX_STATUS, _T("无"));
  1104. }
  1105. else if ( _case->_nExecutionResult == SATHTTP::SUCCESS ) {
  1106. _stprintf_s(pbuff[count].ssCases[nIndex].szResultStatus, SATPROTO::MAX_STATUS, _T("成功"));
  1107. }
  1108. else if ( _case->_nExecutionResult == SATHTTP::FAIL ) {
  1109. _stprintf_s(pbuff[count].ssCases[nIndex].szResultStatus, SATPROTO::MAX_STATUS, _T("失败"));
  1110. }
  1111. else if ( _case->_nExecutionResult == SATHTTP::ABNORMAL ) {
  1112. _stprintf_s(pbuff[count].ssCases[nIndex].szResultStatus, SATPROTO::MAX_STATUS, _T("异常"));
  1113. }
  1114. else if ( _case->_nExecutionResult == SATHTTP::OVERTIME ) {
  1115. _stprintf_s(pbuff[count].ssCases[nIndex].szResultStatus, SATPROTO::MAX_STATUS, _T("超时"));
  1116. }
  1117. nIndex++;
  1118. // 超过MAX_CASES退出;
  1119. if ( nIndex == SATPROTO::MAX_CASES )
  1120. break;
  1121. }
  1122. count++;
  1123. // 超过MAX_TASKS退出;
  1124. if ( count == SATPROTO::MAX_TASKS )
  1125. break;
  1126. }
  1127. }
  1128. return count;
  1129. }
  1130. bool CSATExecutor::SmokeTaskPretreated(SATHTTP::STTask &task)
  1131. {
  1132. #ifdef _DBG_SOMKING_
  1133. task.taskInfo.stSomkingCycle.nType = 1;
  1134. task.taskInfo.stSomkingCycle.nWeek = 0;
  1135. task.taskInfo.stSomkingCycle.nDay = 0;
  1136. task.taskInfo.stSomkingCycle.strTime = GLOBAL::g_stSATConfig.szSomkingTime;
  1137. #endif
  1138. bool bTimeIsUp = false;
  1139. // 获取当前日历时间(1900-01-01开始的Unix时间戳);
  1140. __time64_t gmt = time(NULL);
  1141. struct tm gmtm = { 0 };
  1142. // 时间戳转成本地时间;
  1143. localtime_s(&gmtm, &gmt);
  1144. // 获取执行时间;
  1145. int hour, minute;
  1146. sscanf_s(task.taskInfo.stSomkingCycle.strTime.c_str(), _T("%d:%d"), &hour, &minute);
  1147. // 是否到达指定时间;
  1148. if ( task.taskInfo.stSomkingCycle.nType == 0 ) {// 立即;
  1149. bTimeIsUp = true;
  1150. }
  1151. else if ( task.taskInfo.stSomkingCycle.nType == 1 ) {// 每天;
  1152. if ( gmtm.tm_hour == hour && gmtm.tm_min >= minute && gmtm.tm_min <= minute + 3)
  1153. bTimeIsUp = true;
  1154. }
  1155. else if ( task.taskInfo.stSomkingCycle.nType == 2 ) {// 每周;
  1156. if ( gmtm.tm_wday == task.taskInfo.stSomkingCycle.nWeek && gmtm.tm_hour == hour && gmtm.tm_min >= minute && gmtm.tm_min <= minute + 3)
  1157. bTimeIsUp = true;
  1158. }
  1159. else if ( task.taskInfo.stSomkingCycle.nType == 3 ) {// 每月;
  1160. if ( gmtm.tm_mday == task.taskInfo.stSomkingCycle.nDay &&
  1161. gmtm.tm_wday == task.taskInfo.stSomkingCycle.nWeek && gmtm.tm_hour == hour && gmtm.tm_min >= minute && gmtm.tm_min <= minute + 3)
  1162. bTimeIsUp = true;
  1163. }
  1164. // 到达执行时间;
  1165. if ( bTimeIsUp ) {
  1166. // 下载任务,并添加到队列中;
  1167. DownloadTask(task);
  1168. Sleep(10000);
  1169. }
  1170. return bTimeIsUp;
  1171. }
  1172. void CSATExecutor::StartWork()
  1173. {
  1174. m_hEventHearbeat = CreateEvent(NULL, TRUE, FALSE, NULL);
  1175. if ( m_hEventHearbeat == NULL ) {
  1176. _tprintf_s(_T("创建事件失败\n"));
  1177. return;
  1178. }
  1179. m_hEventExcuteScript = CreateEvent(NULL, TRUE, FALSE, NULL);
  1180. if ( m_hEventExcuteScript == NULL ) {
  1181. _tprintf_s(_T("创建事件失败2\n"));
  1182. goto clear;
  1183. }
  1184. m_hEventSomkingScript = CreateEvent(NULL, TRUE, FALSE, NULL);
  1185. if ( m_hEventSomkingScript == NULL ) {
  1186. _tprintf_s(_T("创建事件失败3\n"));
  1187. goto clear;
  1188. }
  1189. m_hThreadHearbeat = CreateThread(NULL, 0, HearbeatThread, this, 0, NULL);
  1190. if ( m_hThreadHearbeat == NULL) {
  1191. _tprintf_s(_T("创建线程失败\n"));
  1192. goto clear;
  1193. }
  1194. m_hThreadExcuteScript = CreateThread(NULL, 0, ExecuteScriptThread, this, 0, NULL);
  1195. if ( m_hThreadExcuteScript == NULL ) {
  1196. goto clear;
  1197. }
  1198. m_hThreadSomkingScript = CreateThread(NULL, 0, SomkingScriptThread, this, 0, &m_dwSomkingThreadId);
  1199. if ( m_hThreadSomkingScript == NULL ) {
  1200. goto clear;
  1201. }
  1202. return;
  1203. clear:
  1204. if ( m_hEventHearbeat ) {
  1205. SetEvent(m_hEventHearbeat);
  1206. CloseHandle(m_hEventHearbeat);
  1207. m_hEventHearbeat = NULL;
  1208. }
  1209. if ( m_hEventExcuteScript ) {
  1210. SetEvent(m_hEventExcuteScript);
  1211. CloseHandle(m_hEventExcuteScript);
  1212. m_hEventExcuteScript = NULL;
  1213. }
  1214. if ( m_hEventSomkingScript ) {
  1215. SetEvent(m_hEventSomkingScript);
  1216. CloseHandle(m_hEventSomkingScript);
  1217. m_hEventSomkingScript = NULL;
  1218. }
  1219. if ( m_hThreadHearbeat ) {
  1220. WaitForSingleObject(m_hThreadHearbeat,INFINITE);
  1221. if (m_hThreadHearbeat)
  1222. CloseHandle(m_hThreadHearbeat);
  1223. m_hThreadHearbeat = NULL;
  1224. }
  1225. if ( m_hThreadExcuteScript ) {
  1226. WaitForSingleObject(m_hThreadExcuteScript,INFINITE);
  1227. if (m_hThreadExcuteScript)
  1228. CloseHandle(m_hThreadExcuteScript);
  1229. m_hThreadExcuteScript = NULL;
  1230. }
  1231. if ( m_hThreadSomkingScript ) {
  1232. WaitForSingleObject(m_hThreadSomkingScript,INFINITE);
  1233. if (m_hThreadSomkingScript)
  1234. CloseHandle(m_hThreadSomkingScript);
  1235. m_hThreadSomkingScript = NULL;
  1236. }
  1237. }
  1238. void CSATExecutor::EndofWork()
  1239. {
  1240. //////////////////////////////////////////////////////////////////////////
  1241. // 设置事件有信号;
  1242. if ( m_hEventHearbeat )
  1243. SetEvent(m_hEventHearbeat);
  1244. // 等待线程结束;
  1245. if ( m_hThreadHearbeat ) {
  1246. WaitForSingleObject(m_hThreadHearbeat, INFINITE);
  1247. CloseHandle(m_hThreadHearbeat);
  1248. m_hThreadHearbeat = NULL;
  1249. }
  1250. // 关闭事件句柄;
  1251. if ( m_hEventHearbeat ) {
  1252. CloseHandle(m_hEventHearbeat);
  1253. m_hEventHearbeat = NULL;
  1254. }
  1255. //////////////////////////////////////////////////////////////////////////
  1256. // 设置事件有信号;
  1257. if ( m_hEventExcuteScript )
  1258. SetEvent(m_hEventExcuteScript);
  1259. // 等待线程结束;
  1260. if ( m_hThreadExcuteScript ) {
  1261. WaitForSingleObject(m_hThreadExcuteScript, INFINITE);
  1262. CloseHandle(m_hThreadExcuteScript);
  1263. m_hThreadExcuteScript = NULL;
  1264. }
  1265. // 关闭事件句柄;
  1266. if ( m_hEventExcuteScript ) {
  1267. CloseHandle(m_hEventExcuteScript);
  1268. m_hEventExcuteScript = NULL;
  1269. }
  1270. //////////////////////////////////////////////////////////////////////////
  1271. // 设置事件有信号;
  1272. if ( m_hEventSomkingScript )
  1273. SetEvent(m_hEventSomkingScript);
  1274. // 等待线程结束;
  1275. if ( m_hThreadSomkingScript ) {
  1276. WaitForSingleObject(m_hThreadSomkingScript, INFINITE);
  1277. CloseHandle(m_hThreadSomkingScript);
  1278. m_hThreadSomkingScript = NULL;
  1279. }
  1280. // 关闭事件句柄;
  1281. if ( m_hEventSomkingScript ) {
  1282. CloseHandle(m_hEventSomkingScript);
  1283. m_hEventSomkingScript = NULL;
  1284. }
  1285. // 如果有脚本在执行,结束脚本;
  1286. CPythonExecutor *pExecutor = NULL;
  1287. for ( std::vector<SATHTTP::STTask>::iterator it = m_vtTask.begin(); it != m_vtTask.end(); it++ ) {
  1288. for ( std::vector<SATHTTP::STCase>::iterator _case = it->vtCases.begin(); _case != it->vtCases.end(); _case++ ) {
  1289. if ( (pExecutor = (CPythonExecutor *)_case->_pExcutor) ) {
  1290. pExecutor->EndThread();
  1291. delete pExecutor;
  1292. pExecutor = NULL;
  1293. }
  1294. }
  1295. }
  1296. m_vtTask.clear();
  1297. }
  1298. DWORD CSATExecutor::HearbeatThread(LPVOID lpVoid)
  1299. {
  1300. CSATExecutor *that = (CSATExecutor*)lpVoid;
  1301. if ( !that ) return 0;
  1302. do {
  1303. // 如果未启用电视监听,启用实时读取配置文件;
  1304. if ( !GLOBAL::g_stSATConfig.bWatchTVPort ) {
  1305. GLOBAL::GetIniInfo();
  1306. }
  1307. // 没有登录成功,不查询;
  1308. if ( !that->m_bLogin )
  1309. continue;
  1310. // 更新设备;
  1311. that->UpdateDevice();
  1312. // 脚本保存目录;
  1313. std::string strScriptSaveDir;
  1314. SATHTTP::STHeartbeatReq stHeartbeatReq;
  1315. SATHTTP::STHeartbeatResp stHeartbeatResp;
  1316. std::string url = GLOBAL::g_stSATConfig.szExecuteServer;
  1317. url.append("/ajaxInteractiveManage!executeHeartbeat.action");
  1318. stHeartbeatReq.strUserName = that->m_stLoginReq.strUserName;
  1319. stHeartbeatReq.strRunnerMac = that->m_stLoginReq.strMAC;
  1320. stHeartbeatReq.devicelist.assign(that->m_vtDevice.begin(), that->m_vtDevice.end());
  1321. if ( Heartbeat(url, stHeartbeatReq, stHeartbeatResp) ) {
  1322. std::vector<SATHTTP::STTask>::iterator it = stHeartbeatResp.vtTask.begin();
  1323. for ( ; it != stHeartbeatResp.vtTask.end(); it++ ) {
  1324. if (!that->IsTaskExist(*it)) {
  1325. that->DownloadTask(*it);
  1326. }
  1327. }
  1328. }
  1329. else {
  1330. // 心跳失败:登录一次;
  1331. that->Login(true);
  1332. }
  1333. } while ( WaitForSingleObject(that->m_hEventHearbeat, 10000) == WAIT_TIMEOUT );
  1334. return 0;
  1335. }
  1336. DWORD CSATExecutor::ExecuteScriptThread(LPVOID lpVoid)
  1337. {
  1338. CSATExecutor *that = (CSATExecutor*)lpVoid;
  1339. if ( !that ) return 0;
  1340. do {
  1341. // 删除已完成的任务;
  1342. that->DelFinishedTask();
  1343. // 是否有任务在执行;
  1344. SATHTTP::STTask *pTask = that->IsThereATaskInProcess();
  1345. if ( pTask ) {// 有任务在执行中;
  1346. if ( pTask->taskInfo._bConcurrent ) {// 并发;
  1347. }
  1348. else {// 串行;
  1349. // 是否有脚本用例在执行;
  1350. SATHTTP::STCase* pCase = that->IsCaseScriptProcess(pTask->vtCases);
  1351. if ( pCase ) {
  1352. CPythonExecutor *pExcutor = (CPythonExecutor*)pCase->_pExcutor;
  1353. if ( pExcutor ) {
  1354. if ( pExcutor->IsScriptOver() ) {
  1355. // 标记脚本已执行;
  1356. pCase->_nExecutionState = SATHTTP::EXECUTED;
  1357. // 如果脚本异常,标记任务失败;
  1358. if ( pCase->_nExecutionResult == SATHTTP::ABNORMAL ) {
  1359. // 设置任务执行结果失败;
  1360. pTask->taskInfo._nExecutionResult = SATHTTP::FAIL;
  1361. GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, "用例脚本异常退出(%s)", pCase->strCaseName.c_str());
  1362. }
  1363. // 上报服务器,完成脚本用例,并上传用例结果;
  1364. that->ReportCaseResult(pTask, pCase);
  1365. }
  1366. else {
  1367. // 判断是否超时;
  1368. ULONGLONG ulCurTickCount = GetTickCount64();
  1369. if ( ulCurTickCount - pExcutor->GetActiveTickCount() > GLOBAL::g_stSATConfig.dwScriptTimeout ) {
  1370. // 标记任务已执行;
  1371. pCase->_nExecutionState = SATHTTP::EXECUTED;
  1372. // 结束进程;
  1373. pExcutor->EndThread();
  1374. // 超时中断;
  1375. pCase->_nExecutionResult = SATHTTP::OVERTIME;
  1376. // 上报用例结果;
  1377. that->ReportCaseResult(pTask, pCase);
  1378. GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, _T("脚本超时:%s"), pCase->strCaseName.c_str());
  1379. }
  1380. }
  1381. }
  1382. }
  1383. else {
  1384. // 没有在执行的用例,开始执行新的用例;
  1385. pCase = that->ExecuteFreeCaseScript(pTask);
  1386. if ( NULL == pCase ) {
  1387. // 没有空闲的用例可执行,说明所有用例已执行完成;
  1388. pTask->taskInfo._nExecutionState = SATHTTP::EXECUTED;
  1389. // 上报任务完成;
  1390. that->ReportTaskFinish(pTask);
  1391. // 上报任务结果;
  1392. that->UploadTaskLog(pTask);
  1393. GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, _T("没有可执行的用例脚本,任务【%s】"), pTask->Job.strUniqueId.c_str());
  1394. }
  1395. }
  1396. }
  1397. }
  1398. else {
  1399. // 获取空闲的任务;
  1400. pTask = that->GetFreeTask();
  1401. if ( pTask ) {
  1402. // 是否支持并发;
  1403. if ( pTask->taskInfo._bConcurrent ) {
  1404. // 暂时全部一起并发;
  1405. std::vector<SATHTTP::STCase>::iterator _case = pTask->vtCases.begin();
  1406. for ( ; _case != pTask->vtCases.end(); _case++) {
  1407. if (!_case->_pExcutor) {
  1408. CPythonExecutor *pExcutor = new CPythonExecutor();
  1409. if ( pExcutor ) {
  1410. _case->_pExcutor = pExcutor;
  1411. pExcutor->InitScript(_case->_strScriptPath, _case->_strFileDir + "\\" + _case->_strFileName + ".txt", "");
  1412. pExcutor->StartScript();
  1413. // 标记用例执行中;
  1414. _case->_nExecutionState = SATHTTP::INEXECUTED;
  1415. }
  1416. }
  1417. }
  1418. // 标记任务为执行中;
  1419. pTask->taskInfo._nExecutionState = SATHTTP::INEXECUTED;
  1420. }
  1421. else {
  1422. GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, _T("\n<===============================================>\n# 1、开始执行任务:%s, 用例数量:%ld#\n<===============================================>\n"),
  1423. pTask->Job.strUniqueId.c_str(),
  1424. pTask->vtCases.size());
  1425. // 是否有用例脚本在执行;
  1426. SATHTTP::STCase* pCase = that->IsCaseScriptProcess(pTask->vtCases);
  1427. if ( !pCase ) {
  1428. // 执行空闲用例脚本;
  1429. that->ExecuteFreeCaseScript(pTask);
  1430. }
  1431. }
  1432. // 通知SAT服务器,脚本开始执行;
  1433. that->NotifyTaskStart(pTask);
  1434. // 通知SAT服务器,脚本开始;
  1435. that->ReportTaskStart(pTask);
  1436. // 将设备变更成繁忙状态;
  1437. that->SetDeviceStatus(pTask->Job.strDeviceId, SATDEV::InUse);
  1438. }
  1439. }
  1440. } while ( WaitForSingleObject(that->m_hEventExcuteScript, 10000) == WAIT_TIMEOUT );
  1441. return 0;
  1442. }
  1443. DWORD CSATExecutor::WathTVPortThread(PVOID lpVoid)
  1444. {
  1445. CSATExecutor *that = (CSATExecutor*)lpVoid;
  1446. if ( !that )
  1447. return 0;
  1448. CSynSerial tv;
  1449. std::string buffer;
  1450. TCHAR szLastPort[10] = {0};
  1451. _tcscpy_s(szLastPort, GLOBAL::g_stSATConfig.szTVPort);
  1452. std::vector<std::string> vtNotifyReboot;
  1453. std::vector<std::string> vtNotifyShutdown;
  1454. DWORD dwTickCount = GetTickCount();
  1455. while( true ) {
  1456. // 实时读取配置文件;
  1457. GLOBAL::GetIniInfo();
  1458. if ( !GLOBAL::g_stSATConfig.bWatchTVPort ) {
  1459. Sleep(5000);
  1460. continue;
  1461. }
  1462. if ( GetTickCount() - dwTickCount > 5000 ) { // 5秒更新一次;
  1463. vtNotifyReboot.clear();
  1464. vtNotifyShutdown.clear();
  1465. dwTickCount = GetTickCount();
  1466. GLOBAL::Split(GLOBAL::g_stSATConfig.szTVReboot, _T(";"), vtNotifyReboot);
  1467. GLOBAL::Split(GLOBAL::g_stSATConfig.szTVShutdown, _T(";"), vtNotifyShutdown);
  1468. }
  1469. // 串口是否变更;
  1470. if ( _tcsicmp(szLastPort, GLOBAL::g_stSATConfig.szTVPort) ) {
  1471. _tcscpy_s(szLastPort, GLOBAL::g_stSATConfig.szTVPort);
  1472. // 重启打开串口;
  1473. tv.CloseSerialPort();
  1474. }
  1475. // 如果串口打开失败重新打开;
  1476. if ( !tv.IsOpen() ) {
  1477. tv.OpenSerialPort(szLastPort, 115200, 8, 0, 1, 0, 1000);
  1478. }
  1479. if ( tv.IsOpen() ) {
  1480. BYTE szBuffer[1024] = {0};
  1481. DWORD dwBuffer = tv.ReadComm(szBuffer, 1024, 1000);
  1482. if ( dwBuffer != 0 ) {
  1483. int nType = 0; // 0表示无异常类型,-1表示关机异常,1表示重启异常;
  1484. bool bAbnormal = false;
  1485. buffer = (char*)szBuffer;
  1486. __time64_t gmt = time(NULL);// 获取当前日历时间(1900-01-01开始的Unix时间戳);
  1487. // 遍历是否有符合的子串;
  1488. for ( std::vector<std::string>::iterator it = vtNotifyReboot.begin(); it != vtNotifyReboot.end(); it++ ) {
  1489. if ( _tcsstr(buffer.c_str(), it->c_str()) ) {
  1490. nType = 1;
  1491. bAbnormal = true;
  1492. break;
  1493. }
  1494. }
  1495. if ( !bAbnormal ) {
  1496. for ( std::vector<std::string>::iterator it = vtNotifyShutdown.begin(); it != vtNotifyShutdown.end(); it++ ) {
  1497. if ( _tcsstr(buffer.c_str(), it->c_str()) ) {
  1498. nType = -1;
  1499. bAbnormal = true;
  1500. break;
  1501. }
  1502. }
  1503. }
  1504. // 1分钟前,是否有收到脚本通知;
  1505. if ( GLOBAL::g_PyNotify.notify ) {
  1506. __int64 nd = gmt - GLOBAL::g_PyNotify.datetime;
  1507. #ifdef _DEBUG
  1508. TRACE3("判断时间%ld-通知时间%ld=相差时间%ld\n\n", gmt, GLOBAL::g_PyNotify.datetime, nd);
  1509. #endif
  1510. if ( nd < 60) {
  1511. // 监测的类型与通知类型是否一致;
  1512. if ( (nType == 1 && GLOBAL::g_PyNotify.report_type == _T("reboot")) ||
  1513. (nType == -1 && GLOBAL::g_PyNotify.report_type == _T("shutdown")) )
  1514. {
  1515. bAbnormal = false;
  1516. // 重置;
  1517. GLOBAL::g_PyNotify.notify = false;
  1518. GLOBAL::g_PyNotify.datetime = 0;
  1519. GLOBAL::g_PyNotify.report_type.clear();
  1520. }
  1521. }
  1522. }
  1523. if (bAbnormal) {
  1524. if ( nType == -1 ) {
  1525. // 遥控:重启电视机;
  1526. if ( Connect("127.0.0.1", 40000) )
  1527. sendSignal("POWER", 1, 1000);
  1528. GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, "出现异常关机重启现象");
  1529. }
  1530. // 压入容器中;
  1531. GLOBAL::PyNotice tlog;
  1532. if ( nType == -1 )
  1533. tlog.report_type = "Abnormal shutdown";
  1534. else if ( nType == 1 )
  1535. tlog.report_type = "Abnormal restart";
  1536. tlog.datetime = gmt; // 发生时间;
  1537. struct tm gmtm = {0};
  1538. localtime_s(&gmtm, &gmt); // 时间戳转成本地时间;
  1539. TCHAR szDataTime[64] = {0};
  1540. _stprintf_s(szDataTime,_T("Time of exception:%04d-%02d-%02d %02d:%02d:%02d"), gmtm.tm_year + 1900, gmtm.tm_mon+1, gmtm.tm_mday, gmtm.tm_hour, gmtm.tm_min, gmtm.tm_sec);
  1541. tlog.report_data = szDataTime;
  1542. // 最后,重置;
  1543. GLOBAL::g_PyNotify.notify = false;
  1544. GLOBAL::g_PyNotify.datetime = 0;
  1545. GLOBAL::g_PyNotify.report_type.clear();
  1546. }
  1547. }
  1548. }
  1549. Sleep(200);
  1550. }
  1551. return 0;
  1552. }
  1553. DWORD CSATExecutor::SomkingScriptThread(LPVOID lpVoid)
  1554. {
  1555. CSATExecutor *that = (CSATExecutor*)lpVoid;
  1556. if ( !that ) return 0;
  1557. int nIndex = 0;
  1558. // 如果任务存在,删除原来的;
  1559. SATHTTP::STTask task;
  1560. do
  1561. {
  1562. AutoThreadSection ats(&that->m_csSomkingTask);
  1563. if ( that->m_vtSmokingTask.size() == 0 ) {
  1564. continue;
  1565. }
  1566. if ( nIndex >= that->m_vtSmokingTask.size() )
  1567. nIndex = 0;
  1568. task = that->m_vtSmokingTask[nIndex];
  1569. if ( that->SmokeTaskPretreated(task) )
  1570. that->m_vtSmokingTask.erase(that->m_vtSmokingTask.begin()+nIndex);
  1571. else
  1572. nIndex++;
  1573. } while (WaitForSingleObject(that->m_hEventSomkingScript, 15000) == WAIT_TIMEOUT);
  1574. return 0;
  1575. }