Pārlūkot izejas kodu

1、非断点下载;
2、关闭下载日志输出 ;

scbc.sat2 5 gadi atpakaļ
vecāks
revīzija
9e019502bf

+ 44 - 5
SATHTTP/SATHTTP/CurlClient.cpp

@@ -5,7 +5,7 @@
 
 CCurlClient::CCurlClient(void)
 {
-	m_bDebug = TRUE;
+	m_bDebug = FALSE;
 	m_headers = NULL;
 }
 
@@ -554,6 +554,49 @@ void CCurlClient::SetHeaders(const std::string headers)
 	m_headers = curl_slist_append(m_headers, headers.c_str());
 }
 
+bool CCurlClient::Download(const std::string& url, const std::string& path, long time_out /* = 3000 */)
+{
+	FILE* pf = NULL;
+	long file_size = 0;
+
+	CURLcode res = CURLE_GOT_NOTHING;
+	// 采用追加方式打开文件,便于实现断点续传;
+	int nErr = _tfopen_s(&pf, path.c_str(), "wb+");
+	if (pf)
+	{
+		CURL* curl = curl_easy_init();
+		if (NULL == curl)
+		{
+			return false;
+		}
+		curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
+		curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, time_out);
+		// 设置http头部处理函数;
+		curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, OnGetContentLength);
+		curl_easy_setopt(curl, CURLOPT_HEADERDATA, &file_size);
+		if (url.find("https://") != std::string::npos)
+		{
+			curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
+			curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
+		}
+		// 设置文件续传的位置给curl;
+		//curl_easy_setopt(curl, CURLOPT_RESUME_FROM_LARGE, 0);
+		curl_easy_setopt(curl, CURLOPT_WRITEDATA, pf);
+		//curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);//设置重定位URL,使用自动跳转,返回的头部中有Location(一般直接请求的url没找到),则继续请求Location对应的数据
+		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteFile);
+		curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
+		//curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); // 不打印日志;
+
+		res = curl_easy_perform(curl);
+		fclose(pf);
+		curl_easy_cleanup(curl);
+
+		if (res == CURLE_OK)
+			return true;
+	}
+
+	return false;
+}
 
 // 参考:https://blog.csdn.net/lengyuezuixue/article/details/81987695
 bool CCurlClient::DownloadEx(const std::string& url, const std::string& path, long time_out /* = 3000 */)
@@ -614,10 +657,6 @@ bool CCurlClient::DownloadEx(const std::string& url, const std::string& path, lo
 }
 
 
-
-
-
-
 size_t CCurlClient::OnGetContentLength(void* ptr, size_t size, size_t nmemb, void* stream)
 {
 	int r;

+ 3 - 1
SATHTTP/SATHTTP/CurlClient.h

@@ -71,6 +71,9 @@ public:
 	int Gets(IN LPCTSTR lpUrl, OUT LPTSTR lpResponse, IN CONST INT& nMaxlen, IN LPCTSTR lpCaPath = NULL, long time_out = 3000);
 	int Gets(IN CString& strUrl, OUT CString& strResponse, IN const CString& strCaPath = _T(""), long time_out = 3000);
 
+	// 一次性下载;
+	bool Download(const std::string& url, const std::string& path, long time_out = 3000);
+	// 断点下载;
 	bool DownloadEx(const std::string& url, const std::string& path, long time_out = 3000);
 	int FormPosts(std::string url, std::multimap<std::string, std::string> form_data, std::string& result, long time_out);
 public:   
@@ -82,7 +85,6 @@ public:
 		m_headers = NULL;
 	}
 
-
 private:   
 	// 是否启用调试输出;
 	BOOL	m_bDebug;	

+ 292 - 3
SATHTTP/SATHTTP/SATHTTP.cpp

@@ -3,6 +3,7 @@
 
 #include "stdafx.h"
 #include "SATHTTP.h"
+#include <direct.h>
 
 #ifdef _DEBUG
 #define new DEBUG_NEW
@@ -16,6 +17,8 @@ CWinApp theApp;
 
 using namespace std;
 
+bool MKDIR(LPCTSTR dir);
+
 int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
 {
 	int nRetCode = 0;
@@ -50,7 +53,7 @@ int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
 		stDevice.strLastJob = "";
 		stDevice.strLastTimeConnected = "2019-12-16 10:16:01";
 		stDevice.strElectric = "";
-		//////////////////////////////////////////////////////////////////////////
+		// ##########################先登录##############################;
 		SATParameters::STLoginReq stLoginReq;
 		SATParameters::STLoginResp stLoginResp;
 		std::string url = host + "/btc_execute_se/ajaxInteractiveManage!executeLogin.action";
@@ -67,7 +70,6 @@ int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
 		stLoginReq.strPassword = "123456";
 		stLoginReq.strCPU = "";
 
-		// ##########################先登录##############################;
 		if ( !Login(url, stLoginReq, stLoginResp) )
 		{
 			system("pause");
@@ -145,6 +147,142 @@ int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
 					stHeartbeatResp.strCode.c_str(),
 					stHeartbeatResp.strMessage.c_str(),
 					stHeartbeatResp.strStr.c_str());
+
+				// 判断是否有任务获取成功;
+				if ( stHeartbeatResp.vtTask.size() )
+				{
+					// #########################################################################################
+					// 判断任务是否在SAT上存在;(感觉没什么意义!!!)
+					SATParameters::STTask stTask = stHeartbeatResp.vtTask[0];
+					SATParameters::STNotifyJobStartReq stNotifyJobStartReq;
+					SATParameters::STNotifyJobStartResp stNotifyJobStartResp;
+
+					TCHAR szValue[36] = {0};
+					_itoa_s(stTask.nDeviceId, szValue, 10);
+					stNotifyJobStartReq.strDeviceId = szValue;
+
+					_itoa_s(stTask.nExecuteId, szValue, 10);
+					stNotifyJobStartReq.strExecuteId = szValue;
+
+					_itoa_s(stTask.nInstanceId, szValue, 10);
+					stNotifyJobStartReq.strInstanceId = szValue;					
+
+					_itoa_s(stTask.nTaskId, szValue, 10);
+					stNotifyJobStartReq.strTaskId = szValue;
+
+					stNotifyJobStartReq.strSignalImageUrl = "D:\\SAT\\Runner\\btc_runner_se\\runner\\output\\ODF_NPI_RT2841\\20191216101613370\\192.168.1.119_5555";
+
+					__if_not_exists(url)
+					{			
+						std::string url = host + "/btc_execute_se/ajaxInteractiveManage!setResult.action";
+					}
+					__if_exists(url)
+					{
+						url = host + "/btc_execute_se/ajaxInteractiveManage!setResult.action";
+					}
+
+					// 查询任务是否已在SAT上存在;
+					if ( NotifyJobStart(url, stNotifyJobStartReq, stNotifyJobStartResp) )
+					{
+						printf("NotifyJobStart 成功\n");
+					}
+					else
+					{
+						printf("NotifyJobStart 失败\n");
+					}
+
+					// #########################################################################################
+					// 开始Job;
+					SATParameters::STJobProcessReq stJobProcessReq;
+					SATParameters::STJobProcessResp stJobProcessResp;
+					__if_not_exists(url)
+					{			
+						std::string url = host + "/btc_execute_se/ajaxInteractiveManage!setResultList.action";
+					}
+					__if_exists(url)
+					{
+						url = host + "/btc_execute_se/ajaxInteractiveManage!setResultList.action";
+					}
+
+					{
+						stJobProcessReq.strResultState = "";
+						stJobProcessReq.strCaseScene = "";
+						stJobProcessReq.strCaseStep = "0";
+						stJobProcessReq.strApkMD5 = "";
+						stJobProcessReq.strCrashTime = "";
+						// 就是Task中的ExecuteId
+						_itoa_s(stTask.nExecuteId, szValue, 10);
+						stJobProcessReq.strRunnerId = szValue;
+						stJobProcessReq.strCPUInfo = "0";
+						stJobProcessReq.strRunnedActionNameList = "";
+						stJobProcessReq.strArtificialResult = "";
+						stJobProcessReq.strArtificialModify = "";
+						stJobProcessReq.strRunnerName = "";
+						stJobProcessReq.strTaskType = "FUNCTIONALITY";
+						stJobProcessReq.strCaseRepeat = "";
+						stJobProcessReq.strApplicationGroup = "";
+						// 实例Id;
+						_itoa_s(stTask.nInstanceId, szValue, 10);
+						stJobProcessReq.strInstanceId = szValue;
+						stJobProcessReq.strCaseId = "";
+						stJobProcessReq.strProgress = "0";
+						stJobProcessReq.strReusltMessage = "任务开始";
+						stJobProcessReq.strJobRepeat = "";
+						stJobProcessReq.strScreenShot = "";
+						stJobProcessReq.strStartTime = "2019-12-16 10:16:43";
+						stJobProcessReq.strCrashNumber = "";
+						stJobProcessReq.strCaseName = "";
+						stJobProcessReq.strFailedReason = "";
+						stJobProcessReq.strImgName = "";
+						stJobProcessReq.strCaseIndex = "";
+						// 实例Id;
+						_itoa_s(stTask.nDeviceId, szValue, 10);
+						stJobProcessReq.strDeviceId = szValue;
+						stJobProcessReq.strSceneIndex = "";
+						// 实例Id;
+						_itoa_s(stTask.nTaskId, szValue, 10);
+						stJobProcessReq.strTaskId = szValue;
+						stJobProcessReq.strAnalysis = "";
+						// 设备名称:即DeviceSerial;
+						stJobProcessReq.strDevnceName = stDevice.strDeviceSerial;
+						// 固定为:TOTAL
+						stJobProcessReq.strInfoType = "TOTAL";
+						// 如果是Android设备,需要通过adb获取;
+						stJobProcessReq.strMemoryInfo = stDevice.strMemory;
+						stJobProcessReq.strEndTime = "2019-12-16 10:18:20";
+						stJobProcessReq.strRoundNumber = "1";
+						stJobProcessReq.strResultType = "0";
+						stJobProcessReq.strOperationStep = "";
+					}
+
+					// 向SAT上报:任务开始,请SAT变更任务状态;
+					if ( ProcessJob(url, stJobProcessReq, stJobProcessResp) )
+					{
+						// 开始下载脚本;
+						__if_not_exists(url)
+						{			
+							std::string url = host + "/btc_caseManagement_se/ajaxInteractiveManage!getCaseFileListUrl.action";
+						}
+						__if_exists(url)
+						{
+							url = host + "/btc_caseManagement_se/ajaxInteractiveManage!getCaseFileListUrl.action";
+						}
+						
+						SATParameters::STScriptUrlResp stScriptUrlResp;
+						std::vector<SATParameters::STCase>::iterator it = stTask.Job.vtCases.begin();
+						for ( ; it != stTask.Job.vtCases.end(); it++ )
+						{
+							if ( DownloadScript(url, it->strId, "D:\\SAT\\", stScriptUrlResp) )
+							{
+								printf("获取脚本下载地址成功:%s\n路径:%s\n", stScriptUrlResp.strURL.c_str(), stScriptUrlResp.strScripFile.c_str());
+							}
+							else
+							{
+								printf("获取脚本下载地址失败\n");
+							}
+						}						
+					}
+				}
 			}
 
 			Sleep(3000);
@@ -159,7 +297,41 @@ int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
 
 #endif //__CONSOLE__
 
+bool MKDIR(LPCTSTR dir) 
+{
+	//////////////////////////////////////////////////////////////////////////
+	// 创建目录;
+	int nleft = 0;
+	int nIndex = -1;
+	std::string strdir = dir;
+	strdir = strdir.substr(0, strdir.find_last_of(_T("\\")));
+
+	if (strdir.at(strdir.size() - 1) != _T('\\'))
+		strdir.append(_T("\\"));
+
+	// 共享路径和硬盘盘符;
+	if (_tcscmp(strdir.substr(0, 2).c_str(), _T("\\\\")) == 0)
+		nleft = strdir.find_first_of(_T("\\"), 2) + 1;	// 去除共享主机名;
+	else if (strdir.at(2) == _T('\\'))
+		nleft = 3;
+
+	do
+	{
+		nIndex = strdir.substr(nleft, -1).find_first_of(_T("\\"));
+
+		if (nIndex != string::npos)
+		{
+			if (_mkdir(strdir.substr(0, nIndex + nleft).c_str()) == -1 && (errno != EEXIST))
+			{
+				return false;
+			}
+
+			nleft += nIndex + 1;
+		}
+	} while (nIndex != -1);
 
+	return true;
+};
 
 SATHTTP_API int Login(std::string url, const SATParameters::STLoginReq &stLoginReq, SATParameters::STLoginResp &stLoginResp)
 {
@@ -769,7 +941,7 @@ SATHTTP_API int SetResultList(std::string url, const SATParameters::STJobProcess
 						cJSON *pObj = cJSON_GetObjectItem(pMsg, "data");
 						if (pObj != NULL)
 						{
-							
+							stJobProcessResp.strIsDelete = cJSON_GetObjectItem(pObj, "isDelete") ? (cJSON_GetObjectItem(pObj, "isDelete")->valuestring ? cJSON_GetObjectItem(pObj, "isDelete")->valuestring : "") : "";
 						}
 
 						// 释放内存;
@@ -855,7 +1027,11 @@ SATHTTP_API int GetCaseFileListUrl(std::string url, std::string strCaseId, SATPa
 							{
 								cJSON *pScripURL = cJSON_GetArrayItem(pObj, 0);
 								if ( pScripURL )
+								{
 									stScriptUrlResp.strURL = cJSON_GetObjectItem(pScripURL, "url") ? (cJSON_GetObjectItem(pScripURL, "url")->valuestring ? cJSON_GetObjectItem(pScripURL, "url")->valuestring : "") : "";
+									// 同时下载脚本目录到指定目录中;
+
+								}
 							}
 						}
 
@@ -872,5 +1048,118 @@ SATHTTP_API int GetCaseFileListUrl(std::string url, std::string strCaseId, SATPa
 		}
 	}
 
+	return FALSE;
+}
+
+SATHTTP_API int DownloadScript(std::string url, std::string strCaseId, std::string strSaveDir, SATParameters::STScriptUrlResp &stScriptUrlResp)
+{
+	// 转化为Json;
+	cJSON *pRoot = cJSON_CreateObject();
+	if ( pRoot == NULL )
+	{
+		return -1;
+	}
+
+	ASSERT(cJSON_AddStringToObject(pRoot, "sysCode", "Execute"));
+	ASSERT(cJSON_AddStringToObject(pRoot, "function", "getCaseFileListUrl"));
+	cJSON *pData = cJSON_CreateObject();
+	if ( pData )
+	{
+		ASSERT(cJSON_AddStringToObject(pData, "testCaseId", strCaseId.c_str()));
+		// 添加到根结点中;
+		cJSON_AddItemToObject(pRoot, "data", pData);
+	}
+
+	char *pText = cJSON_Print(pRoot);
+	std::string post_data = "requestMsg=";
+	post_data.append(CharEncoding::EnCode_UTF8URL(pText));
+
+	// 释放堆内存;
+	if (pText)
+		delete pText;
+	pText = NULL;
+
+	if ( pRoot )
+		cJSON_Delete(pRoot);
+	pRoot = NULL;		
+
+	CCurlClient curl;
+	std::string reponse;	
+	CURLcode curlCode = CURLE_OK;
+	if ( CURLE_OK == curl.Initialize() )
+	{
+		if (_tcsstr(url.c_str(), "https://") || _tcsstr(url.c_str(), "HTTPS://") )
+			curlCode = curl.Posts(url, post_data, reponse);
+		else
+			curlCode = curl.Post(url, post_data, reponse);
+
+		if ( curlCode == CURLE_OK )
+		{
+			reponse = CharEncoding::DeCode_URLUTF8(reponse.c_str());
+
+			// 解析返回值;
+			pRoot = cJSON_Parse(reponse.c_str());
+			if (pRoot != NULL)
+			{
+				cJSON *pMsg = cJSON_GetObjectItem(pRoot, "responseMsg");
+				if ( pMsg )
+				{
+					stScriptUrlResp.strCode = cJSON_GetObjectItem(pMsg, "code") ? cJSON_GetObjectItem(pMsg, "code")->valuestring : "";
+					stScriptUrlResp.strMessage = cJSON_GetObjectItem(pMsg, "message") ? cJSON_GetObjectItem(pMsg, "message")->valuestring : "";
+					stScriptUrlResp.strProjectId = cJSON_GetObjectItem(pMsg, "strProjectId") ? (cJSON_GetObjectItem(pMsg, "strProjectId")->valuestring ? cJSON_GetObjectItem(pMsg, "strProjectId")->valuestring : "") : "";
+					stScriptUrlResp.strCaseType = cJSON_GetObjectItem(pMsg, "caseType") ? (cJSON_GetObjectItem(pMsg, "caseType")->valuestring ? cJSON_GetObjectItem(pMsg, "caseType")->valuestring : "") : "";
+					if ( stScriptUrlResp.strCode == "00" )
+					{				
+						cJSON *pObj = cJSON_GetObjectItem(pMsg, "data");
+						if (pObj != NULL)
+						{
+							if ( cJSON_GetArraySize(pObj) >= 1 )
+							{
+								cJSON *pScripURL = cJSON_GetArrayItem(pObj, 0);
+								if ( pScripURL )
+								{
+									stScriptUrlResp.strURL = cJSON_GetObjectItem(pScripURL, "url") ? (cJSON_GetObjectItem(pScripURL, "url")->valuestring ? cJSON_GetObjectItem(pScripURL, "url")->valuestring : "") : "";
+									std::string strFileDir;
+									std::string strFileName;
+									int nPos1 = 0, nPos2 = 0;
+									nPos1 = stScriptUrlResp.strURL.find("fileDir=");
+									nPos2 = stScriptUrlResp.strURL.find("&fileName=");
+									if ( nPos1 != std::string::npos && nPos2 != std::string::npos )
+									{
+										strFileDir = stScriptUrlResp.strURL.substr(nPos1 + strlen("fileDir="), nPos2 - nPos1 - strlen("fileDir="));
+										strFileName = stScriptUrlResp.strURL.substr(nPos2 + strlen("&fileName="));
+										//strSavePath.append(strFileDir + "\\" + strFileName);
+										CString strPath = strSaveDir.c_str();
+										strPath.TrimRight('\\');
+										strPath += strFileDir.c_str();
+										strPath.Replace('/', '\\');
+										strSaveDir = strPath.GetString();
+										strSaveDir.append("\\"+strFileName);
+										// 创建目录;
+										if ( MKDIR(strSaveDir.c_str()) )
+										{
+											// 同时下载脚本目录到指定目录中;
+											if ( curl.Download(stScriptUrlResp.strURL, strSaveDir, 10000) )
+											{
+												stScriptUrlResp.strScripFile = strSaveDir;
+												// 释放内存;
+												cJSON_Delete(pRoot);
+												// 返回结果;
+												return TRUE;
+											}
+										}
+									}							
+								}
+							}
+						}						
+					}
+				}
+
+				// 错误产生,可输出msg方便查询;
+				cJSON_Delete(pRoot);	
+			}
+		}
+	}
+
 	return FALSE;
 }

+ 27 - 3
SATHTTP/SATHTTP/SATHTTP.h

@@ -51,7 +51,7 @@ namespace SATParameters{
 	// 1、登录SAT的请求参数;
 	typedef struct __ST_LOGIN_REQ__{
 		std::string strUserName;
-		std::string strStatus;
+		std::string strStatus;			// 0:表示请求登录; 1:表示请求登出;
 		std::string strDeleteStatus;
 		std::string strIP;
 		std::string strMemory;
@@ -75,7 +75,7 @@ namespace SATParameters{
 	// 2、更新设备信息的请求参数;
 	typedef struct __ST_UPDATE_DEVICE_REQ__
 	{
-		std::string strStatus;
+		std::string strStatus;				// 0:表示空闲; 1:离线; 2:表示忙碌; 3=?; 4:任务异常?; 5=忙碌中?;
 		std::string strUserName;
 		std::string strIP;
 		std::string strStorage;
@@ -254,8 +254,22 @@ namespace SATParameters{
 		std::string strCode;
 		std::string strURL;
 		std::string strMessage;
-		std::string strProjectId;		
+		std::string strProjectId;	
+		// 脚本保存路径;
+		std::string strScripFile;
 	}STScriptUrlResp,*pSTScriptUrlResp;
+
+	//////////////////////////////////////////////////////////////////////////
+	// 7、保存用例脚本或任务日志;
+	typedef struct __ST_SAVE_LOG_REQ__
+	{
+		std::string strUserId;
+		std::string strFileType;
+		std::string strCaseId;
+		std::string strTaskId;
+		std::string strExecuteId;
+		std::string strUploads;		// 要上传的文件;
+	}STSaveLogReq, *pSTSaveLogReq;
 }
 
 extern SATHTTP_API int nSATHTTP;
@@ -280,8 +294,18 @@ __if_not_exists(NotifyJobStart)
 	}
 }
 
+// 通知SAT用例脚本已开始;
 SATHTTP_API int SetResultList(std::string url, const SATParameters::STJobProcessReq &stJobProcessReq, SATParameters::STJobProcessResp &stJobProcessResp) throw();
+__if_not_exists(ProcessJob)
+{
+	SATHTTP_API int ProcessJob(std::string url, const SATParameters::STJobProcessReq &stJobProcessReq, SATParameters::STJobProcessResp &stJobProcessResp) throw()
+	{
+		return SetResultList(url, stJobProcessReq, stJobProcessResp);
+	}
+}
+
 SATHTTP_API int GetCaseFileListUrl(std::string url, std::string strCaseId, SATParameters::STScriptUrlResp &stScriptUrlResp) throw();
+SATHTTP_API int DownloadScript(std::string url, std::string strCaseId, std::string strSaveDir, SATParameters::STScriptUrlResp &stScriptUrlResp) throw();
 
 SATHTTP_API int GetIdNumber();
 SATHTTP_API int StopTaskFromRunner();