1 //####COPYRIGHTBEGIN####
3 // ----------------------------------------------------------------------------
4 // Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
6 // This program is part of the eCos host tools.
8 // This program is free software; you can redistribute it and/or modify it
9 // under the terms of the GNU General Public License as published by the Free
10 // Software Foundation; either version 2 of the License, or (at your option)
13 // This program is distributed in the hope that it will be useful, but WITHOUT
14 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 // You should have received a copy of the GNU General Public License along with
19 // this program; if not, write to the Free Software Foundation, Inc.,
20 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 // ----------------------------------------------------------------------------
24 //####COPYRIGHTEND####
25 //=================================================================
29 // Resource test class
31 //=================================================================
32 //=================================================================
33 //#####DESCRIPTIONBEGIN####
38 // Description: This class abstracts a test resource for use in the testing infrastructure
41 //####DESCRIPTIONEND####
43 #include "eCosTestUtils.h"
44 #include "eCosTrace.h"
45 #include "Subprocess.h"
47 #include "TestResource.h"
49 CTestResource *CTestResource::pFirstInstance=0;
50 unsigned int CTestResource::nCount=0;
52 String CTestResource::strResourceHostPort;
54 CTestResource::CTestResource(LPCTSTR pszHostPort, LPCTSTR target, LPCTSTR pszDownloadPort, int nBaud, LPCTSTR pszResetString):
55 m_strReset(pszResetString),
58 m_strPort(pszDownloadPort),
62 CeCosSocket::ParseHostPort(pszHostPort,m_strHost,m_nPort);
63 VTRACE(_T("@@@ Created resource %08x %s\n"),(unsigned int)this,(LPCTSTR)Image());
67 CTestResource::~CTestResource()
70 VTRACE(_T("@@@ Destroy resource %08x %s\n"),this,(LPCTSTR)Image());
71 if(m_pPrevInstance || m_pNextInstance){
74 if(pFirstInstance==this){
75 pFirstInstance=m_pNextInstance;
78 m_pPrevInstance->m_pNextInstance=m_pNextInstance;
81 m_pNextInstance->m_pPrevInstance=m_pPrevInstance;
86 // Find the resource matching the given host:port specification
87 // Returns 0 if no such host:port found
88 CTestResource * CTestResource::Lookup(LPCTSTR pszHostPort)
90 CTestResource *pResource=NULL;
94 if(CeCosSocket::ParseHostPort(pszHostPort,strHost,nPort)){
95 for(pResource=pFirstInstance;pResource;pResource=pResource->m_pNextInstance){
96 if(nPort==pResource->TcpIPPort() && CeCosSocket::SameHost(strHost,pResource->Host())){
105 unsigned int CTestResource::GetMatchCount (const CeCosTest::ExecutionParameters &e,bool bIgnoreLocking)
109 for(const CTestResource *pResource=pFirstInstance;pResource;pResource=pResource->m_pNextInstance){
110 if(pResource->Matches(e,bIgnoreLocking)){
118 bool CTestResource::GetMatches (const CeCosTest::ExecutionParameters &e, StringArray &arstr, bool bIgnoreLocking)
124 for(CTestResource *pResource=pFirstInstance;pResource;pResource=pResource->m_pNextInstance){
125 if(pResource->Matches(e,bIgnoreLocking)){
126 arstr.push_back(pResource->HostPort());
135 void CTestResource::DeleteAllInstances()
138 while(pFirstInstance){
139 delete pFirstInstance;
144 bool CTestResource::LoadFromDirectory (LPCTSTR psz)
148 DeleteAllInstances();
149 // Find all the files in directory "psz" and load from each of them
150 TCHAR szOrigDir[256];
151 _tgetcwd(szOrigDir,sizeof szOrigDir-1);
155 for(bool b=CeCosTestUtils::StartSearch(pHandle,strFile);b;b=CeCosTestUtils::NextFile(pHandle,strFile)){
156 if(CeCosTestUtils::IsFile(strFile)){
157 CTestResource *pResource=new CTestResource(_T(""),_T(""));
158 CTestResourceProperties prop(pResource);
159 prop.LoadFromFile(strFile);
162 CeCosTestUtils::EndSearch(pHandle);
164 TRACE(_T("Failed to change to %s from %s\n"),psz,szOrigDir);
172 bool CTestResource::SaveToDirectory (LPCTSTR pszDir)
177 // Delete all the files under directory "pszDir"
179 TCHAR szOrigDir[256];
180 _tgetcwd(szOrigDir,sizeof szOrigDir-1);
181 if(0==_tchdir(pszDir)){
183 for(bool b=CeCosTestUtils::StartSearch(pHandle,strFile);b;b=CeCosTestUtils::NextFile(pHandle,strFile)){
184 if(CeCosTestUtils::IsFile(strFile)){
188 CeCosTestUtils::EndSearch(pHandle);
190 for(CTestResource *pResource=pFirstInstance;pResource;pResource=pResource->m_pNextInstance){
191 CTestResourceProperties prop(pResource);
192 rc&=prop.SaveToFile(pResource->FileName());
195 fprintf(stderr,"Failed to change to %s from %s\n",pszDir,szOrigDir);
206 bool CTestResource::LoadFromRegistry(HKEY key,LPCTSTR psz)
208 // Find all the keys under "psz" and load from each of them
212 if(ERROR_SUCCESS==RegOpenKeyEx ((HKEY)key, psz, 0L, KEY_ENUMERATE_SUB_KEYS, &hKey)){
214 DWORD dwSizeName=sizeof szName;
215 FILETIME ftLastWriteTime;
216 for(DWORD dwIndex=0;ERROR_SUCCESS==RegEnumKeyEx(hKey, dwIndex, szName, &dwSizeName, NULL, NULL, NULL, &ftLastWriteTime); dwIndex++){
217 CTestResource *pResource=new CTestResource(_T(""),_T(""));
219 strKey.Format(_T("%s\\%s"),psz,szName);
220 CTestResourceProperties prop1(pResource);
221 prop1.LoadFromRegistry(key,strKey);
222 dwSizeName=sizeof szName;
230 bool CTestResource::SaveToRegistry(HKEY key,LPCTSTR psz)
234 // Delete all the keys under "psz"
236 if(ERROR_SUCCESS==RegOpenKeyEx ((HKEY)key, psz, 0L, KEY_ENUMERATE_SUB_KEYS, &hKey)){
238 DWORD dwSizeName=sizeof szName;
239 FILETIME ftLastWriteTime;
241 if(ERROR_SUCCESS==RegQueryInfoKey(hKey,0,0,0,&dwIndex,0,0,0,0,0,0,0)){
242 while((signed)--dwIndex>=0){
243 if(ERROR_SUCCESS!=RegEnumKeyEx(hKey, dwIndex, szName, &dwSizeName, NULL, NULL, NULL, &ftLastWriteTime) ||
244 ERROR_SUCCESS!=RegDeleteKey(hKey,szName)){
247 dwSizeName=sizeof szName;
253 for(CTestResource *pResource=pFirstInstance;pResource;pResource=pResource->m_pNextInstance){
254 CTestResourceProperties prop1(pResource);
255 rc&=prop1.SaveToRegistry(key,pResource->FileName());
264 CTestResource::CTestResourceProperties::CTestResourceProperties(CTestResource *pResource)
266 Add(_T("Baud"), pResource->m_nBaud);
267 Add(_T("BoardId"), pResource->m_strBoardID);
268 Add(_T("Date"), pResource->m_strDate);
269 Add(_T("Email"), pResource->m_strEmail);
270 Add(_T("Host"), pResource->m_strHost);
271 Add(_T("Port"), pResource->m_nPort);
272 Add(_T("Locked"), pResource->m_bLocked);
273 Add(_T("Originator"), pResource->m_strUser);
274 Add(_T("Reason"), pResource->m_strReason);
275 Add(_T("Reset"), pResource->m_strReset);
276 Add(_T("Serial"), pResource->m_strPort);
277 Add(_T("Target"), pResource->m_Target);
278 Add(_T("User"), pResource->m_strUser);
281 bool CTestResource::Lock()
291 bool CTestResource::Unlock()
301 bool CTestResource::LoadSocket(LPCTSTR pszResourceHostPort,Duration dTimeout/*=10*1000*/)
305 CTestResource *pResource;
306 // If the resource is in use, we don't dare delete it!
307 for(pResource=CTestResource::First();pResource;pResource=pResource->Next()){
308 pResource->m_bFlag=false;
311 if(sock.Connect(pszResourceHostPort,dTimeout)){
312 // Write the message to the socket
313 int nRequest=0; // read
314 if(!sock.sendInteger(nRequest)){
315 ERROR(_T("Failed to write to socket\n"));
318 if(sock.recvInteger(nResources,_T(""),dTimeout)){
322 if(sock.recvString(strImage,_T(""),dTimeout)){
323 VTRACE(_T("Recv \"%s\"\n"),(LPCTSTR)strImage);
325 tmp.FromStr(strImage);
326 CTestResource *pResource=Lookup(tmp.HostPort());
328 pResource=new CTestResource(_T(""),_T(""));
330 pResource->FromStr(strImage);
331 pResource->m_bFlag=true;
340 // If the resource is in use, we don't dare delete it!
341 CTestResource *pNext;
342 for(pResource=CTestResource::First();pResource;pResource=pNext){
343 pNext=pResource->Next();
344 if(!pResource->m_bFlag && !pResource->m_bInUse){
353 bool CTestResource::SaveSocket(LPCTSTR pszResourceHostPort,Duration dTimeout)
357 CeCosSocket sock(pszResourceHostPort, dTimeout);
359 // Write the message to the socket
360 int nRequest=1; //write
361 if(!sock.sendInteger(nRequest, _T(""),dTimeout)){
362 ERROR(_T("Failed to write to socket\n"));
366 CTestResource *pResource;
367 for(pResource=CTestResource::First();pResource;pResource=pResource->Next()){
370 if(sock.sendInteger(nResources,_T("resource count"),dTimeout)){
371 for(pResource=CTestResource::First();pResource;pResource=pResource->Next()){
373 CTestResourceProperties prop(pResource);
374 strImage=prop.MakeCommandString();
375 TRACE(_T("Send \"%s\"\n"),(LPCTSTR)strImage);
376 if(!sock.sendString (strImage, _T("reply"),dTimeout)){
393 void CTestResource::Image(String &str)
395 CTestResourceProperties prop(this);
396 str=prop.MakeCommandString();
397 VTRACE(_T("Make command string %s\n"),(LPCTSTR)str);
401 bool CTestResource::FromStr(LPCTSTR pszImage)
403 CTestResourceProperties prop(this);
404 prop.LoadFromCommandString(pszImage);
405 VTRACE(_T("From command string %s\n"),pszImage);
409 void CTestResource::Chain()
413 m_pNextInstance=pFirstInstance;
415 m_pNextInstance->m_pPrevInstance=this;
422 bool CTestResource::Matches (const CeCosTest::ExecutionParameters &e,bool bIgnoreLocking) const
424 return (bIgnoreLocking||(!m_bLocked)) && (0==_tcsicmp(e.PlatformName(),m_Target));
427 CeCosTest::ServerStatus CTestResource::Query()
429 CeCosTest::ExecutionParameters e(CeCosTest::ExecutionParameters::QUERY,m_Target);
430 CeCosSocket *pSock=0;
431 CeCosTest::ServerStatus s=CeCosTest::Connect(HostPort(),pSock,e,m_strInfo);
436 int CTestResource::Count(const CeCosTest::ExecutionParameters &e)
439 for(const CTestResource *p=pFirstInstance;p;p=p->m_pNextInstance){
447 bool CTestResource::Use()
461 CTestResource *CTestResource::GetResource (const CeCosTest::ExecutionParameters &e)
465 ERROR(_T("GetResource: no candidates available\n"));
468 for(p=pFirstInstance;p;p=p->m_pNextInstance){
469 if(p->Matches(e) && !p->m_bInUse){
470 TRACE(_T("Acquired %s\n"),p->Serial());
480 const String CTestResource::Image() const
483 str.Format(_T("%10s %20s %8s"),(LPCTSTR)HostPort(),(LPCTSTR)Target(),(LPCTSTR)Serial());
490 bool CTestResource::Matches(LPCTSTR pszHostPort, const CeCosTest::ExecutionParameters &e)
495 CTestResource *pResource=Lookup(pszHostPort);
497 rc=pResource->Matches(e);
504 CResetAttributes::ResetResult CTestResource::Reset(LogFunc *pfnLog, void *pfnLogparam)
507 strReset.Format(_T("port(%s,%d) %s"),Serial(),Baud(),ResetString());
508 return CResetAttributes(strReset).Reset(pfnLog,pfnLogparam);
511 CResetAttributes::ResetResult CTestResource::Reset(String &str)
513 return Reset(StringLogFunc,&str);
516 void CALLBACK CTestResource::StringLogFunc (void *pParam,LPCTSTR psz)
518 *((String *)pParam)+=psz;
522 CResetAttributes::ResetResult CTestResource::RemoteReset(LogFunc *pfnLog, void *pfnLogparam)
526 CeCosSocket::ParseHostPort(HostPort(),strHost,nPort);
528 strCmd.Format(_T("rsh %s x10reset %s\n"),(LPCTSTR)strHost,ResetString());
529 pfnLog(pfnLogparam,strCmd);
532 sp.Run(pfnLog,pfnLogparam,strCmd);
533 return CResetAttributes::RESET_OK; // FIXME
536 String CTestResource::FileName() const
540 CeCosSocket::ParseHostPort(HostPort(),strHost,nPort);
541 return String::SFormat(_T("%s-%d"),(LPCTSTR)strHost,nPort);