VirtualBox

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

Last change on this file since 10278 was 8155, checked in by vboxsync, 17 years ago

The Big Sun Rebranding Header Change

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