VirtualBox

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

Last change on this file since 95841 was 93115, checked in by vboxsync, 3 years ago

scm --update-copyright-year

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