VirtualBox

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

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

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

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