VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstRTTraceLog.cpp@ 86715

Last change on this file since 86715 was 82968, checked in by vboxsync, 5 years ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.9 KB
Line 
1/* $Id: tstRTTraceLog.cpp 82968 2020-02-04 10:35:17Z vboxsync $ */
2/** @file
3 * IPRT Testcase - RTTraceLog.
4 */
5
6/*
7 * Copyright (C) 2018-2020 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/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#include <iprt/tracelog.h>
32
33#include <iprt/err.h>
34#include <iprt/file.h>
35#include <iprt/mem.h>
36#include <iprt/string.h>
37#include <iprt/test.h>
38#include <iprt/time.h>
39
40
41/**
42 * Trace log buffer.
43 */
44typedef struct TSTRTTRACELOGBUF
45{
46 /** Size of the buffer. */
47 size_t cbBuf;
48 /** Current write offset. */
49 size_t offBuf;
50 /** Streamed data - variable in size. */
51 uint8_t abBuf[1];
52} TSTRTTRACELOGBUF;
53/** Pointer to a trace log buffer. */
54typedef TSTRTTRACELOGBUF *PTSTRTTRACELOGBUF;
55
56
57/**
58 * Structure matching the event descriptor.
59 */
60typedef struct RTTESTTRACELOGEVTDATA
61{
62 /** Test pointer. */
63 uintptr_t ptr;
64 /** Test size_t value. */
65 size_t sz;
66 /** Test 32bit value. */
67 uint32_t u32;
68 /** Test boolean. */
69 bool f;
70 /** Test raw data. */
71 uint8_t abRaw[42];
72} RTTESTTRACELOGEVTDATA;
73/** Pointer to event data. */
74typedef RTTESTTRACELOGEVTDATA *PRTTESTTRACELOGEVTDATA;
75
76
77/**
78 * Test event item descriptor.
79 */
80static RTTRACELOGEVTITEMDESC g_EvtItemDesc[] =
81{
82 {"TestPtr", NULL, RTTRACELOGTYPE_POINTER, 0},
83 {"TestSz", NULL, RTTRACELOGTYPE_SIZE, 0},
84 {"TestU32", NULL, RTTRACELOGTYPE_UINT32, 0},
85 {"TestBool", "This is a test description", RTTRACELOGTYPE_BOOL, 0},
86 {"TestRawStatic", NULL, RTTRACELOGTYPE_RAWDATA, 42}
87};
88
89
90/**
91 * Test event descriptor.
92 */
93static RTTRACELOGEVTDESC g_EvtDesc =
94{
95 "idTest",
96 "This is a test event",
97 RTTRACELOGEVTSEVERITY_INFO,
98 RT_ELEMENTS(g_EvtItemDesc),
99 g_EvtItemDesc
100};
101
102
103
104/**
105 * Allocates a new buffer for the raw trace log stream.
106 *
107 * @returns IPRT status code.
108 * @param cbBuf Size of the buffer in bytes.
109 * @param ppBuf Where to store the pointer to the buffer on success.
110 */
111static int tstRTTraceLogBufAlloc(size_t cbBuf, PTSTRTTRACELOGBUF *ppBuf)
112{
113 PTSTRTTRACELOGBUF pBuf = (PTSTRTTRACELOGBUF)RTMemAllocZ(RT_UOFFSETOF_DYN(TSTRTTRACELOGBUF, abBuf[cbBuf]));
114 if (RT_LIKELY(pBuf))
115 {
116 pBuf->cbBuf = cbBuf;
117 pBuf->offBuf = 0;
118 *ppBuf = pBuf;
119 return VINF_SUCCESS;
120 }
121
122 return VERR_NO_MEMORY;
123}
124
125
126/**
127 * @copydoc{FNRTTRACELOGWRSTREAM}
128 */
129static DECLCALLBACK(int) tstRTTraceLogStreamOut(void *pvUser, const void *pvBuf, size_t cbBuf, size_t *pcbWritten)
130{
131 PTSTRTTRACELOGBUF pBuf = (PTSTRTTRACELOGBUF)pvUser;
132
133 if (pBuf)
134 {
135 size_t cbWrite = RT_MIN(cbBuf, pBuf->cbBuf - pBuf->offBuf);
136 if ( cbWrite != 0
137 && ( cbWrite >= cbBuf
138 || pcbWritten))
139 {
140 memcpy(&pBuf->abBuf[pBuf->offBuf], pvBuf, cbWrite);
141 pBuf->offBuf += cbWrite;
142 if (pcbWritten)
143 *pcbWritten = cbWrite;
144 return VINF_SUCCESS;
145 }
146
147 return VERR_DISK_FULL;
148 }
149
150 /* Benchmark mode, forget everything immediately. */
151 return VINF_SUCCESS;
152}
153
154
155/**
156 * @copydoc{FNRTTRACELOGRDRSTREAM}
157 */
158static DECLCALLBACK(int) tstRTTraceLogStreamIn(void *pvUser, void *pvBuf, size_t cbBuf, size_t *pcbRead,
159 RTMSINTERVAL cMsTimeout)
160{
161 RT_NOREF(cMsTimeout);
162 PTSTRTTRACELOGBUF pBuf = (PTSTRTTRACELOGBUF)pvUser;
163
164 size_t cbRead = RT_MIN(cbBuf, pBuf->cbBuf - pBuf->offBuf);
165 if ( cbRead != 0
166 && ( cbRead >= cbBuf
167 || pcbRead))
168 {
169 memcpy(pvBuf, &pBuf->abBuf[pBuf->offBuf], cbRead);
170 pBuf->offBuf += cbRead;
171 if (pcbRead)
172 *pcbRead = cbRead;
173 return VINF_SUCCESS;
174 }
175
176 return VERR_EOF;
177}
178
179
180/**
181 * @copydoc{FNRTTRACELOGSTREAMCLOSE}
182 */
183static DECLCALLBACK(int) tstRTTraceLogStreamClose(void *pvUser)
184{
185 RT_NOREF(pvUser);
186 return VINF_SUCCESS;
187}
188
189
190static PTSTRTTRACELOGBUF tstRTTraceLogWriter(void)
191{
192 RTTRACELOGWR hTraceLogWr = NIL_RTTRACELOGWR;
193 PTSTRTTRACELOGBUF pLogBuf = NULL;
194 RTTESTTRACELOGEVTDATA EvtData;
195
196 EvtData.ptr = (uintptr_t)&EvtData;
197 EvtData.sz = 0xdeadcafe;
198 EvtData.u32 = 0;
199 EvtData.f = true;
200 memset(&EvtData.abRaw[0], 0x42, sizeof(EvtData.abRaw));
201
202 /*
203 * Bad set pointer and handle values.
204 */
205 RTTestSub(NIL_RTTEST, "Writer");
206 RTTESTI_CHECK_RC(RTTraceLogWrCreate(NULL, NULL, NULL, NULL, NULL), VERR_INVALID_POINTER);
207 RTTESTI_CHECK_RC(RTTraceLogWrCreate(&hTraceLogWr, NULL, NULL, NULL, NULL), VERR_INVALID_POINTER);
208 RTTRACELOGWR hTraceLogWrInvl = (RTTRACELOGWR)(intptr_t)-3;
209 RTTESTI_CHECK_RC(RTTraceLogWrDestroy(hTraceLogWrInvl), VERR_INVALID_HANDLE);
210 RTTESTI_CHECK_RC(RTTraceLogWrAddEvtDesc(hTraceLogWr, NULL), VERR_INVALID_HANDLE);
211 RTTESTI_CHECK_RC(RTTraceLogWrEvtAdd(hTraceLogWr, NULL, 0, 0, 0, NULL, NULL), VERR_INVALID_HANDLE);
212
213 RTTESTI_CHECK_RC_RET(tstRTTraceLogBufAlloc(_4K, &pLogBuf), VINF_SUCCESS, NULL);
214 RTTESTI_CHECK_RC_RET(RTTraceLogWrCreate(&hTraceLogWr, NULL, tstRTTraceLogStreamOut,
215 tstRTTraceLogStreamClose, pLogBuf), VINF_SUCCESS, NULL);
216 RTTESTI_CHECK_RC_RET(RTTraceLogWrAddEvtDesc(hTraceLogWr, &g_EvtDesc), VINF_SUCCESS, NULL);
217 RTTESTI_CHECK_RC_RET(RTTraceLogWrAddEvtDesc(hTraceLogWr, &g_EvtDesc), VERR_ALREADY_EXISTS, NULL);
218 RTTESTI_CHECK_RC_RET(RTTraceLogWrEvtAdd(hTraceLogWr, &g_EvtDesc, 0, 0, 0, &EvtData, NULL), VINF_SUCCESS, NULL);
219 RTTESTI_CHECK_RC_RET(RTTraceLogWrDestroy(hTraceLogWr), VINF_SUCCESS, NULL);
220
221 return pLogBuf;
222}
223
224
225static void tstRTTraceLogWriterBenchmark(void)
226{
227 RTTRACELOGWR hTraceLogWr = NIL_RTTRACELOGWR;
228 RTTESTTRACELOGEVTDATA EvtData;
229
230 EvtData.ptr = (uintptr_t)&EvtData;
231 EvtData.sz = 0xdeadcafe;
232 EvtData.u32 = 0;
233 EvtData.f = true;
234 memset(&EvtData.abRaw[0], 0x42, sizeof(EvtData.abRaw));
235
236 RTTestSub(NIL_RTTEST, "Writer Benchmark");
237 RTTESTI_CHECK_RC_RETV(RTTraceLogWrCreate(&hTraceLogWr, NULL, tstRTTraceLogStreamOut,
238 tstRTTraceLogStreamClose, NULL), VINF_SUCCESS);
239 RTTESTI_CHECK_RC_RETV(RTTraceLogWrAddEvtDesc(hTraceLogWr, &g_EvtDesc), VINF_SUCCESS);
240
241 uint64_t tsStart = RTTimeNanoTS();
242 for (uint32_t i = 0; i < 1000000; i++)
243 {
244 RTTESTI_CHECK_RC_BREAK(RTTraceLogWrEvtAdd(hTraceLogWr, &g_EvtDesc, 0, 0, 0, &EvtData, NULL), VINF_SUCCESS);
245 }
246 uint64_t tsRuntime = RTTimeNanoTS() - tsStart;
247 RTTestValue(NIL_RTTEST, "RTTraceLogWrEvtAdd()", tsRuntime / 1000000, RTTESTUNIT_NS_PER_CALL);
248 RTTESTI_CHECK_RC(RTTraceLogWrDestroy(hTraceLogWr), VINF_SUCCESS);
249}
250
251static void tstRTTraceLogReader(PTSTRTTRACELOGBUF pLogBuf)
252{
253 RTTRACELOGRDRPOLLEVT enmEvt = RTTRACELOGRDRPOLLEVT_INVALID;
254 RTTRACELOGRDR hTraceLogRdr = NIL_RTTRACELOGRDR;
255
256 RTTestSub(NIL_RTTEST, "Reader");
257
258 /*
259 * Bad set pointer and handle values.
260 */
261 RTTESTI_CHECK_RC(RTTraceLogRdrCreate(NULL, NULL, NULL, NULL), VERR_INVALID_POINTER);
262 RTTESTI_CHECK_RC(RTTraceLogRdrCreate(&hTraceLogRdr, NULL, NULL, NULL), VERR_INVALID_POINTER);
263 RTTRACELOGRDR hTraceLogRdrInvl = (RTTRACELOGRDR)(intptr_t)-3;
264 RTTESTI_CHECK_RC(RTTraceLogRdrDestroy(hTraceLogRdrInvl), VERR_INVALID_HANDLE);
265 RTTESTI_CHECK_RC(RTTraceLogRdrEvtPoll(hTraceLogRdrInvl, NULL, RT_INDEFINITE_WAIT), VERR_INVALID_HANDLE);
266
267 /*
268 * Test with log buffer created previously.
269 */
270 RTTESTI_CHECK_RC_RETV(RTTraceLogRdrCreate(&hTraceLogRdr, tstRTTraceLogStreamIn, tstRTTraceLogStreamClose, pLogBuf),
271 VINF_SUCCESS);
272 RTTESTI_CHECK_RC_RETV(RTTraceLogRdrEvtPoll(hTraceLogRdr, &enmEvt, RT_INDEFINITE_WAIT), VINF_SUCCESS);
273 RTTESTI_CHECK_RETV(enmEvt == RTTRACELOGRDRPOLLEVT_HDR_RECVD);
274 RTTESTI_CHECK_RC_RETV(RTTraceLogRdrEvtPoll(hTraceLogRdr, &enmEvt, RT_INDEFINITE_WAIT), VINF_SUCCESS);
275 RTTESTI_CHECK_RETV(enmEvt == RTTRACELOGRDRPOLLEVT_TRACE_EVENT_RECVD);
276 RTTESTI_CHECK_RC_RETV(RTTraceLogRdrDestroy(hTraceLogRdr), VINF_SUCCESS);
277}
278
279
280int main()
281{
282 RTTEST hTest;
283 int rc = RTTestInitAndCreate("tstRTTraceLog", &hTest);
284 if (rc)
285 return rc;
286 RTTestBanner(hTest);
287
288 /*
289 * The tests.
290 */
291 bool fMayPanic = RTAssertMayPanic();
292 bool fQuiet = RTAssertAreQuiet();
293 RTAssertSetMayPanic(false);
294 RTAssertSetQuiet(true);
295 PTSTRTTRACELOGBUF pLogBuf = tstRTTraceLogWriter();
296 if (RTTestErrorCount(hTest) == 0)
297 {
298 pLogBuf->offBuf = 0;
299 tstRTTraceLogReader(pLogBuf);
300 }
301 RTMemFree(pLogBuf);
302 tstRTTraceLogWriterBenchmark();
303 RTAssertSetQuiet(fQuiet);
304 RTAssertSetMayPanic(fMayPanic);
305
306 /*
307 * Summary.
308 */
309 return RTTestSummaryAndDestroy(hTest);
310}
311
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