VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstRTR0Common.h@ 93931

Last change on this file since 93931 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: 8.1 KB
Line 
1/* $Id: tstRTR0Common.h 93115 2022-01-01 11:31:46Z vboxsync $ */
2/** @file
3 * IPRT R0 Testcase - Common header.
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_tstRTR0Common_h
28#define IPRT_INCLUDED_SRC_testcase_tstRTR0Common_h
29#ifndef RT_WITHOUT_PRAGMA_ONCE
30# pragma once
31#endif
32
33#include <iprt/stdarg.h>
34#include <iprt/string.h>
35#include "tstRTR0CommonReq.h"
36
37
38/*******************************************************************************
39* Global Variables *
40*******************************************************************************/
41/** Global error buffer used by macros and inline functions in this file. */
42static char g_szErr[2048];
43/** The number of errors reported in this g_szErr. */
44static uint32_t volatile g_cErrors;
45
46
47/**
48 * Service request handler prolog.
49 *
50 * Returns if the input is invalid. Initializes the return packet as well as
51 * the globals (g_szErr, g_cErrors).
52 *
53 * @param pReqHdr The request packet header.
54 */
55#define RTR0TESTR0_SRV_REQ_PROLOG_RET(pReqHdr) \
56 do \
57 { \
58 if (!RT_VALID_PTR(pReqHdr)) \
59 return VERR_INVALID_PARAMETER; \
60 \
61 PRTTSTR0REQ pReq = (PRTTSTR0REQ)(pReqHdr); \
62 size_t cchErr = pReqHdr->cbReq - sizeof(pReq->Hdr); \
63 if (cchErr < 32 || cchErr >= 0x10000) \
64 return VERR_INVALID_PARAMETER; \
65 pReq->szMsg[0] = '\0'; \
66 \
67 /* Initialize the global buffer. */ \
68 memset(&g_szErr[0], 0, sizeof(g_szErr)); \
69 ASMAtomicWriteU32(&g_cErrors, 0); \
70 } while (0)
71
72
73/**
74 * Service request handler epilog.
75 *
76 * Copies any errors or messages into the request packet.
77 *
78 * @param pReqHdr The request packet header.
79 */
80#define RTR0TESTR0_SRV_REQ_EPILOG(pReqHdr) \
81 do \
82 { \
83 PRTTSTR0REQ pReq = (PRTTSTR0REQ)(pReqHdr); \
84 size_t cbErr = pReqHdr->cbReq - sizeof(pReq->Hdr); \
85 if (g_szErr[0] && pReq->szMsg[0] != '!') \
86 RTStrCopyEx(pReq->szMsg, (cbErr), g_szErr, sizeof(g_szErr) - 1); \
87 } while (0)
88
89
90/**
91 * Implement the sanity check switch-cases of a service request handler.
92 */
93#define RTR0TESTR0_IMPLEMENT_SANITY_CASES() \
94 case RTTSTR0REQ_SANITY_OK: \
95 break; \
96 case RTTSTR0REQ_SANITY_FAILURE: \
97 RTR0TestR0Error("42failure42%4096s", ""); \
98 break
99
100/**
101 * Implements the default switch-case of a service request handler.
102 * @param uOperation The operation.
103 */
104#define RTR0TESTR0_IMPLEMENT_DEFAULT_CASE(uOperation) \
105 default: \
106 RTR0TestR0Error("Unknown test #%d", (uOperation)); \
107 break
108
109
110/**
111 * Macro for checking the return code of an API in the ring-0 testcase.
112 *
113 * Similar to RTTESTI_CHECK_RC.
114 *
115 * @param rcExpr The expression producing the return code. Only
116 * evaluated once.
117 * @param rcExpect The expected result. Evaluated multiple times.
118 */
119#define RTR0TESTR0_CHECK_RC(rcExpr, rcExpect) \
120 do { \
121 int rcCheck = (rcExpr); \
122 if (rcCheck != (rcExpect)) \
123 RTR0TestR0Error("line %u: %s: expected %Rrc, got %Rrc", __LINE__, #rcExpr, (rcExpect), rcCheck); \
124 } while (0)
125
126/**
127 * Same as RTR0TESTR0_CHECK_RC + break.
128 */
129#define RTR0TESTR0_CHECK_RC_BREAK(rcExpr, rcExpect) \
130 if (1) \
131 { \
132 int rcCheck = (rcExpr); \
133 if (rcCheck != (rcExpect)) \
134 { \
135 RTR0TestR0Error("line %u: %s: expected %Rrc, got %Rrc", __LINE__, #rcExpr, (rcExpect), rcCheck); \
136 break; \
137 } \
138 } else do { } while (0)
139
140/**
141 * Macro for checking the return code of an API in the ring-0 testcase.
142 *
143 * Similar to RTTESTI_CHECK_MSG
144 *
145 * @param expr The expression to evaluate.
146 * @param DetailsArgs Format string + arguments - in parenthesis.
147 */
148#define RTR0TESTR0_CHECK_MSG(expr, DetailsArgs) \
149 do { \
150 if (!(expr)) \
151 { \
152 RTR0TestR0Error("line %u: expression failed: %s - ", __LINE__, #expr); \
153 RTR0TestR0AppendDetails DetailsArgs; \
154 } \
155 } while (0)
156
157/**
158 * Same as RTR0TESTR0_CHECK_MSG + break.
159 */
160#define RTR0TESTR0_CHECK_MSG_BREAK(expr, DetailsArgs) \
161 if (!(expr)) \
162 { \
163 RTR0TestR0Error("line %u: expression failed: %s - ", __LINE__, #expr); \
164 RTR0TestR0AppendDetails DetailsArgs; \
165 break; \
166 } else do { } while (0)
167
168/**
169 * Same as RTR0TESTR0_CHECK_MSG + return @a rcRete.
170 */
171#define RTR0TESTR0_CHECK_MSG_RET(expr, DetailsArgs, rcRet) \
172 do { \
173 if (!(expr)) \
174 { \
175 RTR0TestR0Error("line %u: expression failed: %s - ", __LINE__, #expr); \
176 RTR0TestR0AppendDetails DetailsArgs; \
177 return (rcRet); \
178 } \
179 } while (0)
180
181/**
182 * Macro for skipping a test in the ring-0 testcase.
183 */
184#define RTR0TESTR0_SKIP() \
185 do { \
186 RTR0TestR0Skip("line %u: SKIPPED", __LINE__); \
187 } while (0)
188
189/**
190 * Same as RTR0TESTR0_SKIP + break.
191 */
192#define RTR0TESTR0_SKIP_BREAK() \
193 if (1) \
194 { \
195 RTR0TestR0Skip("line %u: SKIPPED", __LINE__); \
196 break; \
197 } else do { } while (0)
198
199
200/**
201 * Report an error.
202 */
203void RTR0TestR0Error(const char *pszFormat, ...)
204{
205 size_t off = RTStrNLen(g_szErr, sizeof(g_szErr) - 1);
206 size_t cbLeft = sizeof(g_szErr) - off;
207 if (cbLeft > 10)
208 {
209 char *psz = &g_szErr[off];
210 if (off)
211 {
212 *psz++ = '\n';
213 *psz++ = '\n';
214 cbLeft -= 2;
215 }
216 *psz++ = '!';
217 cbLeft--;
218
219 va_list va;
220 va_start(va, pszFormat);
221 RTStrPrintfV(psz, cbLeft, pszFormat, va);
222 va_end(va);
223 }
224 ASMAtomicIncU32(&g_cErrors);
225}
226
227
228/**
229 * Append error details.
230 */
231void RTR0TestR0AppendDetails(const char *pszFormat, ...)
232{
233 size_t off = RTStrNLen(g_szErr, sizeof(g_szErr) - 1);
234 va_list va;
235 va_start(va, pszFormat);
236 RTStrPrintfV(&g_szErr[off], sizeof(g_szErr) - off, pszFormat, va);
237 va_end(va);
238}
239
240
241/**
242 * Informational message.
243 */
244void RTR0TestR0Info(const char *pszFormat, ...)
245{
246 size_t off = RTStrNLen(g_szErr, sizeof(g_szErr) - 1);
247 size_t cbLeft = sizeof(g_szErr) - off;
248 if (cbLeft > 10)
249 {
250 char *psz = &g_szErr[off];
251 if (off)
252 {
253 *psz++ = '\n';
254 *psz++ = '\n';
255 cbLeft -= 2;
256 }
257 *psz++ = '?';
258 cbLeft--;
259
260 va_list va;
261 va_start(va, pszFormat);
262 RTStrPrintfV(psz, cbLeft, pszFormat, va);
263 va_end(va);
264 }
265}
266
267
268/**
269 * Report an error.
270 */
271void RTR0TestR0Skip(const char *pszFormat, ...)
272{
273 size_t off = RTStrNLen(g_szErr, sizeof(g_szErr) - 1);
274 size_t cbLeft = sizeof(g_szErr) - off;
275 if (cbLeft > 10)
276 {
277 char *psz = &g_szErr[off];
278 if (off)
279 {
280 *psz++ = '\n';
281 *psz++ = '\n';
282 cbLeft -= 2;
283 }
284 *psz++ = '$';
285 cbLeft--;
286
287 va_list va;
288 va_start(va, pszFormat);
289 RTStrPrintfV(psz, cbLeft, pszFormat, va);
290 va_end(va);
291 }
292 ASMAtomicIncU32(&g_cErrors);
293}
294
295
296/**
297 * Checks if we have any error reports.
298 *
299 * @returns true if there are errors, false if none.
300 */
301bool RTR0TestR0HaveErrors(void)
302{
303 return ASMAtomicUoReadU32(&g_cErrors) > 0;
304}
305
306#endif /* !IPRT_INCLUDED_SRC_testcase_tstRTR0Common_h */
307
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