📄 ecostest.cpp
字号:
TRACE(_T("ConnectForExecution : cancelled\n"));
goto Done;
}
if(nDelay<20*1000){
nDelay+=rand() % 500;
}
}
Done:
delete [] arbHostTried;
}
void CeCosTest::SetStatus (StatusType status)
{
ENTERCRITICAL;
if((int)status>(int)m_Status){
TRACE(_T("Status <- %s\n"),(LPCTSTR)Image(status));
m_Status=status;
}
LEAVECRITICAL;
}
bool CeCosTest::WaitForAllInstances(int nPoll,Duration nTimeout)
{
Time t0=Now();
while(InstanceCount>0){
CeCosThreadUtils::Sleep(nPoll);
if(NOTIMEOUT!=nTimeout && Now()-t0>nTimeout){
return false;
}
}
return true;
}
void CeCosTest::DeleteAllInstances()
{
while(pFirstInstance){
delete pFirstInstance;
}
}
void CeCosTest::CancelAllInstances()
{
ENTERCRITICAL;
for(CeCosTest *pTest=pFirstInstance;pTest;pTest=pTest->m_pNextInstance){
pTest->Cancel();
}
LEAVECRITICAL;
}
// The same format is used for _stscanf as for Format (which is like printf), so restrict to the format specifiers
// the former is happy with. In particular, do not use %-3s etc...
LPCTSTR CeCosTest::pszFormat=
// 1999-01-15 17:24:36 Fireblade:5002 MN10300 sin.exe 219k/134k Pass sin download=106.3/117.0 Total=107.6 Max inactive=1.0/300.0
_T("%04d-%02d-%02d %02d:%02d:%02d ") // Time
_T("%15s ") // Execution host:port
_T("%16s ") // Target
_T("%30s ") // Executable tail
_T("%11s ") // Result
_T("%dk/%dk ") // Sizes
_T("D=") WFS _T("/") WFS _T(" Total=") WFS _T(" ") // Times
_T("E=") WFS _T("/") WFS _T(" ")
_T("\"%s\"");
bool CeCosTest::Value (
LPCTSTR pszStr,
struct tm &t,
StatusType &status,
String &target,
String &strExecutionHostPort,
String &strExecutableTail,
String &strTitle,
int &nFileSize,
Duration &nTotalTime,
Duration &nMaxInactiveTime,
Duration &nDownloadTime,
Duration &nDownloadTimeout,
Duration &nActiveTimeout,
int &nDownloadedSize)
{
int nLen=_tcslen(pszStr);
String strStatus;
nFileSize=nTotalTime=nMaxInactiveTime=nDownloadTime=nDownloadTimeout=nActiveTimeout=nDownloadedSize=0;
int nTotalTimeFrac=0;
int nMaxInactiveTimeFrac=0;
int nActiveTimeoutFrac=0;
int nDownloadTimeFrac=0;
int nDownloadTimeoutFrac=0;
static String strFormat;
if(0==strFormat.size()){
// Construct a version of the format string sans length attributes for %s items
LPCTSTR c=pszFormat;
TCHAR *d=strFormat.GetBuffer(_tcslen(pszFormat));
while(_TCHAR('\0')!=*c){
if(_TCHAR('%')==c[0] && _istdigit(c[1])){
*d++=_TCHAR('%');
do {
c++;
} while (_istdigit(*c));
}
*d++=*c++;
}
*d=_TCHAR('\0');
strFormat.ReleaseBuffer();
}
_stscanf(pszStr,
strFormat,
&t.tm_year,&t.tm_mon,&t.tm_mday,
&t.tm_hour,&t.tm_min,&t.tm_sec, // Time of day
strExecutionHostPort.GetBuffer(1+nLen), // Execution host:port
target.GetBuffer(1+nLen), // Target
strExecutableTail.GetBuffer(1+nLen), // Executable
strStatus.GetBuffer(1+nLen), // Result
&nDownloadedSize,&nFileSize, // Sizes
&nDownloadTime,&nDownloadTimeFrac, // Times
&nDownloadTimeout,&nDownloadTimeoutFrac,
&nTotalTime,&nTotalTimeFrac,
&nMaxInactiveTime,&nMaxInactiveTimeFrac,
&nActiveTimeout,&nActiveTimeoutFrac,
strTitle.GetBuffer(1+nLen) // Title
);
strExecutionHostPort.ReleaseBuffer();
target.ReleaseBuffer();
strExecutableTail.ReleaseBuffer();
strStatus.ReleaseBuffer();
strTitle.ReleaseBuffer();
status=StatusTypeValue(strStatus);
LPCTSTR c1=_tcschr(pszStr,_TCHAR('"'));
if(c1){
c1++;
LPCTSTR c2=_tcschr(c1+1,_TCHAR('"'));
if(c2){
strTitle=String(c1,c2-c1);
}
}
nTotalTime=nTotalTime*1000+nTotalTimeFrac*100;
nMaxInactiveTime=nMaxInactiveTime*1000+nMaxInactiveTimeFrac*100;
nActiveTimeout=nActiveTimeout*1000+nActiveTimeoutFrac*100;
nDownloadTime=nDownloadTime*1000+nDownloadTimeFrac*100;
nDownloadTimeout=nDownloadTimeout*1000+nDownloadTimeoutFrac*100;
nFileSize*=1024;
nDownloadedSize*=1024;
t.tm_year-=1900;
t.tm_mon--;
return t.tm_year>=0 && t.tm_year<=200 && t.tm_mon>=0 && t.tm_mon<=11 && t.tm_mday>=1 && t.tm_mday<=31 && t.tm_hour>=0 && t.tm_hour<=23 && t.tm_min>=0 && t.tm_min<=59 && t.tm_sec>=0 && t.tm_sec<=59 &&
status!=StatusTypeMax
//&& exetype!=ExecutionParameters::ExecutableTypeMax
;
}
const String CeCosTest::ResultString(bool bIncludeOutput) const
{
String strResultString;
String strTitle(m_strTitle);
String strExecutionHostPort(m_strExecutionHostPort);
if(0==strTitle.size()){
strTitle=CeCosSocket::MySimpleHostName();
strTitle+=_TCHAR(':');
strTitle+=m_strExecutable;
}
if(0==strExecutionHostPort.size()){
strExecutionHostPort=CeCosSocket::MySimpleHostName();
strExecutionHostPort+=_T(":0");
}
ENTERCRITICAL;
time_t ltime;
time(<ime);
struct tm *now=localtime( <ime );
strResultString.Format(
pszFormat,
1900+now->tm_year,1+now->tm_mon,now->tm_mday,
now->tm_hour,now->tm_min,now->tm_sec, // Time of day
(LPCTSTR)strExecutionHostPort, // Execution host:port
(LPCTSTR)m_ep.PlatformName(), // Target
(LPCTSTR)CeCosTestUtils::Tail(m_strExecutable), // Executable
(LPCTSTR)Image(Status()), // Result
m_nStrippedSize/1024,m_nFileSize/1024, // Sizes
WF(m_nDownloadTime),WF(m_ep.DownloadTimeout()),WF(m_nTotalTime),// Times
WF(m_nMaxInactiveTime),WF(m_ep.ActiveTimeout()),
(LPCTSTR)strTitle // Title
);
if(bIncludeOutput && m_strOutput.size()>0){
strResultString+=_TCHAR('\n');
strResultString+=m_strOutput;
}
LEAVECRITICAL;
return strResultString;
}
// Run as a server, listening on the port given as parameter
bool CeCosTest::RunAgent(int nTcpPort)
{
bool bLocked=false;
// Create socket
int nSock = CeCosSocket::Listen(nTcpPort);
int nLastClient=0;
if (-1!=nSock) {
for (;;) {
try {
CeCosSocket *pSock=new CeCosSocket(nSock); // AcceptThreadFunc deletes if not deleted below
String str;
// Read the execution parameters
if(!pSock->recvString(str)){
// Socket error on the recv - nothing much we can do
TRACE(_T("RunAgent : could not read execution parameters\n"));
delete pSock;
pSock=0;
} else {
ExecutionParameters e;
e.FromStr(str);
TRACE(_T("Execution parameters: %s\n"),(LPCTSTR)e.Image());
ServerStatus s;
CTestResource *pPort=0;
String strInfo;
switch(e.Request()) {
case ExecutionParameters::LOCK:
if(bLocked){
s=SERVER_BUSY;
} else {
WaitForAllInstances(1000,NOTIMEOUT);
bLocked=true;
s=SERVER_LOCKED;
}
break;
case ExecutionParameters::UNLOCK:
if(bLocked){
bLocked=false;
s=SERVER_READY;
} else {
s=SERVER_BUSY;
}
break;
case ExecutionParameters::QUERY:
if (bLocked) {
s=SERVER_LOCKED;
} else {
s=SERVER_BUSY;
ENTERCRITICAL;
for(CTestResource *pResource=CTestResource::First();pResource;pResource=pResource->Next()){
if(!pResource->InUse()){
s=SERVER_READY;
break;
}
}
LEAVECRITICAL;
if(SERVER_READY!=s){
strInfo.Format(_T("serving %s"),(LPCTSTR)CeCosSocket::ClientName(nLastClient));
}
}
break;
case ExecutionParameters::RUN:
if(NULL==e.Platform()){
// Looks like a confused client ...
strInfo.Format(_T("Bad target value %s read from client\n"),(LPCTSTR)str);
s=SERVER_CANT_RUN;
} else if(0==CTestResource::Count(e)){
// No chance of running this test
strInfo.Format(_T("Cannot run a %s test from this server\n"),(LPCTSTR)e.PlatformName());
s=SERVER_CANT_RUN;
} else if (bLocked) {
s=SERVER_LOCKED;
} else {
pPort=CTestResource::GetResource(e);
if(0==pPort){
// We must disappoint our client
strInfo.Format(_T("serving %s"),(LPCTSTR)CeCosSocket::ClientName(nLastClient));
s=SERVER_BUSY;
} else {
s=SERVER_READY;
nLastClient=pSock->Client();
}
}
break;
case ExecutionParameters::STOP:
s=SERVER_READY;
break;
default:
s=SERVER_CANT_RUN;
}
#ifndef VERBOSE
if(ExecutionParameters::QUERY!=e.Request())
#endif
TRACE(_T("RunAgent : %s request tActive=%d tDownload=%d Target=%s Reply status=%s %s\n"),
(LPCTSTR)e.Image(e.Request()),e.ActiveTimeout(),e.DownloadTimeout(),
(LPCTSTR)e.PlatformName(),
(LPCTSTR)Image(s),(LPCTSTR)strInfo);
bool bSendok=pSock->sendInteger(s) && pSock->sendString(strInfo);
if(SERVER_READY==s && bSendok && ExecutionParameters::RUN==e.Request()){
// Create a new class instance
// AcceptThreadFunc deletes the instance and closes new_sock
// RunLocal, called by AcceptThreadFunc, releases the port
// No need for meaningful callback, but must run asynchronously
int nAuxPort=30000;
int nAuxListenSock=-1;
do {
nAuxListenSock=CeCosSocket::Listen(nAuxPort);
} while (-1==nAuxListenSock && nAuxPort++<=0xffff);
if(-1==nAuxListenSock){
ERROR(_T("Couldn't find a socket to bind to for RDI\n"));
} else {
CeCosTest *pTest=new CeCosTest(e,NULL);
pTest->m_nAuxPort=nAuxPort;
pTest->m_nAuxListenSock=nAuxListenSock;
pTest->m_pSock=pSock;
pTest->m_strExecutionHostPort=CeCosSocket::HostPort(CeCosSocket::MyHostName(),nTcpPort);
pTest->m_pResource=pPort;
CeCosThreadUtils::RunThread(SAcceptThreadFunc,pTest,_T("SAcceptThreadFunc"));
// AcceptThreadFunc deletes pSock
}
} else {
delete pSock;
pSock=0;
if(pPort){
pPort->Release();
pPort=0;
}
if(CeCosTest::ExecutionParameters::STOP==e.Request()){
CancelAllInstances();
WaitForAllInstances(1000,20*1000);
break;
}
}
}
}
catch(...){
TRACE(_T("!!! Exception caught in RunAgent()\n"));
}
}
CeCosSocket::CloseSocket (nSock);
}
return false;
}
CeCosTest::StatusType CeCosTest::StatusTypeValue(LPCTSTR pszStr)
{
for(int i=0;i<StatusTypeMax;i++){
StatusType t=(StatusType)i;
if(0==_tcsicmp(Image(t),pszStr)){
return t;
}
}
return StatusTypeMax;
}
// Thread to run ConnectSocketToSerial
void CeCosTest::ConnectSocketToSerialThreadFunc()
{
TRACE(_T("ConnectSocketToSerialThreadFunc sock=%d\n"),m_nAuxListenSock);
CeCosTestSerialFilter serial_filter;
CeCosTestDownloadFilter download_filter;
CeCosSerial serial;
serial.SetBlockingReads(false);
bool rc=false;
// Open serial device.
if (!serial.Open(m_pResource->Serial(),m_pResource->Baud())){
ERROR(_T("Couldn't open port %s\n"),m_pResource->Serial());
} else {
for(;;){
// Flush the serial buffer.
serial.Flush();
TRACE(_T("ConnectSocketToSerial: waiting for connection...\n"));
CeCosSocket socket;
if(!socket.Accept(m_nAuxListenSock,&m_bStopConnectSocketToSerial)){
ERROR(_T("ConnectSocketToSerial - couldn't accept: %s\n"),(LPCTSTR)socket.SocketErrString());
break;
} else if (m_pSock->Client() != socket.Client()){
// Make sure the client is who we think it is...
TRACE(_T("ConnectSocketToSerialThread - illegal connection attempted from %s\n"),(LPCTSTR)socket.ClientName(socket.Client()));
} else {
try {
rc=CeCosSocket::ConnectSocketToSerial(socket,serial,m_ep.m_bUseFilter?SerialFilterFunction:NULL, (void*)&serial_filter, m_ep.m_bUseFilter?DownloadFilterFunction:NULL, (void*)&download_filter, &m_bStopConnectSocketToSerial);
// If the download filter was just active, it may
// allow the session to continue.
if(!download_filter.ContinueSession()){
break;
}
}
catch (LPCTSTR pszMsg){
Log(_T("!!! ConnectSocketToSerial exception caught: %s!!!\n"),pszMsg);
rc=false;
break;
}
catch (...){
Log(_T("!!! ConnectSocketToSerial exception caught!!!\n"));
rc=false;
break;
}
}
}
}
TRACE(_T("ConnectSocketToSerial : done\n"));
CeCosSocket::CloseSocket(m_nAuxListenSock);
}
static bool CALLBACK DerefBool(void *pParam)
{
return *(bool *)pParam;
}
// Function called (on a separate thread) to process a successful connection to the RunAgent loop
// In the case of a simulator server, we can have many of these active at the same time.
void CeCosTest::AcceptThreadFunc()
{
if(m_ep.Platform()->ServerSideGdb()){
// We dream up a temporary name for the executable
ENTERCRITICAL;
m_strExecutable.Format(_T("%s-%s-%d"),_ttmpnam(0),(LPCTSTR)m_ep.PlatformName(),m_nAuxPort);
LEAVECRITICAL;
int n;
if(m_pSock->recvInteger(n,_T("file size"))){
m_nFileSize=n;
// Read file from the socket
bool bCanRun=true;
TRACE(_T("AcceptThreadFunc file size=%d reading...\n"),m_nFileSize);
FILE *f2;
f2=_tfopen(m_strExecutable,_T("wb"));
if(0==f2){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -