VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstRTR0CommonDriver.h@ 47553

Last change on this file since 47553 was 47553, checked in by vboxsync, 11 years ago

Fix R0 timer testcase on darwin and make it possible to skip R0 tests when the feature is not supported (for the timer testcase it is the RTTIMER_FLAGS_CPU_ALL flag which is not supported on darwin)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.2 KB
Line 
1/* $Id: tstRTR0CommonDriver.h 47553 2013-08-06 10:03:55Z vboxsync $ */
2/** @file
3 * IPRT R0 Testcase - Common header for the testcase drivers.
4 */
5
6/*
7 * Copyright (C) 2010 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 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28#ifndef ___testcase_tstRTR0CommonDriver_h
29#define ___testcase_tstRTR0CommonDriver_h
30
31
32/*******************************************************************************
33* Header Files *
34*******************************************************************************/
35#include <iprt/ctype.h>
36#include <iprt/string.h>
37#include <VBox/sup.h>
38#include "tstRTR0CommonReq.h"
39
40
41/*******************************************************************************
42* Global Variables *
43*******************************************************************************/
44/** The test handle. */
45RTTEST g_hTest;
46/** The test & service name. */
47char g_szSrvName[64];
48/** The length of the service name. */
49uint32_t g_cchSrvName;
50/** The base address of the service module. */
51void *g_pvImageBase;
52
53
54/**
55 * Initializes the test driver.
56 *
57 * This means creating a test instance (RTTEST), initializing the support
58 * library, and loading the service module.
59 *
60 * @returns RTEXITCODE_SUCCESS on success, appropriate exit code on failure.
61 * @param pszTestServiceName The name of the test and service. This
62 * will be used when creating the test
63 * instance as well as when talking with the
64 * kernel side of the test.
65 *
66 * The ring-0 module name will be derived from
67 * this + '.r0'.
68 *
69 * The service request handler function name
70 * will be derived by upper casing the first
71 * chars and appending 'SrvReqHandler'.
72 *
73 */
74RTEXITCODE RTR3TestR0CommonDriverInit(const char *pszTestServiceName)
75{
76 /*
77 * Init the test.
78 */
79 RTEXITCODE rcExit = RTTestInitAndCreate(pszTestServiceName, &g_hTest);
80 if (rcExit != RTEXITCODE_SUCCESS)
81 return rcExit;
82 RTTestBanner(g_hTest);
83
84 /*
85 * Init the globals.
86 */
87 g_cchSrvName = strlen(pszTestServiceName);
88 int rc = RTStrCopy(g_szSrvName, sizeof(g_szSrvName), pszTestServiceName);
89 if (rc != VINF_SUCCESS)
90 {
91 RTTestFailed(g_hTest, "The test name is too long! (%zu bytes)", g_cchSrvName);
92 return RTTestSummaryAndDestroy(g_hTest);
93 }
94
95 /*
96 * Initialize the support driver session.
97 */
98 PSUPDRVSESSION pSession;
99 rc = SUPR3Init(&pSession);
100 if (RT_FAILURE(rc))
101 {
102 RTTestFailed(g_hTest, "SUPR3Init failed with rc=%Rrc\n", rc);
103 return RTTestSummaryAndDestroy(g_hTest);
104 }
105
106 char szPath[RTPATH_MAX + sizeof(".r0")];
107 rc = RTPathExecDir(szPath, RTPATH_MAX);
108 if (RT_SUCCESS(rc))
109 rc = RTPathAppend(szPath, RTPATH_MAX, pszTestServiceName);
110 if (RT_SUCCESS(rc))
111 strcat(szPath, ".r0");
112 if (RT_FAILURE(rc))
113 {
114 RTTestFailed(g_hTest, "Failed constructing .r0 filename (rc=%Rrc)", rc);
115 return RTTestSummaryAndDestroy(g_hTest);
116 }
117
118 char szSrvReqHandler[sizeof(g_szSrvName) + sizeof("SrvReqHandler")];
119 strcpy(szSrvReqHandler, pszTestServiceName);
120 strcat(szSrvReqHandler, "SrvReqHandler");
121 for (size_t off = 0; RT_C_IS_LOWER(szSrvReqHandler[off]); off++)
122 szSrvReqHandler[off] = RT_C_TO_UPPER(szSrvReqHandler[off]);
123
124 rc = SUPR3LoadServiceModule(szPath, pszTestServiceName, szSrvReqHandler, &g_pvImageBase);
125 if (RT_FAILURE(rc))
126 {
127 RTTestFailed(g_hTest, "SUPR3LoadServiceModule(%s,%s,%s,) failed with rc=%Rrc\n",
128 szPath, pszTestServiceName, szSrvReqHandler, rc);
129 return RTTestSummaryAndDestroy(g_hTest);
130 }
131
132 /*
133 * Do the sanity checks.
134 */
135 RTTestSub(g_hTest, "Sanity");
136 RTTSTR0REQ Req;
137 Req.Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC;
138 Req.Hdr.cbReq = sizeof(Req);
139 memset(Req.szMsg, 0xef, sizeof(Req.szMsg));
140 RTTESTI_CHECK_RC(rc = SUPR3CallR0Service(g_szSrvName, g_cchSrvName, RTTSTR0REQ_SANITY_OK, 0, &Req.Hdr), VINF_SUCCESS);
141 if (RT_FAILURE(rc))
142 return RTTestSummaryAndDestroy(g_hTest);
143 RTTESTI_CHECK_MSG(Req.szMsg[0] == '\0', ("%s", Req.szMsg));
144 if (Req.szMsg[0] != '\0')
145 return RTTestSummaryAndDestroy(g_hTest);
146
147
148 Req.Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC;
149 Req.Hdr.cbReq = sizeof(Req);
150 Req.szMsg[0] = '\0';
151 memset(Req.szMsg, 0xfe, sizeof(Req.szMsg));
152 RTTESTI_CHECK_RC(rc = SUPR3CallR0Service(g_szSrvName, g_cchSrvName, RTTSTR0REQ_SANITY_FAILURE, 0, &Req.Hdr), VINF_SUCCESS);
153 if (RT_FAILURE(rc))
154 return RTTestSummaryAndDestroy(g_hTest);
155 rc = !strncmp(Req.szMsg, "!42failure42", sizeof("!42failure42"));
156 if (rc)
157 {
158 RTTestFailed(g_hTest, "the negative sanity check failed");
159 return RTTestSummaryAndDestroy(g_hTest);
160 }
161 RTTestSubDone(g_hTest);
162
163 return RTEXITCODE_SUCCESS;
164}
165
166
167/**
168 * Processes the messages in the request.
169 *
170 * @returns true on success, false on failure.
171 * @param pReq The request.
172 */
173static bool rtR3TestR0ProcessMessages(PRTTSTR0REQ pReq)
174{
175 /*
176 * Process the message strings.
177 *
178 * We can have multiple failures and info messages packed into szMsg. They
179 * are separated by a double newline. The kind of message is indicated by
180 * the first character, '!' means error and '?' means info message. '$' means
181 * the test was skipped because a feature is not supported on the host.
182 */
183 bool fRc = true;
184 if (pReq->szMsg[0])
185 {
186 pReq->szMsg[sizeof(pReq->szMsg) - 1] = '\0'; /* paranoia */
187
188 char *pszNext = &pReq->szMsg[0];
189 do
190 {
191 char *pszCur = pszNext;
192 do
193 pszNext = strpbrk(pszNext + 1, "!?$");
194 while (pszNext && (pszNext[-1] != '\n' || pszNext[-2] != '\n'));
195
196 char *pszEnd = pszNext ? pszNext - 1 : strchr(pszCur, '\0');
197 while ( (uintptr_t)pszEnd > (uintptr_t)pszCur
198 && pszEnd[-1] == '\n')
199 *--pszEnd = '\0';
200
201 if (*pszCur == '!')
202 {
203 RTTestFailed(g_hTest, "%s", pszCur + 1);
204 fRc = false;
205 }
206 else if (*pszCur == '$')
207 {
208 RTTestSkipped(g_hTest, "%s", pszCur + 1);
209 }
210 else
211 RTTestPrintfNl(g_hTest, RTTESTLVL_ALWAYS, "%s", pszCur + 1);
212 } while (pszNext);
213 }
214
215 return fRc;
216}
217
218
219/**
220 * Performs a simple test with an argument (@a u64Arg).
221 *
222 * @returns true on success, false on failure.
223 * @param uOperation The operation to perform.
224 * @param u64Arg 64-bit argument.
225 * @param pszTestFmt The sub-test name.
226 * @param ... Format arguments.
227 */
228bool RTR3TestR0SimpleTestWithArg(uint32_t uOperation, uint64_t u64Arg, const char *pszTestFmt, ...)
229{
230 va_list va;
231 va_start(va, pszTestFmt);
232 RTTestSubV(g_hTest, pszTestFmt, va);
233 va_end(va);
234
235 RTTSTR0REQ Req;
236 Req.Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC;
237 Req.Hdr.cbReq = sizeof(Req);
238 RT_ZERO(Req.szMsg);
239 int rc = SUPR3CallR0Service(g_szSrvName, g_cchSrvName, uOperation, u64Arg, &Req.Hdr);
240 if (RT_FAILURE(rc))
241 {
242 RTTestFailed(g_hTest, "SUPR3CallR0Service failed with rc=%Rrc", rc);
243 return false;
244 }
245
246 return rtR3TestR0ProcessMessages(&Req);
247}
248
249
250/**
251 * Performs a simple test.
252 *
253 * @returns true on success, false on failure.
254 * @param uOperation The operation to perform.
255 * @param pszTestFmt The sub-test name.
256 * @param ... Format arguments.
257 */
258bool RTR3TestR0SimpleTest(uint32_t uOperation, const char *pszTestFmt, ...)
259{
260 va_list va;
261 va_start(va, pszTestFmt);
262 RTTestSubV(g_hTest, pszTestFmt, va);
263 va_end(va);
264
265 RTTSTR0REQ Req;
266 Req.Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC;
267 Req.Hdr.cbReq = sizeof(Req);
268 RT_ZERO(Req.szMsg);
269 int rc = SUPR3CallR0Service(g_szSrvName, g_cchSrvName, uOperation, 0, &Req.Hdr);
270 if (RT_FAILURE(rc))
271 {
272 RTTestFailed(g_hTest, "SUPR3CallR0Service failed with rc=%Rrc", rc);
273 return false;
274 }
275
276 return rtR3TestR0ProcessMessages(&Req);
277}
278
279#endif
280
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