VirtualBox

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

Last change on this file since 4895 was 4071, checked in by vboxsync, 17 years ago

Biggest check-in ever. New source code headers for all (C) innotek files.

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