summaryrefslogtreecommitdiffstats
path: root/include/iprt/test.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/iprt/test.h')
-rw-r--r--include/iprt/test.h1411
1 files changed, 1411 insertions, 0 deletions
diff --git a/include/iprt/test.h b/include/iprt/test.h
new file mode 100644
index 00000000..572870be
--- /dev/null
+++ b/include/iprt/test.h
@@ -0,0 +1,1411 @@
+/** @file
+ * IPRT - Testcase Framework.
+ */
+
+/*
+ * Copyright (C) 2009-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef IPRT_INCLUDED_test_h
+#define IPRT_INCLUDED_test_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/stdarg.h>
+#include <iprt/assert.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_test RTTest - Testcase Framework.
+ * @ingroup grp_rt
+ * @{
+ */
+
+/** A test handle. */
+typedef R3PTRTYPE(struct RTTESTINT *) RTTEST;
+/** A pointer to a test handle. */
+typedef RTTEST *PRTTEST;
+/** A const pointer to a test handle. */
+typedef RTTEST const *PCRTTEST;
+
+/** A NIL Test handle. */
+#define NIL_RTTEST ((RTTEST)0)
+
+/**
+ * Test message importance level.
+ */
+typedef enum RTTESTLVL
+{
+ /** Invalid 0. */
+ RTTESTLVL_INVALID = 0,
+ /** Message should always be printed. */
+ RTTESTLVL_ALWAYS,
+ /** Failure message. */
+ RTTESTLVL_FAILURE,
+ /** Sub-test banner. */
+ RTTESTLVL_SUB_TEST,
+ /** Info message. */
+ RTTESTLVL_INFO,
+ /** Debug message. */
+ RTTESTLVL_DEBUG,
+ /** The last (invalid). */
+ RTTESTLVL_END
+} RTTESTLVL;
+
+
+/**
+ * Creates a test instance.
+ *
+ * @returns IPRT status code.
+ * @param pszTest The test name.
+ * @param phTest Where to store the test instance handle.
+ */
+RTR3DECL(int) RTTestCreate(const char *pszTest, PRTTEST phTest);
+
+/**
+ * Creates a test instance for a child process.
+ *
+ * This differs from RTTestCreate in that it disabled result reporting to file
+ * and pipe in order to avoid producing invalid XML.
+ *
+ * @returns IPRT status code.
+ * @param pszTest The test name.
+ * @param phTest Where to store the test instance handle.
+ */
+RTR3DECL(int) RTTestCreateChild(const char *pszTest, PRTTEST phTest);
+
+/** @name RTTEST_C_XXX - Flags for RTTestCreateEx.
+ * @{ */
+/** Whether to check the IPRT_TEST_XXX variables when constructing the
+ * instance. The following environment variables get checks:
+ *
+ * - IPRT_TEST_MAX_LEVEL: String value indicating which level.
+ * The env. var. is applied if the program specified the default level
+ * (by passing RTTESTLVL_INVALID).
+ *
+ * - IPRT_TEST_PIPE: The native pipe/fifo handle to write XML
+ * results to.
+ * The env. var. is applied if iNativeTestPipe is -1.
+ *
+ * - IPRT_TEST_FILE: Path to file/named-pipe/fifo/whatever to
+ * write XML results to.
+ * The env. var. is applied if the program specified a NULL path, it is
+ * not applied if the program hands us an empty string.
+ *
+ * - IPRT_TEST_OMIT_TOP_TEST: If present, this makes the XML output omit
+ * the top level test element.
+ * The env. var is applied when present.
+ *
+ */
+#define RTTEST_C_USE_ENV RT_BIT(0)
+/** Whether to omit the top test in the XML. */
+#define RTTEST_C_XML_OMIT_TOP_TEST RT_BIT(1)
+/** Whether to delay the top test XML element until testing commences. */
+#define RTTEST_C_XML_DELAY_TOP_TEST RT_BIT(2)
+/** Whether to try install the test instance in the test TLS slot. Setting
+ * this flag is incompatible with using the RTTestIXxxx variant of the API. */
+#define RTTEST_C_NO_TLS RT_BIT(3)
+/** Don't report to the pipe (IPRT_TEST_PIPE or other). */
+#define RTTEST_C_NO_XML_REPORTING_PIPE RT_BIT(4)
+/** Don't report to the results file (IPRT_TEST_FILE or other). */
+#define RTTEST_C_NO_XML_REPORTING_FILE RT_BIT(4)
+/** No XML reporting to pipes, file or anything.
+ * Child processes may want to use this so they don't garble the output of
+ * the main test process. */
+#define RTTEST_C_NO_XML_REPORTING (RTTEST_C_NO_XML_REPORTING_PIPE | RTTEST_C_NO_XML_REPORTING_FILE)
+/** Mask containing the valid bits. */
+#define RTTEST_C_VALID_MASK UINT32_C(0x0000003f)
+/** @} */
+
+
+/**
+ * Creates a test instance.
+ *
+ * @returns IPRT status code.
+ * @param pszTest The test name.
+ * @param pszXmlFile The XML output file/pipe/whatever.
+ * @param fFlags Flags, see RTTEST_C_XXX.
+ * @param enmMaxLevel The max message level. Use RTTESTLVL_INVALID for
+ * the default output level or one from the
+ * environment. If specified, the environment variable
+ * will not be able to override it.
+ * @param iNativeTestPipe Native handle to a test pipe. -1 if not interested.
+ * @param pszXmlFile The XML output file name. If NULL the environment
+ * may be used. To selectively avoid that, pass an
+ * empty string.
+ * @param phTest Where to store the test instance handle.
+ *
+ * @note At the moment, we don't fail if @a pszXmlFile or @a iNativeTestPipe
+ * fails to open. This may change later.
+ */
+RTR3DECL(int) RTTestCreateEx(const char *pszTest, uint32_t fFlags, RTTESTLVL enmMaxLevel,
+ RTHCINTPTR iNativeTestPipe, const char *pszXmlFile, PRTTEST phTest);
+
+/**
+ * Initializes IPRT and creates a test instance.
+ *
+ * Typical usage is:
+ * @code
+ int main(int argc, char **argv)
+ {
+ RTTEST hTest;
+ int rc = RTTestInitAndCreate("tstSomething", &hTest);
+ if (rc)
+ return rc;
+ ...
+ }
+ @endcode
+ *
+ * @returns RTEXITCODE_SUCCESS on success. On failure an error message is
+ * printed and a suitable exit code is return.
+ *
+ * @param pszTest The test name.
+ * @param phTest Where to store the test instance handle.
+ */
+RTR3DECL(RTEXITCODE) RTTestInitAndCreate(const char *pszTest, PRTTEST phTest);
+
+/**
+ * Variant of RTTestInitAndCreate that includes IPRT init flags and argument
+ * vectors.
+ *
+ * @returns RTEXITCODE_SUCCESS on success. On failure an error message is
+ * printed and a suitable exit code is return.
+ *
+ * @param cArgs Pointer to the argument count.
+ * @param ppapszArgs Pointer to the argument vector pointer.
+ * @param fRtInit Flags, see RTR3INIT_XXX.
+ * @param pszTest The test name.
+ * @param phTest Where to store the test instance handle.
+ */
+RTR3DECL(RTEXITCODE) RTTestInitExAndCreate(int cArgs, char ***ppapszArgs, uint32_t fRtInit, const char *pszTest, PRTTEST phTest);
+
+/**
+ * Destroys a test instance previously created by RTTestCreate.
+ *
+ * @returns IPRT status code.
+ * @param hTest The test handle. NIL_RTTEST is ignored.
+ */
+RTR3DECL(int) RTTestDestroy(RTTEST hTest);
+
+/**
+ * Changes the default test instance for the calling thread.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hNewDefaultTest The new default test. NIL_RTTEST is fine.
+ * @param phOldTest Where to store the old test handle. Optional.
+ */
+RTR3DECL(int) RTTestSetDefault(RTTEST hNewDefaultTest, PRTTEST phOldTest);
+
+/**
+ * Changes the test case name.
+ *
+ * @returns IRPT status code.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param pszName The new test case name. Empty string is not accepted,
+ * nor are strings longer than 127 chars. Keep it short
+ * but descriptive.
+ */
+RTR3DECL(int) RTTestChangeName(RTTEST hTest, const char *pszName);
+
+/**
+ * Allocate a block of guarded memory.
+ *
+ * @returns IPRT status code.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param cb The amount of memory to allocate.
+ * @param cbAlign The alignment of the returned block.
+ * @param fHead Head or tail optimized guard.
+ * @param ppvUser Where to return the pointer to the block.
+ */
+RTR3DECL(int) RTTestGuardedAlloc(RTTEST hTest, size_t cb, uint32_t cbAlign, bool fHead, void **ppvUser);
+
+/**
+ * Allocates a block of guarded memory where the guarded is immediately after
+ * the user memory.
+ *
+ * @returns Pointer to the allocated memory. NULL on failure.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param cb The amount of memory to allocate.
+ */
+RTR3DECL(void *) RTTestGuardedAllocTail(RTTEST hTest, size_t cb);
+
+/**
+ * Allocates a block of guarded memory where the guarded is right in front of
+ * the user memory.
+ *
+ * @returns Pointer to the allocated memory. NULL on failure.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param cb The amount of memory to allocate.
+ */
+RTR3DECL(void *) RTTestGuardedAllocHead(RTTEST hTest, size_t cb);
+
+/**
+ * Frees a block of guarded memory.
+ *
+ * @returns IPRT status code.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param pv The memory. NULL is ignored.
+ */
+RTR3DECL(int) RTTestGuardedFree(RTTEST hTest, void *pv);
+
+/**
+ * Test vprintf making sure the output starts on a new line.
+ *
+ * @returns Number of chars printed.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param enmLevel Message importance level.
+ * @param pszFormat The message.
+ * @param va Arguments.
+ */
+RTR3DECL(int) RTTestPrintfNlV(RTTEST hTest, RTTESTLVL enmLevel, const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(3, 0);
+
+/**
+ * Test printf making sure the output starts on a new line.
+ *
+ * @returns Number of chars printed.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param enmLevel Message importance level.
+ * @param pszFormat The message.
+ * @param ... Arguments.
+ */
+RTR3DECL(int) RTTestPrintfNl(RTTEST hTest, RTTESTLVL enmLevel, const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(3, 4);
+
+/**
+ * Test vprintf, makes sure lines are prefixed and so forth.
+ *
+ * @returns Number of chars printed.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param enmLevel Message importance level.
+ * @param pszFormat The message.
+ * @param va Arguments.
+ */
+RTR3DECL(int) RTTestPrintfV(RTTEST hTest, RTTESTLVL enmLevel, const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(3, 0);
+
+/**
+ * Test printf, makes sure lines are prefixed and so forth.
+ *
+ * @returns Number of chars printed.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param enmLevel Message importance level.
+ * @param pszFormat The message.
+ * @param ... Arguments.
+ */
+RTR3DECL(int) RTTestPrintf(RTTEST hTest, RTTESTLVL enmLevel, const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(3, 4);
+
+/**
+ * Prints the test banner.
+ *
+ * @returns Number of chars printed.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ */
+RTR3DECL(int) RTTestBanner(RTTEST hTest);
+
+/**
+ * Summaries the test, destroys the test instance and return an exit code.
+ *
+ * @returns Test program exit code.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ */
+RTR3DECL(RTEXITCODE) RTTestSummaryAndDestroy(RTTEST hTest);
+
+/**
+ * Skips the test, destroys the test instance and return an exit code.
+ *
+ * @returns Test program exit code.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param pszReasonFmt Text explaining why, optional (NULL).
+ * @param va Arguments for the reason format string.
+ */
+RTR3DECL(RTEXITCODE) RTTestSkipAndDestroyV(RTTEST hTest, const char *pszReasonFmt, va_list va) RT_IPRT_FORMAT_ATTR(2, 0);
+
+/**
+ * Skips the test, destroys the test instance and return an exit code.
+ *
+ * @returns Test program exit code.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param pszReasonFmt Text explaining why, optional (NULL).
+ * @param ... Arguments for the reason format string.
+ */
+RTR3DECL(RTEXITCODE) RTTestSkipAndDestroy(RTTEST hTest, const char *pszReasonFmt, ...) RT_IPRT_FORMAT_ATTR(2, 3);
+
+/**
+ * Starts a sub-test.
+ *
+ * This will perform an implicit RTTestSubDone() call if that has not been done
+ * since the last RTTestSub call.
+ *
+ * @returns Number of chars printed.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param pszSubTest The sub-test name.
+ */
+RTR3DECL(int) RTTestSub(RTTEST hTest, const char *pszSubTest);
+
+/**
+ * Format string version of RTTestSub.
+ *
+ * See RTTestSub for details.
+ *
+ * @returns Number of chars printed.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param pszSubTestFmt The sub-test name format string.
+ * @param ... Arguments.
+ */
+RTR3DECL(int) RTTestSubF(RTTEST hTest, const char *pszSubTestFmt, ...) RT_IPRT_FORMAT_ATTR(2, 3);
+
+/**
+ * Format string version of RTTestSub.
+ *
+ * See RTTestSub for details.
+ *
+ * @returns Number of chars printed.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param pszSubTestFmt The sub-test name format string.
+ * @param va Arguments.
+ */
+RTR3DECL(int) RTTestSubV(RTTEST hTest, const char *pszSubTestFmt, va_list va) RT_IPRT_FORMAT_ATTR(2, 0);
+
+/**
+ * Completes a sub-test.
+ *
+ * @returns Number of chars printed, negative numbers are IPRT error codes.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ */
+RTR3DECL(int) RTTestSubDone(RTTEST hTest);
+
+/**
+ * Prints an extended PASSED message, optional.
+ *
+ * This does not conclude the sub-test, it could be used to report the passing
+ * of a sub-sub-to-the-power-of-N-test.
+ *
+ * @returns Number of chars printed, negative numbers are IPRT error codes.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param pszFormat The message. No trailing newline.
+ * @param va The arguments.
+ */
+RTR3DECL(int) RTTestPassedV(RTTEST hTest, const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(2, 0);
+
+/**
+ * Prints an extended PASSED message, optional.
+ *
+ * This does not conclude the sub-test, it could be used to report the passing
+ * of a sub-sub-to-the-power-of-N-test.
+ *
+ * @returns Number of chars printed, negative numbers are IPRT error codes.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param pszFormat The message. No trailing newline.
+ * @param ... The arguments.
+ */
+RTR3DECL(int) RTTestPassed(RTTEST hTest, const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(2, 3);
+
+/**
+ * Marks the current test as 'SKIPPED' and optionally displays a message
+ * explaining why.
+ *
+ * @returns Number of chars printed, negative numbers are IPRT error codes.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param pszFormat The message. No trailing newline. Can be NULL or empty.
+ * @param ... The arguments.
+ */
+RTR3DECL(int) RTTestSkipped(RTTEST hTest, const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(2, 3);
+
+/**
+ * Marks the current test as 'SKIPPED' and optionally displays a message
+ * explaining why.
+ *
+ * @returns Number of chars printed, negative numbers are IPRT error codes.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param pszFormat The message. No trailing newline. Can be NULL or empty.
+ * @param va The arguments.
+ */
+RTR3DECL(int) RTTestSkippedV(RTTEST hTest, const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(2, 0);
+
+
+/**
+ * Value units.
+ *
+ * @remarks This is an interface where we have to be binary compatible with both
+ * older versions of this header and other components using the same
+ * contant values.
+ * @remarks When adding a new item:
+ * - Always add at the end of the list - do NOT group it.
+ * - Add it to rtTestUnitName in r3/test.cpp.
+ * - include/VBox/VMMDevTesting.h (VMMDEV_TESTING_UNIT_XXX).
+ * - Add it to g_aszBs2TestUnitNames in
+ * TestSuite/bootsectors/bootsector2-common-routines.mac.
+ *
+ */
+typedef enum RTTESTUNIT
+{
+ /** The customary invalid zero value. */
+ RTTESTUNIT_INVALID = 0,
+
+ RTTESTUNIT_PCT, /**< Percentage (10^-2). */
+ RTTESTUNIT_BYTES, /**< Bytes. */
+ RTTESTUNIT_BYTES_PER_SEC, /**< Bytes per second. */
+ RTTESTUNIT_KILOBYTES, /**< Kilobytes. */
+ RTTESTUNIT_KILOBYTES_PER_SEC, /**< Kilobytes per second. */
+ RTTESTUNIT_MEGABYTES, /**< Megabytes. */
+ RTTESTUNIT_MEGABYTES_PER_SEC, /**< Megabytes per second. */
+ RTTESTUNIT_PACKETS, /**< Packets. */
+ RTTESTUNIT_PACKETS_PER_SEC, /**< Packets per second. */
+ RTTESTUNIT_FRAMES, /**< Frames. */
+ RTTESTUNIT_FRAMES_PER_SEC, /**< Frames per second. */
+ RTTESTUNIT_OCCURRENCES, /**< Occurrences. */
+ RTTESTUNIT_OCCURRENCES_PER_SEC, /**< Occurrences per second. */
+ RTTESTUNIT_CALLS, /**< Calls. */
+ RTTESTUNIT_CALLS_PER_SEC, /**< Calls per second. */
+ RTTESTUNIT_ROUND_TRIP, /**< Round trips. */
+ RTTESTUNIT_SECS, /**< Seconds. */
+ RTTESTUNIT_MS, /**< Milliseconds. */
+ RTTESTUNIT_NS, /**< Nanoseconds. */
+ RTTESTUNIT_NS_PER_CALL, /**< Nanoseconds per call. */
+ RTTESTUNIT_NS_PER_FRAME, /**< Nanoseconds per frame. */
+ RTTESTUNIT_NS_PER_OCCURRENCE, /**< Nanoseconds per occurrence. */
+ RTTESTUNIT_NS_PER_PACKET, /**< Nanoseconds per frame. */
+ RTTESTUNIT_NS_PER_ROUND_TRIP, /**< Nanoseconds per round trip. */
+ RTTESTUNIT_INSTRS, /**< Instructions. */
+ RTTESTUNIT_INSTRS_PER_SEC, /**< Instructions per second. */
+ RTTESTUNIT_NONE, /**< No unit. */
+ RTTESTUNIT_PP1K, /**< Parts per thousand (10^-3). */
+ RTTESTUNIT_PP10K, /**< Parts per ten thousand (10^-4). */
+ RTTESTUNIT_PPM, /**< Parts per million (10^-6). */
+ RTTESTUNIT_PPB, /**< Parts per billion (10^-9). */
+
+ /** The end of valid units. */
+ RTTESTUNIT_END
+} RTTESTUNIT;
+AssertCompile(RTTESTUNIT_INSTRS == 0x19);
+AssertCompile(RTTESTUNIT_NONE == 0x1b);
+
+/**
+ * Report a named test result value.
+ *
+ * This is typically used for benchmarking but can be used for other purposes
+ * like reporting limits of some implementation. The value gets associated with
+ * the current sub test, the name must be unique within the sub test.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param pszName The value name.
+ * @param u64Value The value.
+ * @param enmUnit The value unit.
+ */
+RTR3DECL(int) RTTestValue(RTTEST hTest, const char *pszName, uint64_t u64Value, RTTESTUNIT enmUnit);
+
+/**
+ * Same as RTTestValue, except that the name is now a format string.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param u64Value The value.
+ * @param enmUnit The value unit.
+ * @param pszNameFmt The value name format string.
+ * @param ... String arguments.
+ */
+RTR3DECL(int) RTTestValueF(RTTEST hTest, uint64_t u64Value, RTTESTUNIT enmUnit,
+ const char *pszNameFmt, ...) RT_IPRT_FORMAT_ATTR(4, 5);
+
+/**
+ * Same as RTTestValue, except that the name is now a format string.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param u64Value The value.
+ * @param enmUnit The value unit.
+ * @param pszNameFmt The value name format string.
+ * @param va String arguments.
+ */
+RTR3DECL(int) RTTestValueV(RTTEST hTest, uint64_t u64Value, RTTESTUNIT enmUnit,
+ const char *pszNameFmt, va_list va) RT_IPRT_FORMAT_ATTR(4, 0);
+
+/**
+ * Increments the error counter.
+ *
+ * @returns IPRT status code.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ */
+RTR3DECL(int) RTTestErrorInc(RTTEST hTest);
+
+/**
+ * Get the current error count.
+ *
+ * @returns The error counter, UINT32_MAX if no valid test handle.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ */
+RTR3DECL(uint32_t) RTTestErrorCount(RTTEST hTest);
+
+/**
+ * Get the error count of the current sub test.
+ *
+ * @returns The error counter, UINT32_MAX if no valid test handle.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ */
+RTR3DECL(uint32_t) RTTestSubErrorCount(RTTEST hTest);
+
+/**
+ * Increments the error counter and prints a failure message.
+ *
+ * @returns IPRT status code.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param pszFormat The message. No trailing newline.
+ * @param va The arguments.
+ */
+RTR3DECL(int) RTTestFailedV(RTTEST hTest, const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(2, 0);
+
+/**
+ * Increments the error counter and prints a failure message.
+ *
+ * @returns IPRT status code.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param pszFormat The message. No trailing newline.
+ * @param ... The arguments.
+ */
+RTR3DECL(int) RTTestFailed(RTTEST hTest, const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(2, 3);
+
+/**
+ * Same as RTTestPrintfV with RTTESTLVL_FAILURE.
+ *
+ * @returns Number of chars printed.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param pszFormat The message.
+ * @param va Arguments.
+ */
+RTR3DECL(int) RTTestFailureDetailsV(RTTEST hTest, const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(2, 0);
+
+/**
+ * Same as RTTestPrintf with RTTESTLVL_FAILURE.
+ *
+ * @returns Number of chars printed.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param pszFormat The message.
+ * @param ... Arguments.
+ */
+RTR3DECL(int) RTTestFailureDetails(RTTEST hTest, const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(2, 3);
+
+/**
+ * Disables and shuts up assertions.
+ *
+ * Max 8 nestings.
+ *
+ * @returns IPRT status code.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @sa RTAssertSetMayPanic, RTAssertSetQuiet.
+ */
+RTR3DECL(int) RTTestDisableAssertions(RTTEST hTest);
+
+/**
+ * Restores the previous call to RTTestDisableAssertions.
+ *
+ * @returns IPRT status code.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ */
+RTR3DECL(int) RTTestRestoreAssertions(RTTEST hTest);
+
+
+/** @def RTTEST_CHECK
+ * Check whether a boolean expression holds true.
+ *
+ * If the expression is false, call RTTestFailed giving the line number and expression.
+ *
+ * @param hTest The test handle.
+ * @param expr The expression to evaluate.
+ */
+#define RTTEST_CHECK(hTest, expr) \
+ do { if (!(expr)) { \
+ RTTestFailed((hTest), "line %u: %s", __LINE__, #expr); \
+ } \
+ } while (0)
+/** @def RTTEST_CHECK_RET
+ * Check whether a boolean expression holds true, returns on false.
+ *
+ * If the expression is false, call RTTestFailed giving the line number and
+ * expression, then return @a rcRet.
+ *
+ * @param hTest The test handle.
+ * @param expr The expression to evaluate.
+ * @param rcRet What to return on failure.
+ */
+#define RTTEST_CHECK_RET(hTest, expr, rcRet) \
+ do { if (!(expr)) { \
+ RTTestFailed((hTest), "line %u: %s", __LINE__, #expr); \
+ return (rcRet); \
+ } \
+ } while (0)
+/** @def RTTEST_CHECK_RETV
+ * Check whether a boolean expression holds true, returns void on false.
+ *
+ * If the expression is false, call RTTestFailed giving the line number and
+ * expression, then return void.
+ *
+ * @param hTest The test handle.
+ * @param expr The expression to evaluate.
+ */
+#define RTTEST_CHECK_RETV(hTest, expr) \
+ do { if (!(expr)) { \
+ RTTestFailed((hTest), "line %u: %s", __LINE__, #expr); \
+ return; \
+ } \
+ } while (0)
+/** @def RTTEST_CHECK_BREAK
+ * Check whether a boolean expression holds true.
+ *
+ * If the expression is false, call RTTestFailed giving the line number and
+ * expression, then break.
+ *
+ * @param hTest The test handle.
+ * @param expr The expression to evaluate.
+ */
+#define RTTEST_CHECK_BREAK(hTest, expr) \
+ if (!(expr)) { \
+ RTTestFailed((hTest), "line %u: %s", __LINE__, #expr); \
+ break; \
+ } else do {} while (0)
+
+
+/** @def RTTEST_CHECK_MSG
+ * Check whether a boolean expression holds true.
+ *
+ * If the expression is false, call RTTestFailed giving the line number and expression.
+ *
+ * @param hTest The test handle.
+ * @param expr The expression to evaluate.
+ * @param DetailsArgs Argument list for RTTestFailureDetails, including
+ * parenthesis.
+ */
+#define RTTEST_CHECK_MSG(hTest, expr, DetailsArgs) \
+ do { if (!(expr)) { \
+ RTTestFailed((hTest), "line %u: %s", __LINE__, #expr); \
+ RTTestFailureDetails DetailsArgs; \
+ } \
+ } while (0)
+/** @def RTTEST_CHECK_MSG_RET
+ * Check whether a boolean expression holds true, returns on false.
+ *
+ * If the expression is false, call RTTestFailed giving the line number and expression.
+ *
+ * @param hTest The test handle.
+ * @param expr The expression to evaluate.
+ * @param DetailsArgs Argument list for RTTestFailureDetails, including
+ * parenthesis.
+ * @param rcRet What to return on failure.
+ */
+#define RTTEST_CHECK_MSG_RET(hTest, expr, DetailsArgs, rcRet) \
+ do { if (!(expr)) { \
+ RTTestFailed((hTest), "line %u: %s", __LINE__, #expr); \
+ RTTestFailureDetails DetailsArgs; \
+ return (rcRet); \
+ } \
+ } while (0)
+/** @def RTTEST_CHECK_MSG_RET
+ * Check whether a boolean expression holds true, returns void on false.
+ *
+ * If the expression is false, call RTTestFailed giving the line number and expression.
+ *
+ * @param hTest The test handle.
+ * @param expr The expression to evaluate.
+ * @param DetailsArgs Argument list for RTTestFailureDetails, including
+ * parenthesis.
+ */
+#define RTTEST_CHECK_MSG_RETV(hTest, expr, DetailsArgs) \
+ do { if (!(expr)) { \
+ RTTestFailed((hTest), "line %u: %s", __LINE__, #expr); \
+ RTTestFailureDetails DetailsArgs; \
+ return; \
+ } \
+ } while (0)
+
+
+/** @def RTTEST_CHECK_RC
+ * Check whether an expression returns a specific IPRT style status code.
+ *
+ * If a different status code is return, call RTTestFailed giving the line
+ * number, expression, actual and expected status codes.
+ *
+ * @param hTest The test handle.
+ * @param rcExpr The expression resulting in an IPRT status code.
+ * @param rcExpect The expected return code. This may be referenced
+ * more than once by the macro.
+ */
+#define RTTEST_CHECK_RC(hTest, rcExpr, rcExpect) \
+ do { \
+ int rcCheck = (rcExpr); \
+ if (rcCheck != (rcExpect)) { \
+ RTTestFailed((hTest), "line %u: %s: expected %Rrc, got %Rrc", __LINE__, #rcExpr, (rcExpect), rcCheck); \
+ } \
+ } while (0)
+/** @def RTTEST_CHECK_RC_RET
+ * Check whether an expression returns a specific IPRT style status code.
+ *
+ * If a different status code is return, call RTTestFailed giving the line
+ * number, expression, actual and expected status codes, then return.
+ *
+ * @param hTest The test handle.
+ * @param rcExpr The expression resulting in an IPRT status code.
+ * This will be assigned to a local rcCheck variable
+ * that can be used as return value.
+ * @param rcExpect The expected return code. This may be referenced
+ * more than once by the macro.
+ * @param rcRet The return code.
+ */
+#define RTTEST_CHECK_RC_RET(hTest, rcExpr, rcExpect, rcRet) \
+ do { \
+ int rcCheck = (rcExpr); \
+ if (rcCheck != (rcExpect)) { \
+ RTTestFailed((hTest), "line %u: %s: expected %Rrc, got %Rrc", __LINE__, #rcExpr, (rcExpect), rcCheck); \
+ return (rcRet); \
+ } \
+ } while (0)
+/** @def RTTEST_CHECK_RC_RETV
+ * Check whether an expression returns a specific IPRT style status code.
+ *
+ * If a different status code is return, call RTTestFailed giving the line
+ * number, expression, actual and expected status codes, then return.
+ *
+ * @param hTest The test handle.
+ * @param rcExpr The expression resulting in an IPRT status code.
+ * @param rcExpect The expected return code. This may be referenced
+ * more than once by the macro.
+ */
+#define RTTEST_CHECK_RC_RETV(hTest, rcExpr, rcExpect) \
+ do { \
+ int rcCheck = (rcExpr); \
+ if (rcCheck != (rcExpect)) { \
+ RTTestFailed((hTest), "line %u: %s: expected %Rrc, got %Rrc", __LINE__, #rcExpr, (rcExpect), rcCheck); \
+ return; \
+ } \
+ } while (0)
+/** @def RTTEST_CHECK_RC_BREAK
+ * Check whether an expression returns a specific IPRT style status code.
+ *
+ * If a different status code is return, call RTTestFailed giving the line
+ * number, expression, actual and expected status codes, then break.
+ *
+ * @param hTest The test handle.
+ * @param rcExpr The expression resulting in an IPRT status code.
+ * @param rcExpect The expected return code. This may be referenced
+ * more than once by the macro.
+ */
+#define RTTEST_CHECK_RC_BREAK(hTest, rcExpr, rcExpect) \
+ if (1) { \
+ int rcCheck = (rcExpr); \
+ if (rcCheck != (rcExpect)) { \
+ RTTestFailed((hTest), "line %u: %s: expected %Rrc, got %Rrc", __LINE__, #rcExpr, (rcExpect), rcCheck); \
+ break; \
+ } \
+ } else do {} while (0)
+
+
+/** @def RTTEST_CHECK_RC_OK
+ * Check whether a IPRT style status code indicates success.
+ *
+ * If the status indicates failure, call RTTestFailed giving the line number,
+ * expression and status code.
+ *
+ * @param hTest The test handle.
+ * @param rcExpr The expression resulting in an IPRT status code.
+ */
+#define RTTEST_CHECK_RC_OK(hTest, rcExpr) \
+ do { \
+ int rcCheck = (rcExpr); \
+ if (RT_FAILURE(rcCheck)) { \
+ RTTestFailed((hTest), "line %u: %s: %Rrc", __LINE__, #rcExpr, rcCheck); \
+ } \
+ } while (0)
+/** @def RTTEST_CHECK_RC_OK_RET
+ * Check whether a IPRT style status code indicates success.
+ *
+ * If the status indicates failure, call RTTestFailed giving the line number,
+ * expression and status code, then return with the specified value.
+ *
+ * @param hTest The test handle.
+ * @param rcExpr The expression resulting in an IPRT status code.
+ * This will be assigned to a local rcCheck variable
+ * that can be used as return value.
+ * @param rcRet The return code.
+ */
+#define RTTEST_CHECK_RC_OK_RET(hTest, rcExpr, rcRet) \
+ do { \
+ int rcCheck = (rcExpr); \
+ if (RT_FAILURE(rcCheck)) { \
+ RTTestFailed((hTest), "line %u: %s: %Rrc", __LINE__, #rcExpr, rcCheck); \
+ return (rcRet); \
+ } \
+ } while (0)
+/** @def RTTEST_CHECK_RC_OK_RETV
+ * Check whether a IPRT style status code indicates success.
+ *
+ * If the status indicates failure, call RTTestFailed giving the line number,
+ * expression and status code, then return.
+ *
+ * @param hTest The test handle.
+ * @param rcExpr The expression resulting in an IPRT status code.
+ */
+#define RTTEST_CHECK_RC_OK_RETV(hTest, rcExpr) \
+ do { \
+ int rcCheck = (rcExpr); \
+ if (RT_FAILURE(rcCheck)) { \
+ RTTestFailed((hTest), "line %u: %s: %Rrc", __LINE__, #rcExpr, rcCheck); \
+ return; \
+ } \
+ } while (0)
+
+
+
+
+/** @name Implicit Test Handle API Variation
+ * The test handle is retrieved from the test TLS entry of the calling thread.
+ * @{
+ */
+
+/**
+ * Test vprintf, makes sure lines are prefixed and so forth.
+ *
+ * @returns Number of chars printed.
+ * @param enmLevel Message importance level.
+ * @param pszFormat The message.
+ * @param va Arguments.
+ */
+RTR3DECL(int) RTTestIPrintfV(RTTESTLVL enmLevel, const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(2, 0);
+
+/**
+ * Test printf, makes sure lines are prefixed and so forth.
+ *
+ * @returns Number of chars printed.
+ * @param enmLevel Message importance level.
+ * @param pszFormat The message.
+ * @param ... Arguments.
+ */
+RTR3DECL(int) RTTestIPrintf(RTTESTLVL enmLevel, const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(2, 3);
+
+/**
+ * Starts a sub-test.
+ *
+ * This will perform an implicit RTTestSubDone() call if that has not been done
+ * since the last RTTestSub call.
+ *
+ * @returns Number of chars printed.
+ * @param pszSubTest The sub-test name.
+ */
+RTR3DECL(int) RTTestISub(const char *pszSubTest);
+
+/**
+ * Format string version of RTTestSub.
+ *
+ * See RTTestSub for details.
+ *
+ * @returns Number of chars printed.
+ * @param pszSubTestFmt The sub-test name format string.
+ * @param ... Arguments.
+ */
+RTR3DECL(int) RTTestISubF(const char *pszSubTestFmt, ...) RT_IPRT_FORMAT_ATTR(1, 2);
+
+/**
+ * Format string version of RTTestSub.
+ *
+ * See RTTestSub for details.
+ *
+ * @returns Number of chars printed.
+ * @param pszSubTestFmt The sub-test name format string.
+ * @param va Arguments.
+ */
+RTR3DECL(int) RTTestISubV(const char *pszSubTestFmt, va_list va) RT_IPRT_FORMAT_ATTR(1, 0);
+
+/**
+ * Completes a sub-test.
+ *
+ * @returns Number of chars printed.
+ */
+RTR3DECL(int) RTTestISubDone(void);
+
+/**
+ * Prints an extended PASSED message, optional.
+ *
+ * This does not conclude the sub-test, it could be used to report the passing
+ * of a sub-sub-to-the-power-of-N-test.
+ *
+ * @returns IPRT status code.
+ * @param pszFormat The message. No trailing newline.
+ * @param va The arguments.
+ */
+RTR3DECL(int) RTTestIPassedV(const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(1, 0);
+
+/**
+ * Prints an extended PASSED message, optional.
+ *
+ * This does not conclude the sub-test, it could be used to report the passing
+ * of a sub-sub-to-the-power-of-N-test.
+ *
+ * @returns IPRT status code.
+ * @param pszFormat The message. No trailing newline.
+ * @param ... The arguments.
+ */
+RTR3DECL(int) RTTestIPassed(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
+
+/**
+ * Report a named test result value.
+ *
+ * This is typically used for benchmarking but can be used for other purposes
+ * like reporting limits of some implementation. The value gets associated with
+ * the current sub test, the name must be unique within the sub test.
+ *
+ * @returns IPRT status code.
+ *
+ * @param pszName The value name.
+ * @param u64Value The value.
+ * @param enmUnit The value unit.
+ */
+RTR3DECL(int) RTTestIValue(const char *pszName, uint64_t u64Value, RTTESTUNIT enmUnit);
+
+/**
+ * Same as RTTestValue, except that the name is now a format string.
+ *
+ * @returns IPRT status code.
+ *
+ * @param u64Value The value.
+ * @param enmUnit The value unit.
+ * @param pszNameFmt The value name format string.
+ * @param ... String arguments.
+ */
+RTR3DECL(int) RTTestIValueF(uint64_t u64Value, RTTESTUNIT enmUnit, const char *pszNameFmt, ...) RT_IPRT_FORMAT_ATTR(3, 4);
+
+/**
+ * Same as RTTestValue, except that the name is now a format string.
+ *
+ * @returns IPRT status code.
+ *
+ * @param u64Value The value.
+ * @param enmUnit The value unit.
+ * @param pszNameFmt The value name format string.
+ * @param va String arguments.
+ */
+RTR3DECL(int) RTTestIValueV(uint64_t u64Value, RTTESTUNIT enmUnit, const char *pszNameFmt, va_list va) RT_IPRT_FORMAT_ATTR(3, 0);
+
+/**
+ * Increments the error counter.
+ *
+ * @returns IPRT status code.
+ */
+RTR3DECL(int) RTTestIErrorInc(void);
+
+/**
+ * Get the current error count.
+ *
+ * @returns The error counter, UINT32_MAX if no valid test handle.
+ */
+RTR3DECL(uint32_t) RTTestIErrorCount(void);
+
+/**
+ * Increments the error counter and prints a failure message.
+ *
+ * @returns IPRT status code.
+ * @param pszFormat The message. No trailing newline.
+ * @param va The arguments.
+ */
+RTR3DECL(int) RTTestIFailedV(const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(1, 0);
+
+/**
+ * Increments the error counter and prints a failure message.
+ *
+ * @returns IPRT status code.
+ * @param pszFormat The message. No trailing newline.
+ * @param ... The arguments.
+ */
+RTR3DECL(int) RTTestIFailed(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
+
+/**
+ * Increments the error counter, prints a failure message and returns the
+ * specified status code.
+ *
+ * This is mainly a convenience method for saving vertical space in the source
+ * code.
+ *
+ * @returns @a rcRet
+ * @param rcRet The IPRT status code to return.
+ * @param pszFormat The message. No trailing newline.
+ * @param va The arguments.
+ */
+RTR3DECL(int) RTTestIFailedRcV(int rcRet, const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(2, 0);
+
+/**
+ * Increments the error counter, prints a failure message and returns the
+ * specified status code.
+ *
+ * This is mainly a convenience method for saving vertical space in the source
+ * code.
+ *
+ * @returns @a rcRet
+ * @param rcRet The IPRT status code to return.
+ * @param pszFormat The message. No trailing newline.
+ * @param ... The arguments.
+ */
+RTR3DECL(int) RTTestIFailedRc(int rcRet, const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(2, 3);
+
+/**
+ * Same as RTTestIPrintfV with RTTESTLVL_FAILURE.
+ *
+ * @returns Number of chars printed.
+ * @param pszFormat The message.
+ * @param va Arguments.
+ */
+RTR3DECL(int) RTTestIFailureDetailsV(const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(1, 0);
+
+/**
+ * Same as RTTestIPrintf with RTTESTLVL_FAILURE.
+ *
+ * @returns Number of chars printed.
+ * @param pszFormat The message.
+ * @param ... Arguments.
+ */
+RTR3DECL(int) RTTestIFailureDetails(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
+
+/**
+ * Disables and shuts up assertions.
+ *
+ * Max 8 nestings.
+ *
+ * @returns IPRT status code.
+ * @sa RTAssertSetMayPanic, RTAssertSetQuiet.
+ */
+RTR3DECL(int) RTTestIDisableAssertions(void);
+
+/**
+ * Restores the previous call to RTTestDisableAssertions.
+ *
+ * @returns IPRT status code.
+ */
+RTR3DECL(int) RTTestIRestoreAssertions(void);
+
+
+/** @def RTTESTI_CHECK
+ * Check whether a boolean expression holds true.
+ *
+ * If the expression is false, call RTTestIFailed giving the line number and
+ * expression.
+ *
+ * @param expr The expression to evaluate.
+ */
+#define RTTESTI_CHECK(expr) \
+ do { if (!(expr)) { \
+ RTTestIFailed("line %u: %s", __LINE__, #expr); \
+ } \
+ } while (0)
+/** @def RTTESTI_CHECK_RET
+ * Check whether a boolean expression holds true, returns on false.
+ *
+ * If the expression is false, call RTTestIFailed giving the line number and
+ * expression, then return @a rcRet.
+ *
+ * @param expr The expression to evaluate.
+ * @param rcRet What to return on failure.
+ */
+#define RTTESTI_CHECK_RET(expr, rcRet) \
+ do { if (!(expr)) { \
+ RTTestIFailed("line %u: %s", __LINE__, #expr); \
+ return (rcRet); \
+ } \
+ } while (0)
+/** @def RTTESTI_CHECK_RETV
+ * Check whether a boolean expression holds true, returns void on false.
+ *
+ * If the expression is false, call RTTestIFailed giving the line number and
+ * expression, then return void.
+ *
+ * @param expr The expression to evaluate.
+ */
+#define RTTESTI_CHECK_RETV(expr) \
+ do { if (!(expr)) { \
+ RTTestIFailed("line %u: %s", __LINE__, #expr); \
+ return; \
+ } \
+ } while (0)
+/** @def RTTESTI_CHECK_RETV
+ * Check whether a boolean expression holds true, returns void on false.
+ *
+ * If the expression is false, call RTTestIFailed giving the line number and
+ * expression, then break.
+ *
+ * @param expr The expression to evaluate.
+ */
+#define RTTESTI_CHECK_BREAK(expr) \
+ if (!(expr)) { \
+ RTTestIFailed("line %u: %s", __LINE__, #expr); \
+ break; \
+ } else do {} while (0)
+
+
+/** @def RTTESTI_CHECK_MSG
+ * Check whether a boolean expression holds true.
+ *
+ * If the expression is false, call RTTestIFailed giving the line number and
+ * expression.
+ *
+ * @param expr The expression to evaluate.
+ * @param DetailsArgs Argument list for RTTestIFailureDetails, including
+ * parenthesis.
+ */
+#define RTTESTI_CHECK_MSG(expr, DetailsArgs) \
+ do { if (!(expr)) { \
+ RTTestIFailed("line %u: %s", __LINE__, #expr); \
+ RTTestIFailureDetails DetailsArgs; \
+ } \
+ } while (0)
+/** @def RTTESTI_CHECK_MSG_BREAK
+ * Check whether a boolean expression holds true, returns on false.
+ *
+ * If the expression is false, call RTTestIFailed giving the line number and
+ * expression.
+ *
+ * @param expr The expression to evaluate.
+ * @param DetailsArgs Argument list for RTTestIFailureDetails, including
+ * parenthesis.
+ */
+#define RTTESTI_CHECK_MSG_BREAK(expr, DetailsArgs) \
+ if (!(expr)) { \
+ RTTestIFailed("line %u: %s", __LINE__, #expr); \
+ RTTestIFailureDetails DetailsArgs; \
+ break; \
+ } else do {} while (0)
+/** @def RTTESTI_CHECK_MSG_RET
+ * Check whether a boolean expression holds true, returns on false.
+ *
+ * If the expression is false, call RTTestIFailed giving the line number and
+ * expression.
+ *
+ * @param expr The expression to evaluate.
+ * @param DetailsArgs Argument list for RTTestIFailureDetails, including
+ * parenthesis.
+ * @param rcRet What to return on failure.
+ */
+#define RTTESTI_CHECK_MSG_RET(expr, DetailsArgs, rcRet) \
+ do { if (!(expr)) { \
+ RTTestIFailed("line %u: %s", __LINE__, #expr); \
+ RTTestIFailureDetails DetailsArgs; \
+ return (rcRet); \
+ } \
+ } while (0)
+/** @def RTTESTI_CHECK_MSG_RET
+ * Check whether a boolean expression holds true, returns void on false.
+ *
+ * If the expression is false, call RTTestIFailed giving the line number and
+ * expression.
+ *
+ * @param expr The expression to evaluate.
+ * @param DetailsArgs Argument list for RTTestIFailureDetails, including
+ * parenthesis.
+ */
+#define RTTESTI_CHECK_MSG_RETV(expr, DetailsArgs) \
+ do { if (!(expr)) { \
+ RTTestIFailed("line %u: %s", __LINE__, #expr); \
+ RTTestIFailureDetails DetailsArgs; \
+ return; \
+ } \
+ } while (0)
+
+/** @def RTTESTI_CHECK_RC
+ * Check whether an expression returns a specific IPRT style status code.
+ *
+ * If a different status code is return, call RTTestIFailed giving the line
+ * number, expression, actual and expected status codes.
+ *
+ * @param rcExpr The expression resulting in an IPRT status code.
+ * @param rcExpect The expected return code. This may be referenced
+ * more than once by the macro.
+ */
+#define RTTESTI_CHECK_RC(rcExpr, rcExpect) \
+ do { \
+ int rcCheck = (rcExpr); \
+ if (rcCheck != (rcExpect)) { \
+ RTTestIFailed("line %u: %s: expected %Rrc, got %Rrc", __LINE__, #rcExpr, (rcExpect), rcCheck); \
+ } \
+ } while (0)
+/** @def RTTESTI_CHECK_RC_RET
+ * Check whether an expression returns a specific IPRT style status code.
+ *
+ * If a different status code is return, call RTTestIFailed giving the line
+ * number, expression, actual and expected status codes, then return.
+ *
+ * @param rcExpr The expression resulting in an IPRT status code.
+ * This will be assigned to a local rcCheck variable
+ * that can be used as return value.
+ * @param rcExpect The expected return code. This may be referenced
+ * more than once by the macro.
+ * @param rcRet The return code.
+ */
+#define RTTESTI_CHECK_RC_RET(rcExpr, rcExpect, rcRet) \
+ do { \
+ int rcCheck = (rcExpr); \
+ if (rcCheck != (rcExpect)) { \
+ RTTestIFailed("line %u: %s: expected %Rrc, got %Rrc", __LINE__, #rcExpr, (rcExpect), rcCheck); \
+ return (rcRet); \
+ } \
+ } while (0)
+/** @def RTTESTI_CHECK_RC_RETV
+ * Check whether an expression returns a specific IPRT style status code.
+ *
+ * If a different status code is return, call RTTestIFailed giving the line
+ * number, expression, actual and expected status codes, then return.
+ *
+ * @param rcExpr The expression resulting in an IPRT status code.
+ * @param rcExpect The expected return code. This may be referenced
+ * more than once by the macro.
+ */
+#define RTTESTI_CHECK_RC_RETV(rcExpr, rcExpect) \
+ do { \
+ int rcCheck = (rcExpr); \
+ if (rcCheck != (rcExpect)) { \
+ RTTestIFailed("line %u: %s: expected %Rrc, got %Rrc", __LINE__, #rcExpr, (rcExpect), rcCheck); \
+ return; \
+ } \
+ } while (0)
+/** @def RTTESTI_CHECK_RC_BREAK
+ * Check whether an expression returns a specific IPRT style status code.
+ *
+ * If a different status code is return, call RTTestIFailed giving the line
+ * number, expression, actual and expected status codes, then break.
+ *
+ * @param rcExpr The expression resulting in an IPRT status code.
+ * @param rcExpect The expected return code. This may be referenced
+ * more than once by the macro.
+ */
+#define RTTESTI_CHECK_RC_BREAK(rcExpr, rcExpect) \
+ if (1) { \
+ int rcCheck = (rcExpr); \
+ if (rcCheck != (rcExpect)) { \
+ RTTestIFailed("line %u: %s: expected %Rrc, got %Rrc", __LINE__, #rcExpr, (rcExpect), rcCheck); \
+ break; \
+ } \
+ } else do {} while (0)
+/** @def RTTESTI_CHECK_RC_OK
+ * Check whether a IPRT style status code indicates success.
+ *
+ * If the status indicates failure, call RTTestIFailed giving the line number,
+ * expression and status code.
+ *
+ * @param rcExpr The expression resulting in an IPRT status code.
+ */
+#define RTTESTI_CHECK_RC_OK(rcExpr) \
+ do { \
+ int rcCheck = (rcExpr); \
+ if (RT_FAILURE(rcCheck)) { \
+ RTTestIFailed("line %u: %s: %Rrc", __LINE__, #rcExpr, rcCheck); \
+ } \
+ } while (0)
+/** @def RTTESTI_CHECK_RC_OK_BREAK
+ * Check whether a IPRT style status code indicates success.
+ *
+ * If a different status code is return, call RTTestIFailed giving the line
+ * number, expression, actual and expected status codes, then break.
+ *
+ * @param rcExpr The expression resulting in an IPRT status code.
+ */
+#define RTTESTI_CHECK_RC_OK_BREAK(rcExpr) \
+ do { \
+ int rcCheck = (rcExpr); \
+ if (RT_FAILURE(rcCheck)) { \
+ RTTestIFailed("line %u: %s: %Rrc", __LINE__, #rcExpr, rcCheck); \
+ break; \
+ } \
+ } while (0)
+/** @def RTTESTI_CHECK_RC_OK_RET
+ * Check whether a IPRT style status code indicates success.
+ *
+ * If the status indicates failure, call RTTestIFailed giving the line number,
+ * expression and status code, then return with the specified value.
+ *
+ * @param rcExpr The expression resulting in an IPRT status code.
+ * This will be assigned to a local rcCheck variable
+ * that can be used as return value.
+ * @param rcRet The return code.
+ */
+#define RTTESTI_CHECK_RC_OK_RET(rcExpr, rcRet) \
+ do { \
+ int rcCheck = (rcExpr); \
+ if (RT_FAILURE(rcCheck)) { \
+ RTTestIFailed("line %u: %s: %Rrc", __LINE__, #rcExpr, rcCheck); \
+ return (rcRet); \
+ } \
+ } while (0)
+/** @def RTTESTI_CHECK_RC_OK_RETV
+ * Check whether a IPRT style status code indicates success.
+ *
+ * If the status indicates failure, call RTTestIFailed giving the line number,
+ * expression and status code, then return.
+ *
+ * @param rcExpr The expression resulting in an IPRT status code.
+ */
+#define RTTESTI_CHECK_RC_OK_RETV(rcExpr) \
+ do { \
+ int rcCheck = (rcExpr); \
+ if (RT_FAILURE(rcCheck)) { \
+ RTTestIFailed("line %u: %s: %Rrc", __LINE__, #rcExpr, rcCheck); \
+ return; \
+ } \
+ } while (0)
+
+/** @} */
+
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif /* !IPRT_INCLUDED_test_h */
+