VirtualBox

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

Last change on this file since 14810 was 14384, checked in by vboxsync, 16 years ago

testcases: no point in running tstDir and tstDir-2, as they will always return success since they expect parameters on the cmdline to work on. Running tstVD-2 is useful however, as it's quick.

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