SATExecutor.cpp 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323
  1. #include "StdAfx.h"
  2. #include "SATExecutor.h"
  3. #include "PythonExecutor.h"
  4. #include "CharEncoding.h"
  5. #include "SynSerial.h"
  6. CSATExecutor::CSATExecutor(void)
  7. {
  8. m_bLogin = FALSE;
  9. m_hEventHearbeat = NULL;
  10. m_hThreadHearbeat = NULL;
  11. m_hEventExcuteScript = NULL;
  12. m_hThreadExcuteScript = NULL;
  13. }
  14. CSATExecutor::~CSATExecutor(void)
  15. {
  16. }
  17. bool CSATExecutor::IsTaskExist(SATHTTP::STTask &task)
  18. {
  19. bool found = false;
  20. std::list<SATHTTP::STTask>::iterator it = m_vtTask.begin();
  21. for ( ; it != m_vtTask.end(); it++ ) {
  22. // 不要使用nTaskId,这个值没啥用;
  23. if ( it->Id == task.Id ) {
  24. found = true;
  25. break;
  26. }
  27. }
  28. return found;
  29. }
  30. SATHTTP::STTask* CSATExecutor::IsThereATaskInProcess()
  31. {
  32. std::list<SATHTTP::STTask>::iterator it = m_vtTask.begin();
  33. for ( ; it != m_vtTask.end(); it++ ) {
  34. // 执行中的任务;
  35. if ( it->_nExecutionState == SATHTTP::INEXECUTED ) {
  36. return &(*it);
  37. }
  38. }
  39. return NULL;
  40. }
  41. SATHTTP::STTask* CSATExecutor::GetFreeTask()
  42. {
  43. std::list<SATHTTP::STTask>::iterator it = m_vtTask.begin();
  44. for ( ; it != m_vtTask.end(); it++ ) {
  45. // 未执行的任务;
  46. if ( it->_nExecutionState == SATHTTP::UNEXECUTED ) {
  47. return &(*it);
  48. }
  49. }
  50. return NULL;
  51. }
  52. void CSATExecutor::DelFinishedTask()
  53. {
  54. AutoThreadSection ats(&m_csTask);
  55. std::list<SATHTTP::STTask>::iterator it = m_vtTask.begin();
  56. for ( ; it != m_vtTask.end(); it++ ) {
  57. // 状态为2的完成任务;
  58. if ( it->_nExecutionState == SATHTTP::EXECUTED ) {
  59. GLOBAL::WriteTextLog("==>删除已完成任务:%s", it->Job.strUniqueId.c_str());
  60. // 删除所有执行器对象;
  61. for (std::vector<SATHTTP::STCase>::iterator _case = it->Job.vtCases.begin(); _case != it->Job.vtCases.end(); _case++ ) {
  62. if ( _case->_pExcutor )
  63. delete _case->_pExcutor;
  64. _case->_pExcutor = NULL;
  65. }
  66. m_vtTask.erase(it);
  67. break;
  68. }
  69. }
  70. }
  71. SATHTTP::STCase* CSATExecutor::IsCaseScriptProcess(std::vector<SATHTTP::STCase> &vtCases)
  72. {
  73. std::vector<SATHTTP::STCase>::iterator it = vtCases.begin();
  74. for ( ; it != vtCases.end(); it++) {
  75. // 执行中的脚本;
  76. if ( it->_nExecutionState == SATHTTP::INEXECUTED ) {
  77. return &(*it);
  78. }
  79. }
  80. return NULL;
  81. }
  82. SATHTTP::STCase* CSATExecutor::GetFreeCaseScript(std::vector<SATHTTP::STCase> &vtCases)
  83. {
  84. std::vector<SATHTTP::STCase>::iterator it = vtCases.begin();
  85. for ( ; it != vtCases.end(); it++) {
  86. // 未执行的脚本;
  87. if ( it->_nExecutionState == SATHTTP::UNEXECUTED ) {
  88. return &(*it);
  89. }
  90. }
  91. return NULL;
  92. }
  93. SATHTTP::STCase* CSATExecutor::ExecuteFreeCaseScript(SATHTTP::STTask* pTask)
  94. {
  95. // 多取未执行的脚本;
  96. SATHTTP::STCase* pCase = GetFreeCaseScript(pTask->Job.vtCases);
  97. if (pCase) {
  98. if ( !pCase->_pExcutor ) {
  99. CPythonExecutor *pExcutor = new CPythonExecutor();
  100. if ( pExcutor ) {
  101. pCase->_pExcutor = pExcutor;
  102. // 用例的日志文件路径;
  103. pCase->_strCaseLog = pCase->_strFileDir + "\\" + pCase->_strFileName + ".txt";
  104. if ( pExcutor->InitScript(pCase->_strScriptPath, pCase->_strCaseLog, "") ) {
  105. // 设置用例对象;
  106. pExcutor->SetCaseObje(pCase);
  107. pExcutor->StartScript();
  108. // 标记用例执行中;
  109. pCase->_nExecutionState = SATHTTP::INEXECUTED;
  110. }
  111. else { // 标记脚本失败;
  112. pCase->_nExecutionResult = SATHTTP::FAIL;
  113. }
  114. // 标记任务为执行中;
  115. pTask->_nExecutionState = SATHTTP::INEXECUTED;
  116. // 记录开始时间;
  117. pCase->_ulStartTickCount = GetTickCount64();
  118. pCase->_strStartTime = CTime::GetCurrentTime().Format(_T("%Y-%m-%d %H:%M:%S"));
  119. }
  120. }
  121. else {
  122. //CScriptExecutor *pExcutor = (CScriptExecutor *)pCase->_pExcutor;
  123. }
  124. }
  125. return pCase;
  126. }
  127. void CSATExecutor::AddDevices(const SATDEV::STDevice &stDevice)
  128. {
  129. if ( IsDeviceExist(stDevice.strName) )
  130. return;
  131. SATHTTP::STDevice http_dev;
  132. // 设备使用状态;
  133. if ( stDevice.nStatus == SATDEV::Idle )
  134. http_dev.strStatus = "0";
  135. else if ( stDevice.nStatus == SATDEV::InUse )
  136. http_dev.strStatus = "1";
  137. // 设备序列号;
  138. http_dev.strDeviceSerial = stDevice.strName;
  139. // 余下变量固定值;
  140. http_dev.strComments = "";
  141. http_dev.strCPU = "";
  142. http_dev.strDeviceMac = "";
  143. http_dev.strElectric = "";
  144. http_dev.strHardwareVersion = "SAT-HV";
  145. http_dev.strLastJob = "";
  146. http_dev.strLastJobFinishTime = "";
  147. http_dev.strLastJobStartTime = "";
  148. http_dev.strLastTimeBreak = "";
  149. http_dev.strLastTimeConnected = "";
  150. http_dev.strManu = "";
  151. http_dev.strMemory = "";
  152. http_dev.strModel = "SATModel";
  153. http_dev.strPhoneNumber = "";
  154. http_dev.strSoftwareVersion = "0123456789";
  155. m_vtDevice.push_back(http_dev);
  156. }
  157. void CSATExecutor::DelDevices(const SATDEV::STDevice &stDevice)
  158. {
  159. std::vector<SATHTTP::STDevice>::iterator it = m_vtDevice.begin();
  160. for ( ; it != m_vtDevice.end(); it++ ) {
  161. if ( _tcsicmp(it->strDeviceSerial.c_str(), stDevice.strName.c_str()) == 0 ) {
  162. m_vtDevice.erase(it);
  163. break;
  164. }
  165. }
  166. }
  167. void CSATExecutor::SynchDeviceStatus(std::string strDevName, SATDEV::DEVICE_USAGE_STATUS status)
  168. {
  169. std::vector<SATHTTP::STDevice>::iterator it = m_vtDevice.begin();
  170. for ( ; it != m_vtDevice.end(); it++ ) {
  171. if ( _tcsicmp(it->strDeviceSerial.c_str(), strDevName.c_str()) == 0 ) {
  172. if ( status == SATDEV::Idle )
  173. it->strStatus = "0";
  174. else if ( status == SATDEV::InUse )
  175. it->strStatus = "1";
  176. break;
  177. }
  178. }
  179. CSATDevices::SetDeviceUsageStatus(strDevName, status);
  180. }
  181. bool CSATExecutor::IsDeviceExist(std::string strDevName)
  182. {
  183. bool bExist = false;
  184. std::vector<SATHTTP::STDevice>::iterator it = m_vtDevice.begin();
  185. for ( ; it != m_vtDevice.end(); it++ ) {
  186. if ( _tcsicmp(it->strDeviceSerial.c_str(), strDevName.c_str()) == 0 ) {
  187. bExist = true;
  188. break;
  189. }
  190. }
  191. return bExist;
  192. }
  193. bool CSATExecutor::Login(std::string user, std::string password, std::string actuator, bool bLogin /*= true*/)
  194. {
  195. std::string url = GLOBAL::g_stSATConfig.szExecuteServer;
  196. url.append("/ajaxInteractiveManage!executeLogin.action");
  197. // 填充数据;
  198. m_stLoginReq.strUserName = user;
  199. m_stLoginReq.strPassword = password;
  200. m_stLoginReq.strStatus = bLogin ? "0" : "1"; // 0表示登录;
  201. m_stLoginReq.strDeleteStatus = "";
  202. m_stLoginReq.strIP = GLOBAL::g_strIPAddress;
  203. m_stLoginReq.strStorage = "";
  204. if ( bLogin ) {
  205. m_stLoginReq.strDisconnectTime = "";
  206. m_stLoginReq.strConnectTime = CTime::GetCurrentTime().Format(_T("%Y-%m-%d %H:%M:%S"));
  207. } else {
  208. m_stLoginReq.strConnectTime = "";
  209. m_stLoginReq.strDisconnectTime = CTime::GetCurrentTime().Format(_T("%Y-%m-%d %H:%M:%S"));
  210. }
  211. // 执行器名称;
  212. m_stLoginReq.strExecuteName = m_strActuatorName = actuator;
  213. // 执行器PC物理地址;
  214. m_stLoginReq.strMAC = GLOBAL::g_strMacs;
  215. m_stLoginReq.strCPU = "";
  216. if ( ::Login(url, m_stLoginReq, m_stLoginResp) ) {
  217. GLOBAL::WriteTextLog("登录成功");
  218. m_bLogin = TRUE;
  219. return true;
  220. }
  221. GLOBAL::WriteTextLog("登录失败");
  222. return false;
  223. }
  224. bool CSATExecutor::Logout(std::string user, std::string password)
  225. {
  226. return Login(user, password, false);
  227. }
  228. bool CSATExecutor::UpdateDevice()
  229. {
  230. SATHTTP::STUpdateDeviceReq stUpdateDeviceReq;
  231. SATHTTP::STUpdateDeviceResp stUpdateDeviceResp;
  232. std::string url = GLOBAL::g_stSATConfig.szExecuteServer;
  233. url.append("/ajaxInteractiveManage!updateDeviceMessage.action");
  234. // 这个状态值要怎么设置?// 此处统一为0;
  235. stUpdateDeviceReq.strStatus = "0";
  236. stUpdateDeviceReq.strUserName = m_stLoginReq.strUserName;
  237. stUpdateDeviceReq.strIP = GLOBAL::g_strIPAddress;
  238. stUpdateDeviceReq.strStorage = "";
  239. stUpdateDeviceReq.strRunnerName = m_strActuatorName;
  240. // 这里使用PC物理地址;
  241. stUpdateDeviceReq.strMAC = GLOBAL::g_strMacs;
  242. // 这个reportType具体意义不明;
  243. stUpdateDeviceReq.strReportType = "1";
  244. stUpdateDeviceReq.strStartTime = CTime::GetCurrentTime().Format(_T("%Y-%m-%d %H:%M:%S"));
  245. stUpdateDeviceReq.strMemory = "";
  246. stUpdateDeviceReq.strEndTime = "";
  247. stUpdateDeviceReq.strCPU = "";
  248. stUpdateDeviceReq.devicelist.assign(m_vtDevice.begin(), m_vtDevice.end());
  249. if ( !::UpdateDeviceMessage(url, stUpdateDeviceReq, stUpdateDeviceResp) )
  250. {
  251. GLOBAL::WriteTextLog("更新设备信息失败");
  252. return false;
  253. }
  254. return true;
  255. }
  256. bool CSATExecutor::NotifyTaskStart(SATHTTP::STTask* pTask)
  257. {
  258. if ( !pTask )
  259. return false;
  260. SATHTTP::STNotifyJobStartReq stNotifyJobStartReq;
  261. SATHTTP::STNotifyJobStartResp stNotifyJobStartResp;
  262. std::string url = GLOBAL::g_stSATConfig.szExecuteServer;
  263. url.append("/ajaxInteractiveManage!setResult.action");
  264. TCHAR szValue[36] = {0};
  265. _itoa_s(pTask->nDeviceId, szValue, 10);
  266. stNotifyJobStartReq.strDeviceId = szValue;
  267. _itoa_s(pTask->nExecuteId, szValue, 10);
  268. stNotifyJobStartReq.strExecuteId = szValue;
  269. // _itoa_s(stTask.nInstanceId, szValue, 10); // 误导:应该使用id而不是nInstanceId
  270. _itoa_s(pTask->Id, szValue, 10);
  271. stNotifyJobStartReq.strInstanceId = szValue;
  272. //_itoa_s(pTask->nTaskId, szValue, 10);
  273. stNotifyJobStartReq.strTaskId = pTask->Job.strTaskId;
  274. // 这个映像路径有何用?
  275. stNotifyJobStartReq.strSignalImageUrl = GLOBAL::g_stSATConfig.szScriptDir;
  276. stNotifyJobStartReq.strSignalImageUrl.append(pTask->strTaskName+"\\\\");
  277. stNotifyJobStartReq.strSignalImageUrl.append(pTask->Job.strUniqueId+"\\\\");
  278. stNotifyJobStartReq.strSignalImageUrl.append(pTask->Job.strDeviceId);
  279. if ( SetResult(url, stNotifyJobStartReq, stNotifyJobStartResp) )
  280. {
  281. // 此处可能需要设置设备为忙碌状态;
  282. // SetDeviceStatus(BUSY);
  283. GLOBAL::WriteTextLog("更新任务状态成功:%s", pTask->Job.strUniqueId.c_str());
  284. return true;
  285. }
  286. GLOBAL::WriteTextLog("更新任务状态失败:%s", pTask->Job.strUniqueId.c_str());
  287. return false;
  288. }
  289. bool CSATExecutor::UploadCaseImg(SATHTTP::STTask* pTask, SATHTTP::STCase *pCase, std::string img)
  290. {
  291. TCHAR szValue[MAX_PATH] = {0};
  292. std::string url = GLOBAL::g_stSATConfig.szExecuteServer;
  293. url.append("/ajaxInteractiveManage!saveResultImg.action");
  294. SATHTTP::STSaveImgReq stSaveImgReq;
  295. SATHTTP::STSaveImgResp stSaveImgResp;
  296. stSaveImgReq.strCaseId = pCase->strId;
  297. stSaveImgReq.strCaseRepeat = "0";
  298. _itoa_s(pCase->_nCaseStep, szValue, 10);
  299. stSaveImgReq.strCaseStep = szValue;
  300. // 实例Id;
  301. _itoa_s(pTask->nDeviceId, szValue, 10);
  302. stSaveImgReq.strDeviceId = szValue;//pTask->Job.strDeviceId;
  303. // 就是Task中的ExecuteId
  304. _itoa_s(pTask->nExecuteId, szValue, 10);
  305. stSaveImgReq.strExecuteId = szValue;
  306. // 实例Id;
  307. _itoa_s(pTask->nInstanceId, szValue, 10);
  308. stSaveImgReq.strInstanceId = szValue;
  309. stSaveImgReq.strJobRepeat = "0";
  310. // 注意避坑:roundnum必须赋值0或1;
  311. stSaveImgReq.strRoundNum = "0";
  312. stSaveImgReq.strTaskType = pTask->strTaskType;
  313. stSaveImgReq.strUploads = img;
  314. // 上传用例图片;
  315. if ( SaveResultImg(url, stSaveImgReq, stSaveImgResp) )
  316. {
  317. GLOBAL::WriteTextLog("上传图片成功:任务=%s, 用例=%s, 图片=%s", pTask->Job.strUniqueId.c_str(), pCase->strCaseName.c_str(), img.c_str());
  318. return true;
  319. }
  320. GLOBAL::WriteTextLog("上传图片失败:任务=%s, 用例=%s, 图片=%s", pTask->Job.strUniqueId.c_str(), pCase->strCaseName.c_str(), img.c_str());
  321. return false;
  322. }
  323. bool CSATExecutor::UploadCaseLog(SATHTTP::STTask* pTask, SATHTTP::STCase *pCase)
  324. {
  325. TCHAR szValue[MAX_PATH] = {0};
  326. std::string url = GLOBAL::g_stSATConfig.szExecuteServer;
  327. url.append("/ajaxInteractiveManage!saveCaseOrTaskLog.action");
  328. SATHTTP::STSaveLogReq stSaveLogReq;
  329. SATHTTP::STSaveLogResp stSaveLogResp;
  330. stSaveLogReq.strCaseId = pCase->strId;
  331. // 执行ID;
  332. _itoa_s(pTask->nExecuteId, szValue, 10);
  333. stSaveLogReq.strExecuteId = szValue;
  334. stSaveLogReq.strFileType = "caseLogFile";
  335. // 任务Id;
  336. //_itoa_s(pTask->nTaskId, szValue, 10);
  337. stSaveLogReq.strTaskId = pTask->Job.strTaskInstanceId;
  338. stSaveLogReq.strUserId = pTask->Job.strUserId;
  339. // 要上传的日志文件;
  340. stSaveLogReq.strUploads = pCase->_strCaseLog;
  341. if ( SaveCaseOrTaskLog(url, stSaveLogReq, stSaveLogResp) )
  342. {
  343. GLOBAL::WriteTextLog("上传日志成功:任务=%s, 用例=%s, 日志=%s", pTask->Job.strUniqueId.c_str(), pCase->strCaseName.c_str(), pCase->_strCaseLog.c_str());
  344. return true;
  345. }
  346. GLOBAL::WriteTextLog("上传日志失败:任务=%s, 用例=%s, 日志=%s", pTask->Job.strUniqueId.c_str(), pCase->strCaseName.c_str(), pCase->_strCaseLog.c_str());
  347. return false;
  348. }
  349. bool CSATExecutor::ReportCaseItemFinish(SATHTTP::STTask* pTask, SATHTTP::STCase *pCase, STCaseItem &caseItem)
  350. {
  351. TCHAR szValue[MAX_PATH] = {0};
  352. std::string url = GLOBAL::g_stSATConfig.szExecuteServer;
  353. url.append("/ajaxInteractiveManage!setResultList.action");
  354. SATHTTP::STJobProcessReq stJobProcessReq;
  355. SATHTTP::STJobProcessResp stJobProcessResp;
  356. // 根据测试项结果决定测试项成功与否;
  357. stJobProcessReq.strResultState = caseItem.result ? "1" : "0";
  358. // 如果测试项失败,标记用例和任务失败;
  359. if ( !caseItem.result ) {
  360. pCase->_nExecutionResult = SATHTTP::FAIL;
  361. pTask->_nExecutionResult = SATHTTP::FAIL;
  362. }
  363. stJobProcessReq.strCaseScene = "";
  364. // 索引;
  365. _itoa_s(pCase->_nCaseStep, szValue, 10);
  366. stJobProcessReq.strCaseStep = szValue;
  367. stJobProcessReq.strApkMD5 = "";
  368. stJobProcessReq.strCrashTime = "";
  369. // 就是Task中的ExecuteId
  370. _itoa_s(pTask->nExecuteId, szValue, 10);
  371. stJobProcessReq.strRunnerId = szValue;
  372. stJobProcessReq.strCPUInfo = "0";
  373. stJobProcessReq.strRunnedActionNameList = "";
  374. stJobProcessReq.strArtificialResult = "";
  375. stJobProcessReq.strArtificialModify = "";
  376. stJobProcessReq.strRunnerName = "";
  377. stJobProcessReq.strTaskType = "FUNCTIONALITY";
  378. stJobProcessReq.strCaseRepeat = "0";
  379. stJobProcessReq.strApplicationGroup = "";
  380. // 实例Id;
  381. _itoa_s(pTask->Id, szValue, 10);
  382. stJobProcessReq.strInstanceId = szValue;
  383. stJobProcessReq.strCaseId = pCase->strId;
  384. // 进度;
  385. _itoa_s(100*(atoi(pCase->strIndex.c_str()))/pTask->Job.vtCases.size(), szValue, 10);
  386. stJobProcessReq.strProgress = szValue;
  387. // 需要将utf-8转gbk;
  388. stJobProcessReq.strReusltMessage = caseItem.name;//CharEncoding::UTF82ASCII(caseItem.name.c_str());
  389. stJobProcessReq.strJobRepeat = "0";
  390. stJobProcessReq.strScreenShot = "";
  391. stJobProcessReq.strStartTime = pCase->_strStartTime;
  392. stJobProcessReq.strCrashNumber = "";
  393. stJobProcessReq.strCaseName = pCase->strCaseName;
  394. //stJobProcessReq.strFailedReason = CharEncoding::UTF82ASCII(caseItem.remark.c_str());
  395. //stJobProcessReq.strFailedReason = (char*)CharEncoding::UTF82UNICODE(caseItem.remark.c_str());
  396. stJobProcessReq.strFailedReason = caseItem.remark;
  397. for (std::vector<std::string>::iterator it = caseItem.imgs.begin(); it != caseItem.imgs.end(); it++ )
  398. {
  399. int npos = it->find_last_of('/');
  400. if ( std::string::npos != npos )
  401. {
  402. stJobProcessReq.strImgName.append(it->substr(npos+1));
  403. stJobProcessReq.strImgName.append("&");
  404. }
  405. }
  406. if ( stJobProcessReq.strImgName.size() && stJobProcessReq.strImgName.at(stJobProcessReq.strImgName.size()-1) == '&')
  407. stJobProcessReq.strImgName.erase(stJobProcessReq.strImgName.size()-1);
  408. stJobProcessReq.strCaseIndex = pCase->strIndex;
  409. // 实例Id;
  410. _itoa_s(pTask->nDeviceId, szValue, 10);
  411. stJobProcessReq.strDeviceId = szValue;
  412. stJobProcessReq.strSceneIndex = "0";
  413. // 实例Id;
  414. //_itoa_s(pTask->nTaskId, szValue, 10);
  415. stJobProcessReq.strTaskId = pTask->Job.strTaskId;
  416. //stJobProcessReq.strAnalysis = CharEncoding::UTF82ASCII(caseItem.data.c_str());
  417. stJobProcessReq.strAnalysis = caseItem.data.c_str();
  418. // 设备名称:即DeviceSerial;
  419. stJobProcessReq.strDevnceName = pTask->Job.strDeviceId; // 命名及其不范围,一会deviceid是deviceserial,一会是id;
  420. // 固定为:TOTAL
  421. stJobProcessReq.strInfoType = "";
  422. // 如果是Android设备,需要通过adb获取;
  423. //stJobProcessReq.strMemoryInfo = stDevice.strMemory;
  424. stJobProcessReq.strEndTime = CTime::GetCurrentTime().Format(_T("%Y-%m-%d %H:%M:%S"));//"2019-12-16 10:18:20";
  425. stJobProcessReq.strRoundNumber = "1";
  426. stJobProcessReq.strResultType = "4"; // reportActionFinish;
  427. stJobProcessReq.strOperationStep = "";
  428. if ( SetResultList(url, stJobProcessReq, stJobProcessResp) )
  429. {
  430. GLOBAL::WriteTextLog("上传【用例测试项】结果完成【成功】:任务=%s, 用例=%s", pTask->Job.strUniqueId.c_str(), pCase->strCaseName.c_str());
  431. // 再上传图片;
  432. std::string img;
  433. for (std::vector<std::string>::iterator it = caseItem.imgs.begin(); it != caseItem.imgs.end(); it++ )
  434. {
  435. img = GLOBAL::g_stSATConfig.szCaseResultDir;
  436. img.append(it->substr(3));
  437. img = GLOBAL::Replace(img, "/", "\\");
  438. GLOBAL::WriteTextLog("图片路径=%s", img.c_str());
  439. UploadCaseImg(pTask, pCase, img);
  440. }
  441. return true;
  442. }
  443. GLOBAL::WriteTextLog("上传【用例测试项】结果完成【失败】:任务=%s, 用例=%s", pTask->Job.strUniqueId.c_str(), pCase->strCaseName.c_str());
  444. return false;
  445. }
  446. bool CSATExecutor::ReportCaseFinish(SATHTTP::STTask* pTask, SATHTTP::STCase *pCase)
  447. {
  448. TCHAR szValue[MAX_PATH] = {0};
  449. std::string url = GLOBAL::g_stSATConfig.szExecuteServer;
  450. url.append("/ajaxInteractiveManage!setResultList.action");
  451. SATHTTP::STJobProcessReq stJobProcessReq;
  452. SATHTTP::STJobProcessResp stJobProcessResp;
  453. // 上报用例结果:0表示脚本成功执行, 1表示脚本出错或超时;
  454. if ( pCase->_nExecutionState == SATHTTP::EXECUTED )
  455. {
  456. if ( pCase->_nExecutionResult == SATHTTP::SUCCESS )
  457. stJobProcessReq.strResultState = "0"; // 脚本未执行完成;
  458. else
  459. {
  460. if ( pCase->_nExecutionResult == SATHTTP::ABNORMAL )
  461. stJobProcessReq.strFailedReason = CharEncoding::ASCII2UTF8("脚本异常结束");
  462. stJobProcessReq.strResultState = "1";
  463. // 同时标记任务失败;
  464. pTask->_nExecutionResult = SATHTTP::FAIL;
  465. }
  466. }
  467. else
  468. {
  469. stJobProcessReq.strResultState = "1"; // 脚本执行未完成,认为fail;
  470. // 同时标记任务失败;
  471. pTask->_nExecutionResult = SATHTTP::FAIL;
  472. }
  473. stJobProcessReq.strCaseScene = "";
  474. // 索引;
  475. _itoa_s(pCase->_nCaseStep, szValue, 10);
  476. stJobProcessReq.strCaseStep = szValue;
  477. stJobProcessReq.strApkMD5 = "";
  478. stJobProcessReq.strCrashTime = "";
  479. // 就是Task中的ExecuteId
  480. _itoa_s(pTask->nExecuteId, szValue, 10);
  481. stJobProcessReq.strRunnerId = szValue;
  482. stJobProcessReq.strCPUInfo = "0";
  483. stJobProcessReq.strRunnedActionNameList = "";
  484. stJobProcessReq.strArtificialResult = "";
  485. stJobProcessReq.strArtificialModify = "";
  486. stJobProcessReq.strRunnerName = "";
  487. stJobProcessReq.strTaskType = "FUNCTIONALITY";
  488. stJobProcessReq.strCaseRepeat = "";
  489. stJobProcessReq.strApplicationGroup = "";
  490. // 实例Id;注意避坑;
  491. _itoa_s(pTask->Id, szValue, 10);
  492. stJobProcessReq.strInstanceId = szValue;
  493. stJobProcessReq.strCaseId = pCase->strId;
  494. // 进度(###需要修改此处###);
  495. _itoa_s(100*(atoi(pCase->strIndex.c_str()))/pTask->Job.vtCases.size(), szValue, 10);
  496. stJobProcessReq.strProgress = szValue;
  497. // 需要将utf-8转gbk;
  498. stJobProcessReq.strReusltMessage = CharEncoding::ASCII2UTF8("测试用例结果:");
  499. stJobProcessReq.strJobRepeat = "";
  500. stJobProcessReq.strScreenShot = "";
  501. stJobProcessReq.strStartTime = pCase->_strStartTime;
  502. stJobProcessReq.strCrashNumber = "";
  503. stJobProcessReq.strCaseName = pCase->strCaseName;
  504. stJobProcessReq.strImgName = "";
  505. stJobProcessReq.strCaseIndex = pCase->strIndex;
  506. // 实例Id;
  507. _itoa_s(pTask->nDeviceId, szValue, 10);
  508. stJobProcessReq.strDeviceId = szValue;
  509. stJobProcessReq.strSceneIndex = "0";
  510. // 实例Id;
  511. //_itoa_s(pTask->nTaskId, szValue, 10);
  512. stJobProcessReq.strTaskId = pTask->Job.strTaskId;
  513. stJobProcessReq.strAnalysis = "";
  514. // 设备名称:即DeviceSerial;
  515. stJobProcessReq.strDevnceName = pTask->Job.strDeviceId; // 命名及其不范围,一会deviceid是deviceserial,一会是id;
  516. // 固定为:TOTAL
  517. stJobProcessReq.strInfoType = "TOTAL";
  518. // 如果是Android设备,需要通过adb获取;
  519. //stJobProcessReq.strMemoryInfo = stDevice.strMemory;
  520. stJobProcessReq.strEndTime = pCase->_strEndTime;//CTime::GetCurrentTime().Format(_T("%Y-%m-%d %H:%M:%S"));//"2019-12-16 10:18:20";
  521. stJobProcessReq.strRoundNumber = "1";
  522. stJobProcessReq.strResultType = "5"; // reportCaseFinish;
  523. stJobProcessReq.strOperationStep = "";
  524. if ( SetResultList(url, stJobProcessReq, stJobProcessResp) )
  525. {
  526. GLOBAL::WriteTextLog("上传用例结果完成【成功】:任务=%s, 用例=%s", pTask->Job.strUniqueId.c_str(), pCase->strCaseName.c_str());
  527. return true;
  528. }
  529. GLOBAL::WriteTextLog("上传用例结果完成【失败】:任务=%s, 用例=%s", pTask->Job.strUniqueId.c_str(), pCase->strCaseName.c_str());
  530. return false;
  531. }
  532. bool CSATExecutor::ReportCaseResult(SATHTTP::STTask* pTask, SATHTTP::STCase *pCase)
  533. {
  534. // 获取xml文件内容;
  535. std::string xmlpath = GLOBAL::g_stSATConfig.szCaseResultDir;
  536. xmlpath.append("detail\\");
  537. xmlpath.append(pCase->_strFileName);
  538. xmlpath.append("_result.xml");
  539. std::vector<STCaseItem> vtCaseItem;
  540. GetCaseXMLResult(xmlpath, vtCaseItem);
  541. // 如果测试项空,任务失败;
  542. if ( vtCaseItem.size() == 0 ) {
  543. pCase->_nExecutionResult = SATHTTP::ABNORMAL;
  544. // 同时标记任务失败;
  545. pTask->_nExecutionResult = SATHTTP::FAIL;
  546. }
  547. int nIndex = 1;
  548. TCHAR szValue[MAX_PATH] = {0};
  549. std::string url = GLOBAL::g_stSATConfig.szExecuteServer;
  550. url.append("/ajaxInteractiveManage!setResultList.action");
  551. SATHTTP::STJobProcessReq stJobProcessReq;
  552. SATHTTP::STJobProcessResp stJobProcessResp;
  553. // 遍历所有用例测试项;
  554. std::vector<STCaseItem>::iterator it = vtCaseItem.begin();
  555. for (; it != vtCaseItem.end(); it++ )
  556. {
  557. // 上报测试项结果(包含相片);
  558. ReportCaseItemFinish(pTask, pCase, *it);
  559. }
  560. // 上报用例完成;
  561. ReportCaseFinish(pTask, pCase);
  562. // 上传用例日志;
  563. UploadCaseLog(pTask, pCase);
  564. // 删除执行对象;
  565. if ( pCase->_pExcutor )
  566. delete pCase->_pExcutor;
  567. pCase->_pExcutor = NULL;
  568. GLOBAL::WriteTextLog(_T("用例已完成,执行器对象删除成功,脚本用例名为=%s"), pCase->strCaseName.c_str());
  569. return true;
  570. }
  571. bool CSATExecutor::UploadTaskLog(SATHTTP::STTask* pTask)
  572. {
  573. TCHAR szValue[MAX_PATH] = {0};
  574. std::string url = GLOBAL::g_stSATConfig.szExecuteServer;
  575. url.append("/ajaxInteractiveManage!saveCaseOrTaskLog.action");
  576. SATHTTP::STSaveLogReq stSaveLogReq;
  577. SATHTTP::STSaveLogResp stSaveLogResp;
  578. stSaveLogReq.strCaseId = "";
  579. // 执行ID;
  580. _itoa_s(pTask->nExecuteId, szValue, 10);
  581. stSaveLogReq.strExecuteId = szValue;
  582. stSaveLogReq.strFileType = "taskLogFile";
  583. // 任务Id;
  584. //_itoa_s(pTask->nTaskId, szValue, 10);
  585. stSaveLogReq.strTaskId = pTask->Job.strTaskInstanceId;
  586. stSaveLogReq.strUserId = pTask->Job.strUserId;
  587. // 要上传的日志文件;
  588. stSaveLogReq.strUploads = "D:\\sat\\log.txt";//pTask->_strTaskLog;
  589. if ( SaveCaseOrTaskLog(url, stSaveLogReq, stSaveLogResp) )
  590. {
  591. GLOBAL::WriteTextLog(_T("任务已完成,上传任务日志【成功】,任务编号为=%s"), pTask->Job.strUniqueId.c_str());
  592. return true;
  593. }
  594. GLOBAL::WriteTextLog(_T("任务已完成,上传任务日志【失败】,任务编号为=%s"), pTask->Job.strUniqueId.c_str());
  595. return false;
  596. }
  597. bool CSATExecutor::ReportTaskStart(SATHTTP::STTask* pTask)
  598. {
  599. TCHAR szValue[MAX_PATH] = {0};
  600. std::string url = GLOBAL::g_stSATConfig.szExecuteServer;
  601. url.append("/ajaxInteractiveManage!setResultList.action");
  602. SATHTTP::STJobProcessReq stJobProcessReq;
  603. SATHTTP::STJobProcessResp stJobProcessResp;
  604. // 需要处理###
  605. stJobProcessReq.strResultState = ""; // 脚本执行中,认为fail;
  606. stJobProcessReq.strCaseScene = "";
  607. // 索引;
  608. stJobProcessReq.strCaseStep = "0";
  609. stJobProcessReq.strApkMD5 = "";
  610. stJobProcessReq.strCrashTime = "";
  611. // 就是Task中的ExecuteId
  612. _itoa_s(pTask->nExecuteId, szValue, 10);
  613. stJobProcessReq.strRunnerId = szValue;
  614. stJobProcessReq.strCPUInfo = "0";
  615. stJobProcessReq.strRunnedActionNameList = "";
  616. stJobProcessReq.strArtificialResult = "";
  617. stJobProcessReq.strArtificialModify = "";
  618. stJobProcessReq.strRunnerName = "";
  619. stJobProcessReq.strTaskType = "FUNCTIONALITY";
  620. stJobProcessReq.strCaseRepeat = "";
  621. stJobProcessReq.strApplicationGroup = "";
  622. // 实例Id;注意避坑;
  623. _itoa_s(pTask->Id, szValue, 10);
  624. stJobProcessReq.strInstanceId = szValue;
  625. stJobProcessReq.strCaseId = "";
  626. // 进度(###需要修改此处###);
  627. stJobProcessReq.strProgress = "0";
  628. // 需要将utf-8转gbk;
  629. stJobProcessReq.strReusltMessage = "任务开始";
  630. stJobProcessReq.strJobRepeat = "";
  631. stJobProcessReq.strScreenShot = "";
  632. stJobProcessReq.strStartTime = pTask->strStartTime;
  633. stJobProcessReq.strCrashNumber = "";
  634. stJobProcessReq.strCaseName = "";
  635. stJobProcessReq.strFailedReason = "";
  636. stJobProcessReq.strImgName = "";
  637. stJobProcessReq.strCaseIndex = "";
  638. // 实例Id;
  639. _itoa_s(pTask->nDeviceId, szValue, 10);
  640. stJobProcessReq.strDeviceId = szValue;
  641. stJobProcessReq.strSceneIndex = "";
  642. // 实例Id;
  643. //_itoa_s(pTask->nTaskId, szValue, 10);
  644. stJobProcessReq.strTaskId = pTask->Job.strTaskId;
  645. stJobProcessReq.strAnalysis = "";
  646. // 设备名称:即DeviceSerial;
  647. stJobProcessReq.strDevnceName = pTask->Job.strDeviceId; // 命名及其不范围,一会deviceid是deviceserial,一会是id;
  648. // 固定为:TOTAL
  649. stJobProcessReq.strInfoType = "TOTAL";
  650. // 如果是Android设备,需要通过adb获取;
  651. //stJobProcessReq.strMemoryInfo = stDevice.strMemory;
  652. stJobProcessReq.strEndTime = "";// CTime::GetCurrentTime().Format(_T("%Y-%m-%d %H:%M:%S"));//"2019-12-16 10:18:20";
  653. stJobProcessReq.strRoundNumber = "1";
  654. stJobProcessReq.strResultType = "0"; // reportJobStart;
  655. stJobProcessReq.strOperationStep = "";
  656. if ( SetResultList(url, stJobProcessReq, stJobProcessResp) )
  657. {
  658. GLOBAL::WriteTextLog(_T("上报任务开始【成功】,任务编号为=%s"), pTask->Job.strUniqueId.c_str());
  659. return true;
  660. }
  661. GLOBAL::WriteTextLog(_T("上报任务开始【失败】,任务编号为=%s"), pTask->Job.strUniqueId.c_str());
  662. return false;
  663. }
  664. bool CSATExecutor::ReportTaskFinish(SATHTTP::STTask* pTask)
  665. {
  666. TCHAR szValue[MAX_PATH] = {0};
  667. std::string url = GLOBAL::g_stSATConfig.szExecuteServer;
  668. url.append("/ajaxInteractiveManage!setResultList.action");
  669. SATHTTP::STJobProcessReq stJobProcessReq;
  670. SATHTTP::STJobProcessResp stJobProcessResp;
  671. // 需要处理(只要有用例失败,任务就失败)
  672. if ( pTask->_nExecutionState == SATHTTP::EXECUTED )
  673. {
  674. if ( pTask->_nExecutionResult == SATHTTP::SUCCESS )
  675. stJobProcessReq.strResultState = "0"; // 脚本执行中,认为fail;
  676. else
  677. stJobProcessReq.strResultState = "1"; // 脚本执行中,认为fail;
  678. }
  679. else
  680. stJobProcessReq.strResultState = "1"; // 脚本执行中,认为fail;
  681. stJobProcessReq.strCaseScene = "";
  682. // 索引;
  683. stJobProcessReq.strCaseStep = "0";
  684. stJobProcessReq.strApkMD5 = "";
  685. stJobProcessReq.strCrashTime = "";
  686. // 就是Task中的ExecuteId
  687. _itoa_s(pTask->nExecuteId, szValue, 10);
  688. stJobProcessReq.strRunnerId = szValue;
  689. stJobProcessReq.strCPUInfo = "0";
  690. stJobProcessReq.strRunnedActionNameList = "";
  691. stJobProcessReq.strArtificialResult = "";
  692. stJobProcessReq.strArtificialModify = "";
  693. stJobProcessReq.strRunnerName = "";
  694. stJobProcessReq.strTaskType = "FUNCTIONALITY";
  695. stJobProcessReq.strCaseRepeat = "0";
  696. stJobProcessReq.strApplicationGroup = "";
  697. // 实例Id;注意避坑;
  698. _itoa_s(pTask->Id, szValue, 10);
  699. stJobProcessReq.strInstanceId = szValue;
  700. stJobProcessReq.strCaseId = "";
  701. // 进度(###需要修改此处###);
  702. stJobProcessReq.strProgress = "100";
  703. // 需要将utf-8转gbk;
  704. stJobProcessReq.strReusltMessage = "任务结束";
  705. stJobProcessReq.strJobRepeat = "0";
  706. stJobProcessReq.strScreenShot = "";
  707. stJobProcessReq.strStartTime = pTask->strStartTime;
  708. stJobProcessReq.strCrashNumber = "";
  709. stJobProcessReq.strCaseName = "";
  710. stJobProcessReq.strFailedReason = "";
  711. stJobProcessReq.strImgName = "";
  712. stJobProcessReq.strCaseIndex = "";
  713. // 实例Id;
  714. _itoa_s(pTask->nDeviceId, szValue, 10);
  715. stJobProcessReq.strDeviceId = szValue;
  716. stJobProcessReq.strSceneIndex = "0";
  717. // 实例Id;
  718. //_itoa_s(pTask->nTaskId, szValue, 10);
  719. stJobProcessReq.strTaskId = pTask->Job.strTaskId;
  720. stJobProcessReq.strAnalysis = "";
  721. // 设备名称:即DeviceSerial;
  722. stJobProcessReq.strDevnceName = pTask->Job.strDeviceId; // 命名及其不范围,一会deviceid是deviceserial,一会是id;
  723. // 固定为:TOTAL
  724. stJobProcessReq.strInfoType = "";
  725. // 如果是Android设备,需要通过adb获取;
  726. //stJobProcessReq.strMemoryInfo = stDevice.strMemory;
  727. stJobProcessReq.strEndTime = CTime::GetCurrentTime().Format(_T("%Y-%m-%d %H:%M:%S"));//"2019-12-16 10:18:20";
  728. stJobProcessReq.strRoundNumber = "1";
  729. stJobProcessReq.strResultType = "1"; // reportJobFinish;
  730. stJobProcessReq.strOperationStep = "";
  731. if ( SetResultList(url, stJobProcessReq, stJobProcessResp) )
  732. {
  733. GLOBAL::WriteTextLog(_T("上报任务结束【成功】,任务编号为=%s"), pTask->Job.strUniqueId.c_str());
  734. return true;
  735. }
  736. GLOBAL::WriteTextLog(_T("上报任务结束【成功】,任务编号为=%s"), pTask->Job.strUniqueId.c_str());
  737. return false;
  738. }
  739. bool CSATExecutor::GetCaseXMLResult(std::string xmlpath, std::vector<STCaseItem> &vtCaseItem)
  740. {
  741. // 解析xml;
  742. tinyxml2::XMLDocument doc;
  743. if (tinyxml2::XML_SUCCESS != doc.LoadFile(xmlpath.c_str()) ) {
  744. return false;
  745. }
  746. tinyxml2::XMLElement *pXmlRoot = NULL;
  747. if ((pXmlRoot = doc.RootElement()) == NULL)
  748. return false;
  749. if (_tcsicmp(pXmlRoot->Value(), "results") != 0)
  750. return false;
  751. tinyxml2::XMLElement *pXmlElent = pXmlRoot->FirstChildElement();
  752. while (pXmlElent) {
  753. if (_tcsicmp(pXmlElent->Value(), _T("item")) == 0) {
  754. STCaseItem cItem;
  755. tinyxml2::XMLElement *pItem = pXmlElent->FirstChildElement();
  756. while (pItem) {
  757. if (_tcsicmp(pItem->Value(), _T("name")) == 0)
  758. {
  759. cItem.name = pItem->GetText();
  760. }
  761. else if (_tcsicmp(pItem->Value(), _T("result")) == 0)
  762. {
  763. cItem.result = pItem->BoolText();
  764. }
  765. else if (_tcsicmp(pItem->Value(), _T("data")) == 0)
  766. {
  767. cItem.data = pItem->GetText();
  768. }
  769. else if (_tcsicmp(pItem->Value(), _T("log")) == 0)
  770. {
  771. cItem.log = pItem->GetText();
  772. }
  773. else if (_tcsicmp(pItem->Value(), _T("remark")) == 0)
  774. {
  775. cItem.remark = pItem->GetText();
  776. }
  777. else if (_tcsicmp(pItem->Value(), _T("screen")) == 0)
  778. {
  779. cItem.imgs.push_back(pItem->GetText());
  780. }
  781. pItem = pItem->NextSiblingElement();
  782. }
  783. // 压入容器;
  784. if ( cItem.name.size() )
  785. vtCaseItem.push_back(cItem);
  786. }
  787. pXmlElent = pXmlElent->NextSiblingElement();
  788. }
  789. return true;
  790. }
  791. int CSATExecutor::AttachTaskInfo2Buffer(SATPROTO::TaskInfo (&pbuff)[SATPROTO::MAX_TASKS])
  792. {
  793. int count = 0;
  794. if ( pbuff ) {
  795. AutoThreadSection ats(&m_csTask);
  796. std::list<SATHTTP::STTask>::iterator it = m_vtTask.begin();
  797. for ( ;it != m_vtTask.end(); it++ ) {
  798. pbuff[count].nStatus = it->_nExecutionState;
  799. pbuff[count].nTaskId = it->Id;
  800. memcpy_s(pbuff[count].szTaskNo, SATPROTO::MAX_NAME, it->Job.strUniqueId.c_str(), it->Job.strUniqueId.size());
  801. memcpy_s(pbuff[count].szTaskName, SATPROTO::MAX_NAME, it->strTaskName.c_str(), it->strTaskName.size());
  802. int nIndex = 0;
  803. for (std::vector<SATHTTP::STCase>::iterator _case = it->Job.vtCases.begin(); _case != it->Job.vtCases.end(); _case++) {
  804. pbuff[count].ssCases[nIndex].nStatus = _case->_nExecutionState;
  805. //pbuff[count].ssCases[nIndex].nCaseId = _case->_nCaseStep;
  806. memcpy_s(pbuff[count].ssCases[nIndex].szCaseName, SATPROTO::MAX_NAME, _case->strCaseName.c_str(), _case->strCaseName.size());
  807. nIndex++;
  808. }
  809. count++;
  810. // 超过MAX_TASKS退出;
  811. if ( count == SATPROTO::MAX_TASKS )
  812. break;
  813. }
  814. }
  815. return count;
  816. }
  817. void CSATExecutor::StartWork()
  818. {
  819. m_hEventHearbeat = CreateEvent(NULL, TRUE, FALSE, NULL);
  820. if ( m_hEventHearbeat == NULL ) {
  821. _tprintf_s(_T("创建事件失败\n"));
  822. return;
  823. }
  824. m_hEventExcuteScript = CreateEvent(NULL, TRUE, FALSE, NULL);
  825. if ( m_hEventExcuteScript == NULL ) {
  826. _tprintf_s(_T("创建事件失败2\n"));
  827. return;
  828. }
  829. m_hThreadHearbeat = CreateThread(NULL, 0, HearbeatThread, this, 0, NULL);
  830. if ( m_hThreadHearbeat == NULL) {
  831. SetEvent(m_hEventHearbeat);
  832. SetEvent(m_hEventExcuteScript);
  833. CloseHandle(m_hEventHearbeat);
  834. CloseHandle(m_hEventExcuteScript);
  835. m_hEventHearbeat = NULL;
  836. m_hEventExcuteScript = NULL;
  837. _tprintf_s(_T("创建线程失败\n"));
  838. return;
  839. }
  840. m_hThreadExcuteScript = CreateThread(NULL, 0, ExecuteScriptThread, this, 0, NULL);
  841. if ( m_hThreadExcuteScript == NULL ) {
  842. SetEvent(m_hEventHearbeat);
  843. SetEvent(m_hEventExcuteScript);
  844. CloseHandle(m_hEventHearbeat);
  845. CloseHandle(m_hEventExcuteScript);
  846. m_hEventHearbeat = NULL;
  847. m_hEventExcuteScript = NULL;
  848. WaitForSingleObject(m_hThreadHearbeat,INFINITE);
  849. if (m_hThreadHearbeat)
  850. CloseHandle(m_hThreadHearbeat);
  851. m_hThreadHearbeat = NULL;
  852. _tprintf_s(_T("创建线程失败2\n"));
  853. return;
  854. }
  855. }
  856. void CSATExecutor::EndofWork()
  857. {
  858. //////////////////////////////////////////////////////////////////////////
  859. // 设置事件有信号;
  860. if ( m_hEventHearbeat )
  861. SetEvent(m_hEventHearbeat);
  862. // 等待线程结束;
  863. if ( m_hThreadHearbeat ) {
  864. WaitForSingleObject(m_hThreadHearbeat, INFINITE);
  865. CloseHandle(m_hThreadHearbeat);
  866. m_hThreadHearbeat = NULL;
  867. }
  868. // 关闭事件句柄;
  869. if ( m_hEventHearbeat ) {
  870. CloseHandle(m_hEventHearbeat);
  871. m_hEventHearbeat = NULL;
  872. }
  873. //////////////////////////////////////////////////////////////////////////
  874. // 设置事件有信号;
  875. if ( m_hEventExcuteScript )
  876. SetEvent(m_hEventExcuteScript);
  877. // 等待线程结束;
  878. if ( m_hThreadExcuteScript ) {
  879. WaitForSingleObject(m_hThreadExcuteScript, INFINITE);
  880. CloseHandle(m_hThreadExcuteScript);
  881. m_hThreadExcuteScript = NULL;
  882. }
  883. // 关闭事件句柄;
  884. if ( m_hEventExcuteScript ) {
  885. CloseHandle(m_hEventExcuteScript);
  886. m_hEventExcuteScript = NULL;
  887. }
  888. // 如果有脚本在执行,结束脚本;
  889. CPythonExecutor *pExecutor = NULL;
  890. for ( std::list<SATHTTP::STTask>::iterator it = m_vtTask.begin(); it != m_vtTask.end(); it++ ) {
  891. for ( std::vector<SATHTTP::STCase>::iterator _case = it->Job.vtCases.begin(); _case != it->Job.vtCases.end(); _case++ ) {
  892. if ( (pExecutor = (CPythonExecutor *)_case->_pExcutor) ) {
  893. pExecutor->EndThread();
  894. delete pExecutor;
  895. pExecutor = NULL;
  896. }
  897. }
  898. }
  899. m_vtTask.clear();
  900. }
  901. DWORD CSATExecutor::HearbeatThread(LPVOID lpVoid)
  902. {
  903. CSATExecutor *that = (CSATExecutor*)lpVoid;
  904. if ( !that ) return 0;
  905. do {
  906. // 没有登录成功,不查询;
  907. if ( !that->m_bLogin ) continue;
  908. // 更新设备;
  909. that->UpdateDevice();
  910. // 脚本保存目录;
  911. std::string strScriptSaveDir;
  912. SATHTTP::STHeartbeatReq stHeartbeatReq;
  913. SATHTTP::STHeartbeatResp stHeartbeatResp;
  914. std::string url = GLOBAL::g_stSATConfig.szExecuteServer;
  915. url.append("/ajaxInteractiveManage!executeHeartbeat.action");
  916. stHeartbeatReq.strUserName = that->m_stLoginReq.strUserName;
  917. stHeartbeatReq.strRunnerMac = that->m_stLoginReq.strMAC;
  918. stHeartbeatReq.devicelist.assign(that->m_vtDevice.begin(), that->m_vtDevice.end());
  919. if ( Heartbeat(url, stHeartbeatReq, stHeartbeatResp) ) {
  920. std::vector<SATHTTP::STTask>::iterator it = stHeartbeatResp.vtTask.begin();
  921. for ( ; it != stHeartbeatResp.vtTask.end(); it++ ) {
  922. if (!that->IsTaskExist(*it)) {
  923. // 将任务压入队列中;
  924. AutoThreadSection ats(&that->m_csTask);
  925. // 同时下载任务;
  926. std::string host = GLOBAL::g_stSATConfig.szCaseServer;
  927. std::string url = host + "/ajaxInteractiveManage!getCaseFileListUrl.action";
  928. std::vector<SATHTTP::STCase>::iterator _case = it->Job.vtCases.begin();
  929. for ( int i = 1; _case != it->Job.vtCases.end(); _case++) {
  930. // 下载脚本;
  931. _case->_nCaseStep = i++;
  932. SATHTTP::STScriptUrlResp stScriptUrlResp;
  933. // 脚本保存路径;
  934. strScriptSaveDir = GLOBAL::g_stSATConfig.szScriptDir;
  935. strScriptSaveDir.append(it->Job.strProjectName+"\\");
  936. strScriptSaveDir.append(it->Job.strUniqueId+"\\");
  937. // 把冒号改成下划线;
  938. strScriptSaveDir.append(GLOBAL::Replace(it->Job.strDeviceId, "_", ":")+"\\");
  939. if ( DownloadScript(url, _case->strId, strScriptSaveDir, stScriptUrlResp) ) {
  940. _case->_strFileDir = stScriptUrlResp._strFileDir;
  941. _case->_strFileName = stScriptUrlResp._strFileName;
  942. _case->_strScriptPath = stScriptUrlResp._strScripFile;
  943. }
  944. }
  945. that->m_vtTask.push_back(*it);
  946. // 通知SAT服务器,脚本开始执行;
  947. // 待开发:同时将任务存储到数据库中;
  948. /*
  949. db process
  950. */
  951. }
  952. }
  953. }
  954. } while ( WaitForSingleObject(that->m_hEventHearbeat, 5000) == WAIT_TIMEOUT );
  955. return 0;
  956. }
  957. DWORD CSATExecutor::ExecuteScriptThread(LPVOID lpVoid)
  958. {
  959. CSATExecutor *that = (CSATExecutor*)lpVoid;
  960. if ( !that ) return 0;
  961. do {
  962. // 删除已完成的任务;
  963. that->DelFinishedTask();
  964. // 是否有任务在执行;
  965. SATHTTP::STTask *pTask = that->IsThereATaskInProcess();
  966. if ( pTask ) {// 有任务在执行中;
  967. if ( pTask->_bConcurrent ) {// 并发;
  968. }
  969. else {// 串行;
  970. // 是否有脚本用例在执行;
  971. SATHTTP::STCase* pCase = that->IsCaseScriptProcess(pTask->Job.vtCases);
  972. if ( pCase ) {
  973. CPythonExecutor *pExcutor = (CPythonExecutor*)pCase->_pExcutor;
  974. if ( pExcutor ) {
  975. if ( pExcutor->IsScriptOver() ) {
  976. // 标记脚本已执行;
  977. pCase->_nExecutionState = SATHTTP::EXECUTED;
  978. // 如果脚本异常,标记任务失败;
  979. if ( pCase->_nExecutionResult == SATHTTP::ABNORMAL ) {
  980. // 设置任务执行结果失败;
  981. pTask->_nExecutionResult = SATHTTP::FAIL;
  982. GLOBAL::WriteTextLog("用例脚本异常退出(%s)", pCase->strCaseName.c_str());
  983. }
  984. // 上报服务器,完成脚本用例,并上传用例结果;
  985. that->ReportCaseResult(pTask, pCase);
  986. }
  987. else {
  988. // 判断是否超时;
  989. ULONGLONG ulCurTickCount = GetTickCount64();
  990. if ( ulCurTickCount - pExcutor->GetActiveTickCount() > GLOBAL::g_stSATConfig.dwScriptTimeout ) {
  991. // 结束进程;
  992. pExcutor->EndSubprocess();
  993. // 超时中断;
  994. pCase->_nExecutionState = 3;
  995. // 上报用例结果;
  996. that->ReportCaseResult(pTask, pCase);
  997. }
  998. }
  999. }
  1000. }
  1001. else {
  1002. // 没有在执行的用例,开始执行新的用例;
  1003. pCase = that->ExecuteFreeCaseScript(pTask);
  1004. if ( NULL == pCase ) {
  1005. // 没有空闲的用例可执行,说明所有用例已执行完成;
  1006. pTask->_nExecutionState = 2;
  1007. // 上报任务完成;
  1008. that->ReportTaskFinish(pTask);
  1009. // 上报任务结果;
  1010. that->UploadTaskLog(pTask);
  1011. }
  1012. }
  1013. }
  1014. }
  1015. else {
  1016. // 获取空闲的任务;
  1017. pTask = that->GetFreeTask();
  1018. if ( pTask ) {
  1019. // 是否支持并发;
  1020. if ( pTask->_bConcurrent ) {
  1021. // 暂时全部一起并发;
  1022. std::vector<SATHTTP::STCase>::iterator _case = pTask->Job.vtCases.begin();
  1023. for ( ; _case != pTask->Job.vtCases.end(); _case++) {
  1024. if (!_case->_pExcutor) {
  1025. CPythonExecutor *pExcutor = new CPythonExecutor();
  1026. if ( pExcutor ) {
  1027. _case->_pExcutor = pExcutor;
  1028. pExcutor->InitScript(_case->_strScriptPath, _case->_strFileDir + "\\" + _case->_strFileName + ".txt", "");
  1029. pExcutor->StartScript();
  1030. // 标记用例执行中;
  1031. _case->_nExecutionState = 1;
  1032. }
  1033. }
  1034. }
  1035. // 标记任务为执行中;
  1036. pTask->_nExecutionState = 1;
  1037. }
  1038. else {
  1039. // 是否有用例脚本在执行;
  1040. SATHTTP::STCase* pCase = that->IsCaseScriptProcess(pTask->Job.vtCases);
  1041. if ( !pCase ) {
  1042. // 执行空闲用例脚本;
  1043. that->ExecuteFreeCaseScript(pTask);
  1044. }
  1045. }
  1046. // 通知SAT服务器,脚本开始执行;
  1047. that->NotifyTaskStart(pTask);
  1048. // 通知SAT服务器,脚本开始;
  1049. that->ReportTaskStart(pTask);
  1050. }
  1051. }
  1052. } while ( WaitForSingleObject(that->m_hEventExcuteScript, 10000) == WAIT_TIMEOUT );
  1053. return 0;
  1054. }
  1055. DWORD CSATExecutor::WathTVPortThread(PVOID lpVoid)
  1056. {
  1057. CSynSerial tv;
  1058. std::string buffer;
  1059. TCHAR szLastPort[10] = {0};
  1060. _tcscpy_s(szLastPort, GLOBAL::g_stSATConfig.szTVPort);
  1061. std::vector<std::string> vtNotifyReboot;
  1062. std::vector<std::string> vtNotifyShutdown;
  1063. DWORD dwTickCount = GetTickCount();
  1064. /*
  1065. while(!g_bStopThread)
  1066. {
  1067. // 读取配置文件;
  1068. GLOBAL::GetIniInfo();
  1069. if ( !GLOBAL::g_stSATConfig.bWatchTVPort )
  1070. {
  1071. Sleep(5000);
  1072. continue;
  1073. }
  1074. if ( GetTickCount() - dwTickCount > 5000 )
  1075. {// 5秒更新一次;
  1076. dwTickCount = GetTickCount();
  1077. vtNotifyReboot.clear();
  1078. vtNotifyShutdown.clear();
  1079. GLOBAL::Split(GLOBAL::g_stSATConfig.szTVReboot, _T(";"), vtNotifyReboot);
  1080. GLOBAL::Split(GLOBAL::g_stSATConfig.szTVShutdown, _T(";"), vtNotifyShutdown);
  1081. }
  1082. // 串口是否变更;
  1083. if ( _tcsicmp(szLastPort, GLOBAL::g_stSATConfig.szTVPort) )
  1084. {
  1085. _tcscpy_s(szLastPort, GLOBAL::g_stSATConfig.szTVPort);
  1086. // 重启打开串口;
  1087. tv.CloseSerialPort();
  1088. }
  1089. if ( !tv.IsOpen() )
  1090. {
  1091. tv.OpenSerialPort(szLastPort, 115200, 8, 0, 1, 0, 1000);
  1092. }
  1093. if ( tv.IsOpen() )
  1094. {
  1095. BYTE szBuffer[1024] = {0};
  1096. DWORD dwBuffer = tv.ReadComm(szBuffer, 1024, 1000);
  1097. if ( dwBuffer != 0 )
  1098. {
  1099. int nType = 0; // 0表示无异常类型,-1表示关机异常,1表示重启异常;
  1100. bool bAbnormal = false;
  1101. buffer = (char*)szBuffer;
  1102. __time64_t gmt = time(NULL);// 获取当前日历时间(1900-01-01开始的Unix时间戳);
  1103. // 遍历是否有符合的子串;
  1104. for ( std::vector<std::string>::iterator it = vtNotifyReboot.begin(); it != vtNotifyReboot.end(); it++ )
  1105. {
  1106. if ( _tcsstr(buffer.c_str(), it->c_str()) )
  1107. {
  1108. nType = 1;
  1109. bAbnormal = true;
  1110. break;
  1111. }
  1112. }
  1113. if ( !bAbnormal )
  1114. {
  1115. for ( std::vector<std::string>::iterator it = vtNotifyShutdown.begin(); it != vtNotifyShutdown.end(); it++ )
  1116. {
  1117. if ( _tcsstr(buffer.c_str(), it->c_str()) )
  1118. {
  1119. nType = -1;
  1120. bAbnormal = true;
  1121. break;
  1122. }
  1123. }
  1124. }
  1125. // 1分钟前,是否有收到脚本通知;
  1126. if ( Global::g_notify.notify )
  1127. {
  1128. __int64 nd = gmt - Global::g_notify.datetime;
  1129. #ifdef _DEBUG
  1130. TRACE3("判断时间%ld-通知时间%ld=相差时间%ld\n\n", gmt, Global::g_notify.datetime, nd);
  1131. #endif
  1132. if ( nd < 60)
  1133. {
  1134. // 监测的类型与通知类型是否一致;
  1135. if ( (nType == 1 && Global::g_notify.report_type == _T("reboot")) ||
  1136. (nType == -1 && Global::g_notify.report_type == _T("shutdown")) )
  1137. {
  1138. bAbnormal = false;
  1139. // 重置;
  1140. Global::g_notify.notify = false;
  1141. Global::g_notify.datetime = 0;
  1142. Global::g_notify.report_type.clear();
  1143. }
  1144. }
  1145. }
  1146. if (bAbnormal)
  1147. {
  1148. if ( nType == -1 )
  1149. {
  1150. // 遥控:重启电视机;
  1151. if ( Global::g_SendPowerKey )
  1152. Global::g_SendPowerKey();
  1153. }
  1154. // 压入容器中;
  1155. Global::TLog tlog;
  1156. if ( nType == -1 )
  1157. tlog.report_type = "Abnormal shutdown";
  1158. else if ( nType == 1 )
  1159. tlog.report_type = "Abnormal restart";
  1160. tlog.datetime = gmt; // 发生时间;
  1161. struct tm gmtm = {0};
  1162. localtime_s(&gmtm, &gmt); // 时间戳转成本地时间;
  1163. TCHAR szDataTime[64] = {0};
  1164. _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);
  1165. tlog.report_data = szDataTime;
  1166. Global::g_vtAbnormal.push_back(tlog);
  1167. // 最后,重置;
  1168. Global::g_notify.notify = false;
  1169. Global::g_notify.datetime = 0;
  1170. Global::g_notify.report_type.clear();
  1171. }
  1172. }
  1173. }
  1174. Sleep(200);
  1175. }
  1176. */
  1177. return 0;
  1178. }