VirtualBox

root/trunk/src/testcase/tstRunTestcases.cpp

Revision 14831, 10.1 kB (checked in by vboxsync, 1 month ago)

whole bunch: avoid runtime.h, include individual headers indead.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1 /* $Id$ */
2 /** @file
3  * tstRunTescases - Driver program for running VBox testcase (tst* testcase/tst*).
4  */
5
6 /*
7  * Copyright (C) 2006-2007 Sun Microsystems, Inc.
8  *
9  * This file is part of VirtualBox Open Source Edition (OSE), as
10  * available from http://www.virtualbox.org. This file is free software;
11  * you can redistribute it and/or modify it under the terms of the GNU
12  * General Public License (GPL) as published by the Free Software
13  * Foundation, in version 2 as it comes in the "COPYING" file of the
14  * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15  * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16  *
17  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18  * Clara, CA 95054 USA or visit http://www.sun.com if you need
19  * additional information or have any questions.
20  */
21
22
23 /*******************************************************************************
24 *   Header Files                                                               *
25 *******************************************************************************/
26 #include <iprt/initterm.h>
27 #include <iprt/dir.h>
28 #include <iprt/param.h>
29 #include <iprt/path.h>
30 #include <iprt/process.h>
31 #include <iprt/string.h>
32 #include <iprt/stream.h>
33 #include <iprt/thread.h>
34 #include <iprt/err.h>
35 #include <iprt/env.h>
36
37
38 /*******************************************************************************
39 *   Global Variables                                                           *
40 *******************************************************************************/
41 /** The number of passed testcases. */
42 static unsigned     g_cPasses = 0;
43 /** The number of failed testcases. */
44 static unsigned     g_cFailures = 0;
45 /** The number of skipped testcases. */
46 static unsigned     g_cSkipped = 0;
47 /** The exclude list. */
48 static const char  *g_apszExclude[] =
49 {
50 #if 1 // slow stuff
51     "testcase/tstFile",
52     "testcase/tstAvl",
53     "testcase/tstSemMutex",
54     "testcase/tstVD",
55 #endif
56     "testcase/tstFileLock",
57     "testcase/tstCritSect",
58     "testcase/tstCritSectW32",
59     "testcase/tstDeadlock",
60     "testcase/tstDisasm-2",
61     "testcase/tstFileAppendWin-1",
62     "testcase/tstDir",              /* useless, requires parameters */
63     "testcase/tstDir-2",            /* useless, requires parameters */
64     "testcase/tstGlobalConfig",
65     "testcase/tstLdr-2",
66     "testcase/tstLdr-3",
67     "testcase/tstLdr",
68     "testcase/tstLdrLoad",
69     "testcase/tstLdrObj",
70     "testcase/tstLdrObjR0",
71     "testcase/tstMove",
72     "testcase/tstRunTestcases",
73     "testcase/tstSDL",
74     "testcase/tstTime-3",
75     "testcase/tstSeamlessX11",
76     "testcase/tstVBoxControl",
77     "./tstRunTestcases",
78     "./tstAnimate",
79     "./tstAPI",
80     "./tstHeadless",
81     "./tstHeadless2",
82     "./tstMicro",
83     "./tstMicroGC",
84     "./tstVBoxDbg",
85     "./tstVMM-2",
86     "./tstTestServMgr",
87     "./tstXptDump",
88     "./tstnsIFileEnumerator",
89     "./tstSimpleTypeLib",
90     "./tstTestAtoms",
91     "./tstXptLink",
92     "./tstTestCallTemplates",
93 #if 1 // later
94     "testcase/tstIntNetR0",
95     "./tstVMM",
96     "./tstVMReq",
97     "./tstVMREQ",
98 #endif
99     /* final entry*/
100     ""
101 };
102
103
104 /**
105  * Checks if a testcase is include or should be skipped.
106  *
107  * @param pszTestcase   The testcase (filename).
108  *
109  * @return  true if the testcase is included.
110  *          false if the testcase should be skipped.
111  */
112 static bool IsTestcaseIncluded(const char *pszTestcase)
113 {
114     char *pszDup = RTStrDup(pszTestcase);
115     if (pszDup)
116     {
117         RTPathStripExt(pszDup);
118         for (unsigned i = 0; i < RT_ELEMENTS(g_apszExclude); i++)
119         {
120             if (!strcmp(g_apszExclude[i], pszDup))
121             {
122                 RTStrFree(pszDup);
123                 return false;
124             }
125         }
126         RTStrFree(pszDup);
127         return true;
128     }
129
130     RTPrintf("tstRunTestcases: Out of memory!\n");
131     return false;
132 }
133
134
135 /**
136  * Process the testcases found in the filter.
137  *
138  * @param   pszFilter   The filter (winnt) to pass to RTDirOpenFiltered for
139  *                      selecting the testcases.
140  * @param   pszDir      The directory we're processing.
141  */
142 static void Process(const char *pszFilter, const char *pszDir)
143 {
144     /*
145      * Open and enumerate the directory.
146      */
147     PRTDIR pDir;
148     int rc = RTDirOpenFiltered(&pDir, pszFilter, RTDIRFILTER_WINNT);
149     if (RT_SUCCESS(rc))
150     {
151         for (;;)
152         {
153             RTDIRENTRY DirEntry;
154             rc = RTDirRead(pDir, &DirEntry, NULL);
155             if (RT_FAILURE(rc))
156             {
157                 if (rc == VERR_NO_MORE_FILES)
158                     rc = VINF_SUCCESS;
159                 else
160                     RTPrintf("tstRunTestcases: reading '%s' -> %Rrc\n", pszFilter, rc);
161                 break;
162             }
163
164             /*
165              * Construct the testcase name.
166              */
167             char *pszTestcase;
168             RTStrAPrintf(&pszTestcase, "%s/%s", pszDir, DirEntry.szName);
169             if (!pszTestcase)
170             {
171                 RTPrintf("tstRunTestcases: out of memory!\n");
172                 rc = VERR_NO_MEMORY;
173                 break;
174             }
175             if (IsTestcaseIncluded(pszTestcase))
176             {
177                 /*
178                  * Execute the testcase.
179                  */
180                 RTPrintf("*** %s: Executing...\n", pszTestcase);  RTStrmFlush(g_pStdOut);
181                 const char *papszArgs[2];
182                 papszArgs[0] = pszTestcase;
183                 papszArgs[1] = NULL;
184                 RTPROCESS Process;
185                 rc = RTProcCreate(pszTestcase, papszArgs, RTENV_DEFAULT, 0, &Process);
186                 if (RT_SUCCESS(rc))
187                 {
188                     /*
189                      * Wait for the process and collect it's return code.
190                      * If it takes too long, we'll terminate it and continue.
191                      */
192                     RTTIMESPEC Start;
193                     RTTimeNow(&Start);
194                     RTPROCSTATUS ProcStatus;
195                     for (;;)
196                     {
197                         rc = RTProcWait(Process, RTPROCWAIT_FLAGS_NOBLOCK, &ProcStatus);
198                         if (rc != VERR_PROCESS_RUNNING)
199                             break;
200                         RTTIMESPEC Now;
201                         if (RTTimeSpecGetMilli(RTTimeSpecSub(RTTimeNow(&Now), &Start)) > 60*1000 /* 1 min */)
202                         {
203                             RTPrintf("*** %s: FAILED - timed out. killing it.\n", pszTestcase);
204                             RTProcTerminate(Process);
205                             RTThreadSleep(100);
206                             RTProcWait(Process, RTPROCWAIT_FLAGS_NOBLOCK, &ProcStatus);
207                             g_cFailures++;
208                             break;
209                         }
210                         RTThreadSleep(100);
211                     }
212
213                     /*
214                      * Examin the exit status.
215                      */
216                     if (RT_SUCCESS(rc))
217                     {
218                         if (    ProcStatus.enmReason == RTPROCEXITREASON_NORMAL
219                             &&  ProcStatus.iStatus == 0)
220                         {
221                             RTPrintf("*** %s: PASSED\n", pszTestcase);
222                             g_cPasses++;
223                         }
224                         else
225                         {
226                             RTPrintf("*** %s: FAILED\n", pszTestcase);
227                             g_cFailures++;
228                         }
229                     }
230                     else if (rc != VERR_PROCESS_RUNNING)
231                     {
232                         RTPrintf("tstRunTestcases: %s: RTProcWait failed -> %Rrc\n", pszTestcase, rc);
233                         g_cFailures++;
234                     }
235                 }
236                 else
237                 {
238                     RTPrintf("tstRunTestcases: %s: failed to start -> %Rrc\n", pszTestcase, rc);
239                     g_cFailures++;
240                 }
241
242             }
243             else
244             {
245                 RTPrintf("tstRunTestcases: %s: SKIPPED\n", pszTestcase);
246                 g_cSkipped++;
247             }
248             RTStrFree(pszTestcase);
249         } /* enumeration loop */
250
251         RTDirClose(pDir);
252     }
253     else
254         RTPrintf("tstRunTestcases: opening '%s' -> %Rrc\n", pszDir, rc);
255 }
256
257
258
259 int main(int argc, char **argv)
260 {
261     RTR3Init();
262
263     if (argc == 1)
264     {
265         char szPath[RTPATH_MAX];
266         int rc = RTPathProgram(szPath, sizeof(szPath) - sizeof("/.."));
267         if (RT_FAILURE(rc))
268         {
269             RTPrintf("fatal error: RTPathProgram -> %Rrc\n", rc);
270             return 1;
271         }
272         rc = RTPathSetCurrent(strcat(szPath, "/.."));
273         if (RT_FAILURE(rc))
274         {
275             RTPrintf("fatal error: RTPathSetCurrent -> %Rrc\n", rc);
276             return 1;
277         }
278
279         Process("testcase/tst*", "testcase");
280         Process("tst*", ".");
281     }
282     else
283     {
284         char szDir[RTPATH_MAX];
285         for (int i = 1; i < argc; i++)
286         {
287             if (argv[i][0] == '-')
288             {
289                 switch (argv[i][1])
290                 {
291                     /* case '':... */
292
293                     default:
294                         RTPrintf("syntax error: Option '%s' is not recognized\n", argv[i]);
295                         return 1;
296                 }
297             }
298             else
299             {
300                 size_t cch = strlen(argv[i]);
301                 if (cch >= sizeof(szDir))
302                 {
303                     RTPrintf("syntax error: '%s' is too long!\n", argv[i]);
304                     return 1;
305                 }
306                 memcpy(szDir, argv[i], cch + 1);
307                 char *pszFilename = RTPathFilename(szDir);
308                 if (!pszFilename)
309                 {
310                     RTPrintf("syntax error: '%s' does not include a file name or file name mask!\n", argv[i]);
311                     return 1;
312                 }
313                 RTPathStripFilename(szDir);
314                 Process(argv[i], szDir);
315             }
316         }
317     }
318
319     RTPrintf("\n"
320              "********************\n"
321              "***  PASSED: %u\n"
322              "***  FAILED: %u\n"
323              "*** SKIPPED: %u\n"
324              "***   TOTAL: %u\n",
325              g_cPasses,
326              g_cFailures,
327              g_cSkipped,
328              g_cPasses + g_cFailures + g_cSkipped);
329     return !!g_cFailures;
330 }
331
Note: See TracBrowser for help on using the browser.

© 2008 Sun Microsystems, Inc.
ContactPrivacy policy