📄 ecostest.cpp
字号:
//####COPYRIGHTBEGIN####// // ----------------------------------------------------------------------------// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.//// This program is part of the eCos host tools.//// This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version.// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details.// // You should have received a copy of the GNU General Public License along with// this program; if not, write to the Free Software Foundation, Inc., // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.//// ----------------------------------------------------------------------------// //####COPYRIGHTEND####//=================================================================//// eCosTest.cpp//// Test class////=================================================================//=================================================================//#####DESCRIPTIONBEGIN####//// Author(s): sdf// Contributors: sdf// Date: 1999-04-01// Description: This class abstracts a test for use in the testing infrastructure// Usage:////####DESCRIPTIONEND####///////////////////////////////////////////////////////////////////////////////#include "eCosStd.h"#include "eCosTest.h"#include "eCosTrace.h"#include "TestResource.h"#include "eCosTestUtils.h"#include "eCosTestSocket.h"#include "eCosTestSerial.h"#include "eCosTestSerialFilter.h"#include "eCosTestDownloadFilter.h"#define WF(n) (n+50)/1000,((n+50)%1000)/100 // Present n as whole and fractional part. Round to nearest least significant digit#define WFS _T("%u.%u") // The format string to output the abovestatic int nAuxPort; //hackstatic int nAuxListenSock; // hack#ifdef _WIN32 #include "Subprocess.h" #ifdef _DEBUG #define CloseHandle(x) try { ::CloseHandle(x); } catch(...) { TRACE(_T("!!! Exception caught closing handle %08x\n"),x); } #endif#endifstd::vector<CeCosTest::TargetInfo> CeCosTest::arTargetInfo;LPCTSTR const CeCosTest::arResultImage[1+CeCosTest::StatusTypeMax]={_T("NotStarted"), _T("NoResult"), _T("Inapplicable"), _T("Pass"), _T("DTimeout"), _T("Timeout"), _T("Cancelled"), _T("Fail"), _T("AssertFail"), _T("Unknown")};CeCosTest *CeCosTest::pFirstInstance=0;int CeCosTest::InstanceCount=0;LPCTSTR const CeCosTest::arServerStatusImage[1+CeCosTest::ServerStatusMax]={ _T("Busy"), _T("Ready"), _T("Can't run"), _T("Connection failed"), _T("Locked"), _T("Bad server status")};LPCTSTR CeCosTest::ExecutionParameters::arRequestImage [1+ExecutionParameters::RequestTypeMax]={ _T("Run"), _T("Query"), _T("Lock"), _T("Unlock"), _T("Stop"), _T("Bad request") }; const CeCosTest::TargetInfo CeCosTest::tDefault(_T("Unknown"),_T(""),-1);// Do not use spaces in image strings for consideration of _stscanf// One day this can be loadable from some external resource.int CeCosTest::InitTargetInfo(LPCTSTR pszFilename){ TRACE(_T("InitTargetInfo %s\n"),pszFilename); FILE *f=_tfopen(pszFilename,_T("rt")); if(f){ enum {BUFSIZE=512}; int nLine=0; TCHAR buf[BUFSIZE]; while(_fgetts(buf,sizeof(buf)-1,f)){ nLine++; StringArray ar; String(buf).Chop(ar); switch(ar.size()){ // <target> <prefix> <nType> [<gdbcmds>] case 0: continue; case 3: arTargetInfo.push_back(TargetInfo(ar[0],ar[1],ar[2],0)); break; case 1: case 2: ERROR(_T("Illegal configuration at line %d\n"),nLine); continue; default: arTargetInfo.push_back(TargetInfo(ar[0],ar[1],ar[2],ar[3])); break; } } fclose(f); } return arTargetInfo.size();}int CeCosTest::InitTargetInfoReg(LPCTSTR pszRegKey){ #ifdef _WIN32 HKEY hKey; bool rc=ERROR_SUCCESS==RegOpenKeyEx (HKEY_LOCAL_MACHINE, pszRegKey, 0L, KEY_READ, &hKey); DWORD dwSubKeys=0; if(rc){ // Found the given key. // Subkeys' names are the target image names: // Subkeys's values are: // Prefix String // Type String // GdbCmd String [optional] FILETIME ftLastWriteTime; DWORD dwMaxSubKeyLen; if(ERROR_SUCCESS==RegQueryInfoKey(hKey,NULL,NULL,NULL,&dwSubKeys,&dwMaxSubKeyLen,NULL,NULL,NULL,NULL,NULL,NULL)){ TCHAR *szName=new TCHAR[1+dwMaxSubKeyLen]; DWORD dwSizeName=dwMaxSubKeyLen; for(DWORD dwIndex=0;ERROR_SUCCESS==RegEnumKeyEx(hKey, dwIndex, szName, &dwSizeName, NULL, NULL, NULL, &ftLastWriteTime); dwIndex++){ HKEY hKey2; if(ERROR_SUCCESS!=RegOpenKeyEx (hKey, szName, 0L, KEY_READ, &hKey2)){ ERROR(_T("Failed to open %s\\%s\n"),pszRegKey,szName); rc=false; } else { DWORD dwMaxValueLen; if(ERROR_SUCCESS==RegQueryInfoKey(hKey2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&dwMaxValueLen,NULL,NULL)){ DWORD dwSizePrefix=dwMaxValueLen; DWORD dwSizeGdbCmd=dwMaxValueLen; DWORD dwSizeHwType=dwMaxValueLen; TCHAR *szPrefix=new TCHAR[1+dwMaxValueLen]; TCHAR *szGdbCmd=new TCHAR[1+dwMaxValueLen]; TCHAR *szHwType=new TCHAR[1+dwMaxValueLen]; if(ERROR_SUCCESS==RegQueryValueEx(hKey2, _T("Prefix"),NULL, NULL,(LPBYTE)szPrefix,&dwSizePrefix)){ arTargetInfo.push_back(TargetInfo(szName,szPrefix, (ERROR_SUCCESS==RegQueryValueEx(hKey2,_T("HwType"),NULL, NULL,(LPBYTE)szHwType,&dwSizeHwType))?szHwType:_T(""), (ERROR_SUCCESS==RegQueryValueEx(hKey2,_T("GdbCmd"),NULL, NULL,(LPBYTE)szGdbCmd,&dwSizeGdbCmd))?szGdbCmd:0 )); } delete [] szPrefix; delete [] szGdbCmd; delete [] szHwType; } RegCloseKey(hKey2); } dwSizeName=dwMaxSubKeyLen; } delete [] szName; } RegCloseKey(hKey); } return rc?dwSubKeys:0;#else // UNIX return 0;#endif}bool CeCosTest::Init(){ TRACE(_T("CeCosTest::Init\n")); srand( (unsigned)time( NULL ) ); #ifdef _WIN32 WSADATA wsaData; WORD wVersionRequested = MAKEWORD( 2, 0 ); WSAStartup( wVersionRequested, &wsaData ); // get target info from the registry String strPlatformsKey = _T("Software\\Red Hat\\eCos\\"); strPlatformsKey += GetGreatestSubkey (_T("Software\\Red Hat\\eCos")); strPlatformsKey += _T("\\Platforms"); InitTargetInfoReg (strPlatformsKey); // add target info from .eCosrc LPCTSTR psz=_tgetenv(_T("HOMEDRIVE")); if(psz){ String strFile(psz); psz=_tgetenv(_T("HOMEPATH")); if(psz){ strFile+=psz; } if(_TCHAR('\\')!=strFile[strFile.GetLength()-1]){ strFile+=_TCHAR('\\'); } strFile+=_T(".eCosrc"); InitTargetInfo(strFile); }#else // UNIX sigset_t mask; // Clean out all the signals sigemptyset(&mask); // Add our sigpipe sigaddset(&mask, SIGPIPE); sigprocmask(SIG_SETMASK, &mask, NULL); // _WIN32 not defined so get target info from .eCosrc LPCTSTR psz=_tgetenv(_T("HOME")); if(psz){ String strFile(psz); strFile+=_T("/.eCosrc"); InitTargetInfo(strFile); }#endif if(0==TargetTypeMax()){ ERROR(_T("Failed to initialize any targets\n")); } return true;}void CeCosTest::Term(){ TRACE(_T("CeCosTest::Term\n"));#ifdef _WIN32 WSACleanup();#endif};bool CeCosTest::SaveTargetInfo(){#ifdef _WIN32 // save target info to the registry String strPlatformsKey = _T("Software\\Red Hat\\eCos\\"); strPlatformsKey += GetGreatestSubkey (_T("Software\\Red Hat\\eCos")); strPlatformsKey += _T("\\Platforms"); return SaveTargetInfoReg (strPlatformsKey);#else // UNIX // get target info from .eCosrc String strFile=_tgetenv(_T("HOME")); if(strFile.GetLength()>0){ strFile+=_T("/.eCosrc"); return SaveTargetInfo(strFile); } else { return false; }#endif}bool CeCosTest::SaveTargetInfo(LPCTSTR pszFilename){ return false; //FIXME}#ifdef _WIN32bool CeCosTest::SaveTargetInfoReg(LPCTSTR pszRegKey){ CProperties::CreateKey(pszRegKey,HKEY_LOCAL_MACHINE); HKEY hKey; bool rc=ERROR_SUCCESS==RegOpenKeyEx (HKEY_LOCAL_MACHINE, pszRegKey, 0L, KEY_ALL_ACCESS, &hKey); if(rc){ for(int i=0;i<(signed)arTargetInfo.size();i++){ HKEY hKey2; DWORD dwDisp; const TargetInfo &ti=arTargetInfo[i]; rc&=(ERROR_SUCCESS==RegCreateKeyEx(hKey,ti.Image(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey2, &dwDisp)); if(rc){ LPCTSTR pszPrefix=ti.Prefix(); LPCTSTR pszGdb =ti.GdbCmd(); LPCTSTR pszHwType=CeCosTest::TargetInfo::arHwTypeImage[ti.Type()]; rc&=(ERROR_SUCCESS==RegSetValueEx(hKey2,_T("Prefix"),0,REG_SZ, (CONST BYTE *)pszPrefix,(1+_tcslen(pszPrefix))*sizeof TCHAR)) && (ERROR_SUCCESS==RegSetValueEx(hKey2,_T("HwType"),0,REG_SZ, (CONST BYTE *)pszHwType,(1+_tcslen(pszHwType))*sizeof TCHAR)) && (ERROR_SUCCESS==RegSetValueEx(hKey2,_T("GdbCmd"),0,REG_SZ, (CONST BYTE *)pszGdb,(1+_tcslen(pszGdb))*sizeof TCHAR)); } RegCloseKey(hKey2); } RegCloseKey(hKey); } return rc;}#endifstatic bool CALLBACK IsCancelled(void *pThis){ return CeCosTest::Cancelled==((CeCosTest *)pThis)->Status();}// Ctors and dtors:CeCosTest::CeCosTest(const ExecutionParameters &e, LPCTSTR pszExecutable,LPCTSTR pszTitle):m_nRunCount(0), m_nStrippedSize(0), m_nFileSize(0), m_bDownloading(false), m_pSock(0), m_ep(e), m_strTitle(pszTitle), m_Status(NotStarted), m_nDownloadTime(0), m_nTotalTime(0), m_nMaxInactiveTime(0), m_pPort(0){ SetExecutable (pszExecutable); TRACE(_T("%%%% Create test instance %08x count:=%d\n"),this,InstanceCount+1); GetPath(m_strPath); ENTERCRITICAL; InstanceCount++; m_pNextInstance=pFirstInstance; if(m_pNextInstance){ m_pNextInstance->m_pPrevInstance=this; } m_pPrevInstance=0; pFirstInstance=this; LEAVECRITICAL; }CeCosTest::~CeCosTest(){ TRACE(_T("%%%% Delete test instance %08x\n"),this); Cancel(); CloseSocket(); if(m_pPort){ m_pPort->Release(); //delete m_pPort; //m_pPort=0; } VTRACE(_T("~CeCosTest(): EnterCritical and decrease instance count\n")); ENTERCRITICAL; InstanceCount--; TRACE(_T("%%%% Destroy instance. Instance count:=%d\n"),InstanceCount); if(pFirstInstance==this){ pFirstInstance=m_pNextInstance; } if(m_pPrevInstance){ m_pPrevInstance->m_pNextInstance=m_pNextInstance; } if(m_pNextInstance){ m_pNextInstance->m_pPrevInstance=m_pPrevInstance; } LEAVECRITICAL;}bool CeCosTest::RunRemote (LPCTSTR pszRemoteHostPort){ bool rc=false; m_nRunCount++; TRACE(_T("RunRemote\n")); m_strExecutionHostPort=pszRemoteHostPort; SetPath(m_strPath); m_Status=NotStarted; VTRACE(_T("RemoteThreadFunc()\n")); // Find a server. ConnectForExecution(); if(Cancelled!=Status()){ if(ServerSideGdb()){ // The executable is transmitted to the server for execution. // Send file size if(m_pSock->sendInteger(m_nFileSize,_T("file size"))&&m_nFileSize>0){ int nBufSize=MIN(10000,m_nFileSize); Buffer b(nBufSize); TRACE(_T("Sending [%d bytes]\n"), m_nFileSize); int nToSend=m_nFileSize; FILE *f1=_tfopen(m_strExecutable,_T("rb")); if(0==f1){ Log(_T("Failed to open %s - %s\n"),(LPCTSTR )m_strExecutable,strerror(errno)); } else { while (nToSend>0){ int nRead=fread( b.Data(), 1, nBufSize, f1); if(nRead<=0){ Log(_T("Failure reading %s - %s\n"),(LPCTSTR )m_strExecutable,strerror(errno)); break; } if(!send( b.Data(), nRead, _T("executable"))){ Log(_T("Failure sending %s - %s\n"),(LPCTSTR )m_strExecutable,(LPCTSTR )m_pSock->SocketErrString()); break; } nToSend-=nRead; } fclose(f1); f1=0; if(nToSend>0){ TRACE(_T("done [%d bytes sent]\n"),m_nFileSize-nToSend); Log(_T("Failed to transmit %s - %d/%d bytes sent\n"),(LPCTSTR )m_strExecutable,m_nFileSize-nToSend,m_nFileSize); } else { TRACE(_T("done\n")); rc=true; } } if(!recvResult(9*1000*60)){ // nine minutes Log(_T("Failed to receive result from remote server\n")); rc=false; } m_pSock->sendInteger(1); // send an ack [n'importe quoi] CloseSocket(); } } else { // The server sets up a connection between port and tcp/ip socket, and gdb is run locally
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -