Переглянути джерело

多轮任务:
1、新增TaskRoundSetting,处理新任务多轮配置;
2、修改GetFreeCaseScript,以符合查找Round.CaseIndex的空闲用例 ;

Jeff 5 роки тому
батько
коміт
cfb1f517b7

+ 1 - 1
SATService/SATService/Global.cpp

@@ -184,7 +184,7 @@ namespace GLOBAL
 		if (szPath != NULL && szIniName != NULL)
 			StringCchPrintf(szIniPath, MAX_PATH, _T("%s%s"), szPath, szIniName);
 		else
-#if defined _DEBUG || defined RTEST
+#if !defined _DEBUG && !defined RTEST
 			StringCchPrintf(szIniPath, MAX_PATH, _T("%sSATService.ini"), g_szCurModuleDir);
 #else
 			StringCchPrintf(szIniPath, MAX_PATH, _T("%sSATService_Test.ini"), g_szCurModuleDir);

+ 101 - 22
SATService/SATService/SATExecutor.cpp

@@ -76,7 +76,7 @@ void CSATExecutor::DelFinishedTask()
 		if ( it->taskInfo._nExecutionState == SATHTTP::EXECUTED ) {
 			// 删除所有执行器对象;
 			CPythonExecutor *pExecutor = NULL;
-			for (std::vector<SATHTTP::STCase>::iterator _case = it->Job.vtCases.begin(); _case != it->Job.vtCases.end(); _case++ ) {
+			for (std::vector<SATHTTP::STCase>::iterator _case = it->vtCases.begin(); _case != it->vtCases.end(); _case++ ) {
 				// 一般被停止的任务,才会触发下面的操作;
 				pExecutor = (CPythonExecutor *)_case->_pExcutor;
 				if ( pExecutor ) {	
@@ -100,6 +100,7 @@ void CSATExecutor::DelFinishedTask()
 	}
 }
 
+// 返回正在执行的用例对象, 如果没有正在执行的任务返回NULL;
 SATHTTP::STCase* CSATExecutor::IsCaseScriptProcess(std::vector<SATHTTP::STCase> &vtCases)
 {
 	std::vector<SATHTTP::STCase>::iterator it = vtCases.begin();
@@ -113,9 +114,10 @@ SATHTTP::STCase* CSATExecutor::IsCaseScriptProcess(std::vector<SATHTTP::STCase>
 	return NULL;
 }
 
-SATHTTP::STCase* CSATExecutor::GetFreeCaseScript(std::vector<SATHTTP::STCase> &vtCases)
+SATHTTP::STCase* CSATExecutor::GetFreeCaseScript(SATHTTP::STTask* pTask)
 {
-	std::vector<SATHTTP::STCase>::iterator it = vtCases.begin();
+#if 0 // 原获取方式;
+	std::vector<SATHTTP::STCase>::iterator it = pTask->vtCases.begin();
 	for ( ; it != vtCases.end(); it++) {
 		// 未执行的脚本;
 		if ( it->_nExecutionState == SATHTTP::UNEXECUTED ) {
@@ -124,12 +126,56 @@ SATHTTP::STCase* CSATExecutor::GetFreeCaseScript(std::vector<SATHTTP::STCase> &v
 	}
 
 	return NULL;
+#else
+	int nCaseIndex = 0;
+	int nCaseRound = 0;
+	SATHTTP::STCase *pCase = NULL;
+	std::vector<SATHTTP::STCase>::iterator it = pTask->vtCases.begin();
+	for ( ; it != pTask->vtCases.end(); it++) {
+		// 获取用例索引;
+		nCaseIndex = _tstol(it->strIndex.c_str());
+		nCaseRound = _tstol(it->_strRoundNum.c_str());
+		if ( nCaseRound == pTask->_curRound ) {
+			if ( nCaseIndex == pTask->_curCaseIndex ) {
+				// 正常:未执行的脚本;
+				if ( it->_nExecutionState == SATHTTP::UNEXECUTED ) {
+					// 是否转到下一轮;
+					if ( nCaseIndex == pTask->_roundSize ) {
+						pTask->_curRound++;			// 下一轮;
+						pTask->_curCaseIndex = 1;	// 重置为1;
+					} else 
+						pTask->_curCaseIndex++;
+					// 返回结果;
+					pCase = &*it;
+					// 退出;
+					break;
+				}
+
+				GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, _T("用例轮空:round=%d, caseIndex=%d"), pTask->_curRound, pTask->_curCaseIndex);
+
+				// 是否转到下一轮;
+				if ( nCaseIndex == pTask->_roundSize ) {
+					pTask->_curRound++;			// 下一轮;
+					pTask->_curCaseIndex = 1;	// 重置为0;
+				} else
+					pTask->_curCaseIndex++;				
+			}
+		}
+	}
+
+	// 容错处理;
+	if ( pCase == NULL ) {
+		GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, _T("获取可用用例失败"));
+	}
+
+	return pCase;
+#endif
 }
 
 SATHTTP::STCase* CSATExecutor::ExecuteFreeCaseScript(SATHTTP::STTask* pTask)
 {
 	// 获取未执行的脚本;
-	SATHTTP::STCase* pCase = GetFreeCaseScript(pTask->Job.vtCases);
+	SATHTTP::STCase* pCase = GetFreeCaseScript(pTask);
 	if (pCase) {		
 #if 1 // 额外追加代码:清除之前的xml文件;
 #if 0
@@ -143,13 +189,16 @@ SATHTTP::STCase* CSATExecutor::ExecuteFreeCaseScript(SATHTTP::STTask* pTask)
 		// 删除文件;
 		DeleteFile(xmlpath.c_str());
 #endif
+		// 命令行:{"Round": %d}
+		TCHAR szCommandLine[MAX_PATH] = { 0 };
+		_stprintf_s(szCommandLine, _T("{\"Round\": %s"), pCase->_strRoundNum.c_str());
 		if ( !pCase->_pExcutor ) {
 			CPythonExecutor *pExcutor = new CPythonExecutor(); 
 			if ( pExcutor ) {
 				pCase->_pExcutor = pExcutor;
 				// 用例的日志文件路径;
 				pCase->_strCaseLog = pCase->_strFileDir + pCase->_strFileName + ".txt";
-				if ( pExcutor->InitScript(pCase->_strScriptPath, pCase->_strCaseLog, "") ) {
+				if ( pExcutor->InitScript(pCase->_strScriptPath, pCase->_strCaseLog, szCommandLine) ) {
 					// 设置用例对象;
 					pExcutor->SetCaseObje(pCase);
 					pExcutor->StartScript();
@@ -169,7 +218,7 @@ SATHTTP::STCase* CSATExecutor::ExecuteFreeCaseScript(SATHTTP::STTask* pTask)
 			GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, "重新初始化脚本(%s)", pCase->strCaseName.c_str());
 			// 重新初始化脚本;
 			CPythonExecutor *pExcutor = (CPythonExecutor *)pCase->_pExcutor;
-			if ( pExcutor->InitScript(pCase->_strScriptPath, pCase->_strCaseLog, "") ) {
+			if ( pExcutor->InitScript(pCase->_strScriptPath, pCase->_strCaseLog, szCommandLine) ) {
 				// 设置用例对象;
 				pExcutor->SetCaseObje(pCase);
 				pExcutor->StartScript();
@@ -185,6 +234,33 @@ SATHTTP::STCase* CSATExecutor::ExecuteFreeCaseScript(SATHTTP::STTask* pTask)
 	return pCase;
 }
 
+void CSATExecutor::TaskRoundSetting(SATHTTP::STTask* pTask)
+{
+	if ( pTask == NULL )
+		return;
+	
+	// 1轮有多少用例数量;
+	pTask->_roundSize = pTask->vtCases.size();
+	// 获取执行轮数;
+	pTask->_roundCount = _tstol(pTask->Job.strRound.c_str());
+	if ( pTask->_roundCount > 1 )
+	{
+		TCHAR szValue[8] = { 0 }; 
+		// 复制一份出来,修改round值,再添加给任务;
+		std::vector<SATHTTP::STCase> vtOrgCase = pTask->vtCases;
+		for ( int i = 2; i <= pTask->_roundCount; i++ )
+		{
+			_itoa_s(i, szValue, 10);
+			std::vector<SATHTTP::STCase> vtCase = vtOrgCase;
+			for ( std::vector<SATHTTP::STCase>::iterator it = vtCase.begin(); it != vtCase.end(); it++ )
+			{				
+				it->_strRoundNum = szValue;
+				pTask->vtCases.push_back(*it);
+			}			
+		}
+	}
+}
+
 void CSATExecutor::AddDevices(const SATDEV::STDevice &stDevice)
 {
 	if ( IsDeviceExist(stDevice.strName) )
@@ -396,7 +472,7 @@ bool CSATExecutor::UploadCaseImg(SATHTTP::STTask* pTask, SATHTTP::STCase *pCase,
 	stSaveImgReq.strInstanceId = szValue;
 	stSaveImgReq.strJobRepeat = "0";
 	// 注意避坑:roundnum必须赋值0或1;
-	stSaveImgReq.strRoundNum = "0";
+	stSaveImgReq.strRoundNum = pCase->_strRoundNum;
 	stSaveImgReq.strImgType = "";
 	stSaveImgReq.strUploads = img;
 
@@ -429,6 +505,8 @@ bool CSATExecutor::UploadCaseLog(SATHTTP::STTask* pTask, SATHTTP::STCase *pCase)
 	//_itoa_s(pTask->nTaskId, szValue, 10);
 	stSaveLogReq.strTaskId = pTask->Job.strTaskInstanceId;
 	stSaveLogReq.strUserId = pTask->Job.strUserId;
+	// 第几轮日志;
+	stSaveLogReq.strRoundNum = pCase->_strRoundNum;
 	// 要上传的日志文件;
 	stSaveLogReq.strUploads = pCase->_strCaseLog;
 	if ( SaveCaseOrTaskLog(url, stSaveLogReq, stSaveLogResp) ) {
@@ -479,7 +557,7 @@ bool CSATExecutor::ReportCaseItemFinish(SATHTTP::STTask* pTask, SATHTTP::STCase
 	stJobProcessReq.strInstanceId = szValue;
 	stJobProcessReq.strCaseId = pCase->strId;
 	// 进度;
-	_itoa_s(100*(atoi(pCase->strIndex.c_str()))/pTask->Job.vtCases.size(), szValue, 10);
+	_itoa_s(100*(atoi(pCase->strIndex.c_str()))/pTask->vtCases.size(), szValue, 10);
 	stJobProcessReq.strProgress = szValue;
 	// 需要将utf-8转gbk;
 	stJobProcessReq.strReusltMessage = caseItem.name;//CharEncoding::UTF82ASCII(caseItem.name.c_str());
@@ -517,7 +595,7 @@ bool CSATExecutor::ReportCaseItemFinish(SATHTTP::STTask* pTask, SATHTTP::STCase
 	// 如果是Android设备,需要通过adb获取;
 	//stJobProcessReq.strMemoryInfo = stDevice.strMemory;
 	stJobProcessReq.strEndTime = CTime::GetCurrentTime().Format(_T("%Y-%m-%d %H:%M:%S"));//"2019-12-16 10:18:20";
-	stJobProcessReq.strRoundNumber = "1";
+	stJobProcessReq.strRoundNumber = pCase->_strRoundNum;
 	stJobProcessReq.strResultType = "4";		// reportActionFinish;
 	stJobProcessReq.strOperationStep = "";
 
@@ -601,7 +679,7 @@ bool CSATExecutor::ReportCaseFinish(SATHTTP::STTask* pTask, SATHTTP::STCase *pCa
 	stJobProcessReq.strInstanceId = szValue;
 	stJobProcessReq.strCaseId = pCase->strId;
 	// 进度(###需要修改此处###);
-	_itoa_s(100*(atoi(pCase->strIndex.c_str()))/pTask->Job.vtCases.size(), szValue, 10);
+	_itoa_s(100*(atoi(pCase->strIndex.c_str()))/pTask->vtCases.size(), szValue, 10);
 	stJobProcessReq.strProgress = szValue;
 	// 需要将utf-8转gbk;
 	stJobProcessReq.strReusltMessage = CharEncoding::ASCII2UTF8("测试用例结果:");
@@ -628,7 +706,7 @@ bool CSATExecutor::ReportCaseFinish(SATHTTP::STTask* pTask, SATHTTP::STCase *pCa
 	// 如果是Android设备,需要通过adb获取;
 	//stJobProcessReq.strMemoryInfo = stDevice.strMemory;
 	stJobProcessReq.strEndTime = pCase->_strEndTime;//CTime::GetCurrentTime().Format(_T("%Y-%m-%d %H:%M:%S"));//"2019-12-16 10:18:20";
-	stJobProcessReq.strRoundNumber = "1";
+	stJobProcessReq.strRoundNumber = pCase->_strRoundNum;
 	stJobProcessReq.strResultType = "5";		// reportCaseFinish;
 	stJobProcessReq.strOperationStep = "";
 
@@ -881,7 +959,7 @@ bool CSATExecutor::ReportTaskFinish(SATHTTP::STTask* pTask)
 	// 如果是Android设备,需要通过adb获取;
 	//stJobProcessReq.strMemoryInfo = stDevice.strMemory;
 	stJobProcessReq.strEndTime = CTime::GetCurrentTime().Format(_T("%Y-%m-%d %H:%M:%S"));//"2019-12-16 10:18:20";
-	stJobProcessReq.strRoundNumber = "1";
+	stJobProcessReq.strRoundNumber = pTask->Job.strRound;
 	stJobProcessReq.strResultType = "1";		// reportJobFinish;
 	stJobProcessReq.strOperationStep = "";
 
@@ -1005,8 +1083,8 @@ int CSATExecutor::AttachTaskInfo2Buffer(SATPROTO::TaskInfo (&pbuff)[SATPROTO::MA
 
 			int nIndex = 0;
 			// 用例数量;
-			pbuff[count].nCaseSize = it->Job.vtCases.size();		
-			for (std::vector<SATHTTP::STCase>::iterator _case = it->Job.vtCases.begin(); _case != it->Job.vtCases.end(); _case++) {
+			pbuff[count].nCaseSize = it->vtCases.size();		
+			for (std::vector<SATHTTP::STCase>::iterator _case = it->vtCases.begin(); _case != it->vtCases.end(); _case++) {
 				// 用例状态;
 				// pbuff[count].ssCases[nIndex].nStatus = _case->_nExecutionState;
 				//pbuff[count].ssCases[nIndex].nCaseId = _case->_nCaseStep;
@@ -1149,7 +1227,7 @@ void CSATExecutor::EndofWork()
 	// 如果有脚本在执行,结束脚本;
 	CPythonExecutor *pExecutor = NULL;
 	for ( std::list<SATHTTP::STTask>::iterator it = m_vtTask.begin(); it != m_vtTask.end(); it++ ) {
-		for ( std::vector<SATHTTP::STCase>::iterator _case = it->Job.vtCases.begin(); _case != it->Job.vtCases.end(); _case++ ) {
+		for ( std::vector<SATHTTP::STCase>::iterator _case = it->vtCases.begin(); _case != it->vtCases.end(); _case++ ) {
 			if ( (pExecutor = (CPythonExecutor *)_case->_pExcutor) ) {
 				pExecutor->EndThread();
 				delete pExecutor;
@@ -1196,8 +1274,8 @@ DWORD CSATExecutor::HearbeatThread(LPVOID lpVoid)
 					GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, _T("【任务脚本下载】:%s"), it->Job.strUniqueId.c_str());
 					std::string host = GLOBAL::g_stSATConfig.szCaseServer;
 					std::string url = host + "/ajaxInteractiveManage!getCaseFileListUrl.action";
-					std::vector<SATHTTP::STCase>::iterator _case = it->Job.vtCases.begin();
-					for ( int i = 1; _case != it->Job.vtCases.end(); _case++) {
+					std::vector<SATHTTP::STCase>::iterator _case = it->vtCases.begin();
+					for ( int i = 1; _case != it->vtCases.end(); _case++) {
 						// 下载脚本;
 						_case->_nCaseStep = i++;
 						SATHTTP::STScriptUrlResp stScriptUrlResp;
@@ -1219,6 +1297,7 @@ DWORD CSATExecutor::HearbeatThread(LPVOID lpVoid)
 						}
 					}
 
+					that->TaskRoundSetting(&*it);
 					that->m_vtTask.push_back(*it);
 					
 					// 通知SAT服务器,脚本开始执行;
@@ -1251,7 +1330,7 @@ DWORD CSATExecutor::ExecuteScriptThread(LPVOID lpVoid)
 			}
 			else {// 串行;
 				// 是否有脚本用例在执行;
-				SATHTTP::STCase* pCase = that->IsCaseScriptProcess(pTask->Job.vtCases);
+				SATHTTP::STCase* pCase = that->IsCaseScriptProcess(pTask->vtCases);
 				if ( pCase ) {
 					CPythonExecutor *pExcutor = (CPythonExecutor*)pCase->_pExcutor;
 					if ( pExcutor ) {
@@ -1306,8 +1385,8 @@ DWORD CSATExecutor::ExecuteScriptThread(LPVOID lpVoid)
 				// 是否支持并发;
 				if ( pTask->taskInfo._bConcurrent ) {
 					// 暂时全部一起并发;
-					std::vector<SATHTTP::STCase>::iterator _case = pTask->Job.vtCases.begin();
-					for ( ; _case != pTask->Job.vtCases.end(); _case++) {
+					std::vector<SATHTTP::STCase>::iterator _case = pTask->vtCases.begin();
+					for ( ; _case != pTask->vtCases.end(); _case++) {
 						if (!_case->_pExcutor) {					
 							CPythonExecutor *pExcutor = new CPythonExecutor();
 							if ( pExcutor ) {
@@ -1326,9 +1405,9 @@ DWORD CSATExecutor::ExecuteScriptThread(LPVOID lpVoid)
 				else {
 					GLOBAL::WriteTextLog(GLOBAL::SAT_EXE, _T("\n<===============================================>\n# 1、开始执行任务:%s, 用例数量:%ld#\n<===============================================>\n"), 
 						pTask->Job.strUniqueId.c_str(), 
-						pTask->Job.vtCases.size());
+						pTask->vtCases.size());
 					// 是否有用例脚本在执行;
-					SATHTTP::STCase* pCase = that->IsCaseScriptProcess(pTask->Job.vtCases);
+					SATHTTP::STCase* pCase = that->IsCaseScriptProcess(pTask->vtCases);
 					if ( !pCase ) {
 						// 执行空闲用例脚本;
 						that->ExecuteFreeCaseScript(pTask);

+ 18 - 17
SATService/SATService/SATExecutor.h

@@ -6,17 +6,6 @@
 #include "CritSection.h"
 #include "SATDevices.h"
 
-// 用例xml;
-typedef struct __ST_CASEITEM__
-{
-	bool result;
-	std::string name;
-	std::string data;
-	std::vector<std::string> imgs;
-	std::string log;
-	std::string remark;
-}STCaseItem, *pSTCaseItem;
-
 class CSATExecutor
 {
 	CSATExecutor(void);
@@ -35,6 +24,16 @@ public:
 
 	~CSATExecutor(void);
 
+	// 用例xml;
+	typedef struct __ST_CASEITEM__ {
+		bool result;
+		std::string name;
+		std::string data;
+		std::vector<std::string> imgs;
+		std::string log;
+		std::string remark;
+	}STCaseItem, *pSTCaseItem;
+
 protected:
 	// 线程控制句柄;
 	HANDLE  m_hEventHearbeat;
@@ -50,11 +49,11 @@ protected:
 	// 是否结束TV串口监听;
 	BOOL	m_bStopWathTV;
 
-	ThreadSection	m_csTask;
-	std::list<SATHTTP::STTask> m_vtTask;
-	std::vector<SATHTTP::STDevice> m_vtDevice;
-	SATHTTP::STLoginReq	m_stLoginReq;
-	SATHTTP::STLoginResp	m_stLoginResp;
+	ThreadSection					m_csTask;
+	std::list<SATHTTP::STTask>		m_vtTask;
+	std::vector<SATHTTP::STDevice>	m_vtDevice;
+	SATHTTP::STLoginReq				m_stLoginReq;
+	SATHTTP::STLoginResp			m_stLoginResp;
 	// 执行器名称;
 	std::string m_strActuatorName;
 
@@ -69,9 +68,11 @@ protected:
 	// 是否有用例脚本在执行;
 	SATHTTP::STCase* IsCaseScriptProcess(std::vector<SATHTTP::STCase> &vtCases);
 	// 提取未执行的用例;
-	SATHTTP::STCase* GetFreeCaseScript(std::vector<SATHTTP::STCase> &vtCases);
+	SATHTTP::STCase* GetFreeCaseScript(SATHTTP::STTask* pTask);
 	// 执行空闲新用例;
 	SATHTTP::STCase* ExecuteFreeCaseScript(SATHTTP::STTask* pTask);
+	// 新任务Round配置;
+	void TaskRoundSetting(SATHTTP::STTask* pTask);
 	
 public:
 	// 添加设备;