VirtualBox

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

Last change on this file since 102797 was 99775, checked in by vboxsync, 20 months ago

*: Mark functions as static if not used outside of a given compilation unit. Enables the compiler to optimize inlining, reduces the symbol tables, exposes unused functions and in some rare cases exposes mismtaches between function declarations and definitions, but most importantly reduces the number of parfait reports for the extern-function-no-forward-declaration category. This should not result in any functional changes, bugref:3409

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