VirtualBox

source: vbox/trunk/src/VBox/VMM/testcase/tstVMM-2.cpp@ 3840

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

InnoTek -> innotek: all the headers and comments.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 13.9 KB
Line 
1/* $Id: tstVMM-2.cpp 2981 2007-06-01 16:01:28Z vboxsync $ */
2/** @file
3 * VMM Testcase - no. 2.
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 <VBox/vm.h>
27#include <VBox/vmm.h>
28#include <VBox/cpum.h>
29#include <VBox/err.h>
30
31#include <VBox/log.h>
32#include <iprt/assert.h>
33#include <iprt/runtime.h>
34#include <iprt/semaphore.h>
35#include <iprt/thread.h>
36#include <iprt/string.h>
37#include <iprt/ctype.h>
38#include <iprt/stream.h>
39
40#include <stdio.h> /** @todo get rid of this. */
41
42
43/*******************************************************************************
44* Defined Constants And Macros *
45*******************************************************************************/
46#define TESTCASE "tstVMM-2"
47
48
49/*******************************************************************************
50* Structures and Typedefs *
51*******************************************************************************/
52typedef struct TSTVMMARGS
53{
54 /** The filename. */
55 const char *pszFilename;
56 /** The opened file. */
57 FILE *pFile;
58} TSTVMMARGS, *PTSTVMMARGS;
59
60
61
62/**
63 * Configuration constructor - takes flat file as input.
64 */
65static DECLCALLBACK(int) ConfigConstructor(PVM pVM, void *pvArgs)
66{
67 PTSTVMMARGS pArgs = (PTSTVMMARGS)pvArgs;
68 LogFlow(("%s: Reading configuration %s.\n", TESTCASE, pArgs->pszFilename));
69
70 /*
71 * Read the file.
72 */
73 unsigned iLine = 0;
74 char szLine[16384];
75 PCFGMNODE pNode = NULL;
76 while (fgets(szLine, sizeof(szLine), pArgs->pFile))
77 {
78 iLine++;
79 char *psz = szLine;
80 /* leading blanks */
81 while (isspace(*psz))
82 psz++;
83 if (*psz == '[')
84 {
85 /*
86 * Key path.
87 */
88 psz++;
89 if (*psz != '/')
90 {
91 RTPrintf("%s(%d): error: key path must start with slash.\n", pArgs->pszFilename, iLine);
92 return VERR_GENERAL_FAILURE;
93 }
94 char *pszEnd = strchr(psz, ']');
95 if (!pszEnd)
96 {
97 RTPrintf("%s(%d): error: missing ']'.\n", pArgs->pszFilename, iLine);
98 return VERR_GENERAL_FAILURE;
99 }
100 while (pszEnd - 1 > psz && pszEnd[-1] == '/') /* strip trailing slashes. */
101 pszEnd--;
102 *pszEnd++ = '/';
103 *pszEnd = '\0';
104
105 /*
106 * Create the key path.
107 */
108 pNode = CFGMR3GetRoot(pVM);
109 char *pszCur = psz + 1;
110 while (pNode && psz < pszEnd)
111 {
112 char *pszCurEnd = strchr(pszCur, '/');
113 *pszCurEnd = '\0';
114 PCFGMNODE pChild = CFGMR3GetChild(pNode, pszCur);
115 if (!pChild)
116 {
117 int rc = CFGMR3InsertNode(pNode, pszCur, &pChild);
118 if (VBOX_FAILURE(rc))
119 {
120 *pszCurEnd = '/';
121 RTPrintf("%s(%d): error: failed to create node '%s', rc=%d.\n", pArgs->pszFilename, iLine, psz, rc);
122 return rc;
123 }
124 }
125
126 /* next path component */
127 *pszCurEnd = '/';
128 pNode = pChild;
129 pszCur = pszCurEnd + 1;
130 }
131 }
132 else if (*psz != '#' && *psz != ';' && *psz != '\0' && *psz != '\n' && *psz != '\r')
133 {
134 /*
135 * Value Name.
136 */
137 char *pszName = psz;
138 char *pszNameEnd;
139 if (*pszName == '"' || *pszName == '\'')
140 {
141 /* quoted name */
142 pszNameEnd = pszName;
143 for (;;)
144 {
145 pszNameEnd = strchr(pszNameEnd + 1, *pszName);
146 if (!pszNameEnd)
147 {
148 RTPrintf("%s(%d): error: unbalanced quote.\n", pArgs->pszFilename, iLine);
149 return VERR_GENERAL_FAILURE;
150 }
151 if (pszNameEnd[1] != pszNameEnd[0])
152 break;
153 pszNameEnd++;
154 }
155 psz = strchr(pszNameEnd, '=');
156 *pszNameEnd-- = '\0';
157 *pszName++ = '\0';
158 }
159 else
160 {
161 /* unquoted name. Name ends before '<type>' or '='. */
162 pszNameEnd = strpbrk(psz, "=<");
163 if (!pszNameEnd)
164 {
165 RTPrintf("%s(%d): error: missing '='.\n", pArgs->pszFilename, iLine);
166 return VERR_GENERAL_FAILURE;
167 }
168 psz = strchr(pszNameEnd, '=');
169 *pszNameEnd-- = '\0';
170 while (pszNameEnd > psz && isspace(pszNameEnd[-1]))
171 pszNameEnd--;
172 if (!pszNameEnd)
173 {
174 RTPrintf("%s(%d): error: missing '<'.\n", pArgs->pszFilename, iLine);
175 return VERR_GENERAL_FAILURE;
176 }
177 }
178 if (pszName == pszNameEnd)
179 {
180 RTPrintf("%s(%d): error: empty value name.\n", pArgs->pszFilename, iLine);
181 return VERR_GENERAL_FAILURE;
182 }
183
184 /* check if equal sign present and skip past it and all following blanks. */
185 if (!psz)
186 {
187 RTPrintf("%s(%d): error: missing '='.\n", pArgs->pszFilename, iLine);
188 return VERR_GENERAL_FAILURE;
189 }
190 psz++;
191 while (isspace(*psz))
192 psz++;
193
194 /*
195 * Value.
196 */
197 if (*psz == '"' || *psz == '\'')
198 {
199 /* string */
200 char *pszValueEnd = psz;
201 for (;;)
202 {
203 pszValueEnd = strchr(pszValueEnd + 1, *psz);
204 if (!pszValueEnd)
205 {
206 RTPrintf("%s(%d): error: unbalanced quote in string value.\n", pArgs->pszFilename, iLine);
207 return VERR_GENERAL_FAILURE;
208 }
209 if (pszValueEnd[1] != pszValueEnd[0])
210 break;
211 pszValueEnd++;
212 }
213 *pszValueEnd-- = '\0';
214 *psz++ = '\0';
215
216 int rc = CFGMR3InsertString(pNode, pszName, psz);
217 if (VBOX_FAILURE(rc))
218 {
219 RTPrintf("%s(%d): error: failed to insert string value named '%s' and with value '%s', rc=%d.\n",
220 pArgs->pszFilename, iLine, pszName, psz, rc);
221 return rc;
222 }
223 }
224 else if ( isxdigit(psz[0]) && isxdigit(psz[1])
225 && isspace(psz[2])
226 && isxdigit(psz[3]) && isxdigit(psz[4]))
227 {
228 /* byte string */
229 RTPrintf("%s(%d): error: byte string is not implemented\n", pArgs->pszFilename, iLine);
230 return VERR_GENERAL_FAILURE;
231 }
232 else if (isdigit(psz[0]))
233 {
234 /* integer */
235 uint64_t u64 = 0;
236 if (psz[0] == '0' && (psz[1] == 'x' || psz[1] == 'X'))
237 { /* hex */
238 psz += 2;
239 while (isxdigit(*psz))
240 {
241 u64 *= 16;
242 u64 += *psz <= '9' ? *psz - '0' : *psz >= 'a' ? *psz - 'a' + 10 : *psz - 'A' + 10;
243 psz++;
244 }
245 }
246 else
247 { /* decimal */
248 while (isdigit(*psz))
249 {
250 u64 *= 10;
251 u64 += *psz - '0';
252 psz++;
253 }
254 }
255 if (isalpha(*psz))
256 {
257 RTPrintf("%s(%d): error: unexpected char(s) after number '%.10s'\n", pArgs->pszFilename, iLine, psz);
258 return VERR_GENERAL_FAILURE;
259 }
260
261 int rc = CFGMR3InsertInteger(pNode, pszName, u64);
262 if (VBOX_FAILURE(rc))
263 {
264 RTPrintf("%s(%d): error: failed to insert integer value named '%s' and with value %#llx, rc=%d.\n",
265 pArgs->pszFilename, iLine, pszName, u64, rc);
266 return rc;
267 }
268 }
269 else
270 {
271 RTPrintf("%s(%d): error: unknown value format.\n", pArgs->pszFilename, iLine);
272 return VERR_GENERAL_FAILURE;
273 }
274 }
275 /* else: skip */
276 } /* for each line */
277
278 LogFlow(("%s: successfully read config\n"));
279 return VINF_SUCCESS;
280}
281
282
283
284int main(int argc, char **argv)
285{
286 TSTVMMARGS Args = {0};
287 int rcRet = 0; /* error count. */
288 int fPowerOn = 0;
289
290 RTR3Init();
291
292
293 /*
294 * Parse arguments.
295 */
296 for (int i = 1; i < argc; i++)
297 {
298 const char *psz = argv[i];
299 if (*psz == '-')
300 {
301 psz++;
302 if (*psz == '-')
303 psz++;
304 if (!strcmp(psz, "config"))
305 {
306 if (Args.pszFilename)
307 {
308 RTPrintf("syntax error: only one config argument!\n");
309 return 1;
310 }
311 if (i + 1 >= argc)
312 {
313 RTPrintf("syntax error: no configuration filename!\n");
314 return 1;
315 }
316 Args.pszFilename = argv[++i];
317 Args.pFile = fopen(Args.pszFilename, "r");
318 if (!Args.pFile)
319 {
320 RTPrintf("%s: Failed to open '%s' for reading!\n", TESTCASE, Args.pszFilename);
321 return 1;
322 }
323 }
324 else if (!strcmp(psz, "poweron"))
325 fPowerOn = 1;
326 else if ( !strncmp(psz, "help", 4)
327 || (*psz == 'h' && !psz[1]))
328 {
329 RTPrintf("syntax: %s [options]\n"
330 "\n"
331 "options (prefixed with a dash or two)\n"
332 " config <filename> Load the flat config file.\n"
333 " help This help text.\n", argv[0]);
334 return 1;
335 }
336 else
337 {
338 RTPrintf("syntax error: unknown option '%s' in arg %d.\n", psz, i);
339 return 1;
340 }
341
342 }
343 else
344 {
345 RTPrintf("syntax error: Sorry dude, no idea what you're passing to me.\n"
346 " arg %d '%s'\n", i, argv[i]);
347 return 1;
348 }
349 }
350
351
352 /*
353 * Create empty VM.
354 */
355 PVM pVM;
356 int rc = VMR3Create(NULL, NULL, Args.pszFilename ? ConfigConstructor : NULL, &Args, &pVM);
357 if (VBOX_SUCCESS(rc))
358 {
359 /*
360 * Power it on if that was requested.
361 */
362 if (fPowerOn)
363 {
364 PVMREQ pReq;
365 rc = VMR3ReqCall(pVM, &pReq, RT_INDEFINITE_WAIT, (PFNRT)VMR3PowerOn, 1, pVM);
366 if (VBOX_SUCCESS(rc))
367 {
368 rc = pReq->iStatus;
369 VMR3ReqFree(pReq);
370 if (VBOX_SUCCESS(rc))
371 {
372 RTPrintf(TESTCASE ": info: VMR3PowerOn succeeded. rc=%d\n", rc);
373 RTPrintf(TESTCASE ": info: main thread is taking a nap...\n");
374 rc = RTThreadSleep(8*3600*1000); /* 8 hours */
375 RTPrintf(TESTCASE ": info: main thread is woke up... rc=%d\n", rc);
376
377 /*
378 * Power Off the VM.
379 */
380 rc = VMR3ReqCall(pVM, &pReq, RT_INDEFINITE_WAIT, (PFNRT)VMR3PowerOff, 1, pVM);
381 if (VBOX_SUCCESS(rc))
382 {
383 rc = pReq->iStatus;
384 VMR3ReqFree(pReq);
385 if (VBOX_SUCCESS(rc))
386 RTPrintf(TESTCASE ": info: Successfully powered off the VM. rc=%d\n", rc);
387 else
388 {
389 RTPrintf(TESTCASE ": error: VMR3PowerOff -> %d\n", rc);
390 rcRet++;
391 }
392 }
393 else
394 {
395 RTPrintf(TESTCASE ": error: VMR3ReqCall (power off) -> %d\n", rc);
396 rcRet++;
397 }
398 }
399 }
400 else
401 {
402 RTPrintf(TESTCASE ": error: VMR3ReqCall (power on) -> %d\n", rc);
403 rcRet++;
404 }
405 }
406
407 /*
408 * Cleanup.
409 */
410 rc = VMR3Destroy(pVM);
411 if (!VBOX_SUCCESS(rc))
412 {
413 RTPrintf(TESTCASE ": error: failed to destroy vm! rc=%d\n", rc);
414 rcRet++;
415 }
416 }
417 else
418 {
419 RTPrintf(TESTCASE ": fatal error: failed to create vm! rc=%d\n", rc);
420 rcRet++;
421 }
422
423 return rcRet;
424}
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