VirtualBox

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

Last change on this file since 32190 was 32190, checked in by vboxsync, 14 years ago

PDMDevHlpVMSuspendSaveAndPowerOff: More code.

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