VirtualBox

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

Last change on this file since 27212 was 21303, checked in by vboxsync, 15 years ago

-:

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