VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstRTAcpi.cpp

Last change on this file was 108723, checked in by vboxsync, 6 weeks ago

Runtime/testcase/tstRTAcpi.cpp: Temporarily disable testcase until I got around fixing it

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 18.5 KB
Line 
1/* $Id: tstRTAcpi.cpp 108723 2025-03-24 18:25:39Z vboxsync $ */
2/** @file
3 * IPRT Testcase - ACPI API.
4 */
5
6/*
7 * Copyright (C) 2025 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
38/*********************************************************************************************************************************
39* Header Files *
40*********************************************************************************************************************************/
41#include <iprt/acpi.h>
42
43#include <iprt/err.h>
44#include <iprt/file.h> /* RTFILE_O_READ and RTFILE_O_WRITE */
45#include <iprt/script.h>
46#include <iprt/string.h>
47#include <iprt/test.h>
48#include <iprt/vfs.h>
49
50
51/*********************************************************************************************************************************
52* Global Variables *
53*********************************************************************************************************************************/
54static DECLCALLBACK(int) tstRtAcpiAslLexerParseNumber(RTSCRIPTLEX hScriptLex, char ch, PRTSCRIPTLEXTOKEN pToken, void *pvUser);
55
56
57static const char *s_aszSingleStart[] =
58{
59 "//",
60 NULL
61};
62
63
64static const char *s_aszMultiStart[] =
65{
66 "/*",
67 NULL
68};
69
70
71static const char *s_aszMultiEnd[] =
72{
73 "*/",
74 NULL
75};
76
77
78static const RTSCRIPTLEXTOKMATCH s_aMatches[] =
79{
80 /* Punctuators */
81 { RT_STR_TUPLE(","), RTSCRIPTLEXTOKTYPE_PUNCTUATOR, false, 0 },
82 { RT_STR_TUPLE("("), RTSCRIPTLEXTOKTYPE_PUNCTUATOR, false, 0 },
83 { RT_STR_TUPLE(")"), RTSCRIPTLEXTOKTYPE_PUNCTUATOR, false, 0 },
84 { RT_STR_TUPLE("{"), RTSCRIPTLEXTOKTYPE_PUNCTUATOR, false, 0 },
85 { RT_STR_TUPLE("}"), RTSCRIPTLEXTOKTYPE_PUNCTUATOR, false, 0 },
86 { NULL, 0, RTSCRIPTLEXTOKTYPE_INVALID, false, 0 }
87};
88
89
90static const RTSCRIPTLEXRULE s_aRules[] =
91{
92 { '\"', '\"', RTSCRIPT_LEX_RULE_CONSUME, RTScriptLexScanStringLiteralC, NULL},
93 { '0', '9', RTSCRIPT_LEX_RULE_DEFAULT, tstRtAcpiAslLexerParseNumber, NULL},
94 { 'A', 'Z', RTSCRIPT_LEX_RULE_DEFAULT, RTScriptLexScanIdentifier, NULL},
95 { '_', '_', RTSCRIPT_LEX_RULE_DEFAULT, RTScriptLexScanIdentifier, NULL},
96 { '^', '^', RTSCRIPT_LEX_RULE_DEFAULT, RTScriptLexScanIdentifier, NULL},
97 { '\\', '\\', RTSCRIPT_LEX_RULE_DEFAULT, RTScriptLexScanIdentifier, NULL},
98
99 { '\0', '\0', RTSCRIPT_LEX_RULE_DEFAULT, NULL, NULL}
100};
101
102
103static const RTSCRIPTLEXCFG s_AslLexCfg =
104{
105 /** pszName */
106 "TstAcpiAsl",
107 /** pszDesc */
108 "ACPI ASL lexer for the testcase",
109 /** fFlags */
110 RTSCRIPT_LEX_CFG_F_CASE_INSENSITIVE_UPPER,
111 /** pszWhitespace */
112 NULL,
113 /** pszNewline */
114 NULL,
115 /** papszCommentMultiStart */
116 s_aszMultiStart,
117 /** papszCommentMultiEnd */
118 s_aszMultiEnd,
119 /** papszCommentSingleStart */
120 s_aszSingleStart,
121 /** paTokMatches */
122 s_aMatches,
123 /** paRules */
124 s_aRules,
125 /** pfnProdDef */
126 NULL,
127 /** pfnProdDefUser */
128 NULL
129};
130
131
132static DECLCALLBACK(int) tstRtAcpiAslLexerParseNumber(RTSCRIPTLEX hScriptLex, char ch, PRTSCRIPTLEXTOKEN pToken, void *pvUser)
133{
134 RT_NOREF(ch, pvUser);
135 return RTScriptLexScanNumber(hScriptLex, 0 /*uBase*/, false /*fAllowReal*/, pToken);
136}
137
138
139static DECLCALLBACK(int) tstRtAcpiAslLexerRead(RTSCRIPTLEX hScriptLex, size_t offBuf, char *pchCur,
140 size_t cchBuf, size_t *pcchRead, void *pvUser)
141{
142 RT_NOREF(hScriptLex, offBuf);
143
144 size_t cbRead = 0;
145 int rc = RTVfsFileRead((RTVFSFILE)pvUser, pchCur, cchBuf, &cbRead);
146 if (RT_FAILURE(rc))
147 return rc;
148
149 *pcchRead = cbRead * sizeof(char);
150 if (!cbRead)
151 return VINF_EOF;
152
153 return VINF_SUCCESS;
154}
155
156
157static void tstAcpiVerifySemantic(RTTEST hTest, RTVFSFILE hVfsFileAslSrc, RTVFSFILE hVfsFileAslOut)
158{
159 RT_NOREF(hTest);
160
161 /* Build the lexer and compare that it semantically is equal to the source input. */
162 RTSCRIPTLEX hLexAslSrc = NULL;
163 int rc = RTScriptLexCreateFromReader(&hLexAslSrc, tstRtAcpiAslLexerRead,
164 NULL /*pfnDtor*/, hVfsFileAslSrc /*pvUser*/, 0 /*cchBuf*/,
165 NULL /*phStrCacheId*/, NULL /*phStrCacheStringLit*/,
166 NULL /*phStrCacheComments*/, &s_AslLexCfg);
167 RTTESTI_CHECK_RC(rc, VINF_SUCCESS);
168 if (RT_FAILURE(rc))
169 return; /* Can't do our work if this fails. */
170
171 RTSCRIPTLEX hLexAslOut = NULL;
172 rc = RTScriptLexCreateFromReader(&hLexAslOut, tstRtAcpiAslLexerRead,
173 NULL /*pfnDtor*/, hVfsFileAslOut /*pvUser*/, 0 /*cchBuf*/,
174 NULL /*phStrCacheId*/, NULL /*phStrCacheStringLit*/,
175 NULL /*phStrCacheComments*/, &s_AslLexCfg);
176 RTTESTI_CHECK_RC(rc, VINF_SUCCESS);
177 if (RT_FAILURE(rc))
178 {
179 RTScriptLexDestroy(hLexAslSrc);
180 return; /* Can't do our work if this fails. */
181 }
182
183 if (RT_SUCCESS(rc))
184 {
185 uint32_t const cErrBefore = RTTestIErrorCount();
186
187 /* Now compare the token streams until we hit EOS in the lexers. */
188 for (;;)
189 {
190 PCRTSCRIPTLEXTOKEN pTokAslSrc;
191 rc = RTScriptLexQueryToken(hLexAslSrc, &pTokAslSrc);
192 RTTESTI_CHECK_RC(rc, VINF_SUCCESS);
193
194 PCRTSCRIPTLEXTOKEN pTokAslOut;
195 rc = RTScriptLexQueryToken(hLexAslOut, &pTokAslOut);
196 RTTESTI_CHECK_RC(rc, VINF_SUCCESS);
197
198 RTTESTI_CHECK(pTokAslSrc->enmType == pTokAslOut->enmType);
199 if (pTokAslSrc->enmType == RTSCRIPTLEXTOKTYPE_EOS)
200 break;
201
202 if (pTokAslSrc->enmType == pTokAslOut->enmType)
203 {
204 switch (pTokAslSrc->enmType)
205 {
206 case RTSCRIPTLEXTOKTYPE_IDENTIFIER:
207 {
208 int iCmp = strcmp(pTokAslSrc->Type.Id.pszIde, pTokAslOut->Type.Id.pszIde);
209 RTTESTI_CHECK(!iCmp);
210 if (iCmp)
211 RTTestIFailureDetails("<IDE{%u.%u, %u.%u}, %s != %s>\n",
212 pTokAslSrc->PosStart.iLine, pTokAslSrc->PosStart.iCh,
213 pTokAslSrc->PosEnd.iLine, pTokAslSrc->PosEnd.iCh,
214 pTokAslSrc->Type.Id.pszIde, pTokAslOut->Type.Id.pszIde);
215 break;
216 }
217 case RTSCRIPTLEXTOKTYPE_NUMBER:
218 RTTESTI_CHECK(pTokAslSrc->Type.Number.enmType == pTokAslOut->Type.Number.enmType);
219 if (pTokAslSrc->Type.Number.enmType == pTokAslOut->Type.Number.enmType)
220 {
221 switch (pTokAslSrc->Type.Number.enmType)
222 {
223 case RTSCRIPTLEXTOKNUMTYPE_NATURAL:
224 {
225 RTTESTI_CHECK(pTokAslSrc->Type.Number.Type.u64 == pTokAslOut->Type.Number.Type.u64);
226 if (pTokAslSrc->Type.Number.Type.u64 != pTokAslOut->Type.Number.Type.u64)
227 RTTestIFailureDetails("<NUM{%u.%u, %u.%u} %RU64 != %RU64>\n",
228 pTokAslSrc->PosStart.iLine, pTokAslSrc->PosStart.iCh,
229 pTokAslSrc->PosEnd.iLine, pTokAslSrc->PosEnd.iCh,
230 pTokAslSrc->Type.Number.Type.u64, pTokAslOut->Type.Number.Type.u64);
231 break;
232 }
233 case RTSCRIPTLEXTOKNUMTYPE_INTEGER:
234 {
235 RTTESTI_CHECK(pTokAslSrc->Type.Number.Type.i64 == pTokAslOut->Type.Number.Type.i64);
236 if (pTokAslSrc->Type.Number.Type.i64 != pTokAslOut->Type.Number.Type.i64)
237 RTTestIFailureDetails("<NUM{%u.%u, %u.%u} %RI64 != %RI64>\n",
238 pTokAslSrc->PosStart.iLine, pTokAslSrc->PosStart.iCh,
239 pTokAslSrc->PosEnd.iLine, pTokAslSrc->PosEnd.iCh,
240 pTokAslSrc->Type.Number.Type.i64, pTokAslOut->Type.Number.Type.i64);
241 break;
242 }
243 case RTSCRIPTLEXTOKNUMTYPE_REAL:
244 default:
245 AssertReleaseFailed();
246 }
247 }
248 else
249 RTTestIFailureDetails("<NUM{%u.%u, %u.%u} %u != %u>\n",
250 pTokAslSrc->PosStart.iLine, pTokAslSrc->PosStart.iCh,
251 pTokAslSrc->PosEnd.iLine, pTokAslSrc->PosEnd.iCh,
252 pTokAslSrc->Type.Number.enmType, pTokAslOut->Type.Number.enmType);
253 break;
254 case RTSCRIPTLEXTOKTYPE_PUNCTUATOR:
255 {
256 int iCmp = strcmp(pTokAslSrc->Type.Punctuator.pPunctuator->pszMatch,
257 pTokAslOut->Type.Punctuator.pPunctuator->pszMatch);
258 RTTESTI_CHECK(!iCmp);
259 if (iCmp)
260 RTTestIFailureDetails("<PUNCTUATOR{%u.%u, %u.%u}, %s != %s>\n",
261 pTokAslSrc->PosStart.iLine, pTokAslSrc->PosStart.iCh,
262 pTokAslSrc->PosEnd.iLine, pTokAslSrc->PosEnd.iCh,
263 pTokAslSrc->Type.Punctuator.pPunctuator->pszMatch,
264 pTokAslOut->Type.Punctuator.pPunctuator->pszMatch);
265 break;
266 }
267 case RTSCRIPTLEXTOKTYPE_STRINGLIT:
268 {
269 int iCmp = strcmp(pTokAslSrc->Type.StringLit.pszString,
270 pTokAslOut->Type.StringLit.pszString);
271 RTTESTI_CHECK(!iCmp);
272 if (iCmp)
273 RTTestIFailureDetails("<STRINGLIT{%u.%u, %u.%u}, \"%s\" != \"%s\">\n",
274 pTokAslSrc->PosStart.iLine, pTokAslSrc->PosStart.iCh,
275 pTokAslSrc->PosEnd.iLine, pTokAslSrc->PosEnd.iCh,
276 pTokAslSrc->Type.StringLit.pszString,
277 pTokAslOut->Type.StringLit.pszString);
278 break;
279 }
280
281 /* These should never occur and indicate an issue in the lexer. */
282 case RTSCRIPTLEXTOKTYPE_KEYWORD:
283 RTTestIFailureDetails("<KEYWORD{%u.%u, %u.%u}, %s>\n",
284 pTokAslSrc->PosStart.iLine, pTokAslSrc->PosStart.iCh,
285 pTokAslSrc->PosEnd.iLine, pTokAslSrc->PosEnd.iCh,
286 pTokAslSrc->Type.Keyword.pKeyword->pszMatch);
287 break;
288 case RTSCRIPTLEXTOKTYPE_OPERATOR:
289 RTTestIFailureDetails("<OPERATOR{%u.%u, %u.%u}, %s>\n",
290 pTokAslSrc->PosStart.iLine, pTokAslSrc->PosStart.iCh,
291 pTokAslSrc->PosEnd.iLine, pTokAslSrc->PosEnd.iCh,
292 pTokAslSrc->Type.Operator.pOp->pszMatch);
293 break;
294 case RTSCRIPTLEXTOKTYPE_INVALID:
295 RTTestIFailureDetails("<INVALID>\n");
296 break;
297 case RTSCRIPTLEXTOKTYPE_ERROR:
298 RTTestIFailureDetails("<ERROR{%u.%u, %u.%u}> %s\n",
299 pTokAslSrc->PosStart.iLine, pTokAslSrc->PosStart.iCh,
300 pTokAslSrc->PosEnd.iLine, pTokAslSrc->PosEnd.iCh,
301 pTokAslSrc->Type.Error.pErr->pszMsg);
302 break;
303 case RTSCRIPTLEXTOKTYPE_EOS:
304 RTTestIFailureDetails("<EOS>\n");
305 break;
306 default:
307 AssertFailed();
308 }
309 }
310 else
311 RTTestIFailureDetails("pTokAslSrc->enmType=%u pTokAslOut->enmType=%u\n",
312 pTokAslSrc->enmType, pTokAslOut->enmType);
313
314 /*
315 * Abort on error as the streams are now out of sync and matching will not work
316 * anymore producing lots of noise.
317 */
318 if (cErrBefore != RTTestIErrorCount())
319 break;
320
321 /* Advance to the next token. */
322 pTokAslSrc = RTScriptLexConsumeToken(hLexAslSrc);
323 Assert(pTokAslSrc);
324
325 pTokAslOut = RTScriptLexConsumeToken(hLexAslOut);
326 Assert(pTokAslOut);
327 }
328 }
329
330 RTScriptLexDestroy(hLexAslSrc);
331 RTScriptLexDestroy(hLexAslOut);
332}
333
334
335
336/**
337 * Some basic ASL -> AML -> ASL testcases.
338 */
339static void tstBasic(RTTEST hTest)
340{
341 RTTestSub(hTest, "Basic valid tests");
342 static struct
343 {
344 const char *pszName;
345 const char *pszAsl;
346 } const aTests[] =
347 {
348 { "Empty", "DefinitionBlock (\"\", \"SSDT\", 1, \"VBOX \", \"VBOXTEST\", 2) {}\n" },
349#if 0 /** @todo r=aeichner Fails currently, needs fixing. */
350 { "Method", "DefinitionBlock (\"\", \"SSDT\", 1, \"VBOX \", \"VBOXTEST\", 2)\n"
351 "{\n"
352 "Method(TEST, 1, NotSerialized, 0) {\n"
353 "If (LEqual(Arg0, One)) {\n"
354 " Return (One)\n"
355 "} Else {\n"
356 " Return (Zero)\n"
357 "}\n"
358 "}\n"
359 "}\n" }
360#endif
361 };
362 for (unsigned iTest = 0; iTest < RT_ELEMENTS(aTests); iTest++)
363 {
364 RTTestISub(aTests[iTest].pszName);
365
366 RTVFSFILE hVfsFileSrc = NIL_RTVFSFILE;
367 int rc = RTVfsFileFromBuffer(RTFILE_O_READ, aTests[iTest].pszAsl, strlen(aTests[iTest].pszAsl), &hVfsFileSrc);
368 RTTESTI_CHECK_RC(rc, VINF_SUCCESS);
369
370 if (RT_SUCCESS(rc))
371 {
372 RTVFSFILE hVfsFileDst = NIL_RTVFSFILE;
373 rc = RTVfsFileFromBuffer(RTFILE_O_READ | RTFILE_O_WRITE, NULL, 0, &hVfsFileDst);
374 RTTESTI_CHECK_RC(rc, VINF_SUCCESS);
375
376 if (RT_SUCCESS(rc))
377 {
378 RTVFSIOSTREAM hVfsIosSrc = RTVfsFileToIoStream(hVfsFileSrc);
379 RTVFSIOSTREAM hVfsIosDst = RTVfsFileToIoStream(hVfsFileDst);
380 RTTESTI_CHECK(hVfsIosSrc != NIL_RTVFSIOSTREAM && hVfsIosDst != NIL_RTVFSIOSTREAM);
381
382 RTERRINFOSTATIC ErrInfo;
383 rc = RTAcpiTblConvertFromVfsIoStrm(hVfsIosDst, RTACPITBLTYPE_AML, hVfsIosSrc, RTACPITBLTYPE_ASL, RTErrInfoInitStatic(&ErrInfo));
384 RTTESTI_CHECK_RC(rc, VINF_SUCCESS);
385
386 RTVfsIoStrmRelease(hVfsIosSrc);
387 RTVfsIoStrmRelease(hVfsIosDst);
388
389 rc = RTVfsFileSeek(hVfsFileDst, 0 /*offSeek*/, RTFILE_SEEK_BEGIN, NULL /*poffActual*/);
390 RTTESTI_CHECK_RC(rc, VINF_SUCCESS);
391
392 rc = RTVfsFileSeek(hVfsFileSrc, 0 /*offSeek*/, RTFILE_SEEK_BEGIN, NULL /*poffActual*/);
393 RTTESTI_CHECK_RC(rc, VINF_SUCCESS);
394
395 hVfsIosSrc = RTVfsFileToIoStream(hVfsFileSrc);
396 hVfsIosDst = RTVfsFileToIoStream(hVfsFileDst);
397
398 RTVFSFILE hVfsFileDstAsl = NIL_RTVFSFILE;
399 rc = RTVfsFileFromBuffer(RTFILE_O_READ | RTFILE_O_WRITE, NULL, 0, &hVfsFileDstAsl);
400 RTTESTI_CHECK_RC(rc, VINF_SUCCESS);
401
402 if (RT_SUCCESS(rc))
403 {
404 RTVFSIOSTREAM hVfsIosDstAsl = RTVfsFileToIoStream(hVfsFileDstAsl);
405 RTTESTI_CHECK(hVfsIosDstAsl != NIL_RTVFSIOSTREAM);
406
407 rc = RTAcpiTblConvertFromVfsIoStrm(hVfsIosDstAsl, RTACPITBLTYPE_ASL, hVfsIosDst, RTACPITBLTYPE_AML, RTErrInfoInitStatic(&ErrInfo));
408 RTTESTI_CHECK_RC(rc, VINF_SUCCESS);
409 RTVfsIoStrmRelease(hVfsIosDstAsl);
410
411 rc = RTVfsFileSeek(hVfsFileDstAsl, 0 /*offSeek*/, RTFILE_SEEK_BEGIN, NULL /*poffActual*/);
412 RTTESTI_CHECK_RC(rc, VINF_SUCCESS);
413
414 tstAcpiVerifySemantic(hTest, hVfsFileSrc, hVfsFileDstAsl);
415
416 RTVfsFileRelease(hVfsFileDstAsl);
417 }
418
419 RTVfsIoStrmRelease(hVfsIosSrc);
420 RTVfsIoStrmRelease(hVfsIosDst);
421 RTVfsFileRelease(hVfsFileDst);
422 }
423
424 RTVfsFileRelease(hVfsFileSrc);
425 }
426 }
427}
428
429int main(int argc, char **argv)
430{
431 RTTEST hTest;
432 int rc = RTTestInitExAndCreate(argc, &argv, 0, "tstRTAcpi", &hTest);
433 if (rc)
434 return rc;
435 RTTestBanner(hTest);
436
437 tstBasic(hTest);
438
439 /*
440 * Summary.
441 */
442 return RTTestSummaryAndDestroy(hTest);
443}
444
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