VirtualBox

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

Last change on this file since 33000 was 28800, checked in by vboxsync, 14 years ago

Automated rebranding to Oracle copyright/license strings via filemuncher

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

© 2023 Oracle
ContactPrivacy policyTerms of Use