VirtualBox

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

Last change on this file since 7692 was 6290, checked in by vboxsync, 17 years ago

Guest Additions: update for the Linux seamless additions

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