VirtualBox

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

Last change on this file since 3696 was 2981, checked in by vboxsync, 17 years ago

InnoTek -> innotek: all the headers and comments.

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