VirtualBox

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

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

Storage/VBoxHDD-new: Added backend info, listing the supported file extensions. Implemented a testcase anf fixed a small bug which it found.

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