VirtualBox

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

Last change on this file since 26224 was 26153, checked in by vboxsync, 15 years ago

build fix

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 10.2 KB
Line 
1/* $Id: tstVMM.cpp 26153 2010-02-02 16:06:07Z 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 { "--help", 'h', 0 },
208 };
209 enum
210 {
211 kTstVMMTest_VMM, kTstVMMTest_TM
212 } enmTestOpt = kTstVMMTest_VMM;
213
214 int ch;
215 int i = 1;
216 RTGETOPTUNION ValueUnion;
217 RTGETOPTSTATE GetState;
218 RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0);
219 while ((ch = RTGetOpt(&GetState, &ValueUnion)))
220 {
221 switch (ch)
222 {
223 case 'c':
224 g_cCpus = ValueUnion.u8;
225 break;
226
227 case 't':
228 if (!strcmp("vmm", ValueUnion.psz))
229 enmTestOpt = kTstVMMTest_VMM;
230 else if (!strcmp("tm", ValueUnion.psz))
231 enmTestOpt = kTstVMMTest_TM;
232 else
233 {
234 RTPrintf("tstVMM: unknown test: '%s'\n", ValueUnion.psz);
235 return 1;
236 }
237 break;
238
239 case 'h':
240 RTPrintf("usage: tstVMM [--cpus|-c cpus] [--test <vmm|tm>]\n");
241 return 1;
242
243 case VINF_GETOPT_NOT_OPTION:
244 RTPrintf("tstVMM: syntax error: non option '%s'\n", ValueUnion.psz);
245 break;
246
247 default:
248 if (ch > 0)
249 {
250 if (RT_C_IS_GRAPH(ch))
251 RTPrintf("tstVMM: unhandled option: -%c\n", ch);
252 else
253 RTPrintf("tstVMM: unhandled option: %i\n", ch);
254 }
255 else if (ch == VERR_GETOPT_UNKNOWN_OPTION)
256 RTPrintf("tstVMM: unknown option: %s\n", ValueUnion.psz);
257 else if (ValueUnion.pDef)
258 RTPrintf("tstVMM: %s: %Rrs\n", ValueUnion.pDef->pszLong, ch);
259 else
260 RTPrintf("tstVMM: %Rrs\n", ch);
261 return 1;
262 }
263 }
264
265 /*
266 * Create the test VM.
267 */
268 RTPrintf(TESTCASE ": Initializing...\n");
269 PVM pVM;
270 rc = VMR3Create(g_cCpus, NULL, NULL, tstVMMConfigConstructor, NULL, &pVM);
271 if (RT_SUCCESS(rc))
272 {
273 PDMR3LdrEnumModules(pVM, tstVMMLdrEnum, NULL);
274 RTStrmFlush(g_pStdOut);
275 RTThreadSleep(256);
276
277 /*
278 * Do the requested testing.
279 */
280 switch (enmTestOpt)
281 {
282 case kTstVMMTest_VMM:
283 {
284 RTTestSub(hTest, "VMM");
285 rc = VMR3ReqCallWait(pVM, VMCPUID_ANY, (PFNRT)VMMDoTest, 1, pVM);
286 if (RT_FAILURE(rc))
287 RTTestFailed(hTest, "VMMDoTest failed: rc=%Rrc\n", rc);
288 break;
289 }
290
291 case kTstVMMTest_TM:
292 {
293 RTTestSub(hTest, "TM");
294 for (VMCPUID idCpu = 1; idCpu < g_cCpus; idCpu++)
295 {
296 rc = VMR3ReqCallNoWaitU(pVM->pUVM, idCpu, (PFNRT)tstTMWorker, 2, pVM, hTest);
297 if (RT_FAILURE(rc))
298 RTTestFailed(hTest, "VMR3ReqCall failed: rc=%Rrc\n", rc);
299 }
300
301 rc = VMR3ReqCallWait(pVM, 0 /*idDstCpu*/, (PFNRT)tstTMWorker, 2, pVM, hTest);
302 if (RT_FAILURE(rc))
303 RTTestFailed(hTest, "VMMDoTest failed: rc=%Rrc\n", rc);
304 break;
305 }
306 }
307
308 STAMR3Dump(pVM, "*");
309
310 /*
311 * Cleanup.
312 */
313 rc = VMR3Destroy(pVM);
314 if (RT_FAILURE(rc))
315 RTTestFailed(hTest, "VMR3Destroy failed: rc=%Rrc\n", rc);
316 }
317 else
318 RTTestFailed(hTest, "VMR3Create failed: rc=%Rrc\n", rc);
319
320 return RTTestSummaryAndDestroy(hTest);
321}
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