⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ecostest.cpp

📁 移植到WLIT项目的redboot源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//####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 "eCosTestPlatform.h"#include "eCosTrace.h"#include "TestResource.h"#include "eCosTestUtils.h"#include "eCosSocket.h"#include "eCosSerial.h"#include "eCosTestSerialFilter.h"#include "eCosTestDownloadFilter.h"#include "Properties.h"#include "Subprocess.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 aboveLPCTSTR  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") };  static bool CALLBACK IsCancelled(void *pThis){  return CeCosTest::Cancelled==((CeCosTest *)pThis)->Status();}// Ctors and dtors:CeCosTest::CeCosTest(const ExecutionParameters &e, LPCTSTR pszExecutable,LPCTSTR pszTitle):  m_pspPipe(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_pResource(0),  m_psp(0){    assert(e.Platform());    SetExecutable (pszExecutable);    TRACE(_T("%%%% Create test instance %08x count:=%d\n"),this,InstanceCount+1);    // By recording the path now, we ensure processes are always run in the context in which the test instance  // is created (important for the ConfigTool to be able to call PrepareEnvironment).#ifdef _WIN32  // for some reason _tgetenv() doesn't return the PATH set  // by PrepareEnvironment() so use GetEnvironmentVariable() instead  // JLD - 2000-06-09  String strPath;  int nSize=GetEnvironmentVariable(_T("PATH"), NULL, 0);  GetEnvironmentVariable(_T("PATH"), strPath.GetBuffer(nSize), nSize);  strPath.ReleaseBuffer();  m_strPath=strPath;#else  LPCTSTR pszPath=_tgetenv(_T("PATH"));  if(pszPath){    m_strPath=pszPath;  }#endif    ENTERCRITICAL;  InstanceCount++;  m_pNextInstance=pFirstInstance;  if(m_pNextInstance){    m_pNextInstance->m_pPrevInstance=this;  }   m_pPrevInstance=0;  pFirstInstance=this;  LEAVECRITICAL;  }CeCosTest::~CeCosTest(){  for(int i=0;i<(signed)m_arpExecsp.size();i++){    delete (CSubprocess *)m_arpExecsp[i];  }  delete m_pspPipe;  TRACE(_T("%%%% Delete test instance %08x\n"),this);  Cancel();  CloseSocket();  if(m_pResource){    m_pResource->Release();    //delete m_pResource;    //m_pResource=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;  TRACE(_T("RunRemote\n"));  m_strExecutionHostPort=pszRemoteHostPort;  m_Status=NotStarted;    VTRACE(_T("RemoteThreadFunc()\n"));    // Find a server.  ConnectForExecution();  if(Cancelled!=Status()){           if(m_ep.Platform()->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(456); // 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      // Big timeout here because we have to wait for the target to be reset      // We do this:      // do {      //     target ready indicator (0==fail, 1==ready, 2==fail and will retry)      //     any output so far      // } while (2==target ready indicator)      // read host:port      String strHostPort;      if(GetTargetReady(strHostPort)){        // Fix up a resource to represent permission to use the host:port we have been told about        CTestResource resource;        resource.SetTarget(m_ep.PlatformName());        resource.SetDownload(strHostPort,0);        m_pResource=&resource;        RunLocal();        m_pResource=0;        m_pSock->sendInteger(Status(),_T("Terminating ack"));        m_pSock->Close();        rc=true;      }    }  }  TRACE(_T("RemoteThreadFunc - exiting\n"));  return rc;}// Run the test locallybool CeCosTest::RunLocal(){  bool rc=false;  TRACE(_T("RunLocal %s\n"),(LPCTSTR)Executable());  if(!CeCosTestUtils::IsFile(Executable())){    Log(_T("Cannot run - %s is not a file\n"),(LPCTSTR)Executable());  } else if(0==m_pResource && 0==CTestResource::Count(m_ep)){    Log(_T("Cannot run a %s test\n"),(LPCTSTR)m_ep.PlatformName());  } else {        m_Status=NotStarted;    TRACE(_T("LocalThreadFunc - target=%s\n"),(LPCTSTR)m_ep.PlatformName());    // Acquire a port (our caller may have done this for us)    VTRACE(_T("LocalThreadFunc():Trying to acquire a port\n"));    if(0==m_pResource){      for(;;){        m_pResource=CTestResource::GetResource(m_ep);        if(m_pResource||Cancelled==Status()){          break;        }        CeCosThreadUtils::Sleep(2000);        TRACE(_T("Waiting for a port\n"));      }    }    VTRACE(_T("\nPort acquired!\n"));        if(Cancelled!=Status()){      // This means we have acquired a local port       bool bTargetReady=false;      if(!m_pResource->HasReset()){        bTargetReady=true;      } else {        bTargetReady=(CResetAttributes::RESET_OK==m_pResource->Reset(0,this));      }      // we may proceed to execute the test      if(bTargetReady){        SetStatus(NotStarted);        if(NOTIMEOUT==m_ep.DownloadTimeout()){          // No elapsed timeout given - calculate from knowledge of executable size and baud rate          // 10 baud ~= 1 byte/sec, but we halve this to account for download in hex :-(          // We use a minimum of 30 seconds and double the calculated result for safety          // Note that the baud rate is generally unknown on the client side.          int nBaud=m_pResource->Baud();          if(0==nBaud){            CTestResource *pExecutionResource=CTestResource::Lookup(m_strExecutionHostPort);            if(pExecutionResource){              nBaud=pExecutionResource->Baud();            }           }          if(0==nBaud){            nBaud=38400;          }          int nBytesPerSec=(nBaud/10)/2; // division by 2 assumes download in "ascii" (2 bytes/char)          m_ep.SetDownloadTimeout (1000*MAX(30,2*(m_nStrippedSize/nBytesPerSec)));          TRACE(_T("Estimated download time %d sec (%d bytes @ %d bytes/sec [%d baud])\n"),m_nStrippedSize/nBytesPerSec,m_nStrippedSize,nBytesPerSec,nBaud);        }        TRACE(_T("Active timeout=%d download timeout=%d\n"),m_ep.ActiveTimeout(), m_ep.DownloadTimeout());        GetInferiorCommands(m_arstrInferiorCmds);        String strInferior(m_ep.Platform()->Inferior());        strInferior.Replace(_T("%e"),CygPath(m_strExecutable),true);        RunInferior(strInferior);        rc=true;                }    }    if(m_pResource){      m_pResource->Release();      m_pResource=0;    }    TRACE(_T("RunLocal - exiting\n"));  }  return rc;}void CeCosTest::Cancel (){  SetStatus(Cancelled);}CeCosTest::ServerStatus CeCosTest::Connect (LPCTSTR pszHostPort, CeCosSocket *&pSock, const ExecutionParameters &e,String &strInfo,Duration dTimeout){  // Find out whether this host is receptive  ServerStatus s=CONNECTION_FAILED;  pSock=new CeCosSocket(pszHostPort,dTimeout);  int nStatus;      if(pSock->Ok() &&    pSock->sendString(e.Image(), _T("execution parameters")) &&    pSock->recvInteger(nStatus,_T("ready status")) &&    pSock->recvString(strInfo)){    s=(ServerStatus)MIN(nStatus,ServerStatusMax);  }  if(SERVER_READY!=s || ExecutionParameters::RUN!=e.Request()){    delete pSock;    pSock=0;  }  return s;}// Initiate a connection to hostName:nPort and acquire the ready status [retry until this is achieved]// The socket (m_pSock) is left open.// This function is either called with m_strExecutionHostPort already set to a desired server// or else m_strExecutionHostPort empty (in which case the server is / dynamically)void CeCosTest::ConnectForExecution (){  bool bSchedule=(0==m_strExecutionHostPort.size());  Duration nDelay=2000;    m_pSock=0;    bool *arbHostTried=0;    while(Cancelled!=Status()){    StringArray arstrHostPort,arstrTries;    int nChoices;        if(bSchedule){      if(!CTestResource::GetMatches(m_ep,arstrHostPort)){        Log(_T("Could not establish matches\n"));        continue;      }      nChoices=arstrHostPort.size();      if(nChoices>0){        TRACE(_T("ConnectForExecution: choices are:\n"));        for(int i=0;i<nChoices;i++){          TRACE(_T("\t%s\n"),(LPCTSTR)arstrHostPort[i]);        }      }    } else {      // Server has already been picked by caller      nChoices=1;      String str;      arstrHostPort.push_back(m_strExecutionHostPort);    }        if(nChoices>0){      delete [] arbHostTried;      arbHostTried=new bool[nChoices];      for(int i=0;i<nChoices;i++){        arbHostTried[i]=false;      }            // Loop around the choices      for(int nUntried=nChoices;nUntried>0;nUntried--) {        // Select one we haven't tried already:        int nChoice;                do {          nChoice=rand() % nChoices;        } while (arbHostTried[nChoice]);                m_strExecutionHostPort=arstrHostPort[nChoice];                TRACE(_T("ConnectForExecution: chosen %s\n"),(LPCTSTR)m_strExecutionHostPort);        if(CeCosSocket::IsLegalHostPort(m_strExecutionHostPort)){          // If we're using the resource server we had better check that the host          // we are about to lock has not been resource-locked (the other match checks          // will of course always succeed)          String strInfo;           ServerStatus s=bSchedule && !CTestResource::Matches(m_strExecutionHostPort,m_ep)?SERVER_LOCKED:              Connect(m_strExecutionHostPort,m_pSock,m_ep,strInfo);          arbHostTried[nChoice]=true;                  TRACE(_T("Connect: %s says %s %s\n"),(LPCTSTR)m_strExecutionHostPort,(LPCTSTR)Image(s),(LPCTSTR)strInfo);          CTestResource *pResource=CTestResource::Lookup(m_strExecutionHostPort);          if(pResource){            String str;            str.Format(_T("%s %s %s"),(LPCTSTR)pResource->Image(),(LPCTSTR)strInfo,(LPCTSTR)Image(s));            arstrTries.push_back(str);          }          if(SERVER_READY==s){            // So that's ok then.  We're outta here.            INTERACTIVE(_T("Connected to %s\n"),(LPCTSTR)m_strExecutionHostPort);            goto Done;          } else {            delete m_pSock;            m_pSock=0;          }        }      }     }        INTERACTIVE(_T("Warning - could not connect to any test servers:\n"));    if(arstrTries.size()>0){      for(unsigned int i=0;i<arstrTries.size();i++){        INTERACTIVE(_T("    %s\n"),(LPCTSTR)arstrTries[i]);      }    } else {      INTERACTIVE(_T("No servers available to execute %s test:\n"),(LPCTSTR)m_ep.PlatformName());      ENTERCRITICAL;      for(CTestResource *pResource=CTestResource::First();pResource;pResource=pResource->Next()){        INTERACTIVE(_T("    %s\n"),(LPCTSTR)pResource->Image());      }      LEAVECRITICAL;    }    INTERACTIVE(_T("Retry in %d seconds...\n"),nDelay/1000);        // We have tried all possibilities - sleep before retrying    CeCosThreadUtils::Sleep(nDelay);        if(Cancelled==m_Status){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -