]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - tools/src/tools/ecostest/common/eCosTest.h
Initial revision
[karo-tx-redboot.git] / tools / src / tools / ecostest / common / eCosTest.h
1 //####COPYRIGHTBEGIN####
2 //                                                                          
3 // ----------------------------------------------------------------------------
4 // Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
5 //
6 // This program is part of the eCos host tools.
7 //
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) 
11 // any later version.
12 // 
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 
16 // more details.
17 // 
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.
21 //
22 // ----------------------------------------------------------------------------
23 //                                                                          
24 //####COPYRIGHTEND####
25 //=================================================================
26 //
27 //        eCosTest.h
28 //
29 //        run test header
30 //
31 //=================================================================
32 //=================================================================
33 //#####DESCRIPTIONBEGIN####
34 //
35 // Author(s):     sdf
36 // Contributors:  sdf
37 // Date:          1999-04-01
38 // Description:   Run one or more tests
39 // Usage:
40 //
41 //####DESCRIPTIONEND####
42
43 #ifndef _ECOSTEST_H
44 #define _ECOSTEST_H
45
46 //=================================================================
47 // This class represents a single eCos test [executable].
48 // It includes member functions to run the test and to manage related system resources.
49 //=================================================================
50
51 #include "Collections.h"
52 #include "eCosStd.h"
53 #include "eCosTestPlatform.h"
54 #include "eCosTestUtils.h"
55 #include "ResetAttributes.h"
56
57 class CSubprocess;
58 class CTestResource;
59 class CeCosSocket;
60
61 class CeCosTest{
62 public:
63
64   static LPCTSTR pszFormat;
65   
66   ///////////////////////////////////////////////////////////////////////////
67   // Representation of an elapsed time (units of milliseconds)
68   enum {NOTIMEOUT=0x7fffffff}; // No timeout specified
69   
70   ///////////////////////////////////////////////////////////////////////////
71   // ctors, dtors and their friends
72   class ExecutionParameters;
73   CeCosTest(const ExecutionParameters &e, LPCTSTR  const pszExecutable, LPCTSTR  const pszTitle=0);
74   virtual ~CeCosTest();
75   // Count of number of instances of this class:
76   static int InstanceCount;
77   // Delete all heap instances of this class (*must* be allocated on heap)
78   static void DeleteAllInstances ();
79   // Simply wait for instances to die a natural death
80   static bool WaitForAllInstances (int nPoll=1000,Duration nTimeout=NOTIMEOUT);
81   // Tap them on the shoulder (does not wait)
82   static void CancelAllInstances ();
83   ///////////////////////////////////////////////////////////////////////////
84   
85   ///////////////////////////////////////////////////////////////////////////
86   // Class used to represent execution parameters (to be passed with request to execute a test)
87   ///////////////////////////////////////////////////////////////////////////
88   class ExecutionParameters {
89   public:
90     
91     enum RequestType { RUN, QUERY, LOCK, UNLOCK, STOP, RequestTypeMax};
92     static RequestType RequestTypeValue(LPCTSTR );
93     static const String Image(RequestType r) { return (r>=0 && r<=RequestTypeMax)?String(arRequestImage[r]):String::SFormat(_T("Unknown(%d)"),r); }
94     
95     Duration    ActiveTimeout()   const { return m_nActiveTimeout; }
96     Duration    DownloadTimeout() const { return m_nDownloadTimeout; }
97
98     const CeCosTestPlatform *Platform() const { return CeCosTestPlatform::Get(m_Target); }
99     LPCTSTR PlatformName() const { return Platform()?Platform()->Name():_T("UNKNOWN"); }
100
101     RequestType Request() const { return m_Request;}
102     void SetActiveTimeout   (Duration t){m_nActiveTimeout=t;}
103     void SetDownloadTimeout (Duration t){m_nDownloadTimeout=t;}
104
105     ExecutionParameters (
106       RequestType r=CeCosTest::ExecutionParameters::RUN,
107       LPCTSTR  Target=_T(""),
108       Duration    nActiveTimeout=NOTIMEOUT,
109       Duration    nDownloadTimeout=NOTIMEOUT);
110     bool FromStr(LPCTSTR psz);
111     
112     String Image() const;
113     virtual ~ExecutionParameters(){}
114     bool m_bUseFilter;
115   protected:
116     static LPCTSTR  arRequestImage [1+RequestTypeMax];
117     String m_Target;
118     Duration m_nActiveTimeout,m_nDownloadTimeout;
119     RequestType m_Request;
120     int  m_nUnused1;
121     int  m_nUnused2;
122     int  m_nUnused3;
123     bool m_bUnused2;
124     bool m_bUnused3;
125   };
126   ///////////////////////////////////////////////////////////////////////////
127   
128   ///////////////////////////////////////////////////////////////////////////
129   // Result status stuff.
130   // Order is important - SetStatus can only change status in left-to-right direction
131   void AnalyzeOutput();
132   enum StatusType {NotStarted, NoResult, Inapplicable, Pass, DownloadTimeOut, TimeOut, Cancelled, Fail, 
133     AssertFail, StatusTypeMax};
134   static StatusType StatusTypeValue (LPCTSTR  const pszStr);
135   static const String Image(StatusType s) { return (s>=0 && s<StatusTypeMax)?String(arResultImage[s]):String::SFormat(_T("Unknown(%d)"),s); }
136   ///////////////////////////////////////////////////////////////////////////
137   
138   ///////////////////////////////////////////////////////////////////////////
139   // Attributes
140   LPCTSTR  const      Executable()             const { return m_strExecutable;}            // Executable name
141   
142   StatusType          Status()                 const { return m_Status; }                  // Test status
143   
144   Duration            Download()               const { return m_nDownloadTime; }           // Download time
145   Duration            Total()                  const { return m_nTotalTime; }              // Total
146   Duration            MaxInactive()            const { return m_nMaxInactiveTime; }        // Max. inactive
147   
148   LPCTSTR  const  Output()                     const { return m_strOutput; }               // Output generated by a test run [for report purposes]
149   //const CTestResource * const Port()           const { return m_pResource; }               // Resource used for a test run [for report purposes]
150   
151   const String ResultString (bool bIncludeOutput=true)             const;
152   ///////////////////////////////////////////////////////////////////////////
153   
154   ///////////////////////////////////////////////////////////////////////////
155   // Running a test:
156   
157   // Run a test locally:
158   bool RunLocal ();
159   
160   // Run a test remotely: 
161   // If pszRemoteHostPort is given, it sends the test for execution on the given host:post.
162   // Otherwise, a suitable host:port is determined from the test resource information.
163   bool RunRemote (LPCTSTR  const pszRemoteHostPort);
164   ///////////////////////////////////////////////////////////////////////////
165   
166   ///////////////////////////////////////////////////////////////////////////
167   // Resource functions
168   
169   // Run as a server on given TCP/IP port
170   static bool RunAgent(int nTcpPort); 
171   
172   bool InteractiveInferior(LPCTSTR pszHostPort,TCHAR **argv);
173   void SetTimeouts (Duration dActive=NOTIMEOUT,Duration dDownload=NOTIMEOUT/*,Duration dElapsed=15*60*1000*/);
174   void SetExecutable (LPCTSTR pszExecutable);
175   static bool Value (
176     LPCTSTR pszStr, 
177     struct tm &t,
178     StatusType &status,
179     String &target,
180     String &strExecutionHostPort,
181     String &strExecutableTail,
182     String &strTitle,
183     int &nFileSize,
184     Duration &nTotalTime,
185     Duration &nMaxInactiveTime,
186     Duration &nDownloadTime,
187     Duration &nDownloadTimeout,
188     Duration &nActiveTimeout,
189     int &nDownloadedSize);
190   
191   enum ServerStatus {SERVER_BUSY, SERVER_READY, SERVER_CANT_RUN, CONNECTION_FAILED, SERVER_LOCKED, ServerStatusMax};
192   static LPCTSTR  const Image(ServerStatus s) { return arServerStatusImage[MIN(s,ServerStatusMax)]; }
193   static ServerStatus ServerStatusValue(LPCTSTR psz);
194
195   // Force the result to change.  Generally you can only set the result left-to-right in the order of the enumeration literals
196   void ForceResult(StatusType s) { m_Status=s; }
197
198   // Get size information (generally by running *gdb-size)
199   bool GetSizes();
200
201   // Connect to a test server
202   static ServerStatus CeCosTest::Connect (LPCTSTR pszHostPort, CeCosSocket *&pSock, const ExecutionParameters &e,String &strInfo,Duration dTimeout=10*1000);
203
204   // Log some output.  The accumulated output can be retrieved using Output()
205   void Log (LPCTSTR  const pszFormat,...);
206   void LogString (LPCTSTR psz);
207
208 protected:
209         int m_nOutputLen;
210
211   void Cancel (); // Stop the run
212
213   // Connect to m_strExecutionHostPort
214   void ConnectForExecution ();
215   
216   // Callback used when EXEC output is used to create host-side processes
217   static void CALLBACK AppendFunc(void *pParam,LPCTSTR psz) { ((CeCosTest*)pParam)->Log(_T("%%%% %s"),psz);}
218   
219         void GetInferiorCommands (StringArray &arstrInferiorCmds);
220   CSubprocess *m_pspPipe;
221   PtrArray m_arpExecsp;
222
223   // Extract a directive (such as "EXEC:") from the test output.  The index passed keeps track of the last such
224   // directive extracted such that successive calls march through the output, returning a different one each time.
225         bool GetDirective (LPCTSTR pszDirective, String &str,int &nIndex);
226         
227   // Keep track of directives in the gdb output
228   int m_nLastGdbInst;     // GDB
229   int m_nLastExecInst;    // EXEC
230   int m_nLastTimeoutInst; // TIMEOUT
231   int m_nLastPipeInst;    // PIPE   
232
233   // Commands to be sent to gdb, or other inferior process
234   StringArray m_arstrInferiorCmds;
235   // Last command sent
236         unsigned int m_nCmdIndex;
237
238   // Inferior process output comes through here
239   static void CALLBACK SInferiorOutputFunc(void *pParam,LPCTSTR psz) { ((CeCosTest *)pParam)->InferiorOutputFunc(psz); }
240   void InferiorOutputFunc(LPCTSTR psz);
241
242   // Has a timeout occurred?  Returns false if so.
243   static bool CALLBACK SCheckForTimeout(void *pParam) { return ((CeCosTest *)pParam)->CheckForTimeout(); }
244
245   // Read target ready indicator from server
246   bool GetTargetReady(String &strHostPort);
247   
248   // This may be set to force the socket-to-serial connection to terminate
249   bool m_bStopConnectSocketToSerial;
250   
251   // Convert a path to one understandable by Cygwin
252   static String CygPath (LPCTSTR pszPath);
253
254   // Are we at a prompt?
255   bool AtPrompt();
256   
257   // To limit calls to ps, under UNIX.  This prevents the acquisition of cpu time consuming the whole machine :-).
258   mutable Time m_tInferiorCpuTime;
259   mutable Time m_tPrevSample;
260   Time InferiorTime() const;
261   
262   unsigned int m_nStrippedSize;
263
264   // Path to use to execute subprocesses
265   String m_strPath;
266   
267   // Size of executable
268   unsigned int m_nFileSize;                   
269   
270   // host:port we are connecting to
271   String m_strExecutionHostPort;
272   
273   ///////////////////////////////////////////////////////////////////////////
274   // Stuff to manage running gdb (or some other inferior process)
275   bool CheckForTimeout();                     // Check for a timeout - set status and return false if it happens
276   bool m_bDownloading;                        // Are we currently downloading executable?
277   bool InferiorProcessAlive ();                    // Is gdb still alive and kicking?
278   Time m_tBase;                               // Base used for measurement of timeouts
279   Time m_tBase0;                              // Base used for measurement of timeouts
280   Time m_tWallClock0;                         // When the test was actually started
281
282   ///////////////////////////////////////////////////////////////////////////
283   // Close the socket used by the current class instance
284   void CloseSocket ();
285   
286   bool send(const void * const pData,unsigned int nLength,LPCTSTR  const pszMsg=_T(""),Duration dTimeout=10*1000);
287   bool recv(const void *pData,unsigned int nLength,LPCTSTR  const pszMsg=_T(""),Duration dTimeout=10*1000);
288   
289   bool sendResult(Duration dTimeout=10*1000);
290   bool recvResult(Duration dTimeout=10*1000);
291   
292   ///////////////////////////////////////////////////////////////////////////
293   
294   ///////////////////////////////////////////////////////////////////////////
295   CeCosSocket *m_pSock;
296   
297   ExecutionParameters m_ep;
298   
299   // Chaining to allow *AllInstances functions to work:
300   static CeCosTest * pFirstInstance;
301   CeCosTest * m_pPrevInstance;
302   CeCosTest * m_pNextInstance;
303   
304   void RunInferior (LPCTSTR pszCmdline);
305   
306   bool OutputContains(LPCTSTR psz) const { return 0!=_tcsstr(m_strOutput,psz); }
307   
308   static void CALLBACK SAcceptThreadFunc (void *pParam) {((CeCosTest *)pParam)->AcceptThreadFunc(); }
309   void AcceptThreadFunc();
310
311   static void CALLBACK SConnectSocketToSerialThreadFunc(void *pParam) { ((CeCosTest *)pParam)->ConnectSocketToSerialThreadFunc(); }
312   void ConnectSocketToSerialThreadFunc();
313   
314   String m_strExecutable;
315   String m_strTitle;
316   
317   void SetStatus (StatusType status);
318   StatusType m_Status;
319   
320   Duration  m_nDownloadTime;
321   Duration  m_nTotalTime;
322   Duration  m_nMaxInactiveTime;
323   
324   CTestResource *m_pResource;
325   CSubprocess *m_psp;
326   
327   String m_strOutput; // the output of the test run goes here
328
329   static LPCTSTR  const arResultImage[1+StatusTypeMax];
330   static LPCTSTR  const arServerStatusImage[1+ServerStatusMax];
331   bool m_bConnectSocketToSerialThreadDone;
332   static void CALLBACK ResetLogFunc(void *pParam, LPCTSTR psz);
333
334   // These are used by RunAgent and its friends for setting up the RDI connection
335   int m_nAuxPort;
336   int m_nAuxListenSock;
337
338
339 }; // class CeCosTest
340
341
342
343 #endif