VirtualBox

source: vbox/trunk/src/testcase/tstRunTestcases.cpp@ 39568

Last change on this file since 39568 was 38636, checked in by vboxsync, 13 years ago

*,IPRT: Redid the ring-3 init to always convert the arguments to UTF-8.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 11.1 KB
Line 
1/* $Id: tstRunTestcases.cpp 38636 2011-09-05 13:49:45Z vboxsync $ */
2/** @file
3 * tstRunTestcases - Driver program for running VBox testcase (tst* testcase/tst*).
4 */
5
6/*
7 * Copyright (C) 2006-2007 Oracle Corporation
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
18
19/*******************************************************************************
20* Header Files *
21*******************************************************************************/
22#include <iprt/initterm.h>
23#include <iprt/dir.h>
24#include <iprt/param.h>
25#include <iprt/path.h>
26#include <iprt/process.h>
27#include <iprt/string.h>
28#include <iprt/stream.h>
29#include <iprt/thread.h>
30#include <iprt/err.h>
31#include <iprt/env.h>
32
33
34/*******************************************************************************
35* Global Variables *
36*******************************************************************************/
37/** The number of passed testcases. */
38static unsigned g_cPasses = 0;
39/** The number of failed testcases. */
40static unsigned g_cFailures = 0;
41/** The number of skipped testcases. */
42static unsigned g_cSkipped = 0;
43/** The exclude list.
44 * @note Stripped extensions! */
45static const char *g_apszExclude[] =
46{
47#if 1 // slow stuff
48 "testcase/tstFile",
49 "testcase/tstRTAvl",
50 "testcase/tstSemMutex",
51 "testcase/tstVD",
52#endif
53 "testcase/tstFileLock",
54 "testcase/tstCritSect",
55 "testcase/tstCritSectW32",
56 "testcase/tstDeadlock",
57 "testcase/tstDisasm-2",
58 "testcase/tstFileAppendWin-1",
59 "testcase/tstDir", /* useless, requires parameters */
60 "testcase/tstDir-2", /* useless, requires parameters */
61 "testcase/tstGlobalConfig",
62 "testcase/tstHostHardwareLinux", /* must be killed with CTRL-C */
63 "testcase/tstLdr-2",
64 "testcase/tstLdr-3",
65 "testcase/tstLdr",
66 "testcase/tstLdrLoad",
67 "testcase/tstLdrObj",
68 "testcase/tstLdrObjR0",
69 "testcase/tstMove",
70#if !defined(RT_OS_LINUX)
71 "testcase/tstRTR0Timer",
72#endif
73 "testcase/tstRunTestcases",
74 "testcase/tstRTS3", /* requires parameters <access key>, <secret key> */
75 "testcase/tstSDL",
76 "testcase/tstTime-3",
77 "testcase/tstSeamlessX11",
78 "testcase/tstVBoxControl",
79 "testcase/tstVDCopy", /* requires parameters <hdd1>, <hdd2> */
80 "./tstRunTestcases",
81 "./tstAnimate",
82 "./tstAPI",
83 "./tstCollector", /* takes forever */
84 "./tstHeadless",
85 "./tstHeadless2",
86 "./tstMicro",
87 "./tstMicroGC",
88 "./tstVBoxDbg",
89 "./tstVMM-2",
90 "./tstTestServMgr",
91 "./tstPDMAsyncCompletion", /* requires parameters <source>, <dest> */
92 "./tstXptDump",
93 "./tstnsIFileEnumerator",
94 "./tstSimpleTypeLib",
95 "./tstTestAtoms",
96 "./tstXptLink",
97 "./tstXPCOMCGlue", /* user interaction required */
98 "./tstTestCallTemplates",
99#if 1 // later
100 "testcase/tstIntNetR0",
101 "./tstVMM",
102 "./tstVMReq",
103 "./tstVMREQ",
104#endif
105 /* final entry*/
106 ""
107};
108
109
110/**
111 * Checks if a testcase is include or should be skipped.
112 *
113 * @param pszTestcase The testcase (filename).
114 *
115 * @return true if the testcase is included.
116 * false if the testcase should be skipped.
117 */
118static bool IsTestcaseIncluded(const char *pszTestcase)
119{
120 /* exclude special modules based on extension. */
121 const char *pszExt = RTPathExt(pszTestcase);
122 if ( !RTStrICmp(pszExt, ".r0")
123 || !RTStrICmp(pszExt, ".gc")
124 || !RTStrICmp(pszExt, ".sys")
125 || !RTStrICmp(pszExt, ".ko")
126 || !RTStrICmp(pszExt, ".o")
127 || !RTStrICmp(pszExt, ".obj")
128 || !RTStrICmp(pszExt, ".lib")
129 || !RTStrICmp(pszExt, ".a")
130 || !RTStrICmp(pszExt, ".so")
131 || !RTStrICmp(pszExt, ".dll")
132 || !RTStrICmp(pszExt, ".dylib")
133 || !RTStrICmp(pszExt, ".tmp")
134 || !RTStrICmp(pszExt, ".log")
135 )
136 return false;
137
138 /* check by name */
139 char *pszDup = RTStrDup(pszTestcase);
140 if (pszDup)
141 {
142 RTPathStripExt(pszDup);
143 for (unsigned i = 0; i < RT_ELEMENTS(g_apszExclude); i++)
144 {
145 if (!strcmp(g_apszExclude[i], pszDup))
146 {
147 RTStrFree(pszDup);
148 return false;
149 }
150 }
151 RTStrFree(pszDup);
152 return true;
153 }
154
155 RTPrintf("tstRunTestcases: Out of memory!\n");
156 return false;
157}
158
159
160/**
161 * Process the testcases found in the filter.
162 *
163 * @param pszFilter The filter (winnt) to pass to RTDirOpenFiltered for
164 * selecting the testcases.
165 * @param pszDir The directory we're processing.
166 */
167static void Process(const char *pszFilter, const char *pszDir)
168{
169 /*
170 * Open and enumerate the directory.
171 */
172 PRTDIR pDir;
173 int rc = RTDirOpenFiltered(&pDir, pszFilter, RTDIRFILTER_WINNT);
174 if (RT_SUCCESS(rc))
175 {
176 for (;;)
177 {
178 RTDIRENTRY DirEntry;
179 rc = RTDirRead(pDir, &DirEntry, NULL);
180 if (RT_FAILURE(rc))
181 {
182 if (rc == VERR_NO_MORE_FILES)
183 rc = VINF_SUCCESS;
184 else
185 RTPrintf("tstRunTestcases: reading '%s' -> %Rrc\n", pszFilter, rc);
186 break;
187 }
188
189 /*
190 * Construct the testcase name.
191 */
192 char *pszTestcase;
193 RTStrAPrintf(&pszTestcase, "%s/%s", pszDir, DirEntry.szName);
194 if (!pszTestcase)
195 {
196 RTPrintf("tstRunTestcases: out of memory!\n");
197 rc = VERR_NO_MEMORY;
198 break;
199 }
200 if (IsTestcaseIncluded(pszTestcase))
201 {
202 /*
203 * Execute the testcase.
204 */
205 RTPrintf("*** %s: Executing...\n", pszTestcase); RTStrmFlush(g_pStdOut);
206 const char *papszArgs[2];
207 papszArgs[0] = pszTestcase;
208 papszArgs[1] = NULL;
209 RTPROCESS Process;
210 rc = RTProcCreate(pszTestcase, papszArgs, RTENV_DEFAULT, 0, &Process);
211 if (RT_SUCCESS(rc))
212 {
213 /*
214 * Wait for the process and collect it's return code.
215 * If it takes too long, we'll terminate it and continue.
216 */
217 RTTIMESPEC Start;
218 RTTimeNow(&Start);
219 RTPROCSTATUS ProcStatus;
220 for (;;)
221 {
222 rc = RTProcWait(Process, RTPROCWAIT_FLAGS_NOBLOCK, &ProcStatus);
223 if (rc != VERR_PROCESS_RUNNING)
224 break;
225 RTTIMESPEC Now;
226 if (RTTimeSpecGetMilli(RTTimeSpecSub(RTTimeNow(&Now), &Start)) > 120*1000 /* 1 min */)
227 {
228 RTPrintf("*** %s: FAILED - timed out. killing it.\n", pszTestcase);
229 RTProcTerminate(Process);
230 RTThreadSleep(100);
231 RTProcWait(Process, RTPROCWAIT_FLAGS_NOBLOCK, &ProcStatus);
232 g_cFailures++;
233 break;
234 }
235 RTThreadSleep(100);
236 }
237
238 /*
239 * Examin the exit status.
240 */
241 if (RT_SUCCESS(rc))
242 {
243 if ( ProcStatus.enmReason == RTPROCEXITREASON_NORMAL
244 && ProcStatus.iStatus == 0)
245 {
246 RTPrintf("*** %s: PASSED\n", pszTestcase);
247 g_cPasses++;
248 }
249 else
250 {
251 RTPrintf("*** %s: FAILED\n", pszTestcase);
252 g_cFailures++;
253 }
254 }
255 else if (rc != VERR_PROCESS_RUNNING)
256 {
257 RTPrintf("tstRunTestcases: %s: RTProcWait failed -> %Rrc\n", pszTestcase, rc);
258 g_cFailures++;
259 }
260 }
261 else
262 {
263 RTPrintf("tstRunTestcases: %s: failed to start -> %Rrc\n", pszTestcase, rc);
264 g_cFailures++;
265 }
266
267 }
268 else
269 {
270 RTPrintf("tstRunTestcases: %s: SKIPPED\n", pszTestcase);
271 g_cSkipped++;
272 }
273 RTStrFree(pszTestcase);
274 } /* enumeration loop */
275
276 RTDirClose(pDir);
277 }
278 else
279 RTPrintf("tstRunTestcases: opening '%s' -> %Rrc\n", pszDir, rc);
280}
281
282
283
284int main(int argc, char **argv)
285{
286 RTR3InitExe(argc, &argv, 0);
287
288 if (argc == 1)
289 {
290 char szPath[RTPATH_MAX];
291 int rc = RTPathExecDir(szPath, sizeof(szPath) - sizeof("/.."));
292 if (RT_FAILURE(rc))
293 {
294 RTPrintf("fatal error: RTPathExecDir -> %Rrc\n", rc);
295 return 1;
296 }
297 rc = RTPathSetCurrent(strcat(szPath, "/.."));
298 if (RT_FAILURE(rc))
299 {
300 RTPrintf("fatal error: RTPathSetCurrent -> %Rrc\n", rc);
301 return 1;
302 }
303
304 Process("testcase/tst*", "testcase");
305 Process("tst*", ".");
306 }
307 else
308 {
309 char szDir[RTPATH_MAX];
310 for (int i = 1; i < argc; i++)
311 {
312 if (argv[i][0] == '-')
313 {
314 switch (argv[i][1])
315 {
316 /* case '':... */
317
318 default:
319 RTPrintf("syntax error: Option '%s' is not recognized\n", argv[i]);
320 return 1;
321 }
322 }
323 else
324 {
325 size_t cch = strlen(argv[i]);
326 if (cch >= sizeof(szDir))
327 {
328 RTPrintf("syntax error: '%s' is too long!\n", argv[i]);
329 return 1;
330 }
331 memcpy(szDir, argv[i], cch + 1);
332 char *pszFilename = RTPathFilename(szDir);
333 if (!pszFilename)
334 {
335 RTPrintf("syntax error: '%s' does not include a file name or file name mask!\n", argv[i]);
336 return 1;
337 }
338 RTPathStripFilename(szDir);
339 Process(argv[i], szDir);
340 }
341 }
342 }
343
344 RTPrintf("\n"
345 "********************\n"
346 "*** PASSED: %u\n"
347 "*** FAILED: %u\n"
348 "*** SKIPPED: %u\n"
349 "*** TOTAL: %u\n",
350 g_cPasses,
351 g_cFailures,
352 g_cSkipped,
353 g_cPasses + g_cFailures + g_cSkipped);
354 return !!g_cFailures;
355}
356
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette