URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [host/] [tools/] [ecostest/] [common/] [TestResource.cpp] - Rev 786
Compare with Previous | Blame | View Log
// ####ECOSHOSTGPLCOPYRIGHTBEGIN#### // ------------------------------------------- // This file is part of the eCos host tools. // Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. // // 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 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., 51 Franklin Street, // Fifth Floor, Boston, MA 02110-1301, USA. // ------------------------------------------- // ####ECOSHOSTGPLCOPYRIGHTEND#### //================================================================= // // TestResource.cpp // // Resource test class // //================================================================= //================================================================= //#####DESCRIPTIONBEGIN#### // // Author(s): sdf // Contributors: sdf // Date: 1999-04-01 // Description: This class abstracts a test resource for use in the testing infrastructure // Usage: // //####DESCRIPTIONEND#### #include "eCosStd.h" #include "eCosTestUtils.h" #include "eCosTrace.h" #include "Subprocess.h" #include "TestResource.h" CTestResource *CTestResource::pFirstInstance=0; unsigned int CTestResource::nCount=0; String CTestResource::strResourceHostPort; CTestResource::CTestResource(LPCTSTR pszHostPort, LPCTSTR target, LPCTSTR pszDownloadPort, int nBaud, LPCTSTR pszResetString): m_strReset(pszResetString), m_bInUse(false), m_nBaud(nBaud), m_strPort(pszDownloadPort), m_bLocked(false), m_Target(target) { CeCosSocket::ParseHostPort(pszHostPort,m_strHost,m_nPort); VTRACE(_T("@@@ Created resource %08x %s\n"),(unsigned int)this,(LPCTSTR)Image()); Chain(); } CTestResource::~CTestResource() { ENTERCRITICAL; VTRACE(_T("@@@ Destroy resource %08x %s\n"),this,(LPCTSTR)Image()); if(m_pPrevInstance || m_pNextInstance){ nCount--; } 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; } // Find the resource matching the given host:port specification // Returns 0 if no such host:port found CTestResource * CTestResource::Lookup(LPCTSTR pszHostPort) { CTestResource *pResource=NULL; ENTERCRITICAL; String strHost; int nPort; if(CeCosSocket::ParseHostPort(pszHostPort,strHost,nPort)){ for(pResource=pFirstInstance;pResource;pResource=pResource->m_pNextInstance){ if(nPort==pResource->TcpIPPort() && CeCosSocket::SameHost(strHost,pResource->Host())){ break; } } } LEAVECRITICAL; return pResource; } unsigned int CTestResource::GetMatchCount (const CeCosTest::ExecutionParameters &e,bool bIgnoreLocking) { unsigned int i=0; ENTERCRITICAL; for(const CTestResource *pResource=pFirstInstance;pResource;pResource=pResource->m_pNextInstance){ if(pResource->Matches(e,bIgnoreLocking)){ i++; } } LEAVECRITICAL; return i; } bool CTestResource::GetMatches (const CeCosTest::ExecutionParameters &e, StringArray &arstr, bool bIgnoreLocking) { bool rc=false; arstr.clear(); if(Load()){ ENTERCRITICAL; for(CTestResource *pResource=pFirstInstance;pResource;pResource=pResource->m_pNextInstance){ if(pResource->Matches(e,bIgnoreLocking)){ arstr.push_back(pResource->HostPort()); } } LEAVECRITICAL; rc=true; } return rc; } void CTestResource::DeleteAllInstances() { ENTERCRITICAL; while(pFirstInstance){ delete pFirstInstance; } LEAVECRITICAL; } bool CTestResource::LoadFromDirectory (LPCTSTR psz) { bool rc=true; ENTERCRITICAL; DeleteAllInstances(); // Find all the files in directory "psz" and load from each of them TCHAR szOrigDir[256]; _tgetcwd(szOrigDir,sizeof szOrigDir-1); if(0==_tchdir(psz)){ String strFile; void *pHandle; for(bool b=CeCosTestUtils::StartSearch(pHandle,strFile);b;b=CeCosTestUtils::NextFile(pHandle,strFile)){ if(CeCosTestUtils::IsFile(strFile)){ CTestResource *pResource=new CTestResource(_T(""),_T("")); CTestResourceProperties prop(pResource); prop.LoadFromFile(strFile); } } CeCosTestUtils::EndSearch(pHandle); } else { TRACE(_T("Failed to change to %s from %s\n"),psz,szOrigDir); } _tchdir(szOrigDir); LEAVECRITICAL; return rc; } bool CTestResource::SaveToDirectory (LPCTSTR pszDir) { bool rc=false; ENTERCRITICAL; { // Delete all the files under directory "pszDir" void *pHandle; TCHAR szOrigDir[256]; _tgetcwd(szOrigDir,sizeof szOrigDir-1); if(0==_tchdir(pszDir)){ String strFile; for(bool b=CeCosTestUtils::StartSearch(pHandle,strFile);b;b=CeCosTestUtils::NextFile(pHandle,strFile)){ if(CeCosTestUtils::IsFile(strFile)){ _tunlink(strFile); } } CeCosTestUtils::EndSearch(pHandle); rc=true; for(CTestResource *pResource=pFirstInstance;pResource;pResource=pResource->m_pNextInstance){ CTestResourceProperties prop(pResource); rc&=prop.SaveToFile(pResource->FileName()); } } else { fprintf(stderr,"Failed to change to %s from %s\n",pszDir,szOrigDir); } _tchdir(szOrigDir); } LEAVECRITICAL; return rc; } #ifdef _WIN32 bool CTestResource::LoadFromRegistry(HKEY key,LPCTSTR psz) { // Find all the keys under "psz" and load from each of them bool rc=false; ENTERCRITICAL; HKEY hKey; if(ERROR_SUCCESS==RegOpenKeyEx ((HKEY)key, psz, 0L, KEY_ENUMERATE_SUB_KEYS, &hKey)){ TCHAR szName[256]; DWORD dwSizeName=sizeof szName; FILETIME ftLastWriteTime; for(DWORD dwIndex=0;ERROR_SUCCESS==RegEnumKeyEx(hKey, dwIndex, szName, &dwSizeName, NULL, NULL, NULL, &ftLastWriteTime); dwIndex++){ CTestResource *pResource=new CTestResource(_T(""),_T("")); String strKey; strKey.Format(_T("%s\\%s"),psz,szName); CTestResourceProperties prop1(pResource); prop1.LoadFromRegistry(key,strKey); dwSizeName=sizeof szName; } RegCloseKey(hKey); } LEAVECRITICAL; return rc; } bool CTestResource::SaveToRegistry(HKEY key,LPCTSTR psz) { bool rc=false; ENTERCRITICAL; // Delete all the keys under "psz" HKEY hKey; if(ERROR_SUCCESS==RegOpenKeyEx ((HKEY)key, psz, 0L, KEY_ENUMERATE_SUB_KEYS, &hKey)){ TCHAR szName[256]; DWORD dwSizeName=sizeof szName; FILETIME ftLastWriteTime; DWORD dwIndex; if(ERROR_SUCCESS==RegQueryInfoKey(hKey,0,0,0,&dwIndex,0,0,0,0,0,0,0)){ while((signed)--dwIndex>=0){ if(ERROR_SUCCESS!=RegEnumKeyEx(hKey, dwIndex, szName, &dwSizeName, NULL, NULL, NULL, &ftLastWriteTime) || ERROR_SUCCESS!=RegDeleteKey(hKey,szName)){ rc=false; } dwSizeName=sizeof szName; } } RegCloseKey(hKey); } rc=true; for(CTestResource *pResource=pFirstInstance;pResource;pResource=pResource->m_pNextInstance){ CTestResourceProperties prop1(pResource); rc&=prop1.SaveToRegistry(key,pResource->FileName()); } LEAVECRITICAL; return rc; } #endif CTestResource::CTestResourceProperties::CTestResourceProperties(CTestResource *pResource) { Add(_T("Baud"), pResource->m_nBaud); Add(_T("BoardId"), pResource->m_strBoardID); Add(_T("Date"), pResource->m_strDate); Add(_T("Email"), pResource->m_strEmail); Add(_T("Host"), pResource->m_strHost); Add(_T("Port"), pResource->m_nPort); Add(_T("Locked"), pResource->m_bLocked); Add(_T("Originator"), pResource->m_strUser); Add(_T("Reason"), pResource->m_strReason); Add(_T("Reset"), pResource->m_strReset); Add(_T("Serial"), pResource->m_strPort); Add(_T("Target"), pResource->m_Target); Add(_T("User"), pResource->m_strUser); } bool CTestResource::Lock() { if(!m_bLocked){ m_bLocked=true; return true; } else { return false; } } bool CTestResource::Unlock() { if(m_bLocked){ m_bLocked=false; return true; } else { return false; } } bool CTestResource::LoadSocket(LPCTSTR pszResourceHostPort,Duration dTimeout/*=10*1000*/) { bool rc=false; ENTERCRITICAL; CTestResource *pResource; // If the resource is in use, we don't dare delete it! for(pResource=CTestResource::First();pResource;pResource=pResource->Next()){ pResource->m_bFlag=false; } CeCosSocket sock; if(sock.Connect(pszResourceHostPort,dTimeout)){ // Write the message to the socket int nRequest=0; // read if(!sock.sendInteger(nRequest)){ ERROR(_T("Failed to write to socket\n")); } else { int nResources; if(sock.recvInteger(nResources,_T(""),dTimeout)){ rc=true; while(nResources--){ String strImage; if(sock.recvString(strImage,_T(""),dTimeout)){ VTRACE(_T("Recv \"%s\"\n"),(LPCTSTR)strImage); CTestResource tmp; tmp.FromStr(strImage); CTestResource *pResource=Lookup(tmp.HostPort()); if(0==pResource){ pResource=new CTestResource(_T(""),_T("")); } pResource->FromStr(strImage); pResource->m_bFlag=true; } else { rc=false; break; } } } } } // If the resource is in use, we don't dare delete it! CTestResource *pNext; for(pResource=CTestResource::First();pResource;pResource=pNext){ pNext=pResource->Next(); if(!pResource->m_bFlag && !pResource->m_bInUse){ delete pResource; } } LEAVECRITICAL; return rc; } bool CTestResource::SaveSocket(LPCTSTR pszResourceHostPort,Duration dTimeout) { bool rc=true; ENTERCRITICAL; CeCosSocket sock(pszResourceHostPort, dTimeout); if(sock.Ok()){ // Write the message to the socket int nRequest=1; //write if(!sock.sendInteger(nRequest, _T(""),dTimeout)){ ERROR(_T("Failed to write to socket\n")); rc=false; } else { int nResources=0; CTestResource *pResource; for(pResource=CTestResource::First();pResource;pResource=pResource->Next()){ nResources++; } if(sock.sendInteger(nResources,_T("resource count"),dTimeout)){ for(pResource=CTestResource::First();pResource;pResource=pResource->Next()){ String strImage; CTestResourceProperties prop(pResource); strImage=prop.MakeCommandString(); TRACE(_T("Send \"%s\"\n"),(LPCTSTR)strImage); if(!sock.sendString (strImage, _T("reply"),dTimeout)){ rc=false; break; } } } else { rc=false; } } } else { rc=false; } LEAVECRITICAL; return rc; } /* void CTestResource::Image(String &str) { CTestResourceProperties prop(this); str=prop.MakeCommandString(); VTRACE(_T("Make command string %s\n"),(LPCTSTR)str); } */ bool CTestResource::FromStr(LPCTSTR pszImage) { CTestResourceProperties prop(this); prop.LoadFromCommandString(pszImage); VTRACE(_T("From command string %s\n"),pszImage); return true; } void CTestResource::Chain() { ENTERCRITICAL; nCount++; m_pNextInstance=pFirstInstance; if(m_pNextInstance){ m_pNextInstance->m_pPrevInstance=this; } m_pPrevInstance=0; pFirstInstance=this; LEAVECRITICAL; } bool CTestResource::Matches (const CeCosTest::ExecutionParameters &e,bool bIgnoreLocking) const { return (bIgnoreLocking||(!m_bLocked)) && (0==_tcsicmp(e.PlatformName(),m_Target)); }; CeCosTest::ServerStatus CTestResource::Query() { CeCosTest::ExecutionParameters e(CeCosTest::ExecutionParameters::QUERY,m_Target); CeCosSocket *pSock=0; CeCosTest::ServerStatus s=CeCosTest::Connect(HostPort(),pSock,e,m_strInfo); delete pSock; return s; } int CTestResource::Count(const CeCosTest::ExecutionParameters &e) { int nCount=0; for(const CTestResource *p=pFirstInstance;p;p=p->m_pNextInstance){ if(p->Matches(e)){ nCount++; } } return nCount; } bool CTestResource::Use() { bool rc; ENTERCRITICAL; if(m_bInUse){ rc=false; } else { m_bInUse=true; rc=true; } LEAVECRITICAL; return rc; } CTestResource *CTestResource::GetResource (const CeCosTest::ExecutionParameters &e) { CTestResource *p=0; if(0==Count(e)){ ERROR(_T("GetResource: no candidates available\n")); } else { ENTERCRITICAL; for(p=pFirstInstance;p;p=p->m_pNextInstance){ if(p->Matches(e) && !p->m_bInUse){ TRACE(_T("Acquired %s\n"),p->Serial()); p->Use(); break; } } LEAVECRITICAL; } return p; } const String CTestResource::Image() const { String str; str.Format(_T("%10s %20s %8s"),(LPCTSTR)HostPort(),(LPCTSTR)Target(),(LPCTSTR)Serial()); if(IsLocked()){ str+=_T(" [RL]"); } return str; } bool CTestResource::Matches(LPCTSTR pszHostPort, const CeCosTest::ExecutionParameters &e) { bool rc=false; ENTERCRITICAL; if(Load()){ CTestResource *pResource=Lookup(pszHostPort); if(pResource){ rc=pResource->Matches(e); } } LEAVECRITICAL; return rc; } CResetAttributes::ResetResult CTestResource::Reset(LogFunc *pfnLog, void *pfnLogparam) { String strReset; strReset.Format(_T("port(%s,%d) %s"),Serial(),Baud(),ResetString()); return CResetAttributes(strReset).Reset(pfnLog,pfnLogparam); } CResetAttributes::ResetResult CTestResource::Reset(String &str) { return Reset(StringLogFunc,&str); } void CALLBACK CTestResource::StringLogFunc (void *pParam,LPCTSTR psz) { *((String *)pParam)+=psz; } CResetAttributes::ResetResult CTestResource::RemoteReset(LogFunc *pfnLog, void *pfnLogparam) { String strHost; int nPort; CeCosSocket::ParseHostPort(HostPort(),strHost,nPort); String strCmd; strCmd.Format(_T("rsh %s x10reset %s\n"),(LPCTSTR)strHost,ResetString()); pfnLog(pfnLogparam,strCmd); CSubprocess sp; sp.Run(pfnLog,pfnLogparam,strCmd); return CResetAttributes::RESET_OK; // FIXME } String CTestResource::FileName() const { String strHost; int nPort; CeCosSocket::ParseHostPort(HostPort(),strHost,nPort); return String::SFormat(_T("%s-%d"),(LPCTSTR)strHost,nPort); }