VirtualBox

source: vbox/trunk/src/VBox/VMM/testcase/tstVMM.cpp@ 26624

Last change on this file since 26624 was 26517, checked in by vboxsync, 15 years ago

*: RTGetOpt cleanup related to --help and --version (now standard option). Use RTGetOptPrintError.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 9.6 KB
Line 
1/* $Id: tstVMM.cpp 26517 2010-02-14 21:39:00Z vboxsync $ */
2/** @file
3 * VMM Testcase.
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 <VBox/vm.h>
27#include <VBox/vmm.h>
28#include <VBox/cpum.h>
29#include <VBox/tm.h>
30#include <VBox/pdmapi.h>
31#include <VBox/err.h>
32#include <VBox/log.h>
33#include <iprt/assert.h>
34#include <iprt/ctype.h>
35#include <iprt/getopt.h>
36#include <iprt/initterm.h>
37#include <iprt/semaphore.h>
38#include <iprt/stream.h>
39#include <iprt/string.h>
40#include <iprt/test.h>
41#include <iprt/thread.h>
42
43
44/*******************************************************************************
45* Defined Constants And Macros *
46*******************************************************************************/
47#define TESTCASE "tstVMM"
48
49
50
51/*******************************************************************************
52* Global Variables *
53*******************************************************************************/
54static uint32_t g_cCpus = 1;
55
56
57/*******************************************************************************
58* Internal Functions *
59*******************************************************************************/
60VMMR3DECL(int) VMMDoTest(PVM pVM); /* Linked into VMM, see ../VMMTests.cpp. */
61
62
63/** Dummy timer callback. */
64static DECLCALLBACK(void) tstTMDummyCallback(PVM pVM, PTMTIMER pTimer, void *pvUser)
65{
66 NOREF(pVM);
67 NOREF(pTimer);
68 NOREF(pvUser);
69}
70
71
72/**
73 * This is called on each EMT and will beat TM.
74 *
75 * @returns VINF_SUCCESS, test failure is reported via RTTEST.
76 * @param pVM The VM handle.
77 * @param hTest The test handle.
78 */
79DECLCALLBACK(int) tstTMWorker(PVM pVM, RTTEST hTest)
80{
81 VMCPUID idCpu = VMMGetCpuId(pVM);
82 RTTestPrintfNl(hTest, RTTESTLVL_ALWAYS, "idCpu=%d STARTING\n", idCpu);
83
84 /*
85 * Create the test set.
86 */
87 int rc;
88 PTMTIMER apTimers[5];
89 for (size_t i = 0; i < RT_ELEMENTS(apTimers); i++)
90 {
91 rc = TMR3TimerCreateInternal(pVM, i & 1 ? TMCLOCK_VIRTUAL : TMCLOCK_VIRTUAL_SYNC,
92 tstTMDummyCallback, NULL, "test timer", &apTimers[i]);
93 RTTEST_CHECK_RET(hTest, RT_SUCCESS(rc), rc);
94 }
95
96 /*
97 * The run loop.
98 */
99 unsigned uPrevPct = 0;
100 uint32_t const cLoops = 100000;
101 for (uint32_t iLoop = 0; iLoop < cLoops; iLoop++)
102 {
103 size_t cLeft = RT_ELEMENTS(apTimers);
104 unsigned i = iLoop % RT_ELEMENTS(apTimers);
105 while (cLeft-- > 0)
106 {
107 PTMTIMER pTimer = apTimers[i];
108
109 if ( cLeft == RT_ELEMENTS(apTimers) / 2
110 && TMTimerIsActive(pTimer))
111 {
112 rc = TMTimerStop(pTimer);
113 RTTEST_CHECK_MSG(hTest, RT_SUCCESS(rc), (hTest, "TMTimerStop: %Rrc\n", rc));
114 }
115 else
116 {
117 rc = TMTimerSetMicro(pTimer, 50 + cLeft);
118 RTTEST_CHECK_MSG(hTest, RT_SUCCESS(rc), (hTest, "TMTimerSetMicro: %Rrc\n", rc));
119 }
120
121 /* next */
122 i = (i + 1) % RT_ELEMENTS(apTimers);
123 }
124
125 if (i % 3)
126 TMR3TimerQueuesDo(pVM);
127
128 /* Progress report. */
129 unsigned uPct = (unsigned)(100.0 * iLoop / cLoops);
130 if (uPct != uPrevPct)
131 {
132 uPrevPct = uPct;
133 if (!(uPct % 10))
134 RTTestPrintfNl(hTest, RTTESTLVL_ALWAYS, "idCpu=%d - %3u%%\n", idCpu, uPct);
135 }
136 }
137
138 RTTestPrintfNl(hTest, RTTESTLVL_ALWAYS, "idCpu=%d DONE\n", idCpu);
139 return 0;
140}
141
142
143/** PDMR3LdrEnumModules callback, see FNPDMR3ENUM. */
144static DECLCALLBACK(int)
145tstVMMLdrEnum(PVM pVM, const char *pszFilename, const char *pszName, RTUINTPTR ImageBase, size_t cbImage, bool fGC, void *pvUser)
146{
147 NOREF(pVM); NOREF(pszFilename); NOREF(fGC); NOREF(pvUser);
148 RTPrintf("tstVMM: %RTptr %s\n", ImageBase, pszName);
149 return VINF_SUCCESS;
150}
151
152static DECLCALLBACK(int)
153tstVMMConfigConstructor(PVM pVM, void *pvUser)
154{
155 int rc = CFGMR3ConstructDefaultTree(pVM);
156 if ( RT_SUCCESS(rc)
157 && g_cCpus > 1)
158 {
159 PCFGMNODE pRoot = CFGMR3GetRoot(pVM);
160 CFGMR3RemoveValue(pRoot, "NumCPUs");
161 rc = CFGMR3InsertInteger(pRoot, "NumCPUs", g_cCpus);
162 RTTESTI_CHECK_MSG_RET(RT_SUCCESS(rc), ("CFGMR3InsertInteger(pRoot,\"NumCPUs\",) -> %Rrc\n", rc), rc);
163
164 CFGMR3RemoveValue(pRoot, "HwVirtExtForced");
165 rc = CFGMR3InsertInteger(pRoot, "HwVirtExtForced", true);
166 RTTESTI_CHECK_MSG_RET(RT_SUCCESS(rc), ("CFGMR3InsertInteger(pRoot,\"HwVirtExtForced\",) -> %Rrc\n", rc), rc);
167
168 PCFGMNODE pHwVirtExt = CFGMR3GetChild(pRoot, "HWVirtExt");
169 CFGMR3RemoveNode(pHwVirtExt);
170 rc = CFGMR3InsertNode(pRoot, "HWVirtExt", &pHwVirtExt);
171 RTTESTI_CHECK_MSG_RET(RT_SUCCESS(rc), ("CFGMR3InsertNode(pRoot,\"HWVirtExt\",) -> %Rrc\n", rc), rc);
172 rc = CFGMR3InsertInteger(pHwVirtExt, "Enabled", true);
173 RTTESTI_CHECK_MSG_RET(RT_SUCCESS(rc), ("CFGMR3InsertInteger(pHwVirtExt,\"Enabled\",) -> %Rrc\n", rc), rc);
174 rc = CFGMR3InsertInteger(pHwVirtExt, "64bitEnabled", false);
175 RTTESTI_CHECK_MSG_RET(RT_SUCCESS(rc), ("CFGMR3InsertInteger(pHwVirtExt,\"64bitEnabled\",) -> %Rrc\n", rc), rc);
176 }
177 return rc;
178}
179
180
181int main(int argc, char **argv)
182{
183 /*
184 * Init runtime and the test environment.
185 */
186 int rc = RTR3InitAndSUPLib();
187 if (RT_FAILURE(rc))
188 {
189 RTPrintf("tstVMM: RTR3InitAndSUPLib failed: %Rrc\n", rc);
190 return 1;
191 }
192 RTTEST hTest;
193 rc = RTTestCreate("tstVMM", &hTest);
194 if (RT_FAILURE(rc))
195 {
196 RTPrintf("tstVMM: RTTestCreate failed: %Rrc\n", rc);
197 return 1;
198 }
199
200 /*
201 * Parse arguments.
202 */
203 static const RTGETOPTDEF s_aOptions[] =
204 {
205 { "--cpus", 'c', RTGETOPT_REQ_UINT8 },
206 { "--test", 't', RTGETOPT_REQ_STRING },
207 };
208 enum
209 {
210 kTstVMMTest_VMM, kTstVMMTest_TM
211 } enmTestOpt = kTstVMMTest_VMM;
212
213 int ch;
214 int i = 1;
215 RTGETOPTUNION ValueUnion;
216 RTGETOPTSTATE GetState;
217 RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0);
218 while ((ch = RTGetOpt(&GetState, &ValueUnion)))
219 {
220 switch (ch)
221 {
222 case 'c':
223 g_cCpus = ValueUnion.u8;
224 break;
225
226 case 't':
227 if (!strcmp("vmm", ValueUnion.psz))
228 enmTestOpt = kTstVMMTest_VMM;
229 else if (!strcmp("tm", ValueUnion.psz))
230 enmTestOpt = kTstVMMTest_TM;
231 else
232 {
233 RTPrintf("tstVMM: unknown test: '%s'\n", ValueUnion.psz);
234 return 1;
235 }
236 break;
237
238 case 'h':
239 RTPrintf("usage: tstVMM [--cpus|-c cpus] [--test <vmm|tm>]\n");
240 return 1;
241
242 case 'V':
243 RTPrintf("$Revision: $\n");
244 return 0;
245
246 default:
247 return RTGetOptPrintError(ch, &ValueUnion);
248 }
249 }
250
251 /*
252 * Create the test VM.
253 */
254 RTPrintf(TESTCASE ": Initializing...\n");
255 PVM pVM;
256 rc = VMR3Create(g_cCpus, NULL, NULL, tstVMMConfigConstructor, NULL, &pVM);
257 if (RT_SUCCESS(rc))
258 {
259 PDMR3LdrEnumModules(pVM, tstVMMLdrEnum, NULL);
260 RTStrmFlush(g_pStdOut);
261 RTThreadSleep(256);
262
263 /*
264 * Do the requested testing.
265 */
266 switch (enmTestOpt)
267 {
268 case kTstVMMTest_VMM:
269 {
270 RTTestSub(hTest, "VMM");
271 rc = VMR3ReqCallWait(pVM, VMCPUID_ANY, (PFNRT)VMMDoTest, 1, pVM);
272 if (RT_FAILURE(rc))
273 RTTestFailed(hTest, "VMMDoTest failed: rc=%Rrc\n", rc);
274 break;
275 }
276
277 case kTstVMMTest_TM:
278 {
279 RTTestSub(hTest, "TM");
280 for (VMCPUID idCpu = 1; idCpu < g_cCpus; idCpu++)
281 {
282 rc = VMR3ReqCallNoWaitU(pVM->pUVM, idCpu, (PFNRT)tstTMWorker, 2, pVM, hTest);
283 if (RT_FAILURE(rc))
284 RTTestFailed(hTest, "VMR3ReqCall failed: rc=%Rrc\n", rc);
285 }
286
287 rc = VMR3ReqCallWait(pVM, 0 /*idDstCpu*/, (PFNRT)tstTMWorker, 2, pVM, hTest);
288 if (RT_FAILURE(rc))
289 RTTestFailed(hTest, "VMMDoTest failed: rc=%Rrc\n", rc);
290 break;
291 }
292 }
293
294 STAMR3Dump(pVM, "*");
295
296 /*
297 * Cleanup.
298 */
299 rc = VMR3Destroy(pVM);
300 if (RT_FAILURE(rc))
301 RTTestFailed(hTest, "VMR3Destroy failed: rc=%Rrc\n", rc);
302 }
303 else
304 RTTestFailed(hTest, "VMR3Create failed: rc=%Rrc\n", rc);
305
306 return RTTestSummaryAndDestroy(hTest);
307}
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