VirtualBox

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

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette